gtkwave-3.3.66/0000775000076400007640000000000012546303360012601 5ustar bybellbybellgtkwave-3.3.66/Makefile.in0000664000076400007640000006020312261434733014652 0ustar bybellbybell# Makefile.in generated by automake 1.13.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 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__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } 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 = : subdir = . DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/configure $(am__configure_deps) \ $(srcdir)/config.h.in AUTHORS COPYING ChangeLog INSTALL NEWS \ README compile config.guess config.sub depcomp install-sh \ missing ylwrap ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.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 \ cscope distdir dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ $(LISP)config.h.in # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags CSCOPE = cscope DIST_SUBDIRS = $(SUBDIRS) 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 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@ AET2_CFLAGS = @AET2_CFLAGS@ AET2_LDADD = @AET2_LDADD@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COCOA_GTK_CFLAGS = @COCOA_GTK_CFLAGS@ COCOA_GTK_LDADD = @COCOA_GTK_LDADD@ COCOA_GTK_LDFLAGS = @COCOA_GTK_LDFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTDEBUG = @EXTDEBUG@ EXTDEBUG2 = @EXTDEBUG2@ EXTDEBUG3 = @EXTDEBUG3@ EXTDEBUG4 = @EXTDEBUG4@ EXTLOAD_CFLAGS = @EXTLOAD_CFLAGS@ FASTTREE_CFLAGS = @FASTTREE_CFLAGS@ FSDB_CFLAGS = @FSDB_CFLAGS@ FSDB_LDADD = @FSDB_LDADD@ GCONF_CFLAGS = @GCONF_CFLAGS@ GCONF_LIBS = @GCONF_LIBS@ GEDITTEST = @GEDITTEST@ GEDIT_CFLAGS = @GEDIT_CFLAGS@ GPERF = @GPERF@ GREP = @GREP@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_CONFIG = @GTK_CONFIG@ GTK_LIBS = @GTK_LIBS@ GTK_MAC_CFLAGS = @GTK_MAC_CFLAGS@ GTK_MAC_LIBS = @GTK_MAC_LIBS@ GTK_UNIX_PRINT_CFLAGS = @GTK_UNIX_PRINT_CFLAGS@ GTK_UNIX_PRINT_LIBS = @GTK_UNIX_PRINT_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBBZ2_CFLAGS = @LIBBZ2_CFLAGS@ LIBBZ2_DIR = @LIBBZ2_DIR@ LIBBZ2_LDADD = @LIBBZ2_LDADD@ LIBJUDY_CFLAGS = @LIBJUDY_CFLAGS@ LIBJUDY_LDADD = @LIBJUDY_LDADD@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBXZ_CFLAGS = @LIBXZ_CFLAGS@ LIBXZ_LDADD = @LIBXZ_LDADD@ LIBZ_CFLAGS = @LIBZ_CFLAGS@ LIBZ_DIR = @LIBZ_DIR@ LIBZ_LDADD = @LIBZ_LDADD@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MINGW_LDADD = @MINGW_LDADD@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ 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@ POW_LIB = @POW_LIB@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ STRUCT_PACK = @STRUCT_PACK@ TCL_DEFADD = @TCL_DEFADD@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LDADD = @TCL_LDADD@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_MAJOR_VERSION = @TCL_MAJOR_VERSION@ TCL_MINOR_VERSION = @TCL_MINOR_VERSION@ TK_INCLUDE_SPEC = @TK_INCLUDE_SPEC@ TK_LDADD = @TK_LDADD@ TK_LIB_SPEC = @TK_LIB_SPEC@ UPDATE_DESKTOP_DATABASE = @UPDATE_DESKTOP_DATABASE@ UPDATE_MIME_DATABASE = @UPDATE_MIME_DATABASE@ VERSION = @VERSION@ XDGDATADIR = @XDGDATADIR@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ 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_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ 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@ 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 = doc examples man src contrib share EXTRA_DIST = ChangeLog COPYING INSTALL LICENSE.TXT README NEWS AUTHORS \ autogen.sh wave_locale.h tcl.m4 all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: am--refresh: Makefile @: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): config.h: stamp-h1 @if test ! -f $@; then rm -f stamp-h1; else :; fi @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 # 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= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ 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 distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @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) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -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*) \ GZIP=$(GZIP_ENV) gzip -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*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) mkdir $(distdir)/_build $(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 \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile config.h 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 mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr 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 $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) all install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--refresh check check-am clean clean-cscope clean-generic \ cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \ distcheck distclean distclean-generic distclean-hdr \ distclean-tags distcleancheck distdir distuninstallcheck dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs installdirs-am \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am # 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: gtkwave-3.3.66/LICENSE.TXT0000664000076400007640000001267012546303410014266 0ustar bybellbybell########################################################################## GTKWave 3.3.66 Wave Viewer is Copyright (C) 1999-2015 Tony Bybell. Portions of GTKWave are Copyright (C) 1999-2015 Udi Finkelstein. Context support is Copyright (C) 2007-2015 Kermin Elliott Fleming. Trace group support is Copyright (C) 2009-2015 Donald Baltus. GHW and additional GUI support is Copyright (C) 2005-2015 Tristan Gingold. Analog support is Copyright (C) 2005-2015 Thomas Sailer. External DnD support is Copyright (C) 2008-2015 Concept Engineering GmbH. FastLZ is Copyright (C) 2005-2015 Ariya Hidayat. LZ4 is Copyright (C) 2011-2015 Yann Collet. 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 - Suite 500, Boston, MA 02110-1335, USA. ########################################################################## PCCTS 1.33MR is Copyright (C) 1989-2015 Terence Parr, Russell Quong, Will Cohen, Hank Dietz, and Thomas Moog. It is in the public domain. Please read contrib/pccts/RIGHTS for more information. ########################################################################## Some public domain clip art by contributors at http://www.sxc.hu/ Hierarchy marker icons from the Silk icons set by Mark James found at http://www.famfamfam.com/lab/icons/silk/ ########################################################################## For tcl_np.c and tcl_np.h: This software is copyrighted by the Regents of the University of California, Sun Microsystems, Inc., Scriptics Corporation, ActiveState Corporation, and other parties. The following terms apply to all files associated with the software unless explicitly disclaimed in individual files. The authors hereby grant permission to use, copy, modify, distribute, and license this software and its documentation for any purpose, provided that existing copyright notices are retained in all copies and that this notice is included verbatim in any distributions. No written agreement, license, or royalty fee is required for any of the authorized uses. Modifications to this software may be copyrighted by their authors and need not follow the licensing terms described here, provided that the new terms are clearly indicated on the first page of each file where they apply. IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. GOVERNMENT USE: If you are acquiring this software on behalf of the U.S. government, the Government shall have only "Restricted Rights" in the software and related documentation as defined in the Federal Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you are acquiring the software on behalf of the Department of Defense, the software shall be classified as "Commercial Computer Software" and the Government shall have only "Restricted Rights" as defined in Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the authors grant the U.S. Government and others acting in its behalf permission to use and distribute the software in accordance with the terms specified in this license. ########################################################################## The dumpfile processing source code in src/helpers is licensed under the MIT license in order to facilitate greater re-use: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ########################################################################## gtkwave-3.3.66/depcomp0000775000076400007640000005570312124357656014201 0ustar bybellbybell#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2012-10-18.11; # UTC # Copyright (C) 1999-2013 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" 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 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: gtkwave-3.3.66/aclocal.m40000664000076400007640000012703212124357656014457 0ustar bybellbybell# generated automatically by aclocal 1.13.1 -*- Autoconf -*- # Copyright (C) 1996-2012 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, [m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- # # Copyright © 2004 Scott James Remnant . # # 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 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. # PKG_PROG_PKG_CONFIG([MIN-VERSION]) # ---------------------------------- AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) m4_pattern_allow([^PKG_CONFIG(_PATH)?$]) AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl 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 ])# PKG_PROG_PKG_CONFIG # PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) # # Check to see whether a particular set of modules exists. Similar # to PKG_CHECK_MODULES(), but does not set variables or print errors. # # # Similar to PKG_CHECK_MODULES, make sure that the first instance of # this or PKG_CHECK_MODULES is called, or make sure 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_ifval([$2], [$2], [:]) m4_ifvaln([$3], [else $3])dnl fi]) # _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) # --------------------------------------------- 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`], [pkg_failed=yes]) else pkg_failed=untried fi[]dnl ])# _PKG_CONFIG # _PKG_SHORT_ERRORS_SUPPORTED # ----------------------------- 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 ])# _PKG_SHORT_ERRORS_SUPPORTED # PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], # [ACTION-IF-NOT-FOUND]) # # # Note that if there is a possibility the first call to # PKG_CHECK_MODULES might not happen, you should be sure to include an # 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 $1]) _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 _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "$2" 2>&1` else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD ifelse([$4], , [AC_MSG_ERROR(dnl [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 ])], [AC_MSG_RESULT([no]) $4]) elif test $pkg_failed = untried; then ifelse([$4], , [AC_MSG_FAILURE(dnl [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 .])], [$4]) else $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS $1[]_LIBS=$pkg_cv_[]$1[]_LIBS AC_MSG_RESULT([yes]) ifelse([$3], , :, [$3]) fi[]dnl ])# PKG_CHECK_MODULES # Copyright (C) 2002-2013 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.13' 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.13.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.13.1])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-2013 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], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2013 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-2013 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-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each '.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2013 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. # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) AC_REQUIRE([AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl ]) 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-2013 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}" != 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-2013 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])]) # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering # Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAINTAINER_MODE([DEFAULT-MODE]) # ---------------------------------- # Control maintainer-specific portions of Makefiles. # Default is to disable them, unless 'enable' is passed literally. # For symmetry, 'disable' may be passed as well. Anyway, the user # can override the default with the --enable/--disable switch. AC_DEFUN([AM_MAINTAINER_MODE], [m4_case(m4_default([$1], [disable]), [enable], [m4_define([am_maintainer_other], [disable])], [disable], [m4_define([am_maintainer_other], [enable])], [m4_define([am_maintainer_other], [enable]) m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) dnl maintainer-mode's default is 'disable' unless 'enable' is passed AC_ARG_ENABLE([maintainer-mode], [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode], am_maintainer_other[ make rules and dependencies not useful (and sometimes confusing) to the casual installer])], [USE_MAINTAINER_MODE=$enableval], [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) AC_MSG_RESULT([$USE_MAINTAINER_MODE]) AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) MAINT=$MAINTAINER_MODE_TRUE AC_SUBST([MAINT])dnl ] ) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Copyright (C) 1999-2013 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. AC_DEFUN([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC_C_O])dnl AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl # FIXME: we rely on the cache variable name because # there is no other way. set dummy $CC am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']` eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o if test "$am_t" != 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 dnl Make sure AC_PROG_CC is never called again, or it will override our dnl setting of CC. m4_define([AC_PROG_CC], [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])]) ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it is modern enough. # If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2013 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])]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2013 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-2013 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-2013 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-2013 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-2013 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}']) m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar],, [pax],, [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' _am_tools=${am_cv_prog_tar_$1-$_am_tools} # Do not fold the above two line into one, because Tru64 sh and # Solaris sh will not grok spaces in the rhs of '-'. 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 builtin(include,./tcl.m4) gtkwave-3.3.66/configure0000775000076400007640000124120012546303311014504 0ustar bybellbybell#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for gtkwave 3.3.66. # # Report bugs to . # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and $0: bybell@rocketmail.com about your system, including any $0: error possibly output before this message. Then install $0: a modern shell, or manually run the script under such a $0: shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" 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='gtkwave' PACKAGE_TARNAME='gtkwave' PACKAGE_VERSION='3.3.66' PACKAGE_STRING='gtkwave 3.3.66' PACKAGE_BUGREPORT='bybell@rocketmail.com' PACKAGE_URL='' ac_unique_file="src/vcd.c" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_header_list= ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS TK_LDADD TCL_DEFADD TCL_LDADD MINGW_LDADD POW_LIB LIBOBJS ALLOCA EGREP GREP CPP GTK_UNIX_PRINT_LIBS GTK_UNIX_PRINT_CFLAGS GCONF_LIBS GCONF_CFLAGS COCOA_GTK_LDFLAGS COCOA_GTK_LDADD COCOA_GTK_CFLAGS GTK_MAC_LIBS GTK_MAC_CFLAGS GTK_LIBS GTK_CFLAGS PKG_CONFIG GTK_CONFIG LIBJUDY_CFLAGS LIBJUDY_LDADD FASTTREE_CFLAGS LIBXZ_CFLAGS LIBXZ_LDADD LIBBZ2_DIR LIBBZ2_LDADD LIBBZ2_CFLAGS LIBZ_DIR LIBZ_LDADD LIBZ_CFLAGS GPERF EXTLOAD_CFLAGS EXTDEBUG4 EXTDEBUG3 EXTDEBUG2 EXTDEBUG GEDIT_CFLAGS GEDITTEST RANLIB LEXLIB LEX_OUTPUT_ROOT LEX am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE ac_ct_CC CFLAGS CC am__fastdepCXX_FALSE am__fastdepCXX_TRUE CXXDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CXX CPPFLAGS LDFLAGS CXXFLAGS CXX FSDB_LDADD FSDB_CFLAGS AET2_LDADD AET2_CFLAGS TK_INCLUDE_SPEC TK_STUB_LIB_SPEC TK_STUB_LIB_FLAG TK_STUB_LIB_FILE TK_LIB_SPEC TK_LIB_FLAG TK_LIB_FILE TK_SRC_DIR TK_BIN_DIR TK_VERSION TCL_MINOR_VERSION TCL_MAJOR_VERSION TCL_INCLUDE_SPEC TCL_STUB_LIB_SPEC TCL_STUB_LIB_FLAG TCL_STUB_LIB_FILE TCL_LIB_SPEC TCL_LIB_FLAG TCL_LIB_FILE TCL_SRC_DIR TCL_BIN_DIR TCL_PATCH_LEVEL TCL_VERSION STRUCT_PACK FDO_MIME_FALSE FDO_MIME_TRUE UPDATE_DESKTOP_DATABASE UPDATE_MIME_DATABASE XDGDATADIR MAINT MAINTAINER_MODE_FALSE MAINTAINER_MODE_TRUE AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V 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 localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_silent_rules enable_maintainer_mode with_gconf with_xdgdatadir enable_mime_update enable_struct_pack enable_tcl with_tcl with_tk enable_stubify enable_gtk1 enable_fatlines enable_manymarkers enable_ae2 enable_fsdb enable_dependency_tracking enable_local_libz enable_local_libbz2 enable_xz enable_fasttree enable_judy enable_largefile ' ac_precious_vars='build_alias host_alias target_alias CXX CXXFLAGS LDFLAGS LIBS CPPFLAGS CCC CC CFLAGS PKG_CONFIG GTK_CFLAGS GTK_LIBS GTK_MAC_CFLAGS GTK_MAC_LIBS GCONF_CFLAGS GCONF_LIBS GTK_UNIX_PRINT_CFLAGS GTK_UNIX_PRINT_LIBS CPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures gtkwave 3.3.66 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/gtkwave] --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 _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of gtkwave 3.3.66:";; 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-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer --disable-mime-update Disables MIME type and desktop/icon updating --enable-struct-pack Enables C language structure packing pragmas intended for use on architectures which support misaligned loads and stores (x86/x86_64/AVR32/ M68K/PowerPC/S390). This can reduce memory on traces with very many signals. --disable-tcl Disables Tcl if found --enable-stubify Causes the Tcl/Tk libraries to be dynamically loaded. --enable-gtk1 Causes the GTK+ frontend to be built with gtk1 instead of gtk2. --enable-fatlines Renders lines as double width in gtkwave. --enable-manymarkers Expands named marker count from 26 to 702. --enable-ae2 Compiles in AE2 from env var SIMARAMA_BASE location. --enable-fsdb Compiles in FsdbReader from env vars FSDBREADER_HDRS header and FSDBREADER_LIBS library directories. --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --enable-local-libz Use the bundled libz instead of any libz which may already be installed on your system. Default is to first look for an installed libz and fall back to using the bundled one. --enable-local-libbz2 Use the bundled libbz2 instead of any libbz2 which may already be installed on your system. Default is to first look for an installed libbz2 and fall back to using the bundled one. --disable-xz Disables LZMA support for VZT --disable-fasttree Disables experimental Fast SST Tree widget code --enable-judy Enables Judy array support --disable-largefile omit support for large files Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-gconf Use GConf to store preferences --with-xdgdatadir=path Change where the theme icons and mime registrations are installed [DATADIR] --with-tcl directory containing tcl configuration (tclConfig.sh) --with-tk directory containing tk configuration (tkConfig.sh) Some influential environment variables: CXX C++ compiler command CXXFLAGS 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 CC C compiler command CFLAGS C compiler flags PKG_CONFIG path to pkg-config utility GTK_CFLAGS C compiler flags for GTK, overriding pkg-config GTK_LIBS linker flags for GTK, overriding pkg-config GTK_MAC_CFLAGS C compiler flags for GTK_MAC, overriding pkg-config GTK_MAC_LIBS linker flags for GTK_MAC, overriding pkg-config GCONF_CFLAGS C compiler flags for GCONF, overriding pkg-config GCONF_LIBS linker flags for GCONF, overriding pkg-config GTK_UNIX_PRINT_CFLAGS C compiler flags for GTK_UNIX_PRINT, overriding pkg-config GTK_UNIX_PRINT_LIBS linker flags for GTK_UNIX_PRINT, overriding pkg-config CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF gtkwave configure 3.3.66 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_cxx_try_compile LINENO # ---------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ( $as_echo "## ------------------------------------ ## ## Report this to bybell@rocketmail.com ## ## ------------------------------------ ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_c_compute_int LINENO EXPR VAR INCLUDES # -------------------------------------------- # Tries to find the compile-time value of EXPR in a program that includes # INCLUDES, setting VAR accordingly. Returns whether the value could be # computed ac_fn_c_compute_int () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=0 ac_mid=0 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid; break else as_fn_arith $ac_mid + 1 && ac_lo=$as_val if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) < 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=-1 ac_mid=-1 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=$ac_mid; break else as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid else as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in #(( ?*) eval "$3=\$ac_lo"; ac_retval=0 ;; '') ac_retval=1 ;; esac else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 static long int longval () { return $2; } static unsigned long int ulongval () { return $2; } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (($2) < 0) { long int i = longval (); if (i != ($2)) return 1; fprintf (f, "%ld", i); } else { unsigned long int i = ulongval (); if (i != ($2)) return 1; fprintf (f, "%lu", i); } /* Do not output a trailing newline, as this causes \r\n confusion on some platforms. */ return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : echo >>conftest.val; read $3 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 gtkwave $as_me 3.3.66, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi as_fn_append ac_header_list " stdlib.h" as_fn_append ac_header_list " unistd.h" as_fn_append ac_header_list " sys/param.h" # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu am__api_version='1.13' ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=1;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='gtkwave' VERSION='3.3.66' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' # We need awk for the "check" target. 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}' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' ac_config_headers="$ac_config_headers config.h" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 $as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } # Check whether --enable-maintainer-mode was given. if test "${enable_maintainer_mode+set}" = set; then : enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval else USE_MAINTAINER_MODE=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 $as_echo "$USE_MAINTAINER_MODE" >&6; } if test $USE_MAINTAINER_MODE = yes; then MAINTAINER_MODE_TRUE= MAINTAINER_MODE_FALSE='#' else MAINTAINER_MODE_TRUE='#' MAINTAINER_MODE_FALSE= fi MAINT=$MAINTAINER_MODE_TRUE # ------------- GCONF ------------------- # Check whether --with-gconf was given. if test "${with_gconf+set}" = set; then : withval=$with_gconf; else with_gconf=check fi # ------------- XDG ------------------- # Check whether --with-xdgdatadir was given. if test "${with_xdgdatadir+set}" = set; then : withval=$with_xdgdatadir; opt_xdgdatadir=$withval fi if test x$opt_xdgdatadir = x; then # path was not specified with --with-xdgdatadir XDGDATADIR='${datadir}' else # path WAS specified with --with-xdgdatadir XDGDATADIR="$opt_xdgdatadir" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if MIME and desktop updates should be disabled" >&5 $as_echo_n "checking if MIME and desktop updates should be disabled... " >&6; } EMIM=yes DMIM=no # Check whether --enable-mime_update was given. if test "${enable_mime_update+set}" = set; then : enableval=$enable_mime_update; if test "X$enable_mime_update" = "Xno" ; then EMIM=no DMIM=yes else EMIM=yes DMIM=no fi else EMIM=yes fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DMIM" >&5 $as_echo "$DMIM" >&6; } # Extract the first word of "update-mime-database", so it can be a program name with args. set dummy update-mime-database; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_UPDATE_MIME_DATABASE+:} false; then : $as_echo_n "(cached) " >&6 else case $UPDATE_MIME_DATABASE in [\\/]* | ?:[\\/]*) ac_cv_path_UPDATE_MIME_DATABASE="$UPDATE_MIME_DATABASE" # 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 test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_UPDATE_MIME_DATABASE="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_UPDATE_MIME_DATABASE" && ac_cv_path_UPDATE_MIME_DATABASE="no" ;; esac fi UPDATE_MIME_DATABASE=$ac_cv_path_UPDATE_MIME_DATABASE if test -n "$UPDATE_MIME_DATABASE"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $UPDATE_MIME_DATABASE" >&5 $as_echo "$UPDATE_MIME_DATABASE" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "update-desktop-database", so it can be a program name with args. set dummy update-desktop-database; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_UPDATE_DESKTOP_DATABASE+:} false; then : $as_echo_n "(cached) " >&6 else case $UPDATE_DESKTOP_DATABASE in [\\/]* | ?:[\\/]*) ac_cv_path_UPDATE_DESKTOP_DATABASE="$UPDATE_DESKTOP_DATABASE" # 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 test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_UPDATE_DESKTOP_DATABASE="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_UPDATE_DESKTOP_DATABASE" && ac_cv_path_UPDATE_DESKTOP_DATABASE="no" ;; esac fi UPDATE_DESKTOP_DATABASE=$ac_cv_path_UPDATE_DESKTOP_DATABASE if test -n "$UPDATE_DESKTOP_DATABASE"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $UPDATE_DESKTOP_DATABASE" >&5 $as_echo "$UPDATE_DESKTOP_DATABASE" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "X$DMIM" = "Xyes" ; then UPDATE_MIME_DATABASE=: UPDATE_DESKTOP_DATABASE=: fi if test x$UPDATE_MIME_DATABASE != xno -a x$UPDATE_DESKTOP_DATABASE != xno; then FDO_MIME_TRUE= FDO_MIME_FALSE='#' else FDO_MIME_TRUE='#' FDO_MIME_FALSE= fi # ------------- Set simarama base ------------------- if test "X$SIMARAMA_BASE" = "X" ; then SIMARAMA_BASE="/afs/awd/projects/simarama/releases/latest" fi # ------------- Set fsdbreader base ------------------- if test "X$FSDBREADER_HDRS" = "X" ; then FSDBREADER_HDRS="/pub/FsdbReader" fi if test "X$FSDBREADER_LIBS" = "X" ; then FSDBREADER_LIBS="/pub/FsdbReader" fi # Checks for build options # ------------- Structure Packing ------------------- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if structure packing should be enabled" >&5 $as_echo_n "checking if structure packing should be enabled... " >&6; } ESTP=no STRUCT_PACK= # Check whether --enable-struct_pack was given. if test "${enable_struct_pack+set}" = set; then : enableval=$enable_struct_pack; if test "X$enable_struct_pack" = "Xyes" ; then ESTP=yes STRUCT_PACK=-DWAVE_USE_STRUCT_PACKING fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ESTP" >&5 $as_echo "$ESTP" >&6; } # ------------- Tcl ------------------- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if Tcl usage should be disabled" >&5 $as_echo_n "checking if Tcl usage should be disabled... " >&6; } ETCL=yes DTCL=no # Check whether --enable-tcl was given. if test "${enable_tcl+set}" = set; then : enableval=$enable_tcl; if test "X$enable_tcl" = "Xno" ; then ETCL=no DTCL=yes else ETCL=yes DTCL=no fi else ETCL=yes fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DTCL" >&5 $as_echo "$DTCL" >&6; } if test "X$ETCL" = "Xyes" ; then # # Ok, lets find the tcl configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tcl # if test x"${no_tcl}" = x ; then # we reset no_tcl in case something fails here no_tcl=true # Check whether --with-tcl was given. if test "${with_tcl+set}" = set; then : withval=$with_tcl; with_tclconfig="${withval}" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl configuration" >&5 $as_echo_n "checking for Tcl configuration... " >&6; } if ${ac_cv_c_tclconfig+:} false; then : $as_echo_n "(cached) " >&6 else # First check to see if --with-tcl was specified. if test x"${with_tclconfig}" != x ; then case "${with_tclconfig}" in */tclConfig.sh ) if test -f "${with_tclconfig}"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&5 $as_echo "$as_me: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&2;} with_tclconfig="`echo "${with_tclconfig}" | sed 's!/tclConfig\.sh$!!'`" fi ;; esac if test -f "${with_tclconfig}/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd "${with_tclconfig}"; pwd)`" else as_fn_error $? "${with_tclconfig} directory doesn't contain tclConfig.sh" "$LINENO" 5 fi fi # then check for a private Tcl installation if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ../tcl \ `ls -dr ../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ../tcl[8-9].[0-9] 2>/dev/null` \ `ls -dr ../tcl[8-9].[0-9]* 2>/dev/null` \ ../../tcl \ `ls -dr ../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ../../tcl[8-9].[0-9] 2>/dev/null` \ `ls -dr ../../tcl[8-9].[0-9]* 2>/dev/null` \ ../../../tcl \ `ls -dr ../../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ../../../tcl[8-9].[0-9] 2>/dev/null` \ `ls -dr ../../../tcl[8-9].[0-9]* 2>/dev/null` ; do if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd $i/unix; pwd)`" break fi done fi # on Darwin, check in Framework installation locations if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d ~/Library/Frameworks 2>/dev/null` \ `ls -d /Library/Frameworks 2>/dev/null` \ `ls -d /Network/Library/Frameworks 2>/dev/null` \ `ls -d /System/Library/Frameworks 2>/dev/null` \ ; do if test -f "$i/Tcl.framework/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd $i/Tcl.framework; pwd)`" break fi done fi # check in a few common install locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d ${libdir} 2>/dev/null` \ `ls -d ${exec_prefix}/lib 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ `ls -d /usr/lib64 2>/dev/null` \ ; do if test -f "$i/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd $i; pwd)`" break fi done fi # check in a few other private locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ${srcdir}/../tcl \ `ls -dr ${srcdir}/../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ${srcdir}/../tcl[8-9].[0-9] 2>/dev/null` \ `ls -dr ${srcdir}/../tcl[8-9].[0-9]* 2>/dev/null` ; do if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd $i/unix; pwd)`" break fi done fi fi if test x"${ac_cv_c_tclconfig}" = x ; then TCL_BIN_DIR="# no Tcl configs found" as_fn_error $? "Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh" "$LINENO" 5 else no_tcl= TCL_BIN_DIR="${ac_cv_c_tclconfig}" { $as_echo "$as_me:${as_lineno-$LINENO}: result: found ${TCL_BIN_DIR}/tclConfig.sh" >&5 $as_echo "found ${TCL_BIN_DIR}/tclConfig.sh" >&6; } fi fi if test "X$TCL_BIN_DIR" = "X# no Tcl configs found" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Tcl not found, skipping." >&5 $as_echo "$as_me: WARNING: Tcl not found, skipping." >&2;} ETCL=no DTCL=yes else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for existence of ${TCL_BIN_DIR}/tclConfig.sh" >&5 $as_echo_n "checking for existence of ${TCL_BIN_DIR}/tclConfig.sh... " >&6; } if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: loading" >&5 $as_echo "loading" >&6; } . "${TCL_BIN_DIR}/tclConfig.sh" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: could not find ${TCL_BIN_DIR}/tclConfig.sh" >&5 $as_echo "could not find ${TCL_BIN_DIR}/tclConfig.sh" >&6; } fi # eval is required to do the TCL_DBGX substitution eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\"" eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\"" # If the TCL_BIN_DIR is the build directory (not the install directory), # then set the common variable name to the value of the build variables. # For example, the variable TCL_LIB_SPEC will be set to the value # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC # instead of TCL_BUILD_LIB_SPEC since it will work with both an # installed and uninstalled version of Tcl. if test -f "${TCL_BIN_DIR}/Makefile" ; then TCL_LIB_SPEC="${TCL_BUILD_LIB_SPEC}" TCL_STUB_LIB_SPEC="${TCL_BUILD_STUB_LIB_SPEC}" TCL_STUB_LIB_PATH="${TCL_BUILD_STUB_LIB_PATH}" elif test "`uname -s`" = "Darwin"; then # If Tcl was built as a framework, attempt to use the libraries # from the framework at the given location so that linking works # against Tcl.framework installed in an arbitrary location. case ${TCL_DEFS} in *TCL_FRAMEWORK*) if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then for i in "`cd "${TCL_BIN_DIR}"; pwd`" \ "`cd "${TCL_BIN_DIR}"/../..; pwd`"; do if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then TCL_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TCL_LIB_FILE}" break fi done fi if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then TCL_STUB_LIB_SPEC="-L`echo "${TCL_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TCL_STUB_LIB_FLAG}" TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}" fi ;; esac fi # eval is required to do the TCL_DBGX substitution eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\"" eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\"" eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\"" eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\"" if test "$TCL_MAJOR_VERSION" -lt "8" ; then as_fn_error $? "Upgrade to at least Tcl version 8.4." "$LINENO" 5 else if test "$TCL_MAJOR_VERSION" -eq "8" ; then if test "$TCL_MINOR_VERSION" -lt "4" ; then as_fn_error $? "Upgrade to at least Tcl version 8.4." "$LINENO" 5 fi fi fi fi fi if test "X$ETCL" = "Xyes" ; then # # Ok, lets find the tk configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tk # if test x"${no_tk}" = x ; then # we reset no_tk in case something fails here no_tk=true # Check whether --with-tk was given. if test "${with_tk+set}" = set; then : withval=$with_tk; with_tkconfig="${withval}" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tk configuration" >&5 $as_echo_n "checking for Tk configuration... " >&6; } if ${ac_cv_c_tkconfig+:} false; then : $as_echo_n "(cached) " >&6 else # First check to see if --with-tkconfig was specified. if test x"${with_tkconfig}" != x ; then case "${with_tkconfig}" in */tkConfig.sh ) if test -f "${with_tkconfig}"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself" >&5 $as_echo "$as_me: WARNING: --with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself" >&2;} with_tkconfig="`echo "${with_tkconfig}" | sed 's!/tkConfig\.sh$!!'`" fi ;; esac if test -f "${with_tkconfig}/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd "${with_tkconfig}"; pwd)`" else as_fn_error $? "${with_tkconfig} directory doesn't contain tkConfig.sh" "$LINENO" 5 fi fi # then check for a private Tk library if test x"${ac_cv_c_tkconfig}" = x ; then for i in \ ../tk \ `ls -dr ../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ../tk[8-9].[0-9] 2>/dev/null` \ `ls -dr ../tk[8-9].[0-9]* 2>/dev/null` \ ../../tk \ `ls -dr ../../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ../../tk[8-9].[0-9] 2>/dev/null` \ `ls -dr ../../tk[8-9].[0-9]* 2>/dev/null` \ ../../../tk \ `ls -dr ../../../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ../../../tk[8-9].[0-9] 2>/dev/null` \ `ls -dr ../../../tk[8-9].[0-9]* 2>/dev/null` ; do if test -f "$i/unix/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd $i/unix; pwd)`" break fi done fi # on Darwin, check in Framework installation locations if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then for i in `ls -d ~/Library/Frameworks 2>/dev/null` \ `ls -d /Library/Frameworks 2>/dev/null` \ `ls -d /Network/Library/Frameworks 2>/dev/null` \ `ls -d /System/Library/Frameworks 2>/dev/null` \ ; do if test -f "$i/Tk.framework/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd $i/Tk.framework; pwd)`" break fi done fi # check in a few common install locations if test x"${ac_cv_c_tkconfig}" = x ; then for i in `ls -d ${libdir} 2>/dev/null` \ `ls -d ${exec_prefix}/lib 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ `ls -d /usr/lib64 2>/dev/null` \ ; do if test -f "$i/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd $i; pwd)`" break fi done fi # check in a few other private locations if test x"${ac_cv_c_tkconfig}" = x ; then for i in \ ${srcdir}/../tk \ `ls -dr ${srcdir}/../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ `ls -dr ${srcdir}/../tk[8-9].[0-9] 2>/dev/null` \ `ls -dr ${srcdir}/../tk[8-9].[0-9]* 2>/dev/null` ; do if test -f "$i/unix/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd $i/unix; pwd)`" break fi done fi fi if test x"${ac_cv_c_tkconfig}" = x ; then TK_BIN_DIR="# no Tk configs found" as_fn_error $? "Can't find Tk configuration definitions. Use --with-tk to specify a directory containing tkConfig.sh" "$LINENO" 5 else no_tk= TK_BIN_DIR="${ac_cv_c_tkconfig}" { $as_echo "$as_me:${as_lineno-$LINENO}: result: found ${TK_BIN_DIR}/tkConfig.sh" >&5 $as_echo "found ${TK_BIN_DIR}/tkConfig.sh" >&6; } fi fi if test "X$TK_BIN_DIR" = "X# no Tk configs found" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Tk not found, skipping." >&5 $as_echo "$as_me: WARNING: Tk not found, skipping." >&2;} ETCL=no DTCL=yes else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for existence of ${TK_BIN_DIR}/tkConfig.sh" >&5 $as_echo_n "checking for existence of ${TK_BIN_DIR}/tkConfig.sh... " >&6; } if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: loading" >&5 $as_echo "loading" >&6; } . "${TK_BIN_DIR}/tkConfig.sh" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: could not find ${TK_BIN_DIR}/tkConfig.sh" >&5 $as_echo "could not find ${TK_BIN_DIR}/tkConfig.sh" >&6; } fi # eval is required to do the TK_DBGX substitution eval "TK_LIB_FILE=\"${TK_LIB_FILE}\"" eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\"" # If the TK_BIN_DIR is the build directory (not the install directory), # then set the common variable name to the value of the build variables. # For example, the variable TK_LIB_SPEC will be set to the value # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC # instead of TK_BUILD_LIB_SPEC since it will work with both an # installed and uninstalled version of Tcl. if test -f "${TK_BIN_DIR}/Makefile" ; then TK_LIB_SPEC="${TK_BUILD_LIB_SPEC}" TK_STUB_LIB_SPEC="${TK_BUILD_STUB_LIB_SPEC}" TK_STUB_LIB_PATH="${TK_BUILD_STUB_LIB_PATH}" elif test "`uname -s`" = "Darwin"; then # If Tk was built as a framework, attempt to use the libraries # from the framework at the given location so that linking works # against Tk.framework installed in an arbitrary location. case ${TK_DEFS} in *TK_FRAMEWORK*) if test -f "${TK_BIN_DIR}/${TK_LIB_FILE}"; then for i in "`cd "${TK_BIN_DIR}"; pwd`" \ "`cd "${TK_BIN_DIR}"/../..; pwd`"; do if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then TK_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TK_LIB_FILE}" break fi done fi if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then TK_STUB_LIB_SPEC="-L` echo "${TK_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TK_STUB_LIB_FLAG}" TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}" fi ;; esac fi # eval is required to do the TK_DBGX substitution eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\"" eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\"" eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\"" eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\"" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if Tcl/Tk (if present) should be stubified" >&5 $as_echo_n "checking if Tcl/Tk (if present) should be stubified... " >&6; } STUBIFY=no # Check whether --enable-stubify was given. if test "${enable_stubify+set}" = set; then : enableval=$enable_stubify; if test "X$enable_stubify" = "Xno" ; then STUBIFY=no else STUBIFY=yes fi else STUBIFY=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STUBIFY" >&5 $as_echo "$STUBIFY" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if gtk1 or gtk2 should be used" >&5 $as_echo_n "checking if gtk1 or gtk2 should be used... " >&6; } GTK1=no # Check whether --enable-gtk1 was given. if test "${enable_gtk1+set}" = set; then : enableval=$enable_gtk1; if test "X$enable_gtk1" = "Xno" ; then GTK1=no else GTK1=yes fi else GTK1=no fi if test "X$GTK1" = "Xyes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: gtk1" >&5 $as_echo "gtk1" >&6; } CPPFLAGS="$CPPFLAGS" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: gtk2" >&5 $as_echo "gtk2" >&6; } CPPFLAGS="-DWAVE_USE_GTK2 $CPPFLAGS" fi # check for "fisher price" (simvision rendering style) mode { $as_echo "$as_me:${as_lineno-$LINENO}: checking if fatlines should be used" >&5 $as_echo_n "checking if fatlines should be used... " >&6; } FLN=no # Check whether --enable-fatlines was given. if test "${enable_fatlines+set}" = set; then : enableval=$enable_fatlines; if test "X$enable_fatlines" = "Xno" ; then FLN=no else FLN=yes fi else FLN=no fi if test "X$FLN" = "Xno" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } CPPFLAGS="-DWAVE_DOUBLE_LINE_WIDTH_MODE $CPPFLAGS" fi # check for massive amounts of named markers enabled { $as_echo "$as_me:${as_lineno-$LINENO}: checking if manymarkers should be used" >&5 $as_echo_n "checking if manymarkers should be used... " >&6; } MMC=no # Check whether --enable-manymarkers was given. if test "${enable_manymarkers+set}" = set; then : enableval=$enable_manymarkers; if test "X$enable_manymarkers" = "Xno" ; then MMC=no else MMC=yes fi else MMC=no fi if test "X$MMC" = "Xno" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } CPPFLAGS="-DWAVE_MANYMARKERS_MODE $CPPFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if ae2 support should be used" >&5 $as_echo_n "checking if ae2 support should be used... " >&6; } AE2_CFLAGS= AET2_LDADD= AE2=no # Check whether --enable-ae2 was given. if test "${enable_ae2+set}" = set; then : enableval=$enable_ae2; if test "X$enable_ae2" = "Xno" ; then AE2=no else AE2=yes fi else AE2=no fi if test "X$AE2" = "Xyes" ; then as_ac_File=`$as_echo "ac_cv_file_"$SIMARAMA_BASE/libae2rw.so"" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for \"$SIMARAMA_BASE/libae2rw.so\"" >&5 $as_echo_n "checking for \"$SIMARAMA_BASE/libae2rw.so\"... " >&6; } if eval \${$as_ac_File+:} false; then : $as_echo_n "(cached) " >&6 else test "$cross_compiling" = yes && as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 if test -r ""$SIMARAMA_BASE/libae2rw.so""; then eval "$as_ac_File=yes" else eval "$as_ac_File=no" fi fi eval ac_res=\$$as_ac_File { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_File"\" = x"yes"; then : AET2_SO=yes else AET2_SO=no fi if test "X$AET2_SO" = "Xyes" ; then AET2_CFLAGS="-DAET2_IS_PRESENT -I$SIMARAMA_BASE" AET2_LDADD="$SIMARAMA_BASE/libae2rw.so" else as_ac_File=`$as_echo "ac_cv_file_"$SIMARAMA_BASE/libae2rw.a"" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for \"$SIMARAMA_BASE/libae2rw.a\"" >&5 $as_echo_n "checking for \"$SIMARAMA_BASE/libae2rw.a\"... " >&6; } if eval \${$as_ac_File+:} false; then : $as_echo_n "(cached) " >&6 else test "$cross_compiling" = yes && as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 if test -r ""$SIMARAMA_BASE/libae2rw.a""; then eval "$as_ac_File=yes" else eval "$as_ac_File=no" fi fi eval ac_res=\$$as_ac_File { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_File"\" = x"yes"; then : AET2_A=yes else AET2_A=no fi if test "X$AET2_A" = "Xyes" ; then AET2_CFLAGS="-DAET2_IS_PRESENT -I$SIMARAMA_BASE" AET2_LDADD="$SIMARAMA_BASE/libae2rw.a" else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: AET2 library not found, skipping." >&5 $as_echo "$as_me: WARNING: AET2 library not found, skipping." >&2;} fi fi as_ac_File=`$as_echo "ac_cv_file_"$SIMARAMA_BASE/libaliasdb.so"" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for \"$SIMARAMA_BASE/libaliasdb.so\"" >&5 $as_echo_n "checking for \"$SIMARAMA_BASE/libaliasdb.so\"... " >&6; } if eval \${$as_ac_File+:} false; then : $as_echo_n "(cached) " >&6 else test "$cross_compiling" = yes && as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 if test -r ""$SIMARAMA_BASE/libaliasdb.so""; then eval "$as_ac_File=yes" else eval "$as_ac_File=no" fi fi eval ac_res=\$$as_ac_File { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_File"\" = x"yes"; then : AAET2_SO=yes else AAET2_SO=no fi if test "X$AAET2_SO" = "Xyes" ; then as_ac_File=`$as_echo "ac_cv_file_"$SIMARAMA_BASE/aliasdb.h"" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for \"$SIMARAMA_BASE/aliasdb.h\"" >&5 $as_echo_n "checking for \"$SIMARAMA_BASE/aliasdb.h\"... " >&6; } if eval \${$as_ac_File+:} false; then : $as_echo_n "(cached) " >&6 else test "$cross_compiling" = yes && as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 if test -r ""$SIMARAMA_BASE/aliasdb.h""; then eval "$as_ac_File=yes" else eval "$as_ac_File=no" fi fi eval ac_res=\$$as_ac_File { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_File"\" = x"yes"; then : AAET2_SOY=yes else AAET2_SOY=no fi if test "X$AAET2_SOY" = "Xyes" ; then AET2_CFLAGS="-DAET2_ALIASDB_IS_PRESENT $AET2_CFLAGS" AET2_LDADD="$SIMARAMA_BASE/libaliasdb.so $AET2_LDADD" else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: AET2 alias header not found, skipping." >&5 $as_echo "$as_me: WARNING: AET2 alias header not found, skipping." >&2;} fi else as_ac_File=`$as_echo "ac_cv_file_"$SIMARAMA_BASE/libaliasdb.a"" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for \"$SIMARAMA_BASE/libaliasdb.a\"" >&5 $as_echo_n "checking for \"$SIMARAMA_BASE/libaliasdb.a\"... " >&6; } if eval \${$as_ac_File+:} false; then : $as_echo_n "(cached) " >&6 else test "$cross_compiling" = yes && as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 if test -r ""$SIMARAMA_BASE/libaliasdb.a""; then eval "$as_ac_File=yes" else eval "$as_ac_File=no" fi fi eval ac_res=\$$as_ac_File { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_File"\" = x"yes"; then : AET2_A=yes else AET2_A=no fi if test "X$AAET2_A" = "Xyes" ; then as_ac_File=`$as_echo "ac_cv_file_"$SIMARAMA_BASE/aliasdb.h"" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for \"$SIMARAMA_BASE/aliasdb.h\"" >&5 $as_echo_n "checking for \"$SIMARAMA_BASE/aliasdb.h\"... " >&6; } if eval \${$as_ac_File+:} false; then : $as_echo_n "(cached) " >&6 else test "$cross_compiling" = yes && as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 if test -r ""$SIMARAMA_BASE/aliasdb.h""; then eval "$as_ac_File=yes" else eval "$as_ac_File=no" fi fi eval ac_res=\$$as_ac_File { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_File"\" = x"yes"; then : AAET2_SOY=yes else AAET2_SOY=no fi if test "X$AAET2_SOY" = "Xyes" ; then AET2_CFLAGS="-DAET2_ALIASDB_IS_PRESENT $AET2_CFLAGS" AET2_LDADD="$SIMARAMA_BASE/libaliasdb.a $AET2_LDADD" else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: AET2 alias header not found, skipping." >&5 $as_echo "$as_me: WARNING: AET2 alias header not found, skipping." >&2;} fi else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: AET2 alias library not found, skipping." >&5 $as_echo "$as_me: WARNING: AET2 alias library not found, skipping." >&2;} fi fi as_ac_File=`$as_echo "ac_cv_file_"$SIMARAMA_BASE/ae2rw.h"" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for \"$SIMARAMA_BASE/ae2rw.h\"" >&5 $as_echo_n "checking for \"$SIMARAMA_BASE/ae2rw.h\"... " >&6; } if eval \${$as_ac_File+:} false; then : $as_echo_n "(cached) " >&6 else test "$cross_compiling" = yes && as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 if test -r ""$SIMARAMA_BASE/ae2rw.h""; then eval "$as_ac_File=yes" else eval "$as_ac_File=no" fi fi eval ac_res=\$$as_ac_File { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_File"\" = x"yes"; then : AET2_SOY=yes else AET2_SOY=no fi if test "X$AET2_SOY" = "Xno" ; then AET2_CFLAGS= AET2_LDADD= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: AET2 header not found, skipping." >&5 $as_echo "$as_me: WARNING: AET2 header not found, skipping." >&2;} fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if FsdbReader support should be used" >&5 $as_echo_n "checking if FsdbReader support should be used... " >&6; } FFR_CFLAGS= FSDB_LDADD= FFR=no # Check whether --enable-fsdb was given. if test "${enable_fsdb+set}" = set; then : enableval=$enable_fsdb; if test "X$enable_fsdb" = "Xno" ; then FFR=no else FFR=yes fi else FFR=no fi EXTLOAD_CFLAGS= if test "X$FFR" = "Xyes" ; then # AC_CHECK_FILE("$FSDBREADER_LIBS/libnffr.so", FSDB_SO=yes, FSDB_SO=no) # # if test "X$FSDB_SO" = "Xyes" ; then # FSDB_CFLAGS="-DFSDB_IS_PRESENT -I$FSDBREADER_HDRS" # FSDB_LDADD="$FSDBREADER_LIBS/libnffr.so" # EXTLOAD_CFLAGS="-DEXTLOAD_SUFFIX=\\\"fsdb\\\"" # else as_ac_File=`$as_echo "ac_cv_file_"$FSDBREADER_LIBS/libnffr.a"" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for \"$FSDBREADER_LIBS/libnffr.a\"" >&5 $as_echo_n "checking for \"$FSDBREADER_LIBS/libnffr.a\"... " >&6; } if eval \${$as_ac_File+:} false; then : $as_echo_n "(cached) " >&6 else test "$cross_compiling" = yes && as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 if test -r ""$FSDBREADER_LIBS/libnffr.a""; then eval "$as_ac_File=yes" else eval "$as_ac_File=no" fi fi eval ac_res=\$$as_ac_File { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_File"\" = x"yes"; then : FSDB_A=yes else FSDB_A=no fi if test "X$FSDB_A" = "Xyes" ; then FSDB_CFLAGS="-DFSDB_IS_PRESENT -I$FSDBREADER_HDRS" FSDB_LDADD="$FSDBREADER_LIBS/libnffr.a" else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: FSDB reader library not found, skipping." >&5 $as_echo "$as_me: WARNING: FSDB reader library not found, skipping." >&2;} fi # fi # AC_CHECK_FILE("$FSDBREADER_LIBS/libnsys.so", AFSDB_SO=yes, AFSDB_SO=no) # # if test "X$AFSDB_SO" = "Xyes" ; then # FSDB_CFLAGS="-DFSDB_NSYS_IS_PRESENT $FSDB_CFLAGS" # FSDB_LDADD="$FSDBREADER_LIBS/libnsys.so $FSDB_LDADD" # EXTLOAD_CFLAGS="-DEXTLOAD_SUFFIX=\\\"fsdb\\\"" # else as_ac_File=`$as_echo "ac_cv_file_"$FSDBREADER_LIBS/libnsys.a"" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for \"$FSDBREADER_LIBS/libnsys.a\"" >&5 $as_echo_n "checking for \"$FSDBREADER_LIBS/libnsys.a\"... " >&6; } if eval \${$as_ac_File+:} false; then : $as_echo_n "(cached) " >&6 else test "$cross_compiling" = yes && as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 if test -r ""$FSDBREADER_LIBS/libnsys.a""; then eval "$as_ac_File=yes" else eval "$as_ac_File=no" fi fi eval ac_res=\$$as_ac_File { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_File"\" = x"yes"; then : AFSDB_A=yes else AFSDB_A=no fi if test "X$AFSDB_A" = "Xyes" ; then FSDB_CFLAGS="-DFSDB_NSYS_IS_PRESENT $FSDB_CFLAGS" FSDB_LDADD="$FSDB_LDADD $FSDBREADER_LIBS/libnsys.a" else FSDB_CFLAGS= FSDB_LDADD= EXTLOAD_CFLAGS= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: FSDB system library not found, skipping." >&5 $as_echo "$as_me: WARNING: FSDB system library not found, skipping." >&2;} fi # fi as_ac_File=`$as_echo "ac_cv_file_"$FSDBREADER_HDRS/ffrAPI.h"" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for \"$FSDBREADER_HDRS/ffrAPI.h\"" >&5 $as_echo_n "checking for \"$FSDBREADER_HDRS/ffrAPI.h\"... " >&6; } if eval \${$as_ac_File+:} false; then : $as_echo_n "(cached) " >&6 else test "$cross_compiling" = yes && as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 if test -r ""$FSDBREADER_HDRS/ffrAPI.h""; then eval "$as_ac_File=yes" else eval "$as_ac_File=no" fi fi eval ac_res=\$$as_ac_File { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_File"\" = x"yes"; then : FSDB_SOY=yes else FSDB_SOY=no fi if test "X$FSDB_SOY" = "Xno" ; then FSDB_CFLAGS= FSDB_LDADD= EXTLOAD_CFLAGS= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: FSDB header not found, skipping." >&5 $as_echo "$as_me: WARNING: FSDB header not found, skipping." >&2;} fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Checks for programs. ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CXX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler works" >&5 $as_echo_n "checking whether the C++ compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C++ compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler default output file name" >&5 $as_echo_n "checking for C++ compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C++ compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } if ${ac_cv_cxx_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 $as_echo "$ac_cv_cxx_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if ${ac_cv_prog_cxx_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes else CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 $as_echo "$ac_cv_prog_cxx_g" >&6; } if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CXX" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CXX_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CXX_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CXX_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 $as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then am__fastdepCXX_TRUE= am__fastdepCXX_FALSE='#' else am__fastdepCXX_TRUE='#' am__fastdepCXX_FALSE= fi for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi for ac_prog in flex lex do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LEX+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LEX"; then ac_cv_prog_LEX="$LEX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LEX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LEX=$ac_cv_prog_LEX if test -n "$LEX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LEX" >&5 $as_echo "$LEX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$LEX" && break done test -n "$LEX" || LEX=":" if test "x$LEX" != "x:"; then cat >conftest.l <<_ACEOF %% a { ECHO; } b { REJECT; } c { yymore (); } d { yyless (1); } e { /* IRIX 6.5 flex 2.5.4 underquotes its yyless argument. */ yyless ((input () != 0)); } f { unput (yytext[0]); } . { BEGIN INITIAL; } %% #ifdef YYTEXT_POINTER extern char *yytext; #endif int main (void) { return ! yylex () + ! yywrap (); } _ACEOF { { ac_try="$LEX conftest.l" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$LEX conftest.l") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking lex output file root" >&5 $as_echo_n "checking lex output file root... " >&6; } if ${ac_cv_prog_lex_root+:} false; then : $as_echo_n "(cached) " >&6 else if test -f lex.yy.c; then ac_cv_prog_lex_root=lex.yy elif test -f lexyy.c; then ac_cv_prog_lex_root=lexyy else as_fn_error $? "cannot find output from $LEX; giving up" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_root" >&5 $as_echo "$ac_cv_prog_lex_root" >&6; } LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root if test -z "${LEXLIB+set}"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking lex library" >&5 $as_echo_n "checking lex library... " >&6; } if ${ac_cv_lib_lex+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_LIBS=$LIBS ac_cv_lib_lex='none needed' for ac_lib in '' -lfl -ll; do LIBS="$ac_lib $ac_save_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ `cat $LEX_OUTPUT_ROOT.c` _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_lex=$ac_lib fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext test "$ac_cv_lib_lex" != 'none needed' && break done LIBS=$ac_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lex" >&5 $as_echo "$ac_cv_lib_lex" >&6; } test "$ac_cv_lib_lex" != 'none needed' && LEXLIB=$ac_cv_lib_lex fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether yytext is a pointer" >&5 $as_echo_n "checking whether yytext is a pointer... " >&6; } if ${ac_cv_prog_lex_yytext_pointer+:} false; then : $as_echo_n "(cached) " >&6 else # POSIX says lex can declare yytext either as a pointer or an array; the # default is implementation-dependent. Figure out which it is, since # not all implementations provide the %pointer and %array declarations. ac_cv_prog_lex_yytext_pointer=no ac_save_LIBS=$LIBS LIBS="$LEXLIB $ac_save_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define YYTEXT_POINTER 1 `cat $LEX_OUTPUT_ROOT.c` _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_prog_lex_yytext_pointer=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_yytext_pointer" >&5 $as_echo "$ac_cv_prog_lex_yytext_pointer" >&6; } if test $ac_cv_prog_lex_yytext_pointer = yes; then $as_echo "#define YYTEXT_POINTER 1" >>confdefs.h fi rm -f conftest.l $LEX_OUTPUT_ROOT.c fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi if test "x$CC" != xcc; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5 $as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5 $as_echo_n "checking whether cc understands -c and -o together... " >&6; } fi set dummy $CC; ac_cc=`$as_echo "$2" | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` if eval \${ac_cv_prog_cc_${ac_cc}_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # We do the test twice because some compilers refuse to overwrite an # existing .o file with -o, though they will create one. ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5' rm -f conftest2.* if { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -f conftest2.$ac_objext && { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then eval ac_cv_prog_cc_${ac_cc}_c_o=yes if test "x$CC" != xcc; then # Test first that cc exists at all. if { ac_try='cc -c conftest.$ac_ext >&5' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5' rm -f conftest2.* if { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -f conftest2.$ac_objext && { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # cc works too. : else # cc exists but doesn't like -o. eval ac_cv_prog_cc_${ac_cc}_c_o=no fi fi fi else eval ac_cv_prog_cc_${ac_cc}_c_o=no fi rm -f core conftest* fi if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h fi # FIXME: we rely on the cache variable name because # there is no other way. set dummy $CC am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o if test "$am_t" != 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 # # for "Open Hierarchy Source" # # Extract the first word of "gedit", so it can be a program name with args. set dummy gedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_GEDITTEST+:} false; then : $as_echo_n "(cached) " >&6 else case $GEDITTEST in [\\/]* | ?:[\\/]*) ac_cv_path_GEDITTEST="$GEDITTEST" # 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 test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_GEDITTEST="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_GEDITTEST" && ac_cv_path_GEDITTEST="notfound" ;; esac fi GEDITTEST=$ac_cv_path_GEDITTEST if test -n "$GEDITTEST"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GEDITTEST" >&5 $as_echo "$GEDITTEST" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$GEDITTEST" = "notfound" ; then GEDIT_CFLAGS= else GEDIT_CFLAGS="-DGEDIT_PATH=\\\"$GEDITTEST\\\"" fi # # only needed if user wishes to process various files with an external reader # # Extract the first word of "fsdbdebug", so it can be a program name with args. set dummy fsdbdebug; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_EXTDEBUG+:} false; then : $as_echo_n "(cached) " >&6 else case $EXTDEBUG in [\\/]* | ?:[\\/]*) ac_cv_path_EXTDEBUG="$EXTDEBUG" # 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 test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_EXTDEBUG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_EXTDEBUG" && ac_cv_path_EXTDEBUG="notfound" ;; esac fi EXTDEBUG=$ac_cv_path_EXTDEBUG if test -n "$EXTDEBUG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $EXTDEBUG" >&5 $as_echo "$EXTDEBUG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$EXTDEBUG" = "notfound" ; then EXTLOAD_CFLAGS="$EXTLOAD_CFLAGS" else EXTLOAD_CFLAGS="-DEXTLOAD_PATH=\\\"$EXTDEBUG\\\" -DEXTLOAD_SUFFIX=\\\"fsdb\\\"" fi # enables .fsdb as input filetype in vcd2fst, and also gtkwave -o # Extract the first word of "fsdb2vcd", so it can be a program name with args. set dummy fsdb2vcd; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_EXTDEBUG2+:} false; then : $as_echo_n "(cached) " >&6 else case $EXTDEBUG2 in [\\/]* | ?:[\\/]*) ac_cv_path_EXTDEBUG2="$EXTDEBUG2" # 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 test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_EXTDEBUG2="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_EXTDEBUG2" && ac_cv_path_EXTDEBUG2="notfound" ;; esac fi EXTDEBUG2=$ac_cv_path_EXTDEBUG2 if test -n "$EXTDEBUG2"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $EXTDEBUG2" >&5 $as_echo "$EXTDEBUG2" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$EXTDEBUG2" != "notfound" ; then EXTLOAD_CFLAGS="$EXTLOAD_CFLAGS -DEXTCONV_PATH=\\\"$EXTDEBUG2\\\"" fi # enables .vpd as input filetype in vcd2fst, and also gtkwave -o # Extract the first word of "vpd2vcd", so it can be a program name with args. set dummy vpd2vcd; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_EXTDEBUG3+:} false; then : $as_echo_n "(cached) " >&6 else case $EXTDEBUG3 in [\\/]* | ?:[\\/]*) ac_cv_path_EXTDEBUG3="$EXTDEBUG3" # 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 test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_EXTDEBUG3="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_EXTDEBUG3" && ac_cv_path_EXTDEBUG3="notfound" ;; esac fi EXTDEBUG3=$ac_cv_path_EXTDEBUG3 if test -n "$EXTDEBUG3"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $EXTDEBUG3" >&5 $as_echo "$EXTDEBUG3" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$EXTDEBUG3" != "notfound" ; then EXTLOAD_CFLAGS="$EXTLOAD_CFLAGS -DEXT2CONV_PATH=\\\"$EXTDEBUG3\\\" -DEXT2LOAD_SUFFIX=\\\"vpd\\\"" fi # enables .wlf as input filetype in vcd2fst, and also gtkwave -o # Extract the first word of "wlf2vcd", so it can be a program name with args. set dummy wlf2vcd; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_EXTDEBUG4+:} false; then : $as_echo_n "(cached) " >&6 else case $EXTDEBUG4 in [\\/]* | ?:[\\/]*) ac_cv_path_EXTDEBUG4="$EXTDEBUG4" # 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 test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_EXTDEBUG4="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_EXTDEBUG4" && ac_cv_path_EXTDEBUG4="notfound" ;; esac fi EXTDEBUG4=$ac_cv_path_EXTDEBUG4 if test -n "$EXTDEBUG4"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $EXTDEBUG4" >&5 $as_echo "$EXTDEBUG4" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$EXTDEBUG4" != "notfound" ; then EXTLOAD_CFLAGS="$EXTLOAD_CFLAGS -DEXT3CONV_PATH=\\\"$EXTDEBUG4\\\" -DEXT3LOAD_SUFFIX=\\\"wlf\\\"" fi # # gperf only needed if the user updates the gperf data # files which only developers will be doing... # # Extract the first word of "gperf", so it can be a program name with args. set dummy gperf; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_GPERF+:} false; then : $as_echo_n "(cached) " >&6 else case $GPERF in [\\/]* | ?:[\\/]*) ac_cv_path_GPERF="$GPERF" # 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 test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_GPERF="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_GPERF" && ac_cv_path_GPERF="notfound" ;; esac fi GPERF=$ac_cv_path_GPERF if test -n "$GPERF"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GPERF" >&5 $as_echo "$GPERF" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$GPERF" = "notfound" ; then as_fn_error $? "Couldn't find a usable gperf program. Please install gperf which is available from ftp://ftp.gnu.org/pub/gnu/gperf/ " "$LINENO" 5 fi # Checks for libraries. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBDL 1 _ACEOF LIBS="-ldl $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqrt in -lm" >&5 $as_echo_n "checking for sqrt in -lm... " >&6; } if ${ac_cv_lib_m_sqrt+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-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. */ #ifdef __cplusplus extern "C" #endif char sqrt (); int main () { return sqrt (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_sqrt=yes else ac_cv_lib_m_sqrt=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_sqrt" >&5 $as_echo "$ac_cv_lib_m_sqrt" >&6; } if test "x$ac_cv_lib_m_sqrt" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lpthread" >&5 $as_echo_n "checking for main in -lpthread... " >&6; } if ${ac_cv_lib_pthread_main+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pthread_main=yes else ac_cv_lib_pthread_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_main" >&5 $as_echo "$ac_cv_lib_pthread_main" >&6; } if test "x$ac_cv_lib_pthread_main" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBPTHREAD 1 _ACEOF LIBS="-lpthread $LIBS" fi # included or system libz and libbz2. By default, we search for the # system libz and libbz2. If not found, build the included ones. # The --enable-local-libz and --enable-local_libbz2 arguments can be # used to force the use of the included libs. --disable-local-libz # and --disable-local-libbz2 can be used to force the use of system # libs # Check whether --enable-local-libz was given. if test "${enable_local_libz+set}" = set; then : enableval=$enable_local_libz; if test "X$enable_local_libz" = "Xno" ; then force_system_libz=yes else force_bundled_libz=yes fi fi need_libz=no LIBZ_LDADD= LIBZ_CFLAGS= if test "X$force_bundled_libz" != "Xyes" ; then cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { gzdopen(0,"rb"); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else need_libz=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test "$need_libz" = "yes" -a "X$force_system_libz" = "Xyes" ; then as_fn_error $? " You have disabled building the bundled libz but no system libz headers could be found. Either allow building the bundled libz (by not using --disable-local-libz) or make sure your system has a libz installed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gzread in -lz" >&5 $as_echo_n "checking for gzread in -lz... " >&6; } if ${ac_cv_lib_z_gzread+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lz $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gzread (); int main () { return gzread (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_z_gzread=yes else ac_cv_lib_z_gzread=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_gzread" >&5 $as_echo "$ac_cv_lib_z_gzread" >&6; } if test "x$ac_cv_lib_z_gzread" = xyes; then : LIBZ_LDADD=-lz else need_libz=yes fi if test "$need_libz" = "yes" -a "X$force_system_libz" = "Xyes" ; then as_fn_error $? " You have disabled building the bundled libz but no system libz could be found. Either allow building the bundled libz (by not using --disable-local-libz) or make sure your system has a libz installed" "$LINENO" 5 fi else need_libz=yes fi # Check whether --enable-local-libbz2 was given. if test "${enable_local_libbz2+set}" = set; then : enableval=$enable_local_libbz2; if test "X$enable_local_libbz2" = "Xno" ; then force_system_libbz2=yes else force_bundled_libbz2=yes fi fi need_libbz2=no LIBBZ2_LDADD= LIBBZ2_CFLAGS= if test "X$force_bundled_libbz2" != "Xyes" ; then cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { BZ2_bzdopen(0,"rb"); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else need_libbz2=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test "$need_libbz2" = "yes" -a "X$force_system_libbz2" = "Xyes" ; then as_fn_error $? " You have disabled building the bundled libbz2 but no system libbz2 headers could be found. Either allow building the bundled libbz2 (by not using --disable-local-libbz2) or make sure your system has a libbz2 installed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BZ2_bzread in -lbz2" >&5 $as_echo_n "checking for BZ2_bzread in -lbz2... " >&6; } if ${ac_cv_lib_bz2_BZ2_bzread+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lbz2 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char BZ2_bzread (); int main () { return BZ2_bzread (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_bz2_BZ2_bzread=yes else ac_cv_lib_bz2_BZ2_bzread=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bz2_BZ2_bzread" >&5 $as_echo "$ac_cv_lib_bz2_BZ2_bzread" >&6; } if test "x$ac_cv_lib_bz2_BZ2_bzread" = xyes; then : LIBBZ2_LDADD=-lbz2 else need_libbz2=yes fi if test "$need_libbz2" = "yes" -a "X$force_system_libbz2" = "Xyes" ; then as_fn_error $? " You have disabled building the bundled libbz2 but no system libbz2 could be found. Either allow building the bundled libbz2 (by not using --disable-local-libbz2) or make sure your system has a libbz2 installed" "$LINENO" 5 fi else need_libbz2=yes fi LIBZ_DIR= if test "$need_libz" = "yes" ; then LIBZ_CFLAGS='-I$(top_srcdir)/src/libz' LIBZ_LDADD='$(top_builddir)/src/libz/libz.a' LIBZ_DIR=libz fi LIBBZ2_DIR= if test "$need_libbz2" = "yes" ; then LIBBZ2_CFLAGS='-I$(top_srcdir)/src/libbz2' LIBBZ2_LDADD='$(top_builddir)/src/libbz2/libbz2.a' LIBBZ2_DIR=libbz2 fi # ------------- LZMA / XZ ------------------- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if XZ should be enabled" >&5 $as_echo_n "checking if XZ should be enabled... " >&6; } EXZ=yes # Check whether --enable-xz was given. if test "${enable_xz+set}" = set; then : enableval=$enable_xz; if test "X$enable_xz" = "Xno" ; then EXZ=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $EXZ" >&5 $as_echo "$EXZ" >&6; } LIBXZ_LDADD= LIBXZ_CFLAGS= if test "X$EXZ" == "Xyes"; then have_liblzma=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { lzma_end(NULL); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else have_liblzma=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lzma_end in -llzma" >&5 $as_echo_n "checking for lzma_end in -llzma... " >&6; } if ${ac_cv_lib_lzma_lzma_end+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-llzma $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char lzma_end (); int main () { return lzma_end (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_lzma_lzma_end=yes else ac_cv_lib_lzma_lzma_end=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lzma_lzma_end" >&5 $as_echo "$ac_cv_lib_lzma_lzma_end" >&6; } if test "x$ac_cv_lib_lzma_lzma_end" = xyes; then : LIBLZMA_LDADD=-llzma else have_liblzma=yes fi if test "$have_liblzma" = "yes" ; then as_fn_error $? "LZMA support for VZT is enabled, but xz could not be found. Please install the xz-devel package, see the http://tukaani.org/xz website, or use the --disable-xz flag." "$LINENO" 5 fi LIBXZ_LDADD='-llzma' LIBXZ_CFLAGS='-D_WAVE_HAVE_XZ' fi # ------------- Fast Tree ------------------- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if Fast SST Tree should be enabled" >&5 $as_echo_n "checking if Fast SST Tree should be enabled... " >&6; } FASTTREE=yes # Check whether --enable-fasttree was given. if test "${enable_fasttree+set}" = set; then : enableval=$enable_fasttree; if test "X$enable_fasttree" = "Xno" ; then FASTTREE=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FASTTREE" >&5 $as_echo "$FASTTREE" >&6; } FASTTREE_CFLAGS= if test "X$FASTTREE" == "Xno"; then FASTTREE_CFLAGS='-DWAVE_DISABLE_FAST_TREE' fi # ------------- Judy ------------------- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if Judy array support should be enabled" >&5 $as_echo_n "checking if Judy array support should be enabled... " >&6; } EJUDY=no # Check whether --enable-judy was given. if test "${enable_judy+set}" = set; then : enableval=$enable_judy; if test "X$enable_judy" = "Xno" ; then EJUDY=no else EJUDY=yes fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $EJUDY" >&5 $as_echo "$EJUDY" >&6; } LIBJUDY_LDADD= LIBJUDY_CFLAGS= if test "X$EJUDY" == "Xyes"; then have_libjudy=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { JudySLIns (NULL, NULL, NULL); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else have_libjudy=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for JudySLIns in -lJudy" >&5 $as_echo_n "checking for JudySLIns in -lJudy... " >&6; } if ${ac_cv_lib_Judy_JudySLIns+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lJudy $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char JudySLIns (); int main () { return JudySLIns (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_Judy_JudySLIns=yes else ac_cv_lib_Judy_JudySLIns=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Judy_JudySLIns" >&5 $as_echo "$ac_cv_lib_Judy_JudySLIns" >&6; } if test "x$ac_cv_lib_Judy_JudySLIns" = xyes; then : LIBJUDY_LDADD=-lJudy else have_libjudy=yes fi if test "$have_libjudy" = "yes" ; then as_fn_error $? "Judy support is enabled, but could not be found. Please install Judy, see the http://judy.sourceforge.net website or use the --disable-judy flag." "$LINENO" 5 fi LIBJUDY_LDADD='-lJudy' LIBJUDY_CFLAGS='-D_WAVE_HAVE_JUDY' fi # ------------- GTK ------------------- if test "X$GTK1" = "Xyes" ; then # Extract the first word of "gtk-config", so it can be a program name with args. set dummy gtk-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_GTK_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $GTK_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_GTK_CONFIG="$GTK_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 test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_GTK_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_GTK_CONFIG" && ac_cv_path_GTK_CONFIG="notfound" ;; esac fi GTK_CONFIG=$ac_cv_path_GTK_CONFIG if test -n "$GTK_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GTK_CONFIG" >&5 $as_echo "$GTK_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$GTK_CONFIG" = "notfound"; then as_fn_error $? "You must have gtk installed on your system" "$LINENO" 5 else { $as_echo "$as_me:${as_lineno-$LINENO}: checking gtk1 version" >&5 $as_echo_n "checking gtk1 version... " >&6; } GTK_VER=`$GTK_CONFIG --version` { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GTK_VER" >&5 $as_echo "$GTK_VER" >&6; } case $GTK_VER in 1.2.* ) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gtk1 CFLAGS" >&5 $as_echo_n "checking for gtk1 CFLAGS... " >&6; } GTK_CFLAGS=`$GTK_CONFIG --cflags` { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GTK_CFLAGS" >&5 $as_echo "$GTK_CFLAGS" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gtk1 libs" >&5 $as_echo_n "checking for gtk1 libs... " >&6; } GTK_LIBS=`$GTK_CONFIG --libs` { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GTK_LIBS" >&5 $as_echo "$GTK_LIBS" >&6; } ;; * ) as_fn_error $? "when building with gtk1, you need version 1.2.*" "$LINENO" 5 ;; esac fi else 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else 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 test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 $as_echo "$PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else 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 test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG if test -n "$ac_pt_PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 $as_echo "$ac_pt_PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_PKG_CONFIG" = x; then PKG_CONFIG="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac 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 { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 $as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } PKG_CONFIG="" fi fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTK" >&5 $as_echo_n "checking for GTK... " >&6; } if test -n "$GTK_CFLAGS"; then pkg_cv_GTK_CFLAGS="$GTK_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-2.0 >= 2.2.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "gtk+-2.0 >= 2.2.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GTK_CFLAGS=`$PKG_CONFIG --cflags "gtk+-2.0 >= 2.2.0" 2>/dev/null` else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$GTK_LIBS"; then pkg_cv_GTK_LIBS="$GTK_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-2.0 >= 2.2.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "gtk+-2.0 >= 2.2.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GTK_LIBS=`$PKG_CONFIG --libs "gtk+-2.0 >= 2.2.0" 2>/dev/null` else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then 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 GTK_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "gtk+-2.0 >= 2.2.0" 2>&1` else GTK_PKG_ERRORS=`$PKG_CONFIG --print-errors "gtk+-2.0 >= 2.2.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$GTK_PKG_ERRORS" >&5 as_fn_error $? "Package requirements (gtk+-2.0 >= 2.2.0) were not met: $GTK_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables GTK_CFLAGS and GTK_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. " "$LINENO" 5 elif test $pkg_failed = untried; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "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. Alternatively, you may set the environment variables GTK_CFLAGS and GTK_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else GTK_CFLAGS=$pkg_cv_GTK_CFLAGS GTK_LIBS=$pkg_cv_GTK_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } : fi GTK_VER=`$PKG_CONFIG gtk+-2.0 --modversion` _gdk_tgt=`$PKG_CONFIG --variable=target gdk-2.0` # removed...causes problems with gtk-1.2... # AM_CONDITIONAL([GDK_TARGET_QUARTZ], [test x$_gdk_tgt = xquartz]) if test "x$_gdk_tgt" = xquartz; then pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTK_MAC" >&5 $as_echo_n "checking for GTK_MAC... " >&6; } if test -n "$GTK_MAC_CFLAGS"; then pkg_cv_GTK_MAC_CFLAGS="$GTK_MAC_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk-mac-integration >= 2.0.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "gtk-mac-integration >= 2.0.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GTK_MAC_CFLAGS=`$PKG_CONFIG --cflags "gtk-mac-integration >= 2.0.0" 2>/dev/null` else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$GTK_MAC_LIBS"; then pkg_cv_GTK_MAC_LIBS="$GTK_MAC_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk-mac-integration >= 2.0.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "gtk-mac-integration >= 2.0.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GTK_MAC_LIBS=`$PKG_CONFIG --libs "gtk-mac-integration >= 2.0.0" 2>/dev/null` else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then 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 GTK_MAC_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "gtk-mac-integration >= 2.0.0" 2>&1` else GTK_MAC_PKG_ERRORS=`$PKG_CONFIG --print-errors "gtk-mac-integration >= 2.0.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$GTK_MAC_PKG_ERRORS" >&5 as_fn_error $? "Package requirements (gtk-mac-integration >= 2.0.0) were not met: $GTK_MAC_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables GTK_MAC_CFLAGS and GTK_MAC_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. " "$LINENO" 5 elif test $pkg_failed = untried; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "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. Alternatively, you may set the environment variables GTK_MAC_CFLAGS and GTK_MAC_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else GTK_MAC_CFLAGS=$pkg_cv_GTK_MAC_CFLAGS GTK_MAC_LIBS=$pkg_cv_GTK_MAC_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } : fi COCOA_GTK_CFLAGS="-xobjective-c -DWAVE_COCOA_GTK" COCOA_GTK_LDADD="-lobjc" COCOA_GTK_LDFLAGS="-framework Cocoa -framework ApplicationServices" fi if test x$with_gconf = xyes; then pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCONF" >&5 $as_echo_n "checking for GCONF... " >&6; } if test -n "$GCONF_CFLAGS"; then pkg_cv_GCONF_CFLAGS="$GCONF_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gconf-2.0 >= 2.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "gconf-2.0 >= 2.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GCONF_CFLAGS=`$PKG_CONFIG --cflags "gconf-2.0 >= 2.0" 2>/dev/null` else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$GCONF_LIBS"; then pkg_cv_GCONF_LIBS="$GCONF_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gconf-2.0 >= 2.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "gconf-2.0 >= 2.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GCONF_LIBS=`$PKG_CONFIG --libs "gconf-2.0 >= 2.0" 2>/dev/null` else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then 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 GCONF_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "gconf-2.0 >= 2.0" 2>&1` else GCONF_PKG_ERRORS=`$PKG_CONFIG --print-errors "gconf-2.0 >= 2.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$GCONF_PKG_ERRORS" >&5 as_fn_error $? "Package requirements (gconf-2.0 >= 2.0) were not met: $GCONF_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables GCONF_CFLAGS and GCONF_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. " "$LINENO" 5 elif test $pkg_failed = untried; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "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. Alternatively, you may set the environment variables GCONF_CFLAGS and GCONF_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else GCONF_CFLAGS=$pkg_cv_GCONF_CFLAGS GCONF_LIBS=$pkg_cv_GCONF_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } : fi GCONF_CFLAGS="-DWAVE_HAVE_GCONF $GCONF_CFLAGS" fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTK_UNIX_PRINT" >&5 $as_echo_n "checking for GTK_UNIX_PRINT... " >&6; } if test -n "$GTK_UNIX_PRINT_CFLAGS"; then pkg_cv_GTK_UNIX_PRINT_CFLAGS="$GTK_UNIX_PRINT_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-unix-print-2.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "gtk+-unix-print-2.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GTK_UNIX_PRINT_CFLAGS=`$PKG_CONFIG --cflags "gtk+-unix-print-2.0" 2>/dev/null` else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$GTK_UNIX_PRINT_LIBS"; then pkg_cv_GTK_UNIX_PRINT_LIBS="$GTK_UNIX_PRINT_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gtk+-unix-print-2.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "gtk+-unix-print-2.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GTK_UNIX_PRINT_LIBS=`$PKG_CONFIG --libs "gtk+-unix-print-2.0" 2>/dev/null` else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then 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 GTK_UNIX_PRINT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "gtk+-unix-print-2.0" 2>&1` else GTK_UNIX_PRINT_PKG_ERRORS=`$PKG_CONFIG --print-errors "gtk+-unix-print-2.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$GTK_UNIX_PRINT_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } GUP_F="no" elif test $pkg_failed = untried; then GUP_F="no" else GTK_UNIX_PRINT_CFLAGS=$pkg_cv_GTK_UNIX_PRINT_CFLAGS GTK_UNIX_PRINT_LIBS=$pkg_cv_GTK_UNIX_PRINT_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } GUP_F="yes" fi if test "x$GUP_F" = xyes; then GTK_UNIX_PRINT_CFLAGS="${GTK_UNIX_PRINT_CFLAGS} -DWAVE_GTK_UNIX_PRINT" fi fi # Checks for header files. ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5 $as_echo_n "checking for working alloca.h... " >&6; } if ${ac_cv_working_alloca_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { char *p = (char *) alloca (2 * sizeof (int)); if (p) return 0; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_working_alloca_h=yes else ac_cv_working_alloca_h=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5 $as_echo "$ac_cv_working_alloca_h" >&6; } if test $ac_cv_working_alloca_h = yes; then $as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5 $as_echo_n "checking for alloca... " >&6; } if ${ac_cv_func_alloca_works+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __GNUC__ # define alloca __builtin_alloca #else # ifdef _MSC_VER # include # define alloca _alloca # else # ifdef HAVE_ALLOCA_H # include # else # ifdef _AIX #pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ void *alloca (size_t); # endif # endif # endif # endif #endif int main () { char *p = (char *) alloca (1); if (p) return 0; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_func_alloca_works=yes else ac_cv_func_alloca_works=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5 $as_echo "$ac_cv_func_alloca_works" >&6; } if test $ac_cv_func_alloca_works = yes; then $as_echo "#define HAVE_ALLOCA 1" >>confdefs.h else # The SVR3 libPW and SVR4 libucb both contain incompatible functions # that cause trouble. Some versions do not even contain alloca or # contain a buggy version. If you still want to use their alloca, # use ar to extract alloca.o from them instead of compiling alloca.c. ALLOCA=\${LIBOBJDIR}alloca.$ac_objext $as_echo "#define C_ALLOCA 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5 $as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; } if ${ac_cv_os_cray+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if defined CRAY && ! defined CRAY2 webecray #else wenotbecray #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "webecray" >/dev/null 2>&1; then : ac_cv_os_cray=yes else ac_cv_os_cray=no fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5 $as_echo "$ac_cv_os_cray" >&6; } if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define CRAY_STACKSEG_END $ac_func _ACEOF break fi done fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5 $as_echo_n "checking stack direction for C alloca... " >&6; } if ${ac_cv_c_stack_direction+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_c_stack_direction=0 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int find_stack_direction (int *addr, int depth) { int dir, dummy = 0; if (! addr) addr = &dummy; *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1; dir = depth ? find_stack_direction (addr, depth - 1) : 0; return dir + dummy; } int main (int argc, char **argv) { return find_stack_direction (0, argc + !argv + 20) < 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_c_stack_direction=1 else ac_cv_c_stack_direction=-1 fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5 $as_echo "$ac_cv_c_stack_direction" >&6; } cat >>confdefs.h <<_ACEOF #define STACK_DIRECTION $ac_cv_c_stack_direction _ACEOF fi ac_header_dirent=no for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5 $as_echo_n "checking for $ac_hdr that defines DIR... " >&6; } if eval \${$as_ac_Header+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include <$ac_hdr> int main () { if ((DIR *) 0) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$as_ac_Header=yes" else eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$as_ac_Header { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 _ACEOF ac_header_dirent=$ac_hdr; break fi done # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. if test $ac_header_dirent = dirent.h; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 $as_echo_n "checking for library containing opendir... " >&6; } if ${ac_cv_search_opendir+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char opendir (); int main () { return opendir (); ; return 0; } _ACEOF for ac_lib in '' dir; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_opendir=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_opendir+:} false; then : break fi done if ${ac_cv_search_opendir+:} false; then : else ac_cv_search_opendir=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 $as_echo "$ac_cv_search_opendir" >&6; } ac_res=$ac_cv_search_opendir if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 $as_echo_n "checking for library containing opendir... " >&6; } if ${ac_cv_search_opendir+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char opendir (); int main () { return opendir (); ; return 0; } _ACEOF for ac_lib in '' x; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_opendir=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_opendir+:} false; then : break fi done if ${ac_cv_search_opendir+:} false; then : else ac_cv_search_opendir=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 $as_echo "$ac_cv_search_opendir" >&6; } ac_res=$ac_cv_search_opendir if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5 $as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " >&6; } if ${ac_cv_header_sys_wait_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #ifndef WEXITSTATUS # define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8) #endif #ifndef WIFEXITED # define WIFEXITED(stat_val) (((stat_val) & 255) == 0) #endif int main () { int s; wait (&s); s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_sys_wait_h=yes else ac_cv_header_sys_wait_h=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_wait_h" >&5 $as_echo "$ac_cv_header_sys_wait_h" >&6; } if test $ac_cv_header_sys_wait_h = yes; then $as_echo "#define HAVE_SYS_WAIT_H 1" >>confdefs.h fi for ac_header in fcntl.h inttypes.h libintl.h limits.h malloc.h stddef.h stdint.h stdlib.h string.h strings.h sys/time.h unistd.h wchar.h wctype.h getopt.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # rpc workaround for cygwin for ac_header in rpc/types.h rpc/xdr.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "#ifdef HAVE_RPC_TYPES_H # include #endif " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done # Checks for operand sizes. # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of void *" >&5 $as_echo_n "checking size of void *... " >&6; } if ${ac_cv_sizeof_void_p+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void *))" "ac_cv_sizeof_void_p" "$ac_includes_default"; then : else if test "$ac_cv_type_void_p" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (void *) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_void_p=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_void_p" >&5 $as_echo "$ac_cv_sizeof_void_p" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_VOID_P $ac_cv_sizeof_void_p _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of double" >&5 $as_echo_n "checking size of double... " >&6; } if ${ac_cv_sizeof_double+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (double))" "ac_cv_sizeof_double" "$ac_includes_default"; then : else if test "$ac_cv_type_double" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (double) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_double=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_double" >&5 $as_echo "$ac_cv_sizeof_double" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_DOUBLE $ac_cv_sizeof_double _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 $as_echo_n "checking size of long... " >&6; } if ${ac_cv_sizeof_long+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then : else if test "$ac_cv_type_long" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (long) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_long=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 $as_echo "$ac_cv_sizeof_long" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG $ac_cv_sizeof_long _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5 $as_echo_n "checking size of int... " >&6; } if ${ac_cv_sizeof_int+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default"; then : else if test "$ac_cv_type_int" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (int) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_int=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5 $as_echo "$ac_cv_sizeof_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_INT $ac_cv_sizeof_int _ACEOF # Checks for typedefs, structures, and compiler characteristics. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if ${ac_cv_c_const+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __cplusplus /* Ultrix mips cc rejects this sort of thing. */ typedef int charset[2]; const charset cs = { 0, 0 }; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this sort of thing. */ char tx; char *t = &tx; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; } bx; struct s *b = &bx; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5 $as_echo_n "checking for stdbool.h that conforms to C99... " >&6; } if ${ac_cv_header_stdbool_h+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #ifndef bool "error: bool is not defined" #endif #ifndef false "error: false is not defined" #endif #if false "error: false is not 0" #endif #ifndef true "error: true is not defined" #endif #if true != 1 "error: true is not 1" #endif #ifndef __bool_true_false_are_defined "error: __bool_true_false_are_defined is not defined" #endif struct s { _Bool s: 1; _Bool t; } s; char a[true == 1 ? 1 : -1]; char b[false == 0 ? 1 : -1]; char c[__bool_true_false_are_defined == 1 ? 1 : -1]; char d[(bool) 0.5 == true ? 1 : -1]; /* See body of main program for 'e'. */ char f[(_Bool) 0.0 == false ? 1 : -1]; char g[true]; char h[sizeof (_Bool)]; char i[sizeof s.t]; enum { j = false, k = true, l = false * true, m = true * 256 }; /* The following fails for HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */ _Bool n[m]; char o[sizeof n == m * sizeof n[0] ? 1 : -1]; char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1]; /* Catch a bug in an HP-UX C compiler. See http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html */ _Bool q = true; _Bool *pq = &q; int main () { bool e = &s; *pq |= q; *pq |= ! q; /* Refer to every declared value, to avoid compiler optimizations. */ return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l + !m + !n + !o + !p + !q + !pq); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdbool_h=yes else ac_cv_header_stdbool_h=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5 $as_echo "$ac_cv_header_stdbool_h" >&6; } ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default" if test "x$ac_cv_type__Bool" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE__BOOL 1 _ACEOF fi if test $ac_cv_header_stdbool_h = yes; then $as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 $as_echo_n "checking for inline... " >&6; } if ${ac_cv_c_inline+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; static $ac_kw foo_t static_foo () {return 0; } $ac_kw foo_t foo () {return 0; } #endif _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_inline=$ac_kw fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_inline" != no && break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 $as_echo "$ac_cv_c_inline" >&6; } case $ac_cv_c_inline in inline | yes) ;; *) case $ac_cv_c_inline in no) ac_val=;; *) ac_val=$ac_cv_c_inline;; esac cat >>confdefs.h <<_ACEOF #ifndef __cplusplus #define inline $ac_val #endif _ACEOF ;; esac ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default" if test "x$ac_cv_type_off_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define off_t long int _ACEOF fi ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" if test "x$ac_cv_type_pid_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define pid_t int _ACEOF fi ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 $as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } if ${ac_cv_header_time+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { if ((struct tm *) 0) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_time=yes else ac_cv_header_time=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 $as_echo "$ac_cv_header_time" >&6; } if test $ac_cv_header_time = yes; then $as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5 $as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; } if ${ac_cv_struct_tm+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { struct tm tm; int *p = &tm.tm_sec; return !p; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_struct_tm=time.h else ac_cv_struct_tm=sys/time.h fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm" >&5 $as_echo "$ac_cv_struct_tm" >&6; } if test $ac_cv_struct_tm = sys/time.h; then $as_echo "#define TM_IN_SYS_TIME 1" >>confdefs.h fi ac_fn_c_check_type "$LINENO" "ptrdiff_t" "ac_cv_type_ptrdiff_t" "$ac_includes_default" if test "x$ac_cv_type_ptrdiff_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_PTRDIFF_T 1 _ACEOF fi # Check whether --enable-largefile was given. if test "${enable_largefile+set}" = set; then : enableval=$enable_largefile; fi if test "$enable_largefile" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 $as_echo_n "checking for special C compiler options needed for large files... " >&6; } if ${ac_cv_sys_largefile_CC+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_sys_largefile_CC=no if test "$GCC" != yes; then ac_save_CC=$CC while :; do # IRIX 6.2 and later do not support large files by default, # so use the C compiler's -n32 option if that helps. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : break fi rm -f core conftest.err conftest.$ac_objext CC="$CC -n32" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_largefile_CC=' -n32'; break fi rm -f core conftest.err conftest.$ac_objext break done CC=$ac_save_CC rm -f conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 $as_echo "$ac_cv_sys_largefile_CC" >&6; } if test "$ac_cv_sys_largefile_CC" != no; then CC=$CC$ac_cv_sys_largefile_CC fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 $as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } if ${ac_cv_sys_file_offset_bits+:} false; then : $as_echo_n "(cached) " >&6 else while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_file_offset_bits=no; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _FILE_OFFSET_BITS 64 #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_file_offset_bits=64; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_sys_file_offset_bits=unknown break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 $as_echo "$ac_cv_sys_file_offset_bits" >&6; } case $ac_cv_sys_file_offset_bits in #( no | unknown) ;; *) cat >>confdefs.h <<_ACEOF #define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits _ACEOF ;; esac rm -rf conftest* if test $ac_cv_sys_file_offset_bits = unknown; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 $as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; } if ${ac_cv_sys_large_files+:} false; then : $as_echo_n "(cached) " >&6 else while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_large_files=no; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _LARGE_FILES 1 #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_sys_large_files=1; break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_sys_large_files=unknown break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 $as_echo "$ac_cv_sys_large_files" >&6; } case $ac_cv_sys_large_files in #( no | unknown) ;; *) cat >>confdefs.h <<_ACEOF #define _LARGE_FILES $ac_cv_sys_large_files _ACEOF ;; esac rm -rf conftest* fi fi # Checks for library functions. (malloc/realloc removed to get rid of rpl_xxx substitutions) # AC_FUNC_MALLOC # AC_FUNC_REALLOC { $as_echo "$as_me:${as_lineno-$LINENO}: checking for error_at_line" >&5 $as_echo_n "checking for error_at_line... " >&6; } if ${ac_cv_lib_error_at_line+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { error_at_line (0, 0, "", 0, "an error occurred"); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_error_at_line=yes else ac_cv_lib_error_at_line=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_error_at_line" >&5 $as_echo "$ac_cv_lib_error_at_line" >&6; } if test $ac_cv_lib_error_at_line = no; then case " $LIBOBJS " in *" error.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS error.$ac_objext" ;; esac fi for ac_header in vfork.h do : ac_fn_c_check_header_mongrel "$LINENO" "vfork.h" "ac_cv_header_vfork_h" "$ac_includes_default" if test "x$ac_cv_header_vfork_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_VFORK_H 1 _ACEOF fi done for ac_func in fork vfork do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done if test "x$ac_cv_func_fork" = xyes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working fork" >&5 $as_echo_n "checking for working fork... " >&6; } if ${ac_cv_func_fork_works+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_func_fork_works=cross else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { /* By Ruediger Kuhlmann. */ return fork () < 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_func_fork_works=yes else ac_cv_func_fork_works=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fork_works" >&5 $as_echo "$ac_cv_func_fork_works" >&6; } else ac_cv_func_fork_works=$ac_cv_func_fork fi if test "x$ac_cv_func_fork_works" = xcross; then case $host in *-*-amigaos* | *-*-msdosdjgpp*) # Override, as these systems have only a dummy fork() stub ac_cv_func_fork_works=no ;; *) ac_cv_func_fork_works=yes ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5 $as_echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;} fi ac_cv_func_vfork_works=$ac_cv_func_vfork if test "x$ac_cv_func_vfork" = xyes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working vfork" >&5 $as_echo_n "checking for working vfork... " >&6; } if ${ac_cv_func_vfork_works+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_func_vfork_works=cross else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Thanks to Paul Eggert for this test. */ $ac_includes_default #include #ifdef HAVE_VFORK_H # include #endif /* On some sparc systems, changes by the child to local and incoming argument registers are propagated back to the parent. The compiler is told about this with #include , but some compilers (e.g. gcc -O) don't grok . Test for this by using a static variable whose address is put into a register that is clobbered by the vfork. */ static void #ifdef __cplusplus sparc_address_test (int arg) # else sparc_address_test (arg) int arg; #endif { static pid_t child; if (!child) { child = vfork (); if (child < 0) { perror ("vfork"); _exit(2); } if (!child) { arg = getpid(); write(-1, "", 0); _exit (arg); } } } int main () { pid_t parent = getpid (); pid_t child; sparc_address_test (0); child = vfork (); if (child == 0) { /* Here is another test for sparc vfork register problems. This test uses lots of local variables, at least as many local variables as main has allocated so far including compiler temporaries. 4 locals are enough for gcc 1.40.3 on a Solaris 4.1.3 sparc, but we use 8 to be safe. A buggy compiler should reuse the register of parent for one of the local variables, since it will think that parent can't possibly be used any more in this routine. Assigning to the local variable will thus munge parent in the parent process. */ pid_t p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(), p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid(); /* Convince the compiler that p..p7 are live; otherwise, it might use the same hardware register for all 8 local variables. */ if (p != p1 || p != p2 || p != p3 || p != p4 || p != p5 || p != p6 || p != p7) _exit(1); /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent from child file descriptors. If the child closes a descriptor before it execs or exits, this munges the parent's descriptor as well. Test for this by closing stdout in the child. */ _exit(close(fileno(stdout)) != 0); } else { int status; struct stat st; while (wait(&status) != child) ; return ( /* Was there some problem with vforking? */ child < 0 /* Did the child fail? (This shouldn't happen.) */ || status /* Did the vfork/compiler bug occur? */ || parent != getpid() /* Did the file descriptor bug occur? */ || fstat(fileno(stdout), &st) != 0 ); } } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_func_vfork_works=yes else ac_cv_func_vfork_works=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_vfork_works" >&5 $as_echo "$ac_cv_func_vfork_works" >&6; } fi; if test "x$ac_cv_func_fork_works" = xcross; then ac_cv_func_vfork_works=$ac_cv_func_vfork { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5 $as_echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;} fi if test "x$ac_cv_func_vfork_works" = xyes; then $as_echo "#define HAVE_WORKING_VFORK 1" >>confdefs.h else $as_echo "#define vfork fork" >>confdefs.h fi if test "x$ac_cv_func_fork_works" = xyes; then $as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGEFILE_SOURCE value needed for large files" >&5 $as_echo_n "checking for _LARGEFILE_SOURCE value needed for large files... " >&6; } if ${ac_cv_sys_largefile_source+:} false; then : $as_echo_n "(cached) " >&6 else while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include /* for off_t */ #include int main () { int (*fp) (FILE *, off_t, int) = fseeko; return fseeko (stdin, 0, 0) && fp (stdin, 0, 0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_sys_largefile_source=no; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _LARGEFILE_SOURCE 1 #include /* for off_t */ #include int main () { int (*fp) (FILE *, off_t, int) = fseeko; return fseeko (stdin, 0, 0) && fp (stdin, 0, 0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_sys_largefile_source=1; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_cv_sys_largefile_source=unknown break done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_source" >&5 $as_echo "$ac_cv_sys_largefile_source" >&6; } case $ac_cv_sys_largefile_source in #( no | unknown) ;; *) cat >>confdefs.h <<_ACEOF #define _LARGEFILE_SOURCE $ac_cv_sys_largefile_source _ACEOF ;; esac rm -rf conftest* # We used to try defining _XOPEN_SOURCE=500 too, to work around a bug # in glibc 2.1.3, but that breaks too many other things. # If you want fseeko and ftello with glibc, upgrade to a fixed glibc. if test $ac_cv_sys_largefile_source != unknown; then $as_echo "#define HAVE_FSEEKO 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working memcmp" >&5 $as_echo_n "checking for working memcmp... " >&6; } if ${ac_cv_func_memcmp_working+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_func_memcmp_working=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { /* Some versions of memcmp are not 8-bit clean. */ char c0 = '\100', c1 = '\200', c2 = '\201'; if (memcmp(&c0, &c2, 1) >= 0 || memcmp(&c1, &c2, 1) >= 0) return 1; /* The Next x86 OpenStep bug shows up only when comparing 16 bytes or more and with at least one buffer not starting on a 4-byte boundary. William Lewis provided this test program. */ { char foo[21]; char bar[21]; int i; for (i = 0; i < 4; i++) { char *a = foo + i; char *b = bar + i; strcpy (a, "--------01111111"); strcpy (b, "--------10000000"); if (memcmp (a, b, 16) >= 0) return 1; } return 0; } ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_func_memcmp_working=yes else ac_cv_func_memcmp_working=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_memcmp_working" >&5 $as_echo "$ac_cv_func_memcmp_working" >&6; } test $ac_cv_func_memcmp_working = no && case " $LIBOBJS " in *" memcmp.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS memcmp.$ac_objext" ;; esac for ac_header in $ac_header_list do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in getpagesize do : ac_fn_c_check_func "$LINENO" "getpagesize" "ac_cv_func_getpagesize" if test "x$ac_cv_func_getpagesize" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GETPAGESIZE 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working mmap" >&5 $as_echo_n "checking for working mmap... " >&6; } if ${ac_cv_func_mmap_fixed_mapped+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_func_mmap_fixed_mapped=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default /* malloc might have been renamed as rpl_malloc. */ #undef malloc /* Thanks to Mike Haertel and Jim Avera for this test. Here is a matrix of mmap possibilities: mmap private not fixed mmap private fixed at somewhere currently unmapped mmap private fixed at somewhere already mapped mmap shared not fixed mmap shared fixed at somewhere currently unmapped mmap shared fixed at somewhere already mapped For private mappings, we should verify that changes cannot be read() back from the file, nor mmap's back from the file at a different address. (There have been systems where private was not correctly implemented like the infamous i386 svr4.0, and systems where the VM page cache was not coherent with the file system buffer cache like early versions of FreeBSD and possibly contemporary NetBSD.) For shared mappings, we should conversely verify that changes get propagated back to all the places they're supposed to be. Grep wants private fixed already mapped. The main things grep needs to know about mmap are: * does it exist and is it safe to write into the mmap'd area * how to use it (BSD variants) */ #include #include #if !defined STDC_HEADERS && !defined HAVE_STDLIB_H char *malloc (); #endif /* This mess was copied from the GNU getpagesize.h. */ #ifndef HAVE_GETPAGESIZE # ifdef _SC_PAGESIZE # define getpagesize() sysconf(_SC_PAGESIZE) # else /* no _SC_PAGESIZE */ # ifdef HAVE_SYS_PARAM_H # include # ifdef EXEC_PAGESIZE # define getpagesize() EXEC_PAGESIZE # else /* no EXEC_PAGESIZE */ # ifdef NBPG # define getpagesize() NBPG * CLSIZE # ifndef CLSIZE # define CLSIZE 1 # endif /* no CLSIZE */ # else /* no NBPG */ # ifdef NBPC # define getpagesize() NBPC # else /* no NBPC */ # ifdef PAGESIZE # define getpagesize() PAGESIZE # endif /* PAGESIZE */ # endif /* no NBPC */ # endif /* no NBPG */ # endif /* no EXEC_PAGESIZE */ # else /* no HAVE_SYS_PARAM_H */ # define getpagesize() 8192 /* punt totally */ # endif /* no HAVE_SYS_PARAM_H */ # endif /* no _SC_PAGESIZE */ #endif /* no HAVE_GETPAGESIZE */ int main () { char *data, *data2, *data3; const char *cdata2; int i, pagesize; int fd, fd2; pagesize = getpagesize (); /* First, make a file with some known garbage in it. */ data = (char *) malloc (pagesize); if (!data) return 1; for (i = 0; i < pagesize; ++i) *(data + i) = rand (); umask (0); fd = creat ("conftest.mmap", 0600); if (fd < 0) return 2; if (write (fd, data, pagesize) != pagesize) return 3; close (fd); /* Next, check that the tail of a page is zero-filled. File must have non-zero length, otherwise we risk SIGBUS for entire page. */ fd2 = open ("conftest.txt", O_RDWR | O_CREAT | O_TRUNC, 0600); if (fd2 < 0) return 4; cdata2 = ""; if (write (fd2, cdata2, 1) != 1) return 5; data2 = (char *) mmap (0, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd2, 0L); if (data2 == MAP_FAILED) return 6; for (i = 0; i < pagesize; ++i) if (*(data2 + i)) return 7; close (fd2); if (munmap (data2, pagesize)) return 8; /* Next, try to mmap the file at a fixed address which already has something else allocated at it. If we can, also make sure that we see the same garbage. */ fd = open ("conftest.mmap", O_RDWR); if (fd < 0) return 9; if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fd, 0L)) return 10; for (i = 0; i < pagesize; ++i) if (*(data + i) != *(data2 + i)) return 11; /* Finally, make sure that changes to the mapped area do not percolate back to the file as seen by read(). (This is a bug on some variants of i386 svr4.0.) */ for (i = 0; i < pagesize; ++i) *(data2 + i) = *(data2 + i) + 1; data3 = (char *) malloc (pagesize); if (!data3) return 12; if (read (fd, data3, pagesize) != pagesize) return 13; for (i = 0; i < pagesize; ++i) if (*(data + i) != *(data3 + i)) return 14; close (fd); return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_func_mmap_fixed_mapped=yes else ac_cv_func_mmap_fixed_mapped=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_mmap_fixed_mapped" >&5 $as_echo "$ac_cv_func_mmap_fixed_mapped" >&6; } if test $ac_cv_func_mmap_fixed_mapped = yes; then $as_echo "#define HAVE_MMAP 1" >>confdefs.h fi rm -f conftest.mmap conftest.txt for ac_header in sys/select.h sys/socket.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking types of arguments for select" >&5 $as_echo_n "checking types of arguments for select... " >&6; } if ${ac_cv_func_select_args+:} false; then : $as_echo_n "(cached) " >&6 else for ac_arg234 in 'fd_set *' 'int *' 'void *'; do for ac_arg1 in 'int' 'size_t' 'unsigned long int' 'unsigned int'; do for ac_arg5 in 'struct timeval *' 'const struct timeval *'; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default #ifdef HAVE_SYS_SELECT_H # include #endif #ifdef HAVE_SYS_SOCKET_H # include #endif int main () { extern int select ($ac_arg1, $ac_arg234, $ac_arg234, $ac_arg234, $ac_arg5); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_func_select_args="$ac_arg1,$ac_arg234,$ac_arg5"; break 3 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done done done # Provide a safe default value. : "${ac_cv_func_select_args=int,int *,struct timeval *}" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_select_args" >&5 $as_echo "$ac_cv_func_select_args" >&6; } ac_save_IFS=$IFS; IFS=',' set dummy `echo "$ac_cv_func_select_args" | sed 's/\*/\*/g'` IFS=$ac_save_IFS shift cat >>confdefs.h <<_ACEOF #define SELECT_TYPE_ARG1 $1 _ACEOF cat >>confdefs.h <<_ACEOF #define SELECT_TYPE_ARG234 ($2) _ACEOF cat >>confdefs.h <<_ACEOF #define SELECT_TYPE_ARG5 ($3) _ACEOF rm -f conftest* if ${ac_cv_func_setvbuf_reversed+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_func_setvbuf_reversed=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether lstat correctly handles trailing slash" >&5 $as_echo_n "checking whether lstat correctly handles trailing slash... " >&6; } if ${ac_cv_func_lstat_dereferences_slashed_symlink+:} false; then : $as_echo_n "(cached) " >&6 else rm -f conftest.sym conftest.file echo >conftest.file if test "$as_ln_s" = "ln -s" && ln -s conftest.file conftest.sym; then if test "$cross_compiling" = yes; then : ac_cv_func_lstat_dereferences_slashed_symlink=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { struct stat sbuf; /* Linux will dereference the symlink and fail, as required by POSIX. That is better in the sense that it means we will not have to compile and use the lstat wrapper. */ return lstat ("conftest.sym/", &sbuf) == 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_func_lstat_dereferences_slashed_symlink=yes else ac_cv_func_lstat_dereferences_slashed_symlink=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi else # If the `ln -s' command failed, then we probably don't even # have an lstat function. ac_cv_func_lstat_dereferences_slashed_symlink=no fi rm -f conftest.sym conftest.file fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_lstat_dereferences_slashed_symlink" >&5 $as_echo "$ac_cv_func_lstat_dereferences_slashed_symlink" >&6; } test $ac_cv_func_lstat_dereferences_slashed_symlink = yes && cat >>confdefs.h <<_ACEOF #define LSTAT_FOLLOWS_SLASHED_SYMLINK 1 _ACEOF if test "x$ac_cv_func_lstat_dereferences_slashed_symlink" = xno; then case " $LIBOBJS " in *" lstat.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS lstat.$ac_objext" ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stat accepts an empty string" >&5 $as_echo_n "checking whether stat accepts an empty string... " >&6; } if ${ac_cv_func_stat_empty_string_bug+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_func_stat_empty_string_bug=yes else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { struct stat sbuf; return stat ("", &sbuf) == 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_func_stat_empty_string_bug=no else ac_cv_func_stat_empty_string_bug=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_stat_empty_string_bug" >&5 $as_echo "$ac_cv_func_stat_empty_string_bug" >&6; } if test $ac_cv_func_stat_empty_string_bug = yes; then case " $LIBOBJS " in *" stat.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS stat.$ac_objext" ;; esac cat >>confdefs.h <<_ACEOF #define HAVE_STAT_EMPTY_STRING_BUG 1 _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working strtod" >&5 $as_echo_n "checking for working strtod... " >&6; } if ${ac_cv_func_strtod+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_func_strtod=no else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default #ifndef strtod double strtod (); #endif int main() { { /* Some versions of Linux strtod mis-parse strings with leading '+'. */ char *string = " +69"; char *term; double value; value = strtod (string, &term); if (value != 69 || term != (string + 4)) return 1; } { /* Under Solaris 2.4, strtod returns the wrong value for the terminating character under some conditions. */ char *string = "NaN"; char *term; strtod (string, &term); if (term != string && *(term - 1) == 0) return 1; } return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_func_strtod=yes else ac_cv_func_strtod=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_strtod" >&5 $as_echo "$ac_cv_func_strtod" >&6; } if test $ac_cv_func_strtod = no; then case " $LIBOBJS " in *" strtod.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS strtod.$ac_objext" ;; esac ac_fn_c_check_func "$LINENO" "pow" "ac_cv_func_pow" if test "x$ac_cv_func_pow" = xyes; then : fi if test $ac_cv_func_pow = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pow in -lm" >&5 $as_echo_n "checking for pow in -lm... " >&6; } if ${ac_cv_lib_m_pow+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-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. */ #ifdef __cplusplus extern "C" #endif char pow (); int main () { return pow (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_pow=yes else ac_cv_lib_m_pow=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_pow" >&5 $as_echo "$ac_cv_lib_m_pow" >&6; } if test "x$ac_cv_lib_m_pow" = xyes; then : POW_LIB=-lm else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot find library containing definition of pow" >&5 $as_echo "$as_me: WARNING: cannot find library containing definition of pow" >&2;} fi fi fi for ac_func in vprintf do : ac_fn_c_check_func "$LINENO" "vprintf" "ac_cv_func_vprintf" if test "x$ac_cv_func_vprintf" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_VPRINTF 1 _ACEOF ac_fn_c_check_func "$LINENO" "_doprnt" "ac_cv_func__doprnt" if test "x$ac_cv_func__doprnt" = xyes; then : $as_echo "#define HAVE_DOPRNT 1" >>confdefs.h fi fi done for ac_func in atexit btowc bzero dup2 memmove memset munmap pow putenv re_comp realpath regcomp select setenv strcasecmp strchr strdup strerror strncasecmp strrchr strstr getopt_long setenv unsetenv do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for xdrmem_create in -lnsl" >&5 $as_echo_n "checking for xdrmem_create in -lnsl... " >&6; } if ${ac_cv_lib_nsl_xdrmem_create+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnsl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char xdrmem_create (); int main () { return xdrmem_create (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nsl_xdrmem_create=yes else ac_cv_lib_nsl_xdrmem_create=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_xdrmem_create" >&5 $as_echo "$ac_cv_lib_nsl_xdrmem_create" >&6; } if test "x$ac_cv_lib_nsl_xdrmem_create" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBNSL 1 _ACEOF LIBS="-lnsl $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for xdrmem_create in -lrpc" >&5 $as_echo_n "checking for xdrmem_create in -lrpc... " >&6; } if ${ac_cv_lib_rpc_xdrmem_create+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lrpc $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char xdrmem_create (); int main () { return xdrmem_create (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_rpc_xdrmem_create=yes else ac_cv_lib_rpc_xdrmem_create=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rpc_xdrmem_create" >&5 $as_echo "$ac_cv_lib_rpc_xdrmem_create" >&6; } if test "x$ac_cv_lib_rpc_xdrmem_create" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBRPC 1 _ACEOF LIBS="-lrpc $LIBS" fi # some AIX adds (linker flag for 32 bit compiles) if test "X$OSTYPE" = "Xaix" ; then if test "X$MACHTYPE" = "Xrs6000" ; then CFLAGS="${CFLAGS} -D_WAVE_BE32" if test "X$CC" = "Xxlc" ; then LDFLAGS="${LDFLAGS} -bmaxdata:0xd0000000/dsa" else LDFLAGS="${LDFLAGS} -Wl,-bmaxdata:0xd0000000/dsa" fi fi fi CFLAGS="${CFLAGS} ${STRUCT_PACK} -DFST_WRITER_PARALLEL" if test "X$OSTYPE" = "Xmsys" ; then # add library for common dialog found in file.c MINGW_LDADD="-lcomdlg32" fi if test "X$ETCL" = "Xyes" ; then if test "X$OSTYPE" = "Xcygwin" ; then # skip Tcl_CreateInterp check on cygwin... if test "X$STUBIFY" = "Xyes" ; then TCL_DEFADD="-DHAVE_LIBTCL -DWAVE_TCL_STUBIFY -DUSE_TCL_STUBS -DUSE_TK_STUBS" TCL_LDADD="${TCL_STUB_LIB_SPEC}" TK_LDADD="${TK_STUB_LIB_SPEC}" else TCL_DEFADD="-DHAVE_LIBTCL" TCL_LDADD="${TCL_LIB_SPEC}" TK_LDADD="${TK_LIB_SPEC}" # cygwin tkConfig.sh has issues... if test "X$TK_LDADD" = "X" ; then TK_LDADD="${TK_BUILD_LIB_SPEC}" fi fi else if test "X$OSTYPE" = "Xdarwin" ; then # skip Tcl_CreateInterp check on darwin (until we figure out)... if test "X$STUBIFY" = "Xyes" ; then TCL_DEFADD="-DHAVE_LIBTCL -DWAVE_TCL_STUBIFY -DUSE_TCL_STUBS -DUSE_TK_STUBS" TCL_LDADD="${TCL_STUB_LIB_SPEC}" TK_LDADD="${TK_STUB_LIB_SPEC}" else TCL_DEFADD="-DHAVE_LIBTCL" TCL_LDADD="${TCL_LIB_SPEC}" TK_LDADD="${TK_LIB_SPEC}" fi else if test "X$OSTYPE" = "Xmsys" ; then # skip Tcl_CreateInterp check on mingw (until we figure out)... if test "X$STUBIFY" = "Xyes" ; then TCL_DEFADD="-DHAVE_LIBTCL -DWAVE_TCL_STUBIFY -DUSE_TCL_STUBS -DUSE_TK_STUBS" TCL_LDADD="${TCL_STUB_LIB_SPEC}" TK_LDADD="${TK_STUB_LIB_SPEC}" else TCL_DEFADD="-DHAVE_LIBTCL" TCL_LDADD="${TCL_LIB_SPEC}" TK_LDADD="${TK_LIB_SPEC}" fi else OLD_LDFLAGS="${LDFLAGS}" TCLSPEC_LHS="${TCL_LIB_SPEC% *}" TKLSPEC_LHS="${TK_LIB_SPEC% *}" LDFLAGS="${LDFLAGS} ${TCLSPEC_LHS} ${TKLSPEC_LHS}" as_ac_Lib=`$as_echo "ac_cv_lib_tcl${TCL_VERSION}''_Tcl_CreateInterp" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl_CreateInterp in -ltcl${TCL_VERSION}" >&5 $as_echo_n "checking for Tcl_CreateInterp in -ltcl${TCL_VERSION}... " >&6; } if eval \${$as_ac_Lib+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ltcl${TCL_VERSION} $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char Tcl_CreateInterp (); int main () { return Tcl_CreateInterp (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : TCL_LDADD=${TCL_LIB_SPEC} else need_tcl=yes fi if test "$need_tcl" = "yes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Tcl support not enabled." >&5 $as_echo "$as_me: WARNING: Tcl support not enabled." >&2;} else if test "X$STUBIFY" = "Xyes" ; then TCL_DEFADD="-DHAVE_LIBTCL -DWAVE_TCL_STUBIFY -DUSE_TCL_STUBS -DUSE_TK_STUBS" TCL_LDADD="${TCL_STUB_LIB_SPEC}" TK_LDADD="${TK_STUB_LIB_SPEC}" else TCL_DEFADD="-DHAVE_LIBTCL" TCL_LDADD="${TCL_LIB_SPEC}" TK_LDADD="${TK_LIB_SPEC}" fi fi LDFLAGS="${OLD_LDFLAGS}" fi fi fi fi ac_config_files="$ac_config_files Makefile doc/Makefile contrib/Makefile contrib/pccts/IBM_VISUAL_AGE_PROJECTS/Makefile contrib/pccts/Makefile contrib/pccts/antlr/Makefile contrib/pccts/dlg/Makefile contrib/pccts/h/Makefile contrib/pccts/sorcerer/Makefile contrib/pccts/sorcerer/h/Makefile contrib/pccts/sorcerer/lib/Makefile contrib/pccts/sorcerer/test/Makefile contrib/pccts/sorcerer/test/test7/Makefile contrib/pccts/sorcerer/testcpp/Makefile contrib/pccts/support/DECmms/Makefile contrib/pccts/support/Makefile contrib/pccts/support/genmk/Makefile contrib/pccts/support/rexpr/Makefile contrib/pccts/support/set/Makefile contrib/pccts/support/sym/Makefile contrib/pccts/testcpp/Makefile contrib/rtlbrowse/Makefile contrib/vermin/Makefile contrib/bundle_for_osx/Makefile contrib/fst_jni/Makefile contrib/wlf2vcd/Makefile contrib/fsdb2vcd/Makefile examples/Makefile man/Makefile src/Makefile src/cocoa/Makefile src/helpers/Makefile src/liblzma/Makefile src/libbz2/Makefile src/libz/Makefile src/helpers/fst/Makefile share/Makefile share/mime/Makefile share/mime/packages/Makefile share/icons/Makefile share/icons/gnome/Makefile share/icons/gnome/16x16/Makefile share/icons/gnome/16x16/mimetypes/Makefile share/icons/gnome/32x32/Makefile share/icons/gnome/32x32/mimetypes/Makefile share/icons/gnome/48x48/Makefile share/icons/gnome/48x48/mimetypes/Makefile share/applications/Makefile share/appdata/Makefile" { $as_echo "$as_me:${as_lineno-$LINENO}: -------------------------------------------- Configuration summary: FASTTREE_CFLAGS : $FASTTREE_CFLAGS gtk1 : $GTK1 gtk version : $GTK_VER GTK_CFLAGS : $GTK_CFLAGS GTK_LIBS : $GTK_LIBS LIBZ_CFLAGS : $LIBZ_CFLAGS LIBZ_LDADD : $LIBZ_LDADD LIBBZ2_CFLAGS : $LIBBZ2_CFLAGS LIBBZ2_LDADD : $LIBBZ2_LDADD LIBXZ_CFLAGS : $LIBXZ_CFLAGS LIBXZ_LDADD : $LIBXZ_LDADD LIBJUDY_CFLAGS : $LIBJUDY_CFLAGS LIBJUDY_LDADD : $LIBJUDY_LDADD AET2_CFLAGS : $AET2_CFLAGS AET2_LDADD : $AET2_LDADD FSDB_CFLAGS : $FSDB_CFLAGS FSDB_LDADD : $FSDB_LDADD EXTLOAD_CFLAGS : $EXTLOAD_CFLAGS TCL_INCLUDE_SPEC : $TCL_INCLUDE_SPEC TCL_LIB_SPEC : $TCL_LIB_SPEC TCL_LDADD : $TCL_LDADD TCL_DEFADD : $TCL_DEFADD TK_INCLUDE_SPEC : $TK_INCLUDE_SPEC TK_LIB_SPEC : $TK_LIB_SPEC TK_LDADD : $TK_LDADD CPPFLAGS : $CPPFLAGS CFLAGS : $CFLAGS LDFLAGS : $LDFLAGS LIBS : $LIBS MINGW_LDADD : $MINGW_LDADD GTK_MAC_CFLAGS : $GTK_MAC_CFLAGS GTK_MAC_LIBS : $GTK_MAC_LIBS COCOA_GTK_CFLAGS : $COCOA_GTK_CFLAGS COCOA_GTK_LDADD : $COCOA_GTK_LDADD COCOA_GTK_LDFLAGS : $COCOA_GTK_LDFLAGS GCONF_CFLAGS : $GCONF_CFLAGS GCONF_LIBS : $GCONF_LIBS GTK_UNIX_PRINT_CFLAGS : $GTK_UNIX_PRINT_CFLAGS GTK_UNIX_PRINT_LIBS : $GTK_UNIX_PRINT_LIBS GEDIT_CFLAGS : $GEDIT_CFLAGS -------------------------------------------- " >&5 $as_echo "$as_me: -------------------------------------------- Configuration summary: FASTTREE_CFLAGS : $FASTTREE_CFLAGS gtk1 : $GTK1 gtk version : $GTK_VER GTK_CFLAGS : $GTK_CFLAGS GTK_LIBS : $GTK_LIBS LIBZ_CFLAGS : $LIBZ_CFLAGS LIBZ_LDADD : $LIBZ_LDADD LIBBZ2_CFLAGS : $LIBBZ2_CFLAGS LIBBZ2_LDADD : $LIBBZ2_LDADD LIBXZ_CFLAGS : $LIBXZ_CFLAGS LIBXZ_LDADD : $LIBXZ_LDADD LIBJUDY_CFLAGS : $LIBJUDY_CFLAGS LIBJUDY_LDADD : $LIBJUDY_LDADD AET2_CFLAGS : $AET2_CFLAGS AET2_LDADD : $AET2_LDADD FSDB_CFLAGS : $FSDB_CFLAGS FSDB_LDADD : $FSDB_LDADD EXTLOAD_CFLAGS : $EXTLOAD_CFLAGS TCL_INCLUDE_SPEC : $TCL_INCLUDE_SPEC TCL_LIB_SPEC : $TCL_LIB_SPEC TCL_LDADD : $TCL_LDADD TCL_DEFADD : $TCL_DEFADD TK_INCLUDE_SPEC : $TK_INCLUDE_SPEC TK_LIB_SPEC : $TK_LIB_SPEC TK_LDADD : $TK_LDADD CPPFLAGS : $CPPFLAGS CFLAGS : $CFLAGS LDFLAGS : $LDFLAGS LIBS : $LIBS MINGW_LDADD : $MINGW_LDADD GTK_MAC_CFLAGS : $GTK_MAC_CFLAGS GTK_MAC_LIBS : $GTK_MAC_LIBS COCOA_GTK_CFLAGS : $COCOA_GTK_CFLAGS COCOA_GTK_LDADD : $COCOA_GTK_LDADD COCOA_GTK_LDFLAGS : $COCOA_GTK_LDFLAGS GCONF_CFLAGS : $GCONF_CFLAGS GCONF_LIBS : $GCONF_LIBS GTK_UNIX_PRINT_CFLAGS : $GTK_UNIX_PRINT_CFLAGS GTK_UNIX_PRINT_LIBS : $GTK_UNIX_PRINT_LIBS GEDIT_CFLAGS : $GEDIT_CFLAGS -------------------------------------------- " >&6;} cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs { $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 $as_echo_n "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 $as_echo "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${FDO_MIME_TRUE}" && test -z "${FDO_MIME_FALSE}"; then as_fn_error $? "conditional \"FDO_MIME\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 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__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__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 : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by gtkwave $as_me 3.3.66, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ gtkwave config.status 3.3.66 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; "contrib/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/Makefile" ;; "contrib/pccts/IBM_VISUAL_AGE_PROJECTS/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/pccts/IBM_VISUAL_AGE_PROJECTS/Makefile" ;; "contrib/pccts/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/pccts/Makefile" ;; "contrib/pccts/antlr/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/pccts/antlr/Makefile" ;; "contrib/pccts/dlg/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/pccts/dlg/Makefile" ;; "contrib/pccts/h/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/pccts/h/Makefile" ;; "contrib/pccts/sorcerer/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/pccts/sorcerer/Makefile" ;; "contrib/pccts/sorcerer/h/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/pccts/sorcerer/h/Makefile" ;; "contrib/pccts/sorcerer/lib/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/pccts/sorcerer/lib/Makefile" ;; "contrib/pccts/sorcerer/test/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/pccts/sorcerer/test/Makefile" ;; "contrib/pccts/sorcerer/test/test7/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/pccts/sorcerer/test/test7/Makefile" ;; "contrib/pccts/sorcerer/testcpp/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/pccts/sorcerer/testcpp/Makefile" ;; "contrib/pccts/support/DECmms/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/pccts/support/DECmms/Makefile" ;; "contrib/pccts/support/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/pccts/support/Makefile" ;; "contrib/pccts/support/genmk/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/pccts/support/genmk/Makefile" ;; "contrib/pccts/support/rexpr/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/pccts/support/rexpr/Makefile" ;; "contrib/pccts/support/set/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/pccts/support/set/Makefile" ;; "contrib/pccts/support/sym/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/pccts/support/sym/Makefile" ;; "contrib/pccts/testcpp/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/pccts/testcpp/Makefile" ;; "contrib/rtlbrowse/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/rtlbrowse/Makefile" ;; "contrib/vermin/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/vermin/Makefile" ;; "contrib/bundle_for_osx/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/bundle_for_osx/Makefile" ;; "contrib/fst_jni/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/fst_jni/Makefile" ;; "contrib/wlf2vcd/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/wlf2vcd/Makefile" ;; "contrib/fsdb2vcd/Makefile") CONFIG_FILES="$CONFIG_FILES contrib/fsdb2vcd/Makefile" ;; "examples/Makefile") CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;; "man/Makefile") CONFIG_FILES="$CONFIG_FILES man/Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "src/cocoa/Makefile") CONFIG_FILES="$CONFIG_FILES src/cocoa/Makefile" ;; "src/helpers/Makefile") CONFIG_FILES="$CONFIG_FILES src/helpers/Makefile" ;; "src/liblzma/Makefile") CONFIG_FILES="$CONFIG_FILES src/liblzma/Makefile" ;; "src/libbz2/Makefile") CONFIG_FILES="$CONFIG_FILES src/libbz2/Makefile" ;; "src/libz/Makefile") CONFIG_FILES="$CONFIG_FILES src/libz/Makefile" ;; "src/helpers/fst/Makefile") CONFIG_FILES="$CONFIG_FILES src/helpers/fst/Makefile" ;; "share/Makefile") CONFIG_FILES="$CONFIG_FILES share/Makefile" ;; "share/mime/Makefile") CONFIG_FILES="$CONFIG_FILES share/mime/Makefile" ;; "share/mime/packages/Makefile") CONFIG_FILES="$CONFIG_FILES share/mime/packages/Makefile" ;; "share/icons/Makefile") CONFIG_FILES="$CONFIG_FILES share/icons/Makefile" ;; "share/icons/gnome/Makefile") CONFIG_FILES="$CONFIG_FILES share/icons/gnome/Makefile" ;; "share/icons/gnome/16x16/Makefile") CONFIG_FILES="$CONFIG_FILES share/icons/gnome/16x16/Makefile" ;; "share/icons/gnome/16x16/mimetypes/Makefile") CONFIG_FILES="$CONFIG_FILES share/icons/gnome/16x16/mimetypes/Makefile" ;; "share/icons/gnome/32x32/Makefile") CONFIG_FILES="$CONFIG_FILES share/icons/gnome/32x32/Makefile" ;; "share/icons/gnome/32x32/mimetypes/Makefile") CONFIG_FILES="$CONFIG_FILES share/icons/gnome/32x32/mimetypes/Makefile" ;; "share/icons/gnome/48x48/Makefile") CONFIG_FILES="$CONFIG_FILES share/icons/gnome/48x48/Makefile" ;; "share/icons/gnome/48x48/mimetypes/Makefile") CONFIG_FILES="$CONFIG_FILES share/icons/gnome/48x48/mimetypes/Makefile" ;; "share/applications/Makefile") CONFIG_FILES="$CONFIG_FILES share/applications/Makefile" ;; "share/appdata/Makefile") CONFIG_FILES="$CONFIG_FILES share/appdata/Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi gtkwave-3.3.66/examples/0000775000076400007640000000000012546303363014422 5ustar bybellbybellgtkwave-3.3.66/examples/Makefile.in0000664000076400007640000003332712261434733016477 0ustar bybellbybell# Makefile.in generated by automake 1.13.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 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__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } 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 = : subdir = examples DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(dist_examples_DATA) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.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 = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac 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)$(examplesdir)" DATA = $(dist_examples_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AET2_CFLAGS = @AET2_CFLAGS@ AET2_LDADD = @AET2_LDADD@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COCOA_GTK_CFLAGS = @COCOA_GTK_CFLAGS@ COCOA_GTK_LDADD = @COCOA_GTK_LDADD@ COCOA_GTK_LDFLAGS = @COCOA_GTK_LDFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTDEBUG = @EXTDEBUG@ EXTDEBUG2 = @EXTDEBUG2@ EXTDEBUG3 = @EXTDEBUG3@ EXTDEBUG4 = @EXTDEBUG4@ EXTLOAD_CFLAGS = @EXTLOAD_CFLAGS@ FASTTREE_CFLAGS = @FASTTREE_CFLAGS@ FSDB_CFLAGS = @FSDB_CFLAGS@ FSDB_LDADD = @FSDB_LDADD@ GCONF_CFLAGS = @GCONF_CFLAGS@ GCONF_LIBS = @GCONF_LIBS@ GEDITTEST = @GEDITTEST@ GEDIT_CFLAGS = @GEDIT_CFLAGS@ GPERF = @GPERF@ GREP = @GREP@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_CONFIG = @GTK_CONFIG@ GTK_LIBS = @GTK_LIBS@ GTK_MAC_CFLAGS = @GTK_MAC_CFLAGS@ GTK_MAC_LIBS = @GTK_MAC_LIBS@ GTK_UNIX_PRINT_CFLAGS = @GTK_UNIX_PRINT_CFLAGS@ GTK_UNIX_PRINT_LIBS = @GTK_UNIX_PRINT_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBBZ2_CFLAGS = @LIBBZ2_CFLAGS@ LIBBZ2_DIR = @LIBBZ2_DIR@ LIBBZ2_LDADD = @LIBBZ2_LDADD@ LIBJUDY_CFLAGS = @LIBJUDY_CFLAGS@ LIBJUDY_LDADD = @LIBJUDY_LDADD@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBXZ_CFLAGS = @LIBXZ_CFLAGS@ LIBXZ_LDADD = @LIBXZ_LDADD@ LIBZ_CFLAGS = @LIBZ_CFLAGS@ LIBZ_DIR = @LIBZ_DIR@ LIBZ_LDADD = @LIBZ_LDADD@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MINGW_LDADD = @MINGW_LDADD@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ 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@ POW_LIB = @POW_LIB@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ STRUCT_PACK = @STRUCT_PACK@ TCL_DEFADD = @TCL_DEFADD@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LDADD = @TCL_LDADD@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_MAJOR_VERSION = @TCL_MAJOR_VERSION@ TCL_MINOR_VERSION = @TCL_MINOR_VERSION@ TK_INCLUDE_SPEC = @TK_INCLUDE_SPEC@ TK_LDADD = @TK_LDADD@ TK_LIB_SPEC = @TK_LIB_SPEC@ UPDATE_DESKTOP_DATABASE = @UPDATE_DESKTOP_DATABASE@ UPDATE_MIME_DATABASE = @UPDATE_MIME_DATABASE@ VERSION = @VERSION@ XDGDATADIR = @XDGDATADIR@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ 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_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ 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@ 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@ dist_examples_DATA = des.gtkw des.tcl des.v des.fst transaction.fst transaction.gtkw transaction.c gtkwaverc examplesdir = $(pkgdatadir)/examples all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(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) --foreign examples/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign examples/Makefile .PRECIOUS: 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__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-dist_examplesDATA: $(dist_examples_DATA) @$(NORMAL_INSTALL) @list='$(dist_examples_DATA)'; test -n "$(examplesdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(examplesdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(examplesdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(examplesdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(examplesdir)" || exit $$?; \ done uninstall-dist_examplesDATA: @$(NORMAL_UNINSTALL) @list='$(dist_examples_DATA)'; test -n "$(examplesdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(examplesdir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(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 $(DATA) installdirs: for dir in "$(DESTDIR)$(examplesdir)"; 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 mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dist_examplesDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: 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 Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-dist_examplesDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic cscopelist-am \ ctags-am distclean distclean-generic distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dist_examplesDATA 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 \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic pdf pdf-am ps ps-am tags-am uninstall \ uninstall-am uninstall-dist_examplesDATA # 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: gtkwave-3.3.66/examples/transaction.gtkw0000664000076400007640000000154011715634655017655 0ustar bybellbybell[*] [*] GTKWave Analyzer v3.3.32 (w)1999-2012 BSI [*] Sun Feb 12 03:53:14 2012 [*] [dumpfile] "/home/bybell/gtkwave/gtkwave3/examples/transaction.fst" [dumpfile_mtime] "Fri Feb 4 20:50:48 2011" [dumpfile_size] 2912 [savefile] "/home/bybell/gtkwave/gtkwave3/examples/transaction.gtkw" [timestart] 196429 [size] 1024 744 [pos] -1 -1 *-10.463677 -1 196608 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 [markername] AStart [sst_width] 223 [signals_width] 133 [sst_expanded] 1 [sst_vpaned_height] 158 @90022 [color] 6 top.val[7:0] @20000 - - - - - - @200 -ARGS="0" @10000022 [transaction_args] "0" ^<1 /home/bybell/gtkwave/gtkwave3/examples/transaction top.val[7:0] @200 - - - - -ARGS="1" @10000022 [transaction_args] "1" ^<1 /home/bybell/gtkwave/gtkwave3/examples/transaction top.val[7:0] @200 - - - - [pattern_trace] 1 [pattern_trace] 0 gtkwave-3.3.66/examples/des.tcl0000664000076400007640000000220111523063250015664 0ustar bybellbybell# # simple example of using tcl with gtkwave: # 1) query the dumpfile for signals with "clk" or # [1:48] in the signal name # 2) show full signal hierarchy # 3) zoom full # 4) set marker to 128 units # 5) generate the postscript to a file # 6) exit gtkwave # set nfacs [ gtkwave::getNumFacs ] set dumpname [ gtkwave::getDumpFileName ] set dmt [ gtkwave::getDumpType ] puts "number of signals in dumpfile '$dumpname' of type $dmt: $nfacs" set clk48 [list] for {set i 0} {$i < $nfacs } {incr i} { set facname [ gtkwave::getFacName $i ] set indx [ string first "\[1:48\]" $facname ] if {$indx == -1} { set indx [ string first clk $facname ] } if {$indx != -1} { lappend clk48 "$facname" } } set ll [ llength $clk48 ] puts "number of signals found matching either 'clk' or '\[1:48\]': $ll" set num_added [ gtkwave::addSignalsFromList $clk48 ] puts "num signals added: $num_added" gtkwave::/Edit/Set_Trace_Max_Hier 0 gtkwave::/Time/Zoom/Zoom_Full gtkwave::setMarker 128 gtkwave::setNamedMarker A 400 "Example Named Marker" gtkwave::/File/Print_To_File PS {Letter (8.5" x 11")} Full $dumpname.ps gtkwave::/File/Quit gtkwave-3.3.66/examples/gtkwaverc0000664000076400007640000002463012232573312016342 0ustar bybellbybell# # sample rc file # (rename to .gtkwaverc and copy # to home directory to be loaded automatically) # # NOTE: env var GTKWAVE_EDITOR can also be used for this, however the rc file overrides it # %d is line number (can be combined inside a string as shown for vimx) # %s is filename (must stand by itself, can't add anything to it) # # editor "vimx -g +%d %s" # editor "gedit +%d %s" # editor "emacs +%d %s" # For OSX # editor "mate -l %d %s" use_standard_trace_select no highlight_wavewindow no alt_wheel_mode yes vcd_preserve_glitches no vcd_preserve_glitches_real no ignore_savefile_pane_pos no ignore_savefile_pos no ignore_savefile_size no ruler_origin 0 ruler_step 0 disable_ae2_alias no keep_xz_colors no strace_repeat_count 1 enable_fast_exit yes disable_empty_gui off analog_redraw_skip_count 20 splash_disable off hide_sst off sst_dynamic_filter on use_standard_clicking on use_toolbutton_interface on use_pango_fonts on use_scrollwheel_as_y off scale_to_time_dimension * zoom_dynamic off zoom_dynamic_end off vlist_spill off vlist_prepack off vlist_compression 4 hier_max_level 1 force_toolbars 0 #cursor_snap 8 zoom_pow10_snap on dynamic_resizing 1 hpane_pack 1 #initial_window_x 1000 #initial_window_y 600 #initial_window_xpos 50 #initial_window_ypos 50 use_maxtime_display 0 enable_vcd_autosave 0 use_roundcaps 1 use_nonprop_fonts yes enable_horiz_grid yes use_big_fonts no constant_marker_update yes show_grid yes show_base_symbols no atomic_vectors yes vcd_explicit_zero_subscripts no # # color additions # color_back 000000 color_baseline ffffff color_grid 202070 color_grid2 6a5acd color_high 79f6f2 color_low 5dbebb color_1 00ff00 color_0 008000 color_trans 00c000 color_mid c0c000 color_value ffffff color_vbox 00ff00 color_vtrans 00c000 color_x ff0000 color_xfill 400000 color_u cc0000 color_ufill 200000 color_w 79f6f2 color_wfill 3f817f color_dash edf508 color_dashfill 7d8104 color_umark ff8080 color_mark ffff80 color_time ffffff color_timeb 000000 color_brkred cc0000 color_ltblue 5dbebb color_gmstrd 7d8104 # # menu accelerators # accel "/File/Open New Window" N accel "/File/Open New Tab" T accel "/File/Reload Waveform" R accel "/File/Export/Write VCD File As" (null) accel "/File/Export/Write LXT File As" (null) accel "/File/Export/Write TIM File As" (null) accel "/File/Close" W accel "/File/" (null) accel "/File/Print To File" P accel "/File/Grab To File" (null) accel "/File/" (null) accel "/File/Read Save File" O accel "/File/Write Save File" S accel "/File/Write Save File As" S accel "/File/" (null) accel "/File/Read Sim Logfile" L accel "/File/" (null) accel "/File/Read Verilog Stemsfile" (null) accel "/File/" (null) accel "/File/Read Tcl Script File" (null) accel "/File/" (null) accel "/File/Quit" Q accel "/Edit/Set Trace Max Hier" (null) accel "/Edit/Toggle Trace Hier" H accel "/Edit/" (null) accel "/Edit/Insert Blank" B accel "/Edit/Insert Comment" (null) accel "/Edit/Insert Analog Height Extension" (null) accel "/Edit/Cut" X accel "/Edit/Copy" C accel "/Edit/Paste" V accel "/Edit/" (null) accel "/Edit/Alias Highlighted Trace" A accel "/Edit/Remove Highlighted Aliases" A accel "/Edit/" (null) accel "/Edit/Expand" F3 accel "/Edit/Combine Down" F4 accel "/Edit/Combine Up" F5 accel "/Edit/" (null) accel "/Edit/Data Format/Hex" X accel "/Edit/Data Format/Decimal" D accel "/Edit/Data Format/Signed Decimal" (null) accel "/Edit/Data Format/Binary" B accel "/Edit/Data Format/Octal" O accel "/Edit/Data Format/ASCII" (null) accel "/Edit/Data Format/BitsToReal" (null) accel "/Edit/Data Format/RealToBits/On" (null) accel "/Edit/Data Format/RealToBits/Off" (null) accel "/Edit/Data Format/Right Justify/On" J accel "/Edit/Data Format/Right Justify/Off" J accel "/Edit/Data Format/Invert/On" I accel "/Edit/Data Format/Invert/Off" I accel "/Edit/Data Format/Reverse Bits/On" V accel "/Edit/Data Format/Reverse Bits/Off" V accel "/Edit/Data Format/Translate Filter File/Disable" (null) accel "/Edit/Data Format/Translate Filter File/Enable and Select" (null) accel "/Edit/Data Format/Translate Filter Process/Disable" (null) accel "/Edit/Data Format/Translate Filter Process/Enable and Select" (null) accel "/Edit/Data Format/Transaction Filter Process/Disable" (null) accel "/Edit/Data Format/Transaction Filter Process/Enable and Select" (null) accel "/Edit/Data Format/Analog/Off" (null) accel "/Edit/Data Format/Analog/Step" (null) accel "/Edit/Data Format/Analog/Interpolated" (null) accel "/Edit/Data Format/Analog/Interpolated Annotated" (null) accel "/Edit/Data Format/Analog/Resizing/Screen Data" (null) accel "/Edit/Data Format/Analog/Resizing/All Data" (null) accel "/Edit/Data Format/Range Fill/With 0s" (null) accel "/Edit/Data Format/Range Fill/With 1s" (null) accel "/Edit/Data Format/Range Fill/Off" (null) accel "/Edit/Data Format/Gray Filters/To Gray" (null) accel "/Edit/Data Format/Gray Filters/From Gray" (null) accel "/Edit/Data Format/Gray Filters/None" (null) accel "/Edit/Color Format/Normal" (null) accel "/Edit/Color Format/Red" (null) accel "/Edit/Color Format/Orange" (null) accel "/Edit/Color Format/Yellow" (null) accel "/Edit/Color Format/Green" (null) accel "/Edit/Color Format/Blue" (null) accel "/Edit/Color Format/Indigo" (null) accel "/Edit/Color Format/Violet" (null) accel "/Edit/Color Format/Cycle" (null) accel "/Edit/Color Format/" (null) accel "/Edit/Color Format/Keep xz Colors" (null) accel "/Edit/Show-Change All Highlighted" (null) accel "/Edit/Show-Change First Highlighted" F accel "/Edit/" (null) accel "/Edit/Time Warp/Warp Marked" (null) accel "/Edit/Time Warp/Unwarp Marked" (null) accel "/Edit/Time Warp/Unwarp All" (null) accel "/Edit/" (null) accel "/Edit/Exclude" E accel "/Edit/Show" S accel "/Edit/" (null) accel "/Edit/Toggle Group Open|Close" T accel "/Edit/Create Group" G accel "/Edit/" (null) accel "/Edit/Highlight Regexp" R accel "/Edit/UnHighlight Regexp" R accel "/Edit/Highlight All" A accel "/Edit/UnHighlight All" A accel "/Edit/" (null) accel "/Edit/Sort/Alphabetize All" (null) accel "/Edit/Sort/Alphabetize All (CaseIns)" (null) accel "/Edit/Sort/Sigsort All" (null) accel "/Edit/Sort/Reverse All" (null) accel "/Search/Pattern Search 1" (null) accel "/Search/Pattern Search 2" (null) accel "/Search/" (null) accel "/Search/Signal Search Regexp" S accel "/Search/Signal Search Hierarchy" T accel "/Search/Signal Search Tree" T accel "/Search/" (null) accel "/Search/Open Source Definition" (null) accel "/Search/Open Source Instantiation" (null) accel "/Search/Open Scope" (null) accel "/Search/" (null) accel "/Search/Autocoalesce" (null) accel "/Search/Autocoalesce Reversal" (null) accel "/Search/Autoname Bundles" (null) accel "/Search/Search Hierarchy Grouping" (null) accel "/Search/" (null) accel "/Search/Set Pattern Search Repeat Count" (null) accel "/Time/Move To Time" F1 accel "/Time/Zoom/Zoom Amount" F2 accel "/Time/Zoom/Zoom Base" F2 accel "/Time/Zoom/Zoom In" Z accel "/Time/Zoom/Zoom Out" Z accel "/Time/Zoom/Zoom Full" F accel "/Time/Zoom/Zoom Best Fit" F accel "/Time/Zoom/Zoom To Start" Home accel "/Time/Zoom/Zoom To End" End accel "/Time/Zoom/Undo Zoom" U accel "/Time/Fetch/Fetch Size" F7 accel "/Time/Fetch/Fetch ->" 2 accel "/Time/Fetch/Fetch <-" 1 accel "/Time/Discard/Discard ->" 4 accel "/Time/Discard/Discard <-" 3 accel "/Time/Shift/Shift ->" 6 accel "/Time/Shift/Shift <-" 5 accel "/Time/Page/Page ->" 8 accel "/Time/Page/Page <-" 7 accel "/Markers/Show-Change Marker Data" M accel "/Markers/Drop Named Marker" N accel "/Markers/Collect Named Marker" N accel "/Markers/Collect All Named Markers" N accel "/Markers/Copy Primary->B Marker" (null) accel "/Markers/Copy Primary->B Marker" B accel "/Markers/Delete Primary Marker" M accel "/Markers/" (null) accel "/Markers/Find Previous Edge" (null) accel "/Markers/Find Next Edge" (null) accel "/Markers/" (null) accel "/Markers/Alternate Wheel Mode" (null) accel "/Markers/" (null) accel "/Markers/Wave Scrolling" F9 accel "/Markers/Locking/Lock to Lesser Named Marker" Q accel "/Markers/Locking/Lock to Greater Named Marker" W accel "/Markers/Locking/Unlock from Named Marker" O accel "/View/Show Grid" G accel "/View/" (null) accel "/View/Show Mouseover" (null) accel "/View/" (null) accel "/View/Show Base Symbols" F1 accel "/View/" (null) accel "/View/Standard Trace Select" (null) accel "/View/" (null) accel "/View/Dynamic Resize" 9 accel "/View/" (null) accel "/View/Center Zooms" F8 accel "/View/" (null) accel "/View/Toggle Delta-Frequency" (null) accel "/View/Toggle Max-Marker" F10 accel "/View/" (null) accel "/View/Constant Marker Update" F11 accel "/View/" (null) accel "/View/Draw Roundcapped Vectors" F2 accel "/View/" (null) accel "/View/Left Justified Signals" Home accel "/View/Right Justified Signals" End accel "/View/" (null) accel "/View/Zoom Pow10 Snap" Pause accel "/View/Partial VCD Dynamic Zoom Full" (null) accel "/View/Partial VCD Dynamic Zoom To End" (null) accel "/View/Full Precision" Pause accel "/View/" (null) accel "/View/Define Time Ruler Marks" (null) accel "/View/Remove Pattern Marks" (null) accel "/View/" (null) accel "/View/Use Color" (null) accel "/View/Use Black and White" (null) accel "/View/" (null) accel "/View/LXT Clock Compress to Z" (null) accel "/View/" (null) accel "/View/Scale To Time Dimension/None" (null) accel "/View/Scale To Time Dimension/sec" (null) accel "/View/Scale To Time Dimension/ms" (null) accel "/View/Scale To Time Dimension/us" (null) accel "/View/Scale To Time Dimension/ns" (null) accel "/View/Scale To Time Dimension/ps" (null) accel "/View/Scale To Time Dimension/fs" (null) accel "/Help/WAVE Help" H accel "/Help/WAVE User Manual" (null) accel "/Help/Wave Version" (null) gtkwave-3.3.66/examples/des.fst0000664000076400007640000046462612233324310015721 0ustar bybellbybellIiW @Icarus VerilogSun Oct 27 18:53:04 2013 aj- x  ڏo} Zx^Y8[!4c PDmdHٶ '*2$% dVB2Y12>޷?} 6666S{ kKZRbP+YRb+2k[-8PD; 7 !rޛqNjnC+5#gE)% XiҲ j IJ7c0U;d^-<^f-K p&LŖKI"PQ }0 ǖ:6 $Ŵc/쌤' @զL[ p@(>d^6ǽRwC!"&X& ⇩{nuY,mz^2w4=dnP*Ť$E &$َ9ɬw~NOXίo'ըe\72kc7+('0:Pqto)GCRBw;WN}X`p6SK!Sh8> Ƣyy-`t--jJ.oqsf'RWgVrg&2^/ [SY?5Ѧxb%V7=M4jbb9 `KWo-)Ƅf\V< T4%%s)פZQ HTaR,+Ըau*sD2f9D}Y7xV*u\(oGhaspҕ~iJOkEl7|Ż49'[u.'2P~7w2:묢$o1 ;NZox<*] ٻuC]30o6Ag!A1{iE=ޞE" Wy9Tq6&,k/+O94ε.;o&x1^>Ƶ" 5ծ^]mwI&vF \*p(C{#ǡnM+y eGm`p'LV˿LiQKDEVW#h`8q|h  B 5BdQ:`D`, xgty A:Θ编|l58m'z-V.<%>?z 8FmG>qM S܈)J2{ CzuDǧ61R2>}y( 8\奈hm@jLVaRK1)f|DhW`=RMjt;Zpoct`O uZ80|{wNjv5 q~SBjA)kop$BNbkBaAN~_DKCF]dw|/; lmMGi9/['ƚQeϛ)l*QpXCsNAT~f7/3-CDHp5|AOݦgHJɲي/Ja=pAǺձc.OIf뎁R2npJ:sX9QZ2 gF3IО>d-y6 I=}B~ $g0z宾 M"vƓ^ou,-i\zvM -v=;&=.M4z?Sʠ-I.{L}ayhڽ?eƓS$p)r0[$77݀Q[{Dq?|ϐh'ظi aR* 3!=!z; ]?tQC-=Qp/!6pX+<ڌ*%;΍ D6{͈(u ~+CD㢲E&3\ zm1|#HɩwpOI`FfmiY +lCCk3ipM5Ձk%lnhMWM7'Pd)sؕ+"N#}×}\YϬC2EJ?־]~x^cdapB x^c`P`Feg#D5,HfT^Ĺ yq9Xx1s`)m; |:Xԭ3g9/.p%1_k} [N9sJrspPNڕX!&榹A>x^c`P `tFFeg;UE^`Ysg[LW,ؾ9zGwrpb^ȁuvGy+/9`}Wp |ՃY$Jǜr`Sm>M:pqCvQ3!,BIW }nχ %Pt.z|1{t !;|Fג_1-+: ruDf[βx2Lx'q)6VZF E~}&D he->~AC2\g(rJ2Ս.ۖt ?w c&JO7H/ )C`u}{5T\eǷs^{3 h{JA]t% <qMM\JVB>:AɈt3d U_f )Rrluv"Z`!@Aì?/TWo>e~ Aݧ_CV3 ,jXHZ \SbӤjx^;rZẺ/OVf *!o"z(y(Y^rJ`xk* 8eneGD`mKsy8l K9#n~S#L8[) Q:>p#6tX ⓈCzK.@nhO=?T I?dUj"d\xwɠN]x'(P=[q9I,mW!S.9^_zh.<6|{g9 Bcbڴ/M@rߊaoz>L{RvD>/-H.(Ж:څ_B%J6!BUUHwX.FVn}!t6^p-~2 5dF6tjH4*C *R CA" ^{{HN_ZB[5%(ѷz]yBvo<Ұ*($᳽C>23hA&}|^$0 k~AmN +?4GT~!w([†q-S8gW8(Rh0vIZP%p`nЂG7~JLc\TuFԢۅ=_D85 F|bm`;GC밷)Ɖ(I[;AIwkeF4Keļ<>`TDx1OHx4w@ƍAv>(4MVY3"8 TFIR{z4V.C CWpm/҄Oz$6CR H9?`֩wթcsnaytcG6n%;MS׈ [նIdGk1 %7* 9塵lxVZ4՘E^yq8-\^RAtΞ-0FH=EMLܱÙ=ͯ-]?!Qe@e ``FP~ ɇ?Eԋb '[x^/pƽ<I9n߼3,j^6/aaDNKÅsa"oy+,yns;-TL%oIydDGN*(FE0~yE(}9 &wEh sycM@~l +/1y450vvqB38جtEmyG+.FʞtJ4а0 Vg`B26+1ahGXi =d] 2  *&8n<(i>PӹG4Bӟn=hIGjT<򼳓!,XQRŽrRKRF& (D E;aTyVM3P2bǼHF(f1'e"LGтp6'Kn\ M3n7p]|8'"|IIXeiPbr= {\4kRxrtlG/m9;ݞP)Ƚ:.ؗshj1;==%|F.#Z0n w\6\āB"H{l4EPX(W ~]0w9Qx3A; y],4w}|6}2#xi \ Afm0X@8◖IMlC3II/~,S_r5ߒx^Kq`h8Vnrjhdp2)jZbAyYK91Qt< +q8yNȣ7 #`llԅbU>%}lYȲ,u._WVi VDbY+E׭oW,_!vL[BM.2W J&MYs\4mƗ &ZO`qm۠Y\Xd)2,bgMy[Y}11`YzfzGL,]MKY)7+b9=o5Kї?X؅K,jwbq#R,7g,d:rIP T,-֛Xr[Z|Lnsets; Q֘ձ^).|eӔ;Chx^c Xnܸ[ B@,,7m==eW_&qŸE+,˙W<_Ͳ{t )dQX"9, ,]Y&o0p/uv al ,WL_maՏɅ,廒Y\0o!ܼI, ;8%a^G)Oc-%YXQoxi(<cKXׇ0gXv5,&|eq){-WaW0) j,_ebx^c XnܸF]]6,wܶt۝*l8;=Ft`=D qg-lX)lhGm aoQTeƇ6M]rMCr!m/wMiGogtMyts,X.w"6*\EYz:,ڰV,`yK<,'ܽ,-Fgs x^{<q(ϊb:RZYByWEVy $Ĺ)rNe.k](󠤣Bwrҟ66Ƭ3TlD < dO֛?;"s+j bޭ*2'x=mq;G𓿫!sm ~|MFTC:WBVmj~#o#KVpg' D_3JBk M`؄IVeCZ/&7K xc~D#woU3oO{*Ds]SێRkD`;K[nJ}ƌe6\x=y\E12CV<]e>af nNqi$}Ap4,`>K fv81$, 7"!*FODZEMaL$N0bn`A/\KήsC}#gȣ=~~wq2{K z]WGSvn?XIŁ[8WvA_%~ē/.BNO{(_4ʇAqXgE5時#q8ُAO0j2 7l{B&FӮR?+y-.gIsmJ4pRj^~2QĶĢ̘K7JxA|}oװZ^h\Kw _,Z'_ϓGr"N5cnt>fEhOIuQQYgYR1և22#Jr$k)G7kx %t[haǑ7,zxەx΋fm.\A |Mmvh'll愜*ö8.\aEIrL4~O.2Cv{pn[Mj3MP}W;pAwT`D؁)eY.JͲr&[6"R23PkH+\ւ1|Zz>nlfqeYcz1k-l&5bV/,u8 VbW(|*Ӗ1VYcuo}uڋ$| e%ܓ:'5 >`˱r) _q5)MYܽ0337ϔV0f;sGUgE- )#9ɽ!f˻sG a@5_)5$LmA2iO5ҙD-zUxyxRP"#)ao6ڲ51Dc }=T0ս+y_7$ïiinm@} 0+-^}!Q}Ϗ"׭g:X$3%1UKS}LKkOѪhqI1#dDz bDtr¶c x^;-J9 VI.qRK[uh"KţKaDE|gBF'K+uzM.S- uxy^ByXXSt&rYkc֯ʡ~\UTJl`cQ1d*ґs weSdC~ :#HQߎWH ᖸe3f fB6`r#op2:isT)WR,Ɇ*QnkK/$~¸}qȹ*jd2'4f]kTl}2V {ixm eJRm-+ 9F)m3[6FXY. I}Ēި1#EWUhF$~=ySw#E'2٣Zw84ʩČyVdh;L)hueWDRveL}7wg2c!#v=2_c^wo+us,amu6h-c2Rnw;:߈X}Υh)AȌ^HWn@e[,=lv'&~٬͞osy_Y|:ɹHfI:o{G=%x~h-jз)N݁h#lP>:9Gj]>'XADWL6b%-1Q55 _f%ɫe {:;R'd7wwE[_V+)`nPG( SK8 ".!<ы[lNKG\<{s`\K2C3]>H {۸eZrVe;8W4Zؑ"i¦3[`Jf]yXl uv?d-3 -F,on=ȗ# )Ri]C )FL݈ ?mVC۾(tޠ럿";FFf'b":E'qCϕ_I ờ8_,d/0Ν_MU.O|/K,`t{W !(JGYto +l%vrSW']׌.I˦x66Iaqiyq c,Jm7U~CUXk}ho%8UjόsypZ,֕f궈 |$ZljI[:[]V$4*W?_|ge#WY\=nSJ$N)ӣԈ vrJMrXڡJbK|1W2z-rwg. afU2woz"5v0MاlB+k.Am{S_$ʑu*:Jdc]c#SKK*ml L&I 0En;FhS2&s%B) ~dcT%Sz_.R"R;fK-+8~9|ZcI{Wk?wpuԊX_ *2,uo);"Uo^=\9Zfkv'ݖqT9 U-[2VW){,kee,ZWXԆrq=)vwʕkbB9QÊ\z !b)d~GxDk?Jb>fIidʳbcBRhي.y hpۊvzΗ}1X̩HrqX'Y>J_ąA8 W233˸6F[4ɭ*eVlǭ.fEm+iSvJriʷ}JO#{-C@["ƂϩHߴBʸlb]wPTk'x]OQMnql܇Y]Yɷlls 3s2Gj$E/ڙd^iDl.oM{vq#zl p[ [aųNnx dI &MX&Klk 2¹ |1<2+F`vF;F?a.LsEۖM7Zbپy9zRpO^6YgfTRmh {G^׷GdA!apdq;%:gX^j4ce 975j6!@k/Vvy@&U& 6~<^mM_{jTDe$4yuoJO$&N ;Qk˖4&Ϝ>do^s x^_q\2hֱZD18#)՜.Gdmu6%tZNk9rXE-iSY.irJ< ĵk <))|&ǠSxL76[*=M%\_$~0%z_9rs)Ld^t-؜, Aj eq6vt~''!SN46գ9)'f`cВ˩.K/eSmh%r.hGm:t}tMY66 Ւd OXbCwH̺W`{3:#3jOL#Lc=:މ뉐!Ӡ;%畋h2@ldNxv9Syb>YKv<#GU!:kEl#d,VI3t!e\ &OɈ+vu3>g hfQ$kK~N_ 8;m"v0m!g>9?z0vC-o0fTAKaUr&$#T\~#N+HGJ-r|s=jBrW8RLHɢc x^; ƷBHIӖsRvR# ӱQ+4QMȤlrFf+[qf[H5#Z6k{<;?9G8Ly"M?\qs!a $>=3JH6C*SMUk}ӺpwQA[OE*2h FcP7cOU (3 l/PSX4m֔5[Σh$r|;tu;n[#79THȨ 6P :}W€TP;E$,T΂Hkx>B/sm~ ;.ܑ%~h'k@m:7֮U"TzoiR |{RΠoJnWD,[bMEA61O$eI0e .ŃqK33t5,TAnl +wouvo` sy'vׯ#nC=.Cyf⧐h:`=0 Dރiq j!ʸ- [HCri89*>Ô a'hO8tĆRkr"F+‘# K\5d(K\ 9vqf=$4w_<R.G3bnT y`" ZoAHrx5LK罾/ijDp(m+=PЎa0_爆0i+FI >`` "3!t-!S-Jfi$l?кh4ڽ[5=gc2z|Mi1@bMlx': F] :%ZPu6pxi˜ ybKp)dnK\94NV4={Њf#d8o_~t'omBv!jpñLvZby2̻ ^*)x` 'pabq 3 x^Ӎ? qߋjh!ntM4tuЋVQurt-Zvyj5OR\)WJ$Օ^'|^~gDצs(̜9VBSįqF^/19LLg&G]q;v:Vڀ;Vx"(q`8",PA! tJĶwc՘#& cvk QwȭL OpB;!}Mr(l.W4vtⰅ5k6,\@tLw#6SGD5AӲ_(tFk2m7Va]##,)Ukoą|0#?e)Z@{и-.= "S;ήL"د!}|&T!Ȉ\l(Тt.$"UەN.@p)̓H1?Nȇu6g: qyp^5#CdW ! x^m4qѺ54u6v{s{AiՉVWIEeCdIJ,XKu%!됋vvξhxy>-6+ӆg+n*ƘVbTi5&c\.ԘgG~P; uZGn~.n/#FmQJRuOʧĝ,O})QbIYCV [N~GxLV֥L~gEȪfOVfzC +)wv5k8%Y_35%WN(#¶ MfۀꐵBH2&:Ƞ/DrI$,)L%C8%wv1'96pzE&qjEGRI`A5Bon0yů+~G [nLT u?R8]|\tŤ<4Ρ%7Vn 3qTr ̿M3MO7MʩWּp ~S?+PV'hs"Fk).)>YN .w2`UzTxUN1ի؅ 6w^DT))13k7THWf>a6)8K{!\hlMƸ}~ y=F3\3|& CǓQ :V_w,T7Sq< A D Gh70}dvDy23K u#Dh>V\x+ssv7 fԲG lCQg-l> j7En<, /Kԫ?w$͛t'Nd?s{ex^c`@b`*0+xb\,qh:Aa2,tJ ^谨rRb_]sBjÂ/-++pjx^c`@3@>HzcRryó7&EUiE&RM3.t8n d3!Պ2cs*:V[(x^c``d6y BLL NTa AUڛt?%ud+i"̋"\8vX.0cMS]Owxv~Q#?OE:심ӛ DC>ڡ=1IîLѼ77ȐtPndu79x^c`` 8,`bjdpyAU(?>YF2;ZNAEn?Npr¾#>Jp~>fC,~m+ndá,680/Y0g>ƚx^c``Р!21rאָҖ8#;qeH,qH`Rp*Yya'/|iyX>'0I﨤:3\/tX~DCS "nshv8p;Ϛx^c``(884(0x(8(ٴxPwn=<\o=VU  ,5;ڦ'ctXS>|CX.z/rY l8(sXQs"jX,XR-5 x^c`` `Y|!>S39hfv`uyÑ" {r:ayCIYϔ^rt\.Fs'9tE{}w8zyop}L 8x^c``p80pp8u^ZAUFծp*x8!J¼M th+Q8ơߚ/_o7ɡTɊ-KLCIm?185=ƪtAiт 'uW[W<x^c`` -Wh\*wiz_uhs pUDaC,⹧+tq8SWO<\&ig|pH'B]-aaOL2K:$Hܯ<WÂRKs=7x^c`` p48488d.TRr"ݚzaE.),&y;pq;Ѩ?P(7dcvCn_cpdarl.]wϾE76'm@c)H5x^c`` 0t088p3\ AU~;#e[C܄%X .1-P`CcoҋSw9:%sx&P3@|_r.q5šx^c`` d32802t0:8eQ`AUA@ꗤ&.-]6f4}<:!Ooͺ`~ /S29;Y<%-)kgI;fRvؾa^ NwpޢCفqN8x^c``09p2t029l%ƃGCzesK,kWp`q6+аf!jaŝm䗷8Lkn,P񿷬a"}v3&}vАn(Jvx)$؁E3x^c``q30*1298ok AUY\m54opvpsuFiD܏GO;w[m̼1!f:0BIrH;*}ҡىF4uӎN 9x^c``d+0812*)0:LUSqϝ"\kS9S zw8{s-mCKC SV P!y#8=x^c``8 0(4:ApLi|;]80~ vrDѽō4x^c`` 01{lU'cΣ^bB?l?FA2wvoܨp׻-xܟfD:̿`pFu.5[8,Qpy~a G4*9nx^c`p`*DkXmrÎm^fl s98.y0Wh@iu 6>:8L]wl%%o(Anx^c`p``l j ,{o ~]*px5'O3pa:@c'@3@*x@@vI.@sf@" F@gp@@@@@@@S0P@ @ F@ܓ@Iȱ@R@+ N@@X@y6 @ $@]K@\ٱ@H@.nx^c`p1 ,l U80;npRN)8p pAiF| w8\OYN%# e Vq+@@ @@U@@@f@@(@q@i90@qU@a)@aA@<@&@SĐ@kIp@60@ib0@;8E@@@@@@@U3@qP@Д`@8@@*@°@ @匞@@`@Щ@@$@͛@1@"nx^c`phDChZ]5Ï 2 IpS4!1«!F蘿C !n[. ~ z=+>nx^c`pP008F΃%~p'pCJaNu, p&4<Ü8#0Kl&)8\P&nx^c`p*@kXzrF63<8.yPz\3L(V~A]'ClVu'\*vlp(yP'nx^c`p`@cXߪ4퇓86.Tp=!9R!TD'OK8HW;0Mɯg8(g $8Z[8 %nx^c`p`hADChZ_5G LpS4ayb{Dçcl'78e|pPfÍ_8trp;'Q>*nx^c`p`P ,e I*8hܐp(SAl2 4o 88^gpq95p,ۭ`fsCD˛:'3nx^c`p`h*D({[]r bR5&848h=a(p(-lp[v!]]\w@ '8 7p`dgp`0k"nx^c`p`plVa ,{C )685q88L-b0pڽ |pɓ - Î8LY=QN A&nx^c`p`ĩ@X`Yx~)VL,5YIiLߺWǯ\px+8R2pS31pHSþ X%'@@@@2<0@@@W@e@)M @A( @9W @ë@a0@{99 @j0@*@ˉ@5J@H0@/0@I@@@@̪@@@3U@C @S@@J @U@0@|}@@N@@ڀ@8J @2c@@MR@@@`Dnx^c`p@``|˞Zc-є -BM Szv/p0pPYeeC?80t^`TCC_W8\QSd9O]pP3z7Ao688%8_*@nx^c`p2 *B ,lUs^pȡTUCÕ 2RS8L(`rp-A@i"@@ @@@@@@j@@[(p@@@B @@ʰ@FP@@@@DG P@Ɔ\@@\ɠ@$@d}@Lnx^c`ph*@{[jQ9kSKX0-p(lp[vʷ\w NpXnΠ0}l#nx^c`pP@ÙXv\M ^Y&8dY{%C Np; >V048TR(nx^c`pD@EZ]>s,cYa  K% 1p(*OpvCdCb  R?80)p!nx^c`p`9 Xvg  SM0E (6ջn?~fp3g[e68Luqgp8r-aҘ*2 7S$ t09>(x^c`2i άZs·7l߁z&kNr94 xߙzFW^srFɼsM|+q򉃒׺J3G\TFNvPx2?Fov{4 :8%x<Ax^c`2i rgFcaVZρuSCfRB, SwK:0Ȭ6ybÕīe:G\sɳ:g.S}>H:d9%jzfֲ*pܜ8fD6e͛[bApx^c`9 "'91t&SNrlƅS%OrX=`rջn~45aΜWd?8*iI.<k\0kȋٛ8Ud_v"Y)p%"iBx^c`{CH` Ka׷\k YƜۼfe88r褿tXڻCxDiqMǯrD[J:|R_]'!TPF!fdZCbu'T&qHwaɛm=x^c` pfh<8~\WJX75sʌqCJEa;dM{%u+7&pk,OqCK9r|2RqXzffnIvnv8D67"D@x^c`C;foK MaTZjfSR?Rv8h.M Nr`h {2 Cъ[~1ES~堮4M*2 _6sH)km @˰x^c`dw  ia p>L}UVΨw`YxͻaVX[bGUwص.yP*QZz\3Uhr"tW|rQ %Yh/0Xm p-vcʛھ>x^c`i 6VXmaamΆ9ׁ;(&fMUiG "?cp]uc+g!85-m8O>١VNwhULvX=ԷSϡAȷ8CJp0MY:Nb8Yuf)9, zOZw`x2[a1ߺO^;a7OPxviL5&g:l xzAhe -BM*1:X^9x^c` 080 |8k Soo5ax3KMLu`Y$iqӘniOuL^9ram7OPxvśy~-U:詙X>rHRew1N+0pPcqQzy&B2x^c` 60Wkl_qxzhʥML8\9L-b0UwڽuI8lsP C@x^c``` "(c=K!c~F XC90,p ,D+A 1*Ѧ S;L_ɡՙiU-Wr;42p]_pa׽CcWp_+0@@@T@@<@@@@@@(@ @0@@@8@@@0@@@@@P@@0@d@@L@@d@@l@@@@@@@D@@@@@@@t@@@@@t@@@@4@|@@<@@@@D@@<@@@4@D@|@@@@p@t@@@|@H@ @@@@ @@t@@4@@x@P@@@4@\@`@@H@<@@@@@@@$@\@@@@8@t@@|@,@@@@4@@ @H@x@@@@@@@@@t@H@@@@(@(@D@@@ @L@@@@@@h@@@t@@@@@|@(@@@4@@@@@x^c`:\g{.uk'* Sb~Rky7;|Rrz,;?ps/:+{딃Ƃ;Y0D` /fA_:8~s8`ȋ^/;Ws82x^c X/m`|}f[9}'2$pp˛pj}CQJ=~<ݘJVR<;猍"m .wc r@x^%=0 s3["Tx  !\^``p2cE?J?|z¥SU7Q2d5]52JEFjYS7= ߚUCڃי즓s:7TX5cs*p9Fj庬-nfBkDީɷMЏO{FEm[ o5 "s_!$fk tu~W*a*x^-M yU}s@w@=FB$DHT0韙8/e=^7uF:AM{'}XѨ02^ ֨ =$H7밓s`T]`es;ge")bF3a,g?$! -S%Z$v`SytD`س67cC) Yf|:YۧoxIWq gWF\-| tO+n-]*h"M YӟEEϵ˂٢Ss/*Oc x^-90D5U8 ` A A f姬E5uk<[ܪ^YQ/}c>3?k jL[q#u8 wfls%wMfx^A! y8"$ a%$$  +a% I:NikWEMKASf~>*Nu^ʱi+YЭo]qD!sAJLYqڦ2_ihTJ)uwK&ڀ@>MxC݅R`nxeP|[0#hG'gK|j?z޳}npU')_A`䁗΍Ybʅx^%A E3* $T* =J@B%  2|KCoժV.5mvI6TUV:(O%ĉKZ =_d ըRoG9e:YtێJ86^(){1atSF+q=& ;To<^vΘ`W"k˛3kt[BGOpL6aJx^}3pYִl~ZFz1T[fZOk\C虇[UhT21N5.\CHlSc/`w!]C*~!Scvq\m/pf<ڄ3w@0,~n#DgлaE2|’"tJPN<$( sN7@4xځ}_ R9@lq'YeD:;GxLK|J5"&UChb|F;d],rk۟$^lF^)sQdc-^0F x^T;O" ÇOf L `66D؈.]D䋑eh!Aech@cX*>47sW 5ǼoK-0{t +r3]Yـ-d?`$3P?uDA\+iqoiCM1d:$_W:rC@@|8;zDF$)ڥ%0*?4S3i1][@Y&>mWtrdBA.m8 1?>i~cm5g:a hnZ?-G,w'Hp튶XR 7\d ( ѽ4]G,\Nzv*&*͌iN/̝ p[B"C[`{Y3}|H=(s`寺+c~VW@ei-}"t+M h8h\Uu+o$f͞uKUpkW 4;mwWk5 /u&Tm50ʰ>))1!FN>|ԟ"O|ܨkPL "t4f4d"6"FƮ^ e{I aPGBJ];qY٢TuB.J`G1;XBT% *gT%2eGI&.0rֳmh?CRsK3xJbeG#j3!]# p{ ,3;a~*0 ezvp#]razZ6_wfKK\(Ir] e킠 kfhumlN>辻kc][GXK3 ʎ+ |QNxVe:/dN$q|))%2W i*KԈ7M. \3PCg}zSյ,1(,*DSiƸ֫Q N#RYыb_&,lX?*ώɣQ )QPp6 z! Q::K_ߗROWE>Y>cc$ 7W8Fzao(%63WO:$A/a 7L'ԍD_Rq4Oյ VYLb}3U ͱ}i{q?crn'.@78XY6x|@p. c^\8R`Ph.Z;:p4NޘOzq ]=+SnTKoNBa65u KLR,l*x^{BQp!A8A?`paA0 \AAA0 ``y9;{o&w,iEL7+r9=}K:ҟͦI+zLeכJ{eRv-/ h4ŽԲϭTյ/[Zgf:x^pw`<A /Ap88AAp `  wmxљ 5VΜsB@# 9}RN1F*7t'աQR5-?# Ղc=Uik3)*^PiW\pR*Pf%7jghxZQNds m} ;^(f[ jue:A>X_>~npWPhT29fbxC )f 6'Jx5uT nI2lx^t`ι( `0(@aP( APBP P @! BP eyy{{w4#v/A@UtғAtyzBmUs7ZK*ѳY)Omt4U GLz-_R`RMߵ9պ'fXQI/ VxErAYZhDyRə@8V72rBk`{68j@eS1.v15\E ;^{8os6s|{l a] 1C"o x^; QV;ꋜ*Il*b#SP\aIEljYb ;j3)бd8,_^bg8lD—oT߼T7׺:9v)$ɔ}FX0 3;H"+7ɗ}`_Dps( <SD;%HY)N,iy2^TD+ <`@ê΢y)6T+B|xóKlJQu`&z`ޝfW"4cqCm=F'APA.HƅbV;< 9Y/`.zB\/"#\~1+ݚ1[I$ObKk{M~C_hHj9%w' 9g^7|$aP)TVP٬7D_E;+v ғo_+Ow@nj^^}@F)L1ܖD[ #H95ڴXSƈ;]PуsDҭ_43^j B13ڨ/W=^fE#$4gMFh$SgUT:VvE`cP7L*ƥc/,8vĝ ^ʹQIg奰TM4G%\j͟xX<`LAR=J) 2-.?>t酝;qGc4WؗqvGmFX5PMt&R$vCY4[qжFOzCSn6C5dtgr2ͧpTfjgBIْhG ʻ=u|q:x`R^-hc_o`ԾܓIqytd"𢝭p1`E:]I4Ng4ДIEvIG"R[?~]n*<+88| n 1-'ЪM7[⹹dZL 0Չ߂J!ߊdp _H!z\'3DU64#ȶ h*}t\[mP4f @☫ s:6if^X 9*l!To*<+aK',|t;c/Xdњ%_qL& H W"Ho}3⵩" Q^]c?MEs)| i:v W6}-='a1=/YW:*PܢRR6{W\j~Z{BeKL2?1x^ϋ7q+^l+v)qݤ(yZ[jn]ZBqpl^^s׃^eqf}ϸoΡD O[?sZGagj˞`PUQi|de㫨7J)C{}K .\.MdvW+|CZqaN[ݸMl5+3z.MOlEBZ:6YbK&7͋eY Z}G ݷډ錀SĽ,F\%Fz4tʦzB]GY`fRM9e}O h̝hUy5ǽ(@uޚ׏R)ļ?#?BNY@b7.I{Ϻ 6{zqF!;_fNjEM󐓹xcs-H&G¶Z0+8` \'hLL}ln+l(/'#[%۲p_M}yjA /={q;hr'&ȹ18j/OcK[r}ݶ\9=ėe á (] oќ{ +ec ҅Q)Vf`CecvәJWxx*aS%J͑ &6-MJ5 \[8´|_SͯF'z+=9FӇYQ3׽0\&: U k?G$ @Y9W #&ֽ!Q"Dwk[l@dh$*r?m9:NimU4~<x^=10 DgpRWB+  ! ɹ$VjgѣCRѮM;QG%Ħm ~ XC6al32n*y4do;,oz`+aЯ֖B0P&/Oz@wиIrA8E zNd,iU-J WSW6btp3+gGӮ笆epx^1!D 7$ + $  n>|lew?c۲a_h T;&k ˅etU3m ^45N's1~@5BBqMZ 棭 p\NOGCʉ>i{[~g<$~}<*#:]+O W f/L%R+1vGrt+sۆשanNx^- \H(\pC@ .%P%PKng~aG֭`~/{ڴJ<[b\4wþ0fzx0_j%휓jXi0ƛN=ߕ9Px5S֨4L+T@54bVйD@g$A[?kt1QR\<3eIB;hse / l>x^-0 Cs H#dWf#x2GG` Eχ+nL`Nkh=CPw::u~m ]"Nذ3lnn6%^^qm@vl{6jej?R8lf<+nBՎה(o $Ss}Z\K;' uAPTXW?`@WLoF$3/h rY\jNx^%=!& $$ HX xJ |!p$  U3O6*:u}?zRyo?42yg v;AG0ϼLa~6]z_OG`S9ͣj7v6uUuzt.dr:;k4Fٙv 7?Mc[Wub_ ̃Ɖ8䵠@#2h2o*ot}ko+79Xxgnx^-=!yUn8 V `%^$  HX H@}MU0=|~9֬[ÊM{k?ީٲL&p}Vi yw&V}pSrltX7SjE,5ZvE!*AcuKf _. &Hx⋹iF=;cd%jCik_iQ}lK/!e=ړwIe5Tr>.)+s.x^ f*(^ )%@ @ .3hYVǚ'Qe۾`^/iwY޼N6Mv&co+=(V+hEքwnQU_؝|o(ӊi"[G\2KsRtrvO0r*.g$Tmx^% Dg\@Jp @xK !%P/%JJo9ȈjYi% 8 {Y8Q?)`# Ntv 6~sívjcTj}+V3>*~ME' r哎h7ZP]{:MCMaʓpu%Dkdv} 4RQ= } tMP/^{ύڃBҞZ{M$p x^Ћ7q+ZӬJ5Rtj4KԊV`]ԊFȣKʰBJG*tc*e;g>GuE}+Y<x=nsٞa#<y6[LLњ"ws̑Mܸ-r¸#*/L"([/Y1_e  a̶\}7XW}ؖdE/tc!O`I8(%ja e$˰q<]xEWmv3Gz+"*S0 2mIReq?9[^O{gukmux<'4ZVhW4aU:ޏ1&\%j[^>aK~ dO(lI38E }pV=!=4`Xkdy0y'-yb%qB9ZvSWC:ۤC]m3uu4]tH0JGGH黭vC[:'TfPlOèYX\)%wZbNsMY\m!jx3Qo? ' Up?*Hp^\ȭ38=C5c.bu7 ማڏqHAbr$>^!2>o(3jj 8S 3 ./eN !4Hӗڷ x*70@€Q/!x7-A# Գ? YçqOHw3 ӟ90]}M gjNuV*vU% PhsU20ͧ2S֬وLK$LZ/s~a*/ Z3TVp~>K[0#QP@y^*i;K/qKS""$Bپ n{ Ar[Q] 9R$9$uǖsqJ׊_>ʐ yLWZ5'BGmpp|Zړw ^&)|0=3 D{:7GXP.w?En571Je4( *\= CBUx|F Y "d a?2 w1ɲ(jRkן G V VXV3Eŏp8Win0D]<(E\Vvo L({HL[F j&fTܩ`3uo޺&dʨkH)׬!T=_/Ol/ʡ?U8`_,'gvs<&v lWVr3glzp{T{NF _o}gnDx 2ţuyyi K6E?F[)H5!htb9qπ%w:)9o 72enPMS4M{9e#0Ib=d{= 'm>>!0I#pyC릛^cne5/.,3 h.$tzQ`wGvQ"w<|L5L@ݳذ]GZdHgCR靇S';;D6?OLLx^-Qs~x\XX pa!\ ``a  `a!}wzH=*Q VKk gW 5$#rtTf=݈;Zz=ʿE{DWRȼŕrR}bo@;Ź/+M>:Q^Lwɷc8ĹVvVsnD)W|ހw39Xg$Lm'&t'4TxFttE& :ښbjEڻ9xDPxyoHmĉzx^tpŻs. ƒA!0( @0( P(BP  0(`P(-9'Th84TfS+=W|v4U[=mr\j6_J' oVJ4vNͷ"{VfK6ylKդX}pǰXpapN^?7{ ]5*R4 -!jںPU\!N7\87Z \ #q]# L9CЕꀇx=ELt 3n   AAAABB A.A A_w;8aD1mqŭ@;=j XdyuoK)$+~H9Q9dy@_*ԽYH: .2ʸUqոu$mq*dfx3c>,U] fʇnVF?TcPc9%oCߝK腶.sj*Qx>abjG? b._VLΖvرOֹgF KLʾubj{u&=r!o˄s]C)NYm_v=tx^Qw` .A00 @ `A0 @,A0,,aBA A5sy3~w߇G}%ҏPIG+ݵWQc^a)V[eMTrU 5ToĊJUUH-S ^`ڠFq?::_s84nCWX]*C-3S{}L,_WŒzb]&IɼDtF/S9ڙG}3UH⵶qGLIqy;2{#[˴;N>n*t -W,t=\~F % Ep6`ZzT\m &&xف;%7qvx^xP;P(  P(B!P `P  Ba( A0( Ba0(_{ι罇hrU4P2%-uiZЂlB+M*KgPqȥY.q[U'HfC2{|L-68:/&O-ݳTZ15цtc՗ݴՋpIф{qָpD#[[[0eэYs5_`f,#K}rYrϳ-jsmtY6«ͥnOfLAzzG2ցM7F%'E<]И픠U#ux^xP;P(  `P@!P( P( P B!P A0ƒB`P_}s=w_>Mb}iG3wtL-}HAg8#k%jRRtu9Z}}3n8w^.nfݢ:S6ySWIg8-;O4'@=s BqB(X7L8NuҜ9jBRL+#=XΌW+u>UI rn5DK;ұA"Q;N=P Ș*|6x^\a    A0 Ap0   `0 >}{߿ xˀOmH"%<9+f$|C;;;'Rw\17s&|,Jv=)Cr&Q瞵]A}/rwcD}A|-YcoYkʲz*x+]+I`2nnɗVhnC nUTY}"rffv,L/S0TO)3T~&4G?~aI{7;}˙و ?Vtx^tBasA   `pa Ap! A  `  .Ys<=}NwdD] KՇčY.3 x^WFcC?0ً)X BAFV1"kБ$a 6!D+HcQ 3|/>O#ˏ`dg\J7yp#w !dl2na]?g.H 7iK0;행?Co-CU\#`Q2Z=tIZ_0TzOcͻ]_S}tퟠ#Gwg<ǀ#»߷[1V non~$-MZ`kf!^l`ZkΝDZ_?lPbn-r8B>mh FBX0L.̄l#¥k)9*9p#r7.cm;aEx4{6~o'b|@BB&XgbȲf^E^:e< pI)@ϹM1+hI3j VWq kmzRL{/ǖ2i`ҫlx}Q0g g=~>z2?\ %.c>S[ eHcbrޅ7@liGv*W/XR-ؐ is 5̑3 M aqԥg8az<$6:aUi6Nz# QӺ1Oe`@ Z e@~Nt%a- rj(Z|kߔgh @Ւ*+EJwkh.i֠N<d|]ɌJ4.hc\) Eziy.oD {I7k4]E6}MK7r&É[5wrp^*p%C 5wh0rFv..c7-t,ߪ]ww+>:6F`Sv=*LTS{qLpS_K9d~7Ę{47τװM#igF0#.C߀l+-7BQ?r~~/A\Ap /d<,nQA9um(|/ o&^6[ӋR (@9JmPZa])z_`ߞzjd/'|+~GpIn59[ .~.TtL:d׋Xrң6ck7O^`Wkd"1KICG$`\;ؒZV\(JNUC);mf J&P;O08)2;$Gqϓi@&GvXB?ˣu|sٳ8*d?U'}sn7ӞT_RyAucګ{~}>B[K 01:k{c x^7q0d$kEq%NӨNceX Wu/& 7-Ң4Sɸ)/+$oCe?GOxJSGPШm,?qyD/:G:{TǩԜG-IR~ @b. Z8W@^tgZNaŔeldrxn4HP ZʶCIz4X0LH@Ep.MpfV3w^9)+&j \LtOY:›y(nzyyΝR2=ۯіrV<\钐ث] |]WX25-3Dv"zN0ɶ5B>}{"{M#YH05w\jK(5ހRcpkOYfΉ ֏l\P'v^{PJg7@T 7)+lzkx>nhtTIBo|.!ĤGLk1&vkrR}E*`4LF@̨!BΉk h [4=D-ގ^sDpgZ>/TYJp*d@Q-\QZfKVA\\R'M,Hh)`jCNS| =Q-fٙX[%Ԭc(s^֞d!C+Dk4_T̎2Ƥܩ_Sh%;"K͘(89Fwn (naf93۽h9xcu;G^3;Oxl CgS5i FESQhaS3YF]BXYp!Ri"ZMP4 I4轮C5 ZP ذP]]%1>۝32VɞyQ&jv5\ ߳㎂j῎B ˱aLЙp̿.X\4x^- D}3: \ᅔ@C@ @ .(%>`+ׇO#2uujף;A7M5g5Fƭ+ ԨdNEUq{a;!QD*ueT\Z;-FiΘw X ;Wp}W7ؼ:7rqvx^M1u0 D4hCౣ!xh```H't_lXӪ?-kѲM7eOAE4 /v 2R|S .62PeٓOe+ k>)pѴ$ t#ϯW"J&Nz93kuk@H;XhmCZv/[8<1:F3/ f8'bxcz_fwG&e"ّ,\BdH8ݖVMTx9/bz ʬE4޶بJqn7mZ OL[;c1KfDo^l8&F# JL-&˩(2&uH%{!kn5ʌ {r7*>)RBb'4 ..7!=.D4eаlcy9}VQ5@m9|܈ k6<"g"%GTjz>R`Un`Zς7FTВҊ 9)oE11?әm_dgqyyhBī0x⅒J7OD70%tZӞT3? `2!-6+NPxJyӰ֓x^Oby,|8ZmL ml&*Ȍ`cX@c򅈠ƆF pGcllIhQwrdZ[9wA9KoH^;FiS=vChݶTc'<۞i\igЪ2j%-+@d ݐ8ɷݎ_ F8Wd3vs/Y2Ǫ ns+pe/M8:,8a!N1БCǜBd-N%C1v">d5h3:;M< 'ZYCBhW")) h/}SP5P{ Od>T'W0QsAc%1XάU8z4\a=M&Zw3emx;GiF9kTّ wEqcj WAGܙ8c"ν*lȄpm=U!.|^6oԽcSE'lgvbUl#7rGc 635L4w9#~j1dEswH?F[Ȏy5AKRޕus͊}1I!⽮`(z x[5H4U2H/&xh+?t&!6Az$G%\n .cM:RZ.sk5G8B4v!: ôW5ڏVU^aFAUUqr#([l"f)ˍt 6SǏ!M&a>Nw<| 䞗O̲/iU'd3JpӺ~>I(ScwP'^X,b7r9@mJ[!a>:lq:H6vnJ6q*\?zoTt-s2(nVͰ0h_, 0O{hN }~K@D烏tv45'MC)' [R"/5hٸp@}ۇfz˘5U=ݦN/g{Hog3WUuތ?Wr^Jbj,|YUytݺ.h@d΂dv+OrydMɡ VSc[xįx7ː&+>.p{]Ȉy_X !Kb#PȮwĻOԲb 'o@frHe5BJxUOtn(WA:i?R)Yp. LC2Ll pu9dz2 "5XFK$]T;ɶ; >F_2ĸzI&o7nss39]m<;K':Yq?*Qge%qZW[.*jj+@CHW[V+qEѝR1nUkCE :+J[ܘ%gU6R}55=j33 AՑGzkάYR[.(v7%fX´pTe\=Sz uv ϕ;슷 q{Oc :75>b95陚 ?'[Fx^Q;`!       X  y߼y3{&G9Qh@k%LCک*X(?Uz˛ӟFVyUnN0' ~k}G ;s N[D*COc)=sMqآEa Do s[>3M-v55B [~ふUPF]@4+uCn/ J8 P&c}rձ/,O_ ;9FGg>!;&odwy1}J;ҋu:> `f9x^agϹ0 <`!XXX`a!`a! XX   XX~:s^{n׏<*V_;9}\\) RG(D -V~u[=*ӌ \f8'$5#%TDb˙awo%zVLy^ iZdW%AAkzS= )brdpl{ZFE >zLdgevė7GIKY=4CZz${g2*\5 Gjr] waWS.(2TY% wJRdqMK]|tNx^x`9(. `(BP B` @P P(B (BP؛&O~=~r6r4WT=SO~tVv>-_zBZ7xW>3kb =қBhW|gcx*E1ؒ=-ճ$lzw=_C5:'!>充'_i ˤLs%!$K<#f@s} ]吿?yx^ƻ>X8X    X `!  XX vߛy;;ٗ|TQ\})SZ-cJJPYNT j[@ʗ3tzXz"]TFg gbXrT%_Go(hUwt2PB}3#Rתb|Vl̷L+KyYFё.Tp443) $5, OꘑguQ4[p޵`'W~մ+[m70>wƥNz*9ll.M0#[9W9){ٵFx/PrΨ3%z;q٢avNo }x^? Ʊjy}d'i{J3ɭa]!WOR GMIсuIq̰+vEB(b43Ͼ~G@?P TWvqY~(5|pr@a~643=qTxnC_G3hfb h?C@|g)Z'v oaYkTuT- ߾i9ɢdzyЩ"ubo^}.08?ߏQnK6(hlAK啋VEmóHa=s25jN ksEhf%Vo{:@p=YQV`7 '(yR% CO*@1>)M}`~j4.$UVCt4Em`f1ǵ1xs +frq6szqӊ'V@mQJa<{ROJl3?Py|Q-"%I \7 &9#^Q;m$/N8/.+e*Lئۈ9nWhmq6MɆ$og~ZZ. de[tdDݙuƖQ7Rvwn%GZOoca,%q*^;!b;/H}ft ^C8x7FJ!W{X &"ӽJX3 ]>ťȟ􈍨p&v+p,j-e% ,!xp,%a(HH>ndZorb7K Ġ"w2@QZzfzppt̏nt|5(70< :$5J}ٳΧ[<5+>g)|c.c宇ֲE.lfy%^UHt-Tu);%̹]T̅2!b_BbΨQ"WS_p|/G~DOJbؘH.$ {tP-/ hnGbx_X]wPx/pYeJ&û9gƬQfEOLdꚚ2Z1\8*HMЛDܢ!$<9ػ_ypEVa\-ybqK'k3qse4ejOz%)Xg$:&y],AB%#hs{sݮsصUse?o_pjyS{l (32؆}a Ub˪~{z}1K^k dNKI71<u t^ uƅDϠ1f̔F֫Y 4gU-5bh ĠANY{N>Ʊ^];rG 9&)UOfBZNv#5F0dhҞ&&–g '_e~|9ɍy ' IOq1U"b}>$Oo'w[q_Ȑ)$*ȦIg7i00XA(:X\A>A)%VBJS'fQ 'ҽzt⏵VDQkz҈) a +IrM 1 G&{8U^5FGm~j*KG(M !DQ1Ȗ,:FY߆n̚z Cx^51 s3[P+N@$DRHHy%$D -3[v/F uUnG.͟]x/)k?˰+mdNj ?P>A]x蠕Q jL͊ vAc;ҮRt.a՛STBc[~ } :{naw;CwWVόnv[svqFsj0uSq6ߺSSݧ'/;r/d}x^-10 DgTT򗆐JC0@0C@{͜v+}Yn9ebms6{.kŽA Pl>x7d- Wm܅>_'UV0hVT /\Nm' 7n?;뤤+hbpN^S8JOZ@GO*7P»vSVe?o~Gl_ؘ/Š4YȺ6J}gaJwڥ6tGL%} &x^QA! c% a%  HH@B i~8vၣYBS:.^La2Z0xi"p$/[U"RoPfVP^#wS~so8= Xb#ֹ2S%m?+"9&L)sLUfo quV0m?zSkn9|b.&5Fdf./;ԅf4|A)x1\iR)30wx^=0 }3*\B`. 2 ! ! ufgW֮xdia%{"z_c*J뗥D |nn+| s1 zjULPywO>xcjaoʦu^kѹ;T y2 % ;<[{ U/;ʱ{Y /N6P1 &.jVZ&sV6VɫX(,;>vD^\fƮUpP|RPݲq'T]0 >\C'M}ƅx^%;0D}U(`  !8P a!!½ֺt~4ӥ{Gk:߬]EUK\(jSqi48\Ú4( sH\IJ: 'vb+(w7| :+1nDvw`,Vr\*챲SM9sILSI1Gx9? Î%5WLDuk Ttmz ~F׃xu}6x^%10 Ds3[Tq!  !商![ȑj%itjKjT- =gӣC-]1A"LS[Lgflpx36X6"3d B'H,d^]-Rwvi6tBiT=}*ڸ/"]5܊{XVX='x=<Ռk76nszgzx Wn6V\SxO_Q{d[NUiW}N#eoM^lS x^Ѝ; p[g"cE8y^L֋ ׋伿\*za![ݘHW 3w$/#a B=>3rydK(*/j!q^=;#o盈I :ا::PjV(FTX0! F > >׶bq/PYaJ ੈ,Pz q-pu\¹4 os_ 酘M" 4;!]M7n6!൮? G2@SPڟ†XE6 ٝ-f7xKBt;6l1 Үуq[5tTU ZL}#\k_Կ[ުQyip=Z*P{|-^h2v?Q rOd8m:]9{4*8H{v6ÓȿZ:)꜕"΃{z v!=}hrxsLF+)VtFa@'z&a0csTzSx}?H\v'aZ*ΫIbmdZU#g?!dw͂sMP?k2 }WSbMQP}h9%"1dyWugo Z _0jށ/"nʆ:9YYbosQ.bڊtIͲXACʺH矄E ߻4f&!`EQv-7ޖ/Zb(K{A55Օf ^MDQ?mݯ* rF/CȷW K?)kPe'˂i ki^!Kh` #[)uGlQV?)>70_*HZXo+TTe DÚ4?ͩvJm>n˜d%da_5sf:@~D Q>=Uhv:<3nl$k btvB-|Y˾Cu!/;4y[xK@̺ r(EBE,5Ye`JшjkW,d< X圗DNޚ(Mىv9  ݹء߅VlԻ֦=(dco8N2d<5+A lq̓rw)G~ \Hi V=tyz+wxK*2HK0h"^FQZ}Ь q)(S]lO"f_!]ךX"[boބvP > f .Ơ!eo\F4Br`o'l=Ϯ,3Jڬ*z^09qAFm{Ċh|Mi1'Qn3Qx%X?9!1_(Ҷ 8` 9 mޱkp| sw4W-5(>(  0(@0(B!0( B!P BP P Ba4w0_jh'嫯Vt'g\kJM-WwK# jʂUT^Qn_+lDƪ@%|g_PQ/*MN&T}tNrT.vTf̷#3t>q4ԻR/7^`B?p$ܢ7%,xnMcz,G؞u3Ta2x8X,S{OjgznJNd\H.Rm~׆D3zU8Xީ>pВBo35Igzpe|%N`-4Ax^Q;0\`aa!  XXX`BA,B0 BA w߹{aP<*ie{e=*U3t@M[%荒zr Q?`{OjMUTDk5#kZ4䦢:hڲ`s+ |HtQn=y܇h͡Y΃58y0xRS} բ.8hk.yֆP;1la؎dF8&WC8\jNTGj1=7۞"\\Qm1Sۧ&@eߪH k;;9C )m&f~'tbKq?  LB' ?֛x^tBQ9x0`  A0A0`0`0A   ` }^νޓ;d$)sϚ/"(qN>pIS6oI: wE,ElEYY t#qz=i/6Z;uO;%tSІs] ԰O&TZza a[/'P<<G7Dq!&*m֎C!ZC=+!Z(wq_11nguD6nT]=!Bz3LDi3kRD-[)Л>Wp%;骏gͩ髲^]pCt !o93vji&Z\u "]9um$8aN۔?iV%79mͬYtCr59_яBO+82۔J8l@ڠJAOWV#!K3YK:L#5@y2f_4RT9U32Sf4Գ-ӊ n9x^? =|L1}0%"ILuPf<ÄPBv#qYBd̘^%"ZSj#x3euy+ay2d4Zo(8Ah3;e O8.F!;Xu1E+:G89pNZFMk#RҔb?wkrTRoXbjprXb~Re"\!fX0'#|F"7&zIj~PQ$YmӖ|bsg(ԭ.gb4fFg@+ظY''ӻRU*.4^iE>j$j$ܣV5&gImfif@5Ế?0!, \>L7b 9y}z% }P(V>I@lUpdATg Ap"QrT81KT(fbڄi˥o~(V\Ur_Aw* {iК<]q +t!K)9䮸_ c3wGs/so{3+Q$Hz<٪S} B<^H }MdOUO^Eqc&-NoNObnĤ?27oBJNv7Г,Q)h_fPDTW&G1ފ8P9tJ lM/]YZ`֪M\[dzXqz*&և(&OlHyD6"W*ȬBi&Xugm|Uk8(bO/"93 .C5;{,<UYLf5ﻑ\{#UM\qbS1f*aɼsUZrѼRe{c`z#Tz >MΞ7B$iAkYlk0W(ۏ{>BECDΩ}pevuu }CZv8rUpDP3O"vk&@P_Yk%Y 6p} u! dԷǡpCy =7#a*lc SMah;q) 'eoh 3,U&ܿgnx}ywq -VF|s0:VjAVrި݉5yc)VVC1b\ ijjC=#$\< ŨBᲄYF/6G\BlU,2uN[φ2bJZ?E?h!X:CBb$)Fo K[E)^f/)'`~v ׭z6Bk_^-#X ASm@Ca\,hyIͮ[n`qFMdl!UdzNMb!Y^sW|M_gHnD[l6^ukYV(lJu`U3TkyG1' jPRCZSV_)$_[0H9ď1'Cﱰ\r.}E}Jj|q6>%lBiʈ%Pox8ƠsP'IDvrbM6 m ۬=o}X, ёdlTSp kj@{4*'Γ^{W-e`W x^ 7 a)DIZ*E"t(1Ե':HinF\[H%[(-JHlNH̙?0Ox:Ҧ9 >Fij7s'EŹZK*SasJ`$^@Xǥ&8bm8Ụ|u"gdC*(=_f>&Tv>ےY8'kV /rZָW$oSf,=B 4~?6I˘ݝċ5V&_Cus5ep,/ Ϯ"-S? Zݸw# AT.8Xcd|nxZn*ƆZO߰ؐ[uyVY?Yh2ؑH6/jʨq]gAe %W&{?o pM'oh4uU`ݦбGmD [E+x Ug(.,ս<6W?mJgQn(4iև"+`% (w tC9: ֿڟH=m48[ĉpr֯,l!)~t+'P]Asɑ?''uBI!]~O`z32ԖhBޣ-{ .8vEUM'+}J-v*8|y"ISI36!SEv~4\kɐ~\Pv"mieؕ9)1X!+Yue? ۧƋﷃ'6TнXƒ5CK +ybko;0$MӶc#_r=M 6ΥbB $jƶt=rQ\'fwR/3te0k)ZY΋{#,}}<\̛dFQO(xBtx^%QA 䱏}  H@*=P $TN%KgYvlH~CAnl<(xo]&vQm\Fgؾx;z7nr_5?nyQL9^99MN.-6z[šDV$ C{_zF*c$Irޤ<~$K9MYes̪|mk֎fX|G?>[N".H~e5Tl}Wb}J"x^-=0 }3*\pB + !\! %3vׯ>{m9VmٰͲĦ܉,rӺ l@_IBoީp~LlٕWL栢칛)0r%q36tUz0G`F<s7"Mտ3=ڸ4th <*%˕gZV-l3;lźߔ#Q鞸n^rUJқ轥Qʩ-EEM&8[x^%A DU} H@ / $D¾槊==3ݱ(+qjZtjqIUbgw ZSZؕ; B a%ngxJy+Vާ> ({ :ĦPjx:paﮌjD+1]$/#TT_Fڞ\Sçx;YC*3Uu87vT?{uS~= ̱(,kw_X]8c8x^-;0 s3*\0C~.4@0C0@@ou"jW^}YFlZ%Om?vJGN\5_0L\3΄FT"zN˶ - ⃢8*~j=e&XCsJ%bgzO-pmx˿ڀg6eŋXzܙ[VcF}5-{%)peW9T^v&Dhmq}`sLv[Br|q]L:r[?&R7{ޞ 8/ Hx^%90EUt@0C nh ``L5?~mXd_n/qgX݆?ć%I=N{ӱ8mpϋ}r*郎8ڢRޠ.KoL0*yt<\μwXP'dRS$;SgΚRm fh[tXɝb˽&P.BOad޲|蓊i [-iXV>O!]igi:6=uxN܄̬خ^R,8 mQ{ÃXu~vϺ ?o&x^-QA cas@B% $| $  ߾W(I?|duu[;2N޸Ψ71MDNߝ+u\ಪz~9& n`3u֒컨Ɠ:\"R%Z 3+7}FF/aj,'͉H}i(vȗ S4.S%0uQ0rCUx^%A! D٪8p@H H@Ǒ0$  H_?$N痟V`{mnĦ FP˦s1a?5m~g0,edԛxȳ4|C}EOHrkC*狘p' )mowȤ񲑺k_E3/芥]ܒ8 67n'~3 D@E1sw+L<ѕ\|3ȓFݏMgb]Sat^I u5t[M34px^= D}3 ~@ @pP.%@ .%P½3ؕg8mcj][-$md[vk0f <"YBkOwTTRӲ3/˨*HUYphSUjP m2E!U:BtXN˹0!wp::h( {R$@:oA^=5L1LN3ViN4dgd2HVf~đSx;v=&hȏT-tfQ x^;@G6C(RڭX*YY%n}Y#\3҃B_I_4WҰCgYz ?ȘYfxc^z=Y5Bп<cq>GIL"zTS*ϝH7oQʠoOh奉8ݕYFc~lwޗp1Ǻ.w}?{^ַP)6)w2Q &z+Y;fHe)?}X.iX}>{n$sP{Z~kI+\3u:щX߅gM7?4~oMDptB![$s+KRn*99%:F3-OYhSG#WL0SLfX7iZr~{RF{<`|H-#kH k-ك#ŭokO `4 ?Oj4۾>DGR\KU|$Kׯ{ \R[->_QZr"vQf3xM+ 32m@v')FQs$NȹڝJl;}s>[?&eUV2n/_BūIbtr;ASM7HWy| | ͯ{ G+]U\㭔7 gPOP,-E(txOAF@ɏqy <Cl4nY<:~ҫl8=Qk[zf!/PE[x.Wݒ sʂONOL2׎6bDM\wAPFkxh`Z Jד,G.y k"&G|ϳט)>A@SEG&[&OfXj.Zs@#aE۶F',<*'P#h7[$[h/Duv5Jr@7OF;\O{̀C}˸Zp6l UߞxT1rnL5ᙶ\GЕro R+P\Ȝgzb=,Jcd2V1 rI~*{[EG2$`뮒~cmRyT6C;|L)Ƌ$蛨/¿U1[JTK_¾Plo,W(L`G-#xꭓ@"zڷR^VPϙA (e6!)RS]~~vB*8"K!ʋY?p "7ώ~AwCh ]!|^ O&?uK[w ɛ+۞(W'2uo}4 _̶ӆo׬2BUXF34%;HncW(JA(?d-Uh(")]_BJPA3lle"0&m_^FIC[pw2mf@IFB%1N9|źOueos"~:"3WA#6&Gtf+ؙ0 }8ȫ!?8di~/ /`3bhNM$:xk[ce5Rs;M|^?J$\KnXȴCeO;A.)̷Sߑޘ"}ѸT3~ ٵ1(bu+)eeFYMc;x؏u21:࣐״6oɆf‚RE @髪)ww ֌] t3Mc퓪nK^Ƭũ}æ0(8 x^pƻya`AA0 A 8AAA08  8 ߶=﷗a~T *:j+QB?TZjUR:X'J-T#xWUNItP]t.kjl[+k\¥>N[H( ^]33wCI#ZˌTC\a`voN#i2s01m.sQi^$5 3Sxu.-ͅ=s_F>vT 8Y '9Ii4UiB%=n&ҸXvTUFUQUW7VlY>jOqC-"]#2ݣ1 v k b'mx^`ƻ AA0 ` AA0 A0` ۷o<TU )нU1gT]CR-U~*_**;̎ʴ g6.шV@($8BЧozvQtnMt!5 a y&'G9'KR8*{櫅)}T:ڄ$!hrc>vG k@^ɉX{|w-k,| l rr'u+klΜ,W_d끋ճ7z?aڱ55j& x" Rx^pw`0  a `A   `Y=϶wetTG{Ukrx&[iQ {T-'E6B!:ު m`Q*n&WcP釸꒧Jk9dǂ<:h'xmnv&+_[jL}TM™&c4$.41Cnw0ug3,Fύm9nE/3!9NP2oi;㙡2f3>&ho5ʾ? KjUv3߁w [(vW"Wܩ$Hpgv^,dşҟ:x^as.` XX    `  Ņ `a XX93{zT$Rtsg@q3Jn;mׁ(xjW:+G!\n*s*k˩٪~tTGK2mtW͆_l Zɑ NO݌\UP8׈*]!3!/tt Q_2#ͩ_c.|-% Br۶2{\ߩQ{.gP[_kRHN'ĚΡgΕ}#3xz=-S֤VБuTO" S~ŕEMt;SiwĦ8y;>B*M.8{0؊ɞʔ@ݙx^`ǻƒ`pA  8AA0A AA0 v}߿άu*j] 0OjL70SmseFG-Z TSaX<H br[P2wSHsi6@ayىW/ p[ں+9 3z8 :ZBob} HgWph)9 \8>љa]A@efy=nfSgWܓVC)!'K΄.Ynڥ=Y7wuɸf~> L D mE~&zg&NNs.=I6bNrЫpQ 3ח>J>?.x^Q;0pa `        XX X Xyw9m}*a5IjX I=f:9&ke'TSt^݈ǚjB[[娚ȳ.NBMzӍ\mY~Rv0AãrA0D4V{Um/ xxM38u>'sU!dK;0 N3=Dq =!s[P+5;N-Ru6Z),|x<ᅓPwͱba4BAn]' T+(ny"%ۘ, tm#!{m2RW֔X7]O X;%0UP`iښ`37#)!,z&bg?-* /2hHA-danTYKb"& ZjXlYZ=a#aYŻ(E0tH"!M)$#Rz^O KI:T5nڶ2O^d- c@vd8S;1_XHp#Ƃ,0uɬeG&L)%Gd=7犓h@kx]i\,z*PV!8 \$f!ܜ/4#V=gS`'+Amw0Qd"ŒvY@t& rhgˬHB!0c扞#ƓY\;׋'p`ީNcX4B$t!I]$I?C[z@=#}ISgoED?|zUh:/=zUɅ`8#܇@}&homRԤ*qxpLq4~VTZQt2엺hbye7%!9E]YH4au/n[eM7QnGh]r7;w:@z4]T8T~;rXG>- %1Cm=~_Q\3RBDfߖ_ȓ!Fb:C0e=]C‘ٻ^vK>_jcxɨd.QG#IaR4vpP/ -) Q.TxLt9t˂HӰ}g*ht^;)A{5zbMwIa^ D= (M%jwe z^9nj\r{OZ!}r>Ķ}$Rwb#y`fSB[NXzklOiWopt`1QWc$?W[sytǭ-zril5ʴv5<*n_D.0}玈Mgal# smȞ(z)IT"֡ I9woAD/PűV4Uk!aJM3ud='d:U7v;:23vA .~;"SQ^PHJDdZ0xV &FT,J|얶BPݬb[f;+ocn2"EXfY X;Zۜ86Xf9E`}0=Ypv$J/%H9cs?Sj*>Omu0>k4~ Cg*y%QS\x众jѬZ*F%htRRQK8ݐܻ `v0N!0T4[>n|J'6c<~w|8yHZ.8.]'v mq6I2Osx1|ٱY KS~(*U[ށ[rP~ꚟn<}6d5W%^#EU{Wo 4ŷR{9GZ!dP9hYIEУEWtTR0Q%/?%2,F x^Ѝ;Շo!?Z/^R֛y=OBv5%9t!ݲJ_r:QϸwX&ʲHytGLVR8K sZg>ؿR\5ֹ>)616z퓢2F_8QvƟTS9kzt{yܘ-v;U0cj']d9h\Hbc* &Wd~^(L LgMټ7Ҳxhαq䬭.b%5VRdԇN](Fե֠$ZF1Yy )SG2rqD&&|^ycSEZU ~j Lt[r;50|if5~K[½mδYE]h K3{]SH"<*_#PBMUяRE8J|74SWR{]!Ex X<]4a4n68&/+ĖԹ)q& ]i 6C3ᴛae0E Zq8IޕWp`&u5z#dbmSO|ɨ%CA";3ae톍ݺNS"v ,G[ϥm*Gǫ )/BKf;Aܘ4U\.ԯE8y[1dg`)'Opt*&YRGr3Qb=NDr+s-pYʹV*,v/[`'}.ȍ:`Py};Fyn*Hg`[UcY(1s ˺I&3/EeǥuGnߜqeb4 >C!خmADLnG1!*u DwR0/h_11MDgNq&VSfdhHtQCbM?4K>O?Mk&^ *ۣ,c{r{Sl%*(>@Xa~Cux=c^W1m~{Wgm_aS,e)^M[0he,)j{NH JLlxG( 5 n݃QWJ}2SRMx^-10 Ds3*T"0CHye +! !  r&_%_lX ;N>Vm3ɋ]_Ի=ߍXmFu%. 5oE(eT/΋`~DGrL.GW|e IŅ>6;2_amOs- dv`]!/h(YJǔ+p:7;\r[kw.\:]}D"_+aFE _a*Ɯ\6,rXO*ҬzGjÇ,BVR鑮[厏x^%10 D}3*T0C0" !啁`V3?WJgdwl_VvN>xI6ƩOtp㵻Pl()^o`tTN6 :_p>FꦂNwɓW )\A oMMpᏼ\.]_˻~2Dx^-A y39** H@w$ J@6  n/ {>+vxd.{-nnk+ !w_~X':mR?AF:s'Տ(BM qe/T蔨.7J2>-C,67QƇ:W0 =0*eD34MGK{*_]A(QƮ^*ggmk՗AN*gl}U 师\sbuenK=N_^5CNLfO&}[*5Sث?x^-10 Ds3*TC 商`V?^G]^{aɲ5vWKn{ 8xR/ myd;kN]Zq[sz+N'̷*Z;< A3jRhpCGٹ_) :}"ElMpC=&nIp9;E4|x3uD[2Zu͖9G&ز'@ΘiHM+Wsפr#焩JYLvwJ4/gBx^-10 D}3*T`. @0C0@0@e&bI/-;>=In͊oɹYӇw37v'|ѽ/`&j&g/ﮛTa.ՀM^D^>rMWz?e5VXRc){ EllCu ~?bT~EIC0YHX5 <?Œ@̶}EfN4{dDvK}^?P5yVvS"VHBVU m:wysu`իI GzQ 4萩hQOz{OVIfjU.WtbO$*vѸ:Fg*Nq}շWK>ҙ)"vh~E|:ǂڽyqLG1WGP,iIHS(|nlZ ns6pZÜUo#v%qoj-b p/$();FL۱f9UCYd{X,myn*yF5ЪܘyG -9N֝)R>5ZV.'sx:`~ؘBh"DiGAրGyD/>?>Χ&gU#f\OȹzX|9YKiFGս܃Nׅ )74n-e:6]x^V;Lj@E(DmLXHCCP~ݧ566R5=|hl cchBp P5Y3s1\Gc44@Exۡc ciuսJJbw"tw,mT;#C3׷ d(` sT<G^!,&Ƈ+(OU =MA :uhC(m*oD!Y^esU4H^mEugM$\X>tRXJޑ ?MBAkpmGPC\(e6%+*l/nr4[JvL,^"HZ x`E1,/O`eRm'LʰŁ:DRs>"p\oj7~aG|C.[V*; :~UZ1PmxBIMC/\&omd*i9Gk1؆Fq4g v)jKmǼ1vg._x>1POHV@DOH~|d|Y 8ȶzTO_,+g/˞рQG5i¨!^18`>ek,܃K*]NLSwd xDFT = Fg.12'&_?,!Y jNIExT\,Wz1z[+yҞ.nlFЕb&w,xTvVH޶|OuF^XA~}K켾|wi^ ij'VN}EV*oKxDOJrO7q=W}طb["t-\!nF~bTx^_ 7 F#t V3qoʉWmmoLWC8Znb­Iy qyx\>>FO!;U{sڌ_!Y L͵YÓ~&-FgTfU#KeQ 4*< 21g:+@G*8-rqlh|||AA5 D];drSnN G*i]}\-e54 2 c%[z g-1{r#9g6Pޯ{E'W߱8>ݡZl$'w)婅(?5g{&Ǎ0'm8vghE4;2ut;ir+f4SpV]AMqa#gȓx q=f1~/'qevhZP3wU 3de,˭惫L6RXc,ڐ0o/@Yǀx^as.<`     `!`    wNͼw^FϏS\55#Ϟ&:7UY}mB%*23ÙR3T7ZhG?RjQ-ҟR9)s}j28rjHtT׏o{pGw sG8N(SΨ6G_3EuĞpd 9ߡqÇ~_m4LS][QPހ^|yYq% TN=Bs`{,e w  "YSgnA *cnΠVTnj@:pyvptTfe(J\y'6-" PPpM%yyk;<5`Mu2Py)\䶷jc:WCIJx^a烁   8XXXX`!  X`! 8  8 yoy矮P+֧j)ȋE55I,֟zjY~ :i2U"PƙZPd*½J\TD0䚇*z|E-UAAU`ZDX5 frl'UKoԱ܈X7<0o6nSb@ TќL ms@ŞyAH~fh~mQ?' Sw JƖ-]宗#ag:l]m̒ix@AsxX11=\vlsV''}D=. ?kFx^QgB,,AA AA0A0, A0 AB0 ,,, A,Nowy?}Z(яMnK#v/r謵jGg潮Vf)1fj\ub|-3U զ:rFoxKlƼEw J'W8r2jೄ/WƐT&/&I{(vj؞"]|3(\îOM*[gByHvڄNCNjWԕ}Â@t+VwS.Cf,^t$ZѢ.1>3>g"0n(edv4u.n>{Ul~AG)Dcم7Z%q {3WjGTGϨ;!B'צx^Q;p!`aa!         f}{ys:n4Ro]-u^uuէrVU0}*B%3)*Q@[dOқƚi&S?EX˖Vȕ|WԆ#/ ctBEMTV-W tʎچ2~+ o/cUC*o[3bJϡ:BNN(~jk\|lψG:Ɉܒ[Z ύ:59 k;6OOi#ڷkoc@Վ6:[ [T.=ѭ"k:)cκPepwJ$VVR"$.6eL f#rX'hxv9,L~>°Fd' !dg4J|&WM^ڌXWń׼ )l]\[D3Dwx^awϹ` X` ``!X ` `    ` :Mw_KfʵV3[U~85W|{M}y(}UC7RNUh(r(|9)P}t e)RMߛ$2,#1s /n'&YhO2nSh,ảAPK"8SffB=T5eBQ&a` u(*>ǒf6R- (2F9MT5'1_mp3Ͽǡ3(nNt@ Lwt3e_3B3.qhLI,J`] g~zzl`gቡ:xa.wx^Qg```a1    X X X0X`!͛{ιL]5JzUr8k.J4F2@"}ZOІIq`mT]=M'#Gjb 9']Ԇ\r.*NZXOP >ly_1A+a X; q6dpv`: qpƷb_'{z(ʙzܤL;a~Si۝εƳpنΚQ*0*ќiR=G[ܞ9^h\Rh?㼤^=YtHwʩAް!SŨ. vzϙk_q7PIC|x^i4OΖd]^W:2gN2CD4HƄu%"Q)Kr( 3[ovv{8YOO fFv)E \-UބwXVm(L?7fUW#FN曑t2+EA$X%`e( nGi8hyHxc~M 0GU ʄ^%=7}m .$[$ll!-&0pƿ0W ] =J+*Bplixr]}&:VǨ剈<&I\.ʾ 50GU$b!rp-)~+՟6eC Bۙ1V|πqdQ=[Wq9 ZwVlaJԺ.k$céϟ 6pҌvr:7^xmP\},(qɡ {MDUg]J)n b<893 sd^Ẁjha$(NcA4RUUlHwsKfEEKTJ'FeYgwHmy@ [A Vs"+?!ۼo+$G!x-3] Tho &#tpJ`yd#>]fzsmU (hYy;635aYPNZQsd&Ꞌ}~G 0@O:|qJf0èoNҟ']O)AVOTIFmAEB7d[a(5Me=bx}lt{>P % ՍdB8ދi>f0L'5 X0m|8i=~z.rS8i)|`aOnjcyxAx:GLMɁ1 k- n CU/e '8;RY.OaV1%ϸzz`&U<I'f܌2~ Ыr2DiP V)gevhߛ0+Μ+J`HNNrҹO;Km\LC3%ŝTyfa(*Z<ĥ{N`h0HE}>uB3iUF^w HR}an׶E{fЗ$QVL1,ȁ1Ba00 a 22(y[zCaݯ"`>|' B\FdB4)j\t.dS.b3-+I h\ZƏEQXw֞>v[/nCoR`g2u5Vak;pwe1Є;lC^!ܥh~ M- =xL;(`+!%4LJȖ7;2pGn\ v}Հ2/|Ф x^;ևƙy|#ll^z$ibMD$)=6D޶zN&ls8k)*K˱H̙j|cO 9ݖ_-;Nm<ѽȧzszż "bf0yt[nnn^t{8JLVr:oJ0֗t=ڻy&.0eL|q%ҡΕğs]6>Ŝ:҇ϓl&I{v*M('SeOecF?>NxKe+N,k*k#iT#+2ymLo@#-Wۢ`+ث]W%ZO㹰YܵkLs]I#s}A_ {zyaq1>1h:D XpSեuyZ zb0ExhpA!9!<jo.& ?¬ب{߯r#veuS=i#ƠV&a)[8#֏KW; P73(U>I{)_t_!Sć㘪\ZbϪl/lzq6 A|_&kRS|FhUF;;KnRTͮ3p>v:mca\:_|c1uD)͘Nn.`^~ ٝy z5hLl=?:uYS vM46X [p:[lJkY<{䭃F[2KLLlרX<a=w (٣܂D'Y;>XLHJ*Nke(wm°. >(Cv\jgD[A\2.~h_AF|gϠ9XGl q^%e@ ^i!о&7F}X23&O'1a  _Qe OvcMm"֕3o*ytop5=1EX-<^χž}F֜$UIXZ̻nig~ϷŹ>zT,E(}rr 5dS%=$EIQt b^;' yުl]>iK2ڙqlݕqc3)oD@]gd"ĘAВ^ktr؈yYEKiXo[DfTBu䘨W}^M@Huuz=:2x^-10 Ds3*\" !\|)4@0C@0@ˌ[Ү/_\- Wng҈6Kdlp3lxv :/[v BU9Wpa*u֜:u?7f@ |.iz#M2KԴIzק%M'ΖT#k [.Rݸb2V+C^@x^5A! E{raH@88%$  Hh #aS$'~YK [f?žv:&gk»Va;uj&'Gyyq.^_/Qa4m$cS?Uc`W7555ýq`M]-n琫 dUO1枣kBVֈ=;쭸X%f["L;i77?L m)G_iҭҿ"ڑմ5:! }c/#Uh]wKU:@.T8M%x^-=1 /3*\ Li2!!A0C8[]2cEڕg#N;Ye2zA9$jxnrvF;ȍe9m-Fʿ\hx=BƫQe!Pl/&m/jjltj6XLѫ55{ƍ+*k9:IXyE'4[hSRQ UsECs3l"HEKuTzC~u IXBȊȇ_- }婓j5[}: a'7y|u8_}ߨ.RB6o1U!ql7 )x^-10 Es3*Tla)4Cpy!B B !ؑ,/k6;<[lv[wYfݦ-d7{d#C]wh17e'pz n*z"f.mՋ bIzﲪȤ':q ş8Wt#vY{ k+sDa?fEI\NgJ_myٌKxgǤ ihB"lxcQdOE]}2)J*],OFwl@D5|o [XJ ɵ͊m."8z9~Y2YvR x^?ɗWYJ+h(4*I))ݼXQJy^.%cqO#oq5&Q<~>:$y(۹4)l+'X! VSv XTHorBׁb}w;~XX~Is%9_:,W$J}L[ult7"P5xNɋ ~2KP0'ygAxwYb2nm-Xt -ɝSlБ qpIȩa*x|[J[V!3qk1SSgICx/F{#X|~~yx??'Ud?=(h~$ 2l.{v1UA &H>"qا!u邃s5avjXMev<ƋVgnP+\ě62hpx=ܺ ;!/_),~wZ+xnAD(mu%-aA98 {IKh-9[h5!t8t4B>A [lFWHuǙC;V6/ \U( 1x RNB#tG~A`7cjʲG18+H}=y- d䟆w Ō9ЎNw{VW܈  iS';ޫ!T[/,/W@ 7fL8Ľ :g,2*/̚2(؉(jrCB5TW!]u|PÒxZ&~)=Ϛm-z qdzXjrjkN5֊y1c|ow%Ky3Aiy`\Y-7q Gq'I?;zl1Q4L~ mfUT<-B%Уaw5֦OR Xy4{v#%2!jG1ƉXv^] cTrݾ}{S 9LKf\uxnG+'Ne9o>u x]b „qn<:|C14VAIA& A߅{&қtHG䣄8/Y =D':[UAIXMXNU;:$;.HO@'*b|ۮZb cξtOh)-^AÔAg@b4̩XDyފq"?^b[3NmH9ccyq^& O^@qmfGM\ZUø;·AC&eu $6n.||.@9w"3E[̘tͫfQWrC$N'p\8-v))?@LbR ?]dd|{jLޱ<2G,mS2r:"bZWAgr!0(A᳆R(o7P#LF*lio -FMHT2#mlsah&~@ܩLx,^4!l{-qE$ՓP^Y(i{UJ'FR6G'usws.+`Ecf5 ,Y;4'3ٱ21[Iaz7-xp`udSC)10e$:8/z$P5_ƾk-!x |p=@;e159 k7.`U'4Xo1tL p|Gu&IعL䳴?Lu5tSw:Ђ~P2CUTP(0Vn&l— nQ&!Z'l=m!8O}ԝ}dC>诇z DT5lMWǖeUxcswN. JDs+W-vhI -as{8gWb(ƅ69'eWG y3x)(e j5Q Vw=ԾB*N^bE@,}4   8 8 `A0`p0`pAApp~o<|yK/hꜻ鬓bM5xzUV;>o%[҇'l&BCjprex!X Ϛ/Zm]RT藺vCP>.0.( gYz'bkkESoIӍ`{*j!n|"6DSp;b]ŨPsAt6=u**c#WO|RE4oS+P,rr" TlD _mz%]b?уZlzsD_+ZSaf5N95\C+t:sC7 2j9z~5 N j}>Iޡx^tPƻs>@P B!0  PBP( @ ( BB!0Aa$=yya{^mLj,rYDZզ |ov6k@#MyS@LBu{"IOpdGd}0D: Ӟ0tRoBCg/p c_a bqёPv!9N3z20P y-G6B*i6g]ƋMthWAByϝ 1%(2x^`ƻAAA0`0 `0AA 88 8Am}}{*[.KSHUHG .ꨯ2җ kI, jκDQ9}ek6x#h[Q?-`+%4D;&cQ@{gUW=54{wv4#;P j.k?! TP>>]vpPkg-v3* qW'䢜sTP>#kgB7b' 9@a /8q$f^Yθ1Z={ u;QW?ahtQZ0#"t,vMpgĞ' w+;Ci23 rv'%S9pg)q|1x^`ǻBA `p Ap AA     ^8y%|><__+%2i'}WҒqNJٍԒWr;Bm՛hfj÷d 8z.` * T5}rpS+9o![ T!>qSQT *<|0;z8Nu%KyꚻI`` P5 Bp8t$o8ѝjh#1Cx6u ?"'f`1\ R=mtPO܂隒0>.rY.sAI(Y~m[@Ĩ%o9-l[O+>bְ`ɘK}@?!sVX#9:רϜل3¥צ{L;,]?ڭx^`ǻ/A08` A 8A0App A` Ap>{>yBS>޴֋:vCr7W-4J?uAϮ=t֞ wNc0xj,䙚R݀rWߖnTLm0tI(Gx OG3x8-Q 舩|3X6x\'#KW_s\`=~OtTÅ /w6E@i uJ;9q~ UizT(2I<~%CߚXwAe¥veb2v z'*1 Ebq299oWW(GJP[t7&oצ.Y}!oD%a}{ WW7RP>x^pw`0 `A A0`AA  `p088[OIU]S]A MTjU~Oo[7{t\ uYT%0}dXrd0S})ӏ>运*L`66#o P-[M&sxIPPT:[I;= 1}הjS~ 9~O}N`89Wpf } CiԩL![mq2rD7#]-(%]_lpMO2,fW&m \D5C9ڲhçx^i8-%EY+$B%9r+N cPԠQ ƌ"11rǐ=KRՍ4t>} @_td-aPz8Rzo+ɚ,2,źy5 S"3nkQr)4'w<<B?t9[JC\J$2֥w"K1"uAD9"csNm*-R s7Gnº׉PKt8c8 eB!C$߁Y{=ipN8D`ji:6q@g5C j$gY,xL 5*YmERDdd*z\} 鏵U7+aچ"~>:OMns\y' D).F{lg W@p3skQF?T$MWСE5u݊z >%s 3l|)r K kŴGH&e0X_1S1/cu/~܀g Oh&=&9ÑR V{@"f{×@r%/bɖ#(VjN<~սP/E@I+"HDI9RTLR2p2YRLv[_[EosٲD &1roQ^/_ۆѸŶ=G1[XR uW U*Ln{N8Z.p6 ߌ%C290L qKHweMy^7.58;T|}^YD8NB9d1:UIZK`4ޏ9sy)dh/Fux2dF?.ݝ 1Y0^>AFHtj5aMĪ0Vꖂ6g\J=w Α,[vՙ[ʯlV'<'B7*(#:4C?vF0A?kYVDF&*Sk¾jZ ,3/Sm[IJL+t?\5AC4|@FNl ( ZLꀥMF2~auAU٠W0呑Ibv@"*\MN_ ˀh܉lpTuym06Lܘt*[qOHm[E?æg gf8i'P>Lrk{(6w/Bg7ԝ,/R*1>;̋܉M/䲩2CjQO8^zeE¸nԣ6UtS(cF;iNXiF{UgIɃ=fM@ad~1 ejBlpmHݟut1D,Pdb>$GZoR΀y~7D=w[eYO|R0W NB]Q%cLuZ4/q&H-QiǸY+ \ˎ/ VMd(nȅgAA#ɩ"a`}QoiBtdmk!r/w!}djwܳi- H\y6  ~F̔@#m?h{\:*m5l*'z:f;F>1}e"8spe2=/`7k2-3}Xp NBW)aؗOhXՑDCZn(:cgSW[AUk Zf?d4A™͠b^ȆYNDo|,joN;R/vXS)=%yNcM4oJʀT&Ɛ+5 )@+f(M2;a#kLym]u뾊ڈ"r9KM] @Q<@N qz#IX43ߵ0O7 tt1 YN=8qnگhk S: eƉ3NB1*,\U_FA.2m~#яDz"SaC>ӌ58KlGW[ݓ`v;4\Td?G\N<#<&k6< \P``_`R x^ ;;y]D:&᪐0B I3HGR$5hlI"n"S)=ô3ܞ}>Ap(-b+}R7wͣp0RӭŽHR\>O,lF>@q59n0΅Wd=5Jh?Gm'^n~ziFm:#2¾ݒs]%_HLU~ >d;J83Kk;0W OMRuk0 iͫi=vfnw[7?mhLZ5\Ŷ`\6j|j^`ǨFN^L葆ҫRoE$IFEF(ϊx/O?V@تtGEEg9-9)\qO;bgHʻS92 }Ϭ;/*E7tv9;o^BtLOg>s;3*w[l:d[2(ߪ5eøg ZK>:\J%A!S?ϱl~Vlڤh F^*ʷu(V0 <] NLЁkS; (0ދCtP먫lUM d_vnFs埴Mҟ碯ث!nO2خArr[O܏2]Ȏ=3%)Z\gMs}$wTjoA4zHSΡaF60qn O,ˤ5_EVt"Srh LJnRhu$p|~-sX9soFU+aLMys5pX]~VW(I}ȎlӤ|tJ!ioRd#щ:$˸BD[c6G8)BIah@-Ғad8ή νd&;.LErX۬$hs͍k 1?eN^IԬ])D eS3 C'9aS6oaXc70vzH`>9! ]#Te- nUV{Cc ghJRU݉ڎ>X9]oX3? Vm]oZzCZx^q4}12Xι /vaɫ fP,պ ?M><40jf kp u]@:X28(B;6 Ti~Z< ZsKLYYMn5NLeg.QYKY$;3jl|ˎSg\hHr p;RrD %8p#MVJ.p~y;d^n:6Nx^c , lXlX6\`i`1l8el>y X>8$l`Y`exxxx@|@ <<@804\K PX< .8l`) '8l1_Wx^c 5,l6|``3`lXl ,VTKH38< <`YȊxxxxP<TlGx^c }̯i3%߄&6|3J,~{gb_1d-obe)~~̈́U`tM%뾯6{?Z˲TcYC"\ XZ5x^2ٴ2~а%TmMNX.\>`l^N m0^2ul6^g1D ,hvYX?^`>{ëY:pFe(+ˬCOXd3!*Smm^/vQn*W,5,yoYh׌5xxxxxx<@<< <<<<|`+l*@,s fxxxxxx<@@d<<<<<<<<|<<<\<4D,=6+ ,wlDX"6sXlr&@q67Xl6Q`c>,@ 7,-6/Xs)xxxxxx<@<ɒg~G [_{/a4@KM4 %$&W{mm&3L|؅,?csQdFkǔH|8²ȏ4FYY'˃-9l2VƳj?f˭,(fs8. Wd|67i_pxy!SlTnE*0g&>V,'-|ņa,KOo4{"mv6ֵ"R/Cx^c X/e9sMfИY6_ M\&/옾6OޫqV=tvBMeS7y<6rX8Xj*Tm^бu3l1ݻ"d>ΆHlmoeQcUwKmמgUtF{1 lNHqaf7S10uF,YVmLeyx^ 11/3[|i/ e! !D*THZ=^J˙tGӗA&5lLu'E7dhrfxwPc3]݃ ^|x^1 0S?B t! 2v B(B(@([`YiQ r_27M§DW!ov[pQs|//34ݏm:P=zHݬ$_|x^ 1 C.$T—ǎH@** Hː%oW1rRX!+Y=dZ6sM$-` gRmAo$x^1 C2tD3t@ȈJ@B% P ].?:xhE:_t41bp>z,6yo \4:< rX-#.{x^1 !d  _^AqBI$  /)HfnOQ6t+aZ$P,T5$?}3e8۪޲x0]gXwL|x^10/3[4CRe B`|ip jG+D]L:Bj2:k<2]^vսtA5'{{T,"}x^10afD"E$ !()("  Hnn=uLruowC~"A#>W"ODѵ5ewlI"^-$tx^; 0iAp`peJC@0@x!)[H>0tIяT/+z[T&4s^`ؼr3Cx^c Xnܸ[f RD'tHrbR,.˺Xf,_ej}cQfﴴX*Mշ8d]˸e0;C<2Uâ+X*u,+dOؒC[;,Dg'wTnlKNؚ}T*^}Kjǵ67Jh0VE~B ~"? |gj_nYW1ɅȻqaN'+`4Nx^!PDD '~  ? ,h0 @0@4q̽xh֊cחR-OVuD[/t8ykݩi)MMY/Y3A3"]9@FrD$x^`yp  8aЏA a0#`A0 .\`a`a`񃥁e#@?,9wXXXD,\X0E"XXa`c`hz ),+X&ڃx^c56 X<,İ0ay2b KP K ,,Xj5,),6oX\0``I`i`~``aѱai`ba4%x^c#,W,8aIa᱐aa `aHa"c(ba  3,;,X X,tXe18T#Ēy[R klh-Nd!Pv1 {s,dd`I+p!xEӆRYB'eߜ"~(ܢFDɜlC=wMI)eGO*+XY֑jq'ij+I,꜌wbn/cyrd'EC#,^b=ɇc,56In(/RТ,dF-qbl$mx^c X/e93KkPEu!,Ae-NN}(~2CwXzM{jq,on,hHz܏eFYgQn"eEQ,ۗ6M?WbS3w ,XO cٶg/Z\l^e>cQ 2Wzw,[Xf+`-͆#{,%6,?,tgBUg|'Y,>y x}(nD~:;-6NM`){b|!Ů/Vչ,>OXEVde/NFx^1C!D+(+R$ "EJ$  '!$ !;y;+&3p"y[tf1'dIɖĝ ־͹bSKURZcO][dV<,x^10-\>APEʇ`"EJA0CAA:b3ʯe61WOU a[P."]^GTKj\P/ZZɤk3?Eӈ+"x^1C!{SP"!(H$ !EH@—/!N@3޼W;.S/j2o2p6xX$i.*mi{ӯYi,j(gךXWq9S/ҡx^1! D\ H"%+\ H@I@B$  /M23?0J񒿓.MU[qkؖJtk([Gl(p-~ iG]꦳C|/{Hiv ?ul-x^%M; 0 ̓n!! ! !:B B B B %>>Gv,ƈȤ/eB72I?&EΌ*ߤ(rO&X ݂JSk,G\,"x^10 3[4@p" C2C0C0C0C0T褹<ڹOm-v``!-H#NZ4n$$mɜW-󻞮l;i/UP.ңx^-; EfN @EJ$ !(S" $  HxL؝߭av &E:jNm4+x*})L4WK=MA_Q)x^11 C  n B;t@8PŃeYawh)LEx0)U'H[e?mB%*uΰjrOr܍SM?t*x^c Xnܸ(ڇeg=D MUH?ɖoW0^1W&1Ù?HgfIt 0u3&,E|Djݍ>K=d}wXR{.Yq-qOrxX44x^`9`?# ` O|0 `8 0~@}ιsY<"^UJ|:RsܹX+*Ď73f5{<2#Ac-NM|0بb偼b!fKLfO#zZ}T?H5vx^p0 A8 0A `` p` {nI93j)N "#ǔJ7j#}"$*9jyD c Fw|s ी'ނC,' qĜWlnN=_2Nx^`# . A p8 { A 0OߴftҞZJ7L 'au 0mKċJW57uWlj<+qT;).'҃%2zx^`0`8 0A A =~f| YaҚ'Z&L T|tT›d$M~tlܽ͑N镮l}xoTc*NZpgĔMۼ36x^pa?AAp8> `A0A==xsa|杧YϛdYbkSrN"_@Fćp$"?CaRǶd&cNڅBg-yЪuB!U[ ecsjG7^x^` |\ A0A0  ?AA0{O㈓8$Y`:Rל)W#3N+2CLnm4oࣙk FyRO,8Kwr<1`vkZBG/Vx^KqP"c5uR)od--պ[&,īrS]b+T iN<*LE'E@/oݹ?̆&T3 2S2gx,.ה0HH܄7 bZfpm í$I)Ov `*\QwS  V!T;!8Ș}t+o" lAx#٩Z+RKĿMCɇix)`qPK6<6=u u;}MfsyVj{o ,T6иPtZ I^D87^G/k_qj6 x^c X/|'/Ȣs^v9,rR,g=X$4s,Fz~7AX^LxaD,vkh>X~sɇ_Y)?fke-cTGm!+Y}܍<`o^smXXN1-R`ԕ⵮%&WXd[𾑪gd,ۄX~<} gR=n_],侔L}%ۭc,oir{&Kh^.8zjkcR0e랩,_̺EDІeO*Vz=_XXfIG:5|jdddb2e"WgX} |x^1! E_P" )VV( H@${ Eȼy?AU{іYPWR3Yz$e9[UNђ V8~X柸7mPقmiIil-}=W̓[+ڻeC@>L5&x^;1 DW<0C0)RC0Cp !hfYI+>6r<ȄbA㠩2.MFAɾS/sWikn0躶c=ߍI'ig+(晜5ią~1x^1! Dق HHAq%+$$  H@\flp[CϝTc'wЭ8ҙF٢T Il p&\2i^&݄R ykh:3x^%1 0 E}:B  7B!B B B!Uql=(/I{jԗAe*:0;qYMUv0!+Jn8n-Nk@UQ*~wt} K\*TPk Fo'0x^K DU}q$DBK$  $  HR5娜SY.uO-5~!TM?:t+|))փf9˨2즚 2 e=.^"مlO$L<9x^; D-R"!$  ) H@ { 8ۭ]jJ.UY;(tDuBIU@'8;.-O!6`Ɇ/ٝT>uu;J&(v=%u~}Fx6x^1 EyCF$DB @B%TcG$TB%T$[X 7/.k]bj9F .uQ(jQp0;E %ldnlAV]iNc: '5 5x^1!{nD2v%  :" H@I@PKr|W',p88HVm:j{Hotdֿ!td^VTƛ!~ư$Be7x)G|}Ss$2x^iOp`_[ + KZeRbb@%J$eVf 2cEYN`v V5@2-&sejE A>p1Zg0pF "3mGhťv3_lg߼Jw`!`Eg>E#}Ll@-CX7Ky.fQKnWW v\u}Ïhi5`$&Oy=E#ڠ4&I(,?ٶ Qޡ n vP&it 8 rz+HZd&ܗڮ ["7NC+8v\.q3<-伪tkAWv%wZgSYw9a'̷K8J.VXm ** ͼN-p1bPw;U.`ƀF*0( |رoE^2τr`X:s40Gq_<:uQʗM?{N _z*p߾9؎ʼa̍,cl  ' O r$E%Fcx^qkAA0 00AAaA؛vfwg}mq/ dT qMM刘69ई&jt К99K^%1t$ׄ~wb s.]q<9o6,P/ף9nx^!PEu`pE# H  @t`0 x?sϹo+&gR;:5EIlيyؓ Ŝe){\؍NdO(C6)5W/%TkV*邐y"b;{)]L=*x^Xy^ `a A08A   A p0y=#h=0iņ{vd)26w~SNsjy卉X{;V+ix/PBʋ>x%|}횈2s$]m-?Y3(d:fx^qůA  ƒ0?AA88 >@ajgvv罷mc/^8sCqGmfɓؓ3$= [Y&dY{l+bn(,SQA/f&H~-Ry86PRB/sk3.JkQ[̔1dҧ4qZ,n[_1c ;6>x^A x0 A0 A aAAAAЭ{{_tpfL(/?' 75xeEę +lmCI Ǯ%+DJYH ypDTmS[G՚?+YJ]ln'] YH*jr}q;x^`A0    AA0` aA0upw{Q $%EpÞ:񥨰!(ax 5Sт=6+.mcƀ mix$1dD<x^/pOEy5%ܗrtZzqXSy !Bs䮢/)y;za+j7tͤ$dޕZ?g{, ASBSQ@MSJʫiӘf|Nvhk. Ow^T0kܘ l ]-,9@4f^|w+O"eXvlUk*3Dbe::{&Zttcj0w~2(57*GJ;ȿj3YQ7L2 ra8CU}aXXA_vlM'7=Em/ObD9-.(M?a|dgGܡu(,ŕC"9X.ypXNsCB-&BDL"ےNMgm[P5ER^ؽgP0;X4Gwc2!VJ \˾p‘)x3 @µPc i1XD*%{K' v o@4թTGj\k\'/d #rW04}{V"~ASI߬4afBU{I(#~?zb".V-%\5w,'wWZ,~#`]W~@ƿX_֙}\:O)&Br~B`ns ^O*',L$ "xK0AZjI/\[@x^́JQfjZ"mK&b aVjH[a?iksk9F2fXVR۲&)&!es@MX䜈gHR6uBv1H_vEWUrو'Կ6)$f 5,[}Jk p# g{Tه;JQQ{| Hp` Nr|PyÉ]'wc]n]`Z*{EKAy5-Hh(^M3 9Xq \b(G99+ Beh*=a/??0in2a^D#eYRR(9i ?nrý+ҟB7b읒}ۘx^A C39pDB H@BCX H@JfdRJ__=vT'Z 5 ιZ~MTmT Ac'ooꈾ깺y.X,6q$KLWLxsmO][_l+z':*x^%1 DD   HX H \(0^_6M k(quUq6%jxG @VPߚٍ Am;sܺQ*h6MNCnNȃDZ=5Ur@/6rp9jx^NA! ۛɃ'{yO$$  H@.ҴM~~|P02=;6D3$SΨTdfu8!~SM0ЯPKIu=Tt M XbmLް'D0ш9Lwײ8xW=x^1! D3[P"_I8 H%NI@B$  '3!fwg??. ՓVll*Gtʖ15fTܛR_<(xx .l]$s;4`߯rG e$U::HDwYN4ٓ0@Zx^%A! y$p} H@I@٣*T2y}8t(Pet/}tCA P[UYP H@{" + H@pii I .&% M^DVE0x'E|8QE]E M7ǼHjq/v[˜ 7OTfb%nٜ46%>x^-A D! Dd/ ="K$  ;C}iB&wa-4t䜮A2Ьa'dzg–b93h-Hف[7m]:nGF7pzftK}/T*tj,XIPlVyBx^yKq5T<4}+k+2KXC')"RZ'hZv97fd,Jz=ff[K¿(Wů|'huט׻'S*G"h,Do#K48cȀLnP#"{Y\1~ _Qy911Q *qg9|W3 & aA,VQo|ρӴ*Ҧ+ž=9sSw?&AkAdv"G؎c*PRJ@ D41T}UM DIeU%Ȑ+22/e!b}Z/#I=UAZVY93@XK:^1>V"ES2>4ؘ (6o葈Y%˞)"=ȅ!e |LH6-?%sR\-$VY h2pg rIkc5#lw=tz~B'o#[Qn#8gYC0RQ;aR8 HM8f4N }x^O ]U|@ҥ]H/(&d1iqaJ"xP<<􅥋 噰.MEx?}׿ 5Won63" gnV} P sH4[_M;, V#e\C `/e6Z-GYgq!gO.v56.'=hlP\]L 9 |LV-dycS<.LWgۤl=/W;1%J,O'Qѭ7D)$M rs*E>K$F+8 -;)Ad 9z!n/>DiOb}؋/.eؒ+Dg_!ZU 兀0`~OY%j0*YR"U/($@_!5UwOx<>Z\nmLP62f9ؤGm}hs= )/M=-Dr]PKspZfjCx^t`s @0b0 0( B`P0Py7Xݏ7b&8Ċ&0#畃| aΈ'μ|, x":vX ~a*ysDvU J-ʍ3B%~oҳT'^[':&KFYjMΆ+'->x^PO< AAA `0`} `0p0 ++rXPX1(h%h5)[6amitT^+/}Gjx^Py~0` `0AA 0  AA0`t~Ô--RK{)]D<8[.tƝ cؓᕷ?&OBOc/1BK_[)ϐXcmOuYs.%;V$4;ԞX>0R[MQ}>;uȴǗ0nGރx^p A<0 a0A@0A`0  ;ν}?7,ņ- zvND̩piܤKsL#RR\G]B);zL {i.-e"2qqG E1PN3ݱiKޒOQo-V Ix^QF a` AaA 0 XXXXXX`!  ;3w?xҦ3͹!1]L9[КГ# J@jX7C uIXbT2]s,gLw֖r"6)1o g{q&gSirqmN tFFx^mPt0!#BB6A0/ r th,T@ޑ6R $lFۀRF &th`}y?QQe<1-^<4#Sȿ09&F CKbu&]w\I:] WU&$uU-D"UOOͼu>(ji/{pؚrR0d>/TvH!gL_(@u҈3K7nא .ˬU'xZĤa\"^Z7&|[ED5^a3z/_BŁG O6TMC qhאkcg%̎zɞ)ߋrԭm|e #}k[eFIKIT#>A{6ۢ2#anw<^}Qj:iqrxG(ruBdH?D{E>k얶=/ʌR̔lSICYy2}\F ѠQ-| ;y/sΈFi'*аǟӰx\pcC;aV(oB 0P͇lrhSrkߩKy~SڊyaaL/T"ߒP E[8~=WK-v;ڧ{Ez[wrB捚3PU<>&k<i|Cr5`e ugBdէ%8JlX&\JFZiݟE6۱4}&@vXfsNDlu #5x+\V~IBEs1mwhςOR0:!x^/p9tÅ6STpNf]]5c#.G]7vׄ6 ;sh-oD%7?$ ]nVڵ]`SIHo "c-1z( tȌ>90И\MF9v*zɧPEYf1"4ZB} \ZLWRWH&171cHF M}=hª!>d^ߊTv'ŽzO o(B&!W>TbtV30:"C+BԎ@#?>$U g (…| wG(+F"]ї*:RO6^cP&em4IL܁I6 aT`J2% l[x وnQ5h.Ӆ0L0y"8kb>kС^99$&K2,]g\BQhglRwxgA\KÝՒLu|sbOx!`8fb~:x_X<ͧB.=R YNiGֽrp,kwIp % 8\EPLU5@kBx^10 C4d,:B!!   !ssK"Kqtk-M N5uus:][avtd.Fd;aAmMz,4)3R^ݰ4Au;WLxuy׫Im$lE;a怷NtjRIx^-0 .Rh,Rh\eJ4G!#hoG4Y_U*4^EUQ3RvH:ٮ?hR_P"a\"ԍ)VW2g',kM96q8Kwwa8:;֝LWx_I>x^1 D3[P""E$  /# H@" ߅nvh[]iihli+IQ _iLiZv(Cڠ3sRLSaPKi*\&*}1}ZEU|'aQDs_Ȳ2 7s$:=uwͳ+S?[G^x^-1D! D-(@ $  W" H H@mGvM!`ӰQeL$)ԉzC1ŘڄChW 7Y#42[$RTTI3m9t1>Mމ\r3s&o`Dcل(Gegs=^d̴NEZx^1! >8 \$ ~xp TQ,3=/GU* K[,1rUeq Ǟ5N(؂u: y"?;xz*d7fm8s;}HGlm3 {S;}eC{D*x^ D9iBJ KJ B@ .\%poX|8:5cTW*5o,i}`i)5fڙ*hz-{u(+Y(h B~2[e!&'Uv FF{uo7Y死WQiOv ׇltioEx^%1C!D-(@IK@) H@N3voOKݙ{U^J %sM1=jrlz:v:x+70W0u9]a}Q 1cPgc;.򂜻42lWsW%%Nnx^= !Hb$  b+$$$X GKWEU)<.SPSO) 5 s$:CQRAdʤƴ艨"J+/A`@ftZO.qTƶЮ4șFGA /oڀMf4=?Ix^΋3pͣ.'yO*.f%V*gwQfT*=hycZd] >Q &whBMy8I[ %KNH`z n5]5p|?w?xp˜ɦ&dI LBaQ Mv|M7|ݪlEC%!;Nx.x]`љ~2P'ܙ)kh|/MgPKfMlU=iFU (S)34N,Ż "%ۡ͋ #uQEϐ?.b@[bQ60\(P.D؃]e(XCN] 9. X4U๳CTlbQ08x^O" y|ࢷMf6qЈ€l6Q(1!=tf"VM;їLQlfS, 3; ({ U$o;/OcXmӟFdou0#͈Ybl:Q$tPnd.y;._s}&h%=lh }2FT\6xu 1LLk)JFT!_hwmJ{I2e2pU?8ocsHIe Y=-f^Og^)kϑFPR_LZ:*Im >0VN8aAOc.TsԪ ,j̥riT؝[Dy\;~J?pFKp} /\(9{>v&rֳ[Ri-!z61u;3?Rx^x`E;0( A P(`qPAp8 Ba0Aa`PvywY?`{RZ&GnX0J@EΞcDg~03eA%S1LUR;HIY~Ø 1S]qbk'-y3:f<n8xw/bLJW&-i*ӛ,VQA*ҙ'ްQ2x^sQ3`!p P( @!P, @! BP(,@P @ޙ{?|z1',ͬ[Q؃UmѰO -|1RpPۑ^ERf(cBQR;qg!N5)/mHYFxoC{u3/a'‹-c&8gz? Wbx^xA ` p( A( BpA! BP8<(ovٙۓػk>hܰb2>Ë~x$7bdq`)VZ.d)e=vr쭾8F֚%91]Q?g_b}sS63Sǫ:Q{#ˊJ-s:կuYQFAv"o? =FniR:lB)Qfx^{PŻA0( …@ P( A PxX(@( A`0A`0isVa{'™8x`)mFiϛ؎\F䖒ģ8qvTբLm]>gj2hךyLjЦwu#%TɆ|+{h VZħt4!\ǎ1[.@`Uc\&꿈[)r& h'pMbC:XS"):ɐP 5?]3uq)$]I$u`~ÒX-\3 ɔAWl!E~_+a\_WYU~[|DBm~,Pvo~CuLР-zۣVT=[&6WT6 2miq6pA.y`yȽBgb7%V}$fCCoH.%zv>ƕSq]3fZ#eϏ̞ zzR$ݫ]D"o*Xrr(v1R8&NSx^΋S po5+]­\ Ŧ.etҥkݼcY2+y\:7e,㮹.)ĝ/,Z |xE֣?KjBQ8*ڎ[`XNj$e{_x;rmU?<&f'^?Fgȓ,T˻!gY YO6_^ OȡnXc=1vrhV>u$t;NsǯT{atb*p6@[9͆wH38רTtmXNXP! k'eDѠ |,p^gS"Œ)?;8xйR0Y%$ѹ22x;aФ7W x "s.yb}<=1/cӓɚ<:Acp^D^Z0bTa~ 6 1}Ia&ǘPy2 #E G\:!%n_GT@D?XA~A=c,q{1#MDHYr05P|8r_O2x^O1! g ) ' W/$  $ffw^?PqcSG%ل!Ao(h>H$`-Dʆ~ed )d9"UV<-O8J/CJp .(%+3#݉׏n *ߤC꺵'&;@j[t .Ss(Tr&6.xB<*J(M;zXb/0(lvr~iWZq؍v$\&[G4gµhm;ͤ㒩sGO~Z?Hx^%= Es^ARL2" -#  H$ aq0??oЫMIg4uXC!;9]6=b*NX`M;nS)=ŗJf7C_l1wLPM{s5|Kq3Պb| ԍ=bƍ xU^(2\]ǽc}Ktu9!PRx^P1!?b_-Dp@J$  + H@^Xf` &}#6"쳤mcj+ jю y5$ 2&X0]<< An $t 24Z]g$#fKTJ]D^d]N4uwԧse;n>urs9Q)~y Dy>Y۩ֿ9WεxVD=Dfk= [=.ִ;pex$.Pҹx^%1! E_P\H@(NH@$'3M}}'<ʧ!ccbľ˹=}Z SAȤȈx(lQF~Id>|I'n;n/hJUxdۙ4ݪ{4vf7<]j#˽s׵TVw޽7V&&v2cXGx^%O1D! ^7 $ F$  H@. MHҾlO2x^StqG^ΐi$54aJI|A#Q@&bms@E*8FR79OZaF@CB )8yQԺsƷOgOh|[BWϛJ.x&&h)ÅdFb(2vS+эj*=gA2Ϙ܈^iݏަ.'lO~k%F|z_>ѵ#KqfFg\JPo6# q1iQZ Y~ X1'_2q=xB\neVb+ /SUty&bd= *0R+I_/BF+ZфVUȗ5n!l=(8`֡e;GUC zHq G0]m0EԱ*#2մA ő"B)ZXe`z^S7K6jv![Lv m56 rk *@͵Uw;"nRNyQ5F?y̭8/̬ꠣ馰Rϥ/q73둎ȯ^+xz$Xs3vnΦ e%Z5-Ft5YX@Ry;B:*m7 >f񎋗n\&:rIGϙxvĤR{/߀?1GvL5~ׅGT3BM9Y%Oa^^pL%l5Nnͬ0ކ!7WPU/ NQYOx^ta9   A0~  `8p  Sw==}(k9>579ꐄhM7ʼIJ&}Z4%'X8s'wucngQ>J _d@H*J8go 8s/tʟ3*aDJMkNO*ZP\5Jƣ|/DxWHvV1cTx^xP!P…P< B!P( `0  B`0vY:FGcNxe˜Vܲ6G/,Hж,/92;v$"$*$d o@ Q{3FݜV9o}i+M0&,^#j9e˙DilOOxZIPJ}Áud.f|kn?$u']!ց]y]U씿&F҆"T+J |\Zx^xP!P AP B`P( A!0(A0 a`P(B! `Ps=ݟonxeHdlChIEw><%4H׈=Sc'6Ίg~*]g;]|{t}*%0R!$ZŮ34]?:[۶U Ȍ󑽕=#+ YOȘ5>1U6bp]ZO _)04 rmg,SUZx^xPy!`0( 00(Aa0 `0`P `X;=d?)3+F\s V'^ӂKro*잚R{h,&6a3)L 2u^{ՕM1 {ׄ84;Ҏz]yf\漋$GKZ߿J4~e%/R8eLl(ס[e,-שU?ɬYx^xP0, A!P(Aa0 P(baX(@aP @0,Nι?=Dўo4L*|pw eH(mgN9r_l,V-x%a%LNJ8q$nSRw6x Wz|M[Jq'\œ[##= #Y'פ͔:RW3Iʞ.D+ĊEH"7sNO^:x^{BQpa\AA?` `` `\Ax!{8|LﴩԾlYK6td9X0>5U$<ȑ?(sB>U$Nw]m;6d9#O&QłK_s͌$2n;)t%~ҴWNTu'wrFy#fiHw\x^%xBa0A88xa`0 ``A . A0 {n~QP$:ֵOsA#YdLXR盹W-QΝR Am͐L)-~MqVomR(G*;ةoVgΫS^S^TvYZGL=ʺ'u 8]V)3 ;t}wx{9LohqzI8ב/Iat?`x^Qa```  @ X` `aa `0p XX X`aaO}{݊6?tɅY18۱ȄREg[S iu*[,l>ec@Ϫ;2I$TYHS f3yԜfWG6パ.U]SٓЈk9ui @lNߤp}?oj \YX x^Sq̏i212Vy7-X)YWLMayt2u+,SH< 0-p+d>ˊ0ʠ4sZVf-Lv]޿~?>F-L&jBȼcVÖ9H-}8>DZ6`iy0d{C2]AԀ甚.yi2瞞xV.u-^gròk FIDniS */T85Ci4s$:yG~ש8O$љ}3Li-9T0~X:zyS >y|Ě\ SN4u7V "~p*6!xs3yv9\+B?Bc71"B}rF ȋFDj,-P)GG-kXT ܖ*BtI!Mc+v|gd/ch W@!n~v/OUk;Esv{!=lbh&]!ȱ(\fG w_go`Oa7<<[Z$ګܣ~(x $%Z+xŠX^c.DwJ;Ai-Cw1ҺL_!e 8Ū^G .mwbu4QHlM yXTSDҰ>Z+ [8:w="bN4!NzLONJ*1:ʪ/]* 6:)x׶c_mIf]H U;poٱ`4$*.|rӥc;jR e[{ͫK :AɩW_փlQ9Z?Dh--VM3C.6&F dIC|e@\w1;(Cv^!hlt7E1+aC{n]*AY8fZ-m̅ țxǡ33'cmrXHÍL<x^ Oyį\9=!"w*7tBґx"Ԩh-rC6(y\m_9zJ M%TW.waBMpt>iv F Tw8&c5h HZ:B4'ӯ,G5ݼ3YP&x=C /F=>xxfm¥T.w#ƸG(H;ZГ9\|mLnp#\0Ш]L,Z6%ZuGUE8SlK(M(r20~6'O3Z^x^%A DU}HC !aG$D$ ! ?U3dN~x4?IEw* vGMΦ];4`2*{7J\8 =nÙU+Zq}aFʝ6#9٨R"I9IٿDkZoNaAapd;VleښThh,PA'a%vHpBOL$zUuR_2L wT35F/{_x^%;0DuU(@&pp!!(X 7AC pojϯ{F?o>ߠ閁FﲡSIZK9Ұ PjvjU>ēiVЍ⅚J񶺽?X0جYk7Ih%ian̻L62:j~O#Ȗa{<7Yf]a:cwa1_5;+Qx^%1!  )~H@+ HX HX H@ۂL&3ٟ?>oVVUlNmƙ>{`6Nkrۮv\yupӴW55NJzpL>Q%]zPc獃u1oi0&QKHkog4-_wUyLfiF0xb\g5_l Zvx^1! ͤD$ $P/$ $ }f&lg5N吾EK6Eh-d$6u tB ./W2ޣ9Ud)dn[j$vU!\ ;(ϙ1Gmd\3kHg?v>*ЙJm#FNdJTƚu-NVx^%10 D}3[!@0@HqR^```pOq]V~:TM+jڽz5@CEЩKoqxU߽) jCًMt8œ>~|0o ukfduy 3莬Rdk8խ-7&XgKTT IN u]N}3?ߘXx^1! Ef~AqR$P-DVJ@{agKz?:tVb㿴P.P82+zq%-*REW=(͠E 7 Ft>]\71H*eC'_w_Uڎ"eۙNb$3Am]'Sי":t<8uѳN7KִB/[fx^%=! $8HX H8[^$  HX HX 6/|i^%hNMTA+|V7M9tutI(&XC35_(eT#+t 'iZP9wO836Okg:5@$so|to4۠XI-\gJͼ~RJodU)#s¹ BtXfx^3}J-*]4[QO)a2aS&VVH1C칄)?N6jѹ'91v@h}49x4F6%׼N^n9fu~eHkIv {(S2|EOtޜG&b_d ky -o_W#D5!(k_Ͽ;*$4M|̲:S0? Y)Ɨhå4JYnac"d覦_C:n[D{&N%mF/IfVCϳv$&H l7D >2r.K T؝Gkv:F<:ءdՑƞECu3V9R'r Rp6Љ2~d!f+X(vQ%nbD'imq5༯[%q2Bd Lc% R?ىըlzm"C5Ŷ]J4>a+v u?﹟fcY&_fn=mvb##u8(Lo}'k6VbMZTΡmo/qFH%L:zji lٙk-E %Ir[L%$/NJ&+Gpg=X<ՋȯPCn0,8.9UC8 Q%"Զ~0-kX;*lבpB_L|ymb"&A{)V.=t2.<2Ek3OxO gV x^S;O" 5ن)DB<,"Ȫ ɍAglc# ͊Wcch ۘ(@̝ܛkNNrsQ?_)iG )dЏCp*K6FnUen_ s)ʔXCmfڏCc~yOEo&:xcwgSosUq}us5's=}Ldm#E rWO#81UF5w6ؖΞ|x '{-ĝtֺKB:",q@20Ok a~AlKb飖 &]nWo3ɃH2K,D ·uts§\DZrc"7ѪYb877mhfzʔ`=vJhhamhN!?H`{&ӘtMA6̆$Ù0wybߏqQDmeT[+iLʁ&݇^D'yRjﲱk_~FS-t[6}L~N/~6APQI݀R T,:PHg(3F &*rI5y*r-yd®"/ʰjmJ`(<#Dݷ@!toƛAHRG Lsw.r蘅A|o$=NOdu-ŏ iC8nY 0i lQ,A;˲A\{3"i&SFfr֠qIL-+82^uNoqFE`^5(fQ g§:!jaswvZ~k۪m775!7}tny뺌ޔW(FJ4d! #&d%k0Xo=j"O7A]E$}h"Ϗ{Ir~i@.s%|tTjA+ZCϛpx|彧Qvd;<d&_X +0 \\“# =1G";l^V &W>\1ɍ DyMKF-=h7W.=S٥nqUQ2Na%V,+W2-TaeܶDqx^tBa9\    A0A A  A0` sWOWĚ?6R9:W271/6 pYF,.LңOJ[O#sXvxT[R>e"j+MDog͜$1aDʉuyu: c=Z,T6MYLM'^tﰋ璱s_ DM}JI=|N+˷lyO@gx^tBqƷs~`0b `0 0x`A0 `A AA~?{~߽ͮ75^p̗uؐ:ØѣÑOlYFFB%R74Ņ*骽V-xf_7|D&^W1TU D#]Sƈx:ݑ_;m=K-DBBP, BXA ( AaP<(B!P @a(`sO/Gwo5L\S>4+UYG^TX䃙Q2m!phgj gS #}JJM*P0ia'Wx}NRa?|`(z2DZf5OJڋxħbwN &axԕ]K #0U$;w~%6!o'vq˵dx^tPs> A P@0(  P A0( BP AaP(@P䝼{]~8ZL/7*ig$t ؘ5G+[KxWcLH!LIA^&o?➄ZYN–)K|1S[2dMRM"Yv̄zhkG ūuQ)Y'Rnr~HI>H}QտXJn=87mmaצPxn,XtgBf|kj(c'Jex^tBs>AAA< A` A0A`` }޹{~t{M8qɞwsw.zfʗ"Y o*F}idΓ_o} ܦ,Vh:,tGyrƬ"q̺ ;}\od[+V9Q&x?C)jt0!dOY*3ogEĴֈ_/Ot5ebx^tPs>x(0 Aa0( A!(BaP B0  0(@`7K;\eYFharwRf2ZS;ѰfO g*Wf&9)(Evb 4 KVJԙNFI|*шc$Hm8PwJXRģt2dl,VBd uk͋v9{q$R뽕*YR wZCZb""|>X"whzm\lTW`x^tPs> BP @P( @`( ` BaP  8 A P( y缼{7}^GEIji_| %# o[,O%#G񥩤8.fk2=PpycT2c:R[IZY.bhxֶVnG΄)߼[K;1M!ތ/+tDʴГ/ቡ5=utދWh5DHܞçX4^LwLєV.=@ Oөw[ oS3MѹNax^tPs> ƒ BP( A0 @!0( `0( B!P BP w7ÍVBmo~IrZj&4 `ԥ=S^;`Om^ 1b{ "m,x밓G-ƙN8HOjU!߆cɭ\N8e!V2YO:ƴV\-h b Y;VƓ Z&OOUXJU1Pք3Di)-(h"KU,$9y?Ka x^; qUƕ}g!ұEQ瘡jvWjk :0T$W2ٶewq*]eJ#z{S `j<[ň/pmU.5\D&⧩L'qss ) /UBK^Jň˫i?-a61{X l@ZLT3V;啨TN] `(7lrJ/\;fKxU}E  `_F_r /MVOlќSVmre4t0*k}-i ﱋ߿~Qe+MO\H{Alzy`?tq r ௗ(·Fwrx8$(o7M  CU{$%0+qZWՈY١Fo;N$$ͭ8,A&zuLs25{k?=5g3HDett5~*j⠣p\?w(:\":Mۊ /$Aw5Vex^ϋSp8c Ž pLҡɰ%B<7"y :zdXpA1؍$a pFD>1YBe/˱%-ȄJk{#& />N@$*W3F1ev;,)ӎZCdHmN-C !#Nm!9mN9u FGZPxirBy2_b$N_RI {eD]ۺAPcw k_vAʜ&^wmBO~V f1@7BN;Ƀ*80 L~%!K _GW}kIOv cI\$B,6#],T7躅8en@Ԛm8߁hg;4E 873 ,R"½I_m)D9azTݳkW0Ij q„-8KCn p|:h #include #include #ifdef HAVE_INTTYPES_H #include #endif #define OPTIONAL_DEBUG if(1) /* * some structs we'll be using for event harvesting from the VCD that * gtkwave sends via stdin into this executable */ struct tim_t { struct tim_t *next; uint64_t tim; int val; int delta; }; struct event_t { struct event_t *next; uint64_t tim; char *name; }; int main(void) { uint64_t min_time = 0, max_time = 0; uint64_t tim = 0; int prevtim = 0; int prevval = 255; struct tim_t *t_head = NULL, *t_curr = NULL; struct tim_t *t_tmp; int hcnt; uint64_t control_start = 0, control_end = 0; int blks; int my_arg = 0; struct event_t *hdr_head = NULL, *hdr_curr = NULL; struct event_t *data_head = NULL, *data_curr = NULL; OPTIONAL_DEBUG { fprintf(stderr, "*** t_filter executable init ***\n"); } top: /* main control loop */ hcnt = 0; control_start = 0; control_end = 0; blks = 0; while(1) /* reading input from stdin until data_end comment received */ { char buf[1025]; char *pnt = NULL; buf[0] = 0; pnt = fgets(buf, 1024, stdin); /* CACHE (VIA puts()) THIS INPUT TO A FILE TO DEVELOP YOUR CLIENT OFFLINE FROM GTKWAVE! */ if(buf[0]) { pnt = buf; while(*pnt) /* strip off end of line character */ { if(*pnt != '\n') { pnt++; } else { *pnt = 0; break; } } if(buf[0] == '#') /* look for and extract time value */ { char *str = buf+1; unsigned char ch; tim=0; while((ch=*(str++))) { if((ch>='0')&&(ch<='9')) { tim=(tim*10+(ch&15)); } } } else if(buf[0] == 'b') /* extract the binary value of the "val" symbol */ { int collect = 0; pnt = buf+1; while(*pnt && (*pnt != ' ')) { collect <<= 1; collect |= ((*pnt) & 1); pnt++; } if((prevval ^ collect) & 128) { t_tmp = calloc(1, sizeof(struct tim_t)); t_tmp->tim = tim; t_tmp->val = collect; t_tmp->delta = tim - prevtim; prevtim = tim; if(!t_curr) { t_head = t_curr = t_tmp; } else { t_curr = t_curr->next = t_tmp; } } prevval = collect; } else if(buf[0] == '$') /* directive processing */ { if(strstr(buf, "$comment")) { if((pnt = strstr(buf, "args"))) { char *lhq = strchr(pnt, '\"'); if(lhq) my_arg = atoi(lhq+1); OPTIONAL_DEBUG { fprintf(stderr, "args: %s\n", buf); } } else if((pnt = strstr(buf, "min_time"))) { sscanf(pnt + 9, "%"SCNu64, &min_time); OPTIONAL_DEBUG { fprintf(stderr, "min: %d\n", (int)min_time); } } else if((pnt = strstr(buf, "max_time"))) { sscanf(pnt + 9, "%"SCNu64, &max_time); OPTIONAL_DEBUG { fprintf(stderr, "max: %d\n", (int)max_time); } } else if(strstr(buf, "data_end")) { break; } } } } if(feof(stdin)) /* broken pipe coming up */ { OPTIONAL_DEBUG { fprintf(stderr, "*** Terminated t_filter executable\n"); } exit(0); } } printf("$name Decoded FSK\n"); /* 1st trace name */ printf("#0\n"); { uint64_t p_tim = 0; int state = 0; int byte_remain = 0; int bcnt = 0; t_tmp = t_head; while(t_tmp) { if(t_tmp->delta == 16) { int sync_cnt = 0; uint64_t t_start = p_tim; int i; for(i=0;i<16;i++) { if(t_tmp->delta == 16) { sync_cnt++; p_tim = t_tmp->tim; t_tmp = t_tmp->next; } else { break; } } if(sync_cnt==16) { if(!my_arg) { printf("#%"PRIu64" ?darkblue?Sync\n", t_start); /* write out sync xact */ } else { printf("#%"PRIu64" ?blue?Sync\n", t_start); /* write out sync xact */ } printf("#%"PRIu64"\n", p_tim - 4); /* 'z' midline is no value after time */ printf("MA%"PRIu64" Start\n", t_start); /* set position/name for marker A */ control_start = t_start; goto found_sync; } continue; } p_tim = t_tmp->tim; t_tmp = t_tmp->next; } found_sync: state = 0; byte_remain = 11; /* printf("MB%"PRIu64" Num Blocks\n", p_tim); */ while(t_tmp) { int i; int collect = 0; uint64_t t_start = p_tim; if((state == 0) && (byte_remain == 10)) { struct event_t *evt = calloc(1, sizeof(struct event_t)); char buf[32]; evt->tim = p_tim; sprintf(buf, "H%d", hcnt/2); evt->name = strdup(buf); if(!control_end) { control_end = p_tim; } if(!hdr_head) { hdr_head = hdr_curr = evt; } else { hdr_curr = hdr_curr->next = evt; } /**/ if(data_curr) { evt = calloc(1, sizeof(struct event_t)); evt->tim = p_tim; evt->name = NULL; data_curr = data_curr->next = evt; } } if((state == 1) && (byte_remain == 64)) { struct event_t *evt = calloc(1, sizeof(struct event_t)); char buf[32]; evt->tim = p_tim; sprintf(buf, "D%d:", hcnt/2); evt->name = calloc(1, 74); strcpy(evt->name, buf); if(!data_head) { data_head = data_curr = evt; } else { data_curr = data_curr->next = evt; } /**/ if(hdr_curr) { evt = calloc(1, sizeof(struct event_t)); evt->tim = p_tim; evt->name = NULL; hdr_curr = hdr_curr->next = evt; } hcnt++; } for(i=0;(t_tmp) && (i<8);i++) { collect <<= 1; if(t_tmp->delta == 16) { collect |= 1; t_tmp = t_tmp->next; } else { } p_tim = t_tmp->tim; t_tmp = t_tmp->next; } if(!bcnt) { printf("#%"PRIu64" ?gray24?%02X\n", t_start, collect); blks = collect; bcnt++; } else { if(state == 1) { char conv = ((collect < ' ') || (collect >= 127)) ? '.' : collect; int slen = strlen(data_curr->name); data_curr->name[slen] = conv; if((collect >= ' ') && (collect < 127)) { printf("#%"PRIu64" ?darkgreen?%c\n", t_start, (unsigned char)collect); } else { printf("#%"PRIu64" ?darkred?%02X\n", t_start, collect); } } else { printf("#%"PRIu64" ?purple3?%02X\n", t_start, collect); } } printf("#%"PRIu64"\n", p_tim - 4); byte_remain--; if(!byte_remain) { if(state == 0) { state = 1; byte_remain = 64; } else { state = 0; byte_remain = 10; } } } } t_tmp = t_head; /* free up memory allocated */ while(t_tmp) { t_curr = t_tmp->next; free(t_tmp); t_tmp = t_curr; } t_head = t_curr = NULL; printf("$next\n"); /* indicate there is a next trace */ printf("$name Control\n"); /* next trace name */ printf("#0\n"); if(!my_arg) { printf("#%"PRIu64" ?darkblue?%02X blks\n", control_start, blks); } else { printf("#%"PRIu64" ?blue?%02X blks\n", control_start, blks); } printf("#%"PRIu64"\n", control_end); printf("$next\n"); /* indicate there is a next trace */ printf("$name Headers\n"); /* next trace name */ printf("#0\n"); while(hdr_head) { if(hdr_head->name) { printf("#%"PRIu64" ?purple3?%s\n", hdr_head->tim, hdr_head->name); free(hdr_head->name); } else { printf("#%"PRIu64"\n", hdr_head->tim); } hdr_curr = hdr_head->next; free(hdr_head); hdr_head = hdr_curr; } printf("$next\n"); /* indicate there is a next trace */ printf("$name Data Payload\n"); /* next trace name */ printf("#0\n"); while(data_head) { if(data_head->name) { printf("#%"PRIu64" ?darkgreen?%s\n", data_head->tim, data_head->name); free(data_head->name); } else { printf("#%"PRIu64"\n", data_head->tim); } data_curr = data_head->next; free(data_head); data_head = data_curr; } printf("$finish\n"); /* directive to return control to gtkwave */ fflush(stdout); /* ensure nothing is stuck in output buffers which could hang gtkwave */ OPTIONAL_DEBUG { fprintf(stderr, "back to gtkwave...\n"); } goto top; /* loop forever in order to process next xact query */ return(0); } gtkwave-3.3.66/examples/transaction.fst0000664000076400007640000000554011523063250017461 0ustar bybellbybell _,Xp' 㴅rډ5SPYm)&Bܪ!$Z)S 4r;tq7pd[ !۷w3mMݾ|ws#>sΎ~T~kUwtq%ogG~}LMϿ#yG-[7Gůx 4/Z !;=*oV.gccч?s?z/^xh]{Cm,:U_}K>;?6'esvF{\H6Iq#l9\%H)gT|&M {[]XY5;Ʉ'L7W+֤nIh8'ĩ3@'0R= թK@0lz".KכhmRO&QVR>7ϥüМ ܖk,$ 2H45O*rXS?rn2B|,;Ǫ6TM*Z(<^.UψGYGܧ$`A[%:R@}\1o$8H)ڕ~TRu`<@|>P@%ڕ mb+RVp=ZRx ta$e6][D:"nNE8ZQ.ƿ[9;˥#^sgq+=d\ >R{\ KЃAl=^.b@%!E8O)6T1(naqRe19$,5D (x-CG(b3dCSVm ϫ`shZUB'Tj*~T ވA3G8>\I`y 2)4A7%֠CK+44*2 e^K70% 0ņO2rLMDzA(H oE!0a }i.F dwc\ZGDkm!WbB8mfa0^ 'Gu> "[&JǣQ ^hUx% wA/^H)XST tOe yhuDZY'Š] #H9 3+g9ge'(W4ЉAP T$LE9OlCbm̬R:|i91Q mGoS8(C2A\Q6,{F#YĊuX=v2WH9l&;4:LA㪦T '=/A4dI53`O- +zN}J2C&Li1N 4rNսTK69ra#TwwufkxNz^cI:W狾*Ə+\ y*7D#hީ@sC@u Tul8 \ 3+!] `x1eϼI X?8uPo͝v$G#?l/)U)G:/8K ѮWŷ #include "globals.h" #include #include "gtk12compat.h" #include "symbol.h" #include "debug.h" void update_endcap_times_for_partial_vcd(void) { char str[40]; if(GLOBALS->from_entry) { reformat_time(str, GLOBALS->tims.first + GLOBALS->global_time_offset, GLOBALS->time_dimension); gtk_entry_set_text(GTK_ENTRY(GLOBALS->from_entry),str); gtkwavetcl_setvar(WAVE_TCLCB_FROM_ENTRY_UPDATED, str, WAVE_TCLCB_FROM_ENTRY_UPDATED_FLAGS); } if(GLOBALS->to_entry) { reformat_time(str, GLOBALS->tims.last + GLOBALS->global_time_offset, GLOBALS->time_dimension); gtk_entry_set_text(GTK_ENTRY(GLOBALS->to_entry),str); gtkwavetcl_setvar(WAVE_TCLCB_TO_ENTRY_UPDATED, str, WAVE_TCLCB_TO_ENTRY_UPDATED_FLAGS); } } void time_update(void) { DEBUG(printf("Timeentry Configure Event\n")); calczoom(GLOBALS->tims.zoom); fix_wavehadj(); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed"); } void from_entry_callback(GtkWidget *widget, GtkWidget *entry) { (void)widget; G_CONST_RETURN gchar *entry_text; TimeType newlo; char fromstr[40]; entry_text=gtk_entry_get_text(GTK_ENTRY(entry)); entry_text = entry_text ? entry_text : ""; DEBUG(printf("From Entry contents: %s\n",entry_text)); newlo=unformat_time(entry_text, GLOBALS->time_dimension); newlo -= GLOBALS->global_time_offset; if(newlomin_time) { newlo=GLOBALS->min_time; } if(newlo<(GLOBALS->tims.last)) { GLOBALS->tims.first=newlo; if(GLOBALS->tims.starttims.first) GLOBALS->tims.timecache=GLOBALS->tims.start=GLOBALS->tims.first; reformat_time(fromstr, GLOBALS->tims.first + GLOBALS->global_time_offset, GLOBALS->time_dimension); gtk_entry_set_text(GTK_ENTRY(entry),fromstr); time_update(); gtkwavetcl_setvar(WAVE_TCLCB_FROM_ENTRY_UPDATED, fromstr, WAVE_TCLCB_FROM_ENTRY_UPDATED_FLAGS); return; } else { reformat_time(fromstr, GLOBALS->tims.first + GLOBALS->global_time_offset, GLOBALS->time_dimension); gtk_entry_set_text(GTK_ENTRY(entry),fromstr); gtkwavetcl_setvar(WAVE_TCLCB_FROM_ENTRY_UPDATED, fromstr, WAVE_TCLCB_FROM_ENTRY_UPDATED_FLAGS); return; } } void to_entry_callback(GtkWidget *widget, GtkWidget *entry) { (void)widget; G_CONST_RETURN gchar *entry_text; TimeType newhi; char tostr[40]; entry_text=gtk_entry_get_text(GTK_ENTRY(entry)); entry_text = entry_text ? entry_text : ""; DEBUG(printf("To Entry contents: %s\n",entry_text)); newhi=unformat_time(entry_text, GLOBALS->time_dimension); newhi -= GLOBALS->global_time_offset; if(newhi>GLOBALS->max_time) { newhi=GLOBALS->max_time; } if(newhi>(GLOBALS->tims.first)) { GLOBALS->tims.last=newhi; reformat_time(tostr, GLOBALS->tims.last + GLOBALS->global_time_offset, GLOBALS->time_dimension); gtk_entry_set_text(GTK_ENTRY(entry),tostr); time_update(); gtkwavetcl_setvar(WAVE_TCLCB_TO_ENTRY_UPDATED, tostr, WAVE_TCLCB_TO_ENTRY_UPDATED_FLAGS); return; } else { reformat_time(tostr, GLOBALS->tims.last + GLOBALS->global_time_offset, GLOBALS->time_dimension); gtk_entry_set_text(GTK_ENTRY(entry),tostr); gtkwavetcl_setvar(WAVE_TCLCB_TO_ENTRY_UPDATED, tostr, WAVE_TCLCB_TO_ENTRY_UPDATED_FLAGS); return; } } /* Create an entry box */ GtkWidget * create_entry_box(void) { GtkWidget *label, *label2; GtkWidget *box, *box2; GtkWidget *mainbox; char fromstr[32], tostr[32]; GtkTooltips *tooltips; tooltips=gtk_tooltips_new_2(); gtk_tooltips_set_delay_2(tooltips,1500); label=gtk_label_new("From:"); GLOBALS->from_entry=gtk_entry_new_with_max_length(40); reformat_time(fromstr, GLOBALS->min_time + GLOBALS->global_time_offset, GLOBALS->time_dimension); gtk_entry_set_text(GTK_ENTRY(GLOBALS->from_entry),fromstr); gtk_signal_connect (GTK_OBJECT (GLOBALS->from_entry), "activate",GTK_SIGNAL_FUNC (from_entry_callback), GLOBALS->from_entry); box=gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(box), label, TRUE, TRUE, 0); gtk_widget_show(label); gtk_box_pack_start(GTK_BOX(box), GLOBALS->from_entry, TRUE, TRUE, 0); gtk_widget_set_usize(GTK_WIDGET(GLOBALS->from_entry), 90, 22); gtk_tooltips_set_tip_2(tooltips, GLOBALS->from_entry, "Scroll Lower Bound", NULL); gtk_widget_show(GLOBALS->from_entry); label2=gtk_label_new("To:"); GLOBALS->to_entry=gtk_entry_new_with_max_length(40); reformat_time(tostr, GLOBALS->max_time + GLOBALS->global_time_offset, GLOBALS->time_dimension); gtk_entry_set_text(GTK_ENTRY(GLOBALS->to_entry),tostr); gtk_signal_connect (GTK_OBJECT (GLOBALS->to_entry), "activate",GTK_SIGNAL_FUNC (to_entry_callback), GLOBALS->to_entry); box2=gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(box2), label2, TRUE, TRUE, 0); gtk_widget_show(label2); gtk_box_pack_start(GTK_BOX(box2), GLOBALS->to_entry, TRUE, TRUE, 0); gtk_widget_set_usize(GTK_WIDGET(GLOBALS->to_entry), 90, 22); gtk_tooltips_set_tip_2(tooltips, GLOBALS->to_entry, "Scroll Upper Bound", NULL); gtk_widget_show(GLOBALS->to_entry); if(!GLOBALS->use_toolbutton_interface) { mainbox=gtk_vbox_new(FALSE, 0); } else { mainbox=gtk_hbox_new(FALSE, 0); } gtk_box_pack_start(GTK_BOX(mainbox), box, TRUE, FALSE, 1); gtk_widget_show(box); gtk_box_pack_start(GTK_BOX(mainbox), box2, TRUE, FALSE, 1); gtk_widget_show(box2); return(mainbox); } gtkwave-3.3.66/src/pipeio.h0000664000076400007640000000210512341266475015034 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2005-2009 * * 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. */ #include "globals.h" #ifndef WAVE_PIPEIO_H #define WAVE_PIPEIO_H #include #include #include #ifdef HAVE_SYS_STAT_H #include #endif #include #include #include #include "debug.h" #if defined _MSC_VER || defined __MINGW32__ #include #endif struct pipe_ctx { #if defined _MSC_VER || defined __MINGW32__ HANDLE g_hChildStd_IN_Rd; HANDLE g_hChildStd_IN_Wr; /* handle for gtkwave to write to */ HANDLE g_hChildStd_OUT_Rd; /* handle for gtkwave to read from */ HANDLE g_hChildStd_OUT_Wr; PROCESS_INFORMATION piProcInfo; #else FILE *sin, *sout; int fd0, fd1; pid_t pid; #endif }; struct pipe_ctx *pipeio_create(char *execappname, char *arg); void pipeio_destroy(struct pipe_ctx *p); #endif gtkwave-3.3.66/src/Makefile.in0000664000076400007640000012016412523006322015432 0ustar bybellbybell# Makefile.in generated by automake 1.13.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 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__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } 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 = : bin_PROGRAMS = gtkwave$(EXEEXT) twinwave$(EXEEXT) subdir = src DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_gtkwave_OBJECTS = fsdb_wrapper_api.$(OBJEXT) globals.$(OBJEXT) \ ae2.$(OBJEXT) analyzer.$(OBJEXT) baseconvert.$(OBJEXT) \ bitvec.$(OBJEXT) bsearch.$(OBJEXT) busy.$(OBJEXT) \ clipping.$(OBJEXT) color.$(OBJEXT) currenttime.$(OBJEXT) \ debug.$(OBJEXT) discardbuttons.$(OBJEXT) edgebuttons.$(OBJEXT) \ entry.$(OBJEXT) extload.$(OBJEXT) fetchbuttons.$(OBJEXT) \ fgetdynamic.$(OBJEXT) file.$(OBJEXT) fonts.$(OBJEXT) \ fst.$(OBJEXT) gconf.$(OBJEXT) getopt.$(OBJEXT) \ getopt1.$(OBJEXT) ghw.$(OBJEXT) ghwlib.$(OBJEXT) \ hierpack.$(OBJEXT) jrb.$(OBJEXT) help.$(OBJEXT) \ lxt2_read.$(OBJEXT) lxt_write.$(OBJEXT) vzt_read.$(OBJEXT) \ hiersearch.$(OBJEXT) interp.$(OBJEXT) logfile.$(OBJEXT) \ lx2.$(OBJEXT) lxt.$(OBJEXT) main.$(OBJEXT) markerbox.$(OBJEXT) \ menu.$(OBJEXT) mouseover.$(OBJEXT) mouseover_sigs.$(OBJEXT) \ pagebuttons.$(OBJEXT) pipeio.$(OBJEXT) pixmaps.$(OBJEXT) \ print.$(OBJEXT) ptranslate.$(OBJEXT) rc.$(OBJEXT) \ regex.$(OBJEXT) renderopt.$(OBJEXT) rgb.$(OBJEXT) \ savefile.$(OBJEXT) search.$(OBJEXT) shiftbuttons.$(OBJEXT) \ showchange.$(OBJEXT) signalwindow.$(OBJEXT) \ simplereq.$(OBJEXT) splash.$(OBJEXT) status.$(OBJEXT) \ strace.$(OBJEXT) symbol.$(OBJEXT) tcl_commands.$(OBJEXT) \ tcl_helper.$(OBJEXT) tcl_np.$(OBJEXT) \ tcl_support_commands.$(OBJEXT) timeentry.$(OBJEXT) \ translate.$(OBJEXT) tree.$(OBJEXT) treesearch.$(OBJEXT) \ tree_component.$(OBJEXT) ttranslate.$(OBJEXT) vcd.$(OBJEXT) \ vcd_keywords.$(OBJEXT) vcd_partial.$(OBJEXT) \ vcd_recoder.$(OBJEXT) vcd_saver.$(OBJEXT) vlist.$(OBJEXT) \ vzt.$(OBJEXT) wavewindow.$(OBJEXT) zoombuttons.$(OBJEXT) gtkwave_OBJECTS = $(am_gtkwave_OBJECTS) am__DEPENDENCIES_1 = am__DEPENDENCIES_2 = ./cocoa/libgtkwmacintegration.a \ $(am__DEPENDENCIES_1) am__DEPENDENCIES_3 = ./liblzma/libgwlzma.a $(am__DEPENDENCIES_1) gtkwave_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(LIBFST_LDADD) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) gtkwave_LINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(gtkwave_LDFLAGS) \ $(LDFLAGS) -o $@ am_twinwave_OBJECTS = twinwave.$(OBJEXT) twinwave_OBJECTS = $(am_twinwave_OBJECTS) twinwave_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) 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__depfiles_maybe = depfiles am__mv = mv -f 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 = 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 = $(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) 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 = $(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 = $(gtkwave_SOURCES) $(twinwave_SOURCES) DIST_SOURCES = $(gtkwave_SOURCES) $(twinwave_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 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)` ETAGS = etags CTAGS = ctags 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@ AET2_CFLAGS = @AET2_CFLAGS@ AET2_LDADD = @AET2_LDADD@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COCOA_GTK_CFLAGS = @COCOA_GTK_CFLAGS@ COCOA_GTK_LDADD = @COCOA_GTK_LDADD@ COCOA_GTK_LDFLAGS = @COCOA_GTK_LDFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTDEBUG = @EXTDEBUG@ EXTDEBUG2 = @EXTDEBUG2@ EXTDEBUG3 = @EXTDEBUG3@ EXTDEBUG4 = @EXTDEBUG4@ EXTLOAD_CFLAGS = @EXTLOAD_CFLAGS@ FASTTREE_CFLAGS = @FASTTREE_CFLAGS@ FSDB_CFLAGS = @FSDB_CFLAGS@ FSDB_LDADD = @FSDB_LDADD@ GCONF_CFLAGS = @GCONF_CFLAGS@ GCONF_LIBS = @GCONF_LIBS@ GEDITTEST = @GEDITTEST@ GEDIT_CFLAGS = @GEDIT_CFLAGS@ GPERF = @GPERF@ GREP = @GREP@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_CONFIG = @GTK_CONFIG@ GTK_LIBS = @GTK_LIBS@ GTK_MAC_CFLAGS = @GTK_MAC_CFLAGS@ GTK_MAC_LIBS = @GTK_MAC_LIBS@ GTK_UNIX_PRINT_CFLAGS = @GTK_UNIX_PRINT_CFLAGS@ GTK_UNIX_PRINT_LIBS = @GTK_UNIX_PRINT_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBBZ2_CFLAGS = @LIBBZ2_CFLAGS@ LIBBZ2_DIR = @LIBBZ2_DIR@ LIBBZ2_LDADD = @LIBBZ2_LDADD@ LIBJUDY_CFLAGS = @LIBJUDY_CFLAGS@ LIBJUDY_LDADD = @LIBJUDY_LDADD@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBXZ_CFLAGS = @LIBXZ_CFLAGS@ LIBXZ_LDADD = @LIBXZ_LDADD@ LIBZ_CFLAGS = @LIBZ_CFLAGS@ LIBZ_DIR = @LIBZ_DIR@ LIBZ_LDADD = @LIBZ_LDADD@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MINGW_LDADD = @MINGW_LDADD@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ 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@ POW_LIB = @POW_LIB@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ STRUCT_PACK = @STRUCT_PACK@ TCL_DEFADD = @TCL_DEFADD@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LDADD = @TCL_LDADD@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_MAJOR_VERSION = @TCL_MAJOR_VERSION@ TCL_MINOR_VERSION = @TCL_MINOR_VERSION@ TK_INCLUDE_SPEC = @TK_INCLUDE_SPEC@ TK_LDADD = @TK_LDADD@ TK_LIB_SPEC = @TK_LIB_SPEC@ UPDATE_DESKTOP_DATABASE = @UPDATE_DESKTOP_DATABASE@ UPDATE_MIME_DATABASE = @UPDATE_MIME_DATABASE@ VERSION = @VERSION@ XDGDATADIR = @XDGDATADIR@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ 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_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ 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@ 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 = $(LIBZ_DIR) $(LIBBZ2_DIR) liblzma helpers helpers/fst cocoa DIST_SUBDIRS = libz libbz2 liblzma helpers helpers/fst cocoa LIBFST_CFLAGS = -I$(srcdir)/helpers/fst LIBFST_LDADD = ./helpers/fst/libfst.a LIBLZMA_CFLAGS = -I$(srcdir)/liblzma $(LIBXZ_CFLAGS) LIBLZMA_LDADD = ./liblzma/libgwlzma.a $(LIBXZ_LDADD) LIBCOCOA_CFLAGS = -I$(srcdir)/cocoa LIBCOCOA_LDADD = ./cocoa/libgtkwmacintegration.a $(COCOA_GTK_LDADD) AM_CFLAGS = -I$(srcdir)/.. -I$(srcdir)/helpers $(FASTTREE_CFLAGS) $(GTK_CFLAGS) $(LIBLZMA_CFLAGS) \ $(LIBZ_CFLAGS) $(LIBBZ2_CFLAGS) $(LIBFST_CFLAGS) $(AET2_CFLAGS) $(FSDB_CFLAGS) $(TCL_INCLUDE_SPEC) \ $(TCL_DEFADD) $(TK_INCLUDE_SPEC) $(EXTLOAD_CFLAGS) $(GEDIT_CFLAGS) $(LIBJUDY_CFLAGS) \ $(GTK_MAC_CFLAGS) $(GCONF_CFLAGS) $(LIBCOCOA_CFLAGS) $(GTK_UNIX_PRINT_CFLAGS) AM_CXXFLAGS = $(AM_CFLAGS) gtkwave_SOURCES = \ fsdb_wrapper_api.cc fsdb_wrapper_api.h \ baseconvert.h wavewindow.h zoombuttons.h fetchbuttons.h timeentry.h shiftbuttons.h pagebuttons.h edgebuttons.h \ signalwindow.h entry.h file.h status.h search.h showchange.h treesearch.h hiersearch.h renderopt.h markerbox.h \ simplereq.h help.h logfile.h vcd_partial.h mouseover.h mouseover_sigs.h interp.h \ globals.c globals.h ae2.c ae2.h analyzer.c analyzer.h baseconvert.c bitvec.c \ bsearch.c bsearch.h busy.c busy.h \ clipping.c clipping.h color.c color.h currenttime.c currenttime.h \ debug.c debug.h discardbuttons.c edgebuttons.c \ entry.c extload.c extload.h fetchbuttons.c fgetdynamic.c fgetdynamic.h file.c fonts.c fonts.h fst.c fst.h \ gconf.c gconf.h getopt.c \ getopt1.c ghw.c ghw.h ghwlib.c ghwlib.h gnu-getopt.h gnu_regex.h gtk12compat.h \ hierpack.c hierpack.h jrb.c jrb.h help.c helpers/lxt2_read.c \ helpers/lxt_write.c helpers/vzt_read.c hiersearch.c interp.c \ logfile.c lx2.c lx2.h lxt.c lxt.h main.c main.h markerbox.c menu.c menu.h mouseover.c \ mouseover_sigs.c pagebuttons.c pipeio.c pipeio.h pixmaps.c pixmaps.h print.c print.h \ ptranslate.c ptranslate.h rc.c rc.h \ regex.c regex_wave.h renderopt.c rgb.c savefile.c savefile.h search.c shiftbuttons.c showchange.c \ signalwindow.c simplereq.c splash.c status.c strace.c strace.h symbol.c symbol.h tcl_callbacks.h \ tcl_commands.c tcl_helper.c tcl_helper.h tcl_np.c tcl_np.h tcl_support_commands.c tcl_support_commands.h \ timeentry.c translate.c translate.h tree.c tree.h treesearch.c tree_component.c tree_component.h \ ttranslate.c ttranslate.h vcd.c vcd.h vcd_keywords.c \ vcd_partial.c vcd_recoder.c vcd_saver.c vcd_saver.h version.h vlist.c vlist.h vzt.c vzt.h wavealloca.h \ wavewindow.c zoombuttons.c gtkwave_LDADD = $(LIBCOCOA_LDADD) $(GTK_LIBS) $(LIBLZMA_LDADD) $(LIBZ_LDADD) $(LIBBZ2_LDADD) $(LIBFST_LDADD) $(AET2_LDADD) $(TCL_LDADD) $(TK_LDADD) $(FSDB_LDADD) $(LIBJUDY_LDADD) $(GTK_MAC_LIBS) $(GCONF_LIBS) $(GTK_UNIX_PRINT_LIBS) $(MINGW_LDADD) gtkwave_LDFLAGS = $(COCOA_GTK_LDFLAGS) twinwave_SOURCES = twinwave.c twinwave_LDADD = $(GTK_LIBS) $(GTK_MAC_LIBS) $(GCONF_LIBS) BUILT_SOURCES = vcd_keywords.c # I'm listing treesearch_gtk2.c here instead of in SOURCES because we don't directly # compile it. Rather it is #include'd by treesearch.c. EXTRA_DIST = treesearch_gtk1.c treesearch_gtk2.c vcd_keywords.gperf gnu_regex.c all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: .SUFFIXES: .c .cc .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(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) --foreign src/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/Makefile .PRECIOUS: 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__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): 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 \ ; 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) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(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: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) gtkwave$(EXEEXT): $(gtkwave_OBJECTS) $(gtkwave_DEPENDENCIES) $(EXTRA_gtkwave_DEPENDENCIES) @rm -f gtkwave$(EXEEXT) $(AM_V_CXXLD)$(gtkwave_LINK) $(gtkwave_OBJECTS) $(gtkwave_LDADD) $(LIBS) twinwave$(EXEEXT): $(twinwave_OBJECTS) $(twinwave_DEPENDENCIES) $(EXTRA_twinwave_DEPENDENCIES) @rm -f twinwave$(EXEEXT) $(AM_V_CCLD)$(LINK) $(twinwave_OBJECTS) $(twinwave_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ae2.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/analyzer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/baseconvert.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bitvec.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bsearch.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/busy.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clipping.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/color.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/currenttime.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/discardbuttons.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edgebuttons.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/entry.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extload.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fetchbuttons.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fgetdynamic.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fonts.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsdb_wrapper_api.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fst.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gconf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ghw.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ghwlib.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/globals.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/help.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hierpack.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hiersearch.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jrb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logfile.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lx2.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxt2_read.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxt_write.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/markerbox.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/menu.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mouseover.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mouseover_sigs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pagebuttons.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pipeio.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pixmaps.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/print.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ptranslate.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/regex.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/renderopt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rgb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/savefile.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/search.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shiftbuttons.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/showchange.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signalwindow.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simplereq.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/splash.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/status.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strace.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/symbol.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcl_commands.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcl_helper.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcl_np.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcl_support_commands.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/timeentry.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/translate.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tree.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tree_component.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/treesearch.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ttranslate.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/twinwave.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vcd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vcd_keywords.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vcd_partial.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vcd_recoder.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vcd_saver.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vlist.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vzt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vzt_read.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wavewindow.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zoombuttons.Po@am__quote@ .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 $< .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 `$(CYGPATH_W) '$<'` lxt2_read.o: helpers/lxt2_read.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lxt2_read.o -MD -MP -MF $(DEPDIR)/lxt2_read.Tpo -c -o lxt2_read.o `test -f 'helpers/lxt2_read.c' || echo '$(srcdir)/'`helpers/lxt2_read.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lxt2_read.Tpo $(DEPDIR)/lxt2_read.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='helpers/lxt2_read.c' object='lxt2_read.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lxt2_read.o `test -f 'helpers/lxt2_read.c' || echo '$(srcdir)/'`helpers/lxt2_read.c lxt2_read.obj: helpers/lxt2_read.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lxt2_read.obj -MD -MP -MF $(DEPDIR)/lxt2_read.Tpo -c -o lxt2_read.obj `if test -f 'helpers/lxt2_read.c'; then $(CYGPATH_W) 'helpers/lxt2_read.c'; else $(CYGPATH_W) '$(srcdir)/helpers/lxt2_read.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lxt2_read.Tpo $(DEPDIR)/lxt2_read.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='helpers/lxt2_read.c' object='lxt2_read.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lxt2_read.obj `if test -f 'helpers/lxt2_read.c'; then $(CYGPATH_W) 'helpers/lxt2_read.c'; else $(CYGPATH_W) '$(srcdir)/helpers/lxt2_read.c'; fi` lxt_write.o: helpers/lxt_write.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lxt_write.o -MD -MP -MF $(DEPDIR)/lxt_write.Tpo -c -o lxt_write.o `test -f 'helpers/lxt_write.c' || echo '$(srcdir)/'`helpers/lxt_write.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lxt_write.Tpo $(DEPDIR)/lxt_write.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='helpers/lxt_write.c' object='lxt_write.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lxt_write.o `test -f 'helpers/lxt_write.c' || echo '$(srcdir)/'`helpers/lxt_write.c lxt_write.obj: helpers/lxt_write.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lxt_write.obj -MD -MP -MF $(DEPDIR)/lxt_write.Tpo -c -o lxt_write.obj `if test -f 'helpers/lxt_write.c'; then $(CYGPATH_W) 'helpers/lxt_write.c'; else $(CYGPATH_W) '$(srcdir)/helpers/lxt_write.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lxt_write.Tpo $(DEPDIR)/lxt_write.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='helpers/lxt_write.c' object='lxt_write.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lxt_write.obj `if test -f 'helpers/lxt_write.c'; then $(CYGPATH_W) 'helpers/lxt_write.c'; else $(CYGPATH_W) '$(srcdir)/helpers/lxt_write.c'; fi` vzt_read.o: helpers/vzt_read.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT vzt_read.o -MD -MP -MF $(DEPDIR)/vzt_read.Tpo -c -o vzt_read.o `test -f 'helpers/vzt_read.c' || echo '$(srcdir)/'`helpers/vzt_read.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vzt_read.Tpo $(DEPDIR)/vzt_read.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='helpers/vzt_read.c' object='vzt_read.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o vzt_read.o `test -f 'helpers/vzt_read.c' || echo '$(srcdir)/'`helpers/vzt_read.c vzt_read.obj: helpers/vzt_read.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT vzt_read.obj -MD -MP -MF $(DEPDIR)/vzt_read.Tpo -c -o vzt_read.obj `if test -f 'helpers/vzt_read.c'; then $(CYGPATH_W) 'helpers/vzt_read.c'; else $(CYGPATH_W) '$(srcdir)/helpers/vzt_read.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vzt_read.Tpo $(DEPDIR)/vzt_read.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='helpers/vzt_read.c' object='vzt_read.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o vzt_read.obj `if test -f 'helpers/vzt_read.c'; then $(CYGPATH_W) 'helpers/vzt_read.c'; else $(CYGPATH_W) '$(srcdir)/helpers/vzt_read.c'; fi` .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) '$<'` # 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= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ 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: $(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: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-recursive all-am: Makefile $(PROGRAMS) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) 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." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-recursive clean-am: clean-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-recursive -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile 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-binPROGRAMS 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 -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: $(am__recursive_targets) all check install install-am \ install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-binPROGRAMS clean-generic cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-tags distdir 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-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 pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am uninstall-binPROGRAMS ./liblzma/libgwlzma.a: $(srcdir)/liblzma/LzmaLib.c $(srcdir)/liblzma/LzmaLib.h ./helpers/fst/libfst.a: $(srcdir)/helpers/fst/fastlz.c $(srcdir)/helpers/fst/fastlz.h $(srcdir)/helpers/fst/fstapi.c $(srcdir)/helpers/fst/fstapi.h ./cocoa/libgtkwmacintegration.a: $(srcdir)/cocoa/cocoa_misc.c $(srcdir)/cocoa/cocoa_misc.h vcd_keywords.c: vcd_keywords.gperf printf "$(GPERF) -o -i 1 -C -k 1,\044 -L C -H keyword_hash -N check_identifier -tT $(srcdir)/vcd_keywords.gperf >vcd_keywords.c" | sh # 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: gtkwave-3.3.66/src/extload.h0000664000076400007640000000125312341266475015212 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2009. * * 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. */ #include "globals.h" #ifndef WAVE_EXTRDR_H #define WAVE_EXTRDR_H #ifdef HAVE_INTTYPES_H #include #endif #include "vcd.h" #define EXTLOAD "EXTLOAD | " TimeType extload_main(char *fname, char *skip_start, char *skip_end); void import_extload_trace(nptr np); /* FsdbReader adds */ void fsdb_import_masked(void); void fsdb_set_fac_process_mask(nptr np); #endif gtkwave-3.3.66/src/vlist.h0000664000076400007640000000375512341266475014724 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2006-8. * * 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. */ #include "globals.h" #ifndef WAVE_VLIST_H #define WAVE_VLIST_H #include #include #include #include "debug.h" struct vlist_t { struct vlist_t *next; unsigned int siz; unsigned int offs; unsigned int elem_siz; }; /* experimentation shows that 255 is one of the least common bytes found in recoded value change streams */ #define WAVE_ZIVFLAG (0xff) #define WAVE_ZIVWRAP (1<<7) /* must be power of two because of AND mask */ #define WAVE_ZIVSRCH (WAVE_ZIVWRAP) /* search depth in bytes */ #define WAVE_ZIVSKIP (1) /* number of bytes to skip for alternate rollover searches */ #define WAVE_ZIVMASK ((WAVE_ZIVWRAP) - 1) /* then this becomes an AND mask for wrapping */ struct vlist_packer_t { struct vlist_t *v; unsigned char buf[WAVE_ZIVWRAP]; #ifdef WAVE_VLIST_PACKER_STATS unsigned int packed_bytes; #endif unsigned int unpacked_bytes; unsigned int repcnt, repcnt2, repcnt3, repcnt4; unsigned char bufpnt; unsigned char repdist, repdist2, repdist3, repdist4; }; void vlist_init_spillfile(void); void vlist_kill_spillfile(void); struct vlist_t *vlist_create(unsigned int elem_siz); void vlist_destroy(struct vlist_t *v); void *vlist_alloc(struct vlist_t **v, int compressable); unsigned int vlist_size(struct vlist_t *v); void *vlist_locate(struct vlist_t *v, unsigned int idx); void vlist_freeze(struct vlist_t **v); void vlist_uncompress(struct vlist_t **v); struct vlist_packer_t *vlist_packer_create(void); void vlist_packer_alloc(struct vlist_packer_t *v, unsigned char ch); void vlist_packer_finalize(struct vlist_packer_t *v); unsigned char *vlist_packer_decompress(struct vlist_t *vl, unsigned int *declen); void vlist_packer_decompress_destroy(char *mem); #endif gtkwave-3.3.66/src/showchange.c0000664000076400007640000002571212360623564015676 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999. * * 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 file extracted from the GTK tutorial. */ /* radiobuttons.c */ #include "globals.h" #include #include #include "analyzer.h" #include "symbol.h" #include "debug.h" static void toggle_generic(GtkWidget *widget, Ulong msk) { if(GTK_TOGGLE_BUTTON(widget)->active) { GLOBALS->flags_showchange_c_1|=msk; } else { GLOBALS->flags_showchange_c_1&=(~msk); } } static void toggle1_callback(GtkWidget *widget, GtkWidget *nothing) { (void)nothing; toggle_generic(widget, TR_RJUSTIFY); } static void toggle2_callback(GtkWidget *widget, GtkWidget *nothing) { (void)nothing; toggle_generic(widget, TR_INVERT); } static void toggle3_callback(GtkWidget *widget, GtkWidget *nothing) { (void)nothing; toggle_generic(widget, TR_REVERSE); } static void toggle4_callback(GtkWidget *widget, GtkWidget *nothing) { (void)nothing; toggle_generic(widget, TR_EXCLUDE); } static void enter_callback(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; GLOBALS->flags_showchange_c_1=GLOBALS->flags_showchange_c_1&(~(TR_HIGHLIGHT|TR_NUMMASK)); if(GTK_TOGGLE_BUTTON(GLOBALS->button1_showchange_c_1)->active) { GLOBALS->flags_showchange_c_1|=TR_HEX; } else if(GTK_TOGGLE_BUTTON(GLOBALS->button2_showchange_c_1)->active) { GLOBALS->flags_showchange_c_1|=TR_DEC; } else if(GTK_TOGGLE_BUTTON(GLOBALS->button3_showchange_c_1)->active) { GLOBALS->flags_showchange_c_1|=TR_BIN; } else if(GTK_TOGGLE_BUTTON(GLOBALS->button4_showchange_c_1)->active) { GLOBALS->flags_showchange_c_1|=TR_OCT; } else if(GTK_TOGGLE_BUTTON(GLOBALS->button5_showchange_c_1)->active) { GLOBALS->flags_showchange_c_1|=TR_SIGNED; } else if(GTK_TOGGLE_BUTTON(GLOBALS->button6_showchange_c_1)->active) { GLOBALS->flags_showchange_c_1|=TR_ASCII; } GLOBALS->tcache_showchange_c_1->flags=GLOBALS->flags_showchange_c_1; wave_gtk_grab_remove(GLOBALS->window_showchange_c_8); gtk_widget_destroy(GLOBALS->window_showchange_c_8); GLOBALS->window_showchange_c_8 = NULL; GLOBALS->cleanup_showchange_c_6(); } static void destroy_callback(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; wave_gtk_grab_remove(GLOBALS->window_showchange_c_8); gtk_widget_destroy(GLOBALS->window_showchange_c_8); GLOBALS->window_showchange_c_8 = NULL; } void showchange(char *title, Trptr t, GtkSignalFunc func) { GtkWidget *main_vbox; GtkWidget *ok_hbox; GtkWidget *hbox; GtkWidget *box1; GtkWidget *box2; GtkWidget *label; GtkWidget *button; GtkWidget *separator; GSList *group; GtkWidget *frame1, *frame2; GLOBALS->cleanup_showchange_c_6=func; GLOBALS->tcache_showchange_c_1=t; GLOBALS->flags_showchange_c_1=t->flags; /* fix problem where ungrab doesn't occur if button pressed + simultaneous accelerator key occurs */ if(GLOBALS->in_button_press_wavewindow_c_1) { gdk_pointer_ungrab(GDK_CURRENT_TIME); } GLOBALS->window_showchange_c_8 = gtk_window_new (GLOBALS->disable_window_manager ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL); install_focus_cb(GLOBALS->window_showchange_c_8, ((char *)&GLOBALS->window_showchange_c_8) - ((char *)GLOBALS)); gtkwave_signal_connect (GTK_OBJECT (GLOBALS->window_showchange_c_8), "delete_event",GTK_SIGNAL_FUNC(destroy_callback),NULL); gtk_window_set_title (GTK_WINDOW (GLOBALS->window_showchange_c_8), title); gtk_container_border_width (GTK_CONTAINER (GLOBALS->window_showchange_c_8), 0); main_vbox = gtk_vbox_new (FALSE, 1); gtk_container_border_width (GTK_CONTAINER (main_vbox), 1); gtk_widget_show (main_vbox); label=gtk_label_new(t->name); gtk_box_pack_start (GTK_BOX (main_vbox), label, FALSE, TRUE, 0); gtk_widget_show (label); separator = gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX (main_vbox), separator, FALSE, TRUE, 0); gtk_widget_show (separator); hbox = gtk_hbutton_box_new (); gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_END); gtk_button_box_set_spacing(GTK_BUTTON_BOX(hbox), 5); gtk_widget_show (hbox); box2 = gtk_vbox_new (FALSE, 5); gtk_container_border_width (GTK_CONTAINER (box2), 5); gtk_widget_show (box2); GLOBALS->button1_showchange_c_1 = gtk_radio_button_new_with_label (NULL, "Hex"); gtk_box_pack_start (GTK_BOX (box2), GLOBALS->button1_showchange_c_1, TRUE, TRUE, 0); if(GLOBALS->flags_showchange_c_1&TR_HEX) gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (GLOBALS->button1_showchange_c_1), TRUE); gtk_widget_show (GLOBALS->button1_showchange_c_1); group = gtk_radio_button_group (GTK_RADIO_BUTTON (GLOBALS->button1_showchange_c_1)); GLOBALS->button2_showchange_c_1 = gtk_radio_button_new_with_label(group, "Decimal"); gtk_box_pack_start (GTK_BOX (box2), GLOBALS->button2_showchange_c_1, TRUE, TRUE, 0); if(GLOBALS->flags_showchange_c_1&TR_DEC) gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (GLOBALS->button2_showchange_c_1), TRUE); gtk_widget_show (GLOBALS->button2_showchange_c_1); group = gtk_radio_button_group (GTK_RADIO_BUTTON (GLOBALS->button2_showchange_c_1)); GLOBALS->button5_showchange_c_1 = gtk_radio_button_new_with_label(group, "Signed Decimal"); gtk_box_pack_start (GTK_BOX (box2), GLOBALS->button5_showchange_c_1, TRUE, TRUE, 0); if(GLOBALS->flags_showchange_c_1&TR_SIGNED) gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (GLOBALS->button5_showchange_c_1), TRUE); gtk_widget_show (GLOBALS->button5_showchange_c_1); group = gtk_radio_button_group (GTK_RADIO_BUTTON (GLOBALS->button5_showchange_c_1)); GLOBALS->button3_showchange_c_1 = gtk_radio_button_new_with_label(group, "Binary"); gtk_box_pack_start (GTK_BOX (box2), GLOBALS->button3_showchange_c_1, TRUE, TRUE, 0); if(GLOBALS->flags_showchange_c_1&TR_BIN) gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (GLOBALS->button3_showchange_c_1), TRUE); gtk_widget_show (GLOBALS->button3_showchange_c_1); group = gtk_radio_button_group (GTK_RADIO_BUTTON (GLOBALS->button3_showchange_c_1)); GLOBALS->button4_showchange_c_1 = gtk_radio_button_new_with_label(group, "Octal"); gtk_box_pack_start (GTK_BOX (box2), GLOBALS->button4_showchange_c_1, TRUE, TRUE, 0); if(GLOBALS->flags_showchange_c_1&TR_OCT) gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (GLOBALS->button4_showchange_c_1), TRUE); gtk_widget_show (GLOBALS->button4_showchange_c_1); group = gtk_radio_button_group (GTK_RADIO_BUTTON (GLOBALS->button4_showchange_c_1)); GLOBALS->button6_showchange_c_1 = gtk_radio_button_new_with_label(group, "ASCII"); gtk_box_pack_start (GTK_BOX (box2), GLOBALS->button6_showchange_c_1, TRUE, TRUE, 0); if(GLOBALS->flags_showchange_c_1&TR_ASCII) gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (GLOBALS->button6_showchange_c_1), TRUE); gtk_widget_show (GLOBALS->button6_showchange_c_1); frame2 = gtk_frame_new ("Base"); gtk_container_border_width (GTK_CONTAINER (frame2), 3); gtk_container_add (GTK_CONTAINER (frame2), box2); gtk_widget_show (frame2); gtk_box_pack_start(GTK_BOX (hbox), frame2, TRUE, TRUE, 0); /****************************************************************************************************/ box1 = gtk_vbox_new (FALSE, 5); gtk_container_border_width (GTK_CONTAINER (box1), 5); gtk_widget_show (box1); frame1 = gtk_frame_new ("Attributes"); gtk_container_border_width (GTK_CONTAINER (frame1), 3); gtk_container_add (GTK_CONTAINER (frame1), box1); gtk_box_pack_start(GTK_BOX (hbox), frame1, TRUE, TRUE, 0); gtk_widget_show (frame1); GLOBALS->toggle1_showchange_c_1=gtk_check_button_new_with_label("Right Justify"); gtk_box_pack_start (GTK_BOX (box1), GLOBALS->toggle1_showchange_c_1, TRUE, TRUE, 0); if(GLOBALS->flags_showchange_c_1&TR_RJUSTIFY)gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(GLOBALS->toggle1_showchange_c_1), TRUE); gtk_widget_show (GLOBALS->toggle1_showchange_c_1); gtkwave_signal_connect (GTK_OBJECT (GLOBALS->toggle1_showchange_c_1), "toggled", GTK_SIGNAL_FUNC(toggle1_callback), NULL); GLOBALS->toggle2_showchange_c_1=gtk_check_button_new_with_label("Invert"); gtk_box_pack_start (GTK_BOX (box1), GLOBALS->toggle2_showchange_c_1, TRUE, TRUE, 0); if(GLOBALS->flags_showchange_c_1&TR_INVERT)gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(GLOBALS->toggle2_showchange_c_1), TRUE); gtk_widget_show (GLOBALS->toggle2_showchange_c_1); gtkwave_signal_connect (GTK_OBJECT (GLOBALS->toggle2_showchange_c_1), "toggled", GTK_SIGNAL_FUNC(toggle2_callback), NULL); GLOBALS->toggle3_showchange_c_1=gtk_check_button_new_with_label("Reverse"); gtk_box_pack_start (GTK_BOX (box1), GLOBALS->toggle3_showchange_c_1, TRUE, TRUE, 0); if(GLOBALS->flags_showchange_c_1&TR_REVERSE)gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(GLOBALS->toggle3_showchange_c_1), TRUE); gtk_widget_show (GLOBALS->toggle3_showchange_c_1); gtkwave_signal_connect (GTK_OBJECT (GLOBALS->toggle3_showchange_c_1), "toggled", GTK_SIGNAL_FUNC(toggle3_callback), NULL); GLOBALS->toggle4_showchange_c_1=gtk_check_button_new_with_label("Exclude"); gtk_box_pack_start (GTK_BOX (box1), GLOBALS->toggle4_showchange_c_1, TRUE, TRUE, 0); if(GLOBALS->flags_showchange_c_1&TR_EXCLUDE)gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(GLOBALS->toggle4_showchange_c_1), TRUE); gtk_widget_show (GLOBALS->toggle4_showchange_c_1); gtkwave_signal_connect (GTK_OBJECT (GLOBALS->toggle4_showchange_c_1), "toggled", GTK_SIGNAL_FUNC(toggle4_callback), NULL); gtk_container_add (GTK_CONTAINER (main_vbox), hbox); separator = gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX (main_vbox), separator, FALSE, TRUE, 0); gtk_widget_show (separator); /****************************************************************************************************/ ok_hbox = gtk_hbox_new (FALSE, 1); gtk_container_border_width (GTK_CONTAINER (ok_hbox), 1); gtk_widget_show (ok_hbox); button = gtk_button_new_with_label ("Cancel"); gtkwave_signal_connect_object (GTK_OBJECT (button), "clicked",GTK_SIGNAL_FUNC(destroy_callback),GTK_OBJECT (GLOBALS->window_showchange_c_8)); gtk_box_pack_end (GTK_BOX (ok_hbox), button, TRUE, TRUE, 0); GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); gtk_widget_show (button); gtk_container_add (GTK_CONTAINER (main_vbox), ok_hbox); button = gtk_button_new_with_label (" OK "); gtkwave_signal_connect_object (GTK_OBJECT (button), "clicked",GTK_SIGNAL_FUNC(enter_callback),GTK_OBJECT (GLOBALS->window_showchange_c_8)); gtkwave_signal_connect_object (GTK_OBJECT (button), "realize", (GtkSignalFunc) gtk_widget_grab_default, GTK_OBJECT (button)); gtk_box_pack_end (GTK_BOX (ok_hbox), button, TRUE, TRUE, 0); GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); gtk_widget_show (button); /****************************************************************************************************/ gtk_container_add (GTK_CONTAINER (GLOBALS->window_showchange_c_8), main_vbox); gtk_widget_show (GLOBALS->window_showchange_c_8); wave_gtk_grab_add(GLOBALS->window_showchange_c_8); } gtkwave-3.3.66/src/ghwlib.c0000664000076400007640000011425412357342523015023 0ustar bybellbybell/* GHDL Wavefile reader library. Copyright (C) 2005-2014 Tristan Gingold GHDL 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. GHDL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING. If not, write to the Free Software Foundation, 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. */ #include #include #include #include #include #include "ghwlib.h" #ifdef HAVE_TRIO #include #define snprintf trio_snprintf #define printf trio_printf #endif int ghw_open (struct ghw_handler *h, const char *filename) { char hdr[16]; h->stream = fopen (filename, "rb"); if (h->stream == NULL) return -1; if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) return -1; /* Check magic...also check if there is a compression layer on top of the file */ if (!memcmp (hdr, "\x1f\x8b", 2)) { char *p = malloc(strlen("gzip -cd ") + strlen(filename) + 1); sprintf(p, "gzip -cd %s", filename); fclose(h->stream); h->stream = popen(p, "r"); free(p); if (h->stream == NULL) return -1; h->stream_ispipe = 1; if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) return -1; } else if (!memcmp (hdr, "BZ", 2)) { char *p = malloc(strlen("bzip2 -cd ") + strlen(filename) + 1); sprintf(p, "bzip2 -cd %s", filename); fclose(h->stream); h->stream = popen(p, "r"); free(p); if (h->stream == NULL) return -1; h->stream_ispipe = 1; if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) return -1; } else { h->stream_ispipe = 0; } if (memcmp (hdr, "GHDLwave\n", 9) != 0) return -2; /* Check version. */ if (hdr[9] != 16 || hdr[10] != 0) return -2; h->version = hdr[11]; if (h->version > 1) return -3; if (hdr[12] == 1) h->word_be = 0; else if (hdr[12] == 2) h->word_be = 1; else return -4; #if 0 /* Endianness. */ { int endian; union { unsigned char b[4]; uint32_t i;} v; v.i = 0x11223344; if (v.b[0] == 0x11) endian = 2; else if (v.b[0] == 0x44) endian = 1; else return -3; if (hdr[12] != 1 && hdr[12] != 2) return -3; if (hdr[12] != endian) h->swap_word = 1; else h->swap_word = 0; } #endif h->word_len = hdr[13]; h->off_len = hdr[14]; if (hdr[15] != 0) return -5; h->hie = NULL; return 0; } int32_t ghw_get_i32 (struct ghw_handler *h, unsigned char *b) { if (h->word_be) return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3] << 0); else return (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | (b[0] << 0); } int64_t ghw_get_i64 (struct ghw_handler *ghw_h, unsigned char *b) { int l, h; if (ghw_h->word_be) { h = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3] << 0); l = (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | (b[7] << 0); } else { l = (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | (b[0] << 0); h = (b[7] << 24) | (b[6] << 16) | (b[5] << 8) | (b[4] << 0); } return (((int64_t)h) << 32) | l; } int ghw_read_byte (struct ghw_handler *h, unsigned char *res) { int v; v = fgetc (h->stream); if (v == EOF) return -1; *res = v; return 0; } int ghw_read_uleb128 (struct ghw_handler *h, uint32_t *res) { uint32_t r = 0; unsigned int off = 0; while (1) { int v = fgetc (h->stream); if (v == EOF) return -1; r |= (v & 0x7f) << off; if ((v & 0x80) == 0) break; off += 7; } *res = r; return 0; } int ghw_read_sleb128 (struct ghw_handler *h, int32_t *res) { int32_t r = 0; unsigned int off = 0; while (1) { int v = fgetc (h->stream); if (v == EOF) return -1; r |= ((int32_t)(v & 0x7f)) << off; off += 7; if ((v & 0x80) == 0) { if ((v & 0x40) && off < 32) r |= -1 << off; break; } } *res = r; return 0; } int ghw_read_lsleb128 (struct ghw_handler *h, int64_t *res) { static const int64_t r_mask = -1; int64_t r = 0; unsigned int off = 0; while (1) { int v = fgetc (h->stream); if (v == EOF) return -1; r |= ((int64_t)(v & 0x7f)) << off; off += 7; if ((v & 0x80) == 0) { if ((v & 0x40) && off < 64) r |= r_mask << off; break; } } *res = r; return 0; } int ghw_read_f64 (struct ghw_handler *h, double *res) { /* FIXME: handle byte order. */ if (fread (res, sizeof (*res), 1, h->stream) != 1) return -1; return 0; } const char * ghw_read_strid (struct ghw_handler *h) { uint32_t id; if (ghw_read_uleb128 (h, &id) != 0) return NULL; return h->str_table[id]; } union ghw_type * ghw_read_typeid (struct ghw_handler *h) { uint32_t id; if (ghw_read_uleb128 (h, &id) != 0) return NULL; return h->types[id - 1]; } union ghw_range * ghw_read_range (struct ghw_handler *h) { int t = fgetc (h->stream); if (t == EOF) return NULL; switch (t & 0x7f) { case ghdl_rtik_type_b2: { struct ghw_range_b2 *r; r = calloc (1, sizeof (struct ghw_range_b2)); r->kind = t & 0x7f; r->dir = (t & 0x80) != 0; if (ghw_read_byte (h, &r->left) != 0) { free(r); return NULL; } /* scan-build */ if (ghw_read_byte (h, &r->right) != 0) { free(r); return NULL; } /* scan-build */ return (union ghw_range *)r; } case ghdl_rtik_type_e8: { struct ghw_range_e8 *r; r = calloc (1, sizeof (struct ghw_range_e8)); r->kind = t & 0x7f; r->dir = (t & 0x80) != 0; if (ghw_read_byte (h, &r->left) != 0) { free(r); return NULL; } /* scan-build */ if (ghw_read_byte (h, &r->right) != 0) { free(r); return NULL; } /* scan-build */ return (union ghw_range *)r; } case ghdl_rtik_type_i32: case ghdl_rtik_type_p32: { struct ghw_range_i32 *r; r = calloc (1, sizeof (struct ghw_range_i32)); r->kind = t & 0x7f; r->dir = (t & 0x80) != 0; if (ghw_read_sleb128 (h, &r->left) != 0) { free(r); return NULL; } /* scan-build */ if (ghw_read_sleb128 (h, &r->right) != 0) { free(r); return NULL; } /* scan-build */ return (union ghw_range *)r; } case ghdl_rtik_type_i64: case ghdl_rtik_type_p64: { struct ghw_range_i64 *r; r = calloc (1, sizeof (struct ghw_range_i64)); r->kind = t & 0x7f; r->dir = (t & 0x80) != 0; if (ghw_read_lsleb128 (h, &r->left) != 0) { free(r); return NULL; } /* scan-build */ if (ghw_read_lsleb128 (h, &r->right) != 0) { free(r) ; return NULL; } /* scan-build */ return (union ghw_range *)r; } case ghdl_rtik_type_f64: { struct ghw_range_f64 *r; r = calloc (1, sizeof (struct ghw_range_f64)); r->kind = t & 0x7f; r->dir = (t & 0x80) != 0; if (ghw_read_f64 (h, &r->left) != 0) { free(r); return NULL; } /* scan-build */ if (ghw_read_f64 (h, &r->right) != 0) { free(r); return NULL; } /* scan-build */ return (union ghw_range *)r; } default: fprintf (stderr, "ghw_read_range: type %d unhandled\n", t & 0x7f); return NULL; } } int ghw_read_str (struct ghw_handler *h) { char hdr[12]; int i; char *p; int prev_len; if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) return -1; if (hdr[0] != 0 || hdr[1] != 0 || hdr[2] != 0 || hdr[3] != 0) return -1; h->nbr_str = ghw_get_i32 (h, (unsigned char *)&hdr[4]); h->nbr_str++; h->str_size = ghw_get_i32 (h, (unsigned char *)&hdr[8]); h->str_table = (char **)calloc ((h->nbr_str + 1), sizeof (char *)); h->str_content = (char *)calloc (1, h->str_size + h->nbr_str + 1); if (h->flag_verbose) { printf ("Number of strings: %d\n", h->nbr_str - 1); printf ("String table size: %d\n", h->str_size); } h->str_table[0] = ""; p = h->str_content; prev_len = 0; for (i = 1; i < h->nbr_str; i++) { int j; int c; char *prev; int sh; h->str_table[i] = p; prev = h->str_table[i - 1]; for (j = 0; j < prev_len; j++) *p++ = prev[j]; while (1) { c = fgetc (h->stream); if (c == EOF) return -1; if ((c >= 0 && c <= 31) || (c >= 128 && c <= 159)) break; *p++ = c; } *p++ = 0; if (h->flag_verbose > 1) printf (" string %d (pl=%d): %s\n", i, prev_len, h->str_table[i]); prev_len = c & 0x1f; sh = 5; while (c >= 128) { c = fgetc (h->stream); if (c == EOF) return -1; prev_len |= (c & 0x1f) << sh; sh += 5; } } if (fread (hdr, 4, 1, h->stream) != 1) return -1; if (memcmp (hdr, "EOS", 4) != 0) return -1; return 0; } union ghw_type * ghw_get_base_type (union ghw_type *t) { switch (t->kind) { case ghdl_rtik_type_b2: case ghdl_rtik_type_e8: case ghdl_rtik_type_e32: case ghdl_rtik_type_i32: case ghdl_rtik_type_i64: case ghdl_rtik_type_f64: case ghdl_rtik_type_p32: case ghdl_rtik_type_p64: return t; case ghdl_rtik_subtype_scalar: return t->ss.base; case ghdl_rtik_subtype_array: return (union ghw_type*)(t->sa.base); default: fprintf (stderr, "ghw_get_base_type: cannot handle type %d\n", t->kind); abort (); } } int get_nbr_elements (union ghw_type *t) { switch (t->kind) { case ghdl_rtik_type_b2: case ghdl_rtik_type_e8: case ghdl_rtik_type_e32: case ghdl_rtik_type_i32: case ghdl_rtik_type_i64: case ghdl_rtik_type_f64: case ghdl_rtik_type_p32: case ghdl_rtik_type_p64: case ghdl_rtik_subtype_scalar: return 1; case ghdl_rtik_subtype_array: case ghdl_rtik_subtype_array_ptr: return t->sa.nbr_el; case ghdl_rtik_type_record: return t->rec.nbr_el; default: fprintf (stderr, "get_nbr_elements: unhandled type %d\n", t->kind); abort (); } } int ghw_get_range_length (union ghw_range *rng) { if(!rng) /* scan-build */ { fprintf (stderr, "get_range_length: null pointer passed, is GHW file corrupt?\n"); abort (); } switch (rng->kind) { case ghdl_rtik_type_i32: if (rng->i32.dir) return (rng->i32.left - rng->i32.right + 1); else return (rng->i32.right - rng->i32.left + 1); case ghdl_rtik_type_e8: if (rng->e8.dir) return (rng->e8.left - rng->e8.right + 1); else return (rng->e8.right - rng->e8.left + 1); default: fprintf (stderr, "get_range_length: unhandled kind %d\n", rng->kind); abort (); } } int ghw_read_type (struct ghw_handler *h) { char hdr[8]; int i; if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) return -1; if (hdr[0] != 0 || hdr[1] != 0 || hdr[2] != 0 || hdr[3] != 0) return -1; h->nbr_types = ghw_get_i32 (h, (unsigned char *)&hdr[4]); h->types = (union ghw_type **) calloc (h->nbr_types, sizeof (union ghw_type *)); for (i = 0; i < h->nbr_types; i++) { int t; t = fgetc (h->stream); if (t == EOF) return -1; /* printf ("type[%d]= %d\n", i, t); */ switch (t) { case ghdl_rtik_type_b2: case ghdl_rtik_type_e8: { struct ghw_type_enum *e; int j; e = calloc (1, sizeof (struct ghw_type_enum)); e->kind = t; e->wkt = ghw_wkt_unknown; e->name = ghw_read_strid (h); if (ghw_read_uleb128 (h, (uint32_t *)&e->nbr) != 0) { free(e); /* cppcheck */ return -1; } e->lits = (const char **) calloc (1, e->nbr * sizeof (char *)); if (h->flag_verbose > 1) printf ("enum %s:", e->name); for (j = 0; j < e->nbr; j++) { e->lits[j] = ghw_read_strid (h); if (h->flag_verbose > 1) printf (" %s", e->lits[j]); } if (h->flag_verbose > 1) printf ("\n"); h->types[i] = (union ghw_type *)e; } break; case ghdl_rtik_type_i32: case ghdl_rtik_type_i64: case ghdl_rtik_type_f64: { struct ghw_type_scalar *sc; sc = calloc (1, sizeof (struct ghw_type_scalar)); sc->kind = t; sc->name = ghw_read_strid (h); if (h->flag_verbose > 1) printf ("scalar: %s\n", sc->name); h->types[i] = (union ghw_type *)sc; } break; case ghdl_rtik_type_p32: case ghdl_rtik_type_p64: { struct ghw_type_physical *ph; ph = calloc (1, sizeof (struct ghw_type_physical)); ph->kind = t; ph->name = ghw_read_strid (h); if (h->version == 0) ph->nbr_units = 0; else { unsigned int ix; if (ghw_read_uleb128 (h, &ph->nbr_units) != 0) { free(ph); /* cppcheck */ return -1; } ph->units = calloc (ph->nbr_units, sizeof (struct ghw_unit)); for (ix = 0; ix < ph->nbr_units; ix++) { ph->units[ix].name = ghw_read_strid (h); if (ghw_read_lsleb128 (h, &ph->units[ix].val) < 0) { free(ph->units); /* missed by cppcheck */ free(ph); /* missed by cppcheck */ return -1; } } } if (h->flag_verbose > 1) printf ("physical: %s\n", ph->name); h->types[i] = (union ghw_type *)ph; } break; case ghdl_rtik_subtype_scalar: { struct ghw_subtype_scalar *ss; ss = calloc (1, sizeof (struct ghw_subtype_scalar)); ss->kind = t; ss->name = ghw_read_strid (h); ss->base = ghw_read_typeid (h); ss->rng = ghw_read_range (h); if (h->flag_verbose > 1) printf ("subtype scalar: %s\n", ss->name); h->types[i] = (union ghw_type *)ss; } break; case ghdl_rtik_type_array: { struct ghw_type_array *arr; int j; arr = calloc (1, sizeof (struct ghw_type_array)); arr->kind = t; arr->name = ghw_read_strid (h); arr->el = ghw_read_typeid (h); if (ghw_read_uleb128 (h, (uint32_t *)&arr->nbr_dim) != 0) { free(arr); /* cppcheck */ return -1; } arr->dims = (union ghw_type **) calloc (arr->nbr_dim, sizeof (union ghw_type *)); for (j = 0; j < arr->nbr_dim; j++) arr->dims[j] = ghw_read_typeid (h); if (h->flag_verbose > 1) printf ("array: %s\n", arr->name); h->types[i] = (union ghw_type *)arr; } break; case ghdl_rtik_subtype_array: case ghdl_rtik_subtype_array_ptr: { struct ghw_subtype_array *sa; int j; int nbr_el; sa = calloc (1, sizeof (struct ghw_subtype_array)); sa->kind = t; sa->name = ghw_read_strid (h); sa->base = (struct ghw_type_array *)ghw_read_typeid (h); nbr_el = get_nbr_elements (sa->base->el); sa->rngs = calloc (sa->base->nbr_dim, sizeof (union ghw_range *)); for (j = 0; j < sa->base->nbr_dim; j++) { sa->rngs[j] = ghw_read_range (h); nbr_el *= ghw_get_range_length (sa->rngs[j]); } sa->nbr_el = nbr_el; if (h->flag_verbose > 1) printf ("subtype array: %s (nbr_el=%d)\n", sa->name, sa->nbr_el); h->types[i] = (union ghw_type *)sa; } break; case ghdl_rtik_type_record: { struct ghw_type_record *rec; int j; int nbr_el; rec = calloc (1, sizeof (struct ghw_type_record)); rec->kind = t; rec->name = ghw_read_strid (h); if (ghw_read_uleb128 (h, (uint32_t *)&rec->nbr_fields) != 0) { free(rec); /* cppcheck */ return -1; } rec->el = calloc (rec->nbr_fields, sizeof (struct ghw_record_element)); nbr_el = 0; for (j = 0; j < rec->nbr_fields; j++) { rec->el[j].name = ghw_read_strid (h); rec->el[j].type = ghw_read_typeid (h); nbr_el += get_nbr_elements (rec->el[j].type); } rec->nbr_el = nbr_el; if (h->flag_verbose > 1) printf ("record type: %s (nbr_el=%d)\n", rec->name, rec->nbr_el); h->types[i] = (union ghw_type *)rec; } break; default: fprintf (stderr, "ghw_read_type: unknown type %d\n", t); return -1; } } if (fgetc (h->stream) != 0) return -1; return 0; } int ghw_read_wk_types (struct ghw_handler *h) { char hdr[4]; if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) return -1; if (hdr[0] != 0 || hdr[1] != 0 || hdr[2] != 0 || hdr[3] != 0) return -1; while (1) { int t; union ghw_type *tid; t = fgetc (h->stream); if (t == EOF) return -1; else if (t == 0) break; tid = ghw_read_typeid (h); if (tid->kind == ghdl_rtik_type_b2 || tid->kind == ghdl_rtik_type_e8) { if (h->flag_verbose > 0) printf ("%s: wkt=%d\n", tid->en.name, t); tid->en.wkt = t; } } return 0; } void ghw_disp_typename (struct ghw_handler *h, union ghw_type *t) { (void) h; printf ("%s", t->common.name); } /* Read a signal composed of severals elements. */ int ghw_read_signal (struct ghw_handler *h, unsigned int *sigs, union ghw_type *t) { switch (t->kind) { case ghdl_rtik_type_b2: case ghdl_rtik_type_e8: case ghdl_rtik_type_e32: case ghdl_rtik_subtype_scalar: { uint32_t sig_el; if (ghw_read_uleb128 (h, &sig_el) < 0) return -1; *sigs = sig_el; if (((int)sig_el) >= h->nbr_sigs) abort (); if (h->sigs[sig_el].type == NULL) h->sigs[sig_el].type = ghw_get_base_type (t); } return 0; case ghdl_rtik_subtype_array: case ghdl_rtik_subtype_array_ptr: { int i; int stride; int len; len = t->sa.nbr_el; stride = get_nbr_elements (t->sa.base->el); for (i = 0; i < len; i += stride) if (ghw_read_signal (h, &sigs[i], t->sa.base->el) < 0) return -1; } return 0; case ghdl_rtik_type_record: { int i; int off; off = 0; for (i = 0; i < t->rec.nbr_fields; i++) { if (ghw_read_signal (h, &sigs[off], t->rec.el[i].type) < 0) return -1; off += get_nbr_elements (t->rec.el[i].type); } } return 0; default: fprintf (stderr, "ghw_read_signal: type kind %d unhandled\n", t->kind); abort (); } } int ghw_read_value (struct ghw_handler *h, union ghw_val *val, union ghw_type *type) { switch (ghw_get_base_type (type)->kind) { case ghdl_rtik_type_b2: { int v; v = fgetc (h->stream); if (v == EOF) return -1; val->b2 = v; } break; case ghdl_rtik_type_e8: { int v; v = fgetc (h->stream); if (v == EOF) return -1; val->e8 = v; } break; case ghdl_rtik_type_i32: case ghdl_rtik_type_p32: { int32_t v; if (ghw_read_sleb128 (h, &v) < 0) return -1; val->i32 = v; } break; case ghdl_rtik_type_f64: { double v; if (ghw_read_f64 (h, &v) < 0) return -1; val->f64 = v; } break; case ghdl_rtik_type_p64: { int64_t v; if (ghw_read_lsleb128 (h, &v) < 0) return -1; val->i64 = v; } break; default: fprintf (stderr, "read_value: cannot handle format %d\n", type->kind); abort (); } return 0; } int ghw_read_hie (struct ghw_handler *h) { char hdr[16]; int nbr_scopes; int nbr_sigs; int i; struct ghw_hie *blk; struct ghw_hie **last; if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) return -1; if (hdr[0] != 0 || hdr[1] != 0 || hdr[2] != 0 || hdr[3] != 0) return -1; nbr_scopes = ghw_get_i32 (h, (unsigned char *)&hdr[4]); /* Number of declared signals (which may be composite). */ nbr_sigs = ghw_get_i32 (h, (unsigned char *)&hdr[8]); /* Number of basic signals. */ h->nbr_sigs = ghw_get_i32 (h, (unsigned char *)&hdr[12]); if (h->flag_verbose) printf ("%d scopes, %d signals, %d signal elements\n", nbr_scopes, nbr_sigs, h->nbr_sigs); blk = (struct ghw_hie *)calloc (1, sizeof (struct ghw_hie)); blk->kind = ghw_hie_design; blk->name = NULL; blk->parent = NULL; blk->brother = NULL; blk->u.blk.child = NULL; last = &blk->u.blk.child; h->hie = blk; h->nbr_sigs++; h->sigs = (struct ghw_sig *) calloc (h->nbr_sigs, sizeof (struct ghw_sig)); memset (h->sigs, 0, h->nbr_sigs * sizeof (struct ghw_sig)); while (1) { int t; struct ghw_hie *el; uint32_t str; t = fgetc (h->stream); if (t == EOF) return -1; if (t == 0) break; if (t == ghw_hie_eos) { blk = blk->parent; if(!blk) /* scan-build : possibly from malformed file? */ { fprintf (stderr, "ghw_read_hie: NULL pointer on ghw_hie_eos\n"); abort (); } if (blk->u.blk.child == NULL) last = &blk->u.blk.child; else { struct ghw_hie *l = blk->u.blk.child; while (l->brother != NULL) l = l->brother; last = &l->brother; } continue; } el = (struct ghw_hie *) calloc (1, sizeof (struct ghw_hie)); el->kind = t; el->parent = blk; el->brother = NULL; /* Link. */ *last = el; last = &el->brother; /* Read name. */ if (ghw_read_uleb128 (h, &str) != 0) return -1; el->name = h->str_table[str]; switch (t) { case ghw_hie_eoh: case ghw_hie_design: case ghw_hie_eos: /* Should not be here. */ abort (); case ghw_hie_process: break; case ghw_hie_block: case ghw_hie_generate_if: case ghw_hie_generate_for: case ghw_hie_instance: case ghw_hie_generic: case ghw_hie_package: /* Create a block. */ el->u.blk.child = NULL; if (t == ghw_hie_generate_for) { el->u.blk.iter_type = ghw_read_typeid (h); el->u.blk.iter_value = calloc (1, sizeof (union ghw_val)); if (ghw_read_value (h, el->u.blk.iter_value, el->u.blk.iter_type) < 0) return -1; } blk = el; last = &el->u.blk.child; break; case ghw_hie_signal: case ghw_hie_port_in: case ghw_hie_port_out: case ghw_hie_port_inout: case ghw_hie_port_buffer: case ghw_hie_port_linkage: /* For a signal, read type. */ { int nbr_el; unsigned int *sigs; el->u.sig.type = ghw_read_typeid (h); nbr_el = get_nbr_elements (el->u.sig.type); if(nbr_el < 0) { fprintf (stderr, "ghw_read_hie: nbr_el = %d for signal %s\n", nbr_el, el->name); abort(); } sigs = (unsigned int *) calloc ((nbr_el + 1), sizeof (unsigned int)); el->u.sig.sigs = sigs; /* Last element is NULL. */ sigs[nbr_el] = 0; if (h->flag_verbose > 1) printf ("signal %s: %d el [", el->name, nbr_el); if (ghw_read_signal (h, sigs, el->u.sig.type) < 0) return -1; if (h->flag_verbose > 1) { int ix; for (ix = 0; ix < nbr_el; ix++) printf (" #%u", sigs[ix]); printf ("]\n"); } } break; default: fprintf (stderr, "ghw_read_hie: unhandled kind %d\n", t); abort (); } } /* Allocate values. */ for (i = 0; i < h->nbr_sigs; i++) if (h->sigs[i].type != NULL) h->sigs[i].val = (union ghw_val *) calloc (1, sizeof (union ghw_val)); return 0; } const char * ghw_get_hie_name (struct ghw_hie *h) { switch (h->kind) { case ghw_hie_eoh: return "eoh"; case ghw_hie_design: return "design"; case ghw_hie_block: return "block"; case ghw_hie_generate_if: return "generate-if"; case ghw_hie_generate_for: return "generate-for"; case ghw_hie_instance: return "instance"; case ghw_hie_package: return "package"; case ghw_hie_process: return "process"; case ghw_hie_generic: return "generic"; case ghw_hie_eos: return "eos"; case ghw_hie_signal: return "signal"; case ghw_hie_port_in: return "port-in"; case ghw_hie_port_out: return "port-out"; case ghw_hie_port_inout: return "port-inout"; case ghw_hie_port_buffer: return "port-buffer"; case ghw_hie_port_linkage: return "port-linkage"; default: return "??"; } } void ghw_disp_value (union ghw_val *val, union ghw_type *type); void ghw_disp_hie (struct ghw_handler *h, struct ghw_hie *top) { int i; int indent; struct ghw_hie *hie; struct ghw_hie *n; hie = top; indent = 0; while (1) { for (i = 0; i < indent; i++) fputc (' ', stdout); printf ("%s", ghw_get_hie_name (hie)); switch (hie->kind) { case ghw_hie_design: case ghw_hie_block: case ghw_hie_generate_if: case ghw_hie_generate_for: case ghw_hie_instance: case ghw_hie_process: case ghw_hie_package: if (hie->name) printf (" %s", hie->name); if (hie->kind == ghw_hie_generate_for) { printf ("("); ghw_disp_value (hie->u.blk.iter_value, hie->u.blk.iter_type); printf (")"); } n = hie->u.blk.child; if (n == NULL) n = hie->brother; else indent++; break; case ghw_hie_generic: case ghw_hie_eos: abort (); case ghw_hie_signal: case ghw_hie_port_in: case ghw_hie_port_out: case ghw_hie_port_inout: case ghw_hie_port_buffer: case ghw_hie_port_linkage: { unsigned int *sigs; printf (" %s: ", hie->name); ghw_disp_typename (h, hie->u.sig.type); for (sigs = hie->u.sig.sigs; *sigs != 0; sigs++) printf (" #%u", *sigs); n = hie->brother; } break; default: abort (); } printf ("\n"); while (n == NULL) { if (hie->parent == NULL) return; hie = hie->parent; indent--; n = hie->brother; } hie = n; } } int ghw_read_eoh (struct ghw_handler *h) { (void) h; return 0; } int ghw_read_base (struct ghw_handler *h) { unsigned char hdr[4] = { 0, 0, 0, 0 }; /* scan-build */ int res; while (1) { if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) return -1; if (memcmp (hdr, "STR", 4) == 0) res = ghw_read_str (h); else if (memcmp (hdr, "HIE", 4) == 0) res = ghw_read_hie (h); else if (memcmp (hdr, "TYP", 4) == 0) res = ghw_read_type (h); else if (memcmp (hdr, "WKT", 4) == 0) res = ghw_read_wk_types (h); else if (memcmp (hdr, "EOH", 4) == 0) return 0; else { fprintf (stderr, "ghw_read_base: unknown GHW section %c%c%c%c\n", hdr[0], hdr[1], hdr[2], hdr[3]); return -1; } if (res != 0) { fprintf (stderr, "ghw_read_base: error in section %s\n", hdr); return res; } } } int ghw_read_signal_value (struct ghw_handler *h, struct ghw_sig *s) { return ghw_read_value (h, s->val, s->type); } int ghw_read_snapshot (struct ghw_handler *h) { char hdr[12]; int i; struct ghw_sig *s; if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) return -1; if (hdr[0] != 0 || hdr[1] != 0 || hdr[2] != 0 || hdr[3] != 0) return -1; h->snap_time = ghw_get_i64 (h, (unsigned char *)&hdr[4]); if (h->flag_verbose > 1) printf ("Time is "GHWLLD" fs\n", h->snap_time); for (i = 0; i < h->nbr_sigs; i++) { s = &h->sigs[i]; if (s->type != NULL) { if (h->flag_verbose > 1) printf ("read type %d for sig %d\n", s->type->kind, i); if (ghw_read_signal_value (h, s) < 0) return -1; } } if (fread (hdr, 4, 1, h->stream) != 1) return -1; if (memcmp (hdr, "ESN", 4)) return -1; return 0; } void ghw_disp_values (struct ghw_handler *h); int ghw_read_cycle_start (struct ghw_handler *h) { char hdr[8]; if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) return -1; h->snap_time = ghw_get_i64 (h, (unsigned char *)hdr); return 0; } int ghw_read_cycle_cont (struct ghw_handler *h, int *list) { int i; int *list_p; i = 0; list_p = list; while (1) { uint32_t d; /* Read delta to next signal. */ if (ghw_read_uleb128 (h, &d) < 0) return -1; if (d == 0) { /* Last signal reached. */ break; } /* Find next signal. */ while (d > 0) { i++; if (h->sigs[i].type != NULL) d--; } if (ghw_read_signal_value (h, &h->sigs[i]) < 0) return -1; if (list_p) *list_p++ = i; } if (list_p) *list_p = 0; return 0; } int ghw_read_cycle_next (struct ghw_handler *h) { int64_t d_time; if (ghw_read_lsleb128 (h, &d_time) < 0) return -1; if (d_time == -1) return 0; h->snap_time += d_time; return 1; } int ghw_read_cycle_end (struct ghw_handler *h) { char hdr[4]; if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) return -1; if (memcmp (hdr, "ECY", 4)) return -1; return 0; } static const char * ghw_get_lit (union ghw_type *type, int e) { if (e >= type->en.nbr || e < 0) return "??"; else return type->en.lits[e]; } static void ghw_disp_lit (union ghw_type *type, int e) { printf ("%s (%d)", ghw_get_lit (type, e), e); } void ghw_disp_value (union ghw_val *val, union ghw_type *type) { switch (ghw_get_base_type (type)->kind) { case ghdl_rtik_type_b2: ghw_disp_lit (type, val->b2); break; case ghdl_rtik_type_e8: ghw_disp_lit (type, val->e8); break; case ghdl_rtik_type_i32: printf (GHWLD, val->i32); break; case ghdl_rtik_type_p64: printf (GHWLLD, val->i64); break; case ghdl_rtik_type_f64: printf ("%g", val->f64); break; default: fprintf (stderr, "ghw_disp_value: cannot handle type %d\n", type->kind); abort (); } } /* Put the ASCII representation of VAL into BUF, whose size if LEN. A NUL is always written to BUF. */ void ghw_get_value (char *buf, int len, union ghw_val *val, union ghw_type *type) { switch (ghw_get_base_type (type)->kind) { case ghdl_rtik_type_b2: if (val->b2 <= 1) { strncpy (buf, type->en.lits[val->b2], len - 1); buf[len - 1] = 0; } else { snprintf (buf, len, "?%d", val->b2); } break; case ghdl_rtik_type_e8: if (val->e8 <= type->en.nbr) { /* XXX : without the if() is this a programming error? */ if(type->en.lits) { strncpy (buf, type->en.lits[val->e8], len - 1); buf[len - 1] = 0; } else { snprintf (buf, len, "?%d", val->e8); } } else { snprintf (buf, len, "?%d", val->e8); } break; case ghdl_rtik_type_i32: snprintf (buf, len, GHWLD, val->i32); break; case ghdl_rtik_type_p64: snprintf (buf, len, GHWLLD, val->i64); break; case ghdl_rtik_type_f64: snprintf (buf, len, "%g", val->f64); break; default: snprintf (buf, len, "?bad type %d?", type->kind); } } void ghw_disp_values (struct ghw_handler *h) { int i; for (i = 0; i < h->nbr_sigs; i++) { struct ghw_sig *s = &h->sigs[i]; if (s->type != NULL) { printf ("#%d: ", i); ghw_disp_value (s->val, s->type); printf ("\n"); } } } int ghw_read_directory (struct ghw_handler *h) { unsigned char hdr[8]; int nbr_entries; int i; if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) return -1; nbr_entries = ghw_get_i32 (h, &hdr[4]); if (h->flag_verbose) printf ("Directory (%d entries):\n", nbr_entries); for (i = 0; i < nbr_entries; i++) { unsigned char ent[8]; int pos; if (fread (ent, sizeof (ent), 1, h->stream) != 1) return -1; pos = ghw_get_i32 (h, &ent[4]); if (h->flag_verbose) printf (" %s at %d\n", ent, pos); } if (fread (hdr, 4, 1, h->stream) != 1) return -1; if (memcmp (hdr, "EOD", 4)) return -1; return 0; } int ghw_read_tailer (struct ghw_handler *h) { unsigned char hdr[8]; int pos; if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) return -1; pos = ghw_get_i32 (h, &hdr[4]); if (h->flag_verbose) printf ("Tailer: directory at %d\n", pos); return 0; } enum ghw_res ghw_read_sm_hdr (struct ghw_handler *h, int *list) { unsigned char hdr[4] = { 0, 0, 0, 0 }; /* scan-build */ int res; if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) { if (feof (h->stream)) return ghw_res_eof; else return ghw_res_error; } if (memcmp (hdr, "SNP", 4) == 0) { res = ghw_read_snapshot (h); if (res < 0) return res; return ghw_res_snapshot; } else if (memcmp (hdr, "CYC", 4) == 0) { res = ghw_read_cycle_start (h); if (res < 0) return res; res = ghw_read_cycle_cont (h, list); if (res < 0) return res; return ghw_res_cycle; } else if (memcmp (hdr, "DIR", 4) == 0) { res = ghw_read_directory (h); } else if (memcmp (hdr, "TAI", 4) == 0) { res = ghw_read_tailer (h); } else { fprintf (stderr, "unknown GHW section %c%c%c%c\n", hdr[0], hdr[1], hdr[2], hdr[3]); return -1; } if (res != 0) return res; return ghw_res_other; } int ghw_read_sm (struct ghw_handler *h, enum ghw_sm_type *sm) { int res; while (1) { /* printf ("sm: state = %d\n", *sm); */ switch (*sm) { case ghw_sm_init: case ghw_sm_sect: res = ghw_read_sm_hdr (h, NULL); switch (res) { case ghw_res_other: break; case ghw_res_snapshot: *sm = ghw_sm_sect; return res; case ghw_res_cycle: *sm = ghw_sm_cycle; return res; default: return res; } break; case ghw_sm_cycle: if (0) printf ("Time is "GHWLLD" fs\n", h->snap_time); if (0) ghw_disp_values (h); res = ghw_read_cycle_next (h); if (res < 0) return res; if (res == 1) { res = ghw_read_cycle_cont (h, NULL); if (res < 0) return res; return ghw_res_cycle; } res = ghw_read_cycle_end (h); if (res < 0) return res; *sm = ghw_sm_sect; break; } } } int ghw_read_cycle (struct ghw_handler *h) { int res; res = ghw_read_cycle_start (h); if (res < 0) return res; while (1) { res = ghw_read_cycle_cont (h, NULL); if (res < 0) return res; if (0) printf ("Time is "GHWLLD" fs\n", h->snap_time); if (0) ghw_disp_values (h); res = ghw_read_cycle_next (h); if (res < 0) return res; if (res == 0) break; } res = ghw_read_cycle_end (h); return res; } int ghw_read_dump (struct ghw_handler *h) { unsigned char hdr[4] = { 0, 0, 0, 0 }; /* scan-build */ int res; while (1) { if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) { if (feof (h->stream)) return 0; else return -1; } if (memcmp (hdr, "SNP", 4) == 0) { res = ghw_read_snapshot (h); if (0 && res >= 0) ghw_disp_values (h); } else if (memcmp (hdr, "CYC", 4) == 0) { res = ghw_read_cycle (h); } else if (memcmp (hdr, "DIR", 4) == 0) { res = ghw_read_directory (h); } else if (memcmp (hdr, "TAI", 4) == 0) { res = ghw_read_tailer (h); } else { fprintf (stderr, "unknown GHW section %c%c%c%c\n", hdr[0], hdr[1], hdr[2], hdr[3]); return -1; } if (res != 0) return res; } } struct ghw_section ghw_sections[] = { { "\0\0\0", NULL }, { "STR", ghw_read_str }, { "HIE", ghw_read_hie }, { "TYP", ghw_read_type }, { "WKT", ghw_read_wk_types }, { "EOH", ghw_read_eoh }, { "SNP", ghw_read_snapshot }, { "CYC", ghw_read_cycle }, { "DIR", ghw_read_directory }, { "TAI", ghw_read_tailer } }; int ghw_read_section (struct ghw_handler *h) { unsigned char hdr[4]; unsigned int i; if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) { if (feof (h->stream)) return -2; else return -1; } for (i = 1; i < sizeof (ghw_sections) / sizeof (*ghw_sections); i++) if (memcmp (hdr, ghw_sections[i].name, 4) == 0) return i; fprintf (stderr, "ghw_read_section: unknown GHW section %c%c%c%c\n", hdr[0], hdr[1], hdr[2], hdr[3]); return 0; } void ghw_close (struct ghw_handler *h) { if (h->stream) { if(h->stream_ispipe) { pclose (h->stream); } else { fclose (h->stream); } h->stream = NULL; } } const char * ghw_get_dir (int is_downto) { return is_downto ? "downto" : "to"; } void ghw_disp_range (union ghw_type *type, union ghw_range *rng) { switch (rng->kind) { case ghdl_rtik_type_e8: printf ("%s %s %s", ghw_get_lit (type, rng->e8.left), ghw_get_dir (rng->e8.dir), ghw_get_lit (type, rng->e8.right)); break; case ghdl_rtik_type_i32: case ghdl_rtik_type_p32: printf (GHWLD" %s "GHWLD, rng->i32.left, ghw_get_dir (rng->i32.dir), rng->i32.right); break; case ghdl_rtik_type_i64: case ghdl_rtik_type_p64: printf (GHWLLD" %s "GHWLLD, rng->i64.left, ghw_get_dir (rng->i64.dir), rng->i64.right); break; case ghdl_rtik_type_f64: printf ("%g %s %g", rng->f64.left, ghw_get_dir (rng->f64.dir), rng->f64.right); break; default: printf ("?(%d)", rng->kind); } } void ghw_disp_type (struct ghw_handler *h, union ghw_type *t) { switch (t->kind) { case ghdl_rtik_type_b2: case ghdl_rtik_type_e8: { struct ghw_type_enum *e = &t->en; int i; printf ("type %s is (", e->name); for (i = 0; i < e->nbr; i++) { if (i != 0) printf (", "); printf ("%s", e->lits[i]); } printf (");"); if (e->wkt != ghw_wkt_unknown) printf (" -- WKT:%d", e->wkt); printf ("\n"); } break; case ghdl_rtik_type_i32: case ghdl_rtik_type_f64: { struct ghw_type_scalar *s = &t->sc; printf ("type %s is range <>;\n", s->name); } break; case ghdl_rtik_type_p32: case ghdl_rtik_type_p64: { unsigned int i; struct ghw_type_physical *p = &t->ph; printf ("type %s is range <> units\n", p->name); for (i = 0; i < p->nbr_units; i++) { struct ghw_unit *u = &p->units[i]; printf (" %s = "GHWLLD" %s;\n", u->name, u->val, p->units[0].name); } printf ("end units\n"); } break; case ghdl_rtik_subtype_scalar: { struct ghw_subtype_scalar *s = &t->ss; printf ("subtype %s is ", s->name); ghw_disp_typename (h, s->base); printf (" range "); ghw_disp_range (s->base, s->rng); printf (";\n"); } break; case ghdl_rtik_type_array: { struct ghw_type_array *a = &t->ar; int i; printf ("type %s is array (", a->name); for (i = 0; i < a->nbr_dim; i++) { if (i != 0) printf (", "); ghw_disp_typename (h, a->dims[i]); printf (" range <>"); } printf (") of "); ghw_disp_typename (h, a->el); printf (";\n"); } break; case ghdl_rtik_subtype_array: case ghdl_rtik_subtype_array_ptr: { struct ghw_subtype_array *a = &t->sa; int i; printf ("subtype %s is ", a->name); ghw_disp_typename (h, (union ghw_type *)a->base); printf (" ("); for (i = 0; i < a->base->nbr_dim; i++) { if (i != 0) printf (", "); ghw_disp_range ((union ghw_type *)a->base, a->rngs[i]); } printf (");\n"); } break; case ghdl_rtik_type_record: { struct ghw_type_record *r = &t->rec; int i; printf ("type %s is record\n", r->name); for (i = 0; i < r->nbr_fields; i++) { printf (" %s: ", r->el[i].name); ghw_disp_typename (h, r->el[i].type); printf ("\n"); } printf ("end record;\n"); } break; default: printf ("ghw_disp_type: unhandled type kind %d\n", t->kind); } } void ghw_disp_types (struct ghw_handler *h) { int i; for (i = 0; i < h->nbr_types; i++) ghw_disp_type (h, h->types[i]); } gtkwave-3.3.66/src/treesearch.h0000664000076400007640000000220712341266475015677 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2010 * * 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. */ #ifndef WAVE_TREESEARCH_H #define WAVE_TREESEARCH_H void treebox(char *title, GtkSignalFunc func, GtkWidget *old_window); GtkWidget* treeboxframe(char *title, GtkSignalFunc func); void mkmenu_treesearch_cleanup(GtkWidget *widget, gpointer data); void dump_open_tree_nodes(FILE *wave, xl_Tree *t); int force_open_tree_node(char *name, int keep_path_nodes_open, struct tree **t_pnt); void select_tree_node(char *name); void dnd_setup(GtkWidget *src, GtkWidget *widget, int enable_receive); /* dnd from gtk2 tree to signalwindow */ void treeview_select_all_callback(void); /* gtk2 */ void treeview_unselect_all_callback(void); /* gtk2 */ struct tree *fetchlow(struct tree *t); struct tree *fetchhigh(struct tree *t); void fetchvex(struct tree *t, char direction); int treebox_is_active(void); #if WAVE_USE_GTK2 void DND_helper_quartz(char *data); #endif #endif gtkwave-3.3.66/src/status.h0000664000076400007640000000057411523063250015065 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2010 * * 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. */ #ifndef WAVE_STATUS_H #define WAVE_STATUS_H void status_text(char *str); #endif gtkwave-3.3.66/src/lxt.h0000664000076400007640000000413012341266475014356 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2001-2004. * * 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. */ #include "globals.h" #ifndef WAVE_LXT_H #define WAVE_LXT_H #ifndef HAVE_FSEEKO #define fseeko fseek #endif #include "vcd.h" TimeType lxt_main(char *fname); void import_lxt_trace(nptr np); #define LT_SECTION_END (0) #define LT_SECTION_CHG (1) #define LT_SECTION_SYNC_TABLE (2) #define LT_SECTION_FACNAME (3) #define LT_SECTION_FACNAME_GEOMETRY (4) #define LT_SECTION_TIMESCALE (5) #define LT_SECTION_TIME_TABLE (6) #define LT_SECTION_INITIAL_VALUE (7) #define LT_SECTION_DOUBLE_TEST (8) #define LT_SECTION_TIME_TABLE64 (9) #define LT_SECTION_ZFACNAME_PREDEC_SIZE (10) #define LT_SECTION_ZFACNAME_SIZE (11) #define LT_SECTION_ZFACNAME_GEOMETRY_SIZE (12) #define LT_SECTION_ZSYNC_SIZE (13) #define LT_SECTION_ZTIME_TABLE_SIZE (14) #define LT_SECTION_ZCHG_PREDEC_SIZE (15) #define LT_SECTION_ZCHG_SIZE (16) #define LT_SECTION_ZDICTIONARY (17) #define LT_SECTION_ZDICTIONARY_SIZE (18) #define LT_SECTION_EXCLUDE_TABLE (19) #define LT_SECTION_TIMEZERO (20) #define LT_SYM_F_BITS (0) #define LT_SYM_F_INTEGER (1<<0) #define LT_SYM_F_DOUBLE (1<<1) #define LT_SYM_F_STRING (1<<2) #define LT_SYM_F_ALIAS (1<<3) #define LT_HDRID (0x0138) #define LT_VERSION (0x0004) #define LT_TRLID (0xB4) #define LT_MINDICTWIDTH (16) #define LXT_MMAP_MALLOC_BOUNDARY (128*1024*1024) #if defined __MINGW32__ || defined _MSC_VER void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset); int munmap(void *start, size_t length); #endif #endif gtkwave-3.3.66/src/jrb.h0000664000076400007640000000634112341266475014332 0ustar bybellbybell#ifndef _JRB_H_ #define _JRB_H_ /* The Jval -- a type that can hold any 8-byte type */ typedef union { int i; long l; float f; double d; void *v; char *s; char c; unsigned char uc; short sh; unsigned short ush; unsigned int ui; int iarray[2]; float farray[2]; char carray[8]; unsigned char ucarray[8]; } Jval; struct jrb_chain { /* added for rtlbrowse */ struct jrb_chain *next; Jval val; }; /* Main jrb_node. You only ever use the fields flink blink k.key or k.ikey v.val */ typedef struct jrb_node { unsigned char red; unsigned char internal; unsigned char left; unsigned char roothead; /* (bit 1 is root, bit 2 is head) */ struct jrb_node *flink; struct jrb_node *blink; struct jrb_node *parent; Jval key; Jval val; } *JRB; extern JRB make_jrb(void); /* Creates a new rb-tree */ /* Creates a node with key key and val val and inserts it into the tree. jrb_insert uses strcmp() as comparison funcion. jrb_inserti uses <>=, jrb_insertg uses func() */ extern JRB jrb_insert_str(JRB tree, char *key, Jval val); extern JRB jrb_insert_int(JRB tree, int ikey, Jval val); extern JRB jrb_insert_vptr(JRB tree, void *vkey, Jval val); extern JRB jrb_insert_gen(JRB tree, Jval key, Jval val, int (*func)(Jval,Jval)); /* returns an external node in t whose value is equal k. Returns NULL if there is no such node in the tree */ extern JRB jrb_find_str(JRB root, const char *key); extern JRB jrb_find_int(JRB root, int ikey); extern JRB jrb_find_vptr(JRB root, void *vkey); extern JRB jrb_find_gen(JRB root, Jval, int (*func)(Jval, Jval)); /* returns an external node in t whose value is equal k or whose value is the smallest value greater than k. Sets found to 1 if the key was found, and 0 otherwise. */ extern JRB jrb_find_gte_str(JRB root, const char *key, int *found); extern JRB jrb_find_gte_int(JRB root, int ikey, int *found); extern JRB jrb_find_gte_vptr(JRB root, void *vkey, int *found); extern JRB jrb_find_gte_gen(JRB root, Jval key, int (*func)(Jval, Jval), int *found); /* Creates a node with key key and val val and inserts it into the tree before/after node nd. Does not check to ensure that you are keeping the correct order */ extern void jrb_delete_node(JRB node); /* Deletes and frees a node (but not the key or val) */ extern void jrb_free_tree(JRB root); /* Deletes and frees an entire tree */ extern Jval jrb_val(JRB node); /* Returns node->v.val -- this is to shut lint up */ extern int jrb_nblack(JRB n); /* returns # of black nodes in path from n to the root */ int jrb_plength(JRB n); /* returns the # of nodes in path from n to the root */ #define jrb_first(n) (n->flink) #define jrb_last(n) (n->blink) #define jrb_next(n) (n->flink) #define jrb_prev(n) (n->blink) #define jrb_empty(t) (t->flink == t) #ifndef jrb_nil #define jrb_nil(t) (t) #endif #define jrb_traverse(ptr, lst) \ for(ptr = jrb_first(lst); ptr != jrb_nil(lst); ptr = jrb_next(ptr)) #define jrb_rtraverse(ptr, lst) \ for(ptr = jrb_last(lst); ptr != jrb_nil(lst); ptr = jrb_prev(ptr)) #endif gtkwave-3.3.66/src/markerbox.h0000664000076400007640000000162712352352046015541 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2010-2014 * * 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. */ #ifndef WAVE_MARKERBOX_H #define WAVE_MARKERBOX_H #ifdef WAVE_MANYMARKERS_MODE /* 702 will go from A-Z, AA-AZ, ... , ZA-ZZ */ /* this is a bijective name similar to the columns on spreadsheets */ /* the upper count is (practically) unbounded */ #define WAVE_NUM_NAMED_MARKERS (702) #else /* do not go less than 26! */ #define WAVE_NUM_NAMED_MARKERS (26) #endif void markerbox(char *title, GtkSignalFunc func); char *make_bijective_marker_id_string(char *buf, unsigned int value); unsigned int bijective_marker_id_string_hash(char *so); unsigned int bijective_marker_id_string_len(char *s); #endif gtkwave-3.3.66/src/rc.c0000664000076400007640000006443112542115425014147 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2013. * * 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. */ /* AIX may need this for alloca to work */ #if defined _AIX #pragma alloca #endif #include "globals.h" #include #include #include #include #include #include #include #include #include "analyzer.h" #include "currenttime.h" #include "symbol.h" #include "vcd.h" #include "wavealloca.h" #include "fgetdynamic.h" #include "debug.h" #include "main.h" #include "menu.h" #include "color.h" #include "vlist.h" #include "rc.h" #ifdef MAC_INTEGRATION #include #endif #ifndef _MSC_VER #ifndef __MINGW32__ #include #include static char *rcname=".gtkwaverc"; /* name of environment file--POSIX */ #else static char *rcname="gtkwave.ini"; /* name of environment file--WIN32 */ #endif #else static char *rcname="gtkwave.ini"; /* name of environment file--WIN32 */ #define strcasecmp _stricmp #endif /* * functions that set the individual rc variables.. */ int f_accel(char *str) { DEBUG(printf("f_accel(\"%s\")\n",str)); if(strlen(str)) { set_wave_menu_accelerator(str); } return(0); } int f_alt_hier_delimeter(char *str) { DEBUG(printf("f_alt_hier_delimeter(\"%s\")\n",str)); if(strlen(str)) { GLOBALS->alt_hier_delimeter=str[0]; } return(0); } int f_analog_redraw_skip_count(char *str) { DEBUG(printf("f_analog_redraw_skip_count(\"%s\")\n",str)); GLOBALS->analog_redraw_skip_count=atoi_64(str); if(GLOBALS->analog_redraw_skip_count < 0) { GLOBALS->analog_redraw_skip_count = 0; } return(0); } int f_append_vcd_hier(char *str) { DEBUG(printf("f_append_vcd_hier(\"%s\")\n",str)); append_vcd_slisthier(str); return(0); } int f_atomic_vectors(char *str) { DEBUG(printf("f_atomic_vectors(\"%s\")\n",str)); GLOBALS->atomic_vectors=atoi_64(str)?1:0; return(0); } int f_autoname_bundles(char *str) { DEBUG(printf("f_autoname_bundles(\"%s\")\n",str)); GLOBALS->autoname_bundles=atoi_64(str)?1:0; return(0); } int f_autocoalesce(char *str) { DEBUG(printf("f_autocoalesce(\"%s\")\n",str)); GLOBALS->autocoalesce=atoi_64(str)?1:0; return(0); } int f_autocoalesce_reversal(char *str) { DEBUG(printf("f_autocoalesce_reversal(\"%s\")\n",str)); GLOBALS->autocoalesce_reversal=atoi_64(str)?1:0; return(0); } int f_constant_marker_update(char *str) { DEBUG(printf("f_constant_marker_update(\"%s\")\n",str)); GLOBALS->constant_marker_update=atoi_64(str)?1:0; return(0); } int f_context_tabposition(char *str) { DEBUG(printf("f_convert_to_reals(\"%s\")\n",str)); GLOBALS->context_tabposition=atoi_64(str)?1:0; return(0); } int f_convert_to_reals(char *str) { DEBUG(printf("f_convert_to_reals(\"%s\")\n",str)); GLOBALS->convert_to_reals=atoi_64(str)?1:0; return(0); } int f_cursor_snap(char *str) { int val; DEBUG(printf("f_cursor_snap(\"%s\")\n",str)); val=atoi_64(str); GLOBALS->cursor_snap=(val<=0)?0:val; return(0); } int f_disable_ae2_alias(char *str) { DEBUG(printf("f_disable_ae2_alias(\"%s\")\n",str)); GLOBALS->disable_ae2_alias=atoi_64(str)?1:0; return(0); } int f_disable_empty_gui(char *str) { DEBUG(printf("f_disable_empty_gui(\"%s\")\n",str)); GLOBALS->disable_empty_gui=atoi_64(str)?1:0; return(0); } int f_disable_mouseover(char *str) { DEBUG(printf("f_disable_mouseover(\"%s\")\n",str)); GLOBALS->disable_mouseover=atoi_64(str)?1:0; return(0); } int f_disable_tooltips(char *str) { DEBUG(printf("f_disable_tooltips(\"%s\")\n",str)); GLOBALS->disable_tooltips=atoi_64(str)?1:0; return(0); } int f_do_initial_zoom_fit(char *str) { DEBUG(printf("f_do_initial_zoom_fit(\"%s\")\n",str)); GLOBALS->do_initial_zoom_fit=atoi_64(str)?1:0; return(0); } int f_dynamic_resizing(char *str) { DEBUG(printf("f_dynamic_resizing(\"%s\")\n",str)); GLOBALS->do_resize_signals=atoi_64(str)?1:0; return(0); } int f_editor(char *str) { char *path, *pathend; DEBUG(printf("f_editor(\"%s\")\n",str)); path = strchr(str, '\"'); if(path) { path++; if(*path) { pathend = strchr(path, '\"'); if(pathend) { *pathend = 0; if(GLOBALS->editor_name) free_2(GLOBALS->editor_name); GLOBALS->editor_name=(char *)strdup_2(path); } } } return(0); } int f_enable_fast_exit(char *str) { DEBUG(printf("f_enable_fast_exit(\"%s\")\n",str)); GLOBALS->enable_fast_exit=atoi_64(str)?1:0; return(0); } int f_enable_ghost_marker(char *str) { DEBUG(printf("f_enable_ghost_marker(\"%s\")\n",str)); GLOBALS->enable_ghost_marker=atoi_64(str)?1:0; return(0); } int f_enable_horiz_grid(char *str) { DEBUG(printf("f_enable_horiz_grid(\"%s\")\n",str)); GLOBALS->enable_horiz_grid=atoi_64(str)?1:0; return(0); } int f_enable_vcd_autosave(char *str) { DEBUG(printf("f_enable_vcd_autosave(\"%s\")\n",str)); GLOBALS->make_vcd_save_file=atoi_64(str)?1:0; return(0); } int f_enable_vert_grid(char *str) { DEBUG(printf("f_enable_vert_grid(\"%s\")\n",str)); GLOBALS->enable_vert_grid=atoi_64(str)?1:0; return(0); } int f_fontname_logfile(char *str) { DEBUG(printf("f_fontname_logfile(\"%s\")\n",str)); if(GLOBALS->fontname_logfile) free_2(GLOBALS->fontname_logfile); GLOBALS->fontname_logfile=(char *)malloc_2(strlen(str)+1); strcpy(GLOBALS->fontname_logfile,str); return(0); } int f_fontname_signals(char *str) { DEBUG(printf("f_fontname_signals(\"%s\")\n",str)); if(GLOBALS->fontname_signals) free_2(GLOBALS->fontname_signals); GLOBALS->fontname_signals=(char *)malloc_2(strlen(str)+1); strcpy(GLOBALS->fontname_signals,str); return(0); } int f_fontname_waves(char *str) { DEBUG(printf("f_fontname_signals(\"%s\")\n",str)); if(GLOBALS->fontname_waves) free_2(GLOBALS->fontname_waves); GLOBALS->fontname_waves=(char *)malloc_2(strlen(str)+1); strcpy(GLOBALS->fontname_waves,str); return(0); } int f_force_toolbars(char *str) { DEBUG(printf("f_force_toolbars(\"%s\")\n",str)); GLOBALS->force_toolbars=atoi_64(str)?1:0; return(0); } int f_hide_sst(char *str) { DEBUG(printf("f_hide_sst(\"%s\")\n",str)); GLOBALS->hide_sst=atoi_64(str)?1:0; return(0); } int f_keep_xz_colors(char *str) { DEBUG(printf("f_keep_xz_colors(\"%s\")\n",str)); GLOBALS->keep_xz_colors=atoi_64(str)?1:0; return(0); } int f_sst_dynamic_filter(char *str) { DEBUG(printf("f_sst_dynamic_filter(\"%s\")\n",str)); GLOBALS->do_dynamic_treefilter=atoi_64(str)?1:0; return(0); } int f_sst_expanded(char *str) { DEBUG(printf("f_sst_expanded(\"%s\")\n",str)); GLOBALS->sst_expanded=atoi_64(str)?1:0; return(0); } int f_hier_delimeter(char *str) { DEBUG(printf("f_hier_delimeter(\"%s\")\n",str)); if(strlen(str)) { GLOBALS->hier_delimeter=str[0]; GLOBALS->hier_was_explicitly_set=1; } return(0); } int f_hier_grouping(char *str) { DEBUG(printf("f_hier_grouping(\"%s\")\n",str)); GLOBALS->hier_grouping=atoi_64(str)?1:0; return(0); } int f_hier_max_level(char *str) { DEBUG(printf("f_hier_max_level(\"%s\")\n",str)); GLOBALS->hier_max_level_shadow=GLOBALS->hier_max_level=atoi_64(str); return(0); } int f_hpane_pack(char *str) { DEBUG(printf("f_hpane_pack(\"%s\")\n",str)); GLOBALS->paned_pack_semantics=atoi_64(str)?1:0; return(0); } int f_highlight_wavewindow(char *str) { DEBUG(printf("f_highlight_wavewindow(\"%s\")\n",str)); GLOBALS->highlight_wavewindow=atoi_64(str)?1:0; return(0); } int f_ignore_savefile_pane_pos(char *str) { DEBUG(printf("f_ignore_savefile_pane_pos(\"%s\")\n",str)); GLOBALS->ignore_savefile_pane_pos=atoi_64(str)?1:0; return(0); } int f_ignore_savefile_pos(char *str) { DEBUG(printf("f_ignore_savefile_pos(\"%s\")\n",str)); GLOBALS->ignore_savefile_pos=atoi_64(str)?1:0; return(0); } int f_ignore_savefile_size(char *str) { DEBUG(printf("f_ignore_savefile_size(\"%s\")\n",str)); GLOBALS->ignore_savefile_size=atoi_64(str)?1:0; return(0); } int f_initial_signal_window_width(char *str) { int val; DEBUG(printf("f_initial_signal_window_width(\"%s\")\n",str)); val=atoi_64(str); GLOBALS->initial_signal_window_width=(val<0)?0:val; return(0); } int f_initial_window_x(char *str) { int val; DEBUG(printf("f_initial_window_x(\"%s\")\n",str)); val=atoi_64(str); GLOBALS->initial_window_x=(val<=0)?-1:val; return(0); } int f_initial_window_xpos(char *str) { int val; DEBUG(printf("f_initial_window_xpos(\"%s\")\n",str)); val=atoi_64(str); GLOBALS->initial_window_xpos=(val<=0)?-1:val; return(0); } int f_initial_window_y(char *str) { int val; DEBUG(printf("f_initial_window_y(\"%s\")\n",str)); val=atoi_64(str); GLOBALS->initial_window_y=(val<=0)?-1:val; return(0); } int f_initial_window_ypos(char *str) { int val; DEBUG(printf("f_initial_window_ypos(\"%s\")\n",str)); val=atoi_64(str); GLOBALS->initial_window_ypos=(val<=0)?-1:val; return(0); } int f_left_justify_sigs(char *str) { DEBUG(printf("f_left_justify_sigs(\"%s\")\n",str)); GLOBALS->left_justify_sigs=atoi_64(str)?1:0; return(0); } int f_lxt_clock_compress_to_z(char *str) { DEBUG(printf("f_lxt_clock_compress_to_z(\"%s\")\n",str)); GLOBALS->lxt_clock_compress_to_z=atoi_64(str)?1:0; return(0); } int f_page_divisor(char *str) { DEBUG(printf("f_page_divisor(\"%s\")\n",str)); sscanf(str,"%lg",&GLOBALS->page_divisor); if(GLOBALS->page_divisor<0.01) { GLOBALS->page_divisor=0.01; } else if(GLOBALS->page_divisor>100.0) { GLOBALS->page_divisor=100.0; } if(GLOBALS->page_divisor>1.0) GLOBALS->page_divisor=1.0/GLOBALS->page_divisor; return(0); } int f_ps_maxveclen(char *str) { DEBUG(printf("f_ps_maxveclen(\"%s\")\n",str)); GLOBALS->ps_maxveclen=atoi_64(str); if(GLOBALS->ps_maxveclen<4) { GLOBALS->ps_maxveclen=4; } else if(GLOBALS->ps_maxveclen>66) { GLOBALS->ps_maxveclen=66; } return(0); } int f_scale_to_time_dimension(char *str) { int which = tolower((int)(*str)); DEBUG(printf("f_scale_to_time_dimension(\"%s\")\n",str)); if(strchr(WAVE_SI_UNITS, which) || (which == 's')) { GLOBALS->scale_to_time_dimension = which; } else { GLOBALS->scale_to_time_dimension = 0; /* also covers '*' case as not found above */ } return(0); } int f_show_base_symbols(char *str) { DEBUG(printf("f_show_base_symbols(\"%s\")\n",str)); GLOBALS->show_base=atoi_64(str)?1:0; return(0); } int f_show_grid(char *str) { DEBUG(printf("f_show_grid(\"%s\")\n",str)); GLOBALS->display_grid=atoi_64(str)?1:0; return(0); } int f_splash_disable(char *str) { DEBUG(printf("f_splash_disable(\"%s\")\n",str)); GLOBALS->splash_disable=atoi_64(str)?1:0; return(0); } int f_strace_repeat_count(char *str) { DEBUG(printf("f_strace_repeat_count(\"%s\")\n",str)); GLOBALS->strace_repeat_count=atoi_64(str); return(0); } int f_use_big_fonts(char *str) { DEBUG(printf("f_use_big_fonts(\"%s\")\n",str)); GLOBALS->use_big_fonts=atoi_64(str)?1:0; return(0); } int f_use_frequency_display(char *str) { DEBUG(printf("f_use_frequency_display(\"%s\")\n",str)); GLOBALS->use_frequency_delta=atoi_64(str)?1:0; return(0); } int f_use_full_precision(char *str) { DEBUG(printf("f_use_full_precision(\"%s\")\n",str)); GLOBALS->use_full_precision=atoi_64(str)?1:0; return(0); } int f_use_maxtime_display(char *str) { DEBUG(printf("f_use_maxtime_display(\"%s\")\n",str)); GLOBALS->use_maxtime_display=atoi_64(str)?1:0; return(0); } int f_use_nonprop_fonts(char *str) { DEBUG(printf("f_use_nonprop_fonts(\"%s\")\n",str)); GLOBALS->use_nonprop_fonts=atoi_64(str)?1:0; return(0); } int f_use_pango_fonts(char *str) { DEBUG(printf("f_use_pango_fonts(\"%s\")\n",str)); GLOBALS->use_pango_fonts=atoi_64(str)?1:0; return(0); } int f_use_roundcaps(char *str) { DEBUG(printf("f_use_roundcaps(\"%s\")\n",str)); GLOBALS->use_roundcaps=atoi_64(str)?1:0; return(0); } int f_ruler_origin(char *str) { DEBUG(printf("f_ruler_origin(\"%s\")\n",str)); GLOBALS->ruler_origin=atoi_64(str); return(0); } int f_ruler_step(char *str) { DEBUG(printf("f_ruler_step(\"%s\")\n",str)); GLOBALS->ruler_step=atoi_64(str); return(0); } int f_use_scrollbar_only(char *str) { DEBUG(printf("f_use_scrollbar_only(\"%s\")\n",str)); GLOBALS->use_scrollbar_only=atoi_64(str)?1:0; return(0); } int f_use_scrollwheel_as_y(char *str) { DEBUG(printf("f_use_scrollwheel_as_y(\"%s\")\n",str)); GLOBALS->use_scrollwheel_as_y=atoi_64(str)?1:0; return(0); } int f_use_standard_clicking(char *str) { DEBUG(printf("f_use_standard_clicking(\"%s\")\n",str)); GLOBALS->use_standard_clicking=atoi_64(str)?1:0; return(0); } int f_use_standard_trace_select(char *str) { DEBUG(printf("f_f_use_standard_trace_select(\"%s\")\n",str)); GLOBALS->use_standard_trace_select=atoi_64(str)?1:0; return(0); } int f_use_toolbutton_interface(char *str) { #ifndef WAVE_USE_GTK2 (void)str; #endif DEBUG(printf("f_use_toolbutton_interface(\"%s\")\n",str)); #ifdef WAVE_USE_GTK2 GLOBALS->use_toolbutton_interface=atoi_64(str)?1:0; #endif return(0); } int f_vcd_explicit_zero_subscripts(char *str) { DEBUG(printf("f_vcd_explicit_zero_subscripts(\"%s\")\n",str)); GLOBALS->vcd_explicit_zero_subscripts=atoi_64(str)?0:-1; /* 0==yes, -1==no */ return(0); } int f_vcd_preserve_glitches(char *str) { DEBUG(printf("f_vcd_preserve_glitches(\"%s\")\n",str)); GLOBALS->vcd_preserve_glitches=atoi_64(str)?1:0; return(0); } int f_vcd_preserve_glitches_real(char *str) { DEBUG(printf("f_vcd_preserve_glitches_real(\"%s\")\n",str)); GLOBALS->vcd_preserve_glitches_real=atoi_64(str)?1:0; return(0); } int f_vcd_warning_filesize(char *str) { DEBUG(printf("f_vcd_warning_filesize(\"%s\")\n",str)); GLOBALS->vcd_warning_filesize=atoi_64(str); return(0); } int f_vector_padding(char *str) { DEBUG(printf("f_vector_padding(\"%s\")\n",str)); GLOBALS->vector_padding=atoi_64(str); if(GLOBALS->vector_padding<4) GLOBALS->vector_padding=4; else if(GLOBALS->vector_padding>16) GLOBALS->vector_padding=16; return(0); } int f_vlist_compression(char *str) { DEBUG(printf("f_vlist_compression(\"%s\")\n",str)); GLOBALS->vlist_compression_depth=atoi_64(str); if(GLOBALS->vlist_compression_depth<0) GLOBALS->vlist_compression_depth = -1; if(GLOBALS->vlist_compression_depth>9) GLOBALS->vlist_compression_depth = 9; return(0); } int f_vlist_prepack(char *str) { DEBUG(printf("f_vlist_prepack(\"%s\")\n",str)); GLOBALS->vlist_prepack=atoi_64(str); return(0); } int f_vlist_spill(char *str) { DEBUG(printf("f_vlist_spill(\"%s\")\n",str)); GLOBALS->vlist_spill_to_disk=atoi_64(str); return(0); } int f_wave_scrolling(char *str) { DEBUG(printf("f_wave_scrolling(\"%s\")\n",str)); GLOBALS->wave_scrolling=atoi_64(str)?1:0; return(0); } int f_zoom_base(char *str) { float f; DEBUG(printf("f_zoom_base(\"%s\")\n",str)); sscanf(str,"%f",&f); if(f<1.5) f=1.5; else if(f>10.0) f=10.0; GLOBALS->zoombase=(gdouble)f; return(0); } int f_zoom_center(char *str) { DEBUG(printf("f_zoom_center(\"%s\")\n",str)); GLOBALS->do_zoom_center=atoi_64(str)?1:0; return(0); } int f_zoom_dynamic(char *str) { DEBUG(printf("f_zoom_dynamic(\"%s\")\n",str)); GLOBALS->zoom_dyn=atoi_64(str)?1:0; return(0); } int f_zoom_dynamic_end(char *str) { DEBUG(printf("f_zoom_dynamic_end(\"%s\")\n",str)); GLOBALS->zoom_dyne=atoi_64(str)?1:0; return(0); } int f_zoom_pow10_snap(char *str) { DEBUG(printf("f_zoom_pow10_snap(\"%s\")\n",str)); GLOBALS->zoom_pow10_snap=atoi_64(str)?1:0; return(0); } int f_alt_wheel_mode(char *str) { DEBUG(printf("f_alt_wheel_mode(\"%s\")\n",str)); GLOBALS->alt_wheel_mode=atoi_64(str)?1:0; return(0); } int rc_compare(const void *v1, const void *v2) { return(strcasecmp((char *)v1, ((struct rc_entry *)v2)->name)); } /* make the color functions */ #define color_make(Z) int f_color_##Z (char *str) \ { \ int rgb; \ if((rgb=get_rgb_from_name(str))!=~0) \ { \ GLOBALS->color_##Z=rgb; \ } \ return(0); \ } color_make(back) color_make(baseline) color_make(grid) color_make(grid2) color_make(high) color_make(low) color_make(1) color_make(0) color_make(mark) color_make(mid) color_make(time) color_make(timeb) color_make(trans) color_make(umark) color_make(value) color_make(vbox) color_make(vtrans) color_make(x) color_make(xfill) color_make(u) color_make(ufill) color_make(w) color_make(wfill) color_make(dash) color_make(dashfill) color_make(white) color_make(black) color_make(ltgray) color_make(normal) color_make(mdgray) color_make(dkgray) color_make(dkblue) color_make(brkred) color_make(ltblue) color_make(gmstrd) /* * rc variables...these MUST be in alphabetical order for the bsearch! */ static struct rc_entry rcitems[]= { { "accel", f_accel }, { "alt_hier_delimeter", f_alt_hier_delimeter }, { "alt_wheel_mode", f_alt_wheel_mode }, { "analog_redraw_skip_count", f_analog_redraw_skip_count }, { "append_vcd_hier", f_append_vcd_hier }, { "atomic_vectors", f_atomic_vectors }, { "autocoalesce", f_autocoalesce }, { "autocoalesce_reversal", f_autocoalesce_reversal }, { "autoname_bundles", f_autoname_bundles }, { "color_0", f_color_0 }, { "color_1", f_color_1 }, { "color_back", f_color_back }, { "color_baseline", f_color_baseline }, { "color_black", f_color_black }, { "color_brkred", f_color_brkred }, { "color_dash", f_color_dash }, { "color_dashfill", f_color_dashfill }, { "color_dkblue", f_color_dkblue }, { "color_dkgray", f_color_dkgray }, { "color_gmstrd", f_color_gmstrd }, { "color_grid", f_color_grid }, { "color_grid2", f_color_grid2 }, { "color_high", f_color_high }, { "color_low", f_color_low }, { "color_ltblue", f_color_ltblue }, { "color_ltgray", f_color_ltgray }, { "color_mark", f_color_mark }, { "color_mdgray", f_color_mdgray }, { "color_mid", f_color_mid }, { "color_normal", f_color_normal }, { "color_time", f_color_time }, { "color_timeb", f_color_timeb }, { "color_trans", f_color_trans }, { "color_u", f_color_u }, { "color_ufill", f_color_ufill }, { "color_umark", f_color_umark }, { "color_value", f_color_value }, { "color_vbox", f_color_vbox }, { "color_vtrans", f_color_vtrans }, { "color_w", f_color_w }, { "color_wfill", f_color_wfill }, { "color_white", f_color_white }, { "color_x", f_color_x }, { "color_xfill", f_color_xfill }, { "constant_marker_update", f_constant_marker_update }, { "context_tabposition", f_context_tabposition }, { "convert_to_reals", f_convert_to_reals }, { "cursor_snap", f_cursor_snap }, { "disable_ae2_alias", f_disable_ae2_alias }, { "disable_empty_gui", f_disable_empty_gui }, { "disable_mouseover", f_disable_mouseover }, { "disable_tooltips", f_disable_tooltips }, { "do_initial_zoom_fit", f_do_initial_zoom_fit }, { "dynamic_resizing", f_dynamic_resizing }, { "editor", f_editor }, { "enable_fast_exit", f_enable_fast_exit }, { "enable_ghost_marker", f_enable_ghost_marker }, { "enable_horiz_grid", f_enable_horiz_grid }, { "enable_vcd_autosave", f_enable_vcd_autosave }, { "enable_vert_grid", f_enable_vert_grid }, { "fontname_logfile", f_fontname_logfile }, { "fontname_signals", f_fontname_signals }, { "fontname_waves", f_fontname_waves }, { "force_toolbars", f_force_toolbars }, { "hide_sst", f_hide_sst }, { "hier_delimeter", f_hier_delimeter }, { "hier_grouping", f_hier_grouping }, { "hier_max_level", f_hier_max_level }, { "highlight_wavewindow", f_highlight_wavewindow }, { "hpane_pack", f_hpane_pack }, { "ignore_savefile_pane_pos", f_ignore_savefile_pane_pos }, { "ignore_savefile_pos", f_ignore_savefile_pos }, { "ignore_savefile_size", f_ignore_savefile_size }, { "initial_signal_window_width", f_initial_signal_window_width }, { "initial_window_x", f_initial_window_x }, { "initial_window_xpos", f_initial_window_xpos }, { "initial_window_y", f_initial_window_y }, { "initial_window_ypos", f_initial_window_ypos }, { "keep_xz_colors", f_keep_xz_colors }, { "left_justify_sigs", f_left_justify_sigs }, { "lxt_clock_compress_to_z", f_lxt_clock_compress_to_z }, { "page_divisor", f_page_divisor }, { "ps_maxveclen", f_ps_maxveclen }, { "ruler_origin", f_ruler_origin }, { "ruler_step", f_ruler_step }, { "scale_to_time_dimension", f_scale_to_time_dimension }, { "show_base_symbols", f_show_base_symbols }, { "show_grid", f_show_grid }, { "splash_disable", f_splash_disable }, { "sst_dynamic_filter", f_sst_dynamic_filter }, { "sst_expanded", f_sst_expanded }, { "strace_repeat_count", f_strace_repeat_count }, { "use_big_fonts", f_use_big_fonts }, { "use_frequency_display", f_use_frequency_display }, { "use_full_precision", f_use_full_precision }, { "use_maxtime_display", f_use_maxtime_display }, { "use_nonprop_fonts", f_use_nonprop_fonts }, { "use_pango_fonts", f_use_pango_fonts }, { "use_roundcaps", f_use_roundcaps }, { "use_scrollbar_only", f_use_scrollbar_only }, { "use_scrollwheel_as_y", f_use_scrollwheel_as_y }, { "use_standard_clicking", f_use_standard_clicking }, { "use_standard_trace_select", f_use_standard_trace_select }, { "use_toolbutton_interface", f_use_toolbutton_interface }, { "vcd_explicit_zero_subscripts", f_vcd_explicit_zero_subscripts }, { "vcd_preserve_glitches", f_vcd_preserve_glitches }, { "vcd_preserve_glitches_real", f_vcd_preserve_glitches_real }, { "vcd_warning_filesize", f_vcd_warning_filesize }, { "vector_padding", f_vector_padding }, { "vlist_compression", f_vlist_compression }, { "vlist_prepack", f_vlist_prepack }, { "vlist_spill", f_vlist_spill }, { "wave_scrolling", f_wave_scrolling }, { "zoom_base", f_zoom_base }, { "zoom_center", f_zoom_center }, { "zoom_dynamic", f_zoom_dynamic }, { "zoom_dynamic_end", f_zoom_dynamic_end }, { "zoom_pow10_snap", f_zoom_pow10_snap } }; static void vanilla_rc(void) { f_enable_fast_exit ("on"); f_alt_wheel_mode ("on"); f_splash_disable ("off"); f_zoom_pow10_snap ("on"); f_hier_max_level ("1"); f_cursor_snap ("8"); f_use_frequency_display ("off"); f_use_maxtime_display ("off"); f_use_roundcaps ("on"); f_use_nonprop_fonts ("on"); f_use_pango_fonts ("on"); f_constant_marker_update("on"); f_show_base_symbols ("off"); f_color_back ("000000"); /* black */ f_color_baseline ("ffffff"); /* white */ f_color_grid ("202070"); /* dark dark blue */ f_color_grid2 ("6a5acd"); /* slate blue */ f_color_high ("79f6f2"); /* light light blue */ f_color_low ("5dbebb"); /* light blue */ f_color_1 ("00ff00"); /* green */ f_color_0 ("008000"); /* dark green */ f_color_trans ("00c000"); /* medium green */ f_color_mid ("c0c000"); /* mustard */ f_color_value ("ffffff"); /* white */ f_color_vbox ("00ff00"); /* green */ f_color_vtrans ("00c000"); /* medium green */ f_color_x ("ff0000"); /* red */ f_color_xfill ("400000"); /* dark maroon */ f_color_u ("cc0000"); /* brick */ f_color_ufill ("200000"); /* dark maroon */ f_color_w ("79f6f2"); /* light light blue */ f_color_wfill ("3f817f"); /* dark blue-green */ f_color_dash ("edf508"); /* yellow */ f_color_dashfill ("7d8104"); /* green mustard */ f_color_umark ("ff8080"); /* pink */ f_color_mark ("ffff80"); /* light yellow */ f_color_time ("ffffff"); /* white */ f_color_timeb ("000000"); /* black */ f_color_white ("ffffff"); /* white */ f_color_black ("000000"); /* black */ f_color_ltgray ("f5f5f5"); f_color_normal ("e6e6e6"); f_color_mdgray ("cccccc"); f_color_dkgray ("aaaaaa"); f_color_dkblue ("4464ac"); f_color_brkred ("cc0000"); /* brick */ f_color_ltblue ("5dbebb"); /* light blue */ f_color_gmstrd ("7d8104"); /* green mustard */ } void read_rc_file(char *override_rc) { FILE *handle; int i; int num_rcitems = sizeof(rcitems)/sizeof(struct rc_entry); for(i=0;i<(num_rcitems-1);i++) { if(strcmp(rcitems[i].name, rcitems[i+1].name) > 0) { fprintf(stderr, "rcitems misordering: '%s' vs '%s'\n", rcitems[i].name, rcitems[i+1].name); exit(255); } } /* move defaults first and only go whitescreen if instructed to do so */ if(GLOBALS->possibly_use_rc_defaults) vanilla_rc(); if((override_rc)&&((handle=fopen(override_rc,"rb")))) { /* good, we have a handle */ wave_gconf_client_set_string("/current/rcfile", override_rc); } else #if !defined __MINGW32__ && !defined _MSC_VER if(!(handle=fopen(rcname,"rb"))) { char *home; char *rcpath; home=getpwuid(geteuid())->pw_dir; rcpath=(char *)alloca(strlen(home)+1+strlen(rcname)+1); strcpy(rcpath,home); strcat(rcpath,"/"); strcat(rcpath,rcname); if(!(handle=fopen(rcpath,"rb"))) { #ifdef MAC_INTEGRATION const gchar *bundle_id = gtkosx_application_get_bundle_id(); if(bundle_id) { const gchar *rpath = gtkosx_application_get_resource_path(); const char *suf = "/gtkwaverc"; rcpath = NULL; if(rpath) { rcpath = (char *)alloca(strlen(rpath) + strlen(suf) + 1); strcpy(rcpath, rpath); strcat(rcpath, suf); } if(!rcpath || !(handle=fopen(rcpath,"rb"))) { wave_gconf_client_set_string("/current/rcfile", ""); errno=0; return; /* no .rc file */ } else { wave_gconf_client_set_string("/current/rcfile", rcpath); } } else #endif { wave_gconf_client_set_string("/current/rcfile", ""); errno=0; return; /* no .rc file */ } } else { wave_gconf_client_set_string("/current/rcfile", rcpath); } } #else if(!(handle=fopen(rcname,"rb"))) /* no concept of ~ in win32 */ { /* Try to find rcname in USERPROFILE */ char *home; char *rcpath; home=getenv("USERPROFILE"); if (home != NULL) { /* printf("USERPROFILE = %s\n", home); */ rcpath=(char *)alloca(strlen(home)+1+strlen(rcname)+1); strcpy(rcpath,home); strcat(rcpath,"\\"); strcat(rcpath,rcname); /* printf("rcpath = %s\n", rcpath); */ } if ((home == NULL) || (!(handle=fopen(rcpath,"rb")))) { /* printf("No rc file\n"); */ wave_gconf_client_set_string("/current/rcfile", ""); errno=0; if(GLOBALS->possibly_use_rc_defaults) vanilla_rc(); return; /* no .rc file */ } wave_gconf_client_set_string("/current/rcfile", rcpath); } #endif GLOBALS->rc_line_no=0; while(!feof(handle)) { char *str; GLOBALS->rc_line_no++; if((str=fgetmalloc(handle))) { int len; len=strlen(str); if(len) { for(i=0;i=i;j--) { if((str[j]==' ')||(str[j]=='\t')) /* nuke trailing spaces */ { str[j]=0; continue; } else { break; } } r->func(str+i); /* call resolution function */ } break; } break; /* added so multiple word values work properly*/ } } break; } } free_2(str); } } fclose(handle); errno=0; return; } gtkwave-3.3.66/src/menu.h0000664000076400007640000003375712374745343014536 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2014. * * 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. */ #include "globals.h" /* example-start menu menufactory.h */ #ifndef __MENUFACTORY_H__ #define __MENUFACTORY_H__ #include #include #ifndef _MSC_VER #include #endif #include #include "currenttime.h" #include "fgetdynamic.h" #include "strace.h" #include "debug.h" #include "symbol.h" #include "main.h" void do_popup_menu (GtkWidget *my_widget, GdkEventButton *event); void do_sst_popup_menu (GtkWidget *my_widget, GdkEventButton *event); void get_main_menu (GtkWidget *, GtkWidget **menubar); void menu_set_sensitive(void); int file_quit_cmd_callback (GtkWidget *widget, gpointer data); int set_wave_menu_accelerator(char *str); int execute_script(char *name, int dealloc_name); struct stringchain_t { struct stringchain_t *next; char *name; }; #ifdef MAC_INTEGRATION #define WAVE_USE_MLIST_T #endif #ifdef WAVE_USE_MLIST_T typedef void (*gtkwave_mlist_callback) (); struct gtkwave_mlist_t { gchar *path; gchar *accelerator; gtkwave_mlist_callback callback; guint callback_action; /* possible values: * "" -> create a simple item * "" -> create a toggle item * "" -> create a separator */ gchar *item_type; /* Extra data for some item types: * ImageItem -> pointer to inlined pixbuf stream * StockItem -> name of stock item */ gconstpointer extra_data; }; typedef struct gtkwave_mlist_t gtkwave_mlist_t; GtkWidget *alt_menu_top(GtkWidget *window); GtkWidget *alt_menu(gtkwave_mlist_t *mi, int nmenu_items, GtkWidget **wlist, GtkAccelGroup *accel, gboolean is_menubar); #else #define gtkwave_mlist_t GtkItemFactoryEntry #endif enum WV_MenuItems { WV_MENU_FONV, WV_MENU_FONVT, WV_MENU_FRW, WV_MENU_WRVCD, WV_MENU_WRLXT, WV_MENU_WRTIM, WV_MENU_WCLOSE, WV_MENU_SEP2VCD, WV_MENU_FPTF, #if GTK_CHECK_VERSION(2,14,0) WV_MENU_SGRAB, #endif WV_MENU_SEP1, WV_MENU_FRSF, WV_MENU_FWSF, WV_MENU_FWSFAS, WV_MENU_SEP2, WV_MENU_FRLF, WV_MENU_SEP2LF, #if !defined _MSC_VER WV_MENU_FRSTMF, WV_MENU_SEP2STMF, #endif #if defined(HAVE_LIBTCL) WV_MENU_TCLSCR, WV_MENU_TCLSEP, #endif WV_MENU_FQY, WV_MENU_ESTMH, WV_MENU_ETH, WV_MENU_SEP3, WV_MENU_EIB, WV_MENU_EIC, WV_MENU_EIA, WV_MENU_EC, WV_MENU_ECY, WV_MENU_EP, WV_MENU_SEP3A, WV_MENU_EAHT, WV_MENU_ERHA, WV_MENU_SEP4, WV_MENU_EE, WV_MENU_ECD, WV_MENU_ECU, WV_MENU_SEP5, WV_MENU_EDFH, WV_MENU_EDFD, WV_MENU_EDFSD, WV_MENU_EDFB, WV_MENU_EDFO, WV_MENU_EDFA, WV_MENU_EDRL, WV_MENU_EDR2BON, WV_MENU_EDR2BOFF, WV_MENU_EDFRJON, WV_MENU_EDFRJOFF, WV_MENU_EDFION, WV_MENU_EDFIOFF, WV_MENU_EDFRON, WV_MENU_EDFROFF, WV_MENU_XLF_0, WV_MENU_XLF_1, WV_MENU_XLP_0, WV_MENU_XLP_1, WV_MENU_TTXLP_0, WV_MENU_TTXLP_1, WV_MENU_EDFAOFF, WV_MENU_EDFASTEP, WV_MENU_EDFAINTERPOL, WV_MENU_EDFAINTERPOL2, WV_MENU_EDFARSD, WV_MENU_EDFARAD, WV_MENU_RFILL0, WV_MENU_RFILL1, WV_MENU_RFILLOFF, WV_MENU_B2G, WV_MENU_G2B, WV_MENU_GBNONE, WV_MENU_POPON, WV_MENU_POPOFF, WV_MENU_CLRFMT0, WV_MENU_CLRFMT1, WV_MENU_CLRFMT2, WV_MENU_CLRFMT3, WV_MENU_CLRFMT4, WV_MENU_CLRFMT5, WV_MENU_CLRFMT6, WV_MENU_CLRFMT7, WV_MENU_CLRFMTC, WV_MENU_SEP5A, WV_MENU_KEEPXZ, WV_MENU_ESCAH, WV_MENU_ESCFH, WV_MENU_SEP6, WV_MENU_WARP, WV_MENU_UNWARP, WV_MENU_UNWARPA, WV_MENU_SEP7A, WV_MENU_EEX, WV_MENU_ESH, WV_MENU_SEP6A, /* WV_MENU_EXA, */ /* WV_MENU_CPA, */ WV_MENU_TG, WV_MENU_AG, WV_MENU_SEP6A1, WV_MENU_EHR, WV_MENU_EUHR, WV_MENU_EHA, WV_MENU_EUHA, WV_MENU_SEP6B, WV_MENU_ALPHA, WV_MENU_ALPHA2, WV_MENU_LEX, WV_MENU_RVS, WV_MENU_SPS, #ifdef WAVE_USE_GTK2 WV_MENU_SPS2, #endif WV_MENU_SEP7B, WV_MENU_SSR, WV_MENU_SSH, WV_MENU_SST, WV_MENU_SEP7, #if !defined __MINGW32__ && !defined _MSC_VER WV_MENU_OPENHS, WV_MENU_OPENIHS, #endif WV_MENU_OPENH, WV_MENU_SEP7D, WV_MENU_ACOL, WV_MENU_ACOLR, WV_MENU_ABON, WV_MENU_HTGP, WV_MENU_SEP7C, WV_MENU_STRSE, WV_MENU_TMTT, WV_MENU_TZZA, WV_MENU_TZZB, WV_MENU_TZZI, WV_MENU_TZZO, WV_MENU_TZZBFL, WV_MENU_TZZBF, WV_MENU_TZZTS, WV_MENU_TZZTE, WV_MENU_TZUZ, WV_MENU_TFFS, WV_MENU_TFFR, WV_MENU_TFFL, WV_MENU_TDDR, WV_MENU_TDDL, WV_MENU_TSSR, WV_MENU_TSSL, WV_MENU_TPPR, WV_MENU_TPPL, WV_MENU_MSCMD, WV_MENU_MDNM, WV_MENU_MCNM, WV_MENU_MCANM, WV_MENU_MCAB, WV_MENU_MDPM, WV_MENU_SEP8, WV_MENU_SLE, WV_MENU_SRE, WV_MENU_SEP8B, WV_MENU_HSWM, WV_MENU_MWSON, WV_MENU_MLKLT, WV_MENU_MLKRT, WV_MENU_MLKOFF, WV_MENU_VSG, WV_MENU_SEP9, WV_MENU_SHW, WV_MENU_SEP9B, WV_MENU_VSMO, WV_MENU_SEP9A, WV_MENU_VSBS, WV_MENU_SEP10, WV_MENU_ESTS, WV_MENU_SEP10A, WV_MENU_VDR, WV_MENU_SEP11, WV_MENU_VCZ, WV_MENU_SEP12, WV_MENU_VTDF, WV_MENU_VTMM, WV_MENU_SEP13, WV_MENU_VCMU, WV_MENU_SEP14, WV_MENU_VDRV, WV_MENU_SEP15, WV_MENU_VLJS, WV_MENU_VRJS, WV_MENU_SEP16, WV_MENU_VZPS, WV_MENU_VZDYN, WV_MENU_VZDYNE, WV_MENU_VFTP, WV_MENU_SEP17, WV_MENU_RULER, WV_MENU_RMRKS, WV_MENU_SEP17A, WV_MENU_USECOLOR, WV_MENU_USEBW, WV_MENU_SEP18, WV_MENU_LXTCC2Z, WV_MENU_SEP19, WV_MENU_TDSCALEX, WV_MENU_TDSCALES, WV_MENU_TDSCALEM, WV_MENU_TDSCALEU, WV_MENU_TDSCALEN, WV_MENU_TDSCALEP, WV_MENU_TDSCALEF, WV_MENU_HWH, #ifdef MAC_INTEGRATION WV_MENU_HWM, #endif WV_MENU_HWV, WV_MENU_NUMITEMS }; void menu_new_viewer(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_write_vcd_file(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_write_lxt_file(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_print(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_read_save_file(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_write_save_file(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_write_save_file_as(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_read_log_file(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_read_stems_file(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_quit(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_set_max_hier(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_insert_blank_traces(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_insert_comment_traces(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_insert_analog_height_extension(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_alias(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_remove_aliases(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_cut_traces(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_copy_traces(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_paste_traces(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_combine_down(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_combine_up(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_dataformat_hex(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_dataformat_dec(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_dataformat_signed(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_dataformat_bin(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_dataformat_oct(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_dataformat_ascii(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_dataformat_real(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_dataformat_rjustify_on(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_dataformat_rjustify_off(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_dataformat_invert_on(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_dataformat_invert_off(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_dataformat_reverse_on(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_dataformat_reverse_off(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_dataformat_xlate_file_0(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_dataformat_xlate_file_1(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_dataformat_xlate_proc_0(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_dataformat_xlate_proc_1(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_dataformat_analog_off(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_dataformat_analog_step(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_dataformat_analog_interpol(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_showchangeall(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_showchange(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_warp_traces(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_unwarp_traces(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_unwarp_traces_all(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_dataformat_exclude_on(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_dataformat_exclude_off(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_regexp_highlight(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_regexp_unhighlight(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_dataformat_highlight_all(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_dataformat_unhighlight_all(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_alphabetize(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_alphabetize2(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_lexize(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_reverse(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_tracesearchbox(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_signalsearch(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_hiersearch(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_treesearch(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_autocoalesce(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_autocoalesce_reversal(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_autoname_bundles_on(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_hgrouping(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_movetotime(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_zoomsize(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_zoombase(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_fetchsize(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_markerbox(gpointer null_data, guint callback_action, GtkWidget *widget); void drop_named_marker(gpointer null_data, guint callback_action, GtkWidget *widget); void collect_named_marker(gpointer null_data, guint callback_action, GtkWidget *widget); void collect_all_named_markers(gpointer null_data, guint callback_action, GtkWidget *widget); void delete_unnamed_marker(gpointer null_data, guint callback_action, GtkWidget *widget); void wave_scrolling_on(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_show_grid(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_show_mouseover(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_show_base(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_enable_dynamic_resize(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_center_zooms(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_toggle_delta_or_frequency(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_toggle_max_or_marker(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_enable_constant_marker_update(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_use_roundcaps(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_left_justify(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_right_justify(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_zoom10_snap(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_use_full_precision(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_remove_marked(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_lxt_clk_compress(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_help(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_version(gpointer null_data, guint callback_action, GtkWidget *widget); void menu_toggle_group(gpointer null_data, guint callback_action, GtkWidget *widget); gtkwave_mlist_t *retrieve_menu_items_array(int *num_items); void menu_read_stems_cleanup(GtkWidget *widget, gpointer data); void menu_new_viewer_tab_cleanup(GtkWidget *widget, gpointer data); int menu_new_viewer_tab_cleanup_2(char *fname, int optimize_vcd); void movetotime_cleanup(GtkWidget *widget, gpointer data); void zoomsize_cleanup(GtkWidget *widget, gpointer data); void set_scale_to_time_dimension_toggles(void); void SetTraceScrollbarRowValue(int row, unsigned center); bvptr combine_traces(int direction, Trptr single_trace_only); /* currently only for OSX to disable OSX menus when grabbed */ void wave_gtk_grab_add(GtkWidget *w); void wave_gtk_grab_remove(GtkWidget *w); #ifdef MAC_INTEGRATION void osx_menu_sensitivity(gboolean tr); #endif #endif gtkwave-3.3.66/src/vzt.h0000664000076400007640000000116212341266475014374 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2003-2004. * * 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. */ #include "globals.h" #ifndef WAVE_VZTRDR_H #define WAVE_VZTRDR_H #ifdef HAVE_INTTYPES_H #include #endif #include "vcd.h" TimeType vzt_main(char *fname, char *skip_start, char *skip_end); void import_vzt_trace(nptr np); void vzt_set_fac_process_mask(nptr np); void vzt_import_masked(void); #endif gtkwave-3.3.66/src/treesearch_gtk1.c0000664000076400007640000006512512372010236016612 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2011. * * 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. */ #include #include #include "gtk12compat.h" #include "analyzer.h" #include "tree.h" #include "symbol.h" #include "vcd.h" #include "lx2.h" #include "debug.h" void dnd_setup(GtkWidget *src, GtkWidget *w, int enable_receive) { (void)enable_receive; GtkTargetEntry target_entry[3]; /* Realize the clist widget and make sure it has a window, * this will be for DND setup. */ if(!GTK_WIDGET_NO_WINDOW(w)) { /* DND: Set up the clist as a potential DND destination. * First we set up target_entry which is a sequence of of * structure which specify the kinds (which we define) of * drops accepted on this widget. */ /* Set up the list of data format types that our DND * callbacks will accept. */ target_entry[0].target = WAVE_DRAG_TAR_NAME_0; target_entry[0].flags = 0; target_entry[0].info = WAVE_DRAG_TAR_INFO_0; target_entry[1].target = WAVE_DRAG_TAR_NAME_1; target_entry[1].flags = 0; target_entry[1].info = WAVE_DRAG_TAR_INFO_1; target_entry[2].target = WAVE_DRAG_TAR_NAME_2; target_entry[2].flags = 0; target_entry[2].info = WAVE_DRAG_TAR_INFO_2; /* Set the drag destination for this widget, using the * above target entry types, accept move's and coppies'. */ /* required gtk1 hack */ gtk_object_set_data(GTK_OBJECT(w), "gtk-drag-dest", NULL); gtk_drag_dest_set( w, GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP, target_entry, sizeof(target_entry) / sizeof(GtkTargetEntry), GDK_ACTION_MOVE | GDK_ACTION_COPY ); /* Set the drag source for this widget, allowing the user * to drag items off of this clist. */ if(src) gtk_drag_source_set( src, GDK_BUTTON1_MASK | GDK_BUTTON2_MASK, target_entry, sizeof(target_entry) / sizeof(GtkTargetEntry), GDK_ACTION_MOVE | GDK_ACTION_COPY ); } } void treeview_select_all_callback(void) { /* nothing, no treeview for gtk1 implemented yet */ } void treeview_unselect_all_callback(void) { /* nothing, no treeview for gtk1 implemented yet */ } static void select_row_callback(GtkWidget *widget, gint row, gint column, GdkEventButton *event, gpointer data) { (void)widget; (void)column; (void)event; (void)data; struct tree *t; t=(struct tree *)gtk_clist_get_row_data(GTK_CLIST(GLOBALS->ctree_main), row); DEBUG(printf("TS: %08x %s\n",t,t->name)); GLOBALS->selectedtree_treesearch_gtk1_c=t; } static void unselect_row_callback(GtkWidget *widget, gint row, gint column, GdkEventButton *event, gpointer data) { (void)widget; (void)column; (void)event; (void)data; struct tree *t; t=(struct tree *)gtk_clist_get_row_data(GTK_CLIST(GLOBALS->ctree_main), row); DEBUG(printf("TU: %08x %s\n",t,t->name)); GLOBALS->selectedtree_treesearch_gtk1_c=NULL; } int treebox_is_active(void) { return(GLOBALS->is_active_treesearch_gtk1_c); } static void enter_callback_e(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; G_CONST_RETURN gchar *entry_text; int len; entry_text = gtk_entry_get_text(GTK_ENTRY(GLOBALS->entry_a_treesearch_gtk1_c)); entry_text = entry_text ? entry_text : ""; DEBUG(printf("Entry contents: %s\n", entry_text)); if(!(len=strlen(entry_text))) GLOBALS->entrybox_text_local_treesearch_gtk1_c=NULL; else strcpy((GLOBALS->entrybox_text_local_treesearch_gtk1_c=(char *)malloc_2(len+1)),entry_text); wave_gtk_grab_remove(GLOBALS->window1_treesearch_gtk1_c); gtk_widget_destroy(GLOBALS->window1_treesearch_gtk1_c); GLOBALS->window1_treesearch_gtk1_c = NULL; GLOBALS->cleanup_e_treesearch_gtk1_c(); } static void destroy_callback_e(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; DEBUG(printf("Entry Cancel\n")); GLOBALS->entrybox_text_local_treesearch_gtk1_c=NULL; wave_gtk_grab_remove(GLOBALS->window1_treesearch_gtk1_c); gtk_widget_destroy(GLOBALS->window1_treesearch_gtk1_c); GLOBALS->window1_treesearch_gtk1_c = NULL; } static void entrybox_local(char *title, int width, char *default_text, int maxch, GtkSignalFunc func) { GtkWidget *vbox, *hbox; GtkWidget *button1, *button2; GLOBALS->cleanup_e_treesearch_gtk1_c=func; /* fix problem where ungrab doesn't occur if button pressed + simultaneous accelerator key occurs */ if(GLOBALS->in_button_press_wavewindow_c_1) { gdk_pointer_ungrab(GDK_CURRENT_TIME); } /* create a new modal window */ GLOBALS->window1_treesearch_gtk1_c = gtk_window_new(GLOBALS->disable_window_manager ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL); install_focus_cb(GLOBALS->window1_treesearch_gtk1_c, ((char *)&GLOBALS->window1_treesearch_gtk1_c) - ((char *)GLOBALS)); gtk_widget_set_usize( GTK_WIDGET (GLOBALS->window1_treesearch_gtk1_c), width, 60); gtk_window_set_title(GTK_WINDOW (GLOBALS->window1_treesearch_gtk1_c), title); gtkwave_signal_connect(GTK_OBJECT (GLOBALS->window1_treesearch_gtk1_c), "delete_event", (GtkSignalFunc) destroy_callback_e, NULL); vbox = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (GLOBALS->window1_treesearch_gtk1_c), vbox); gtk_widget_show (vbox); GLOBALS->entry_a_treesearch_gtk1_c = gtk_entry_new_with_max_length (maxch); gtkwave_signal_connect(GTK_OBJECT(GLOBALS->entry_a_treesearch_gtk1_c), "activate", GTK_SIGNAL_FUNC(enter_callback_e), GLOBALS->entry_a_treesearch_gtk1_c); gtk_entry_set_text (GTK_ENTRY (GLOBALS->entry_a_treesearch_gtk1_c), default_text); gtk_entry_select_region (GTK_ENTRY (GLOBALS->entry_a_treesearch_gtk1_c), 0, GTK_ENTRY(GLOBALS->entry_a_treesearch_gtk1_c)->text_length); gtk_box_pack_start (GTK_BOX (vbox), GLOBALS->entry_a_treesearch_gtk1_c, TRUE, TRUE, 0); gtk_widget_show (GLOBALS->entry_a_treesearch_gtk1_c); hbox = gtk_hbox_new (FALSE, 1); gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0); gtk_widget_show (hbox); button1 = gtk_button_new_with_label ("OK"); gtk_widget_set_usize(button1, 100, -1); gtkwave_signal_connect(GTK_OBJECT (button1), "clicked", GTK_SIGNAL_FUNC(enter_callback_e), NULL); gtk_widget_show (button1); gtk_container_add (GTK_CONTAINER (hbox), button1); GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT); gtkwave_signal_connect_object (GTK_OBJECT (button1), "realize", (GtkSignalFunc) gtk_widget_grab_default, GTK_OBJECT (button1)); button2 = gtk_button_new_with_label ("Cancel"); gtk_widget_set_usize(button2, 100, -1); gtkwave_signal_connect(GTK_OBJECT (button2), "clicked", GTK_SIGNAL_FUNC(destroy_callback_e), NULL); GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT); gtk_widget_show (button2); gtk_container_add (GTK_CONTAINER (hbox), button2); gtk_widget_show(GLOBALS->window1_treesearch_gtk1_c); wave_gtk_grab_add(GLOBALS->window1_treesearch_gtk1_c); } /***************************************************************************/ struct tree *fetchhigh(struct tree *t) { while(t->child) t=t->child; return(t); } struct tree *fetchlow(struct tree *t) { if(t->child) { t=t->child; for(;;) { while(t->next) t=t->next; if(t->child) t=t->child; else break; } } return(t); } static void fetchvex2(struct tree *t, char direction, char level) { while(t) { if(t->child) { if(t->child->child) { fetchvex2(t->child, direction, 1); } else { add_vector_range(NULL, fetchlow(t)->t_which, fetchhigh(t)->t_which, direction); } } if(level) { t=t->next; } else { break; } } } void fetchvex(struct tree *t, char direction) { if(t) { if(t->child) { fetchvex2(t, direction, 0); } else { add_vector_range(NULL, fetchlow(t)->t_which, fetchhigh(t)->t_which, direction); } } } /* call cleanup() on ok/insert functions */ static void bundle_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; if(GLOBALS->entrybox_text_local_treesearch_gtk1_c) { char *efix; if(!strlen(GLOBALS->entrybox_text_local_treesearch_gtk1_c)) { DEBUG(printf("Bundle name is not specified--recursing into hierarchy.\n")); fetchvex(GLOBALS->selectedtree_treesearch_gtk1_c, GLOBALS->bundle_direction_treesearch_gtk1_c); } else { efix=GLOBALS->entrybox_text_local_treesearch_gtk1_c; while(*efix) { if(*efix==' ') { *efix='_'; } efix++; } DEBUG(printf("Bundle name is: %s\n",GLOBALS->entrybox_text_local_treesearch_gtk1_c)); add_vector_range(GLOBALS->entrybox_text_local_treesearch_gtk1_c, fetchlow(GLOBALS->selectedtree_treesearch_gtk1_c)->t_which, fetchhigh(GLOBALS->selectedtree_treesearch_gtk1_c)->t_which, GLOBALS->bundle_direction_treesearch_gtk1_c); } free_2(GLOBALS->entrybox_text_local_treesearch_gtk1_c); } else { DEBUG(printf("Bundle name is not specified--recursing into hierarchy.\n")); fetchvex(GLOBALS->selectedtree_treesearch_gtk1_c, GLOBALS->bundle_direction_treesearch_gtk1_c); } MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } static void bundle_callback_generic(void) { if(GLOBALS->selectedtree_treesearch_gtk1_c) { if(!GLOBALS->autoname_bundles) { entrybox_local("Enter Bundle Name",300,"",128,GTK_SIGNAL_FUNC(bundle_cleanup)); } else { GLOBALS->entrybox_text_local_treesearch_gtk1_c=NULL; bundle_cleanup(NULL, NULL); } } } static void bundle_callback_up(GtkWidget *widget, gpointer data) { (void)widget; (void)data; GLOBALS->bundle_direction_treesearch_gtk1_c=0; bundle_callback_generic(); } static void bundle_callback_down(GtkWidget *widget, gpointer data) { (void)widget; (void)data; GLOBALS->bundle_direction_treesearch_gtk1_c=1; bundle_callback_generic(); } static void insert_callback(GtkWidget *widget, GtkWidget *nothing) { (void)nothing; Traces tcache; int i; if(!GLOBALS->selectedtree_treesearch_gtk1_c) return; memcpy(&tcache,&GLOBALS->traces,sizeof(Traces)); GLOBALS->traces.total=0; GLOBALS->traces.first=GLOBALS->traces.last=NULL; set_window_busy(widget); for(i=fetchlow(GLOBALS->selectedtree_treesearch_gtk1_c)->t_which;i<=fetchhigh(GLOBALS->selectedtree_treesearch_gtk1_c)->t_which;i++) { struct symbol *s; s=GLOBALS->facs[i]; if(s->vec_root) { set_s_selected(s->vec_root, GLOBALS->autocoalesce); } } /* LX2 */ if(GLOBALS->is_lx2) { int pre_import = 0; for(i=fetchlow(GLOBALS->selectedtree_treesearch_gtk1_c)->t_which;i<=fetchhigh(GLOBALS->selectedtree_treesearch_gtk1_c)->t_which;i++) { struct symbol *s, *t; s=GLOBALS->facs[i]; t=s->vec_root; if((t)&&(GLOBALS->autocoalesce)) { if(get_s_selected(t)) { while(t) { if(t->n->mv.mvlfac) { lx2_set_fac_process_mask(t->n); pre_import++; } t=t->vec_chain; } } } else { if(s->n->mv.mvlfac) { lx2_set_fac_process_mask(s->n); pre_import++; } } } if(pre_import) { lx2_import_masked(); } } /* LX2 */ for(i=fetchlow(GLOBALS->selectedtree_treesearch_gtk1_c)->t_which;i<=fetchhigh(GLOBALS->selectedtree_treesearch_gtk1_c)->t_which;i++) { int len; struct symbol *s, *t; s=GLOBALS->facs[i]; t=s->vec_root; if((t)&&(GLOBALS->autocoalesce)) { if(get_s_selected(t)) { set_s_selected(t, 0); len=0; while(t) { len++; t=t->vec_chain; } if(len) add_vector_chain(s->vec_root, len); } } else { AddNodeUnroll(s->n, NULL); } } set_window_idle(widget); GLOBALS->traces.buffercount=GLOBALS->traces.total; GLOBALS->traces.buffer=GLOBALS->traces.first; GLOBALS->traces.bufferlast=GLOBALS->traces.last; GLOBALS->traces.first=tcache.first; GLOBALS->traces.last=tcache.last; GLOBALS->traces.total=tcache.total; PasteBuffer(); GLOBALS->traces.buffercount=tcache.buffercount; GLOBALS->traces.buffer=tcache.buffer; GLOBALS->traces.bufferlast=tcache.bufferlast; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } static void replace_callback(GtkWidget *widget, GtkWidget *nothing) { (void)nothing; Traces tcache; int i; Trptr tfirst=NULL, tlast=NULL; if(!GLOBALS->selectedtree_treesearch_gtk1_c) return; memcpy(&tcache,&GLOBALS->traces,sizeof(Traces)); GLOBALS->traces.total=0; GLOBALS->traces.first=GLOBALS->traces.last=NULL; set_window_busy(widget); for(i=fetchlow(GLOBALS->selectedtree_treesearch_gtk1_c)->t_which;i<=fetchhigh(GLOBALS->selectedtree_treesearch_gtk1_c)->t_which;i++) { struct symbol *s; s=GLOBALS->facs[i]; if(s->vec_root) { set_s_selected(s->vec_root, GLOBALS->autocoalesce); } } /* LX2 */ if(GLOBALS->is_lx2) { int pre_import = 0; for(i=fetchlow(GLOBALS->selectedtree_treesearch_gtk1_c)->t_which;i<=fetchhigh(GLOBALS->selectedtree_treesearch_gtk1_c)->t_which;i++) { struct symbol *s, *t; s=GLOBALS->facs[i]; t=s->vec_root; if((t)&&(GLOBALS->autocoalesce)) { if(get_s_selected(t)) { while(t) { if(t->n->mv.mvlfac) { lx2_set_fac_process_mask(t->n); pre_import++; } t=t->vec_chain; } } } else { if(s->n->mv.mvlfac) { lx2_set_fac_process_mask(s->n); pre_import++; } } } if(pre_import) { lx2_import_masked(); } } /* LX2 */ for(i=fetchlow(GLOBALS->selectedtree_treesearch_gtk1_c)->t_which;i<=fetchhigh(GLOBALS->selectedtree_treesearch_gtk1_c)->t_which;i++) { int len; struct symbol *s, *t; s=GLOBALS->facs[i]; t=s->vec_root; if((t)&&(GLOBALS->autocoalesce)) { if(get_s_selected(t)) { set_s_selected(t, 0); len=0; while(t) { len++; t=t->vec_chain; } if(len) add_vector_chain(s->vec_root, len); } } else { AddNodeUnroll(s->n, NULL); } } set_window_idle(widget); tfirst=GLOBALS->traces.first; tlast=GLOBALS->traces.last; /* cache for highlighting */ GLOBALS->traces.buffercount=GLOBALS->traces.total; GLOBALS->traces.buffer=GLOBALS->traces.first; GLOBALS->traces.bufferlast=GLOBALS->traces.last; GLOBALS->traces.first=tcache.first; GLOBALS->traces.last=tcache.last; GLOBALS->traces.total=tcache.total; { Trptr t = GLOBALS->traces.first; Trptr *tp = NULL; int numhigh = 0; int it; while(t) { if(t->flags & TR_HIGHLIGHT) { numhigh++; } t = t->t_next; } if(numhigh) { tp = calloc_2(numhigh, sizeof(Trptr)); t = GLOBALS->traces.first; it = 0; while(t) { if(t->flags & TR_HIGHLIGHT) { tp[it++] = t; } t = t->t_next; } } PasteBuffer(); GLOBALS->traces.buffercount=tcache.buffercount; GLOBALS->traces.buffer=tcache.buffer; GLOBALS->traces.bufferlast=tcache.bufferlast; for(i=0;iflags |= TR_HIGHLIGHT; } t = tfirst; while(t) { t->flags &= ~TR_HIGHLIGHT; if(t==tlast) break; t=t->t_next; } CutBuffer(); while(tfirst) { tfirst->flags |= TR_HIGHLIGHT; if(tfirst==tlast) break; tfirst=tfirst->t_next; } if(tp) { free_2(tp); } } MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } static void ok_callback(GtkWidget *widget, GtkWidget *nothing) { (void)nothing; int i; if(!GLOBALS->selectedtree_treesearch_gtk1_c) return; set_window_busy(widget); for(i=fetchlow(GLOBALS->selectedtree_treesearch_gtk1_c)->t_which;i<=fetchhigh(GLOBALS->selectedtree_treesearch_gtk1_c)->t_which;i++) { struct symbol *s; s=GLOBALS->facs[i]; if(s->vec_root) { set_s_selected(s->vec_root, GLOBALS->autocoalesce); } } /* LX2 */ if(GLOBALS->is_lx2) { int pre_import = 0; for(i=fetchlow(GLOBALS->selectedtree_treesearch_gtk1_c)->t_which;i<=fetchhigh(GLOBALS->selectedtree_treesearch_gtk1_c)->t_which;i++) { struct symbol *s, *t; s=GLOBALS->facs[i]; t=s->vec_root; if((t)&&(GLOBALS->autocoalesce)) { if(get_s_selected(t)) { while(t) { if(t->n->mv.mvlfac) { lx2_set_fac_process_mask(t->n); pre_import++; } t=t->vec_chain; } } } else { if(s->n->mv.mvlfac) { lx2_set_fac_process_mask(s->n); pre_import++; } } } if(pre_import) { lx2_import_masked(); } } /* LX2 */ for(i=fetchlow(GLOBALS->selectedtree_treesearch_gtk1_c)->t_which;i<=fetchhigh(GLOBALS->selectedtree_treesearch_gtk1_c)->t_which;i++) { int len; struct symbol *s, *t; s=GLOBALS->facs[i]; t=s->vec_root; if((t)&&(GLOBALS->autocoalesce)) { if(get_s_selected(t)) { set_s_selected(t, 0); len=0; while(t) { len++; t=t->vec_chain; } if(len) add_vector_chain(s->vec_root, len); } } else { AddNodeUnroll(s->n, NULL); } } set_window_idle(widget); GLOBALS->traces.scroll_top = GLOBALS->traces.scroll_bottom = GLOBALS->traces.last; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } static void destroy_callback(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; GLOBALS->is_active_treesearch_gtk1_c=0; gtk_widget_destroy(GLOBALS->window_treesearch_gtk1_c); GLOBALS->window_treesearch_gtk1_c = NULL; } /* * mainline.. */ void treebox(char *title, GtkSignalFunc func, GtkWidget *old_window) { (void)old_window; GtkWidget *scrolled_win; GtkWidget *hbox; GtkWidget *button1, *button2, *button3, *button3a, *button4, *button5; GtkWidget *frame2, *frameh; GtkWidget *table; GtkTooltips *tooltips; GtkCList *clist; if(GLOBALS->is_active_treesearch_gtk1_c) { gdk_window_raise(GLOBALS->window_treesearch_gtk1_c->window); return; } GLOBALS->is_active_treesearch_gtk1_c=1; GLOBALS->cleanup_treesearch_gtk1_c=func; /* create a new modal window */ GLOBALS->window_treesearch_gtk1_c = gtk_window_new(GLOBALS->disable_window_manager ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL); install_focus_cb(GLOBALS->window_treesearch_gtk1_c, ((char *)&GLOBALS->window_treesearch_gtk1_c) - ((char *)GLOBALS)); gtk_window_set_title(GTK_WINDOW (GLOBALS->window_treesearch_gtk1_c), title); gtkwave_signal_connect(GTK_OBJECT (GLOBALS->window_treesearch_gtk1_c), "delete_event", (GtkSignalFunc) destroy_callback, NULL); tooltips=gtk_tooltips_new_2(); table = gtk_table_new (256, 1, FALSE); gtk_widget_show (table); frame2 = gtk_frame_new (NULL); gtk_container_border_width (GTK_CONTAINER (frame2), 3); gtk_widget_show(frame2); gtk_table_attach (GTK_TABLE (table), frame2, 0, 1, 0, 255, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); GLOBALS->tree_treesearch_gtk1_c=gtk_ctree_new(1,0); GLOBALS->ctree_main=GTK_CTREE(GLOBALS->tree_treesearch_gtk1_c); gtk_clist_set_column_auto_resize (GTK_CLIST (GLOBALS->tree_treesearch_gtk1_c), 0, TRUE); gtk_widget_show(GLOBALS->tree_treesearch_gtk1_c); clist=GTK_CLIST(GLOBALS->tree_treesearch_gtk1_c); gtkwave_signal_connect_object (GTK_OBJECT (clist), "select_row", GTK_SIGNAL_FUNC(select_row_callback), NULL); gtkwave_signal_connect_object (GTK_OBJECT (clist), "unselect_row", GTK_SIGNAL_FUNC(unselect_row_callback), NULL); gtk_clist_freeze(clist); gtk_clist_clear(clist); maketree(NULL, GLOBALS->treeroot); gtk_clist_thaw(clist); GLOBALS->selectedtree_treesearch_gtk1_c=NULL; scrolled_win = gtk_scrolled_window_new (NULL, NULL); gtk_widget_set_usize( GTK_WIDGET (scrolled_win), -1, 300); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_widget_show(scrolled_win); gtk_container_add (GTK_CONTAINER (scrolled_win), GTK_WIDGET (GLOBALS->tree_treesearch_gtk1_c)); gtk_container_add (GTK_CONTAINER (frame2), scrolled_win); frameh = gtk_frame_new (NULL); gtk_container_border_width (GTK_CONTAINER (frameh), 3); gtk_widget_show(frameh); gtk_table_attach (GTK_TABLE (table), frameh, 0, 1, 255, 256, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); hbox = gtk_hbox_new (FALSE, 1); gtk_widget_show (hbox); button1 = gtk_button_new_with_label ("Append"); gtk_container_border_width (GTK_CONTAINER (button1), 3); gtkwave_signal_connect_object (GTK_OBJECT (button1), "clicked", GTK_SIGNAL_FUNC(ok_callback), GTK_OBJECT (GLOBALS->window_treesearch_gtk1_c)); gtk_widget_show (button1); gtk_tooltips_set_tip_2(tooltips, button1, "Add selected signal hierarchy to end of the display on the main window.",NULL); gtk_box_pack_start (GTK_BOX (hbox), button1, TRUE, FALSE, 0); button2 = gtk_button_new_with_label (" Insert "); gtk_container_border_width (GTK_CONTAINER (button2), 3); gtkwave_signal_connect_object (GTK_OBJECT (button2), "clicked", GTK_SIGNAL_FUNC(insert_callback), GTK_OBJECT (GLOBALS->window_treesearch_gtk1_c)); gtk_widget_show (button2); gtk_tooltips_set_tip_2(tooltips, button2, "Add selected signal hierarchy after last highlighted signal on the main window.",NULL); gtk_box_pack_start (GTK_BOX (hbox), button2, TRUE, FALSE, 0); if(GLOBALS->vcd_explicit_zero_subscripts>=0) { button3 = gtk_button_new_with_label (" Bundle Up "); gtk_container_border_width (GTK_CONTAINER (button3), 3); gtkwave_signal_connect_object (GTK_OBJECT (button3), "clicked", GTK_SIGNAL_FUNC(bundle_callback_up), GTK_OBJECT (GLOBALS->window_treesearch_gtk1_c)); gtk_widget_show (button3); gtk_tooltips_set_tip_2(tooltips, button3, "Bundle selected signal hierarchy into a single bit " "vector with the topmost signal as the LSB and the " "lowest as the MSB. Entering a zero length bundle " "name will reconstruct the individual vectors " "in the hierarchy. Otherwise, all the bits in " "the hierarchy will be coalesced with the supplied " "name into a single vector.",NULL); gtk_box_pack_start (GTK_BOX (hbox), button3, TRUE, FALSE, 0); button3a = gtk_button_new_with_label (" Bundle Down "); gtk_container_border_width (GTK_CONTAINER (button3a), 3); gtkwave_signal_connect_object (GTK_OBJECT (button3a), "clicked", GTK_SIGNAL_FUNC(bundle_callback_down), GTK_OBJECT (GLOBALS->window_treesearch_gtk1_c)); gtk_widget_show (button3a); gtk_tooltips_set_tip_2(tooltips, button3a, "Bundle selected signal hierarchy into a single bit " "vector with the topmost signal as the MSB and the " "lowest as the LSB. Entering a zero length bundle " "name will reconstruct the individual vectors " "in the hierarchy. Otherwise, all the bits in " "the hierarchy will be coalesced with the supplied " "name into a single vector.",NULL); gtk_box_pack_start (GTK_BOX (hbox), button3a, TRUE, FALSE, 0); } button4 = gtk_button_new_with_label (" Replace "); gtk_container_border_width (GTK_CONTAINER (button4), 3); gtkwave_signal_connect_object (GTK_OBJECT (button4), "clicked", GTK_SIGNAL_FUNC(replace_callback), GTK_OBJECT (GLOBALS->window_treesearch_gtk1_c)); gtk_widget_show (button4); gtk_tooltips_set_tip_2(tooltips, button4, "Replace highlighted signals on the main window with signals selected above.",NULL); gtk_box_pack_start (GTK_BOX (hbox), button4, TRUE, FALSE, 0); button5 = gtk_button_new_with_label (" Exit "); gtk_container_border_width (GTK_CONTAINER (button5), 3); gtkwave_signal_connect_object (GTK_OBJECT (button5), "clicked", GTK_SIGNAL_FUNC(destroy_callback), GTK_OBJECT (GLOBALS->window_treesearch_gtk1_c)); gtk_tooltips_set_tip_2(tooltips, button5, "Do nothing and return to the main window.",NULL); gtk_widget_show (button5); gtk_box_pack_start (GTK_BOX (hbox), button5, TRUE, FALSE, 0); gtk_container_add (GTK_CONTAINER (frameh), hbox); gtk_container_add (GTK_CONTAINER (GLOBALS->window_treesearch_gtk1_c), table); gtk_widget_show(GLOBALS->window_treesearch_gtk1_c); } gtkwave-3.3.66/src/main.c0000664000076400007640000025670512542115425014476 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2014. * * 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. */ /* AIX may need this for alloca to work */ #if defined _AIX #pragma alloca #endif #include "globals.h" #include #include #include #include #ifdef __MINGW32__ #include #endif /* #define WAVE_CRASH_ON_GTK_WARNING */ #include "wave_locale.h" #if !defined _MSC_VER && !defined __MINGW32__ #include #include #include #include #include #endif #if !defined _MSC_VER && defined WAVE_USE_GTK2 #define WAVE_USE_XID #else #undef WAVE_USE_XID #endif #ifdef HAVE_GETOPT_LONG #include #else #include "gnu-getopt.h" #ifndef _MSC_VER #include #else #define strcasecmp _stricmp #endif #endif #include "symbol.h" #include "lx2.h" #include "ae2.h" #include "vzt.h" #include "ghw.h" #include "fst.h" #include "main.h" #include "menu.h" #include "vcd.h" #include "lxt.h" #include "lxt2_read.h" #include "vzt_read.h" #include "pixmaps.h" #include "currenttime.h" #include "fgetdynamic.h" #include "rc.h" #include "translate.h" #include "ptranslate.h" #include "ttranslate.h" #include "tcl_helper.h" #if defined(HAVE_LIBTCL) #include #include #endif #ifdef MAC_INTEGRATION #include #endif char *gtkwave_argv0_cached = NULL; static void switch_page(GtkNotebook *notebook, GtkNotebookPage *page, guint page_num, gpointer user_data) { (void)notebook; (void)page; (void)user_data; char timestr[32]; struct Global *g_old = GLOBALS; set_GLOBALS((*GLOBALS->contexts)[page_num]); GLOBALS->lxt_clock_compress_to_z = g_old->lxt_clock_compress_to_z; GLOBALS->autoname_bundles = g_old->autoname_bundles; GLOBALS->autocoalesce_reversal = g_old->autocoalesce_reversal; GLOBALS->autocoalesce = g_old->autocoalesce; GLOBALS->hier_grouping = g_old->hier_grouping; GLOBALS->wave_scrolling = g_old->wave_scrolling; GLOBALS->constant_marker_update = g_old->constant_marker_update; GLOBALS->do_zoom_center = g_old->do_zoom_center; GLOBALS->use_roundcaps = g_old->use_roundcaps; GLOBALS->do_resize_signals = g_old->do_resize_signals; GLOBALS->alt_wheel_mode = g_old->alt_wheel_mode; GLOBALS->initial_signal_window_width = g_old->initial_signal_window_width; GLOBALS->scale_to_time_dimension = g_old->scale_to_time_dimension; GLOBALS->use_full_precision = g_old->use_full_precision; GLOBALS->show_base = g_old->show_base; GLOBALS->display_grid = g_old->display_grid; GLOBALS->highlight_wavewindow = g_old->highlight_wavewindow; GLOBALS->use_standard_trace_select = g_old->use_standard_trace_select; GLOBALS->disable_mouseover = g_old->disable_mouseover; GLOBALS->keep_xz_colors = g_old->keep_xz_colors; GLOBALS->zoom_pow10_snap = g_old->zoom_pow10_snap; GLOBALS->zoom_dyn = g_old->zoom_dyn; GLOBALS->zoom_dyne = g_old->zoom_dyne; reformat_time(timestr, GLOBALS->tims.first + GLOBALS->global_time_offset, GLOBALS->time_dimension); gtk_entry_set_text(GTK_ENTRY(GLOBALS->from_entry),timestr); reformat_time(timestr, GLOBALS->tims.last + GLOBALS->global_time_offset, GLOBALS->time_dimension); gtk_entry_set_text(GTK_ENTRY(GLOBALS->to_entry),timestr); update_maxmarker_labels(); update_basetime(GLOBALS->tims.baseline); GLOBALS->keypress_handler_id = g_old->keypress_handler_id; if(GLOBALS->second_page_created) { wave_gtk_window_set_title(GTK_WINDOW(GLOBALS->mainwindow), GLOBALS->winname, GLOBALS->dumpfile_is_modified ? WAVE_SET_TITLE_MODIFIED: WAVE_SET_TITLE_NONE, 0); MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } void kill_stems_browser_single(void *V) { struct Global *G = (struct Global *)V; #if !defined _MSC_VER if(G && G->anno_ctx) { #ifdef __MINGW32__ if(G->anno_ctx->browser_process) { TerminateProcess(G->anno_ctx->browser_process, 0); CloseHandle(G->anno_ctx->browser_process); G->anno_ctx->browser_process = 0; } #else if(G->anno_ctx->browser_process) { #ifdef __CYGWIN__ G->anno_ctx->cygwin_remote_kill = 1; /* let cygwin child exit() on its own */ #else kill(G->anno_ctx->browser_process, SIGKILL); #endif G->anno_ctx->browser_process = (pid_t)0; } #endif G->anno_ctx = NULL; } #endif } #if !defined _MSC_VER void kill_stems_browser(void) { unsigned int ix; for(ix=0;ixnum_notebook_pages;ix++) { struct Global *G = (*GLOBALS->contexts)[ix]; kill_stems_browser_single(G); } } #endif #ifdef WAVE_USE_XID static int plug_destroy (GtkWidget *widget, gpointer data) { (void)widget; (void)data; exit(0); return(FALSE); } #endif #if defined __MINGW32__ static void close_all_fst_files(void) /* so mingw does delete of reader tempfiles */ { unsigned int i; for(i=0;inum_notebook_pages;i++) { if((*GLOBALS->contexts)[i]->fst_fst_c_1) { fstReaderClose((*GLOBALS->contexts)[i]->fst_fst_c_1); (*GLOBALS->contexts)[i]->fst_fst_c_1 = NULL; } } } #endif static void print_help(char *nam) { #if defined(EXTLOAD_SUFFIX) && defined(EXTCONV_PATH) int slen = strlen(EXTLOAD_SUFFIX); char *ucase_ext = wave_alloca(slen+1); int i; for(i=0;i.\n",nam #if !defined _MSC_VER && !defined __MINGW32__ #if defined(EXTLOAD_SUFFIX) && defined(EXTCONV_PATH) ,ucase_ext #endif #endif ); exit(0); } /* * file selection for -n/--nocli flag */ static void wave_get_filename_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; gtk_main_quit(); /* do nothing but exit gtk loop */ } static char *wave_get_filename(char *dfile) { if(dfile) { int len = strlen(dfile); GLOBALS->ftext_main_main_c_1 = malloc_2(strlen(dfile)+2); strcpy(GLOBALS->ftext_main_main_c_1, dfile); #if !defined _MSC_VER && !defined __MINGW32__ if((len)&&(dfile[len-1]!='/')) { strcpy(GLOBALS->ftext_main_main_c_1 + len, "/"); } #else if((len)&&(dfile[len-1]!='\\')) { strcpy(GLOBALS->ftext_main_main_c_1 + len, "\\"); } #endif } fileselbox_old("GTKWave: Select a dumpfile...",&GLOBALS->ftext_main_main_c_1,GTK_SIGNAL_FUNC(wave_get_filename_cleanup), GTK_SIGNAL_FUNC(wave_get_filename_cleanup), NULL, 0); gtk_main(); return(GLOBALS->ftext_main_main_c_1); } /* * Modify the name of the executable (argv[0]) handed to Tk_MainEx; * The new executable name has _[pid] appended. This gives a unique * (and known) name to the interpreter (for use with send). */ void addPidToExecutableName(int argc, char* argv[], char* argv_mod[]) { char* pos; char* buffer; int i; for(i=0;ilogfiles = calloc(1, sizeof(void *)); /* calloc is deliberate! */ } else { old_g = GLOBALS; set_GLOBALS(initialize_globals()); GLOBALS->second_page_created = old_g->second_page_created = 1; GLOBALS->notebook = old_g->notebook; GLOBALS->num_notebook_pages = old_g->num_notebook_pages; GLOBALS->num_notebook_pages_cumulative = old_g->num_notebook_pages_cumulative; GLOBALS->contexts = old_g->contexts; GLOBALS->mainwindow = old_g->mainwindow; splash_disable_rc_override = 1; /* busy.c */ GLOBALS->busycursor_busy_c_1 = old_g->busycursor_busy_c_1; /* logfiles.c */ GLOBALS->logfiles = old_g->logfiles; /* menu.c */ #if defined(HAVE_LIBTCL) GLOBALS->interp = old_g->interp; #endif #ifndef WAVE_USE_MLIST_T GLOBALS->item_factory_menu_c_1 = old_g->item_factory_menu_c_1; #endif GLOBALS->vcd_jmp_buf = old_g->vcd_jmp_buf; /* currenttime.c */ GLOBALS->max_or_marker_label_currenttime_c_1 = old_g->max_or_marker_label_currenttime_c_1; GLOBALS->maxtext_currenttime_c_1=(char *)malloc_2(40); GLOBALS->maxtimewid_currenttime_c_1 = old_g->maxtimewid_currenttime_c_1; GLOBALS->curtext_currenttime_c_1 = old_g->curtext_currenttime_c_1; GLOBALS->base_or_curtime_label_currenttime_c_1 = old_g->base_or_curtime_label_currenttime_c_1; GLOBALS->curtimewid_currenttime_c_1 = old_g->curtimewid_currenttime_c_1; /* status.c */ GLOBALS->text_status_c_2 = old_g->text_status_c_2; GLOBALS->vscrollbar_status_c_2 = old_g->vscrollbar_status_c_2; #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) GLOBALS->iter_status_c_3 = old_g->iter_status_c_3; GLOBALS->bold_tag_status_c_3 = old_g->bold_tag_status_c_3; #endif /* timeentry.c */ GLOBALS->from_entry = old_g->from_entry; GLOBALS->to_entry = old_g->to_entry; /* rc.c */ GLOBALS->possibly_use_rc_defaults = old_g->possibly_use_rc_defaults; GLOBALS->ignore_savefile_pane_pos = old_g->ignore_savefile_pane_pos; GLOBALS->ignore_savefile_pos = old_g->ignore_savefile_pos; GLOBALS->ignore_savefile_size = old_g->ignore_savefile_size; GLOBALS->color_back = old_g->color_back; GLOBALS->color_baseline = old_g->color_baseline; GLOBALS->color_grid = old_g->color_grid; GLOBALS->color_grid2 = old_g->color_grid2; GLOBALS->color_high = old_g->color_high; GLOBALS->color_low = old_g->color_low; GLOBALS->color_1 = old_g->color_1; GLOBALS->color_0 = old_g->color_0; GLOBALS->color_mark = old_g->color_mark; GLOBALS->color_mid = old_g->color_mid; GLOBALS->color_time = old_g->color_time; GLOBALS->color_timeb = old_g->color_timeb; GLOBALS->color_trans = old_g->color_trans; GLOBALS->color_umark = old_g->color_umark; GLOBALS->color_value = old_g->color_value; GLOBALS->color_vbox = old_g->color_vbox; GLOBALS->color_vtrans = old_g->color_vtrans; GLOBALS->color_x = old_g->color_x; GLOBALS->color_xfill = old_g->color_xfill; GLOBALS->color_u = old_g->color_u; GLOBALS->color_ufill = old_g->color_ufill; GLOBALS->color_w = old_g->color_w; GLOBALS->color_wfill = old_g->color_wfill; GLOBALS->color_dash = old_g->color_dash; GLOBALS->color_dashfill = old_g->color_dashfill; GLOBALS->color_white = old_g->color_white; GLOBALS->color_black = old_g->color_black; GLOBALS->color_ltgray = old_g->color_ltgray; GLOBALS->color_normal = old_g->color_normal; GLOBALS->color_mdgray = old_g->color_mdgray; GLOBALS->color_dkgray = old_g->color_dkgray; GLOBALS->color_dkblue = old_g->color_dkblue; GLOBALS->color_brkred = old_g->color_brkred; GLOBALS->color_ltblue = old_g->color_ltblue; GLOBALS->color_gmstrd = old_g->color_gmstrd; GLOBALS->atomic_vectors = old_g->atomic_vectors; GLOBALS->autoname_bundles = old_g->autoname_bundles; GLOBALS->autocoalesce = old_g->autocoalesce; GLOBALS->autocoalesce_reversal = old_g->autocoalesce_reversal; GLOBALS->constant_marker_update = old_g->constant_marker_update; GLOBALS->convert_to_reals = old_g->convert_to_reals; GLOBALS->disable_mouseover = old_g->disable_mouseover; GLOBALS->keep_xz_colors = old_g->keep_xz_colors; GLOBALS->disable_tooltips = old_g->disable_tooltips; GLOBALS->do_initial_zoom_fit = old_g->do_initial_zoom_fit; GLOBALS->do_resize_signals = old_g->do_resize_signals; GLOBALS->alt_wheel_mode = old_g->alt_wheel_mode; GLOBALS->initial_signal_window_width = old_g->initial_signal_window_width; GLOBALS->scale_to_time_dimension = old_g->scale_to_time_dimension; GLOBALS->enable_fast_exit = old_g->enable_fast_exit; GLOBALS->enable_ghost_marker = old_g->enable_ghost_marker; GLOBALS->enable_horiz_grid = old_g->enable_horiz_grid; GLOBALS->make_vcd_save_file = old_g->make_vcd_save_file; GLOBALS->enable_vert_grid = old_g->enable_vert_grid; GLOBALS->force_toolbars = old_g->force_toolbars; GLOBALS->hide_sst = old_g->hide_sst; GLOBALS->sst_expanded = old_g->sst_expanded; GLOBALS->hier_grouping = old_g->hier_grouping; GLOBALS->hier_max_level = old_g->hier_max_level; GLOBALS->hier_max_level_shadow = old_g->hier_max_level_shadow; GLOBALS->paned_pack_semantics = old_g->paned_pack_semantics; GLOBALS->left_justify_sigs = old_g->left_justify_sigs; GLOBALS->lxt_clock_compress_to_z = old_g->lxt_clock_compress_to_z; GLOBALS->ps_maxveclen = old_g->ps_maxveclen; GLOBALS->show_base = old_g->show_base; GLOBALS->display_grid = old_g->display_grid; GLOBALS->highlight_wavewindow = old_g->highlight_wavewindow; GLOBALS->use_standard_trace_select = old_g->use_standard_trace_select; GLOBALS->use_big_fonts = old_g->use_big_fonts; GLOBALS->use_full_precision = old_g->use_full_precision; GLOBALS->use_frequency_delta = old_g->use_frequency_delta; GLOBALS->use_maxtime_display = old_g->use_maxtime_display; GLOBALS->use_nonprop_fonts = old_g->use_nonprop_fonts; GLOBALS->use_roundcaps = old_g->use_roundcaps; GLOBALS->use_scrollbar_only = old_g->use_scrollbar_only; GLOBALS->vcd_explicit_zero_subscripts = old_g->vcd_explicit_zero_subscripts; GLOBALS->vcd_preserve_glitches = old_g->vcd_preserve_glitches; GLOBALS->vcd_preserve_glitches_real = old_g->vcd_preserve_glitches_real; GLOBALS->vcd_warning_filesize = old_g->vcd_warning_filesize; GLOBALS->vector_padding = old_g->vector_padding; GLOBALS->vlist_compression_depth = old_g->vlist_compression_depth; GLOBALS->wave_scrolling = old_g->wave_scrolling; GLOBALS->do_zoom_center = old_g->do_zoom_center; GLOBALS->zoom_pow10_snap = old_g->zoom_pow10_snap; GLOBALS->zoom_dyn = old_g->zoom_dyn; GLOBALS->zoom_dyne = old_g->zoom_dyne; GLOBALS->alt_hier_delimeter = old_g->alt_hier_delimeter; GLOBALS->cursor_snap = old_g->cursor_snap; GLOBALS->hier_delimeter = old_g->hier_delimeter; GLOBALS->hier_was_explicitly_set = old_g->hier_was_explicitly_set; GLOBALS->page_divisor = old_g->page_divisor; GLOBALS->ps_maxveclen = old_g->ps_maxveclen; GLOBALS->vector_padding = old_g->vector_padding; GLOBALS->vlist_compression_depth = old_g->vlist_compression_depth; GLOBALS->zoombase = old_g->zoombase; GLOBALS->splash_disable = old_g->splash_disable; GLOBALS->use_pango_fonts = old_g->use_pango_fonts; GLOBALS->ruler_origin = old_g->ruler_origin; GLOBALS->ruler_step = old_g->ruler_step; GLOBALS->disable_ae2_alias = old_g->disable_ae2_alias; GLOBALS->vlist_spill_to_disk = old_g->vlist_spill_to_disk; GLOBALS->vlist_prepack = old_g->vlist_prepack; GLOBALS->do_dynamic_treefilter = old_g->do_dynamic_treefilter; GLOBALS->use_standard_clicking = old_g->use_standard_clicking; GLOBALS->use_toolbutton_interface = old_g->use_toolbutton_interface; GLOBALS->use_scrollwheel_as_y = old_g->use_scrollwheel_as_y; GLOBALS->enable_slider_zoom = old_g->enable_slider_zoom; GLOBALS->missing_file_toolbar = old_g->missing_file_toolbar; GLOBALS->analog_redraw_skip_count = old_g->analog_redraw_skip_count; GLOBALS->context_tabposition = old_g->context_tabposition; GLOBALS->disable_empty_gui = old_g->disable_empty_gui; GLOBALS->make_vcd_save_file = old_g->make_vcd_save_file; GLOBALS->strace_repeat_count = old_g->strace_repeat_count; strcpy2_into_new_context(GLOBALS, &GLOBALS->editor_name, &old_g->editor_name); strcpy2_into_new_context(GLOBALS, &GLOBALS->fontname_logfile, &old_g->fontname_logfile); strcpy2_into_new_context(GLOBALS, &GLOBALS->fontname_signals, &old_g->fontname_signals); strcpy2_into_new_context(GLOBALS, &GLOBALS->fontname_waves, &old_g->fontname_waves); strcpy2_into_new_context(GLOBALS, &GLOBALS->argvlist, &old_g->argvlist); mainwindow_already_built = 1; } GLOBALS->whoami=malloc_2(strlen(argv[0])+1); /* cache name in case we fork later */ strcpy(GLOBALS->whoami, argv[0]); if(!mainwindow_already_built) { #ifdef __MINGW32__ gtk_disable_setlocale(); #endif if(!gtk_init_check(&argc, &argv)) { #if defined(__APPLE__) #ifndef MAC_INTEGRATION if(!getenv("DISPLAY")) { fprintf(stderr, "DISPLAY environment variable is not set. Have you ensured\n"); fprintf(stderr, "that x11 has been initialized through open-x11, launching\n"); fprintf(stderr, "gtkwave in an xterm or x11 window, etc?\n\n"); fprintf(stderr, "Attempting to initialize using DISPLAY=:0.0 value...\n\n"); setenv("DISPLAY", ":0.0", 0); if(gtk_init_check(&argc, &argv)) { goto do_primary_inits; } } #endif #endif fprintf(stderr, "Could not initialize GTK! Is DISPLAY env var/xhost set?\n\n"); print_help(argv[0]); } #ifdef WAVE_CRASH_ON_GTK_WARNING g_log_set_always_fatal(G_LOG_LEVEL_CRITICAL|G_LOG_LEVEL_WARNING); #endif } #if defined(__APPLE__) #ifndef MAC_INTEGRATION do_primary_inits: #endif #endif if(!mainwindow_already_built) { wave_gconf_init(argc, argv); } if(!gtkwave_argv0_cached) gtkwave_argv0_cached = argv[0]; /* for new window option */ init_filetrans_data(); /* for file translation splay trees */ init_proctrans_data(); /* for proc translation structs */ init_ttrans_data(); /* for transaction proc translation structs */ if(!mainwindow_already_built) { atexit(remove_all_proc_filters); atexit(remove_all_ttrans_filters); #if defined __MINGW32__ atexit(close_all_fst_files); #endif } if(mainwindow_already_built) { optind = 1; } else while (1) { int option_index = 0; static struct option long_options[] = { {"dump", 1, 0, 'f'}, {"fastload", 0, 0, 'F'}, {"optimize", 0, 0, 'o'}, {"nocli", 1, 0, 'n'}, {"save", 1, 0, 'a'}, {"autosavename", 0, 0, 'A'}, {"rcfile", 1, 0, 'r'}, {"defaultskip", 0, 0, 'd'}, {"logfile", 1, 0, 'l'}, {"start", 1, 0, 's'}, {"end", 1, 0, 'e'}, {"cpus", 1, 0, 'c'}, {"stems", 1, 0, 't'}, {"nowm", 0, 0, 'N'}, {"script", 1, 0, 'S'}, {"vcd", 0, 0, 'v'}, {"version", 0, 0, 'V'}, {"help", 0, 0, 'h'}, {"exit", 0, 0, 'x'}, {"xid", 1, 0, 'X'}, {"nomenus", 0, 0, 'M'}, {"dualid", 1, 0, 'D'}, {"interactive", 0, 0, 'I'}, {"giga", 0, 0, 'g'}, {"comphier", 0, 0, 'C'}, {"legacy", 0, 0, 'L'}, {"tcl_init", 1, 0, 'T'}, {"wish", 0, 0, 'W'}, {"repscript", 1, 0, 'R'}, {"repperiod", 1, 0, 'P'}, {"output", 1, 0, 'O' }, {"slider-zoom", 0, 0, 'z'}, {"rpcid", 1, 0, '1' }, {"chdir", 1, 0, '2'}, {"restore", 0, 0, '3'}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "zf:Fon:a:Ar:dl:s:e:c:t:NS:vVhxX:MD:IgCLR:P:O:WT:1:2:3", long_options, &option_index); if (c == -1) break; /* no more args */ switch (c) { case 'V': printf( WAVE_VERSION_INFO"\n\n" "This is free software; see the source for copying conditions. There is NO\n" "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" ); exit(0); case 'W': #if defined(HAVE_LIBTCL) #if defined(WIN32) && defined(USE_TCL_STUBS) #else is_wish = 1; #endif #else fprintf(stderr, "GTKWAVE | Tcl support not compiled into this executable, exiting.\n"); exit(255); #endif break; case 'I': #if !defined _MSC_VER is_interactive = 1; #endif break; case 'L': is_legacy = 1; break; case 'D': #if !defined _MSC_VER { char *s = optarg; char *plus = strchr(s, '+'); if((plus)&&(*(plus+1))) { sscanf(plus+1, "%x", &GLOBALS->dual_attach_id_main_c_1); if(plus != s) { char p = *(plus-1); if(p=='0') { GLOBALS->dual_id = 0; break; } else if(p=='1') { GLOBALS->dual_id = 1; break; } } } fprintf(stderr, "Malformed dual session ID. Must be of form m+nnnnnnnn where m is 0 or 1,\n" "and n is a hexadecimal shared memory ID for use with shmat()\n"); exit(255); } #else { fprintf(stderr, "Dual operation not implemented for Win32, exiting.\n"); exit(255); } #endif break; case 'A': is_smartsave = 1; break; case 'v': is_vcd = 1; if(GLOBALS->loaded_file_name) free_2(GLOBALS->loaded_file_name); GLOBALS->loaded_file_name = malloc_2(4+1); strcpy(GLOBALS->loaded_file_name, "-vcd"); break; case 'o': opt_vcd = 1; break; case 'n': wave_get_filename(optarg); if(GLOBALS->filesel_ok) { if(GLOBALS->loaded_file_name) free_2(GLOBALS->loaded_file_name); GLOBALS->loaded_file_name = GLOBALS->ftext_main_main_c_1; GLOBALS->ftext_main_main_c_1 = NULL; } break; case 'h': print_help(argv[0]); break; #ifdef WAVE_USE_XID case 'X': sscanf(optarg, "%x", &GLOBALS->socket_xid); splash_disable_rc_override = 1; break; #endif case '1': sscanf(optarg, "%d", &wave_rpc_id); if(wave_rpc_id < 0) wave_rpc_id = 0; break; case '2': #ifndef _MSC_VER { char *chdir_env = getenv("GTKWAVE_CHDIR"); if(chdir_cache) { free_2(chdir_cache); } chdir_cache = strdup_2(chdir_env ? chdir_env : optarg); if(chdir(chdir_cache) < 0) { fprintf(stderr, "GTKWAVE | Could not chdir '%s', exiting.\n", chdir_cache); perror("Why"); exit(255); } } #endif break; case '3': #ifdef WAVE_HAVE_GCONF { is_vcd = 0; wave_gconf_restore(&GLOBALS->loaded_file_name, &wname, &override_rc, &chdir_cache, &opt_vcd); if(chdir_cache) { if(chdir(chdir_cache) < 0) { fprintf(stderr, "GTKWAVE | Could not chdir '%s', exiting.\n", chdir_cache); perror("Why"); exit(255); } } fprintf(stderr, "GTKWAVE | restore cwd '%s'\n", chdir_cache ? chdir_cache : "(none)"); fprintf(stderr, "GTKWAVE | restore dumpfile '%s'\n", GLOBALS->loaded_file_name ? GLOBALS->loaded_file_name : "(none)"); fprintf(stderr, "GTKWAVE | restore savefile '%s'\n", wname ? wname : "(none)"); fprintf(stderr, "GTKWAVE | restore rcfile '%s'\n", override_rc ? override_rc : "(none)"); fprintf(stderr, "GTKWAVE | restore optimize '%s'\n", opt_vcd ? "yes" : "no"); } #endif break; case 'M': GLOBALS->disable_menus = 1; break; case 'x': fast_exit = 1; splash_disable_rc_override = 1; break; case 'd': GLOBALS->possibly_use_rc_defaults = 0; break; case 'f': is_vcd = 0; if(GLOBALS->loaded_file_name) free_2(GLOBALS->loaded_file_name); GLOBALS->loaded_file_name = malloc_2(strlen(optarg)+1); strcpy(GLOBALS->loaded_file_name, optarg); break; case 'F': is_fastload = VCD_FSL_WRITE; is_giga = 1; break; case 'a': if(wname) free_2(wname); wname = malloc_2(strlen(optarg)+1); strcpy(wname, optarg); break; case 'r': if(override_rc) free_2(override_rc); override_rc = malloc_2(strlen(optarg)+1); strcpy(override_rc, optarg); break; case 's': if(GLOBALS->skip_start) free_2(GLOBALS->skip_start); GLOBALS->skip_start = malloc_2(strlen(optarg)+1); strcpy(GLOBALS->skip_start, optarg); break; case 'e': if(GLOBALS->skip_end) free_2(GLOBALS->skip_end); GLOBALS->skip_end = malloc_2(strlen(optarg)+1); strcpy(GLOBALS->skip_end, optarg); break; case 't': #if !defined _MSC_VER if(GLOBALS->stems_name) free_2(GLOBALS->stems_name); GLOBALS->stems_name = malloc_2(strlen(optarg)+1); strcpy(GLOBALS->stems_name, optarg); #else fprintf(stderr, "GTKWAVE | Warning: '%c' option does not exist in this executable\n", c); #endif break; case 'c': #if !defined _MSC_VER && !defined __MINGW32__ && !defined __FreeBSD__ && !defined __CYGWIN__ GLOBALS->num_cpus = atoi(optarg); if(GLOBALS->num_cpus<1) GLOBALS->num_cpus = 1; if(GLOBALS->num_cpus>8) GLOBALS->num_cpus = 8; #else fprintf(stderr, "GTKWAVE | Warning: '%c' option does not exist in this executable\n", c); #endif break; case 'N': GLOBALS->disable_window_manager = 1; break; case 'S': if(scriptfile) free_2(scriptfile); scriptfile = malloc_2(strlen(optarg)+1); strcpy(scriptfile, optarg); splash_disable_rc_override = 1; break; case 'l': { struct logfile_chain *l = calloc_2(1, sizeof(struct logfile_chain)); struct logfile_chain *ltraverse; l->name = malloc_2(strlen(optarg)+1); strcpy(l->name, optarg); if(GLOBALS->logfile) { ltraverse = GLOBALS->logfile; while(ltraverse->next) ltraverse = ltraverse->next; ltraverse->next = l; } else { GLOBALS->logfile = l; } } break; case 'g': is_giga = 1; break; case 'C': GLOBALS->do_hier_compress = 1; break; case 'R': if(GLOBALS->repscript_name) free_2(GLOBALS->repscript_name); GLOBALS->repscript_name = malloc_2(strlen(optarg)+1); strcpy(GLOBALS->repscript_name, optarg); break; case 'P': { int pd = atoi(optarg); if(pd > 0) { GLOBALS->repscript_period = pd; } } break; case 'T': #if defined(WIN32) && defined(USE_TCL_STUBS) fprintf(stderr, "GTKWAVE | Warning: '%c' option does not exist in this executable\n", c); #else { char* pos; is_wish = 1; if(GLOBALS->tcl_init_cmd) { int length = strlen(GLOBALS->tcl_init_cmd)+9+strlen(optarg); char* buffer = malloc_2(strlen(GLOBALS->tcl_init_cmd)+1); strcpy(buffer, GLOBALS->tcl_init_cmd); free_2(GLOBALS->tcl_init_cmd); GLOBALS->tcl_init_cmd = malloc_2(length+1); strcpy(GLOBALS->tcl_init_cmd, buffer); pos = GLOBALS->tcl_init_cmd + strlen(GLOBALS->tcl_init_cmd); free_2(buffer); } else { int length = 9+strlen(optarg); GLOBALS->tcl_init_cmd = malloc_2(length+1); pos = GLOBALS->tcl_init_cmd; } strcpy(pos, "; source "); pos = GLOBALS->tcl_init_cmd + strlen(GLOBALS->tcl_init_cmd); strcpy(pos, optarg); } #endif break; case 'O': if(output_name) free_2(output_name); output_name = malloc_2(strlen(optarg)+1); strcpy(output_name, optarg); break; case 'z': GLOBALS->enable_slider_zoom = 1; break; case '?': opt_errors_encountered=1; break; default: /* unreachable */ break; } } /* ...while(1) */ if(opt_errors_encountered) { print_help(argv[0]); } if (optind < argc) { while (optind < argc) { if(argv[optind][0] == '-') { if(!strcmp(argv[optind], "--")) { break; } } if(!GLOBALS->loaded_file_name) { is_vcd = 0; GLOBALS->loaded_file_name = malloc_2(strlen(argv[optind])+1); strcpy(GLOBALS->loaded_file_name, argv[optind++]); } else if(!wname) { wname = malloc_2(strlen(argv[optind])+1); strcpy(wname, argv[optind++]); } else if(!override_rc) { override_rc = malloc_2(strlen(argv[optind])+1); strcpy(override_rc, argv[optind++]); break; /* skip any extra args */ } } } if(is_wish && is_vcd) { fprintf(stderr, "GTKWAVE | Cannot use --vcd and --wish options together as both use stdin,\n" "GTKWAVE | exiting!\n"); exit(255); } #if defined(EXTLOAD_SUFFIX) && defined(EXTCONV_PATH) #if !defined(FSDB_IS_PRESENT) || !defined(FSDB_NSYS_IS_PRESENT) if(GLOBALS->loaded_file_name && suffix_check(GLOBALS->loaded_file_name, "."EXTLOAD_SUFFIX)) { opt_vcd = 1; } #endif #endif #if defined(EXT2LOAD_SUFFIX) && defined(EXT2CONV_PATH) if(GLOBALS->loaded_file_name && suffix_check(GLOBALS->loaded_file_name, "."EXT2LOAD_SUFFIX)) { opt_vcd = 1; } #endif #if defined(EXT3LOAD_SUFFIX) && defined(EXT3CONV_PATH) if(GLOBALS->loaded_file_name && suffix_check(GLOBALS->loaded_file_name, "."EXT3LOAD_SUFFIX)) { opt_vcd = 1; } #endif /* attempt to load a dump+save file if only a savefile is specified at the command line */ if((GLOBALS->loaded_file_name) && (!wname) && (suffix_check(GLOBALS->loaded_file_name, ".gtkw") || suffix_check(GLOBALS->loaded_file_name, ".sav"))) { char *extracted_name = extract_dumpname_from_save_file(GLOBALS->loaded_file_name, &GLOBALS->dumpfile_is_modified, &opt_vcd); if(extracted_name) { if(mainwindow_already_built) { deal_with_rpc_open_2(GLOBALS->loaded_file_name, NULL, TRUE); GLOBALS->loaded_file_name = extracted_name; /* wname is still NULL */ } else { wname = GLOBALS->loaded_file_name; GLOBALS->loaded_file_name = extracted_name; } } } else /* same as above but with --save specified */ if((!GLOBALS->loaded_file_name) && wname) { GLOBALS->loaded_file_name = extract_dumpname_from_save_file(wname, &GLOBALS->dumpfile_is_modified, &opt_vcd); /* still can be NULL if file not found... */ } if(!old_g) /* copy all variables earlier when old_g is set */ { read_rc_file(override_rc); } GLOBALS->splash_disable |= splash_disable_rc_override; if(!GLOBALS->loaded_file_name) { /* if rc can gates off gui, default is not to disable */ if(GLOBALS->disable_empty_gui) { print_help(argv[0]); } } if(is_giga) { GLOBALS->vlist_spill_to_disk = 1; GLOBALS->vlist_prepack = 1; } if(output_name) { #if !defined _MSC_VER && !defined __MINGW32__ int iarg; time_t walltime; int fd_replace = open(output_name, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR); if(fd_replace<0) { fprintf(stderr, "Could not open redirect file, exiting.\n"); perror("Why"); exit(255); } dup2(fd_replace, 1); dup2(fd_replace, 2); time(&walltime); printf(WAVE_VERSION_INFO"\nDate: %s\n\n",asctime(localtime(&walltime))); for(iarg=0;iargargvlist = zMergeTclList(argc, (const char**)argv); make_tcl_interpreter(argv); } } if((!wname)&&(GLOBALS->make_vcd_save_file)) { vcd_save_handle_cached = GLOBALS->vcd_save_handle=fopen(vcd_autosave_name,"wb"); errno=0; /* just in case */ is_smartsave = (GLOBALS->vcd_save_handle != NULL); /* use smartsave if for some reason can't open auto savefile */ } if(!GLOBALS->loaded_file_name) { GLOBALS->loaded_file_name = strdup_2("[no file loaded]"); is_missing_file = 1; GLOBALS->min_time=LLDescriptor(0); GLOBALS->max_time=LLDescriptor(0); if(!is_wish) { fprintf(stderr, "GTKWAVE | Use the -h, --help command line flags to display help.\n"); } } /* load either the vcd or aet file depending on suffix then mode setting */ if(is_vcd) { GLOBALS->winname=malloc_2(strlen(winstd)+4+1); strcpy(GLOBALS->winname,winstd); } else { if(!is_interactive) { GLOBALS->winname=malloc_2(strlen(GLOBALS->loaded_file_name)+strlen(winprefix)+1); strcpy(GLOBALS->winname,winprefix); } else { char *iact = "GTKWave - Interactive Shared Memory ID "; GLOBALS->winname=malloc_2(strlen(GLOBALS->loaded_file_name)+strlen(iact)+1); strcpy(GLOBALS->winname,iact); } } strcat(GLOBALS->winname,GLOBALS->loaded_file_name); loader_check_head: if(!is_missing_file) { magic_word_filetype = determine_gtkwave_filetype(GLOBALS->loaded_file_name); } if(is_missing_file) { GLOBALS->loaded_file_type = MISSING_FILE; } else #if defined(EXTLOAD_SUFFIX) if(suffix_check(GLOBALS->loaded_file_name, "."EXTLOAD_SUFFIX) && !opt_vcd) { TimeType extload_max; GLOBALS->loaded_file_type = EXTLOAD_FILE; extload_max = extload_main(GLOBALS->loaded_file_name, GLOBALS->skip_start, GLOBALS->skip_end); if((!GLOBALS->extload) || (GLOBALS->extload_already_errored) || (!extload_max)) { fprintf(stderr, "GTKWAVE | Could not initialize '%s'%s.\n", GLOBALS->loaded_file_name, GLOBALS->vcd_jmp_buf ? "" : ", exiting"); vcd_exit(255); } } else #endif if((magic_word_filetype == G_FT_LXT) || (magic_word_filetype == G_FT_LXT2) || suffix_check(GLOBALS->loaded_file_name, ".lxt") || suffix_check(GLOBALS->loaded_file_name, ".lx2") || suffix_check(GLOBALS->loaded_file_name, ".lxt2")) { FILE *f = fopen(GLOBALS->loaded_file_name, "rb"); int typ = 0; if(f) { char buf[2]; unsigned int matchword; if(fread(buf, 2, 1, f)) { matchword = (((unsigned int)buf[0])<<8) | ((unsigned int)buf[1]); if(matchword == LT_HDRID) typ = 1; } fclose(f); } if(typ) { GLOBALS->loaded_file_type = LXT_FILE; lxt_main(GLOBALS->loaded_file_name); } else { #if !defined _MSC_VER GLOBALS->stems_type = WAVE_ANNO_LXT2; GLOBALS->aet_name = malloc_2(strlen(GLOBALS->loaded_file_name)+1); strcpy(GLOBALS->aet_name, GLOBALS->loaded_file_name); #endif GLOBALS->loaded_file_type = LX2_FILE; lx2_main(GLOBALS->loaded_file_name, GLOBALS->skip_start, GLOBALS->skip_end); if(!GLOBALS->lx2_lx2_c_1) { fprintf(stderr, "GTKWAVE | Could not initialize '%s'%s.\n", GLOBALS->loaded_file_name, GLOBALS->vcd_jmp_buf ? "" : ", exiting"); vcd_exit(255); } } } else if((magic_word_filetype == G_FT_FST) || suffix_check(GLOBALS->loaded_file_name, ".fst")) { #if !defined _MSC_VER GLOBALS->stems_type = WAVE_ANNO_FST; GLOBALS->aet_name = malloc_2(strlen(GLOBALS->loaded_file_name)+1); strcpy(GLOBALS->aet_name, GLOBALS->loaded_file_name); #endif GLOBALS->loaded_file_type = FST_FILE; fst_main(GLOBALS->loaded_file_name, GLOBALS->skip_start, GLOBALS->skip_end); if(!GLOBALS->fst_fst_c_1) { fprintf(stderr, "GTKWAVE | Could not initialize '%s'%s.\n", GLOBALS->loaded_file_name, GLOBALS->vcd_jmp_buf ? "" : ", exiting"); vcd_exit(255); } } else if((magic_word_filetype == G_FT_VZT) || suffix_check(GLOBALS->loaded_file_name, ".vzt")) { #if !defined _MSC_VER GLOBALS->stems_type = WAVE_ANNO_VZT; GLOBALS->aet_name = malloc_2(strlen(GLOBALS->loaded_file_name)+1); strcpy(GLOBALS->aet_name, GLOBALS->loaded_file_name); #endif GLOBALS->loaded_file_type = VZT_FILE; vzt_main(GLOBALS->loaded_file_name, GLOBALS->skip_start, GLOBALS->skip_end); if(!GLOBALS->vzt_vzt_c_1) { fprintf(stderr, "GTKWAVE | Could not initialize '%s'%s.\n", GLOBALS->loaded_file_name, GLOBALS->vcd_jmp_buf ? "" : ", exiting"); vcd_exit(255); } } else if(suffix_check(GLOBALS->loaded_file_name, ".aet") || suffix_check(GLOBALS->loaded_file_name, ".ae2")) { #if !defined _MSC_VER GLOBALS->stems_type = WAVE_ANNO_AE2; GLOBALS->aet_name = malloc_2(strlen(GLOBALS->loaded_file_name)+1); strcpy(GLOBALS->aet_name, GLOBALS->loaded_file_name); #endif GLOBALS->loaded_file_type = AE2_FILE; ae2_main(GLOBALS->loaded_file_name, GLOBALS->skip_start, GLOBALS->skip_end); #ifdef AET2_IS_PRESENT if(!GLOBALS->ae2) { fprintf(stderr, "GTKWAVE | Could not initialize '%s'%s.\n", GLOBALS->loaded_file_name, GLOBALS->vcd_jmp_buf ? "" : ", exiting"); vcd_exit(255); } #else /* fails in stubbed out ae2_main() */ #endif } else if (suffix_check(GLOBALS->loaded_file_name, ".ghw") || suffix_check(GLOBALS->loaded_file_name, ".ghw.gz") || suffix_check(GLOBALS->loaded_file_name, ".ghw.bz2")) { GLOBALS->loaded_file_type = GHW_FILE; if(!ghw_main(GLOBALS->loaded_file_name)) { /* error message printed in ghw_main() */ vcd_exit(255); } } else if (strlen(GLOBALS->loaded_file_name)>4) /* case for .aet? type filenames */ { char sufbuf[5]; memcpy(sufbuf, GLOBALS->loaded_file_name+strlen(GLOBALS->loaded_file_name)-5, 4); sufbuf[4] = 0; if(!strcasecmp(sufbuf, ".aet")) /* strncasecmp() in windows? */ { #if !defined _MSC_VER GLOBALS->stems_type = WAVE_ANNO_AE2; GLOBALS->aet_name = malloc_2(strlen(GLOBALS->loaded_file_name)+1); strcpy(GLOBALS->aet_name, GLOBALS->loaded_file_name); #endif GLOBALS->loaded_file_type = AE2_FILE; #ifdef AET2_IS_PRESENT ae2_main(GLOBALS->loaded_file_name, GLOBALS->skip_start, GLOBALS->skip_end); if(!GLOBALS->ae2) { fprintf(stderr, "GTKWAVE | Could not initialize '%s'%s.\n", GLOBALS->loaded_file_name, GLOBALS->vcd_jmp_buf ? "" : ", exiting"); vcd_exit(255); } #else /* fails in stubbed out ae2_main() */ #endif } else { goto load_vcd; } } else /* nothing else left so default to "something" */ { load_vcd: #if !defined _MSC_VER && !defined __MINGW32__ if(opt_vcd) { GLOBALS->unoptimized_vcd_file_name = calloc_2(1,strlen(GLOBALS->loaded_file_name) + 1); strcpy(GLOBALS->unoptimized_vcd_file_name, GLOBALS->loaded_file_name); optimize_vcd_file(); /* is_vcd = 0; */ /* scan-build */ GLOBALS->optimize_vcd = 1; goto loader_check_head; } #endif #if !defined _MSC_VER if(is_interactive) { GLOBALS->loaded_file_type = DUMPLESS_FILE; vcd_partial_main(GLOBALS->loaded_file_name); } else #endif { if(is_legacy) { GLOBALS->loaded_file_type = (strcmp(GLOBALS->loaded_file_name, "-vcd")) ? VCD_FILE : DUMPLESS_FILE; vcd_main(GLOBALS->loaded_file_name); } else { if(strcmp(GLOBALS->loaded_file_name, "-vcd")) { GLOBALS->loaded_file_type = VCD_RECODER_FILE; GLOBALS->use_fastload = is_fastload; } else { GLOBALS->loaded_file_type = DUMPLESS_FILE; GLOBALS->use_fastload = VCD_FSL_NONE; } vcd_recoder_main(GLOBALS->loaded_file_name); } } } if(((GLOBALS->loaded_file_type != FST_FILE) && (GLOBALS->loaded_file_type != AE2_FILE) #if defined(EXTLOAD_SUFFIX) && (GLOBALS->loaded_file_type != EXTLOAD_FILE) #endif ) || (!GLOBALS->fast_tree_sort)) { GLOBALS->do_hier_compress = 0; /* for now, add more file formats in the future */ } /* deallocate the symbol hash table */ sym_hash_destroy(GLOBALS); /* reset/initialize various markers and time values */ for(i=0;inamed_markers[i]=-1; /* reset all named markers */ GLOBALS->tims.last=GLOBALS->max_time; GLOBALS->tims.end=GLOBALS->tims.last; /* until the configure_event of wavearea */ GLOBALS->tims.first=GLOBALS->tims.start=GLOBALS->tims.laststart=GLOBALS->min_time; GLOBALS->tims.zoom=GLOBALS->tims.prevzoom=0; /* 1 pixel/ns default */ GLOBALS->tims.marker=GLOBALS->tims.lmbcache=-1; /* uninitialized at first */ GLOBALS->tims.baseline=-1; /* middle button toggle marker */ if((wname)||(vcd_save_handle_cached)||(is_smartsave)) { int wave_is_compressed; char *str = NULL; GLOBALS->is_gtkw_save_file = (!wname) || suffix_check(wname, ".gtkw"); if(vcd_save_handle_cached) { wname=vcd_autosave_name; GLOBALS->do_initial_zoom_fit=1; } else if((!wname) /* && (is_smartsave) */) { char *pnt = wave_alloca(strlen(GLOBALS->loaded_file_name) + 1); char *pnt2; strcpy(pnt, GLOBALS->loaded_file_name); if((strlen(pnt)>2)&&(!strcasecmp(pnt+strlen(pnt)-3,".gz"))) { pnt[strlen(pnt)-3] = 0x00; } else if ((strlen(pnt)>3)&&(!strcasecmp(pnt+strlen(pnt)-4,".zip"))) { pnt[strlen(pnt)-4] = 0x00; } pnt2 = pnt + strlen(pnt); if(pnt != pnt2) { do { if(*pnt2 == '.') { *pnt2 = 0x00; break; } } while(pnt2-- != pnt); } wname = malloc_2(strlen(pnt) + 6); strcpy(wname, pnt); strcat(wname, ".gtkw"); } if(((strlen(wname)>2)&&(!strcasecmp(wname+strlen(wname)-3,".gz")))|| ((strlen(wname)>3)&&(!strcasecmp(wname+strlen(wname)-4,".zip")))) { int dlen; dlen=strlen(WAVE_DECOMPRESSOR); str=wave_alloca(strlen(wname)+dlen+1); strcpy(str,WAVE_DECOMPRESSOR); strcpy(str+dlen,wname); wave=popen(str,"r"); wave_is_compressed=~0; } else { wave=fopen(wname,"rb"); wave_is_compressed=0; GLOBALS->filesel_writesave = malloc_2(strlen(wname)+1); /* don't handle compressed files */ strcpy(GLOBALS->filesel_writesave, wname); } if(!wave) { fprintf(stderr, "** WARNING: Error opening save file '%s', skipping.\n",wname); } else { char *iline; int s_ctx_iter; WAVE_STRACE_ITERATOR(s_ctx_iter) { GLOBALS->strace_ctx = &GLOBALS->strace_windows[GLOBALS->strace_current_window = s_ctx_iter]; GLOBALS->strace_ctx->shadow_encountered_parsewavline = 0; } if(GLOBALS->is_lx2) { while((iline=fgetmalloc(wave))) { parsewavline_lx2(iline, NULL, 0); free_2(iline); } switch(GLOBALS->is_lx2) { case LXT2_IS_LXT2: lx2_import_masked(); break; case LXT2_IS_AET2: ae2_import_masked(); break; case LXT2_IS_VZT: vzt_import_masked(); break; case LXT2_IS_VLIST: vcd_import_masked(); break; case LXT2_IS_FST: fst_import_masked(); break; case LXT2_IS_FSDB: fsdb_import_masked(); break; } if(wave_is_compressed) { pclose(wave); wave=popen(str,"r"); } else { fclose(wave); wave=fopen(wname,"rb"); } if(!wave) { fprintf(stderr, "** WARNING: Error opening save file '%s', skipping.\n",wname); EnsureGroupsMatch(); goto savefile_bail; } } read_save_helper_relative_init(wname); GLOBALS->default_flags=TR_RJUSTIFY; GLOBALS->shift_timebase_default_for_add=LLDescriptor(0); GLOBALS->strace_current_window = 0; /* in case there are shadow traces */ GLOBALS->which_t_color = 0; while((iline=fgetmalloc(wave))) { parsewavline(iline, NULL, 0); GLOBALS->strace_ctx->shadow_encountered_parsewavline |= GLOBALS->strace_ctx->shadow_active; free_2(iline); } GLOBALS->which_t_color = 0; GLOBALS->default_flags=TR_RJUSTIFY; GLOBALS->shift_timebase_default_for_add=LLDescriptor(0); if(wave_is_compressed) pclose(wave); else fclose(wave); EnsureGroupsMatch(); WAVE_STRACE_ITERATOR(s_ctx_iter) { GLOBALS->strace_ctx = &GLOBALS->strace_windows[GLOBALS->strace_current_window = s_ctx_iter]; if(GLOBALS->strace_ctx->shadow_encountered_parsewavline) { GLOBALS->strace_ctx->shadow_encountered_parsewavline = 0; if(GLOBALS->strace_ctx->shadow_straces) { GLOBALS->strace_ctx->shadow_active = 1; swap_strace_contexts(); strace_maketimetrace(1); swap_strace_contexts(); GLOBALS->strace_ctx->shadow_active = 0; } } } } } savefile_bail: GLOBALS->current_translate_file = 0; if(fast_exit) { printf("Exiting early because of --exit request.\n"); exit(0); } if ((GLOBALS->loaded_file_type != MISSING_FILE) && (!GLOBALS->zoom_was_explicitly_set) && ((GLOBALS->tims.last-GLOBALS->tims.first)<=400)) GLOBALS->do_initial_zoom_fit=1; /* force zoom on small traces */ calczoom(GLOBALS->tims.zoom); if(!mainwindow_already_built) { #ifdef WAVE_USE_XID if(!GLOBALS->socket_xid) #endif { GLOBALS->mainwindow = gtk_window_new(GLOBALS->disable_window_manager ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL); wave_gtk_window_set_title(GTK_WINDOW(GLOBALS->mainwindow), GLOBALS->winname, GLOBALS->dumpfile_is_modified ? WAVE_SET_TITLE_MODIFIED: WAVE_SET_TITLE_NONE, 0); if((GLOBALS->initial_window_width>0)&&(GLOBALS->initial_window_height>0)) { gtk_window_set_default_size(GTK_WINDOW (GLOBALS->mainwindow), GLOBALS->initial_window_width, GLOBALS->initial_window_height); } else { gtk_window_set_default_size(GTK_WINDOW(GLOBALS->mainwindow), GLOBALS->initial_window_x, GLOBALS->initial_window_y); } gtk_signal_connect(GTK_OBJECT(GLOBALS->mainwindow), "delete_event", /* formerly was "destroy" */GTK_SIGNAL_FUNC(file_quit_cmd_callback), "WM destroy"); gtk_widget_show(GLOBALS->mainwindow); } #ifdef WAVE_USE_XID else { GLOBALS->mainwindow = gtk_plug_new(GLOBALS->socket_xid); gtk_widget_show(GLOBALS->mainwindow); gtk_signal_connect(GTK_OBJECT(GLOBALS->mainwindow), "destroy", /* formerly was "destroy" */GTK_SIGNAL_FUNC(plug_destroy),"Plug destroy"); } #endif } #ifdef MAC_INTEGRATION dock_pb = #endif make_pixmaps(GLOBALS->mainwindow); #ifdef WAVE_USE_GTK2 if(GLOBALS->use_toolbutton_interface) { GtkWidget *tb; GtkWidget *stock; GtkStyle *style; int tb_pos; if(!mainwindow_already_built) { main_vbox = gtk_vbox_new(FALSE, 5); gtk_container_border_width(GTK_CONTAINER(main_vbox), 1); gtk_container_add(GTK_CONTAINER(GLOBALS->mainwindow), main_vbox); gtk_widget_show(main_vbox); if(!GLOBALS->disable_menus) { #ifdef WAVE_USE_MLIST_T menubar = alt_menu_top(GLOBALS->mainwindow); #else get_main_menu(GLOBALS->mainwindow, &menubar); #endif gtk_widget_show(menubar); #ifdef MAC_INTEGRATION { GtkosxApplication *theApp = g_object_new(GTKOSX_TYPE_APPLICATION, NULL); gtk_widget_hide(menubar); gtkosx_application_set_menu_bar(theApp, GTK_MENU_SHELL(menubar)); gtkosx_application_set_use_quartz_accelerators(theApp, TRUE); gtkosx_application_ready(theApp); gtkosx_application_set_dock_icon_pixbuf(theApp, dock_pb); if(GLOBALS->loaded_file_type == MISSING_FILE) { gtkosx_application_attention_request(theApp, INFO_REQUEST); } g_signal_connect(theApp, "NSApplicationOpenFile", G_CALLBACK(deal_with_finder_open), NULL); g_signal_connect(theApp, "NSApplicationBlockTermination", G_CALLBACK(deal_with_termination), NULL); } #endif if(GLOBALS->force_toolbars) { toolhandle=gtk_handle_box_new(); gtk_widget_show(toolhandle); gtk_container_add(GTK_CONTAINER(toolhandle), menubar); gtk_box_pack_start(GTK_BOX(main_vbox), toolhandle, FALSE, TRUE, 0); } else { gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0); } } whole_table = gtk_table_new (256, 16, FALSE); tb = gtk_toolbar_new(); top_table = tb; /* export this as our top widget rather than a table */ gtk_toolbar_set_style(GTK_TOOLBAR(tb), GTK_TOOLBAR_ICONS); tb_pos = 0; if(GLOBALS->force_toolbars) { toolhandle=gtk_handle_box_new(); gtk_widget_show(toolhandle); gtk_container_add(GTK_CONTAINER(toolhandle), top_table); } stock = gtk_toolbar_insert_stock(GTK_TOOLBAR(tb), GTK_STOCK_CUT, "Cut Traces", NULL, GTK_SIGNAL_FUNC(menu_cut_traces), NULL, tb_pos++); style = gtk_widget_get_style(stock); style->xthickness = style->ythickness = 0; gtk_widget_set_style (stock, style); gtk_widget_show(stock); stock = gtk_toolbar_insert_stock(GTK_TOOLBAR(tb), GTK_STOCK_COPY, "Copy Traces", NULL, GTK_SIGNAL_FUNC(menu_copy_traces), NULL, tb_pos++); style = gtk_widget_get_style(stock); style->xthickness = style->ythickness = 0; gtk_widget_set_style (stock, style); gtk_widget_show(stock); stock = gtk_toolbar_insert_stock(GTK_TOOLBAR(tb), GTK_STOCK_PASTE, "Paste Traces", NULL, GTK_SIGNAL_FUNC(menu_paste_traces), NULL, tb_pos++); style = gtk_widget_get_style(stock); style->xthickness = style->ythickness = 0; gtk_widget_set_style (stock, style); gtk_widget_show(stock); gtk_toolbar_insert_space(GTK_TOOLBAR(tb), tb_pos++); stock = gtk_toolbar_insert_stock(GTK_TOOLBAR(tb), GTK_STOCK_ZOOM_FIT, "Zoom Fit", NULL, GTK_SIGNAL_FUNC(service_zoom_fit), NULL, tb_pos++); style = gtk_widget_get_style(stock); style->xthickness = style->ythickness = 0; gtk_widget_set_style (stock, style); gtk_widget_show(stock); stock = gtk_toolbar_insert_stock(GTK_TOOLBAR(tb), GTK_STOCK_ZOOM_IN, "Zoom In", NULL, GTK_SIGNAL_FUNC(service_zoom_in), NULL, tb_pos++); style = gtk_widget_get_style(stock); style->xthickness = style->ythickness = 0; gtk_widget_set_style (stock, style); gtk_widget_show(stock); stock = gtk_toolbar_insert_stock(GTK_TOOLBAR(tb), GTK_STOCK_ZOOM_OUT, "Zoom Out", NULL, GTK_SIGNAL_FUNC(service_zoom_out), NULL, tb_pos++); style = gtk_widget_get_style(stock); style->xthickness = style->ythickness = 0; gtk_widget_set_style (stock, style); gtk_widget_show(stock); stock = gtk_toolbar_insert_stock(GTK_TOOLBAR(tb), GTK_STOCK_UNDO, "Zoom Undo", NULL, GTK_SIGNAL_FUNC(service_zoom_undo), NULL, tb_pos++); style = gtk_widget_get_style(stock); style->xthickness = style->ythickness = 0; gtk_widget_set_style (stock, style); gtk_widget_show(stock); stock = gtk_toolbar_insert_stock(GTK_TOOLBAR(tb), GTK_STOCK_GOTO_FIRST, "Zoom to Start", NULL, GTK_SIGNAL_FUNC(service_zoom_left), NULL, tb_pos++); style = gtk_widget_get_style(stock); style->xthickness = style->ythickness = 0; gtk_widget_set_style (stock, style); gtk_widget_show(stock); stock = gtk_toolbar_insert_stock(GTK_TOOLBAR(tb), GTK_STOCK_GOTO_LAST, "Zoom to End", NULL, GTK_SIGNAL_FUNC(service_zoom_right), NULL, tb_pos++); style = gtk_widget_get_style(stock); style->xthickness = style->ythickness = 0; gtk_widget_set_style (stock, style); gtk_widget_show(stock); gtk_toolbar_insert_space(GTK_TOOLBAR(tb), tb_pos++); stock = gtk_toolbar_insert_stock(GTK_TOOLBAR(tb), GTK_STOCK_GO_BACK, "Find Previous Edge", NULL, GTK_SIGNAL_FUNC(service_left_edge), NULL, tb_pos++); style = gtk_widget_get_style(stock); style->xthickness = style->ythickness = 0; gtk_widget_set_style (stock, style); gtk_widget_show(stock); stock = gtk_toolbar_insert_stock(GTK_TOOLBAR(tb), GTK_STOCK_GO_FORWARD, "Find Next Edge", NULL, GTK_SIGNAL_FUNC(service_right_edge), NULL, tb_pos++); style = gtk_widget_get_style(stock); style->xthickness = style->ythickness = 0; gtk_widget_set_style (stock, style); gtk_widget_show(stock); gtk_toolbar_insert_space(GTK_TOOLBAR(tb), tb_pos++); entry = create_entry_box(); gtk_widget_show(entry); gtk_toolbar_insert_widget(GTK_TOOLBAR(tb), entry, NULL, NULL, tb_pos++); gtk_toolbar_insert_space(GTK_TOOLBAR(tb), tb_pos++); if((GLOBALS->loaded_file_type != DUMPLESS_FILE)&&(!GLOBALS->disable_menus)) { stock = gtk_toolbar_insert_stock(GTK_TOOLBAR(tb), GTK_STOCK_REFRESH, "Reload", NULL, GTK_SIGNAL_FUNC(menu_reload_waveform_marshal), NULL, tb_pos++); style = gtk_widget_get_style(stock); style->xthickness = style->ythickness = 0; gtk_widget_set_style (stock, style); gtk_widget_show(stock); gtk_toolbar_insert_space(GTK_TOOLBAR(tb), tb_pos++); } timebox = create_time_box(); gtk_widget_show (timebox); gtk_toolbar_insert_widget(GTK_TOOLBAR(tb), timebox, NULL, NULL, tb_pos /* ++ */); /* scan-build */ GLOBALS->missing_file_toolbar = tb; if(GLOBALS->loaded_file_type == MISSING_FILE) { gtk_widget_set_sensitive(GLOBALS->missing_file_toolbar, FALSE); } } /* of ...if(mainwindow_already_built) */ } else #endif { if(!mainwindow_already_built) { main_vbox = gtk_vbox_new(FALSE, 5); gtk_container_border_width(GTK_CONTAINER(main_vbox), 1); gtk_container_add(GTK_CONTAINER(GLOBALS->mainwindow), main_vbox); gtk_widget_show(main_vbox); if(!GLOBALS->disable_menus) { #ifdef WAVE_USE_MLIST_T menubar = alt_menu_top(GLOBALS->mainwindow); #else get_main_menu(GLOBALS->mainwindow, &menubar); #endif gtk_widget_show(menubar); #ifdef MAC_INTEGRATION { GtkosxApplication *theApp = g_object_new(GTKOSX_TYPE_APPLICATION, NULL); gtk_widget_hide(menubar); gtkosx_application_set_menu_bar(theApp, GTK_MENU_SHELL(menubar)); gtkosx_application_set_use_quartz_accelerators(theApp, TRUE); gtkosx_application_ready(theApp); gtkosx_application_set_dock_icon_pixbuf(theApp, dock_pb); if(GLOBALS->loaded_file_type == MISSING_FILE) { gtkosx_application_attention_request(theApp, INFO_REQUEST); } g_signal_connect(theApp, "NSApplicationOpenFile", G_CALLBACK(deal_with_finder_open), NULL); g_signal_connect(theApp, "NSApplicationBlockTermination", G_CALLBACK(deal_with_termination), NULL); } #endif if(GLOBALS->force_toolbars) { toolhandle=gtk_handle_box_new(); gtk_widget_show(toolhandle); gtk_container_add(GTK_CONTAINER(toolhandle), menubar); gtk_box_pack_start(GTK_BOX(main_vbox), toolhandle, FALSE, TRUE, 0); } else { gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0); } } top_table = gtk_table_new (1, 284, FALSE); if(GLOBALS->force_toolbars) { toolhandle=gtk_handle_box_new(); gtk_widget_show(toolhandle); gtk_container_add(GTK_CONTAINER(toolhandle), top_table); } whole_table = gtk_table_new (256, 16, FALSE); text1 = create_text (); gtk_table_attach (GTK_TABLE (top_table), text1, 0, 141, 0, 1, GTK_FILL, GTK_FILL | GTK_SHRINK, 0, 0); gtk_widget_set_usize(GTK_WIDGET(text1), 200, -1); gtk_widget_show (text1); dummy1=gtk_label_new(""); gtk_table_attach (GTK_TABLE (top_table), dummy1, 141, 171, 0, 1, GTK_FILL, GTK_SHRINK, 0, 0); gtk_widget_show (dummy1); zoombuttons = create_zoom_buttons (); gtk_table_attach (GTK_TABLE (top_table), zoombuttons, 171, 173, 0, 1, GTK_FILL, GTK_SHRINK, 0, 0); gtk_widget_show (zoombuttons); if(!GLOBALS->use_scrollbar_only) { pagebuttons = create_page_buttons (); gtk_table_attach (GTK_TABLE (top_table), pagebuttons, 173, 174, 0, 1, GTK_FILL, GTK_SHRINK, 0, 0); gtk_widget_show (pagebuttons); fetchbuttons = create_fetch_buttons (); gtk_table_attach (GTK_TABLE (top_table), fetchbuttons, 174, 175, 0, 1, GTK_FILL, GTK_SHRINK, 0, 0); gtk_widget_show (fetchbuttons); discardbuttons = create_discard_buttons (); gtk_table_attach (GTK_TABLE (top_table), discardbuttons, 175, 176, 0, 1, GTK_FILL, GTK_SHRINK, 0, 0); gtk_widget_show (discardbuttons); shiftbuttons = create_shift_buttons (); gtk_table_attach (GTK_TABLE (top_table), shiftbuttons, 176, 177, 0, 1, GTK_FILL, GTK_SHRINK, 0, 0); gtk_widget_show (shiftbuttons); } edgebuttons = create_edge_buttons (); gtk_table_attach (GTK_TABLE (top_table), edgebuttons, 177, 178, 0, 1, GTK_FILL, GTK_SHRINK, 0, 0); gtk_widget_show (edgebuttons); dummy2=gtk_label_new(""); gtk_table_attach (GTK_TABLE (top_table), dummy2, 178, 215, 0, 1, GTK_FILL, GTK_SHRINK, 0, 0); gtk_widget_show (dummy2); entry = create_entry_box(); gtk_table_attach (GTK_TABLE (top_table), entry, 215, 216, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0); gtk_widget_show(entry); timebox = create_time_box(); gtk_table_attach (GTK_TABLE (top_table), timebox, 216, 284, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 20, 0); gtk_widget_show (timebox); if((GLOBALS->loaded_file_type != DUMPLESS_FILE)&&(!GLOBALS->disable_menus)) { GtkWidget *r_pixmap = gtk_pixmap_new(GLOBALS->redo_pixmap, GLOBALS->redo_mask); GtkWidget *main_vbox1; GtkWidget *table, *table2; GtkWidget *b1, *frame; GtkTooltips *tooltips; gtk_widget_show(r_pixmap); tooltips=gtk_tooltips_new_2(); gtk_tooltips_set_delay_2(tooltips,1500); table = gtk_table_new (1, 1, FALSE); main_vbox1 = gtk_vbox_new (FALSE, 1); gtk_container_border_width (GTK_CONTAINER (main_vbox1), 1); gtk_container_add (GTK_CONTAINER (table), main_vbox1); frame = gtk_frame_new ("Reload "); gtk_box_pack_start (GTK_BOX (main_vbox1), frame, TRUE, TRUE, 0); gtk_widget_show (frame); gtk_widget_show (main_vbox1); table2 = gtk_table_new (2, 1, FALSE); b1 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b1), r_pixmap); gtk_table_attach (GTK_TABLE (table2), b1, 0, 1, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); gtk_signal_connect_object (GTK_OBJECT (b1), "clicked", GTK_SIGNAL_FUNC(menu_reload_waveform_marshal), GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(tooltips, b1, "Reload waveform", NULL); gtk_widget_show(b1); gtk_container_add (GTK_CONTAINER (frame), table2); gtk_widget_show(table2); gtk_table_attach (GTK_TABLE (top_table), table, 284, 285, 0, 1, 0, 0, 2, 0); gtk_widget_show (table); } } /* of ...if(mainwindow_already_built) */ } GLOBALS->wavewindow = create_wavewindow(); load_all_fonts(); /* must be done before create_signalwindow() */ gtk_widget_show(GLOBALS->wavewindow); GLOBALS->signalwindow = create_signalwindow(); if(GLOBALS->do_resize_signals) { int os; if(GLOBALS->initial_signal_window_width > GLOBALS->max_signal_name_pixel_width) { os=GLOBALS->initial_signal_window_width; } else { os=GLOBALS->max_signal_name_pixel_width; } os=(os<48)?48:os; gtk_widget_set_usize(GTK_WIDGET(GLOBALS->signalwindow), os+30, -1); } else { if(GLOBALS->initial_signal_window_width) { int os; os=GLOBALS->initial_signal_window_width; os=(os<48)?48:os; gtk_widget_set_usize(GTK_WIDGET(GLOBALS->signalwindow), os+30, -1); } } gtk_widget_show(GLOBALS->signalwindow); #if GTK_CHECK_VERSION(2,4,0) if((!GLOBALS->hide_sst)&&(GLOBALS->loaded_file_type != MISSING_FILE)) { GLOBALS->toppanedwindow = gtk_hpaned_new(); GLOBALS->sstpane = treeboxframe("SST", GTK_SIGNAL_FUNC(mkmenu_treesearch_cleanup)); GLOBALS->expanderwindow = gtk_expander_new_with_mnemonic("_SST"); gtk_expander_set_expanded(GTK_EXPANDER(GLOBALS->expanderwindow), (GLOBALS->sst_expanded==TRUE)); if(GLOBALS->toppanedwindow_size_cache) { gtk_paned_set_position(GTK_PANED(GLOBALS->toppanedwindow), GLOBALS->toppanedwindow_size_cache); GLOBALS->toppanedwindow_size_cache = 0; } gtk_container_add(GTK_CONTAINER(GLOBALS->expanderwindow), GLOBALS->sstpane); gtk_widget_show(GLOBALS->expanderwindow); } #endif GLOBALS->panedwindow = panedwindow = gtk_hpaned_new(); if(GLOBALS->panedwindow_size_cache) { gtk_paned_set_position(GTK_PANED(GLOBALS->panedwindow), GLOBALS->panedwindow_size_cache); GLOBALS->panedwindow_size_cache = 0; } #ifdef HAVE_PANED_PACK if(GLOBALS->paned_pack_semantics) { gtk_paned_pack1(GTK_PANED(panedwindow), GLOBALS->signalwindow, 0, 0); gtk_paned_pack2(GTK_PANED(panedwindow), GLOBALS->wavewindow, ~0, 0); } else #endif { gtk_paned_add1(GTK_PANED(panedwindow), GLOBALS->signalwindow); gtk_paned_add2(GTK_PANED(panedwindow), GLOBALS->wavewindow); } gtk_widget_show(panedwindow); if(GLOBALS->dnd_sigview) { dnd_setup(GLOBALS->dnd_sigview, GLOBALS->signalarea, 1); } else { dnd_setup(NULL, GLOBALS->signalarea, 1); } /* dnd_setup(GLOBALS->signalarea, GLOBALS->signalarea); */ dnd_setup(GLOBALS->signalarea, GLOBALS->wavearea, 1); #if GTK_CHECK_VERSION(2,4,0) if((!GLOBALS->hide_sst)&&(GLOBALS->loaded_file_type != MISSING_FILE)) { gtk_paned_pack1(GTK_PANED(GLOBALS->toppanedwindow), GLOBALS->expanderwindow, 0, 0); gtk_paned_pack2(GTK_PANED(GLOBALS->toppanedwindow), panedwindow, ~0, 0); gtk_widget_show(GLOBALS->toppanedwindow); } #endif #if WAVE_USE_GTK2 if(GLOBALS->treeopen_chain_head) { struct string_chain_t *t = GLOBALS->treeopen_chain_head; struct string_chain_t *t2; while(t) { if(GLOBALS->ctree_main) { force_open_tree_node(t->str, 0, NULL); } t2 = t->next; if(t->str) free_2(t->str); free_2(t); t = t2; } GLOBALS->treeopen_chain_head = GLOBALS->treeopen_chain_curr = NULL; } #endif if(!mainwindow_already_built) { gtk_widget_show(top_table); gtk_table_attach (GTK_TABLE (whole_table), GLOBALS->force_toolbars?toolhandle:top_table, 0, 16, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0); } if(!GLOBALS->notebook) { GLOBALS->num_notebook_pages = 1; GLOBALS->this_context_page = 0; GLOBALS->contexts = calloc(1, sizeof(struct Global **)); /* calloc is deliberate! */ /* scan-build */ *GLOBALS->contexts = calloc(1, sizeof(struct Global *)); /* calloc is deliberate! */ /* scan-build */ (*GLOBALS->contexts)[0] = GLOBALS; GLOBALS->dead_context = calloc(1, sizeof(struct Global **)); /* calloc is deliberate! */ /* scan-build */ *GLOBALS->dead_context = calloc(1, sizeof(struct Global *)); /* calloc is deliberate! */ /* scan-build */ *(GLOBALS->dead_context)[0] = NULL; GLOBALS->notebook = gtk_notebook_new(); gtk_notebook_set_tab_pos(GTK_NOTEBOOK(GLOBALS->notebook), GLOBALS->context_tabposition ? GTK_POS_LEFT : GTK_POS_TOP); gtk_widget_show(GLOBALS->notebook); gtk_notebook_set_show_tabs(GTK_NOTEBOOK(GLOBALS->notebook), 0); /* hide for first time until next tabs */ gtk_notebook_set_show_border(GTK_NOTEBOOK(GLOBALS->notebook), 0); /* hide for first time until next tabs */ gtk_signal_connect(GTK_OBJECT(GLOBALS->notebook), "switch-page", GTK_SIGNAL_FUNC(switch_page), NULL); } else { unsigned int ix; GLOBALS->this_context_page = GLOBALS->num_notebook_pages; GLOBALS->num_notebook_pages++; GLOBALS->num_notebook_pages_cumulative++; /* this never decreases, acts as an incrementing flipper id for side tabs */ *GLOBALS->contexts = realloc(*GLOBALS->contexts, GLOBALS->num_notebook_pages * sizeof(struct Global *)); /* realloc is deliberate! */ /* scan-build */ (*GLOBALS->contexts)[GLOBALS->this_context_page] = GLOBALS; for(ix=0;ixnum_notebook_pages;ix++) { (*GLOBALS->contexts)[ix]->num_notebook_pages = GLOBALS->num_notebook_pages; (*GLOBALS->contexts)[ix]->num_notebook_pages_cumulative = GLOBALS->num_notebook_pages_cumulative; (*GLOBALS->contexts)[ix]->dead_context = (*GLOBALS->contexts)[0]->dead_context; /* mirroring this is OK as page 0 always has value! */ } gtk_notebook_set_show_tabs(GTK_NOTEBOOK(GLOBALS->notebook), ~0); /* then appear */ gtk_notebook_set_show_border(GTK_NOTEBOOK(GLOBALS->notebook), ~0); /* then appear */ gtk_notebook_set_scrollable(GTK_NOTEBOOK(GLOBALS->notebook), ~0); } if(!GLOBALS->context_tabposition) { gtk_notebook_append_page(GTK_NOTEBOOK(GLOBALS->notebook), GLOBALS->toppanedwindow ? GLOBALS->toppanedwindow : panedwindow, gtk_label_new(GLOBALS->loaded_file_name)); } else { char buf[40]; sprintf(buf, "%d", GLOBALS->num_notebook_pages_cumulative); gtk_notebook_append_page(GTK_NOTEBOOK(GLOBALS->notebook), GLOBALS->toppanedwindow ? GLOBALS->toppanedwindow : panedwindow, gtk_label_new(buf)); } if(mainwindow_already_built) { gtk_notebook_set_current_page(GTK_NOTEBOOK(GLOBALS->notebook), GLOBALS->this_context_page); return(0); } gtk_table_attach (GTK_TABLE (whole_table), GLOBALS->notebook, 0, 16, 1, 256, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0); gtk_widget_show(whole_table); gtk_container_add (GTK_CONTAINER (main_vbox), whole_table); if(GLOBALS->tims.marker != -1) { if(GLOBALS->tims.markertims.first) GLOBALS->tims.marker=GLOBALS->tims.first; } update_markertime(GLOBALS->tims.marker); set_window_xypos(GLOBALS->initial_window_xpos, GLOBALS->initial_window_ypos); GLOBALS->xy_ignore_main_c_1 = 1; if(GLOBALS->logfile) { struct logfile_chain *lprev; char buf[50]; int which = 1; while(GLOBALS->logfile) { sprintf(buf, "Logfile viewer [%d]", which++); logbox(buf, 480, GLOBALS->logfile->name); lprev = GLOBALS->logfile; GLOBALS->logfile = GLOBALS->logfile->next; free_2(lprev->name); free_2(lprev); } } activate_stems_reader(GLOBALS->stems_name); gtk_events_pending_gtk_main_iteration(); if(1) /* here in order to calculate window manager delta if present... window is completely rendered by here */ { int dummy_x, dummy_y; get_window_xypos(&dummy_x, &dummy_y); } init_busy(); if(scriptfile) { execute_script(scriptfile, 1); /* deallocate the name in the script because context might swap out from under us! */ scriptfile=NULL; } #ifdef WAVE_HAVE_GCONF if(GLOBALS->loaded_file_type != MISSING_FILE) { if(!chdir_cache) { wave_gconf_client_set_string("/current/pwd", getenv("PWD")); } wave_gconf_client_set_string("/current/dumpfile", GLOBALS->optimize_vcd ? GLOBALS->unoptimized_vcd_file_name : GLOBALS->loaded_file_name); wave_gconf_client_set_string("/current/optimized_vcd", GLOBALS->optimize_vcd ? "1" : "0"); wave_gconf_client_set_string("/current/savefile", GLOBALS->filesel_writesave); } #endif #if !defined _MSC_VER if(GLOBALS->dual_attach_id_main_c_1) { fprintf(stderr, "GTKWAVE | Attaching %08X as dual head session %d\n", GLOBALS->dual_attach_id_main_c_1, GLOBALS->dual_id); #ifdef __MINGW32__ { HANDLE hMapFile; char mapName[257]; sprintf(mapName, "twinwave%d", GLOBALS->dual_attach_id_main_c_1); hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, mapName); if(hMapFile == NULL) { fprintf(stderr, "Could not attach shared memory map name '%s', exiting.\n", mapName); exit(255); } GLOBALS->dual_ctx = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 2 * sizeof(struct gtkwave_dual_ipc_t)); if(GLOBALS->dual_ctx == NULL) { fprintf(stderr, "Could not map view of file '%s', exiting.\n", mapName); exit(255); } } #else GLOBALS->dual_ctx = shmat(GLOBALS->dual_attach_id_main_c_1, NULL, 0); #endif if(GLOBALS->dual_ctx) { if(memcmp(GLOBALS->dual_ctx[GLOBALS->dual_id].matchword, DUAL_MATCHWORD, 4)) { fprintf(stderr, "Not a valid shared memory ID for dual head operation, exiting.\n"); exit(255); } GLOBALS->dual_ctx[GLOBALS->dual_id].viewer_is_initialized = 1; for(;;) { GtkAdjustment *hadj; TimeType pageinc, gt; #ifndef __MINGW32__ struct timeval tv; #endif if(GLOBALS->dual_ctx[1-GLOBALS->dual_id].use_new_times) { GLOBALS->dual_race_lock = 1; gt = GLOBALS->dual_ctx[GLOBALS->dual_id].left_margin_time = GLOBALS->dual_ctx[1-GLOBALS->dual_id].left_margin_time; GLOBALS->dual_ctx[GLOBALS->dual_id].marker = GLOBALS->dual_ctx[1-GLOBALS->dual_id].marker; GLOBALS->dual_ctx[GLOBALS->dual_id].baseline = GLOBALS->dual_ctx[1-GLOBALS->dual_id].baseline; GLOBALS->dual_ctx[GLOBALS->dual_id].zoom = GLOBALS->dual_ctx[1-GLOBALS->dual_id].zoom; GLOBALS->dual_ctx[1-GLOBALS->dual_id].use_new_times = 0; GLOBALS->dual_ctx[GLOBALS->dual_id].use_new_times = 0; if(GLOBALS->dual_ctx[GLOBALS->dual_id].baseline != GLOBALS->tims.baseline) { if((GLOBALS->tims.marker != -1) && (GLOBALS->dual_ctx[GLOBALS->dual_id].marker == -1)) { Trptr t; for(t=GLOBALS->traces.first;t;t=t->t_next) { if(t->asciivalue) { free_2(t->asciivalue); t->asciivalue=NULL; } } for(t=GLOBALS->traces.buffer;t;t=t->t_next) { if(t->asciivalue) { free_2(t->asciivalue); t->asciivalue=NULL; } } } GLOBALS->tims.marker = GLOBALS->dual_ctx[GLOBALS->dual_id].marker; GLOBALS->tims.baseline = GLOBALS->dual_ctx[GLOBALS->dual_id].baseline; update_basetime(GLOBALS->tims.baseline); update_markertime(GLOBALS->tims.marker); GLOBALS->signalwindow_width_dirty = 1; button_press_release_common(); } else if(GLOBALS->dual_ctx[GLOBALS->dual_id].marker != GLOBALS->tims.marker) { if((GLOBALS->tims.marker != -1) && (GLOBALS->dual_ctx[GLOBALS->dual_id].marker == -1)) { Trptr t; for(t=GLOBALS->traces.first;t;t=t->t_next) { if(t->asciivalue) { free_2(t->asciivalue); t->asciivalue=NULL; } } for(t=GLOBALS->traces.buffer;t;t=t->t_next) { if(t->asciivalue) { free_2(t->asciivalue); t->asciivalue=NULL; } } } GLOBALS->tims.marker = GLOBALS->dual_ctx[GLOBALS->dual_id].marker; update_markertime(GLOBALS->tims.marker); GLOBALS->signalwindow_width_dirty = 1; button_press_release_common(); } GLOBALS->tims.prevzoom=GLOBALS->tims.zoom; GLOBALS->tims.zoom=GLOBALS->dual_ctx[GLOBALS->dual_id].zoom; if(gttims.first) gt=GLOBALS->tims.first; else if(gt>GLOBALS->tims.last) gt=GLOBALS->tims.last; hadj=GTK_ADJUSTMENT(GLOBALS->wave_hslider); hadj->value=gt; pageinc=(TimeType)(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx); if(gt<(GLOBALS->tims.last-pageinc+1)) GLOBALS->tims.timecache=gt; else { GLOBALS->tims.timecache=GLOBALS->tims.last-pageinc+1; if(GLOBALS->tims.timecachetims.first) GLOBALS->tims.timecache=GLOBALS->tims.first; } time_update(); } if(is_interactive) { kick_partial_vcd(); } else { while (gtk_events_pending()) gtk_main_iteration(); } GLOBALS->dual_race_lock = 0; #ifdef __MINGW32__ Sleep(1000 / 25); #else tv.tv_sec = 0; tv.tv_usec = 1000000 / 25; select(0, NULL, NULL, NULL, &tv); #endif } } else { fprintf(stderr, "Could not attach to %08X, exiting.\n", GLOBALS->dual_attach_id_main_c_1); exit(255); } } else #endif if(is_interactive) { for(;;) { kick_partial_vcd(); } } else { #if defined(HAVE_LIBTCL) if(is_wish) { char* argv_mod[1]; set_globals_interp(argv[0], 1); addPidToExecutableName(1, argv, argv_mod); Tk_MainEx(1, argv_mod, gtkwaveInterpreterInit, GLOBALS->interp); /* note: for(kk=0;kkmainwindow), x, y); #else *x = GLOBALS->initial_window_x; *y = GLOBALS->initial_window_y; #endif } void set_window_size (int x, int y) { if(GLOBALS->block_xy_update) { return; } if (GLOBALS->mainwindow == NULL) { GLOBALS->initial_window_width = x; GLOBALS->initial_window_height = y; } else { #ifdef WAVE_USE_XID if(!GLOBALS->socket_xid) #endif { #ifdef MAC_INTEGRATION gtk_window_resize(GTK_WINDOW (GLOBALS->mainwindow), x, y); #else gtk_window_set_default_size(GTK_WINDOW (GLOBALS->mainwindow), x, y); #endif } } } void get_window_xypos(int *root_x, int *root_y) { if(!GLOBALS->mainwindow) return; #ifdef WAVE_USE_GTK2 gtk_window_get_position(GTK_WINDOW(GLOBALS->mainwindow), root_x, root_y); if(!GLOBALS->initial_window_get_valid) { if((GLOBALS->mainwindow->window)) { GLOBALS->initial_window_get_valid = 1; GLOBALS->initial_window_xpos_get = *root_x; GLOBALS->initial_window_ypos_get = *root_y; GLOBALS->xpos_delta = GLOBALS->initial_window_xpos_set - GLOBALS->initial_window_xpos_get; GLOBALS->ypos_delta = GLOBALS->initial_window_ypos_set - GLOBALS->initial_window_ypos_get; } } #else *root_x = *root_y = -1; #endif } void set_window_xypos(int root_x, int root_y) { #ifdef MAC_INTEGRATION if(GLOBALS->num_notebook_pages > 1) return; #else if(GLOBALS->xy_ignore_main_c_1) return; #endif #if !defined __MINGW32__ && !defined _MSC_VER GLOBALS->initial_window_xpos = root_x; GLOBALS->initial_window_ypos = root_y; if(!GLOBALS->mainwindow) return; if((GLOBALS->initial_window_xpos>=0)||(GLOBALS->initial_window_ypos>=0)) { if (GLOBALS->initial_window_xpos<0) { GLOBALS->initial_window_xpos = 0; } if (GLOBALS->initial_window_ypos<0) { GLOBALS->initial_window_ypos = 0; } #ifdef WAVE_USE_GTK2 gtk_window_move(GTK_WINDOW(GLOBALS->mainwindow), GLOBALS->initial_window_xpos, GLOBALS->initial_window_ypos); #else gtk_window_reposition(GTK_WINDOW(GLOBALS->mainwindow), GLOBALS->initial_window_xpos, GLOBALS->initial_window_ypos); #endif if(!GLOBALS->initial_window_set_valid) { GLOBALS->initial_window_set_valid = 1; GLOBALS->initial_window_xpos_set = GLOBALS->initial_window_xpos; GLOBALS->initial_window_ypos_set = GLOBALS->initial_window_ypos; } } #endif } /* * bring up stems browser */ #if !defined _MSC_VER int stems_are_active(void) { #ifdef __MINGW32__ if(GLOBALS->anno_ctx && GLOBALS->anno_ctx->browser_process) { /* nothing */ return(1); } #else if(GLOBALS->anno_ctx && GLOBALS->anno_ctx->browser_process) { int mystat =0; pid_t pid = waitpid(GLOBALS->anno_ctx->browser_process, &mystat, WNOHANG); if(!pid) { status_text("Stems reader already active.\n"); return(1); } else { shmdt((void *)GLOBALS->anno_ctx); GLOBALS->anno_ctx = NULL; } } #endif return(0); } #endif void activate_stems_reader(char *stems_name) { #if !defined _MSC_VER #ifdef __CYGWIN__ /* ajb : ok static as this is a one-time warning message... */ static int cyg_called = 0; #endif if(!stems_name) return; #ifdef __CYGWIN__ if(GLOBALS->stems_type != WAVE_ANNO_NONE) { if(!cyg_called) { char *cygserver_env = getenv("CYGWIN"); gboolean found = cygserver_env && (strstr(cygserver_env, "server") != NULL); if(!found) { fprintf(stderr, "GTKWAVE | =================================================================\n"); fprintf(stderr, "GTKWAVE | If the viewer crashes with a Bad system call error,\n"); fprintf(stderr, "GTKWAVE | make sure that Cygserver is enabled.\n"); fprintf(stderr, "GTKWAVE | The Cygserver services are used by Cygwin applications only\n"); fprintf(stderr, "GTKWAVE | if you set the environment variable CYGWIN to contain the\n"); fprintf(stderr, "GTKWAVE | string \"server\". You must do this before starting this program.\n"); fprintf(stderr, "GTKWAVE |\n"); fprintf(stderr, "GTKWAVE | If this still does not work, you may have to enable the cygserver\n"); fprintf(stderr, "GTKWAVE | by entering \"cygserver-config\" and answering \"yes\" followed by\n"); fprintf(stderr, "GTKWAVE | \"net start cygserver\".\n"); fprintf(stderr, "GTKWAVE | =================================================================\n"); } cyg_called = 1; } } #endif if(GLOBALS->stems_type != WAVE_ANNO_NONE) { #ifdef __MINGW32__ int shmid = getpid(); char mapName[257]; HANDLE hMapFile; STARTUPINFO si; PROCESS_INFORMATION pi; BOOL rc; memset(&si, 0, sizeof(STARTUPINFO)); memset(&pi, 0, sizeof(PROCESS_INFORMATION)); si.cb = sizeof(si); sprintf(mapName, "rtlbrowse%d", shmid); hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(struct gtkwave_annotate_ipc_t), mapName); if(hMapFile != NULL) { GLOBALS->anno_ctx = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(struct gtkwave_annotate_ipc_t)); if(GLOBALS->anno_ctx) { char mylist[257]; sprintf(mylist, "rtlbrowse.exe %08x", shmid); memset(GLOBALS->anno_ctx, 0, sizeof(struct gtkwave_annotate_ipc_t)); memcpy(GLOBALS->anno_ctx->matchword, WAVE_MATCHWORD, 4); GLOBALS->anno_ctx->aet_type = GLOBALS->stems_type; strcpy(GLOBALS->anno_ctx->aet_name, GLOBALS->aet_name); strcpy(GLOBALS->anno_ctx->stems_name, stems_name); update_markertime(GLOBALS->tims.marker); rc = CreateProcess( "rtlbrowse.exe", mylist, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); if(!rc) { UnmapViewOfFile(GLOBALS->anno_ctx); CloseHandle(hMapFile); GLOBALS->anno_ctx = NULL; GLOBALS->stems_type = WAVE_ANNO_NONE; } else { GLOBALS->anno_ctx->browser_process = pi.hProcess; } } else { CloseHandle(hMapFile); GLOBALS->stems_type = WAVE_ANNO_NONE; } } #else int shmid = shmget(0, sizeof(struct gtkwave_annotate_ipc_t), IPC_CREAT | 0600 ); if(shmid >=0) { struct shmid_ds ds; GLOBALS->anno_ctx = shmat(shmid, NULL, 0); if(GLOBALS->anno_ctx) { pid_t pid; memset(GLOBALS->anno_ctx, 0, sizeof(struct gtkwave_annotate_ipc_t)); memcpy(GLOBALS->anno_ctx->matchword, WAVE_MATCHWORD, 4); GLOBALS->anno_ctx->aet_type = GLOBALS->stems_type; strcpy(GLOBALS->anno_ctx->aet_name, GLOBALS->aet_name); strcpy(GLOBALS->anno_ctx->stems_name, stems_name); GLOBALS->anno_ctx->gtkwave_process = getpid(); update_markertime(GLOBALS->tims.marker); #ifdef __linux__ shmctl(shmid, IPC_RMID, &ds); /* mark for destroy */ #endif pid=fork(); if(((int)pid) < 0) { /* can't do anything about this */ } else { if(pid) /* parent==original server_pid */ { #ifndef __CYGWIN__ static int kill_installed = 0; if(!kill_installed) { kill_installed = 1; atexit(kill_stems_browser); } #endif GLOBALS->anno_ctx->browser_process = pid; #ifndef __linux__ sleep(2); shmctl(shmid, IPC_RMID, &ds); /* mark for destroy */ #endif } else { char buf[64]; #ifdef MAC_INTEGRATION const gchar *p = gtkosx_application_get_executable_path(); #endif sprintf(buf, "%08x", shmid); #ifdef MAC_INTEGRATION if(p && strstr(p, "Contents/")) { const char *xec = "../Resources/bin/rtlbrowse"; char *res = strdup_2(p); char *slsh = strrchr(res, '/'); if(slsh) { *(slsh+1) = 0; res = realloc_2(res, strlen(res) + strlen(xec) + 1); strcat(res, xec); execlp(res, "rtlbrowse", buf, NULL); fprintf(stderr, "GTKWAVE | Could not find '%s' in .app!\n", res); free_2(res); } } #endif execlp("rtlbrowse", "rtlbrowse", buf, NULL); fprintf(stderr, "GTKWAVE | Could not find rtlbrowse executable, exiting!\n"); exit(255); /* control never gets here if successful */ } } } else { shmctl(shmid, IPC_RMID, &ds); /* actually destroy */ GLOBALS->stems_type = WAVE_ANNO_NONE; } } #endif } else { fprintf(stderr, "GTKWAVE | Unsupported dumpfile type for rtlbrowse.\n"); } #endif } #if !defined _MSC_VER && !defined __MINGW32__ void optimize_vcd_file(void) { if(!strcmp("-vcd", GLOBALS->unoptimized_vcd_file_name)) { #ifdef __CYGWIN__ char *buf = strdup_2("vcd2fst -- - vcd.fst"); system(buf); free_2(buf); GLOBALS->loaded_file_name = strdup_2("vcd.fst"); GLOBALS->is_optimized_stdin_vcd = 1; #else pid_t pid; char *buf = malloc_2(strlen("vcd") + 4 + 1); sprintf(buf, "%s.fst", "vcd"); pid = fork(); if(((int)pid) < 0) { /* can't do anything about this */ } else { if(pid) { int mystat; int rc = waitpid(pid, &mystat, 0); if(rc > 0) { free_2(GLOBALS->loaded_file_name); GLOBALS->loaded_file_name = buf; GLOBALS->is_optimized_stdin_vcd = 1; } } else { execlp("vcd2fst", "vcd2fst", "--", "-", buf, NULL); exit(255); } } #endif } else { #ifdef __CYGWIN__ char *buf = malloc_2(9 + (strlen(GLOBALS->unoptimized_vcd_file_name) + 1) + (strlen(GLOBALS->unoptimized_vcd_file_name) + 4 + 1)); sprintf(buf, "vcd2fst %s %s.fst", GLOBALS->unoptimized_vcd_file_name, GLOBALS->unoptimized_vcd_file_name); system(buf); free_2(buf); buf = malloc_2(strlen(GLOBALS->unoptimized_vcd_file_name) + 4 + 1); sprintf(buf, "%s.fst", GLOBALS->unoptimized_vcd_file_name); GLOBALS->loaded_file_name = buf; #else pid_t pid; char *buf = malloc_2(strlen(GLOBALS->unoptimized_vcd_file_name) + 4 + 1); sprintf(buf, "%s.fst", GLOBALS->unoptimized_vcd_file_name); pid = fork(); if(((int)pid) < 0) { /* can't do anything about this */ } else { if(pid) { int mystat; int rc = waitpid(pid, &mystat, 0); if(rc > 0) { free_2(GLOBALS->loaded_file_name); GLOBALS->loaded_file_name = buf; } } else { #ifdef MAC_INTEGRATION const gchar *p = gtkosx_application_get_executable_path(); if(p && strstr(p, "Contents/")) { const char *xec = "../Resources/bin/vcd2fst"; char *res = strdup_2(p); char *slsh = strrchr(res, '/'); if(slsh) { *(slsh+1) = 0; res = realloc_2(res, strlen(res) + strlen(xec) + 1); strcat(res, xec); execlp(res, "vcd2fst", GLOBALS->unoptimized_vcd_file_name, buf, NULL); fprintf(stderr, "GTKWAVE | Could not find '%s' in .app!\n", res); free_2(res); } } #endif execlp("vcd2fst", "vcd2fst", GLOBALS->unoptimized_vcd_file_name, buf, NULL); fprintf(stderr, "GTKWAVE | Could not find vcd2fst executable, exiting!\n"); exit(255); } } #endif } } #endif gtkwave-3.3.66/src/vcd.h0000664000076400007640000000610012341266475014322 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2010. * * 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. */ #include "globals.h" #ifndef VCD_H #define VCD_H #include #include #ifndef _MSC_VER #include #endif #ifndef HAVE_FSEEKO #define fseeko fseek #define ftello ftell #endif #include #include #ifdef HAVE_SYS_STAT_H #include #endif #include #include #include "symbol.h" #include "wavealloca.h" #include "debug.h" #include "tree.h" #define VCD_SIZE_WARN (256) /* number of MB size where converter warning message appears */ #define VCD_BSIZ 32768 /* size of getch() emulation buffer--this val should be ok */ #define VCD_INDEXSIZ (8 * 1024 * 1024) #define vcd_exit(x) \ if(GLOBALS->vcd_jmp_buf) \ { \ splash_finalize(); \ longjmp(*(GLOBALS->vcd_jmp_buf), x); \ } \ else \ { \ exit(x); \ } enum VCDName_ByteSubstitutions { VCDNAM_NULL=0, #ifdef WAVE_HIERFIX VCDNAM_HIERSORT, #endif VCDNAM_ESCAPE }; /* fix for contrib/rtlbrowse */ #ifndef VLEX_DEFINES_H enum VarTypes { V_EVENT, V_PARAMETER, V_INTEGER, V_REAL, V_REAL_PARAMETER=V_REAL, V_REALTIME=V_REAL, V_SHORTREAL=V_REAL, V_REG, V_SUPPLY0, V_SUPPLY1, V_TIME, V_TRI, V_TRIAND, V_TRIOR, V_TRIREG, V_TRI0, V_TRI1, V_WAND, V_WIRE, V_WOR, V_PORT, V_IN=V_PORT, V_OUT=V_PORT, V_INOUT=V_PORT, V_BIT, V_LOGIC, V_INT, V_SHORTINT, V_LONGINT, V_BYTE, V_ENUM, V_STRINGTYPE, V_END, V_LB, V_COLON, V_RB, V_STRING }; #endif /* for vcd_recoder.c */ enum FastloadState { VCD_FSL_NONE, VCD_FSL_WRITE, VCD_FSL_READ }; TimeType vcd_main(char *fname); TimeType vcd_recoder_main(char *fname); TimeType vcd_partial_main(char *fname); void vcd_partial_mark_and_sweep(int mandclear); void kick_partial_vcd(void); struct sym_chain { struct sym_chain *next; struct symbol *val; }; struct slist { struct slist *next; char *str; struct tree *mod_tree_parent; int len; }; #ifdef WAVE_USE_STRUCT_PACKING #pragma pack(push) #pragma pack(1) #endif struct vcdsymbol { struct vcdsymbol *root, *chain; struct symbol *sym_chain; struct vcdsymbol *next; char *name; char *id; char *value; struct Node **narray; hptr *tr_array; /* points to synthesized trailers (which can move) */ hptr *app_array; /* points to hptr to append to (which can move) */ unsigned int nid; int msi, lsi; int size; unsigned char vartype; }; #ifdef WAVE_USE_STRUCT_PACKING #pragma pack(pop) #endif char *build_slisthier(void); void append_vcd_slisthier(char *str); struct HistEnt *histent_calloc(void); void strcpy_vcdalt(char *too, char *from, char delim); int strcpy_delimfix(char *too, char *from); void vcd_sortfacs(void); void set_vcd_vartype(struct vcdsymbol *v, nptr n); void vcd_import_masked(void); void vcd_set_fac_process_mask(nptr np); void import_vcd_trace(nptr np); int vcd_keyword_code(const char *s, unsigned int len); #endif gtkwave-3.3.66/src/fsdb_wrapper_api.cc0000664000076400007640000004466312540444674017233 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2013-2015. * * 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. */ #include #include "fsdb_wrapper_api.h" #ifdef WAVE_FSDB_READER_IS_PRESENT #ifdef NOVAS_FSDB #undef NOVAS_FSDB #endif #include "ffrAPI.h" #include #include #ifdef HAVE_INTTYPES_H #include #endif #define FSDBR_FXT2U64(xt) (((uint64_t)(xt).hltag.H << 32) | ((uint64_t)(xt).hltag.L)) #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif static bool_T __TreeCB(fsdbTreeCBType cb_type, void *client_data, void *tree_cb_data) { return(TRUE); /* currently unused along with var/scope traversal */ } static bool_T __MyTreeCB(fsdbTreeCBType cb_type, void *client_data, void *tree_cb_data); extern "C" void *fsdbReaderOpenFile(char *nam) { fsdbFileType ft; uint_T blk_idx = 0; if(!ffrObject::ffrIsFSDB(nam)) { return(NULL); } ffrFSDBInfo fsdb_info; ffrObject::ffrGetFSDBInfo(nam, fsdb_info); if((fsdb_info.file_type != FSDB_FT_VERILOG) && (fsdb_info.file_type != FSDB_FT_VERILOG_VHDL) && (fsdb_info.file_type != FSDB_FT_VHDL)) { return(NULL); } ffrObject *fsdb_obj = ffrObject::ffrOpen3(nam); if(!fsdb_obj) { return(NULL); } fsdb_obj->ffrSetTreeCBFunc(__TreeCB, NULL); ft = fsdb_obj->ffrGetFileType(); if((ft != FSDB_FT_VERILOG) && (ft != FSDB_FT_VERILOG_VHDL) && (ft != FSDB_FT_VHDL)) { fsdb_obj->ffrClose(); return(NULL); } fsdb_obj->ffrReadDataTypeDefByBlkIdx(blk_idx); /* necessary if FSDB file has transaction data ... we don't process this but it prevents possible crashes */ return((void *)fsdb_obj); } extern "C" void fsdbReaderReadScopeVarTree(void *ctx,void (*cb)(void *)) { ffrObject *fsdb_obj = (ffrObject *)ctx; fsdb_obj->ffrSetTreeCBFunc(__MyTreeCB, (void *) cb); fsdb_obj->ffrReadScopeVarTree(); } extern "C" int fsdbReaderGetMaxVarIdcode(void *ctx) { ffrObject *fsdb_obj = (ffrObject *)ctx; fsdbVarIdcode max_var_idcode = fsdb_obj->ffrGetMaxVarIdcode(); return(max_var_idcode); } extern "C" void fsdbReaderAddToSignalList(void *ctx, int i) { ffrObject *fsdb_obj = (ffrObject *)ctx; fsdb_obj->ffrAddToSignalList(i); } extern "C" void fsdbReaderResetSignalList(void *ctx) { ffrObject *fsdb_obj = (ffrObject *)ctx; fsdb_obj->ffrResetSignalList(); } extern "C" void fsdbReaderLoadSignals(void *ctx) { ffrObject *fsdb_obj = (ffrObject *)ctx; fsdb_obj->ffrLoadSignals(); } extern "C" void *fsdbReaderCreateVCTraverseHandle(void *ctx, int i) { ffrObject *fsdb_obj = (ffrObject *)ctx; ffrVCTrvsHdl hdl = fsdb_obj->ffrCreateVCTraverseHandle(i); return((void *)hdl); } extern "C" int fsdbReaderHasIncoreVC(void *ctx, void *hdl) { ffrObject *fsdb_obj = (ffrObject *)ctx; ffrVCTrvsHdl fsdb_hdl = (ffrVCTrvsHdl)hdl; return(fsdb_hdl->ffrHasIncoreVC() == TRUE); } extern "C" void fsdbReaderFree(void *ctx, void *hdl) { ffrObject *fsdb_obj = (ffrObject *)ctx; ffrVCTrvsHdl fsdb_hdl = (ffrVCTrvsHdl)hdl; fsdb_hdl->ffrFree(); } extern "C" uint64_t fsdbReaderGetMinXTag(void *ctx, void *hdl) { ffrObject *fsdb_obj = (ffrObject *)ctx; ffrVCTrvsHdl fsdb_hdl = (ffrVCTrvsHdl)hdl; fsdbTag64 timetag; fsdb_hdl->ffrGetMinXTag((void*)&timetag); uint64_t rv = (((uint64_t)timetag.H) << 32) | ((uint64_t)timetag.L); return(rv); } extern "C" uint64_t fsdbReaderGetMaxXTag(void *ctx, void *hdl) { ffrObject *fsdb_obj = (ffrObject *)ctx; ffrVCTrvsHdl fsdb_hdl = (ffrVCTrvsHdl)hdl; fsdbTag64 timetag; fsdb_hdl->ffrGetMaxXTag((void*)&timetag); uint64_t rv = (((uint64_t)timetag.H) << 32) | ((uint64_t)timetag.L); return(rv); } extern "C" int fsdbReaderGotoXTag(void *ctx, void *hdl, uint64_t tim) { ffrObject *fsdb_obj = (ffrObject *)ctx; ffrVCTrvsHdl fsdb_hdl = (ffrVCTrvsHdl)hdl; fsdbTag64 timetag; timetag.H = (uint32_t)(tim >> 32); timetag.L = (uint32_t)(tim & 0xFFFFFFFFUL); return(fsdb_hdl->ffrGotoXTag((void*)&timetag) == FSDB_RC_SUCCESS); } extern "C" uint64_t fsdbReaderGetXTag(void *ctx, void *hdl, int *rc) { ffrObject *fsdb_obj = (ffrObject *)ctx; ffrVCTrvsHdl fsdb_hdl = (ffrVCTrvsHdl)hdl; fsdbTag64 timetag; *rc = (fsdb_hdl->ffrGetXTag((void*)&timetag) == FSDB_RC_SUCCESS); uint64_t rv = (((uint64_t)timetag.H) << 32) | ((uint64_t)timetag.L); return(rv); } extern "C" int fsdbReaderGetVC(void *ctx, void *hdl, void **val_ptr) { ffrObject *fsdb_obj = (ffrObject *)ctx; ffrVCTrvsHdl fsdb_hdl = (ffrVCTrvsHdl)hdl; return(fsdb_hdl->ffrGetVC((byte_T**)val_ptr) == FSDB_RC_SUCCESS); } extern "C" int fsdbReaderGotoNextVC(void *ctx, void *hdl) { ffrObject *fsdb_obj = (ffrObject *)ctx; ffrVCTrvsHdl fsdb_hdl = (ffrVCTrvsHdl)hdl; return(fsdb_hdl->ffrGotoNextVC() == FSDB_RC_SUCCESS); } extern "C" void fsdbReaderUnloadSignals(void *ctx) { ffrObject *fsdb_obj = (ffrObject *)ctx; fsdb_obj->ffrUnloadSignals(); } extern "C" void fsdbReaderClose(void *ctx) { ffrObject *fsdb_obj = (ffrObject *)ctx; fsdb_obj->ffrClose(); } extern "C" int fsdbReaderGetBytesPerBit(void *hdl) { ffrVCTrvsHdl fsdb_hdl = (ffrVCTrvsHdl)hdl; return(fsdb_hdl->ffrGetBytesPerBit()); } extern "C" int fsdbReaderGetBitSize(void *hdl) { ffrVCTrvsHdl fsdb_hdl = (ffrVCTrvsHdl)hdl; return(fsdb_hdl->ffrGetBitSize()); } extern "C" int fsdbReaderGetVarType(void *hdl) { ffrVCTrvsHdl fsdb_hdl = (ffrVCTrvsHdl)hdl; return(fsdb_hdl->ffrGetVarType()); } extern "C" char *fsdbReaderTranslateVC(void *hdl, void *val_ptr) { ffrVCTrvsHdl vc_trvs_hdl = (ffrVCTrvsHdl)hdl; byte_T *vc_ptr = (byte_T *)val_ptr; static byte_T buffer[FSDB_MAX_BIT_SIZE+1]; uint_T i; fsdbVarType var_type; switch (vc_trvs_hdl->ffrGetBytesPerBit()) { case FSDB_BYTES_PER_BIT_1B: for (i = 0; i < vc_trvs_hdl->ffrGetBitSize(); i++) { switch(vc_ptr[i]) { case FSDB_BT_VCD_0: buffer[i] = '0'; break; case FSDB_BT_VCD_1: buffer[i] = '1'; break; case FSDB_BT_VCD_Z: buffer[i] = 'z'; break; case FSDB_BT_VCD_X: default: buffer[i] = 'x'; break; } } buffer[i] = 0; break; case FSDB_BYTES_PER_BIT_2B: for (i = 0; i < vc_trvs_hdl->ffrGetBitSize(); i++) { switch(vc_ptr[i * 2]) { case FSDB_BT_EVCD_D: case FSDB_BT_EVCD_d: case FSDB_BT_EVCD_L: case FSDB_BT_EVCD_l: case FSDB_BT_EVCD_0: buffer[i] = '0'; break; case FSDB_BT_EVCD_U: case FSDB_BT_EVCD_u: case FSDB_BT_EVCD_H: case FSDB_BT_EVCD_h: case FSDB_BT_EVCD_1: buffer[i] = '1'; break; case FSDB_BT_EVCD_Z: case FSDB_BT_EVCD_T: case FSDB_BT_EVCD_F: case FSDB_BT_EVCD_f: buffer[i] = 'z'; break; case FSDB_BT_EVCD_N: case FSDB_BT_EVCD_X: case FSDB_BT_EVCD_QSTN: case FSDB_BT_EVCD_A: case FSDB_BT_EVCD_a: case FSDB_BT_EVCD_B: case FSDB_BT_EVCD_b: case FSDB_BT_EVCD_C: case FSDB_BT_EVCD_c: default: buffer[i] = 'x'; break; } } buffer[i] = 0; break; case FSDB_BYTES_PER_BIT_4B: var_type = vc_trvs_hdl->ffrGetVarType(); switch(var_type) { case FSDB_VT_VCD_MEMORY_DEPTH: case FSDB_VT_VHDL_MEMORY_DEPTH: buffer[0] = 0; break; default: vc_trvs_hdl->ffrGetVC(&vc_ptr); sprintf((char *)buffer, "%f", *((float*)vc_ptr)); break; } break; case FSDB_BYTES_PER_BIT_8B: sprintf((char *)buffer, "%.16g", *((double*)vc_ptr)); break; default: buffer[0] = 0; break; } return((char *)buffer); } extern "C" int fsdbReaderExtractScaleUnit(void *ctx, int *mult, char *scale) { ffrObject *fsdb_obj = (ffrObject *)ctx; uint_T digit; char *unit; str_T su = fsdb_obj->ffrGetScaleUnit(); fsdbRC rc = fsdb_obj->ffrExtractScaleUnit(su, digit, unit); if(rc == FSDB_RC_SUCCESS) { *mult = digit ? ((int)digit) : 1; /* in case digit is zero */ *scale = unit[0]; } return(rc == FSDB_RC_SUCCESS); } extern "C" int fsdbReaderGetMinFsdbTag64(void *ctx, uint64_t *tim) { ffrObject *fsdb_obj = (ffrObject *)ctx; fsdbTag64 tag64; fsdbRC rc = fsdb_obj->ffrGetMinFsdbTag64(&tag64); if(rc == FSDB_RC_SUCCESS) { *tim = (((uint64_t)tag64.H) << 32) | ((uint64_t)tag64.L); } return(rc == FSDB_RC_SUCCESS); } extern "C" int fsdbReaderGetMaxFsdbTag64(void *ctx, uint64_t *tim) { ffrObject *fsdb_obj = (ffrObject *)ctx; fsdbTag64 tag64; fsdbRC rc = fsdb_obj->ffrGetMaxFsdbTag64(&tag64); if(rc == FSDB_RC_SUCCESS) { *tim = (((uint64_t)tag64.H) << 32) | ((uint64_t)tag64.L); } return(rc == FSDB_RC_SUCCESS); } static bool_T __fsdbReaderGetStatisticsCB(fsdbTreeCBType cb_type, void *client_data, void *tree_cb_data) { struct fsdbReaderGetStatistics_t *gs = (struct fsdbReaderGetStatistics_t *)client_data; switch (cb_type) { case FSDB_TREE_CBT_VAR: gs->varCount++; break; case FSDB_TREE_CBT_STRUCT_BEGIN: case FSDB_TREE_CBT_SCOPE: gs->scopeCount++; break; default: break; } return(TRUE); } extern "C" struct fsdbReaderGetStatistics_t *fsdbReaderGetStatistics(void *ctx) { ffrObject *fsdb_obj = (ffrObject *)ctx; struct fsdbReaderGetStatistics_t *gs = (struct fsdbReaderGetStatistics_t *)calloc(1, sizeof(struct fsdbReaderGetStatistics_t)); fsdb_obj->ffrSetTreeCBFunc(__fsdbReaderGetStatisticsCB, gs); fsdb_obj->ffrReadScopeVarTree(); return(gs); } static void __DumpScope(fsdbTreeCBDataScope* scope, void (*cb)(void *)) { str_T type; char bf[65537]; switch (scope->type) { case FSDB_ST_VCD_MODULE: type = (str_T) "vcd_module"; break; case FSDB_ST_VCD_TASK: type = (str_T) "vcd_task"; break; case FSDB_ST_VCD_FUNCTION: type = (str_T) "vcd_function"; break; case FSDB_ST_VCD_BEGIN: type = (str_T) "vcd_begin"; break; case FSDB_ST_VCD_FORK: type = (str_T) "vcd_fork"; break; case FSDB_ST_VCD_GENERATE: type = (str_T) "vcd_generate"; break; case FSDB_ST_SV_INTERFACE: type = (str_T) "sv_interface"; break; case FSDB_ST_VHDL_ARCHITECTURE: type = (str_T) "vhdl_architecture"; break; case FSDB_ST_VHDL_PROCEDURE: type = (str_T) "vhdl_procedure"; break; case FSDB_ST_VHDL_FUNCTION: type = (str_T) "vhdl_function"; break; case FSDB_ST_VHDL_RECORD: type = (str_T) "vhdl_record"; break; case FSDB_ST_VHDL_PROCESS: type = (str_T) "vhdl_process"; break; case FSDB_ST_VHDL_BLOCK: type = (str_T) "vhdl_block"; break; case FSDB_ST_VHDL_FOR_GENERATE: type = (str_T) "vhdl_for_generate"; break; case FSDB_ST_VHDL_IF_GENERATE: type = (str_T) "vhdl_if_generate"; break; case FSDB_ST_VHDL_GENERATE: type = (str_T) "vhdl_generate"; break; default: type = (str_T) "unknown_scope_type"; break; } sprintf(bf, "Scope: %s %s %s", type, scope->name, scope->module ? scope->module : "NULL"); cb(bf); } static char* itoa_2(int value, char* result) { char* ptr = result, *ptr1 = result, tmp_char; int tmp_value; do { tmp_value = value; value /= 10; *ptr++ = "9876543210123456789" [9 + (tmp_value - value * 10)]; } while ( value ); if (tmp_value < 0) *ptr++ = '-'; result = ptr; *ptr-- = '\0'; while(ptr1 < ptr) { tmp_char = *ptr; *ptr--= *ptr1; *ptr1++ = tmp_char; } return(result); } static void __DumpVar(fsdbTreeCBDataVar *var, void (*cb)(void *)) { str_T type; str_T bpb; str_T direction; char *pnt; int len; int typelen; int dirlen; char bf[65537]; switch(var->bytes_per_bit) { case FSDB_BYTES_PER_BIT_1B: bpb = (str_T) "1B"; break; case FSDB_BYTES_PER_BIT_2B: bpb = (str_T) "2B"; break; case FSDB_BYTES_PER_BIT_4B: bpb = (str_T) "4B"; break; case FSDB_BYTES_PER_BIT_8B: bpb = (str_T) "8B"; break; default: bpb = (str_T) "XB"; break; } switch (var->type) { case FSDB_VT_VCD_EVENT: type = (str_T) "vcd_event"; typelen = 9; break; case FSDB_VT_VCD_INTEGER: type = (str_T) "vcd_integer"; typelen = 11; break; case FSDB_VT_VCD_PARAMETER: type = (str_T) "vcd_parameter"; typelen = 13; break; case FSDB_VT_VCD_REAL: type = (str_T) "vcd_real"; typelen = 8; break; case FSDB_VT_VCD_REG: type = (str_T) "vcd_reg"; typelen = 7; break; case FSDB_VT_VCD_SUPPLY0: type = (str_T) "vcd_supply0"; typelen = 11; break; case FSDB_VT_VCD_SUPPLY1: type = (str_T) "vcd_supply1"; typelen = 11; break; case FSDB_VT_VCD_TIME: type = (str_T) "vcd_time"; typelen = 8; break; case FSDB_VT_VCD_TRI: type = (str_T) "vcd_tri"; typelen = 7; break; case FSDB_VT_VCD_TRIAND: type = (str_T) "vcd_triand"; typelen = 10; break; case FSDB_VT_VCD_TRIOR: type = (str_T) "vcd_trior"; typelen = 9; break; case FSDB_VT_VCD_TRIREG: type = (str_T) "vcd_trireg"; typelen = 10; break; case FSDB_VT_VCD_TRI0: type = (str_T) "vcd_tri0"; typelen = 8; break; case FSDB_VT_VCD_TRI1: type = (str_T) "vcd_tri1"; typelen = 8; break; case FSDB_VT_VCD_WAND: type = (str_T) "vcd_wand"; typelen = 8; break; case FSDB_VT_VCD_WIRE: type = (str_T) "vcd_wire"; typelen = 8; break; case FSDB_VT_VCD_WOR: type = (str_T) "vcd_wor"; typelen = 7; break; case FSDB_VT_VCD_PORT: type = (str_T) "vcd_port"; typelen = 8; break; case FSDB_VT_VHDL_SIGNAL: case FSDB_VT_VHDL_VARIABLE: case FSDB_VT_VHDL_CONSTANT: case FSDB_VT_VHDL_FILE: case FSDB_VT_VCD_MEMORY: case FSDB_VT_VHDL_MEMORY: case FSDB_VT_VCD_MEMORY_DEPTH: case FSDB_VT_VHDL_MEMORY_DEPTH: switch(var->vc_dt) { case FSDB_VC_DT_FLOAT: case FSDB_VC_DT_DOUBLE: type = (str_T) "vcd_real"; typelen = 8; break; case FSDB_VC_DT_UNKNOWN: case FSDB_VC_DT_BYTE: case FSDB_VC_DT_SHORT: case FSDB_VC_DT_INT: case FSDB_VC_DT_LONG: case FSDB_VC_DT_HL_INT: case FSDB_VC_DT_PHYSICAL: default: if(var->type == FSDB_VT_VHDL_SIGNAL) { type = (str_T) "vcd_wire"; typelen = 8; } else { type = (str_T) "vcd_reg"; typelen = 7; } break; } break; case FSDB_VT_STREAM: /* these hold transactions: not yet supported */ type = (str_T) "stream"; typelen = 6; break; default: type = (str_T) "vcd_wire"; typelen = 8; break; } switch(var->direction) { case FSDB_VD_INPUT: direction = (str_T) "input"; dirlen = 5; break; case FSDB_VD_OUTPUT: direction = (str_T) "output"; dirlen = 6; break; case FSDB_VD_INOUT: direction = (str_T) "inout"; dirlen = 5; break; case FSDB_VD_BUFFER: direction = (str_T) "buffer"; dirlen = 6; break; case FSDB_VD_LINKAGE: direction = (str_T) "linkage"; dirlen = 7; break; case FSDB_VD_IMPLICIT: default: direction = (str_T) "implicit"; dirlen = 8; break; } /* sprintf(bf, "Var: %s %s l:%d r:%d %s %d %s %d", type, var->name, var->lbitnum, var->rbitnum, direction, var->u.idcode, bpb, var->dtidcode); */ memcpy(bf, "Var: ", 5); pnt = bf+5; len = typelen; /* strlen(type) */ memcpy(pnt, type, len); pnt += len; *(pnt++) = ' '; len = strlen(var->name); memcpy(pnt, var->name, len); pnt += len; memcpy(pnt, " l:", 3); pnt += 3; pnt = itoa_2(var->lbitnum, pnt); memcpy(pnt, " r:", 3); pnt += 3; pnt = itoa_2(var->rbitnum, pnt); *(pnt++) = ' '; len = dirlen; /* strlen(direction) */ memcpy(pnt, direction, len); pnt += len; *(pnt++) = ' '; pnt = itoa_2(var->u.idcode, pnt); *(pnt++) = ' '; len = 2; /* strlen(bpb) */ memcpy(pnt, bpb, len); pnt += len; *(pnt++) = ' '; pnt = itoa_2(var->dtidcode, pnt); *(pnt) = 0; cb(bf); } static void __DumpStruct(fsdbTreeCBDataStructBegin* str, void (*cb)(void *)) { char bf[65537]; /* printf("NAME: %s FIELDS: %d TYPE: %d is_partial_dumped: %d\n", str->name, (int)str->fieldCount, (int)str->type, (int)str->is_partial_dumped); */ sprintf(bf, "Scope: vcd_struct %s %s", str->name, "NULL"); cb(bf); } static void __DumpArray(fsdbTreeCBDataArrayBegin* arr, void (*cb)(void *)) { /* printf("NAME: %s SIZE: %d is_partial_dumped: %d\n", arr->name, (int)arr->size, (int)arr->is_partial_dumped); */ } static bool_T __MyTreeCB(fsdbTreeCBType cb_type, void *client_data, void *tree_cb_data) { void (*cb)(void *) = (void (*)(void *))client_data; char bf[16]; switch (cb_type) { case FSDB_TREE_CBT_BEGIN_TREE: /* fprintf(stderr, "Begin Tree:\n"); */ break; case FSDB_TREE_CBT_SCOPE: __DumpScope((fsdbTreeCBDataScope*)tree_cb_data, cb); break; case FSDB_TREE_CBT_VAR: __DumpVar((fsdbTreeCBDataVar*)tree_cb_data, cb); break; case FSDB_TREE_CBT_UPSCOPE: strcpy(bf, "Upscope:"); cb(bf); break; case FSDB_TREE_CBT_END_TREE: /* fprintf(stderr, "End Tree:\n"); */ break; case FSDB_TREE_CBT_STRUCT_BEGIN: __DumpStruct((fsdbTreeCBDataStructBegin*)tree_cb_data, cb); break; case FSDB_TREE_CBT_STRUCT_END: strcpy(bf, "Upscope:"); cb(bf); break; /* not yet supported */ case FSDB_TREE_CBT_ARRAY_BEGIN: __DumpArray((fsdbTreeCBDataArrayBegin*)tree_cb_data, cb); break; case FSDB_TREE_CBT_ARRAY_END: break; case FSDB_TREE_CBT_FILE_TYPE: case FSDB_TREE_CBT_SIMULATOR_VERSION: case FSDB_TREE_CBT_SIMULATION_DATE: case FSDB_TREE_CBT_X_AXIS_SCALE: case FSDB_TREE_CBT_END_ALL_TREE: case FSDB_TREE_CBT_RECORD_BEGIN: case FSDB_TREE_CBT_RECORD_END: break; default: return(FALSE); } return(TRUE); } /* * $dumpoff/$dumpon support */ extern "C" unsigned int fsdbReaderGetDumpOffRange(void *ctx, struct fsdbReaderBlackoutChain_t **r) { ffrObject *fsdb_obj = (ffrObject *)ctx; if(fsdb_obj->ffrHasDumpOffRange()) { uint_T count; fsdbDumpOffRange *fdr = NULL; if(FSDB_RC_SUCCESS == fsdb_obj->ffrGetDumpOffRange(count, fdr)) { uint_T i; *r = (struct fsdbReaderBlackoutChain_t *)calloc(count * 2, sizeof(struct fsdbReaderBlackoutChain_t)); for(i=0;iffrGetTransInfo((fsdbTransId)idx, info); *trans_info = info; return(rc != FSDB_RC_FAILURE); } #else static void dummy_compilation_unit(void) { } #endif gtkwave-3.3.66/src/pagebuttons.h0000664000076400007640000000073211523063250016071 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2010 * * 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. */ #ifndef WAVE_PAGEBUTTONS_H #define WAVE_PAGEBUTTONS_H void service_left_page(GtkWidget *text, gpointer data); void service_right_page(GtkWidget *text, gpointer data); #endif gtkwave-3.3.66/src/vcd.c0000664000076400007640000021437512477613751014337 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2014. * * 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. */ /* * vcd.c 23jan99ajb * evcd parts 29jun99ajb * profiler optimizations 15jul99ajb * more profiler optimizations 25jan00ajb * finsim parameter fix 26jan00ajb * vector rechaining code 03apr00ajb * multiple var section code 06apr00ajb * fix for duplicate nets 19dec00ajb * support for alt hier seps 23dec00ajb * fix for rcs identifiers 16jan01ajb * coredump fix for bad VCD 04apr02ajb * min/maxid speedup 27feb03ajb * bugfix on min/maxid speedup 06jul03ajb * escaped hier modification 20feb06ajb * added real_parameter vartype 04aug06ajb * added in/out port vartype 31jan07ajb * use gperf for port vartypes 19feb07ajb * MTI SV implicit-var fix 05apr07ajb * MTI SV len=0 is real var 05apr07ajb */ /* AIX may need this for alloca to work */ #if defined _AIX #pragma alloca #endif #include #include "globals.h" #include "vcd.h" #include "hierpack.h" #undef VCD_BSEARCH_IS_PERFECT /* bsearch is imperfect under linux, but OK under AIX */ static void add_histent(TimeType time, struct Node *n, char ch, int regadd, char *vector); static void add_tail_histents(void); static void vcd_build_symbols(void); static void vcd_cleanup(void); static void evcd_strcpy(char *dst, char *src); /******************************************************************/ static void malform_eof_fix(void) { if(feof(GLOBALS->vcd_handle_vcd_c_1)) { memset(GLOBALS->vcdbuf_vcd_c_1, ' ', VCD_BSIZ); GLOBALS->vst_vcd_c_1=GLOBALS->vend_vcd_c_1; } } /**/ void strcpy_vcdalt(char *too, char *from, char delim) { char ch; do { ch=*(from++); if(ch==delim) { ch=GLOBALS->hier_delimeter; } } while((*(too++)=ch)); } int strcpy_delimfix(char *too, char *from) { char ch; int found = 0; do { ch=*(from++); if(ch==GLOBALS->hier_delimeter) { ch=VCDNAM_ESCAPE; found = 1; } } while((*(too++)=ch)); if(found) GLOBALS->escaped_names_found_vcd_c_1 = found; return(found); } /******************************************************************/ /******************************************************************/ enum Tokens { T_VAR, T_END, T_SCOPE, T_UPSCOPE, T_COMMENT, T_DATE, T_DUMPALL, T_DUMPOFF, T_DUMPON, T_DUMPVARS, T_ENDDEFINITIONS, T_DUMPPORTS, T_DUMPPORTSOFF, T_DUMPPORTSON, T_DUMPPORTSALL, T_TIMESCALE, T_VERSION, T_VCDCLOSE, T_TIMEZERO, T_EOF, T_STRING, T_UNKNOWN_KEY }; static char *tokens[]={ "var", "end", "scope", "upscope", "comment", "date", "dumpall", "dumpoff", "dumpon", "dumpvars", "enddefinitions", "dumpports", "dumpportsoff", "dumpportson", "dumpportsall", "timescale", "version", "vcdclose", "timezero", "", "", "" }; #define NUM_TOKENS 19 #define T_GET tok=get_token();if((tok==T_END)||(tok==T_EOF))break; /******************************************************************/ /******************************************************************/ /* * histent structs are NEVER freed so this is OK.. * (we are allocating as many entries that fit in 64k minus the size of the two * bookkeeping void* pointers found in the malloc_2/free_2 routines in * debug.c--unless Judy, then can dispense with pointer subtraction) */ #ifdef _WAVE_HAVE_JUDY #define VCD_HISTENT_GRANULARITY ( (64*1024) / sizeof(HistEnt) ) #else #define VCD_HISTENT_GRANULARITY ( ( (64*1024)-(2*sizeof(void *)) ) / sizeof(HistEnt) ) #endif struct HistEnt *histent_calloc(void) { if(GLOBALS->he_curr_vcd_c_1==GLOBALS->he_fini_vcd_c_1) { GLOBALS->he_curr_vcd_c_1=(struct HistEnt *)calloc_2(VCD_HISTENT_GRANULARITY, sizeof(struct HistEnt)); GLOBALS->he_fini_vcd_c_1=GLOBALS->he_curr_vcd_c_1+VCD_HISTENT_GRANULARITY; } return(GLOBALS->he_curr_vcd_c_1++); } /******************************************************************/ /******************************************************************/ static unsigned int vcdid_hash(char *s, int len) { unsigned int val=0; int i; s+=(len-1); for(i=0;iid)); } /* * actual bsearch */ static struct vcdsymbol *bsearch_vcd(char *key, int len) { struct vcdsymbol **v; struct vcdsymbol *t; if(GLOBALS->indexed_vcd_c_1) { unsigned int hsh = vcdid_hash(key, len); if((hsh>=GLOBALS->vcd_minid_vcd_c_1)&&(hsh<=GLOBALS->vcd_maxid_vcd_c_1)) { return(GLOBALS->indexed_vcd_c_1[hsh-GLOBALS->vcd_minid_vcd_c_1]); } return(NULL); } if(GLOBALS->sorted_vcd_c_1) { v=(struct vcdsymbol **)bsearch(key, GLOBALS->sorted_vcd_c_1, GLOBALS->numsyms_vcd_c_1, sizeof(struct vcdsymbol *), vcdsymbsearchcompare); if(v) { #ifndef VCD_BSEARCH_IS_PERFECT for(;;) { t=*v; if((v==GLOBALS->sorted_vcd_c_1)||(strcmp((*(--v))->id, key))) { return(t); } } #else return(*v); #endif } else { return(NULL); } } else { if(!GLOBALS->err_vcd_c_1) { fprintf(stderr, "Near byte %d, VCD search table NULL..is this a VCD file?\n", (int)(GLOBALS->vcdbyteno_vcd_c_1+(GLOBALS->vst_vcd_c_1-GLOBALS->vcdbuf_vcd_c_1))); GLOBALS->err_vcd_c_1=1; } return(NULL); } } /* * sort on vcdsymbol pointers */ static int vcdsymcompare(const void *s1, const void *s2) { struct vcdsymbol *v1, *v2; v1=*((struct vcdsymbol **)s1); v2=*((struct vcdsymbol **)s2); return(strcmp(v1->id, v2->id)); } /* * create sorted (by id) table */ static void create_sorted_table(void) { struct vcdsymbol *v; struct vcdsymbol **pnt; unsigned int vcd_distance; if(GLOBALS->sorted_vcd_c_1) { free_2(GLOBALS->sorted_vcd_c_1); /* this means we saw a 2nd enddefinition chunk! */ GLOBALS->sorted_vcd_c_1=NULL; } if(GLOBALS->indexed_vcd_c_1) { free_2(GLOBALS->indexed_vcd_c_1); GLOBALS->indexed_vcd_c_1=NULL; } if(GLOBALS->numsyms_vcd_c_1) { vcd_distance = GLOBALS->vcd_maxid_vcd_c_1 - GLOBALS->vcd_minid_vcd_c_1 + 1; if((vcd_distance <= VCD_INDEXSIZ)||(!GLOBALS->vcd_hash_kill)) { GLOBALS->indexed_vcd_c_1 = (struct vcdsymbol **)calloc_2(vcd_distance, sizeof(struct vcdsymbol *)); /* printf("%d symbols span ID range of %d, using indexing...\n", GLOBALS->numsyms_vcd_c_1, vcd_distance); */ v=GLOBALS->vcdsymroot_vcd_c_1; while(v) { if(!GLOBALS->indexed_vcd_c_1[v->nid - GLOBALS->vcd_minid_vcd_c_1]) GLOBALS->indexed_vcd_c_1[v->nid - GLOBALS->vcd_minid_vcd_c_1] = v; v=v->next; } } else { pnt=GLOBALS->sorted_vcd_c_1=(struct vcdsymbol **)calloc_2(GLOBALS->numsyms_vcd_c_1, sizeof(struct vcdsymbol *)); v=GLOBALS->vcdsymroot_vcd_c_1; while(v) { *(pnt++)=v; v=v->next; } qsort(GLOBALS->sorted_vcd_c_1, GLOBALS->numsyms_vcd_c_1, sizeof(struct vcdsymbol *), vcdsymcompare); } } } /******************************************************************/ /* * single char get inlined/optimized */ static void getch_alloc(void) { GLOBALS->vend_vcd_c_1=GLOBALS->vst_vcd_c_1=GLOBALS->vcdbuf_vcd_c_1=(char *)calloc_2(1,VCD_BSIZ); } static void getch_free(void) { free_2(GLOBALS->vcdbuf_vcd_c_1); GLOBALS->vcdbuf_vcd_c_1=GLOBALS->vst_vcd_c_1=GLOBALS->vend_vcd_c_1=NULL; } static int getch_fetch(void) { size_t rd; errno = 0; if(feof(GLOBALS->vcd_handle_vcd_c_1)) return(-1); GLOBALS->vcdbyteno_vcd_c_1+=(GLOBALS->vend_vcd_c_1-GLOBALS->vcdbuf_vcd_c_1); rd=fread(GLOBALS->vcdbuf_vcd_c_1, sizeof(char), VCD_BSIZ, GLOBALS->vcd_handle_vcd_c_1); GLOBALS->vend_vcd_c_1=(GLOBALS->vst_vcd_c_1=GLOBALS->vcdbuf_vcd_c_1)+rd; if((!rd)||(errno)) return(-1); if(GLOBALS->vcd_fsiz_vcd_c_1) { splash_sync(GLOBALS->vcdbyteno_vcd_c_1, GLOBALS->vcd_fsiz_vcd_c_1); /* gnome 2.18 seems to set errno so splash moved here... */ } return((int)(*GLOBALS->vst_vcd_c_1)); } static inline signed char getch(void) { signed char ch = ((GLOBALS->vst_vcd_c_1!=GLOBALS->vend_vcd_c_1)?((int)(*GLOBALS->vst_vcd_c_1)):(getch_fetch())); GLOBALS->vst_vcd_c_1++; return(ch); } static inline signed char getch_peek(void) { signed char ch = ((GLOBALS->vst_vcd_c_1!=GLOBALS->vend_vcd_c_1)?((int)(*GLOBALS->vst_vcd_c_1)):(getch_fetch())); /* no increment */ return(ch); } static int getch_patched(void) { char ch; ch=*GLOBALS->vsplitcurr_vcd_c_1; if(!ch) { return(-1); } else { GLOBALS->vsplitcurr_vcd_c_1++; return((int)ch); } } /* * simple tokenizer */ static int get_token(void) { int ch; int i, len=0; int is_string=0; char *yyshadow; for(;;) { ch=getch(); if(ch<0) return(T_EOF); if(ch<=' ') continue; /* val<=' ' is a quick whitespace check */ break; /* (take advantage of fact that vcd is text) */ } if(ch=='$') { GLOBALS->yytext_vcd_c_1[len++]=ch; for(;;) { ch=getch(); if(ch<0) return(T_EOF); if(ch<=' ') continue; break; } } else { is_string=1; } for(GLOBALS->yytext_vcd_c_1[len++]=ch;;GLOBALS->yytext_vcd_c_1[len++]=ch) { if(len==GLOBALS->T_MAX_STR_vcd_c_1) { GLOBALS->yytext_vcd_c_1=(char *)realloc_2(GLOBALS->yytext_vcd_c_1, (GLOBALS->T_MAX_STR_vcd_c_1=GLOBALS->T_MAX_STR_vcd_c_1*2)+1); } ch=getch(); if(ch<=' ') break; } GLOBALS->yytext_vcd_c_1[len]=0; /* terminator */ if(is_string) { GLOBALS->yylen_vcd_c_1=len; return(T_STRING); } yyshadow=GLOBALS->yytext_vcd_c_1; do { yyshadow++; for(i=0;ivar_prevch_vcd_c_1) { for(;;) { ch=getch_patched(); if(ch<0) { free_2(GLOBALS->varsplit_vcd_c_1); GLOBALS->varsplit_vcd_c_1=NULL; return(V_END); } if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')) continue; break; } } else { ch=GLOBALS->var_prevch_vcd_c_1; GLOBALS->var_prevch_vcd_c_1=0; } if(ch=='[') return(V_LB); if(ch==':') return(V_COLON); if(ch==']') return(V_RB); for(GLOBALS->yytext_vcd_c_1[len++]=ch;;GLOBALS->yytext_vcd_c_1[len++]=ch) { if(len==GLOBALS->T_MAX_STR_vcd_c_1) { GLOBALS->yytext_vcd_c_1=(char *)realloc_2(GLOBALS->yytext_vcd_c_1, (GLOBALS->T_MAX_STR_vcd_c_1=GLOBALS->T_MAX_STR_vcd_c_1*2)+1); } ch=getch_patched(); if(ch<0) { free_2(GLOBALS->varsplit_vcd_c_1); GLOBALS->varsplit_vcd_c_1=NULL; break; } if((ch==':')||(ch==']')) { GLOBALS->var_prevch_vcd_c_1=ch; break; } } GLOBALS->yytext_vcd_c_1[len]=0; /* terminator */ if(match_kw) { int vt = vcd_keyword_code(GLOBALS->yytext_vcd_c_1, len); if(vt != V_STRING) { if(ch<0) { free_2(GLOBALS->varsplit_vcd_c_1); GLOBALS->varsplit_vcd_c_1=NULL; } return(vt); } } GLOBALS->yylen_vcd_c_1=len; if(ch<0) { free_2(GLOBALS->varsplit_vcd_c_1); GLOBALS->varsplit_vcd_c_1=NULL; } return(V_STRING); } static int get_vartoken(int match_kw) { int ch; int len=0; if(GLOBALS->varsplit_vcd_c_1) { int rc=get_vartoken_patched(match_kw); if(rc!=V_END) return(rc); GLOBALS->var_prevch_vcd_c_1=0; } if(!GLOBALS->var_prevch_vcd_c_1) { for(;;) { ch=getch(); if(ch<0) return(V_END); if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')) continue; break; } } else { ch=GLOBALS->var_prevch_vcd_c_1; GLOBALS->var_prevch_vcd_c_1=0; } if(ch=='[') return(V_LB); if(ch==':') return(V_COLON); if(ch==']') return(V_RB); if(ch=='#') /* for MTI System Verilog '$var reg 64 >w #implicit-var###VarElem:ram_di[0.0] [63:0] $end' style declarations */ { /* debussy simply escapes until the space */ GLOBALS->yytext_vcd_c_1[len++]= '\\'; } for(GLOBALS->yytext_vcd_c_1[len++]=ch;;GLOBALS->yytext_vcd_c_1[len++]=ch) { if(len==GLOBALS->T_MAX_STR_vcd_c_1) { GLOBALS->yytext_vcd_c_1=(char *)realloc_2(GLOBALS->yytext_vcd_c_1, (GLOBALS->T_MAX_STR_vcd_c_1=GLOBALS->T_MAX_STR_vcd_c_1*2)+1); } ch=getch(); if(ch==' ') { if(match_kw) break; if(getch_peek() == '[') { ch = getch(); GLOBALS->varsplit_vcd_c_1=GLOBALS->yytext_vcd_c_1+len; /* keep looping so we get the *last* one */ continue; } } if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')||(ch<0)) break; if((ch=='[')&&(GLOBALS->yytext_vcd_c_1[0]!='\\')) { GLOBALS->varsplit_vcd_c_1=GLOBALS->yytext_vcd_c_1+len; /* keep looping so we get the *last* one */ } else if(((ch==':')||(ch==']'))&&(!GLOBALS->varsplit_vcd_c_1)&&(GLOBALS->yytext_vcd_c_1[0]!='\\')) { GLOBALS->var_prevch_vcd_c_1=ch; break; } } GLOBALS->yytext_vcd_c_1[len]=0; /* absolute terminator */ if((GLOBALS->varsplit_vcd_c_1)&&(GLOBALS->yytext_vcd_c_1[len-1]==']')) { char *vst; vst=malloc_2(strlen(GLOBALS->varsplit_vcd_c_1)+1); strcpy(vst, GLOBALS->varsplit_vcd_c_1); *GLOBALS->varsplit_vcd_c_1=0x00; /* zero out var name at the left bracket */ len=GLOBALS->varsplit_vcd_c_1-GLOBALS->yytext_vcd_c_1; GLOBALS->varsplit_vcd_c_1=GLOBALS->vsplitcurr_vcd_c_1=vst; GLOBALS->var_prevch_vcd_c_1=0; } else { GLOBALS->varsplit_vcd_c_1=NULL; } if(match_kw) { int vt = vcd_keyword_code(GLOBALS->yytext_vcd_c_1, len); if(vt != V_STRING) { return(vt); } } GLOBALS->yylen_vcd_c_1=len; return(V_STRING); } static int get_strtoken(void) { int ch; int len=0; if(!GLOBALS->var_prevch_vcd_c_1) { for(;;) { ch=getch(); if(ch<0) return(V_END); if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')) continue; break; } } else { ch=GLOBALS->var_prevch_vcd_c_1; GLOBALS->var_prevch_vcd_c_1=0; } for(GLOBALS->yytext_vcd_c_1[len++]=ch;;GLOBALS->yytext_vcd_c_1[len++]=ch) { if(len==GLOBALS->T_MAX_STR_vcd_c_1) { GLOBALS->yytext_vcd_c_1=(char *)realloc_2(GLOBALS->yytext_vcd_c_1, (GLOBALS->T_MAX_STR_vcd_c_1=GLOBALS->T_MAX_STR_vcd_c_1*2)+1); } ch=getch(); if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')||(ch<0)) break; } GLOBALS->yytext_vcd_c_1[len]=0; /* terminator */ GLOBALS->yylen_vcd_c_1=len; return(V_STRING); } static void sync_end(char *hdr) { int tok; if(hdr) { DEBUG(fprintf(stderr,"%s",hdr)); } for(;;) { tok=get_token(); if((tok==T_END)||(tok==T_EOF)) break; if(hdr) { DEBUG(fprintf(stderr," %s",GLOBALS->yytext_vcd_c_1)); } } if(hdr) { DEBUG(fprintf(stderr,"\n")); } } static int version_sync_end(char *hdr) { int tok; int rc = 0; if(hdr) { DEBUG(fprintf(stderr,"%s",hdr)); } for(;;) { tok=get_token(); if((tok==T_END)||(tok==T_EOF)) break; if(hdr) { DEBUG(fprintf(stderr," %s",GLOBALS->yytext_vcd_c_1)); } if(strstr(GLOBALS->yytext_vcd_c_1, "Icarus")) /* turn off autocoalesce for Icarus */ { GLOBALS->autocoalesce = 0; rc = 1; } } if(hdr) { DEBUG(fprintf(stderr,"\n")); } return(rc); } char *build_slisthier(void) { struct slist *s; int len=0; if(GLOBALS->slisthier) { free_2(GLOBALS->slisthier); } if(!GLOBALS->slistroot) { GLOBALS->slisthier_len=0; GLOBALS->slisthier=(char *)malloc_2(1); *GLOBALS->slisthier=0; return(GLOBALS->slisthier); } s=GLOBALS->slistroot; len=0; while(s) { len+=s->len+(s->next?1:0); s=s->next; } GLOBALS->slisthier=(char *)malloc_2((GLOBALS->slisthier_len=len)+1); s=GLOBALS->slistroot; len=0; while(s) { strcpy(GLOBALS->slisthier+len,s->str); len+=s->len; if(s->next) { strcpy(GLOBALS->slisthier+len,GLOBALS->vcd_hier_delimeter); len++; } s=s->next; } return(GLOBALS->slisthier); } void append_vcd_slisthier(char *str) { struct slist *s; s=(struct slist *)calloc_2(1,sizeof(struct slist)); s->len=strlen(str); s->str=(char *)malloc_2(s->len+1); strcpy(s->str,str); if(GLOBALS->slistcurr) { GLOBALS->slistcurr->next=s; GLOBALS->slistcurr=s; } else { GLOBALS->slistcurr=GLOBALS->slistroot=s; } build_slisthier(); DEBUG(fprintf(stderr, "SCOPE: %s\n",GLOBALS->slisthier)); } static void parse_valuechange(void) { struct vcdsymbol *v; char *vector; int vlen; switch(GLOBALS->yytext_vcd_c_1[0]) { case '0': case '1': case 'x': case 'X': case 'z': case 'Z': case 'h': case 'H': case 'u': case 'U': case 'w': case 'W': case 'l': case 'L': case '-': if(GLOBALS->yylen_vcd_c_1>1) { v=bsearch_vcd(GLOBALS->yytext_vcd_c_1+1, GLOBALS->yylen_vcd_c_1-1); if(!v) { fprintf(stderr,"Near byte %d, Unknown VCD identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_c_1+(GLOBALS->vst_vcd_c_1-GLOBALS->vcdbuf_vcd_c_1)),GLOBALS->yytext_vcd_c_1+1); malform_eof_fix(); } else { v->value[0]=GLOBALS->yytext_vcd_c_1[0]; DEBUG(fprintf(stderr,"%s = '%c'\n",v->name,v->value[0])); add_histent(GLOBALS->current_time_vcd_c_1,v->narray[0],v->value[0],1, NULL); } } else { fprintf(stderr,"Near byte %d, Malformed VCD identifier\n", (int)(GLOBALS->vcdbyteno_vcd_c_1+(GLOBALS->vst_vcd_c_1-GLOBALS->vcdbuf_vcd_c_1))); malform_eof_fix(); } break; case 'b': case 'B': { /* extract binary number then.. */ vector=malloc_2(GLOBALS->yylen_cache_vcd_c_1=GLOBALS->yylen_vcd_c_1); strcpy(vector,GLOBALS->yytext_vcd_c_1+1); vlen=GLOBALS->yylen_vcd_c_1-1; get_strtoken(); v=bsearch_vcd(GLOBALS->yytext_vcd_c_1, GLOBALS->yylen_vcd_c_1); if(!v) { fprintf(stderr,"Near byte %d, Unknown identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_c_1+(GLOBALS->vst_vcd_c_1-GLOBALS->vcdbuf_vcd_c_1)), GLOBALS->yytext_vcd_c_1); free_2(vector); malform_eof_fix(); } else { if ((v->vartype==V_REAL)||(v->vartype==V_STRINGTYPE)||((GLOBALS->convert_to_reals)&&((v->vartype==V_INTEGER)||(v->vartype==V_PARAMETER)))) { double *d; char *pnt; char ch; TimeType k=0; pnt=vector; while((ch=*(pnt++))) { k=(k<<1)|((ch=='1')?1:0); } free_2(vector); d=malloc_2(sizeof(double)); *d=(double)k; if(!v) { fprintf(stderr,"Near byte %d, Unknown identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_c_1+(GLOBALS->vst_vcd_c_1-GLOBALS->vcdbuf_vcd_c_1)), GLOBALS->yytext_vcd_c_1); free_2(d); malform_eof_fix(); } else { add_histent(GLOBALS->current_time_vcd_c_1, v->narray[0],'g',1,(char *)d); } break; } if(vlensize) /* fill in left part */ { char extend; int i, fill; extend=(vector[0]=='1')?'0':vector[0]; fill=v->size-vlen; for(i=0;ivalue[i]=extend; } strcpy(v->value+fill,vector); } else if(vlen==v->size) /* straight copy */ { strcpy(v->value,vector); } else /* too big, so copy only right half */ { int skip; skip=vlen-v->size; strcpy(v->value,vector+skip); } DEBUG(fprintf(stderr,"%s = '%s'\n",v->name, v->value)); if((v->size==1)||(!GLOBALS->atomic_vectors)) { int i; for(i=0;isize;i++) { add_histent(GLOBALS->current_time_vcd_c_1, v->narray[i],v->value[i],1, NULL); } free_2(vector); } else { if(GLOBALS->yylen_cache_vcd_c_1!=(v->size+1)) { free_2(vector); vector=malloc_2(v->size+1); } strcpy(vector,v->value); add_histent(GLOBALS->current_time_vcd_c_1, v->narray[0],0,1,vector); } } break; } case 'p': /* extract port dump value.. */ vector=malloc_2(GLOBALS->yylen_cache_vcd_c_1=GLOBALS->yylen_vcd_c_1); strcpy(vector,GLOBALS->yytext_vcd_c_1+1); vlen=GLOBALS->yylen_vcd_c_1-1; get_strtoken(); /* throw away 0_strength_component */ get_strtoken(); /* throw away 0_strength_component */ get_strtoken(); /* this is the id */ v=bsearch_vcd(GLOBALS->yytext_vcd_c_1, GLOBALS->yylen_vcd_c_1); if(!v) { fprintf(stderr,"Near byte %d, Unknown identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_c_1+(GLOBALS->vst_vcd_c_1-GLOBALS->vcdbuf_vcd_c_1)), GLOBALS->yytext_vcd_c_1); free_2(vector); malform_eof_fix(); } else { if ((v->vartype==V_REAL)||(v->vartype==V_STRINGTYPE)||((GLOBALS->convert_to_reals)&&((v->vartype==V_INTEGER)||(v->vartype==V_PARAMETER)))) { double *d; char *pnt; char ch; TimeType k=0; pnt=vector; while((ch=*(pnt++))) { k=(k<<1)|((ch=='1')?1:0); } free_2(vector); d=malloc_2(sizeof(double)); *d=(double)k; if(!v) { fprintf(stderr,"Near byte %d, Unknown identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_c_1+(GLOBALS->vst_vcd_c_1-GLOBALS->vcdbuf_vcd_c_1)), GLOBALS->yytext_vcd_c_1); free_2(d); malform_eof_fix(); } else { add_histent(GLOBALS->current_time_vcd_c_1, v->narray[0],'g',1,(char *)d); } break; } if(vlensize) /* fill in left part */ { char extend; int i, fill; extend='0'; fill=v->size-vlen; for(i=0;ivalue[i]=extend; } evcd_strcpy(v->value+fill,vector); } else if(vlen==v->size) /* straight copy */ { evcd_strcpy(v->value,vector); } else /* too big, so copy only right half */ { int skip; skip=vlen-v->size; evcd_strcpy(v->value,vector+skip); } DEBUG(fprintf(stderr,"%s = '%s'\n",v->name, v->value)); if((v->size==1)||(!GLOBALS->atomic_vectors)) { int i; for(i=0;isize;i++) { add_histent(GLOBALS->current_time_vcd_c_1, v->narray[i],v->value[i],1, NULL); } free_2(vector); } else { if(GLOBALS->yylen_cache_vcd_c_1size) { free_2(vector); vector=malloc_2(v->size+1); } strcpy(vector,v->value); add_histent(GLOBALS->current_time_vcd_c_1, v->narray[0],0,1,vector); } } break; case 'r': case 'R': { double *d; d=malloc_2(sizeof(double)); sscanf(GLOBALS->yytext_vcd_c_1+1,"%lg",d); get_strtoken(); v=bsearch_vcd(GLOBALS->yytext_vcd_c_1, GLOBALS->yylen_vcd_c_1); if(!v) { fprintf(stderr,"Near byte %d, Unknown identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_c_1+(GLOBALS->vst_vcd_c_1-GLOBALS->vcdbuf_vcd_c_1)), GLOBALS->yytext_vcd_c_1); free_2(d); malform_eof_fix(); } else { add_histent(GLOBALS->current_time_vcd_c_1, v->narray[0],'g',1,(char *)d); } break; } #ifndef STRICT_VCD_ONLY case 's': case 'S': { char *d; d=(char *)malloc_2(GLOBALS->yylen_vcd_c_1); vlen = fstUtilityEscToBin((unsigned char *)d, (unsigned char *)(GLOBALS->yytext_vcd_c_1+1), GLOBALS->yylen_vcd_c_1); /* includes 0 term */ if(vlen != GLOBALS->yylen_vcd_c_1) { d = realloc_2(d, vlen); } get_strtoken(); v=bsearch_vcd(GLOBALS->yytext_vcd_c_1, GLOBALS->yylen_vcd_c_1); if(!v) { fprintf(stderr,"Near byte %d, Unknown identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_c_1+(GLOBALS->vst_vcd_c_1-GLOBALS->vcdbuf_vcd_c_1)), GLOBALS->yytext_vcd_c_1); free_2(d); malform_eof_fix(); } else { add_histent(GLOBALS->current_time_vcd_c_1, v->narray[0],'s',1,(char *)d); } break; } #endif } } static void evcd_strcpy(char *dst, char *src) { static const char *evcd="DUNZduLHXTlh01?FAaBbCcf"; static const char *vcd="01xz0101xz0101xzxxxxxxz"; char ch; int i; while((ch=*src)) { for(i=0;i<23;i++) { if(evcd[i]==ch) { *dst=vcd[i]; break; } } if(i==23) *dst='x'; src++; dst++; } *dst=0; /* null terminate destination */ } static void vcd_parse(void) { int tok; unsigned char ttype; int disable_autocoalesce = 0; for(;;) { switch(get_token()) { case T_COMMENT: sync_end("COMMENT:"); break; case T_DATE: sync_end("DATE:"); break; case T_VERSION: disable_autocoalesce = version_sync_end("VERSION:"); break; case T_TIMEZERO: { int vtok=get_token(); if((vtok==T_END)||(vtok==T_EOF)) break; GLOBALS->global_time_offset=atoi_64(GLOBALS->yytext_vcd_c_1); DEBUG(fprintf(stderr,"TIMEZERO: "TTFormat"\n",GLOBALS->global_time_offset)); sync_end(NULL); } break; case T_TIMESCALE: { int vtok; int i; char prefix=' '; vtok=get_token(); if((vtok==T_END)||(vtok==T_EOF)) break; fractional_timescale_fix(GLOBALS->yytext_vcd_c_1); GLOBALS->time_scale=atoi_64(GLOBALS->yytext_vcd_c_1); if(!GLOBALS->time_scale) GLOBALS->time_scale=1; for(i=0;iyylen_vcd_c_1;i++) { if((GLOBALS->yytext_vcd_c_1[i]<'0')||(GLOBALS->yytext_vcd_c_1[i]>'9')) { prefix=GLOBALS->yytext_vcd_c_1[i]; break; } } if(prefix==' ') { vtok=get_token(); if((vtok==T_END)||(vtok==T_EOF)) break; prefix=GLOBALS->yytext_vcd_c_1[0]; } switch(prefix) { case ' ': case 'm': case 'u': case 'n': case 'p': case 'f': case 'a': case 'z': GLOBALS->time_dimension=prefix; break; case 's': GLOBALS->time_dimension=' '; break; default: /* unknown */ GLOBALS->time_dimension='n'; break; } DEBUG(fprintf(stderr,"TIMESCALE: "TTFormat" %cs\n",GLOBALS->time_scale, GLOBALS->time_dimension)); sync_end(NULL); } break; case T_SCOPE: T_GET; { switch(GLOBALS->yytext_vcd_c_1[0]) { case 'm': ttype = TREE_VCD_ST_MODULE; break; case 't': ttype = TREE_VCD_ST_TASK; break; case 'f': ttype = (GLOBALS->yytext_vcd_c_1[1] == 'u') ? TREE_VCD_ST_FUNCTION : TREE_VCD_ST_FORK; break; case 'b': ttype = TREE_VCD_ST_BEGIN; break; case 'g': ttype = TREE_VCD_ST_GENERATE; break; case 's': ttype = TREE_VCD_ST_STRUCT; break; case 'u': ttype = TREE_VCD_ST_UNION; break; case 'c': ttype = TREE_VCD_ST_CLASS; break; case 'i': ttype = TREE_VCD_ST_INTERFACE; break; case 'p': ttype = (GLOBALS->yytext_vcd_c_1[1] == 'r') ? TREE_VCD_ST_PROGRAM : TREE_VCD_ST_PACKAGE; break; case 'v': { char *vht = GLOBALS->yytext_vcd_c_1; if(!strncmp(vht, "vhdl_", 5)) { switch(vht[5]) { case 'a': ttype = TREE_VHDL_ST_ARCHITECTURE; break; case 'r': ttype = TREE_VHDL_ST_RECORD; break; case 'b': ttype = TREE_VHDL_ST_BLOCK; break; case 'g': ttype = TREE_VHDL_ST_GENERATE; break; case 'i': ttype = TREE_VHDL_ST_GENIF; break; case 'f': ttype = (vht[6] == 'u') ? TREE_VHDL_ST_FUNCTION : TREE_VHDL_ST_GENFOR; break; case 'p': ttype = (!strncmp(vht+6, "roces", 5)) ? TREE_VHDL_ST_PROCESS: TREE_VHDL_ST_PROCEDURE; break; default: ttype = TREE_UNKNOWN; break; } } else { ttype = TREE_UNKNOWN; } } break; default: ttype = TREE_UNKNOWN; break; } } T_GET; if(tok==T_STRING) { struct slist *s; s=(struct slist *)calloc_2(1,sizeof(struct slist)); s->len=GLOBALS->yylen_vcd_c_1; s->str=(char *)malloc_2(GLOBALS->yylen_vcd_c_1+1); strcpy(s->str, GLOBALS->yytext_vcd_c_1); s->mod_tree_parent = GLOBALS->mod_tree_parent; allocate_and_decorate_module_tree_node(ttype, GLOBALS->yytext_vcd_c_1, NULL, GLOBALS->yylen_vcd_c_1, 0, 0, 0); if(GLOBALS->slistcurr) { GLOBALS->slistcurr->next=s; GLOBALS->slistcurr=s; } else { GLOBALS->slistcurr=GLOBALS->slistroot=s; } build_slisthier(); DEBUG(fprintf(stderr, "SCOPE: %s\n",GLOBALS->slisthier)); } sync_end(NULL); break; case T_UPSCOPE: if(GLOBALS->slistroot) { struct slist *s; GLOBALS->mod_tree_parent = GLOBALS->slistcurr->mod_tree_parent; s=GLOBALS->slistroot; if(!s->next) { free_2(s->str); free_2(s); GLOBALS->slistroot=GLOBALS->slistcurr=NULL; } else for(;;) { if(!s->next->next) { free_2(s->next->str); free_2(s->next); s->next=NULL; GLOBALS->slistcurr=s; break; } s=s->next; } build_slisthier(); DEBUG(fprintf(stderr, "SCOPE: %s\n",GLOBALS->slisthier)); } else { GLOBALS->mod_tree_parent = NULL; } sync_end(NULL); break; case T_VAR: if((GLOBALS->header_over_vcd_c_1)&&(0)) { fprintf(stderr,"$VAR encountered after $ENDDEFINITIONS near byte %d. VCD is malformed, exiting.\n", (int)(GLOBALS->vcdbyteno_vcd_c_1+(GLOBALS->vst_vcd_c_1-GLOBALS->vcdbuf_vcd_c_1))); vcd_exit(255); } else { int vtok; struct vcdsymbol *v=NULL; GLOBALS->var_prevch_vcd_c_1=0; if(GLOBALS->varsplit_vcd_c_1) { free_2(GLOBALS->varsplit_vcd_c_1); GLOBALS->varsplit_vcd_c_1=NULL; } vtok=get_vartoken(1); if(vtok>V_STRINGTYPE) goto bail; v=(struct vcdsymbol *)calloc_2(1,sizeof(struct vcdsymbol)); v->vartype=vtok; v->msi=v->lsi=GLOBALS->vcd_explicit_zero_subscripts; /* indicate [un]subscripted status */ if(vtok==V_PORT) { vtok=get_vartoken(1); if(vtok==V_STRING) { v->size=atoi_64(GLOBALS->yytext_vcd_c_1); if(!v->size) v->size=1; } else if(vtok==V_LB) { vtok=get_vartoken(1); if(vtok==V_END) goto err; if(vtok!=V_STRING) goto err; v->msi=atoi_64(GLOBALS->yytext_vcd_c_1); vtok=get_vartoken(0); if(vtok==V_RB) { v->lsi=v->msi; v->size=1; } else { if(vtok!=V_COLON) goto err; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; v->lsi=atoi_64(GLOBALS->yytext_vcd_c_1); vtok=get_vartoken(0); if(vtok!=V_RB) goto err; if(v->msi>v->lsi) { v->size=v->msi-v->lsi+1; } else { v->size=v->lsi-v->msi+1; } } } else goto err; vtok=get_strtoken(); if(vtok==V_END) goto err; v->id=(char *)malloc_2(GLOBALS->yylen_vcd_c_1+1); strcpy(v->id, GLOBALS->yytext_vcd_c_1); v->nid=vcdid_hash(GLOBALS->yytext_vcd_c_1,GLOBALS->yylen_vcd_c_1); if(v->nid == (GLOBALS->vcd_hash_max+1)) { GLOBALS->vcd_hash_max = v->nid; } else if((v->nid>0)&&(v->nid<=GLOBALS->vcd_hash_max)) { /* general case with aliases */ } else { GLOBALS->vcd_hash_kill = 1; } if(v->nid < GLOBALS->vcd_minid_vcd_c_1) GLOBALS->vcd_minid_vcd_c_1 = v->nid; if(v->nid > GLOBALS->vcd_maxid_vcd_c_1) GLOBALS->vcd_maxid_vcd_c_1 = v->nid; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; if(GLOBALS->slisthier_len) { v->name=(char *)malloc_2(GLOBALS->slisthier_len+1+GLOBALS->yylen_vcd_c_1+1); strcpy(v->name,GLOBALS->slisthier); strcpy(v->name+GLOBALS->slisthier_len,GLOBALS->vcd_hier_delimeter); if(GLOBALS->alt_hier_delimeter) { strcpy_vcdalt(v->name+GLOBALS->slisthier_len+1,GLOBALS->yytext_vcd_c_1,GLOBALS->alt_hier_delimeter); } else { if((strcpy_delimfix(v->name+GLOBALS->slisthier_len+1,GLOBALS->yytext_vcd_c_1)) && (GLOBALS->yytext_vcd_c_1[0] != '\\')) { char *sd=(char *)malloc_2(GLOBALS->slisthier_len+1+GLOBALS->yylen_vcd_c_1+2); strcpy(sd,GLOBALS->slisthier); strcpy(sd+GLOBALS->slisthier_len,GLOBALS->vcd_hier_delimeter); sd[GLOBALS->slisthier_len+1] = '\\'; strcpy(sd+GLOBALS->slisthier_len+2,v->name+GLOBALS->slisthier_len+1); free_2(v->name); v->name = sd; } } } else { v->name=(char *)malloc_2(GLOBALS->yylen_vcd_c_1+1); if(GLOBALS->alt_hier_delimeter) { strcpy_vcdalt(v->name,GLOBALS->yytext_vcd_c_1,GLOBALS->alt_hier_delimeter); } else { if((strcpy_delimfix(v->name,GLOBALS->yytext_vcd_c_1)) && (GLOBALS->yytext_vcd_c_1[0] != '\\')) { char *sd=(char *)malloc_2(GLOBALS->yylen_vcd_c_1+2); sd[0] = '\\'; strcpy(sd+1,v->name); free_2(v->name); v->name = sd; } } } if(GLOBALS->pv_vcd_c_1) { if(!strcmp(GLOBALS->pv_vcd_c_1->name,v->name) && !disable_autocoalesce && (!strchr(v->name, '\\'))) { GLOBALS->pv_vcd_c_1->chain=v; v->root=GLOBALS->rootv_vcd_c_1; if(GLOBALS->pv_vcd_c_1==GLOBALS->rootv_vcd_c_1) GLOBALS->pv_vcd_c_1->root=GLOBALS->rootv_vcd_c_1; } else { GLOBALS->rootv_vcd_c_1=v; } } else { GLOBALS->rootv_vcd_c_1=v; } GLOBALS->pv_vcd_c_1=v; } else /* regular vcd var, not an evcd port var */ { vtok=get_vartoken(1); if(vtok==V_END) goto err; v->size=atoi_64(GLOBALS->yytext_vcd_c_1); vtok=get_strtoken(); if(vtok==V_END) goto err; v->id=(char *)malloc_2(GLOBALS->yylen_vcd_c_1+1); strcpy(v->id, GLOBALS->yytext_vcd_c_1); v->nid=vcdid_hash(GLOBALS->yytext_vcd_c_1,GLOBALS->yylen_vcd_c_1); if(v->nid == (GLOBALS->vcd_hash_max+1)) { GLOBALS->vcd_hash_max = v->nid; } else if((v->nid>0)&&(v->nid<=GLOBALS->vcd_hash_max)) { /* general case with aliases */ } else { GLOBALS->vcd_hash_kill = 1; } if(v->nid < GLOBALS->vcd_minid_vcd_c_1) GLOBALS->vcd_minid_vcd_c_1 = v->nid; if(v->nid > GLOBALS->vcd_maxid_vcd_c_1) GLOBALS->vcd_maxid_vcd_c_1 = v->nid; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; if(GLOBALS->slisthier_len) { v->name=(char *)malloc_2(GLOBALS->slisthier_len+1+GLOBALS->yylen_vcd_c_1+1); strcpy(v->name,GLOBALS->slisthier); strcpy(v->name+GLOBALS->slisthier_len,GLOBALS->vcd_hier_delimeter); if(GLOBALS->alt_hier_delimeter) { strcpy_vcdalt(v->name+GLOBALS->slisthier_len+1,GLOBALS->yytext_vcd_c_1,GLOBALS->alt_hier_delimeter); } else { if((strcpy_delimfix(v->name+GLOBALS->slisthier_len+1,GLOBALS->yytext_vcd_c_1)) && (GLOBALS->yytext_vcd_c_1[0] != '\\')) { char *sd=(char *)malloc_2(GLOBALS->slisthier_len+1+GLOBALS->yylen_vcd_c_1+2); strcpy(sd,GLOBALS->slisthier); strcpy(sd+GLOBALS->slisthier_len,GLOBALS->vcd_hier_delimeter); sd[GLOBALS->slisthier_len+1] = '\\'; strcpy(sd+GLOBALS->slisthier_len+2,v->name+GLOBALS->slisthier_len+1); free_2(v->name); v->name = sd; } } } else { v->name=(char *)malloc_2(GLOBALS->yylen_vcd_c_1+1); if(GLOBALS->alt_hier_delimeter) { strcpy_vcdalt(v->name,GLOBALS->yytext_vcd_c_1,GLOBALS->alt_hier_delimeter); } else { if((strcpy_delimfix(v->name,GLOBALS->yytext_vcd_c_1)) && (GLOBALS->yytext_vcd_c_1[0] != '\\')) { char *sd=(char *)malloc_2(GLOBALS->yylen_vcd_c_1+2); sd[0] = '\\'; strcpy(sd+1,v->name); free_2(v->name); v->name = sd; } } } if(GLOBALS->pv_vcd_c_1) { if(!strcmp(GLOBALS->pv_vcd_c_1->name,v->name)) { GLOBALS->pv_vcd_c_1->chain=v; v->root=GLOBALS->rootv_vcd_c_1; if(GLOBALS->pv_vcd_c_1==GLOBALS->rootv_vcd_c_1) GLOBALS->pv_vcd_c_1->root=GLOBALS->rootv_vcd_c_1; } else { GLOBALS->rootv_vcd_c_1=v; } } else { GLOBALS->rootv_vcd_c_1=v; } GLOBALS->pv_vcd_c_1=v; vtok=get_vartoken(1); if(vtok==V_END) goto dumpv; if(vtok!=V_LB) goto err; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; v->msi=atoi_64(GLOBALS->yytext_vcd_c_1); vtok=get_vartoken(0); if(vtok==V_RB) { v->lsi=v->msi; goto dumpv; } if(vtok!=V_COLON) goto err; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; v->lsi=atoi_64(GLOBALS->yytext_vcd_c_1); vtok=get_vartoken(0); if(vtok!=V_RB) goto err; } dumpv: if(v->size == 0) { if(v->vartype != V_EVENT) { if(v->vartype != V_STRINGTYPE) { v->vartype = V_REAL; } } else { v->size = 1; } } /* MTI fix */ if((v->vartype==V_REAL)||(v->vartype==V_STRINGTYPE)||((GLOBALS->convert_to_reals)&&((v->vartype==V_INTEGER)||(v->vartype==V_PARAMETER)))) { if(v->vartype!=V_STRINGTYPE) { v->vartype=V_REAL; } v->size=1; /* override any data we parsed in */ v->msi=v->lsi=0; } else if((v->size>1)&&(v->msi<=0)&&(v->lsi<=0)) { if(v->vartype==V_EVENT) { v->size=1; } else { /* any criteria for the direction here? */ v->msi=v->size-1; v->lsi=0; } } else if((v->msi>v->lsi)&&((v->msi-v->lsi+1)!=v->size)) { if((v->vartype!=V_EVENT)&&(v->vartype!=V_PARAMETER)) { v->msi = v->size-1; v->lsi = 0; /* all this formerly was goto err; */ } else { v->size=v->msi-v->lsi+1; } } else if((v->lsi>=v->msi)&&((v->lsi-v->msi+1)!=v->size)) { if((v->vartype!=V_EVENT)&&(v->vartype!=V_PARAMETER)) { v->lsi = v->size-1; v->msi = 0; /* all this formerly was goto err; */ } else { v->size=v->lsi-v->msi+1; } } /* initial conditions */ v->value=(char *)malloc_2(v->size+1); v->value[v->size]=0; v->narray=(struct Node **)calloc_2(v->size,sizeof(struct Node *)); { int i; if(GLOBALS->atomic_vectors) { for(i=0;isize;i++) { v->value[i]='x'; } v->narray[0]=(struct Node *)calloc_2(1,sizeof(struct Node)); v->narray[0]->head.time=-1; v->narray[0]->head.v.h_val=AN_X; set_vcd_vartype(v, v->narray[0]); } else { for(i=0;isize;i++) { v->value[i]='x'; v->narray[i]=(struct Node *)calloc_2(1,sizeof(struct Node)); v->narray[i]->head.time=-1; v->narray[i]->head.v.h_val=AN_X; if(i == 0) { set_vcd_vartype(v, v->narray[0]); } else { v->narray[i]->vartype = v->narray[0]->vartype; } } } } if(!GLOBALS->vcdsymroot_vcd_c_1) { GLOBALS->vcdsymroot_vcd_c_1=GLOBALS->vcdsymcurr_vcd_c_1=v; } else { GLOBALS->vcdsymcurr_vcd_c_1->next=v; GLOBALS->vcdsymcurr_vcd_c_1=v; } GLOBALS->numsyms_vcd_c_1++; if(GLOBALS->vcd_save_handle) { if(v->msi==v->lsi) { if((v->vartype==V_REAL)||(v->vartype==V_STRINGTYPE)) { fprintf(GLOBALS->vcd_save_handle,"%s\n",v->name); } else { if(v->msi>=0) { if(!GLOBALS->vcd_explicit_zero_subscripts) fprintf(GLOBALS->vcd_save_handle,"%s%c%d\n",v->name,GLOBALS->hier_delimeter,v->msi); else fprintf(GLOBALS->vcd_save_handle,"%s[%d]\n",v->name,v->msi); } else { fprintf(GLOBALS->vcd_save_handle,"%s\n",v->name); } } } else { int i; if(!GLOBALS->atomic_vectors) { fprintf(GLOBALS->vcd_save_handle,"#%s[%d:%d]",v->name,v->msi,v->lsi); if(v->msi>v->lsi) { for(i=v->msi;i>=v->lsi;i--) { if(!GLOBALS->vcd_explicit_zero_subscripts) fprintf(GLOBALS->vcd_save_handle," %s%c%d",v->name,GLOBALS->hier_delimeter,i); else fprintf(GLOBALS->vcd_save_handle," %s[%d]",v->name,i); } } else { for(i=v->msi;i<=v->lsi;i++) { if(!GLOBALS->vcd_explicit_zero_subscripts) fprintf(GLOBALS->vcd_save_handle," %s%c%d",v->name,GLOBALS->hier_delimeter,i); else fprintf(GLOBALS->vcd_save_handle," %s[%d]",v->name,i); } } fprintf(GLOBALS->vcd_save_handle,"\n"); } else { fprintf(GLOBALS->vcd_save_handle,"%s[%d:%d]\n",v->name,v->msi,v->lsi); } } } goto bail; err: if(v) { GLOBALS->error_count_vcd_c_1++; if(v->name) { fprintf(stderr, "Near byte %d, $VAR parse error encountered with '%s'\n", (int)(GLOBALS->vcdbyteno_vcd_c_1+(GLOBALS->vst_vcd_c_1-GLOBALS->vcdbuf_vcd_c_1)), v->name); free_2(v->name); } else { fprintf(stderr, "Near byte %d, $VAR parse error encountered\n", (int)(GLOBALS->vcdbyteno_vcd_c_1+(GLOBALS->vst_vcd_c_1-GLOBALS->vcdbuf_vcd_c_1))); } if(v->id) free_2(v->id); if(v->value) free_2(v->value); free_2(v); GLOBALS->pv_vcd_c_1 = NULL; } bail: if(vtok!=V_END) sync_end(NULL); break; } case T_ENDDEFINITIONS: GLOBALS->header_over_vcd_c_1=1; /* do symbol table management here */ create_sorted_table(); if((!GLOBALS->sorted_vcd_c_1)&&(!GLOBALS->indexed_vcd_c_1)) { fprintf(stderr, "No symbols in VCD file..nothing to do!\n"); vcd_exit(255); } if(GLOBALS->error_count_vcd_c_1) { fprintf(stderr, "\n%d VCD parse errors encountered, exiting.\n", GLOBALS->error_count_vcd_c_1); vcd_exit(255); } break; case T_STRING: if(!GLOBALS->header_over_vcd_c_1) { GLOBALS->header_over_vcd_c_1=1; /* do symbol table management here */ create_sorted_table(); if((!GLOBALS->sorted_vcd_c_1)&&(!GLOBALS->indexed_vcd_c_1)) break; } { /* catchall for events when header over */ if(GLOBALS->yytext_vcd_c_1[0]=='#') { TimeType tim; tim=atoi_64(GLOBALS->yytext_vcd_c_1+1); if(GLOBALS->start_time_vcd_c_1<0) { GLOBALS->start_time_vcd_c_1=tim; } else { if(tim < GLOBALS->current_time_vcd_c_1) /* avoid backtracking time counts which can happen on malformed files */ { tim = GLOBALS->current_time_vcd_c_1; } } GLOBALS->current_time_vcd_c_1=tim; if(GLOBALS->end_time_vcd_c_1end_time_vcd_c_1=tim; /* in case of malformed vcd files */ DEBUG(fprintf(stderr,"#"TTFormat"\n",tim)); } else { parse_valuechange(); } } break; case T_DUMPALL: /* dump commands modify vals anyway so */ case T_DUMPPORTSALL: break; /* just loop through.. */ case T_DUMPOFF: case T_DUMPPORTSOFF: GLOBALS->dumping_off_vcd_c_1=1; if((!GLOBALS->blackout_regions)||((GLOBALS->blackout_regions)&&(GLOBALS->blackout_regions->bstart<=GLOBALS->blackout_regions->bend))) { struct blackout_region_t *bt = calloc_2(1, sizeof(struct blackout_region_t)); bt->bstart = GLOBALS->current_time_vcd_c_1; bt->next = GLOBALS->blackout_regions; GLOBALS->blackout_regions = bt; } break; case T_DUMPON: case T_DUMPPORTSON: GLOBALS->dumping_off_vcd_c_1=0; if((GLOBALS->blackout_regions)&&(GLOBALS->blackout_regions->bstart>GLOBALS->blackout_regions->bend)) { GLOBALS->blackout_regions->bend = GLOBALS->current_time_vcd_c_1; } break; case T_DUMPVARS: case T_DUMPPORTS: if(GLOBALS->current_time_vcd_c_1<0) { GLOBALS->start_time_vcd_c_1=GLOBALS->current_time_vcd_c_1=GLOBALS->end_time_vcd_c_1=0; } break; case T_VCDCLOSE: sync_end("VCDCLOSE:"); break; /* next token will be '#' time related followed by $end */ case T_END: /* either closure for dump commands or */ break; /* it's spurious */ case T_UNKNOWN_KEY: sync_end(NULL); /* skip over unknown keywords */ break; case T_EOF: if((GLOBALS->blackout_regions)&&(GLOBALS->blackout_regions->bstart>GLOBALS->blackout_regions->bend)) { GLOBALS->blackout_regions->bend = GLOBALS->current_time_vcd_c_1; } return; default: DEBUG(fprintf(stderr,"UNKNOWN TOKEN\n")); } } } /*******************************************************************************/ void add_histent(TimeType tim, struct Node *n, char ch, int regadd, char *vector) { struct HistEnt *he; char heval; if(!vector) { if(!n->curr) { he=histent_calloc(); he->time=-1; he->v.h_val=AN_X; n->curr=he; n->head.next=he; add_histent(tim,n,ch,regadd, vector); } else { if(regadd) { tim*=(GLOBALS->time_scale); } if(ch=='0') heval=AN_0; else if(ch=='1') heval=AN_1; else if((ch=='x')||(ch=='X')) heval=AN_X; else if((ch=='z')||(ch=='Z')) heval=AN_Z; else if((ch=='h')||(ch=='H')) heval=AN_H; else if((ch=='u')||(ch=='U')) heval=AN_U; else if((ch=='w')||(ch=='W')) heval=AN_W; else if((ch=='l')||(ch=='L')) heval=AN_L; else /* if(ch=='-') */ heval=AN_DASH; /* default */ if((n->curr->v.h_val!=heval)||(tim==GLOBALS->start_time_vcd_c_1)||(n->vartype==ND_VCD_EVENT)||(GLOBALS->vcd_preserve_glitches)) /* same region == go skip */ { if(n->curr->time==tim) { DEBUG(printf("Warning: Glitch at time ["TTFormat"] Signal [%p], Value [%c->%c].\n", tim, n, AN_STR[n->curr->v.h_val], ch)); n->curr->v.h_val=heval; /* we have a glitch! */ GLOBALS->num_glitches_vcd_c_2++; if(!(n->curr->flags&HIST_GLITCH)) { n->curr->flags|=HIST_GLITCH; /* set the glitch flag */ GLOBALS->num_glitch_regions_vcd_c_2++; } } else { he=histent_calloc(); he->time=tim; he->v.h_val=heval; n->curr->next=he; n->curr=he; GLOBALS->regions+=regadd; } } } } else { switch(ch) { case 's': /* string */ { if(!n->curr) { he=histent_calloc(); he->flags=(HIST_STRING|HIST_REAL); he->time=-1; he->v.h_vector=NULL; n->curr=he; n->head.next=he; add_histent(tim,n,ch,regadd, vector); } else { if(regadd) { tim*=(GLOBALS->time_scale); } if(n->curr->time==tim) { DEBUG(printf("Warning: String Glitch at time ["TTFormat"] Signal [%p].\n", tim, n)); if(n->curr->v.h_vector) free_2(n->curr->v.h_vector); n->curr->v.h_vector=vector; /* we have a glitch! */ GLOBALS->num_glitches_vcd_c_2++; if(!(n->curr->flags&HIST_GLITCH)) { n->curr->flags|=HIST_GLITCH; /* set the glitch flag */ GLOBALS->num_glitch_regions_vcd_c_2++; } } else { he=histent_calloc(); he->flags=(HIST_STRING|HIST_REAL); he->time=tim; he->v.h_vector=vector; n->curr->next=he; n->curr=he; GLOBALS->regions+=regadd; } } break; } case 'g': /* real number */ { if(!n->curr) { he=histent_calloc(); he->flags=HIST_REAL; he->time=-1; #ifdef WAVE_HAS_H_DOUBLE he->v.h_double = strtod("NaN", NULL); #else he->v.h_vector=NULL; #endif n->curr=he; n->head.next=he; add_histent(tim,n,ch,regadd, vector); } else { if(regadd) { tim*=(GLOBALS->time_scale); } if( #ifdef WAVE_HAS_H_DOUBLE (vector&&(n->curr->v.h_double!=*(double *)vector)) #else (n->curr->v.h_vector&&vector&&(*(double *)n->curr->v.h_vector!=*(double *)vector)) #endif ||(tim==GLOBALS->start_time_vcd_c_1) #ifndef WAVE_HAS_H_DOUBLE ||(!n->curr->v.h_vector) #endif ||(GLOBALS->vcd_preserve_glitches)||(GLOBALS->vcd_preserve_glitches_real) ) /* same region == go skip */ { if(n->curr->time==tim) { DEBUG(printf("Warning: Real number Glitch at time ["TTFormat"] Signal [%p].\n", tim, n)); #ifdef WAVE_HAS_H_DOUBLE n->curr->v.h_double = *((double *)vector); #else if(n->curr->v.h_vector) free_2(n->curr->v.h_vector); n->curr->v.h_vector=vector; /* we have a glitch! */ #endif GLOBALS->num_glitches_vcd_c_2++; if(!(n->curr->flags&HIST_GLITCH)) { n->curr->flags|=HIST_GLITCH; /* set the glitch flag */ GLOBALS->num_glitch_regions_vcd_c_2++; } } else { he=histent_calloc(); he->flags=HIST_REAL; he->time=tim; #ifdef WAVE_HAS_H_DOUBLE he->v.h_double = *((double *)vector); #else he->v.h_vector=vector; #endif n->curr->next=he; n->curr=he; GLOBALS->regions+=regadd; } } else { #ifndef WAVE_HAS_H_DOUBLE free_2(vector); #endif } #ifdef WAVE_HAS_H_DOUBLE free_2(vector); #endif } break; } default: { if(!n->curr) { he=histent_calloc(); he->time=-1; he->v.h_vector=NULL; n->curr=he; n->head.next=he; add_histent(tim,n,ch,regadd, vector); } else { if(regadd) { tim*=(GLOBALS->time_scale); } if( (n->curr->v.h_vector&&vector&&(strcmp(n->curr->v.h_vector,vector))) ||(tim==GLOBALS->start_time_vcd_c_1) ||(!n->curr->v.h_vector) ||(GLOBALS->vcd_preserve_glitches) ) /* same region == go skip */ { if(n->curr->time==tim) { DEBUG(printf("Warning: Glitch at time ["TTFormat"] Signal [%p], Value [%c->%c].\n", tim, n, AN_STR[n->curr->v.h_val], ch)); if(n->curr->v.h_vector) free_2(n->curr->v.h_vector); n->curr->v.h_vector=vector; /* we have a glitch! */ GLOBALS->num_glitches_vcd_c_2++; if(!(n->curr->flags&HIST_GLITCH)) { n->curr->flags|=HIST_GLITCH; /* set the glitch flag */ GLOBALS->num_glitch_regions_vcd_c_2++; } } else { he=histent_calloc(); he->time=tim; he->v.h_vector=vector; n->curr->next=he; n->curr=he; GLOBALS->regions+=regadd; } } else { free_2(vector); } } break; } } } } void set_vcd_vartype(struct vcdsymbol *v, nptr n) { unsigned char nvt; switch(v->vartype) { case V_EVENT: nvt = ND_VCD_EVENT; break; case V_PARAMETER: nvt = ND_VCD_PARAMETER; break; case V_INTEGER: nvt = ND_VCD_INTEGER; break; case V_REAL: nvt = ND_VCD_REAL; break; case V_REG: nvt = ND_VCD_REG; break; case V_SUPPLY0: nvt = ND_VCD_SUPPLY0; break; case V_SUPPLY1: nvt = ND_VCD_SUPPLY1; break; case V_TIME: nvt = ND_VCD_TIME; break; case V_TRI: nvt = ND_VCD_TRI; break; case V_TRIAND: nvt = ND_VCD_TRIAND; break; case V_TRIOR: nvt = ND_VCD_TRIOR; break; case V_TRIREG: nvt = ND_VCD_TRIREG; break; case V_TRI0: nvt = ND_VCD_TRI0; break; case V_TRI1: nvt = ND_VCD_TRI1; break; case V_WAND: nvt = ND_VCD_WAND; break; case V_WIRE: nvt = ND_VCD_WIRE; break; case V_WOR: nvt = ND_VCD_WOR; break; case V_PORT: nvt = ND_VCD_PORT; break; case V_STRINGTYPE: nvt = ND_GEN_STRING; break; case V_BIT: nvt = ND_SV_BIT; break; case V_LOGIC: nvt = ND_SV_LOGIC; break; case V_INT: nvt = ND_SV_INT; break; case V_SHORTINT: nvt = ND_SV_SHORTINT; break; case V_LONGINT: nvt = ND_SV_LONGINT; break; case V_BYTE: nvt = ND_SV_BYTE; break; case V_ENUM: nvt = ND_SV_ENUM; break; /* V_SHORTREAL as a type does not exist for VCD: is cast to V_REAL */ default: nvt = ND_UNSPECIFIED_DEFAULT; break; } n->vartype = nvt; } static void add_tail_histents(void) { int j; struct vcdsymbol *v; /* dump out any pending events 1st (removed) */ /* then do 'x' trailers */ v=GLOBALS->vcdsymroot_vcd_c_1; while(v) { if((v->vartype==V_REAL)||(v->vartype==V_STRINGTYPE)) { double *d; d=malloc_2(sizeof(double)); *d=1.0; add_histent(MAX_HISTENT_TIME-1, v->narray[0], 'g', 0, (char *)d); } else if((v->size==1)||(!GLOBALS->atomic_vectors)) for(j=0;jsize;j++) { add_histent(MAX_HISTENT_TIME-1, v->narray[j], 'x', 0, NULL); } else { add_histent(MAX_HISTENT_TIME-1, v->narray[0], 'x', 0, (char *)calloc_2(1,sizeof(char))); } v=v->next; } v=GLOBALS->vcdsymroot_vcd_c_1; while(v) { if((v->vartype==V_REAL)||(v->vartype==V_STRINGTYPE)) { double *d; d=malloc_2(sizeof(double)); *d=0.0; add_histent(MAX_HISTENT_TIME, v->narray[0], 'g', 0, (char *)d); } else if((v->size==1)||(!GLOBALS->atomic_vectors)) for(j=0;jsize;j++) { add_histent(MAX_HISTENT_TIME, v->narray[j], 'z', 0, NULL); } else { add_histent(MAX_HISTENT_TIME, v->narray[0], 'z', 0, (char *)calloc_2(1,sizeof(char))); } v=v->next; } } /*******************************************************************************/ static void vcd_build_symbols(void) { int j; int max_slen=-1; struct sym_chain *sym_chain=NULL, *sym_curr=NULL; int duphier=0; char hashdirty; struct vcdsymbol *v, *vprime; char *str = wave_alloca(1); /* quiet scan-build null pointer warning below */ #ifdef _WAVE_HAVE_JUDY int ss_len, longest = 0; #endif v=GLOBALS->vcdsymroot_vcd_c_1; while(v) { int msi; int delta; { int slen; int substnode; msi=v->msi; delta=((v->lsi-v->msi)<0)?-1:1; substnode=0; slen=strlen(v->name); str=(slen>max_slen)?(wave_alloca((max_slen=slen)+32)):(str); /* more than enough */ strcpy(str,v->name); if(v->msi>=0) { strcpy(str+slen,GLOBALS->vcd_hier_delimeter); slen++; } if((vprime=bsearch_vcd(v->id, strlen(v->id)))!=v) /* hash mish means dup net */ { if(v->size!=vprime->size) { fprintf(stderr,"ERROR: Duplicate IDs with differing width: %s %s\n", v->name, vprime->name); } else { substnode=1; } } if(((v->size==1)||(!GLOBALS->atomic_vectors))&&(v->vartype!=V_REAL)&&(v->vartype!=V_STRINGTYPE)) { struct symbol *s = NULL; for(j=0;jsize;j++) { if(v->msi>=0) { if(!GLOBALS->vcd_explicit_zero_subscripts) sprintf(str+slen,"%d",msi); else sprintf(str+slen-1,"[%d]",msi); } hashdirty=0; if(symfind(str, NULL)) { char *dupfix=(char *)malloc_2(max_slen+32); #ifndef _WAVE_HAVE_JUDY hashdirty=1; #endif DEBUG(fprintf(stderr,"Warning: %s is a duplicate net name.\n",str)); do sprintf(dupfix, "$DUP%d%s%s", duphier++, GLOBALS->vcd_hier_delimeter, str); while(symfind(dupfix, NULL)); strcpy(str, dupfix); free_2(dupfix); duphier=0; /* reset for next duplicate resolution */ } /* fallthrough */ { s=symadd(str,hashdirty?hash(str):GLOBALS->hashcache); #ifdef _WAVE_HAVE_JUDY ss_len = strlen(str); if(ss_len >= longest) { longest = ss_len + 1; } #endif s->n=v->narray[j]; if(substnode) { struct Node *n, *n2; n=s->n; n2=vprime->narray[j]; /* nname stays same */ n->head=n2->head; n->curr=n2->curr; /* harray calculated later */ n->numhist=n2->numhist; } #ifndef _WAVE_HAVE_JUDY s->n->nname=s->name; #endif if(!GLOBALS->firstnode) { GLOBALS->firstnode= GLOBALS->curnode=calloc_2(1, sizeof(struct symchain)); } else { GLOBALS->curnode->next=calloc_2(1, sizeof(struct symchain)); GLOBALS->curnode=GLOBALS->curnode->next; } GLOBALS->curnode->symbol=s; GLOBALS->numfacs++; DEBUG(fprintf(stderr,"Added: %s\n",str)); } msi+=delta; } if((j==1)&&(v->root)) { s->vec_root=(struct symbol *)v->root; /* these will get patched over */ s->vec_chain=(struct symbol *)v->chain; /* these will get patched over */ v->sym_chain=s; if(!sym_chain) { sym_curr=(struct sym_chain *)calloc_2(1,sizeof(struct sym_chain)); sym_chain=sym_curr; } else { sym_curr->next=(struct sym_chain *)calloc_2(1,sizeof(struct sym_chain)); sym_curr=sym_curr->next; } sym_curr->val=s; } } else /* atomic vector */ { if((v->vartype!=V_REAL)&&(v->vartype!=V_STRINGTYPE)&&(v->vartype!=V_INTEGER)&&(v->vartype!=V_PARAMETER)) /* if((v->vartype!=V_REAL)&&(v->vartype!=V_STRINGTYPE)) */ { sprintf(str+slen-1,"[%d:%d]",v->msi,v->lsi); } else { *(str+slen-1)=0; } hashdirty=0; if(symfind(str, NULL)) { char *dupfix=(char *)malloc_2(max_slen+32); #ifndef _WAVE_HAVE_JUDY hashdirty=1; #endif DEBUG(fprintf(stderr,"Warning: %s is a duplicate net name.\n",str)); do sprintf(dupfix, "$DUP%d%s%s", duphier++, GLOBALS->vcd_hier_delimeter, str); while(symfind(dupfix, NULL)); strcpy(str, dupfix); free_2(dupfix); duphier=0; /* reset for next duplicate resolution */ } /* fallthrough */ { struct symbol *s; s=symadd(str,hashdirty?hash(str):GLOBALS->hashcache); /* cut down on double lookups.. */ #ifdef _WAVE_HAVE_JUDY ss_len = strlen(str); if(ss_len >= longest) { longest = ss_len + 1; } #endif s->n=v->narray[0]; if(substnode) { struct Node *n, *n2; n=s->n; n2=vprime->narray[0]; /* nname stays same */ n->head=n2->head; n->curr=n2->curr; /* harray calculated later */ n->numhist=n2->numhist; n->extvals=n2->extvals; n->msi=n2->msi; n->lsi=n2->lsi; } else { s->n->msi=v->msi; s->n->lsi=v->lsi; s->n->extvals=1; } #ifndef _WAVE_HAVE_JUDY s->n->nname=s->name; #endif if(!GLOBALS->firstnode) { GLOBALS->firstnode= GLOBALS->curnode=calloc_2(1, sizeof(struct symchain)); } else { GLOBALS->curnode->next=calloc_2(1, sizeof(struct symchain)); GLOBALS->curnode=GLOBALS->curnode->next; } GLOBALS->curnode->symbol=s; GLOBALS->numfacs++; DEBUG(fprintf(stderr,"Added: %s\n",str)); } } } v=v->next; } #ifdef _WAVE_HAVE_JUDY { Pvoid_t PJArray = GLOBALS->sym_judy; PPvoid_t PPValue; char *Index = calloc_2(1, longest); for (PPValue = JudySLFirst (PJArray, (uint8_t *)Index, PJE0); PPValue != (PPvoid_t) NULL; PPValue = JudySLNext (PJArray, (uint8_t *)Index, PJE0)) { struct symbol *s = *(struct symbol **)PPValue; s->name = strdup_2(Index); s->n->nname = s->name; } free_2(Index); } #endif if(sym_chain) { sym_curr=sym_chain; while(sym_curr) { sym_curr->val->vec_root= ((struct vcdsymbol *)sym_curr->val->vec_root)->sym_chain; if ((struct vcdsymbol *)sym_curr->val->vec_chain) sym_curr->val->vec_chain=((struct vcdsymbol *)sym_curr->val->vec_chain)->sym_chain; DEBUG(printf("Link: ('%s') '%s' -> '%s'\n",sym_curr->val->vec_root->name, sym_curr->val->name, sym_curr->val->vec_chain?sym_curr->val->vec_chain->name:"(END)")); sym_chain=sym_curr; sym_curr=sym_curr->next; free_2(sym_chain); } } } /*******************************************************************************/ void vcd_sortfacs(void) { int i; GLOBALS->facs=(struct symbol **)malloc_2(GLOBALS->numfacs*sizeof(struct symbol *)); GLOBALS->curnode=GLOBALS->firstnode; for(i=0;inumfacs;i++) { char *subst; #ifdef WAVE_HIERFIX char ch; #endif int len; struct symchain *sc; GLOBALS->facs[i]=GLOBALS->curnode->symbol; subst=GLOBALS->facs[i]->name; if((len=strlen(subst))>GLOBALS->longestname) GLOBALS->longestname=len; sc = GLOBALS->curnode; GLOBALS->curnode=GLOBALS->curnode->next; free_2(sc); #ifdef WAVE_HIERFIX while((ch=(*subst))) { if(ch==GLOBALS->hier_delimeter) { *subst=VCDNAM_HIERSORT; } /* forces sort at hier boundaries */ subst++; } #endif } GLOBALS->firstnode=GLOBALS->curnode=NULL; /* quicksort(facs,0,numfacs-1); */ /* quicksort deprecated because it degenerates on sorted traces..badly. very badly. */ wave_heapsort(GLOBALS->facs,GLOBALS->numfacs); #ifdef WAVE_HIERFIX for(i=0;inumfacs;i++) { char *subst, ch; subst=GLOBALS->facs[i]->name; while((ch=(*subst))) { if(ch==VCDNAM_HIERSORT) { *subst=GLOBALS->hier_delimeter; } /* restore back to normal */ subst++; } #ifdef DEBUG_FACILITIES printf("%-4d %s\n",i,facs[i]->name); #endif } #endif GLOBALS->facs_are_sorted=1; init_tree(); for(i=0;inumfacs;i++) { char *n = GLOBALS->facs[i]->name; build_tree_from_name(n, i); if(GLOBALS->escaped_names_found_vcd_c_1) { char *subst, ch; subst=GLOBALS->facs[i]->name; while((ch=(*subst))) { if(ch==VCDNAM_ESCAPE) { *subst=GLOBALS->hier_delimeter; } /* restore back to normal */ subst++; } } } treegraft(&GLOBALS->treeroot); treesort(GLOBALS->treeroot, NULL); if(GLOBALS->escaped_names_found_vcd_c_1) { treenamefix(GLOBALS->treeroot); } } /*******************************************************************************/ static void vcd_cleanup(void) { struct slist *s, *s2; struct vcdsymbol *v, *vt; if(GLOBALS->indexed_vcd_c_1) { free_2(GLOBALS->indexed_vcd_c_1); GLOBALS->indexed_vcd_c_1=NULL; } if(GLOBALS->sorted_vcd_c_1) { free_2(GLOBALS->sorted_vcd_c_1); GLOBALS->sorted_vcd_c_1=NULL; } v=GLOBALS->vcdsymroot_vcd_c_1; while(v) { if(v->name) free_2(v->name); if(v->id) free_2(v->id); if(v->value) free_2(v->value); if(v->narray) free_2(v->narray); vt=v; v=v->next; free_2(vt); } GLOBALS->vcdsymroot_vcd_c_1=GLOBALS->vcdsymcurr_vcd_c_1=NULL; if(GLOBALS->slisthier) { free_2(GLOBALS->slisthier); GLOBALS->slisthier=NULL; } s=GLOBALS->slistroot; while(s) { s2=s->next; if(s->str)free_2(s->str); free_2(s); s=s2; } GLOBALS->slistroot=GLOBALS->slistcurr=NULL; GLOBALS->slisthier_len=0; if(GLOBALS->vcd_is_compressed_vcd_c_1) { pclose(GLOBALS->vcd_handle_vcd_c_1); GLOBALS->vcd_handle_vcd_c_1 = NULL; } else { fclose(GLOBALS->vcd_handle_vcd_c_1); GLOBALS->vcd_handle_vcd_c_1 = NULL; } if(GLOBALS->yytext_vcd_c_1) { free_2(GLOBALS->yytext_vcd_c_1); GLOBALS->yytext_vcd_c_1=NULL; } } /*******************************************************************************/ TimeType vcd_main(char *fname) { GLOBALS->pv_vcd_c_1=GLOBALS->rootv_vcd_c_1=NULL; GLOBALS->vcd_hier_delimeter[0]=GLOBALS->hier_delimeter; errno=0; /* reset in case it's set for some reason */ GLOBALS->yytext_vcd_c_1=(char *)malloc_2(GLOBALS->T_MAX_STR_vcd_c_1+1); if(!GLOBALS->hier_was_explicitly_set) /* set default hierarchy split char */ { GLOBALS->hier_delimeter='.'; } if(suffix_check(fname, ".gz") || suffix_check(fname, ".zip")) { char *str; int dlen; dlen=strlen(WAVE_DECOMPRESSOR); str=wave_alloca(strlen(fname)+dlen+1); strcpy(str,WAVE_DECOMPRESSOR); strcpy(str+dlen,fname); GLOBALS->vcd_handle_vcd_c_1=popen(str,"r"); GLOBALS->vcd_is_compressed_vcd_c_1=~0; } else { if(strcmp("-vcd",fname)) { GLOBALS->vcd_handle_vcd_c_1=fopen(fname,"rb"); if(GLOBALS->vcd_handle_vcd_c_1) { fseeko(GLOBALS->vcd_handle_vcd_c_1, 0, SEEK_END); /* do status bar for vcd load */ GLOBALS->vcd_fsiz_vcd_c_1 = ftello(GLOBALS->vcd_handle_vcd_c_1); fseeko(GLOBALS->vcd_handle_vcd_c_1, 0, SEEK_SET); } if(GLOBALS->vcd_warning_filesize < 0) GLOBALS->vcd_warning_filesize = VCD_SIZE_WARN; if(GLOBALS->vcd_warning_filesize) if(GLOBALS->vcd_fsiz_vcd_c_1 > (GLOBALS->vcd_warning_filesize * (1024 * 1024))) { fprintf(stderr, "Warning! File size is %d MB. This might fail to load.\n" "Consider converting it to the FST database format instead. (See the\n" "vcd2fst(1) manpage for more information.)\n" "To disable this warning, set rc variable vcd_warning_filesize to zero.\n" "Alternatively, use the -o, --optimize command line option to convert to LXT2.\n\n", (int)(GLOBALS->vcd_fsiz_vcd_c_1/(1024*1024))); } } else { GLOBALS->vcd_handle_vcd_c_1=stdin; GLOBALS->splash_disable = 1; } GLOBALS->vcd_is_compressed_vcd_c_1=0; } if(!GLOBALS->vcd_handle_vcd_c_1) { fprintf(stderr, "Error opening %s .vcd file '%s'.\n", GLOBALS->vcd_is_compressed_vcd_c_1?"compressed":"", fname); perror("Why"); vcd_exit(255); } /* SPLASH */ splash_create(); sym_hash_initialize(GLOBALS); getch_alloc(); /* alloc membuff for vcd getch buffer */ build_slisthier(); vcd_parse(); if(GLOBALS->varsplit_vcd_c_1) { free_2(GLOBALS->varsplit_vcd_c_1); GLOBALS->varsplit_vcd_c_1=NULL; } if((!GLOBALS->sorted_vcd_c_1)&&(!GLOBALS->indexed_vcd_c_1)) { fprintf(stderr, "No symbols in VCD file..is it malformed? Exiting!\n"); vcd_exit(255); } add_tail_histents(); if(GLOBALS->vcd_save_handle) { fclose(GLOBALS->vcd_save_handle); GLOBALS->vcd_save_handle = NULL; } fprintf(stderr, "["TTFormat"] start time.\n["TTFormat"] end time.\n", GLOBALS->start_time_vcd_c_1*GLOBALS->time_scale, GLOBALS->end_time_vcd_c_1*GLOBALS->time_scale); if(GLOBALS->num_glitches_vcd_c_2) fprintf(stderr, "Warning: encountered %d glitch%s across %d glitch region%s.\n", GLOBALS->num_glitches_vcd_c_2, (GLOBALS->num_glitches_vcd_c_2!=1)?"es":"", GLOBALS->num_glitch_regions_vcd_c_2, (GLOBALS->num_glitch_regions_vcd_c_2!=1)?"s":""); if(GLOBALS->vcd_fsiz_vcd_c_1) { splash_sync(GLOBALS->vcd_fsiz_vcd_c_1, GLOBALS->vcd_fsiz_vcd_c_1); GLOBALS->vcd_fsiz_vcd_c_1 = 0; } else if(GLOBALS->vcd_is_compressed_vcd_c_1) { splash_sync(1,1); GLOBALS->vcd_fsiz_vcd_c_1 = 0; } GLOBALS->min_time=GLOBALS->start_time_vcd_c_1*GLOBALS->time_scale; GLOBALS->max_time=GLOBALS->end_time_vcd_c_1*GLOBALS->time_scale; GLOBALS->global_time_offset = GLOBALS->global_time_offset * GLOBALS->time_scale; if((GLOBALS->min_time==GLOBALS->max_time)&&(GLOBALS->max_time==LLDescriptor(-1))) { fprintf(stderr, "VCD times range is equal to zero. Exiting.\n"); vcd_exit(255); } vcd_build_symbols(); vcd_sortfacs(); vcd_cleanup(); getch_free(); /* free membuff for vcd getch buffer */ if(GLOBALS->blackout_regions) { struct blackout_region_t *bt = GLOBALS->blackout_regions; while(bt) { bt->bstart *= GLOBALS->time_scale; bt->bend *= GLOBALS->time_scale; bt = bt->next; } } GLOBALS->is_vcd=~0; /* SPLASH */ splash_finalize(); return(GLOBALS->max_time); } /*******************************************************************************/ gtkwave-3.3.66/src/vlist.c0000664000076400007640000004431112341266475014710 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2006-2014. * * 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 code implements generic vlists. (see the original paper from Phil Bagwell in 2002.) the original idea was to clean up histents by using vlist_alloc() to create a growable array that doesn't require next pointers per-element, however that doesn't seem necessary given the space savings that gzipped dormant vlist entries buys you. the vlists have been modified since the original version in two ways: (1) only half as many bytes are allocated as needed and when vlist_alloc() reaches the halfway point the struct is finally reallocated with the rest, (2) if vlist_spill is set to "on" in the rc file, vlist entries spill to a tempfile which can reduce memory usage dramatically. */ #include #include "globals.h" #include "vlist.h" #include #include void vlist_init_spillfile(void) { if(GLOBALS->use_fastload) { char *fname = malloc_2(strlen(GLOBALS->loaded_file_name) + 4 + 1); sprintf(fname, "%s.idx", GLOBALS->loaded_file_name); GLOBALS->vlist_handle = fopen(fname, "w+b"); free_2(fname); fputc('!', GLOBALS->vlist_handle); GLOBALS->vlist_bytes_written = 1; } else { #if defined _MSC_VER || defined __MINGW32__ GLOBALS->vlist_handle = tmpfile(); fputc('!', GLOBALS->vlist_handle); GLOBALS->vlist_bytes_written = 1; #else int fd_dummy; char *nam = tmpnam_2(NULL, &fd_dummy); GLOBALS->vlist_handle = fopen(nam, "w+b"); unlink(nam); if(fd_dummy >=0) { close(fd_dummy); free_2(nam); } fputc('!', GLOBALS->vlist_handle); GLOBALS->vlist_bytes_written = 1; #endif } } void vlist_kill_spillfile(void) { if(GLOBALS->vlist_handle) { fclose(GLOBALS->vlist_handle); GLOBALS->vlist_handle = NULL; } } /* machine-independent header i/o */ static int vlist_fread_hdr(struct vlist_t *vl, FILE *f) { unsigned long val; unsigned int vali; int ch, shamt, rc = 0; val = 0; shamt = 0; do { ch = fgetc(f); if(ch == EOF) goto bail; val |= ((unsigned long)(ch & 0x7f)) << shamt; shamt += 7; } while(!(ch & 0x80)); vl->next = (struct vlist_t *)val; vali = 0; shamt = 0; do { ch = fgetc(f); if(ch == EOF) goto bail; vali |= ((unsigned int)(ch & 0x7f)) << shamt; shamt += 7; } while(!(ch & 0x80)); vl->siz = (unsigned int)vali; vali = 0; shamt = 0; do { ch = fgetc(f); if(ch == EOF) goto bail; vali |= ((unsigned int)(ch & 0x7f)) << shamt; shamt += 7; } while(!(ch & 0x80)); vl->offs = (vali & 1) ? (unsigned int)(-(int)(vali >> 1)) : (vali >> 1); vali = 0; shamt = 0; do { ch = fgetc(f); if(ch == EOF) goto bail; vali |= ((unsigned int)(ch & 0x7f)) << shamt; shamt += 7; } while(!(ch & 0x80)); vl->elem_siz = (unsigned int)vali; rc = 1; bail: return(rc); } static int vlist_fwrite(struct vlist_t *vl, unsigned int rsiz, FILE *f) { unsigned char mem[ 4 * sizeof(long) * 2]; unsigned char *pnt = mem; unsigned long val, nxt; unsigned int vali, nxti; int offs_as_int; int rc; int len = 0; val = (unsigned long)(vl->next); while((nxt = val>>7)) { *(pnt++) = (val&0x7f); val = nxt; } *(pnt++) = (val&0x7f) | 0x80; vali = (vl->siz); while((nxti = vali>>7)) { *(pnt++) = (vali&0x7f); vali = nxti; } *(pnt++) = (vali&0x7f) | 0x80; offs_as_int = (int)(vl->offs); if(offs_as_int < 0) { offs_as_int = -offs_as_int; /* reduce number of one bits propagating left by making sign bit the lsb */ offs_as_int <<= 1; offs_as_int |= 1; } else { offs_as_int <<= 1; } vali = (unsigned int)(offs_as_int); while((nxti = vali>>7)) { *(pnt++) = (vali&0x7f); vali = nxti; } *(pnt++) = (vali&0x7f) | 0x80; vali = (unsigned int)(vl->elem_siz); while((nxti = vali>>7)) { *(pnt++) = (vali&0x7f); vali = nxti; } *(pnt++) = (vali&0x7f) | 0x80; rc = fwrite(mem, 1, (len = (pnt - mem)), f); if(rc) { unsigned int wrlen = (rsiz - sizeof(struct vlist_t)); len += wrlen; rc = fwrite(vl + 1, 1, wrlen, f); if(rc) { rc = len; } } return(rc); } /* create / destroy */ struct vlist_t *vlist_create(unsigned int elem_siz) { struct vlist_t *v; v = calloc_2(1, sizeof(struct vlist_t) + elem_siz); v->siz = 1; v->elem_siz = elem_siz; return(v); } void vlist_destroy(struct vlist_t *v) { struct vlist_t *vt; while(v) { vt = v->next; free_2(v); v = vt; } } /* realtime compression/decompression of bytewise vlists * this can obviously be extended if elem_siz > 1, but * the viewer doesn't need that feature */ struct vlist_t *vlist_compress_block(struct vlist_t *v, unsigned int *rsiz) { if(v->siz > 32) { struct vlist_t *vz; unsigned int *ipnt; char *dmem = malloc_2(compressBound(v->siz)); unsigned long destlen = v->siz; int rc; rc = compress2((unsigned char *)dmem, &destlen, (unsigned char *)(v+1), v->siz, GLOBALS->vlist_compression_depth); if( (rc == Z_OK) && ((destlen + sizeof(int)) < v->siz) ) { /* printf("siz: %d, dest: %d rc: %d\n", v->siz, (int)destlen, rc); */ vz = malloc_2(*rsiz = sizeof(struct vlist_t) + sizeof(int) + destlen); memcpy(vz, v, sizeof(struct vlist_t)); ipnt = (unsigned int *)(vz + 1); ipnt[0] = destlen; memcpy(&ipnt[1], dmem, destlen); vz->offs = (unsigned int)(-(int)v->offs); /* neg value signified compression */ free_2(v); v = vz; } free_2(dmem); } return(v); } void vlist_uncompress(struct vlist_t **v) { struct vlist_t *vl = *v; struct vlist_t *vprev = NULL; if(GLOBALS->vlist_handle) { while(vl) { struct vlist_t vhdr; struct vlist_t *vrebuild; long vl_offs = (long)vl; int rc; off_t seekpos = (off_t) vl_offs; /* possible overflow conflicts were already handled in the writer */ fseeko(GLOBALS->vlist_handle, seekpos, SEEK_SET); if(GLOBALS->use_fastload) { rc = vlist_fread_hdr(&vhdr, GLOBALS->vlist_handle); } else { rc = fread(&vhdr, sizeof(struct vlist_t), 1, GLOBALS->vlist_handle); } if(!rc) { printf("Error in reading from VList spill file!\n"); exit(255); } /* args are reversed to fread (compared to above) to handle short read at end of file! */ /* (this can happen because of how we write out only the used size of a block) */ vrebuild = malloc_2(sizeof(struct vlist_t) + vhdr.siz); memcpy(vrebuild, &vhdr, sizeof(struct vlist_t)); rc = fread(vrebuild+1, 1, vrebuild->siz, GLOBALS->vlist_handle); if(!rc) { printf("Error in reading from VList spill file!\n"); exit(255); } if(vprev) { vprev->next = vrebuild; } else { *v = vrebuild; } vprev = vrebuild; vl = vhdr.next; } vl = *v; vprev = NULL; } while(vl) { if((int)vl->offs < 0) { struct vlist_t *vz = malloc_2(sizeof(struct vlist_t) + vl->siz); unsigned int *ipnt; unsigned long sourcelen, destlen; int rc; memcpy(vz, vl, sizeof(struct vlist_t)); vz->offs = (unsigned int)(-(int)vl->offs); ipnt = (unsigned int *)(vl + 1); sourcelen = (unsigned long)ipnt[0]; destlen = (unsigned long)vl->siz; rc = uncompress((unsigned char *)(vz+1), &destlen, (unsigned char *)&ipnt[1], sourcelen); if(rc != Z_OK) { fprintf(stderr, "Error in vlist uncompress(), rc=%d/destlen=%d exiting!\n", rc, (int)destlen); exit(255); } free_2(vl); vl = vz; if(vprev) { vprev->next = vz; } else { *v = vz; } } vprev = vl; vl = vl->next; } } /* get pointer to one unit of space */ void *vlist_alloc(struct vlist_t **v, int compressable) { struct vlist_t *vl = *v; char *px; struct vlist_t *v2; if(vl->offs == vl->siz) { unsigned int siz, rsiz; /* 2 times versions are the growable, indexable vlists */ siz = 2 * vl->siz; rsiz = sizeof(struct vlist_t) + (vl->siz * vl->elem_siz); if((compressable)&&(vl->elem_siz == 1)) { if(GLOBALS->vlist_compression_depth>=0) { vl = vlist_compress_block(vl, &rsiz); } } if(compressable && GLOBALS->vlist_handle) { size_t rc; long write_cnt; fseeko(GLOBALS->vlist_handle, GLOBALS->vlist_bytes_written, SEEK_SET); if(GLOBALS->use_fastload) { rc = vlist_fwrite(vl, rsiz, GLOBALS->vlist_handle); } else { rc = fwrite(vl, rsiz, 1, GLOBALS->vlist_handle); } if(!rc) { fprintf(stderr, "Error in writing to VList spill file!\n"); perror("Why"); exit(255); } write_cnt = GLOBALS->vlist_bytes_written; if(sizeof(long) != sizeof(off_t)) /* optimizes in or out at compile time */ { if(write_cnt != GLOBALS->vlist_bytes_written) { fprintf(stderr, "VList spill file pointer-file overflow!\n"); exit(255); } } v2 = calloc_2(1, sizeof(struct vlist_t) + (vl->siz * vl->elem_siz)); v2->siz = siz; v2->elem_siz = vl->elem_siz; v2->next = (struct vlist_t *)write_cnt; free_2(vl); *v = v2; vl = *v; if(GLOBALS->use_fastload) { GLOBALS->vlist_bytes_written += rc; } else { GLOBALS->vlist_bytes_written += rsiz; } } else { v2 = calloc_2(1, sizeof(struct vlist_t) + (vl->siz * vl->elem_siz)); v2->siz = siz; v2->elem_siz = vl->elem_siz; v2->next = vl; *v = v2; vl = *v; } } else if(vl->offs*2 == vl->siz) { v2 = calloc_2(1, sizeof(struct vlist_t) + (vl->siz * vl->elem_siz)); memcpy(v2, vl, sizeof(struct vlist_t) + (vl->siz/2 * vl->elem_siz)); free_2(vl); *v = v2; vl = *v; } px =(((char *)(vl)) + sizeof(struct vlist_t) + ((vl->offs++) * vl->elem_siz)); return((void *)px); } /* vlist_size() and vlist_locate() do not work properly on compressed lists...you'll have to call vlist_uncompress() first! */ unsigned int vlist_size(struct vlist_t *v) { return(v->siz - 1 + v->offs); } void *vlist_locate(struct vlist_t *v, unsigned int idx) { unsigned int here = v->siz - 1; unsigned int siz = here + v->offs; /* siz is the same as vlist_size() */ if((!siz)||(idx>=siz)) return(NULL); while (idx < here) { v = v->next; here = v->siz - 1; } idx -= here; return((void *)(((char *)(v)) + sizeof(struct vlist_t) + (idx * v->elem_siz))); } /* calling this if you don't plan on adding any more elements will free up unused space as well as compress final blocks (if enabled) */ void vlist_freeze(struct vlist_t **v) { struct vlist_t *vl = *v; unsigned int siz = vl->offs; unsigned int rsiz = sizeof(struct vlist_t) + (siz * vl->elem_siz); if((vl->elem_siz == 1)&&(siz)) { struct vlist_t *w, *v2; if(vl->offs*2 <= vl->siz) /* Electric Fence, change < to <= */ { v2 = calloc_2(1, sizeof(struct vlist_t) + (vl->siz /* * vl->elem_siz */)); /* scan-build */ memcpy(v2, vl, sizeof(struct vlist_t) + (vl->siz/2 /* * vl->elem_siz */)); /* scan-build */ free_2(vl); *v = v2; vl = *v; } w = vlist_compress_block(vl, &rsiz); *v = w; } else if((siz != vl->siz)&&(!GLOBALS->vlist_handle)) { struct vlist_t *w = malloc_2(rsiz); memcpy(w, vl, rsiz); free_2(vl); *v = w; } if(GLOBALS->vlist_handle) { size_t rc; long write_cnt; vl = *v; fseeko(GLOBALS->vlist_handle, GLOBALS->vlist_bytes_written, SEEK_SET); if(GLOBALS->use_fastload) { rc = vlist_fwrite(vl, rsiz, GLOBALS->vlist_handle); } else { rc = fwrite(vl, rsiz, 1, GLOBALS->vlist_handle); } if(!rc) { fprintf(stderr, "Error in writing to VList spill file!\n"); perror("Why"); exit(255); } write_cnt = GLOBALS->vlist_bytes_written; if(sizeof(long) != sizeof(off_t)) /* optimizes in or out at compile time */ { if(write_cnt != GLOBALS->vlist_bytes_written) { fprintf(stderr, "VList spill file pointer-file overflow!\n"); exit(255); } } *v = (struct vlist_t *)write_cnt; if(GLOBALS->use_fastload) { GLOBALS->vlist_bytes_written += rc; } else { GLOBALS->vlist_bytes_written += rsiz; } free_2(vl); } } /* this code implements an LZ-based filter that can sit on top of the vlists. it uses a generic escape value of 0xff as that is one that statistically occurs infrequently in value change data fed into vlists. */ void vlist_packer_emit_out(struct vlist_packer_t *p, unsigned char byt) { char *pnt; #ifdef WAVE_VLIST_PACKER_STATS p->packed_bytes++; #endif pnt = vlist_alloc(&p->v, 1); *pnt = byt; } void vlist_packer_emit_uv32(struct vlist_packer_t *p, unsigned int v) { unsigned int nxt; while((nxt = v>>7)) { vlist_packer_emit_out(p, v&0x7f); v = nxt; } vlist_packer_emit_out(p, (v&0x7f) | 0x80); } void vlist_packer_emit_uv32rvs(struct vlist_packer_t *p, unsigned int v) { unsigned int nxt; unsigned char buf[2 * sizeof(int)]; unsigned int idx = 0; int i; while((nxt = v>>7)) { buf[idx++] = v&0x7f; v = nxt; } buf[idx] = (v&0x7f) | 0x80; for(i = idx; i >= 0; i--) { vlist_packer_emit_out(p, buf[i]); } } void vlist_packer_alloc(struct vlist_packer_t *p, unsigned char byt) { int i, j, k, l; p->unpacked_bytes++; if(!p->repcnt) { top: for(i=0;ibuf[(p->bufpnt-i) & WAVE_ZIVMASK] == byt) { p->repdist = i; p->repcnt = 1; p->repdist2 = p->repdist3 = p->repdist4 = 0; for(j=i+WAVE_ZIVSKIP;jbuf[(p->bufpnt-j) & WAVE_ZIVMASK] == byt) { p->repdist2 = j; p->repcnt2 = 1; for(k=j+WAVE_ZIVSKIP;kbuf[(p->bufpnt-k) & WAVE_ZIVMASK] == byt) { p->repdist3 = k; p->repcnt3 = 1; for(l=k+WAVE_ZIVSKIP;lbuf[(p->bufpnt-l) & WAVE_ZIVMASK] == byt) { p->repdist4 = l; p->repcnt4 = 1; break; } } break; } } break; } } p->bufpnt++; p->bufpnt &= WAVE_ZIVMASK; p->buf[p->bufpnt] = byt; return; } } p->bufpnt++; p->bufpnt &= WAVE_ZIVMASK; p->buf[p->bufpnt] = byt; vlist_packer_emit_out(p, byt); if(byt==WAVE_ZIVFLAG) { vlist_packer_emit_uv32(p, 0); } } else { attempt2: if(p->buf[(p->bufpnt - p->repdist) & WAVE_ZIVMASK] == byt) { p->repcnt++; if(p->repcnt2) { p->repcnt2 = ((p->buf[(p->bufpnt - p->repdist2) & WAVE_ZIVMASK] == byt)) ? p->repcnt2+1 : 0; } if(p->repcnt3) { p->repcnt3 = ((p->buf[(p->bufpnt - p->repdist3) & WAVE_ZIVMASK] == byt)) ? p->repcnt3+1 : 0; } if(p->repcnt4) { p->repcnt4 = ((p->buf[(p->bufpnt - p->repdist4) & WAVE_ZIVMASK] == byt)) ? p->repcnt4+1 : 0; } p->bufpnt++; p->bufpnt &= WAVE_ZIVMASK; p->buf[p->bufpnt] = byt; } else { if(p->repcnt2) { p->repcnt = p->repcnt2; p->repdist = p->repdist2; p->repcnt2 = p->repcnt3; p->repdist2 = p->repdist3; p->repcnt3 = p->repcnt4; p->repdist3 = p->repdist4; p->repcnt4 = 0; p->repdist4 = 0; goto attempt2; } if(p->repcnt3) { p->repcnt = p->repcnt3; p->repdist = p->repdist3; p->repcnt2 = p->repcnt4; p->repdist2 = p->repdist4; p->repcnt3 = 0; p->repdist3 = 0; p->repcnt4 = 0; p->repdist4 = 0; goto attempt2; } if(p->repcnt4) { p->repcnt = p->repcnt4; p->repdist = p->repdist4; p->repcnt4 = 0; p->repdist4 = 0; goto attempt2; } if(p->repcnt > 2) { vlist_packer_emit_out(p, WAVE_ZIVFLAG); vlist_packer_emit_uv32(p, p->repcnt); p->repcnt = 0; vlist_packer_emit_uv32(p, p->repdist); } else { if(p->repcnt == 2) { vlist_packer_emit_out(p, p->buf[(p->bufpnt-1) & WAVE_ZIVMASK]); if(p->buf[(p->bufpnt-1) & WAVE_ZIVMASK]==WAVE_ZIVFLAG) { vlist_packer_emit_uv32(p, 0); } } vlist_packer_emit_out(p, p->buf[p->bufpnt & WAVE_ZIVMASK]); p->repcnt = 0; if(p->buf[p->bufpnt & WAVE_ZIVMASK]==WAVE_ZIVFLAG) { vlist_packer_emit_uv32(p, 0); } } goto top; } } } void vlist_packer_finalize(struct vlist_packer_t *p) { #ifdef WAVE_VLIST_PACKER_STATS static guint64 pp = 0, upp = 0; #endif if(p->repcnt) { if(p->repcnt > 2) { vlist_packer_emit_out(p, WAVE_ZIVFLAG); vlist_packer_emit_uv32(p, p->repcnt); p->repcnt = 0; vlist_packer_emit_uv32(p, p->repdist); } else { if(p->repcnt == 2) { vlist_packer_emit_out(p, p->buf[(p->bufpnt-1) & WAVE_ZIVMASK]); if(p->buf[(p->bufpnt-1) & WAVE_ZIVMASK]==WAVE_ZIVFLAG) { vlist_packer_emit_uv32(p, 0); } } vlist_packer_emit_out(p, p->buf[p->bufpnt & WAVE_ZIVMASK]); p->repcnt = 0; if(p->buf[p->bufpnt & WAVE_ZIVMASK]==WAVE_ZIVFLAG) { vlist_packer_emit_uv32(p, 0); } } } vlist_packer_emit_uv32rvs(p, p->unpacked_bytes); /* for malloc later during decompress */ #ifdef WAVE_VLIST_PACKER_STATS pp += p->packed_bytes; upp += p->unpacked_bytes; printf("pack:%d orig:%d (%lld %lld %f)\n", p->packed_bytes, p->unpacked_bytes, pp, upp, (float)pp / (float)upp); #endif } struct vlist_packer_t *vlist_packer_create(void) { struct vlist_packer_t *vp = calloc_2(1, sizeof(struct vlist_packer_t)); vp->v = vlist_create(sizeof(char)); return(vp); } unsigned char *vlist_packer_decompress(struct vlist_t *v, unsigned int *declen) { unsigned int list_size = vlist_size(v); unsigned int top_of_packed_size = list_size-1; unsigned char *chp; unsigned int dec_size = 0; unsigned int dec_size_cmp; unsigned int shamt = 0; unsigned char *mem, *dpnt; unsigned int i, j, repcnt, dist; for(;;) { chp = vlist_locate(v, top_of_packed_size); dec_size |= ((unsigned int)(*chp & 0x7f)) << shamt; if(*chp & 0x80) { break; } shamt+=7; top_of_packed_size--; } mem = calloc_2(1, WAVE_ZIVWRAP + dec_size); dpnt = mem + WAVE_ZIVWRAP; for(i=0;i #include #include #include #include "symbol.h" #include "lxt.h" #include "debug.h" #include "bsearch.h" #include "strace.h" #include "translate.h" #include "ptranslate.h" #include "ttranslate.h" #include "hierpack.h" #include "analyzer.h" #ifdef _MSC_VER #define strcasecmp _stricmp #endif void UpdateTraceSelection(Trptr t); int traverse_vector_nodes(Trptr t); /* * extract last n levels of hierarchy */ char *hier_extract(char *pnt, int levels) { int i, len; char ch, *pnt2, *esc; char only_nums_so_far=1; if(!pnt) return(NULL); len=strlen(pnt); if(!len) return(pnt); if(levels<1) levels=1; if((esc=strchr(pnt, '\\'))) { return((levels==1) ? esc : pnt); /* shortcut out on escape IDs: level=1, esc char else all */ } pnt2=pnt+len-1; /* ch=*pnt2; */ /* scan-build : useless given loop below */ for(i=0;i='0')&&(ch<='9')) /* skip 1st set of signal.number hier from right if it exists */ { continue; /* nothing */ } else { if(ch==GLOBALS->hier_delimeter) { if(!only_nums_so_far) levels--; if(!levels) { pnt2+=2; return(pnt2); } } only_nums_so_far=0; } } return(pnt); /* not as many levels as max, so give the full name.. */ } void updateTraceGroup(Trptr t) { /* t->t_match = NULL; */ if (t->t_prev) { if (IsGroupBegin(t->t_prev)) { if (IsGroupEnd(t)) { /* empty group */ Trptr g_begin = t->t_prev; t->t_grp = g_begin->t_grp; t->t_match = g_begin; g_begin->t_match = t; } else { /* first trace in group */ t->t_grp = t->t_prev; } } else { if (IsGroupEnd(t)) { Trptr g_begin = t->t_prev->t_grp; if(g_begin) /* scan-build */ { t->t_grp = g_begin->t_grp; t->t_match = g_begin; g_begin->t_match = t; } } else { t->t_grp = t->t_prev->t_grp; } } } else { /* very first trace */ t->t_grp = NULL; } if ((t->t_grp) && IsSelected(t->t_grp)) { t->flags |= TR_HIGHLIGHT; } } void CloseTrace(Trptr t) { GLOBALS->traces.dirty = 1; if (IsGroupBegin(t)) { t->flags |= TR_CLOSED; if (t->t_match) { t->t_match->flags |= TR_CLOSED; }; if (!HasWave(t)) { /* Group End */ if (t->t_match) { t->t_match->flags |= TR_COLLAPSED; }; } else { /* Composite End */ if (t->t_match) { t->t_match->flags |= TR_COLLAPSED; }; } } if (IsGroupEnd(t)) { t->flags |= TR_CLOSED; if (t->t_match) { t->t_match->flags |= TR_CLOSED; }; if ((t->t_match) && !HasWave(t->t_match)) { /* Group End */ t->flags |= TR_COLLAPSED; } else { /* Composite End */ t->flags |= TR_COLLAPSED; } } } void OpenTrace(Trptr t) { GLOBALS->traces.dirty = 1; if (IsGroupBegin(t) || IsGroupEnd(t)) { t->flags &= ~TR_CLOSED; if (t->t_match) { t->t_match->flags &= ~TR_CLOSED; }; if (!HasWave(t)) { t->flags &= ~TR_COLLAPSED; if(t->t_match) { t->t_match->flags &= ~TR_COLLAPSED; }; } } } void ClearTraces(void) { Trptr t = GLOBALS->traces.first; while(t) { t->flags &= ~TR_HIGHLIGHT; t=t->t_next; } GLOBALS->traces.dirty = 1; } void ClearGroupTraces(Trptr t_grp) { if (IsGroupBegin(t_grp)) { Trptr t = t_grp; while(t) { t->flags &= ~TR_HIGHLIGHT; if(t->t_match == t_grp) break; t=t->t_next; } GLOBALS->traces.dirty = 1; } else { fprintf(stderr, "INTERNAL ERROR: ClearGroupTrace applied to non-group! Exiting.\n"); exit(255); } } /* * Add a trace to the display... */ static void AddTrace( Trptr t ) { GLOBALS->traces.dirty = 1; if((GLOBALS->which_t_color > 0) && (GLOBALS->which_t_color <= WAVE_NUM_RAINBOW)) { t->t_color = GLOBALS->which_t_color; GLOBALS->which_t_color = 0; } if(GLOBALS->default_flags&TR_NUMMASK) t->flags=GLOBALS->default_flags; else t->flags=(t->flags&TR_NUMMASK)|GLOBALS->default_flags; if(GLOBALS->default_flags & TR_FTRANSLATED) { t->f_filter = GLOBALS->current_translate_file; } else if(GLOBALS->default_flags & TR_PTRANSLATED) { t->p_filter = GLOBALS->current_translate_proc; } /* NOT an else! */ if(GLOBALS->default_flags & TR_TTRANSLATED) { t->t_filter = GLOBALS->current_translate_ttrans; if(t->t_filter) { if(!t->vector) { bvptr v; int cache_hi = t->flags & TR_HIGHLIGHT; t->flags |= TR_HIGHLIGHT; v = combine_traces(1, t); /* down: make single signal a vector */ if(v) { v->transaction_nd = t->n.nd; /* cache for savefile, disable */ t->vector = 1; t->n.vec = v; /* splice in */ } t->flags &= ~TR_HIGHLIGHT; t->flags |= cache_hi; } if(GLOBALS->ttranslate_args) { t->transaction_args = strdup_2(GLOBALS->ttranslate_args); } else { t->transaction_args = NULL; } traverse_vector_nodes(t); } else { t->flags &= ~TR_TTRANSLATED; /* malformed filter syntax? should never have "which" of zero here */ } } if (IsGroupBegin(t)) { GLOBALS->group_depth = GLOBALS->group_depth + 1; } if (IsGroupEnd(t)) { if (GLOBALS->group_depth == 0) { fprintf(stderr, "ERROR: Group End encountered with no matching start. Ignoring.\n"); t->flags &= ~TR_GRP_END; } else { GLOBALS->group_depth = GLOBALS->group_depth - 1; } } if(GLOBALS->shift_timebase_default_for_add) t->shift=GLOBALS->shift_timebase_default_for_add; if(!GLOBALS->strace_ctx->shadow_active) { if( GLOBALS->traces.first == NULL ) { t->t_next = t->t_prev = NULL; GLOBALS->traces.first = GLOBALS->traces.last = t; } else { t->t_next = NULL; t->t_prev = GLOBALS->traces.last; GLOBALS->traces.last->t_next = t; GLOBALS->traces.last = t; } GLOBALS->traces.total++; updateTraceGroup(GLOBALS->traces.last); } else /* hide offscreen */ { struct strace *st = calloc_2(1, sizeof(struct strace)); st->next = GLOBALS->strace_ctx->shadow_straces; st->value = GLOBALS->strace_ctx->shadow_type; st->trace = t; st->string = GLOBALS->strace_ctx->shadow_string; /* copy string over */ GLOBALS->strace_ctx->shadow_string = NULL; GLOBALS->strace_ctx->shadow_straces = st; } } /* * Add a blank trace to the display... */ static char *precondition_string(char *s) { int len=0; char *s2; if(!s) return(NULL); s2=s; while((*s2)&&((*s2)!='\n')&&((*s2)!='\r')) /* strip off ending CR/LF */ { len++; s2++; } if(!len) return(NULL); s2=(char *)calloc_2(1,len+1); memcpy(s2,s,len); return(s2); } int AddBlankTrace(char *commentname) { Trptr t; char *comment; unsigned int flags_filtered; if( (t = (Trptr) calloc_2( 1, sizeof( TraceEnt ))) == NULL ) { fprintf( stderr, "Out of memory, can't add blank trace to analyzer\n"); return( 0 ); } AddTrace(t); /* Keep only flags that make sense for a blank trace. */ flags_filtered = TR_BLANK | (GLOBALS->default_flags & (TR_CLOSED| TR_GRP_BEGIN| TR_GRP_END| TR_COLLAPSED| TR_ANALOG_BLANK_STRETCH)); t->flags = flags_filtered; if(t->flags & TR_ANALOG_BLANK_STRETCH) { t->flags &= ~TR_BLANK; } if((comment=precondition_string(commentname))) { t->name = comment; } return(1); } /* * Insert a blank [or comment] trace into the display... */ int InsertBlankTrace(char *comment, int different_flags) { TempBuffer tb; char *comm; Trptr t; if( (t = (Trptr) calloc_2( 1, sizeof( TraceEnt ))) == NULL ) { fprintf( stderr, "Out of memory, can't insert blank trace to analyzer\n"); return( 0 ); } GLOBALS->traces.dirty = 1; if(!different_flags) { t->flags=TR_BLANK; } else { t->flags = different_flags; } if((comm=precondition_string(comment))) { t->name = comm; } if(!GLOBALS->traces.first) { GLOBALS->traces.first=GLOBALS->traces.last=t; GLOBALS->traces.total=1; return(1); } else { tb.buffer=GLOBALS->traces.buffer; tb.bufferlast=GLOBALS->traces.bufferlast; tb.buffercount=GLOBALS->traces.buffercount; GLOBALS->traces.buffer=GLOBALS->traces.bufferlast=t; GLOBALS->traces.buffercount=1; PasteBuffer(); GLOBALS->traces.buffer=tb.buffer; GLOBALS->traces.bufferlast=tb.bufferlast; GLOBALS->traces.buffercount=tb.buffercount; return(1); } } /* * Adds a single bit signal to the display... */ int AddNodeTraceReturn(nptr nd, char *aliasname, Trptr *tret) { Trptr t; hptr histpnt; hptr *harray; int histcount; int i; if(!nd) return(0); /* passed it a null node ptr by mistake */ if(nd->mv.mvlfac) import_trace(nd); GLOBALS->signalwindow_width_dirty=1; GLOBALS->traces.dirty = 1; if( (t = (Trptr) calloc_2( 1, sizeof( TraceEnt ))) == NULL ) { fprintf( stderr, "Out of memory, can't add to analyzer\n" ); return( 0 ); } if(!nd->harray) /* make quick array lookup for aet display */ { histpnt=&(nd->head); histcount=0; while(histpnt) { histcount++; histpnt=histpnt->next; } nd->numhist=histcount; if(!(nd->harray=harray=(hptr *)malloc_2(histcount*sizeof(hptr)))) { fprintf( stderr, "Out of memory, can't add to analyzer\n" ); free_2(t); return(0); } histpnt=&(nd->head); for(i=0;inext; } } if(aliasname) { char *alias; t->name_full = alias =(char *)malloc_2(strlen(aliasname)+1); strcpy(alias,aliasname); t->name = t->name_full; if(GLOBALS->hier_max_level) t->name = hier_extract(t->name_full, GLOBALS->hier_max_level); } else { if(!GLOBALS->hier_max_level) { int flagged = HIER_DEPACK_ALLOC; t->name = hier_decompress_flagged(nd->nname, &flagged); t->is_depacked = (flagged != 0); } else { int flagged = HIER_DEPACK_ALLOC; char *tbuff = hier_decompress_flagged(nd->nname, &flagged); if(!flagged) { t->name = hier_extract(nd->nname, GLOBALS->hier_max_level); } else { t->name = strdup_2(hier_extract(tbuff, GLOBALS->hier_max_level)); free_2(tbuff); t->is_depacked = 1; } } } if(nd->extvals) /* expansion vectors */ { int n; n = nd->msi - nd->lsi; if(n<0)n=-n; n++; t->flags = (( n > 3 )||( n < -3 )) ? TR_HEX|TR_RJUSTIFY : TR_BIN|TR_RJUSTIFY; } else { t->flags |= TR_BIN; /* binary */ } t->vector = FALSE; t->n.nd = nd; if(tret) *tret = t; /* for expand */ AddTrace( t ); return( 1 ); } /* single node */ int AddNode(nptr nd, char *aliasname) { return(AddNodeTraceReturn(nd, aliasname, NULL)); } /* add multiple nodes (if array) */ int AddNodeUnroll(nptr nd, char *aliasname) { #ifdef WAVE_ARRAY_SUPPORT if(nd->array_height <= 1) #endif { return(AddNodeTraceReturn(nd, aliasname, NULL)); } #ifdef WAVE_ARRAY_SUPPORT else { unsigned int i; int rc = 1; for(i=0;iarray_height;i++) { rc |= AddNodeTraceReturn(nd+i, aliasname, NULL); } return(rc); } #endif } /* * Adds a vector to the display... */ int AddVector(bvptr vec, char *aliasname) { Trptr t; int n; if(!vec) return(0); /* must've passed it a null pointer by mistake */ GLOBALS->signalwindow_width_dirty=1; GLOBALS->traces.dirty = 1; n = vec->nbits; t = (Trptr) calloc_2(1, sizeof( TraceEnt ) ); if( t == NULL ) { fprintf( stderr, "Out of memory, can't add %s to analyzer\n", vec->bvname ); return( 0 ); } if (aliasname) { t->name_full = strdup_2(aliasname); t->name = t->name_full; } else { t->name = vec->bvname; } if(GLOBALS->hier_max_level) t->name = hier_extract(t->name, GLOBALS->hier_max_level); t->flags = ( n > 3 ) ? TR_HEX|TR_RJUSTIFY : TR_BIN|TR_RJUSTIFY; t->vector = TRUE; t->n.vec = vec; AddTrace( t ); return( 1 ); } /* * Free up a trace's mallocs... */ void FreeTrace(Trptr t) { GLOBALS->traces.dirty = 1; if(GLOBALS->starting_unshifted_trace == t) { GLOBALS->starting_unshifted_trace = NULL; /* for new "standard" clicking routines */ } if(GLOBALS->strace_ctx->straces) { struct strace_defer_free *sd = calloc_2(1, sizeof(struct strace_defer_free)); sd->next = GLOBALS->strace_ctx->strace_defer_free_head; sd->defer = t; GLOBALS->strace_ctx->strace_defer_free_head = sd; return; } if(t->vector) { bvptr bv, bv2; int i; bv=t->n.vec; /* back out allocation to revert (if any) */ if(bv->transaction_cache) { t->n.vec = bv->transaction_cache; while(bv) { bv2 = bv->transaction_chain; if(bv->bvname) { free_2(bv->bvname); } for(i=0;inumregions;i++) { free_2(bv->vectors[i]); } free_2(bv); bv = bv2; } bv=t->n.vec; } /* normal vector deallocation */ for(i=0;inumregions;i++) { if(bv->vectors[i]) free_2(bv->vectors[i]); } if(bv->bits) { if(bv->bits->name) free_2(bv->bits->name); if(bv->bits->attribs) free_2(bv->bits->attribs); for(i=0;inbits;i++) { DeleteNode(bv->bits->nodes[i]); } free_2(bv->bits); } if(bv->bvname) free_2(bv->bvname); if(t->n.vec) free_2(t->n.vec); } else { if(t->n.nd && t->n.nd->expansion) { DeleteNode(t->n.nd); } } if(t->is_depacked) free_2(t->name); if(t->asciivalue) free_2(t->asciivalue); if(t->name_full) free_2(t->name_full); if(t->transaction_args) free_2(t->transaction_args); free_2( t ); } /* * Remove a trace from the display and optionally * deallocate its memory usage... */ void RemoveTrace( Trptr t, int dofree ) { GLOBALS->traces.dirty = 1; GLOBALS->traces.total--; if( t == GLOBALS->traces.first ) { GLOBALS->traces.first = t->t_next; if( t->t_next ) t->t_next->t_prev = NULL; else GLOBALS->traces.last = NULL; } else { if(t->t_prev) { t->t_prev->t_next = t->t_next; } else { /* this code should likely *never* execute as if( t == GLOBALS->traces.first ) above should catch this */ /* there is likely a problem elsewhere in the code! */ Trptr t2 = GLOBALS->traces.first = t->t_next; GLOBALS->traces.total = 0; while(t2) { t2 = t2->t_next; GLOBALS->traces.total++; } } if( t->t_next ) t->t_next->t_prev = t->t_prev; else GLOBALS->traces.last = t->t_prev; } if(dofree) { FreeTrace(t); } } /* * Deallocate the cut/paste buffer... */ void FreeCutBuffer(void) { Trptr t, t2; t=GLOBALS->traces.buffer; while(t) { t2=t->t_next; FreeTrace(t); t=t2; } GLOBALS->traces.buffer=GLOBALS->traces.bufferlast=NULL; GLOBALS->traces.buffercount=0; } /* * Cut highlighted traces from the main screen * and throw them in the cut buffer. If anything's * in the cut buffer, deallocate it first... */ Trptr CutBuffer(void) { Trptr t, tnext; Trptr first=NULL, current=NULL; GLOBALS->shift_click_trace=NULL; /* so shift-clicking doesn't explode */ t=GLOBALS->traces.first; while(t) { if((t->flags)&(TR_HIGHLIGHT)) break; t=t->t_next; } if(!t) return(NULL); /* keeps a double cut from blowing out the buffer */ GLOBALS->signalwindow_width_dirty=1; GLOBALS->traces.dirty = 1; FreeCutBuffer(); t=GLOBALS->traces.first; while(t) { tnext=t->t_next; if(IsSelected(t) || (t->t_grp && IsSelected(t->t_grp))) { /* members of closed groups may not be highlighted */ /* so propogate highlighting here */ t->flags |= TR_HIGHLIGHT; GLOBALS->traces.bufferlast=t; GLOBALS->traces.buffercount++; /* t->flags&=(~TR_HIGHLIGHT); */ RemoveTrace(t, 0); if(!current) { first=current=t; t->t_prev=NULL; t->t_next=NULL; } else { current->t_next=t; t->t_prev=current; current=t; t->t_next=NULL; } } t=tnext; } return(GLOBALS->traces.buffer=first); } /* * Paste the cut buffer into the main display one and * mark the cut buffer empty... */ Trptr PasteBuffer(void) { Trptr t, tinsert=NULL, tinsertnext; int count; Trptr prev; if(!GLOBALS->traces.buffer) return(NULL); GLOBALS->signalwindow_width_dirty=1; GLOBALS->traces.dirty = 1; if(!(t=GLOBALS->traces.first)) { t=GLOBALS->traces.last=GLOBALS->traces.first=GLOBALS->traces.buffer; prev = NULL; while(t) { t->t_prev = prev; /* defensive re-link move */ prev = t; GLOBALS->traces.last=t; GLOBALS->traces.total++; t=t->t_next; } GLOBALS->traces.buffer=GLOBALS->traces.bufferlast=NULL; GLOBALS->traces.buffercount=0; return(GLOBALS->traces.first); } while(t) { if(t->flags&TR_HIGHLIGHT) { tinsert=t; } t=t->t_next; } if(!tinsert) tinsert=GLOBALS->traces.last; if(IsGroupBegin(tinsert) && IsClosed(tinsert) && IsCollapsed(tinsert->t_match)) tinsert=tinsert->t_match; tinsertnext=tinsert->t_next; tinsert->t_next=GLOBALS->traces.buffer; GLOBALS->traces.buffer->t_prev=tinsert; GLOBALS->traces.bufferlast->t_next=tinsertnext; GLOBALS->traces.total+=GLOBALS->traces.buffercount; if(!tinsertnext) { GLOBALS->traces.last=GLOBALS->traces.bufferlast; } else { tinsertnext->t_prev=GLOBALS->traces.bufferlast; } GLOBALS->traces.scroll_top = GLOBALS->traces.buffer; GLOBALS->traces.scroll_bottom = GLOBALS->traces.bufferlast; if(GLOBALS->traces.first) { t = GLOBALS->traces.first; t->t_grp = NULL; while(t) { updateTraceGroup(t); t->flags &= ~TR_HIGHLIGHT; t=t->t_next; } } count = 0; if (GLOBALS->traces.buffer) { t = GLOBALS->traces.buffer; while(t) { t->flags |= TR_HIGHLIGHT; t=t->t_next; count++; if (count == GLOBALS->traces.buffercount) break; } } /* clean out the buffer */ GLOBALS->traces.buffer=GLOBALS->traces.bufferlast=NULL; GLOBALS->traces.buffercount=0; /* defensive re-link */ t=GLOBALS->traces.first; prev = NULL; while(t) { t->t_prev = prev; prev = t; t=t->t_next; } return(GLOBALS->traces.first); } /* * Prepend the cut buffer into the main display one and * mark the cut buffer empty... */ Trptr PrependBuffer(void) { Trptr t, prev = NULL; int count; if(!GLOBALS->traces.buffer) return(NULL); GLOBALS->signalwindow_width_dirty=1; GLOBALS->traces.dirty = 1; t=GLOBALS->traces.buffer; while(t) { t->t_prev = prev; /* defensive re-link move */ prev=t; t->flags&=(~TR_HIGHLIGHT); GLOBALS->traces.total++; t=t->t_next; } if((prev->t_next=GLOBALS->traces.first)) { /* traces.last current value is ok as it stays the same */ GLOBALS->traces.first->t_prev=prev; /* but we need the reverse link back up */ } else { GLOBALS->traces.last=prev; } GLOBALS->traces.first=GLOBALS->traces.buffer; if(GLOBALS->traces.first) { t = GLOBALS->traces.first; t->t_grp = NULL; while(t) { updateTraceGroup(t); t->flags &= ~TR_HIGHLIGHT; t=t->t_next; } } count = 0; if (GLOBALS->traces.buffer) { t = GLOBALS->traces.buffer; while(t) { t->flags |= TR_HIGHLIGHT; t=t->t_next; count++; if (count == GLOBALS->traces.buffercount) break; } } /* clean out the buffer */ GLOBALS->traces.buffer=GLOBALS->traces.bufferlast=NULL; GLOBALS->traces.buffercount=0; /* defensive re-link */ t=GLOBALS->traces.first; prev = NULL; while(t) { t->t_prev = prev; prev = t; t=t->t_next; } return(GLOBALS->traces.first); } /* * avoid sort/rvs manipulations if there are group traces (for now) */ static int groupsArePresent(void) { Trptr t; int i, rc = 0; t=GLOBALS->traces.first; for(i=0;itraces.total;i++) { if(!t) { fprintf(stderr, "INTERNAL ERROR: traces.total vs traversal mismatch! Exiting.\n"); exit(255); } if((t->t_grp)||(t->t_match)||(t->flags & TR_GRP_MASK)) { rc = 1; break; } t=t->t_next; } return(rc); } /*************************************************************/ /* * sort on tracename pointers (alpha/caseins alpha/sig sort full_reverse) */ static int tracenamecompare(const void *s1, const void *s2) { char *str1, *str2; str1=(*((Trptr *)s1))->name; str2=(*((Trptr *)s2))->name; if((!str1) || (!*str1)) /* force blank lines to go to bottom */ { if((!str2) || (!*str2)) { return(0); } else { return(1); } } else if((!str2) || (!*str2)) { return(-1); /* str1==str2==zero case is covered above */ } return(strcmp(str1, str2)); } static int traceinamecompare(const void *s1, const void *s2) { char *str1, *str2; str1=(*((Trptr *)s1))->name; str2=(*((Trptr *)s2))->name; if((!str1) || (!*str1)) /* force blank lines to go to bottom */ { if((!str2) || (!*str2)) { return(0); } else { return(1); } } else if((!str2) || (!*str2)) { return(-1); /* str1==str2==zero case is covered above */ } return(strcasecmp(str1, str2)); } static int tracesignamecompare(const void *s1, const void *s2) { char *str1, *str2; str1=(*((Trptr *)s1))->name; str2=(*((Trptr *)s2))->name; if((!str1) || (!*str1)) /* force blank lines to go to bottom */ { if((!str2) || (!*str2)) { return(0); } else { return(1); } } else if((!str2) || (!*str2)) { return(-1); /* str1==str2==zero case is covered above */ } return(sigcmp(str1, str2)); } /* * alphabetization/reordering of traces */ int TracesReorder(int mode) { Trptr t, prev = NULL; Trptr *tsort, *tsort_pnt; #ifdef WAVE_HIERFIX char *subst, ch; #endif int i; int (*cptr)(const void*, const void*); if(!GLOBALS->traces.total) return(0); GLOBALS->traces.dirty = 1; t=GLOBALS->traces.first; tsort=tsort_pnt=wave_alloca(sizeof(Trptr)*GLOBALS->traces.total); memset(tsort_pnt, 0, sizeof(Trptr)*GLOBALS->traces.total); for(i=0;itraces.total;i++) { if(!t) { fprintf(stderr, "INTERNAL ERROR: traces.total vs traversal mismatch! Exiting.\n"); exit(255); } *(tsort_pnt++)=t; #ifdef WAVE_HIERFIX if((subst=t->name)) while((ch=(*subst))) { if(ch==GLOBALS->hier_delimeter) { *subst=VCDNAM_HIERSORT; } /* forces sort at hier boundaries */ subst++; } #endif t=t->t_next; } switch(mode) { case TR_SORT_INS: cptr=traceinamecompare; break; case TR_SORT_NORM: cptr=tracenamecompare; break; case TR_SORT_LEX: cptr=tracesignamecompare; break; default: cptr=NULL; break; } if((cptr) && (!groupsArePresent())) { qsort(tsort, GLOBALS->traces.total, sizeof(Trptr), cptr); } else /* keep groups segregated off on the side and sort names + (indirect pointer to) top-level groups */ { Trptr *tsort_reduced = wave_alloca(sizeof(Trptr)*GLOBALS->traces.total); int num_reduced = 0; int j; memset(tsort_reduced, 0, sizeof(Trptr)*GLOBALS->traces.total); for(i=0;itraces.total;i++) { if(tsort[i]->flags & TR_GRP_BEGIN) { int cnt = 0; for(j=i;jtraces.total;j++) { if(tsort[j]->flags & TR_GRP_BEGIN) { cnt++; } else if(tsort[j]->flags & TR_GRP_END) { cnt--; } if(!cnt) { tsort_reduced[num_reduced] = calloc_2(1, sizeof(struct TraceEnt)); tsort_reduced[num_reduced]->name = tsort[i]->name; tsort_reduced[num_reduced]->is_sort_group = 1; tsort_reduced[num_reduced]->t_grp = tsort[i]; tsort[j]->t_next = NULL; num_reduced++; i = j; break; } } } else { tsort_reduced[num_reduced++] = tsort[i]; } } if(num_reduced) { if(mode == TR_SORT_RVS) /* reverse of current order */ { for(i=0;i<=(num_reduced/2);i++) { Trptr t_tmp = tsort_reduced[i]; j = num_reduced-i-1; tsort_reduced[i] = tsort_reduced[j]; tsort_reduced[j] = t_tmp; } } else { if(cptr) { qsort(tsort_reduced, num_reduced, sizeof(Trptr), cptr); } } } i = 0; for(j=0;jis_sort_group) { tsort[i++] = tsort_reduced[j]; } else { Trptr trav = tsort_reduced[j]->t_grp; free_2(tsort_reduced[j]); while(trav) { tsort[i++] = trav; trav = trav->t_next; } } } } tsort_pnt=tsort; for(i=0;itraces.total;i++) { t=*(tsort_pnt++); if(!i) { GLOBALS->traces.first=t; t->t_prev=NULL; } else { prev->t_next=t; t->t_prev=prev; } prev=t; #ifdef WAVE_HIERFIX if((subst=t->name)) while((ch=(*subst))) { if(ch==VCDNAM_HIERSORT) { *subst=GLOBALS->hier_delimeter; } /* restore hier */ subst++; } #endif } GLOBALS->traces.last=prev; if(prev) { prev->t_next=NULL; } /* scan-build */ return(1); } Trptr GiveNextTrace(Trptr t) { if(!t) return(t); /* should not happen */ /* if(t->name) { printf("NEXT: %s %x\n", t->name, t->flags); } */ UpdateTraceSelection(t); if (IsGroupBegin(t) && IsClosed(t)) { Trptr next = t->t_match; if (next) return (IsCollapsed(next) ? GiveNextTrace(next) : next); return NULL; } else { Trptr next = t->t_next; if (next) return (IsCollapsed(next) ? GiveNextTrace(next) : next); return NULL; } } static Trptr GivePrevTraceSkipUpdate(Trptr t, int skip) { if(!t) return(t); /* should not happen */ /* if(t->name) { printf("PREV: %s\n", t->name); } */ if(!skip) { UpdateTraceSelection(t); } if (IsGroupEnd(t) && IsClosed(t)) { Trptr prev = t->t_match; if (prev) return (IsCollapsed(prev) ? GivePrevTrace(prev) : prev); return NULL; } else { Trptr prev = t->t_prev; if (prev) return (IsCollapsed(prev) ? GivePrevTrace(prev) : prev); return NULL; } } Trptr GivePrevTrace(Trptr t) { return(GivePrevTraceSkipUpdate(t, 0)); } /* propogate selection info down into groups */ void UpdateTraceSelection(Trptr t) { if ((t->t_match) && (IsGroupBegin(t) || IsGroupEnd(t)) && (IsSelected(t) || IsSelected(t->t_match))) { t->flags |= TR_HIGHLIGHT; t->t_match->flags |= TR_HIGHLIGHT; } else if ((t->t_grp) && IsSelected(t->t_grp)) { t->flags |= TR_HIGHLIGHT; } else if(t->flags & (TR_BLANK|TR_ANALOG_BLANK_STRETCH)) /* seek to real xact trace if present... */ { if(!(t->flags & TR_HIGHLIGHT)) { Trptr tscan = t; int bcnt = 0; while((tscan) && (tscan = GivePrevTraceSkipUpdate(tscan, 1))) { if(!(tscan->flags & (TR_BLANK|TR_ANALOG_BLANK_STRETCH))) { if(tscan->flags & TR_TTRANSLATED) { break; /* found it */ } else { tscan = NULL; } } else { bcnt++; /* bcnt is number of blank traces */ } } if((tscan)&&(tscan->vector)&&(IsSelected(tscan))) { bvptr bv = tscan->n.vec; do { bv = bv->transaction_chain; /* correlate to blank trace */ } while(bv && (bcnt--)); if(bv) { t->flags |= TR_HIGHLIGHT; } } } } } int UpdateTracesVisible(void) { Trptr t = GLOBALS->traces.first; int cnt = 0; while(t) { t = GiveNextTrace(t); cnt++; } GLOBALS->traces.visible = cnt; return(cnt); } /* where is trace t_in in the list of displayable traces */ int GetTraceNumber(Trptr t_in) { Trptr t = GLOBALS->traces.first; int i = 0; int num = -1; while(t) { if (t == t_in) { num = i; break; } i++; t = GiveNextTrace(t); } return(num); } unsigned IsShadowed( Trptr t ) { if (t->t_grp) { if (HasWave(t->t_grp)) { return IsSelected(t->t_grp); } else { return IsShadowed(t->t_grp); } } return 0; } char* GetFullName( Trptr t, int *was_packed ) { if (HasAlias(t) || !HasWave(t)) { return (t->name_full); } else if (t->vector) { return (t->n.vec->bvname); } else { return (hier_decompress_flagged(t->n.nd->nname, was_packed)); } } /* * sanity checking to make sure there are not any group open/close mismatches */ void EnsureGroupsMatch(void) { Trptr t = GLOBALS->traces.first; Trptr last_good = t; Trptr t2; int oc_cnt = 0; int underflow_sticky = 0; /* Trptr tkill_undeflow = NULL; */ /* scan-build */ while(t) { if(t->flags & TR_GRP_MASK) { if(t->flags & TR_GRP_BEGIN) { oc_cnt++; } else if(t->flags & TR_GRP_END) { oc_cnt--; if(oc_cnt == 0) { if(!underflow_sticky) { last_good = t->t_next; } } } if(oc_cnt < 0) { /* if(!underflow_sticky) { tkill_undeflow = t; } */ /* scan-build */ underflow_sticky = 1; } } else { if((oc_cnt == 0) && (!underflow_sticky)) { last_good = t->t_next; } } t = t->t_next; } if((underflow_sticky) || (oc_cnt > 0)) { t = last_good; while(t) { t2 = t->t_next; RemoveTrace(t, 0); /* conservatively don't set "dofree", if there is a reload memory will reclaim */ t = t2; } } } gtkwave-3.3.66/src/clipping.h0000664000076400007640000000117011570577234015356 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2005 * * 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. */ #ifndef WAVE_CLIP_H #define WAVE_CLIP_H /* pack points into, out of an array */ #define CLIP_PACK(z, a, b, c, d) do{z[0]=a;z[1]=b;z[2]=c;z[3]=d;}while(0) #define CLIP_UNPACK(z, a, b, c, d) do{a=z[0];b=z[1];c=z[2];d=z[3];}while(0) /* returns true if line is visible in rectangle */ int wave_lineclip(int *coords, int *rect); #endif gtkwave-3.3.66/src/signalwindow.c0000664000076400007640000013027512372010236016243 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2013. * * 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. */ #include "globals.h" #include #include #include "gtk12compat.h" #include "currenttime.h" #include "pixmaps.h" #include "symbol.h" #include "debug.h" #undef FOCUS_DEBUG_MSGS /* * complain about certain ops conflict with dnd... */ void dnd_error(void) { status_text("Can't perform that operation when waveform drag and drop is in progress!\n"); } static void service_hslider(GtkWidget *text, gpointer data) { (void)text; (void)data; GtkAdjustment *hadj; gint xsrc; if(GLOBALS->signalpixmap) { hadj=GTK_ADJUSTMENT(GLOBALS->signal_hslider); xsrc=(gint)hadj->value; DEBUG(printf("Signal HSlider Moved to %d\n",xsrc)); GLOBALS->right_align_active = 0; gdk_draw_rectangle(GLOBALS->signalpixmap, GLOBALS->gc.gc_mdgray, TRUE, 0, -1, GLOBALS->signal_fill_width, GLOBALS->fontheight); gdk_draw_line(GLOBALS->signalpixmap, GLOBALS->gc_white, 0, GLOBALS->fontheight-1, GLOBALS->signal_fill_width-1, GLOBALS->fontheight-1); font_engine_draw_string(GLOBALS->signalpixmap, GLOBALS->signalfont, GLOBALS->gc_black, 3+xsrc, GLOBALS->fontheight-4, "Time"); if(GLOBALS->signalarea_has_focus) { gdk_draw_pixmap(GLOBALS->signalarea->window, GLOBALS->signalarea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->signalarea)],GLOBALS->signalpixmap, xsrc+1, 0+1, 0+1, 0+1, GLOBALS->signalarea->allocation.width-2, GLOBALS->signalarea->allocation.height-2); draw_signalarea_focus(); } else { gdk_draw_pixmap(GLOBALS->signalarea->window, GLOBALS->signalarea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->signalarea)],GLOBALS->signalpixmap,xsrc, 0,0, 0,GLOBALS->signalarea->allocation.width, GLOBALS->signalarea->allocation.height); } } } void draw_signalarea_focus(void) { if(GLOBALS->signalarea_has_focus) { gdk_draw_rectangle(GLOBALS->signalarea->window, GLOBALS->gc_black, FALSE, 0, 0, GLOBALS->signalarea->allocation.width-1, GLOBALS->signalarea->allocation.height-1); } } /**************************************************************************/ /*** standard click routines turned on with "use_standard_clicking"=1 ***/ /* * DND "drag_begin" handler, this is called whenever a drag starts. */ static void DNDBeginCB( GtkWidget *widget, GdkDragContext *dc, gpointer data ) { (void)widget; (void)dc; (void)data; GLOBALS->dnd_state = 1; } /* * DND "drag_end" handler, this is called when a drag and drop has * completed. So this function is the last one to be called in * any given DND operation. */ static void DNDEndCB( GtkWidget *widget, GdkDragContext *dc, gpointer data ) { (void)widget; (void)dc; (void)data; GtkWidget *ddest; int which; gdouble x,y; GdkModifierType state; Trptr t; int trwhich, trtarget; int must_update_screen = 0; #ifdef WAVE_USE_GTK2 gint xi, yi; #else GdkEventMotion event[1]; event[0].deviceid = GDK_CORE_POINTER; #endif if(GLOBALS->std_dnd_tgt_on_signalarea || GLOBALS->std_dnd_tgt_on_wavearea) { GtkAdjustment *wadj; wadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider); WAVE_GDK_GET_POINTER(GLOBALS->std_dnd_tgt_on_signalarea ? GLOBALS->signalarea->window : GLOBALS->wavearea->window, &x, &y, &xi, &yi, &state); WAVE_GDK_GET_POINTER_COPY; which=(int)(y); which=(which/GLOBALS->fontheight)-2; if(which < -1) which = -1; trtarget=((int)wadj->value)+which; ddest = (GLOBALS->std_dnd_tgt_on_signalarea) ? GTK_WIDGET(GLOBALS->signalarea) : GTK_WIDGET(GLOBALS->wavearea); if((x<0)||(x>=ddest->allocation.width)||(y<0)||(y>=ddest->allocation.height)) { goto bot; } GLOBALS->cachedtrace=t=GLOBALS->traces.first; trwhich=0; while(t) { if((trwhicht_next && IsGroupEnd(t->t_next) && IsCollapsed(t->t_next)) { /* added missing "t &&" because of possible while termination above */ t = t->t_next; } GLOBALS->cachedtrace=t; if(GLOBALS->cachedtrace) { while(t) { if(!(t->flags&TR_HIGHLIGHT)) { GLOBALS->cachedtrace = t; if(CutBuffer()) { /* char buf[32]; sprintf(buf,"Dragging %d trace%s.\n",GLOBALS->traces.buffercount,GLOBALS->traces.buffercount!=1?"s":""); status_text(buf); */ must_update_screen = 1; } GLOBALS->cachedtrace->flags|=TR_HIGHLIGHT; goto success; } t=GivePrevTrace(t); } goto bot; } success: if( ((which<0) && (GLOBALS->topmost_trace==GLOBALS->traces.first) && PrependBuffer()) || (PasteBuffer()) ) /* short circuit on special which<0 case */ { /* status_text("Drop completed.\n"); */ if(GLOBALS->cachedtrace) { GLOBALS->cachedtrace->flags&=~TR_HIGHLIGHT; } GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); must_update_screen = 0; } } bot: if(must_update_screen) { MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } GLOBALS->dnd_cursor_timer = 0; GLOBALS->dnd_state = 0; GLOBALS->standard_trace_dnd_degate = 1; } /* * DND "drag_motion" handler, this is called whenever the * pointer is dragging over the target widget. */ static gboolean DNDDragMotionCB( GtkWidget *widget, GdkDragContext *dc, gint xx, gint yy, guint tt, gpointer data ) { (void)xx; (void)yy; (void)data; #ifndef WAVE_USE_GTK2 (void)tt; #endif gboolean same_widget; #ifdef WAVE_USE_GTK2 GdkDragAction suggested_action; #endif GtkWidget *src_widget, *tar_widget; if((widget == NULL) || (dc == NULL)) return(FALSE); /* Get source widget and target widget. */ src_widget = gtk_drag_get_source_widget(dc); tar_widget = widget; /* Note if source widget is the same as the target. */ same_widget = (src_widget == tar_widget) ? TRUE : FALSE; if(same_widget) { /* nothing */ } GLOBALS->std_dnd_tgt_on_signalarea = (tar_widget == GLOBALS->signalarea); GLOBALS->std_dnd_tgt_on_wavearea = (tar_widget == GLOBALS->wavearea); #ifdef WAVE_USE_GTK2 /* If this is the same widget, our suggested action should be * move. For all other case we assume copy. */ suggested_action = GDK_ACTION_MOVE; /* Respond with default drag action (status). First we check * the dc's list of actions. If the list only contains * move, copy, or link then we select just that, otherwise we * return with our default suggested action. * If no valid actions are listed then we respond with 0. */ /* Only move? */ if(dc->actions == GDK_ACTION_MOVE) gdk_drag_status(dc, GDK_ACTION_MOVE, tt); /* Only copy? */ else if(dc->actions == GDK_ACTION_COPY) gdk_drag_status(dc, GDK_ACTION_COPY, tt); /* Only link? */ else if(dc->actions == GDK_ACTION_LINK) gdk_drag_status(dc, GDK_ACTION_LINK, tt); /* Other action, check if listed in our actions list? */ else if(dc->actions & suggested_action) gdk_drag_status(dc, suggested_action, tt); /* All else respond with 0. */ else gdk_drag_status(dc, 0, tt); #endif if(GLOBALS->std_dnd_tgt_on_signalarea || GLOBALS->std_dnd_tgt_on_wavearea) { GtkAdjustment *wadj; GtkWidget *ddest; int which; gdouble x,y; GdkModifierType state; Trptr t; int trwhich, trtarget; #ifdef WAVE_USE_GTK2 gint xi, yi; #else GdkEventMotion event[1]; event[0].deviceid = GDK_CORE_POINTER; #endif wadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider); WAVE_GDK_GET_POINTER(GLOBALS->std_dnd_tgt_on_signalarea ? GLOBALS->signalarea->window : GLOBALS->wavearea->window, &x, &y, &xi, &yi, &state); WAVE_GDK_GET_POINTER_COPY; which=(int)(y); which=(which/GLOBALS->fontheight)-2; if(which < -1) which = -1; trtarget=((int)wadj->value)+which; ddest = (GLOBALS->std_dnd_tgt_on_signalarea) ? GTK_WIDGET(GLOBALS->signalarea) : GTK_WIDGET(GLOBALS->wavearea); if((x<0)||(x>=ddest->allocation.width)||(y<0)||(y>=ddest->allocation.height)) { goto bot; } t=GLOBALS->traces.first; trwhich=0; while(t) { if((trwhicht_next && IsGroupEnd(t->t_next) && IsCollapsed(t->t_next)) { t = t->t_next; } /* if(t) */ /* { */ /* while(t) */ /* { */ /* if(t->flags & TR_HIGHLIGHT) */ /* { */ /* t=GivePrevTrace(t); */ /* which--; */ /* } */ /* else */ /* { */ /* break; */ /* } */ /* } */ /* } */ if(1) { GtkAdjustment *hadj=GTK_ADJUSTMENT(GLOBALS->signal_hslider); GtkAdjustment *sadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider); int rsig_trtarget=(int)(sadj->value); gint xsrc=(gint)hadj->value; gint ylin; gdk_draw_rectangle(GLOBALS->signalpixmap, GLOBALS->gc.gc_ltgray, TRUE, 0, 0, GLOBALS->signal_fill_width, GLOBALS->signalarea->allocation.height); RenderSigs(rsig_trtarget, 0); GLOBALS->dnd_cursor_timer = 1; if((t)&&(which >= -1)) { if(which >= GLOBALS->traces.total) { which = GLOBALS->traces.total-1; } ylin = ((which + 2) * GLOBALS->fontheight) - 2; gdk_draw_line(GLOBALS->signalpixmap, GLOBALS->gc_black, 0, ylin, GLOBALS->signal_fill_width-1, ylin); } else { int i; which = -1; ylin = ((which + 2) * GLOBALS->fontheight) - 2; for(i=0;isignal_fill_width-1; i+=16) { gdk_draw_line(GLOBALS->signalpixmap, GLOBALS->gc_black, i, ylin, i+7, ylin); gdk_draw_line(GLOBALS->signalpixmap, GLOBALS->gc_white, i+8, ylin, i+15, ylin); } } gdk_draw_pixmap(GLOBALS->signalarea->window, GLOBALS->signalarea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->signalarea)], GLOBALS->signalpixmap, xsrc, 0, 0, 0, GLOBALS->signalarea->allocation.width, GLOBALS->signalarea->allocation.height); /* printf("drop to %d of %d: '%s'\n", which, GLOBALS->traces.total, t ? t->name : "undef"); */ } bot: return(FALSE); } return(FALSE); } static gboolean ignoreAccelerators(GdkEventKey *event) { if(!GLOBALS || !GLOBALS->filter_entry || !event) { return(FALSE); } else { #ifdef MAC_INTEGRATION return (GTK_WIDGET_HAS_FOCUS(GLOBALS->filter_entry)); #else return (GTK_WIDGET_HAS_FOCUS(GLOBALS->filter_entry) && !(event->state & GDK_CONTROL_MASK) && !(event->state & GDK_MOD1_MASK)); #endif } } /* * keypress processing, return TRUE to block the event from gtk */ static gint keypress_local(GtkWidget *widget, GdkEventKey *event, gpointer data) { (void)widget; (void)data; GtkAdjustment *wadj; int num_traces_displayable; int target; int which; gint rc = FALSE; int yscroll; #ifdef FOCUS_DEBUG_MSGS printf("focus: %d %08x %08x %08x\n", GTK_WIDGET_HAS_FOCUS(GLOBALS->signalarea_event_box), GLOBALS->signalarea_event_box, widget, data); #endif if(GTK_WIDGET_HAS_FOCUS(GLOBALS->signalarea_event_box)) { switch(event->keyval) { #ifdef MAC_INTEGRATION /* need to do this, otherwise if a menu accelerator it steals the key from gtk */ case GDK_a: if(event->state & GDK_MOD2_MASK) { menu_dataformat_highlight_all(NULL, 0, NULL); rc = TRUE; } break; case GDK_A: if(event->state & GDK_MOD2_MASK) { menu_dataformat_unhighlight_all(NULL, 0, NULL); rc = TRUE; } break; case GDK_x: if(event->state & GDK_MOD2_MASK) { menu_cut_traces(NULL, 0, NULL); rc = TRUE; } break; case GDK_c: if(event->state & GDK_MOD2_MASK) { menu_copy_traces(NULL, 0, NULL); rc = TRUE; } break; case GDK_v: if(event->state & GDK_MOD2_MASK) { menu_paste_traces(NULL, 0, NULL); rc = TRUE; } break; #endif case GDK_Page_Up: case GDK_KP_Page_Up: case GDK_Page_Down: case GDK_KP_Page_Down: case GDK_Up: case GDK_KP_Up: case GDK_Down: case GDK_KP_Down: wadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider); num_traces_displayable=(GLOBALS->signalarea->allocation.height)/(GLOBALS->fontheight); num_traces_displayable--; /* for the time trace that is always there */ if(num_traces_displayabletraces.visible) { switch(event->keyval) { case GDK_Down: case GDK_KP_Down: case GDK_Page_Down: case GDK_KP_Page_Down: yscroll = ((event->keyval == GDK_Page_Down) || (event->keyval == GDK_KP_Page_Down)) ? num_traces_displayable : 1; target=((int)wadj->value)+yscroll; which=num_traces_displayable-1; if(target+which>=(GLOBALS->traces.visible-1)) target=GLOBALS->traces.visible-which-1; wadj->value=target; if(GLOBALS->cachedwhich_signalwindow_c_1==which) GLOBALS->cachedwhich_signalwindow_c_1=which-1; /* force update */ gtk_signal_emit_by_name (GTK_OBJECT (wadj), "changed"); /* force bar update */ gtk_signal_emit_by_name (GTK_OBJECT (wadj), "value_changed"); /* force text update */ break; case GDK_Up: case GDK_KP_Up: case GDK_Page_Up: case GDK_KP_Page_Up: yscroll = ((event->keyval == GDK_Page_Up) || (event->keyval == GDK_KP_Page_Up)) ? num_traces_displayable : 1; target=((int)wadj->value)-yscroll; if(target<0) target=0; wadj->value=target; which=0; if(GLOBALS->cachedwhich_signalwindow_c_1==which) GLOBALS->cachedwhich_signalwindow_c_1=-1; /* force update */ gtk_signal_emit_by_name (GTK_OBJECT (wadj), "changed"); /* force bar update */ gtk_signal_emit_by_name (GTK_OBJECT (wadj), "value_changed"); /* force text update */ break; } } rc = TRUE; break; case GDK_Left: case GDK_KP_Left: service_left_edge(NULL, 0); /* hadj=GTK_ADJUSTMENT(GLOBALS->signal_hslider); if(hadj->value < hadj->page_increment) { hadj->value = (gfloat)0.0; } else { hadj->value = hadj->value - hadj->page_increment; } gtk_signal_emit_by_name (GTK_OBJECT (hadj), "changed"); gtk_signal_emit_by_name (GTK_OBJECT (hadj), "value_changed"); signalarea_configure_event(GLOBALS->signalarea, NULL); */ rc = TRUE; break; case GDK_Right: case GDK_KP_Right: service_right_edge(NULL, 0); /* hadj=GTK_ADJUSTMENT(GLOBALS->signal_hslider); if( ((int) hadj->value + hadj->page_increment) >= hadj->upper) { hadj->value = (gfloat)(hadj->upper)-hadj->page_increment; } else { hadj->value = hadj->value + hadj->page_increment; } gtk_signal_emit_by_name (GTK_OBJECT (hadj), "changed"); gtk_signal_emit_by_name (GTK_OBJECT (hadj), "value_changed"); signalarea_configure_event(GLOBALS->signalarea, NULL); */ rc = TRUE; break; default: #ifdef FOCUS_DEBUG_MSGS printf("key %x, widget: %08x\n", event->keyval, widget); #endif break; } } else if(GLOBALS->dnd_sigview) { if(GTK_WIDGET_HAS_FOCUS(GLOBALS->dnd_sigview) || GTK_WIDGET_HAS_FOCUS(GLOBALS->filter_entry)) { switch(event->keyval) { case GDK_a: #ifdef MAC_INTEGRATION if(event->state & GDK_META_MASK) #else if(event->state & GDK_CONTROL_MASK) #endif { treeview_select_all_callback(); rc = TRUE; } break; case GDK_A: #ifdef MAC_INTEGRATION if(event->state & GDK_META_MASK) #else if(event->state & GDK_CONTROL_MASK) #endif { treeview_unselect_all_callback(); rc = TRUE; } default: break; } } else if(GTK_WIDGET_HAS_FOCUS(GLOBALS->tree_treesearch_gtk2_c_1)) { switch(event->keyval) { case GDK_a: #ifdef MAC_INTEGRATION if(event->state & GDK_META_MASK) #else if(event->state & GDK_CONTROL_MASK) #endif { /* eat keystroke */ rc = TRUE; } break; case GDK_A: #ifdef MAC_INTEGRATION if(event->state & GDK_META_MASK) #else if(event->state & GDK_CONTROL_MASK) #endif { /* eat keystroke */ rc = TRUE; } default: break; } } } if (ignoreAccelerators(event)) { gtk_widget_event(GLOBALS->filter_entry, (GdkEvent *)event); /* eat keystroke */ rc = TRUE; } return(rc); } #ifdef WAVE_USE_GTK2 static gint scroll_event( GtkWidget * widget, GdkEventScroll * event ) { GdkEventKey ev_fake; DEBUG(printf("Mouse Scroll Event\n")); switch ( event->direction ) { case GDK_SCROLL_UP: ev_fake.keyval = GDK_Up; keypress_local(widget, &ev_fake, GLOBALS->signalarea_event_box); break; case GDK_SCROLL_DOWN: ev_fake.keyval = GDK_Down; keypress_local(widget, &ev_fake, GLOBALS->signalarea_event_box); default: break; } return(TRUE); } #endif #ifdef WAVE_ALLOW_QUARTZ_FLUSH_WORKAROUND #ifdef MAC_INTEGRATION static gboolean osx_timer(gpointer dummy) { if(GLOBALS) { if(GLOBALS->force_hide_show == 2) { if((GLOBALS->signalarea)&&(GLOBALS->wavearea)) { gtk_widget_hide(GLOBALS->signalarea); gtk_widget_show(GLOBALS->signalarea); gtk_widget_hide(GLOBALS->wavearea); gtk_widget_show(GLOBALS->wavearea); } } if(GLOBALS->force_hide_show) { GLOBALS->force_hide_show--; } } return(TRUE); } #endif #endif static gboolean mouseover_timer(gpointer dummy) { (void)dummy; static gboolean run_once = FALSE; gdouble x,y; GdkModifierType state; TraceEnt t_trans; #ifdef WAVE_USE_GTK2 gint xi, yi; #else GdkEventMotion event[1]; event[0].deviceid = GDK_CORE_POINTER; #endif if(GLOBALS->button2_debounce_flag) { GLOBALS->button2_debounce_flag = 0; } if((GLOBALS->dnd_state)||(GLOBALS->tree_dnd_begin)) /* drag scroll on DnD */ { GtkAdjustment *wadj; int num_traces_displayable; int target; int which; int yscroll; WAVE_GDK_GET_POINTER(GLOBALS->signalarea->window, &x, &y, &xi, &yi, &state); WAVE_GDK_GET_POINTER_COPY; if(y > GLOBALS->signalarea->allocation.height) { wadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider); num_traces_displayable=(GLOBALS->signalarea->allocation.height)/(GLOBALS->fontheight); num_traces_displayable--; /* for the time trace that is always there */ if(num_traces_displayabletraces.visible) { yscroll = 1; target=((int)wadj->value)+yscroll; which=num_traces_displayable-1; if(target+which>=(GLOBALS->traces.visible-1)) target=GLOBALS->traces.visible-which-1; wadj->value=target; if(GLOBALS->cachedwhich_signalwindow_c_1==which) GLOBALS->cachedwhich_signalwindow_c_1=which-1; /* force update */ gtk_signal_emit_by_name (GTK_OBJECT (wadj), "changed"); /* force bar update */ gtk_signal_emit_by_name (GTK_OBJECT (wadj), "value_changed"); /* force text update */ } } else if(y < 0) { wadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider); num_traces_displayable=(GLOBALS->signalarea->allocation.height)/(GLOBALS->fontheight); num_traces_displayable--; /* for the time trace that is always there */ if(num_traces_displayabletraces.visible) { yscroll = 1; target=((int)wadj->value)-yscroll; if(target<0) target=0; wadj->value=target; which=0; if(GLOBALS->cachedwhich_signalwindow_c_1==which) GLOBALS->cachedwhich_signalwindow_c_1=-1; /* force update */ gtk_signal_emit_by_name (GTK_OBJECT (wadj), "changed"); /* force bar update */ gtk_signal_emit_by_name (GTK_OBJECT (wadj), "value_changed"); /* force text update */ } } } if(in_main_iteration()) return(TRUE); if(GLOBALS->splash_is_loading) { return(TRUE); } if(GLOBALS->splash_fix_win_title) { GLOBALS->splash_fix_win_title = 0; wave_gtk_window_set_title(GTK_WINDOW(GLOBALS->mainwindow), GLOBALS->winname, GLOBALS->dumpfile_is_modified ? WAVE_SET_TITLE_MODIFIED: WAVE_SET_TITLE_NONE, 0); } if(GLOBALS->window_entry_c_1) { GLOBALS->entry_raise_timer++; if(GLOBALS->entry_raise_timer > 50) { gdk_window_raise(GLOBALS->window_entry_c_1->window); GLOBALS->entry_raise_timer = 0; } } #ifdef WAVE_USE_GTK2 #ifdef MAC_INTEGRATION if(GLOBALS->dnd_helper_quartz) { char *dhq = g_malloc(strlen(GLOBALS->dnd_helper_quartz)+1); strcpy(dhq, GLOBALS->dnd_helper_quartz); free_2(GLOBALS->dnd_helper_quartz); GLOBALS->dnd_helper_quartz = NULL; DND_helper_quartz(dhq); g_free(dhq); } #endif #endif if(process_finder_names_queued()) { #if GTK_CHECK_VERSION(2,4,0) if(GLOBALS->pFileChoose) #endif { if(!GLOBALS->window_simplereq_c_9) { char *qn = process_finder_extract_queued_name(); if(qn) { int qn_len = strlen(qn); const int mlen = 30; if(qn_len < mlen) { simplereqbox("File queued for loading",300,qn,"OK", NULL, NULL, 1); } else { char *qn_2 = wave_alloca(mlen + 4); strcpy(qn_2, "..."); strcat(qn_2, qn + qn_len - mlen); simplereqbox("File queued for loading",300,qn_2,"OK", NULL, NULL, 1); } return(TRUE); } } } #if GTK_CHECK_VERSION(2,4,0) else { if(process_finder_name_integration()) { return(TRUE); } } #endif } if(GLOBALS->loaded_file_type == MISSING_FILE) { return(TRUE); } if(run_once == FALSE) /* avoid any race conditions with the toolkit for uninitialized data */ { run_once = TRUE; return(TRUE); } if((!GLOBALS->signalarea) || (!GLOBALS->signalarea->window)) { return(TRUE); } if(GLOBALS->dnd_cursor_timer) { GLOBALS->dnd_cursor_timer++; if(GLOBALS->dnd_cursor_timer == 50) { GLOBALS->dnd_cursor_timer = 0; signalarea_configure_event(GLOBALS->signalarea, NULL); } } if(GLOBALS->mouseover_counter < 0) return(TRUE); /* mouseover is up in wave window so don't bother */ WAVE_GDK_GET_POINTER(GLOBALS->signalarea->window, &x, &y, &xi, &yi, &state); WAVE_GDK_GET_POINTER_COPY; GLOBALS->mouseover_counter++; if(!((x>=0)&&(xsignalarea->allocation.width)&&(y>=0)&&(ysignalarea->allocation.height))) { move_mouseover_sigs(NULL, 0, 0, LLDescriptor(0)); } else if(GLOBALS->mouseover_counter == 10) { int num_traces_displayable=GLOBALS->wavearea->allocation.height/(GLOBALS->fontheight); int yr = GLOBALS->cached_mouseover_y; int i; Trptr t=NULL; num_traces_displayable--; /* for the time trace that is always there */ yr-=GLOBALS->fontheight; if(yr<0) goto bot; yr/=GLOBALS->fontheight; /* y now indicates the trace in question */ if(yr>num_traces_displayable) goto bot; t=GLOBALS->topmost_trace; for(i=0;iflags&(/*TR_BLANK|*/TR_EXCLUDE))) /* TR_BLANK removed because of transaction handling below... */ { t = NULL; goto bot; } if(t->flags & (TR_BLANK|TR_ANALOG_BLANK_STRETCH)) /* seek to real xact trace if present... */ { Trptr tscan = t; int bcnt = 0; while((tscan) && (tscan = GivePrevTrace(tscan))) { if(!(tscan->flags & (TR_BLANK|TR_ANALOG_BLANK_STRETCH))) { if(tscan->flags & TR_TTRANSLATED) { break; /* found it */ } else { tscan = NULL; } } else { bcnt++; /* bcnt is number of blank traces */ } } if((tscan)&&(tscan->vector)) { bvptr bv = tscan->n.vec; do { bv = bv->transaction_chain; /* correlate to blank trace */ } while(bv && (bcnt--)); if(bv) { memcpy(&t_trans, tscan, sizeof(TraceEnt)); /* substitute into a synthetic trace */ t_trans.n.vec = bv; t_trans.vector = 1; t_trans.name = bv->bvname; if(GLOBALS->hier_max_level) t_trans.name = hier_extract(t_trans.name, GLOBALS->hier_max_level); t = &t_trans; goto bot; /* is goto process_trace; in wavewindow.c */ } } } if((t->flags&TR_BLANK)) { t = NULL; goto bot; } if(t->flags & TR_ANALOG_BLANK_STRETCH) /* seek to real analog trace is present... */ { while((t) && (t = t->t_prev)) { if(!(t->flags & TR_ANALOG_BLANK_STRETCH)) { if(t->flags & TR_ANALOGMASK) { break; /* found it */ } else { t = NULL; } } } } bot: if(t) { move_mouseover_sigs(t, GLOBALS->cached_mouseover_x, GLOBALS->cached_mouseover_y, GLOBALS->tims.marker); } else { move_mouseover_sigs(NULL, 0, 0, LLDescriptor(0)); } } return(TRUE); } static gint motion_notify_event_std(GtkWidget *widget, GdkEventMotion *event) { (void)widget; gdouble x,y; GdkModifierType state; #ifdef WAVE_USE_GTK2 gint xi, yi; #endif if(event->is_hint) { WAVE_GDK_GET_POINTER(event->window, &x, &y, &xi, &yi, &state); WAVE_GDK_GET_POINTER_COPY; } else { x = event->x; y = event->y; state = event->state; } GLOBALS->cached_mouseover_x = x; GLOBALS->cached_mouseover_y = y; GLOBALS->mouseover_counter = 0; move_mouseover_sigs(NULL, 0, 0, LLDescriptor(0)); return(TRUE); } static gint button_release_event_std(GtkWidget *widget, GdkEventButton *event) { (void)widget; (void)event; if(GLOBALS->std_collapse_pressed) { GLOBALS->std_collapse_pressed = 0; } return(TRUE); } static gint button_press_event_std(GtkWidget *widget, GdkEventButton *event) { int num_traces_displayable; int which; int trwhich, trtarget; GtkAdjustment *wadj; Trptr t, t2; if(GLOBALS->signalarea_event_box) { /* Don't mess with highlights with button 2 (save for dnd) */ if((event->button == 2) && (event->type == GDK_BUTTON_PRESS)) { return(TRUE); } /* Don't mess with highlights with button 3 (save for menu_check) */ if((event->button == 3) && (event->type == GDK_BUTTON_PRESS)) { goto menu_chk; } if((event->x<0)||(event->x>=widget->allocation.width)||(event->y<0)||(event->y>=widget->allocation.height)) { /* let gtk take focus from us with focus out event */ } else { if(!GLOBALS->signalarea_has_focus) { GLOBALS->signalarea_has_focus = TRUE; gtk_widget_grab_focus(GTK_WIDGET(GLOBALS->signalarea_event_box)); } } } if((GLOBALS->traces.visible)&&(GLOBALS->signalpixmap)) { num_traces_displayable=widget->allocation.height/(GLOBALS->fontheight); num_traces_displayable--; /* for the time trace that is always there */ which=(int)(event->y); which=(which/GLOBALS->fontheight)-1; if(which>=GLOBALS->traces.visible) { #ifdef MAC_INTEGRATION if((event->state&(GDK_MOD2_MASK|GDK_SHIFT_MASK)) == (GDK_SHIFT_MASK)) #else if((event->state&(GDK_CONTROL_MASK|GDK_SHIFT_MASK)) == (GDK_SHIFT_MASK)) #endif { /* ok for plain-vanilla shift click only */ which = GLOBALS->traces.visible-1; } else { ClearTraces(); goto redraw; /* off in no man's land */ } } if((which>=num_traces_displayable)||(which<0)) { ClearTraces(); goto redraw; /* off in no man's land */ } wadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider); trtarget=((int)wadj->value)+which; t=GLOBALS->traces.first; trwhich=0; while(t) { if((trwhichstate & GDK_MOD2_MASK) #else if(event->state&GDK_CONTROL_MASK) #endif { if(t) /* scan-build */ { if(IsGroupBegin(t) && IsSelected(t)) { ClearGroupTraces(t); } else if(IsGroupEnd(t) && IsSelected(t)) { ClearGroupTraces(t->t_match); } else { t->flags ^= TR_HIGHLIGHT; } } } else if((event->state&GDK_SHIFT_MASK)&&(GLOBALS->starting_unshifted_trace)) { int src = -1, dst = -1; int cnt = 0; t2=GLOBALS->traces.first; while(t2) { if(t2 == t) { dst = cnt; } if(t2 == GLOBALS->starting_unshifted_trace) { src = cnt; } cnt++; /* t2->flags &= ~TR_HIGHLIGHT; */ t2 = t2->t_next; } if(src != -1) { cnt = 0; t2=GLOBALS->traces.first; while(t2) { if ((cnt == src) && (cnt == dst) && IsSelected(t2)) { GLOBALS->starting_unshifted_trace = NULL; } t2->flags &= ~TR_HIGHLIGHT; t2=t2->t_next; cnt++; } if(src > dst) { int cpy; cpy = src; src = dst; dst = cpy; } cnt = 0; t2=GLOBALS->traces.first; while(t2 && GLOBALS->starting_unshifted_trace) { if((cnt >= src) && (cnt <= dst)) { t2->flags |= TR_HIGHLIGHT; } cnt++; t2=t2->t_next; } } else { GLOBALS->starting_unshifted_trace = t; if(t) { t->flags |= TR_HIGHLIGHT; } /* scan-build */ } } /* else if(!(t->flags & TR_HIGHLIGHT)) Ben Sferrazza suggested fix rather than a regular "else" 11aug08 */ /* changed to add use_standard_trace_select below to make this selectable, Sophana K request 08oct12 */ else if( (!GLOBALS->use_standard_trace_select) || (GLOBALS->standard_trace_dnd_degate) || ((t)&&(!(t->flags & TR_HIGHLIGHT))) ) { GLOBALS->starting_unshifted_trace = t; t2=GLOBALS->traces.first; while(t2) { t2->flags &= ~TR_HIGHLIGHT; t2 = t2->t_next; } if(t) { t->flags |= TR_HIGHLIGHT; } /* scan-build */ } GLOBALS->standard_trace_dnd_degate = 0; if(event->type == GDK_2BUTTON_PRESS) { menu_toggle_group(NULL, 0, widget); goto menu_chk; } redraw: GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } menu_chk: if((event->button == 3) && (event->type == GDK_BUTTON_PRESS)) { do_popup_menu (widget, event); } return(TRUE); } /*** standard click routines turned on with "use_standard_clicking"=1 ***/ /**************************************************************************/ /**************************************************************************/ /*** standard click routines turned on with "use_standard_clicking"=0 ***/ /*** ***/ /*** no longer supported ***/ /*** ***/ /*** gtkwave click routines turned on with "use_standard_clicking"=0 ***/ /**************************************************************************/ gint signalarea_configure_event(GtkWidget *widget, GdkEventConfigure *event) { (void)event; GtkAdjustment *wadj, *hadj; int num_traces_displayable; int width; if((!widget)||(!widget->window)) return(TRUE); #ifdef WAVE_ALLOW_QUARTZ_FLUSH_WORKAROUND #ifdef MAC_INTEGRATION if(!GLOBALS->force_hide_show) { GLOBALS->force_hide_show = 2; } #endif #endif make_sigarea_gcs(widget); UpdateTracesVisible(); num_traces_displayable=widget->allocation.height/(GLOBALS->fontheight); num_traces_displayable--; /* for the time trace that is always there */ DEBUG(printf("SigWin Configure Event h: %d, w: %d\n", widget->allocation.height, widget->allocation.width)); GLOBALS->old_signal_fill_width=GLOBALS->signal_fill_width; GLOBALS->signal_fill_width = ((width=widget->allocation.width) > GLOBALS->signal_pixmap_width) ? widget->allocation.width : GLOBALS->signal_pixmap_width; if(GLOBALS->signalpixmap) { if((GLOBALS->old_signal_fill_width!=GLOBALS->signal_fill_width)||(GLOBALS->old_signal_fill_height!=widget->allocation.height)) { gdk_pixmap_unref(GLOBALS->signalpixmap); GLOBALS->signalpixmap=gdk_pixmap_new(widget->window, GLOBALS->signal_fill_width, widget->allocation.height, -1); } } else { GLOBALS->signalpixmap=gdk_pixmap_new(widget->window, GLOBALS->signal_fill_width, widget->allocation.height, -1); } if (!GLOBALS->left_justify_sigs && !GLOBALS->do_resize_signals) { if (width < GLOBALS->max_signal_name_pixel_width+15) { int delta = GLOBALS->max_signal_name_pixel_width+15 - width; if(GLOBALS->signalpixmap) { hadj=GTK_ADJUSTMENT(GLOBALS->signal_hslider); /* int pos = GLOBALS->max_signal_name_pixel_width+15 - (gint)hadj->value; */ if ((gint) hadj->value > delta) { GLOBALS->right_align_active = 1; delta = (gint)hadj->value; } if (GLOBALS->right_align_active) hadj->value = (gint)delta; } } else { GLOBALS->right_align_active = 1; } } GLOBALS->old_signal_fill_height= widget->allocation.height; gdk_draw_rectangle(GLOBALS->signalpixmap, widget->style->bg_gc[GTK_STATE_PRELIGHT], TRUE, 0, 0, GLOBALS->signal_fill_width, widget->allocation.height); hadj=GTK_ADJUSTMENT(GLOBALS->signal_hslider); hadj->page_size=hadj->page_increment=(gfloat)width; hadj->step_increment=(gfloat)10.0; /* approx 1ch at a time */ hadj->lower=(gfloat)0.0; hadj->upper=(gfloat)GLOBALS->signal_pixmap_width; if( ((int)hadj->value)+width > GLOBALS->signal_fill_width) { hadj->value = (gfloat)(GLOBALS->signal_fill_width-width); } wadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider); wadj->page_size=wadj->page_increment=(gfloat) num_traces_displayable; wadj->step_increment=(gfloat)1.0; wadj->lower=(gfloat)0.0; wadj->upper=(gfloat)(GLOBALS->traces.visible ? GLOBALS->traces.visible : 1); if(GLOBALS->traces.scroll_bottom) { Trptr t = GLOBALS->traces.first; int which = 0; int scroll_top = -1, scroll_bottom = -1; int cur_top = wadj->value; int cur_bottom = cur_top + num_traces_displayable - 1; while(t) { if(t == GLOBALS->traces.scroll_top) { scroll_top = which; } if(t == GLOBALS->traces.scroll_bottom) { scroll_bottom = which; break; } t = GiveNextTrace(t); which++; } GLOBALS->traces.scroll_top = GLOBALS->traces.scroll_bottom = NULL; if((scroll_top >= 0) && (scroll_bottom >= 0)) { if((scroll_top > cur_top) && (scroll_bottom <= cur_bottom)) { /* nothing */ } else { if((scroll_bottom - scroll_top + 1) >= num_traces_displayable) { wadj->value=(gfloat)(scroll_bottom - num_traces_displayable + 1); } else { int midpoint = (cur_top + cur_bottom) / 2; if(scroll_top <= cur_top) { wadj->value=(gfloat)scroll_top-1; } else if(scroll_top >= cur_bottom) { wadj->value=(gfloat)(scroll_bottom - num_traces_displayable + 1); } else if(scroll_top < midpoint) { wadj->value=(gfloat)scroll_top-1; } else { wadj->value=(gfloat)(scroll_bottom - num_traces_displayable + 1); } } if(wadj->value < 0.0) wadj->value = 0.0; } } } if(num_traces_displayable>GLOBALS->traces.visible) { wadj->value=(gfloat)(GLOBALS->trtarget_signalwindow_c_1=0); } else if (wadj->value + num_traces_displayable > GLOBALS->traces.visible) { wadj->value=(gfloat)(GLOBALS->trtarget_signalwindow_c_1=GLOBALS->traces.visible-num_traces_displayable); } gtk_signal_emit_by_name (GTK_OBJECT (wadj), "changed"); /* force bar update */ gtk_signal_emit_by_name (GTK_OBJECT (wadj), "value_changed"); /* force text update */ gtk_signal_emit_by_name (GTK_OBJECT (hadj), "changed"); /* force bar update */ return(TRUE); } static gint signalarea_configure_event_local(GtkWidget *widget, GdkEventConfigure *event) { gint rc; gint page_num = gtk_notebook_get_current_page(GTK_NOTEBOOK(GLOBALS->notebook)); struct Global *g_old = GLOBALS; set_GLOBALS((*GLOBALS->contexts)[page_num]); rc = signalarea_configure_event(widget, event); set_GLOBALS(g_old); return(rc); } static gint expose_event(GtkWidget *widget, GdkEventExpose *event) { GtkAdjustment *hadj; int xsrc; hadj=GTK_ADJUSTMENT(GLOBALS->signal_hslider); xsrc=(gint)hadj->value; gdk_draw_pixmap(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE(widget)], GLOBALS->signalpixmap, xsrc+event->area.x, event->area.y, event->area.x, event->area.y, event->area.width, event->area.height); draw_signalarea_focus(); return(FALSE); } static gint expose_event_local(GtkWidget *widget, GdkEventExpose *event) { gint rc; gint page_num = gtk_notebook_get_current_page(GTK_NOTEBOOK(GLOBALS->notebook)); /* struct Global *g_old = GLOBALS; */ set_GLOBALS((*GLOBALS->contexts)[page_num]); rc = expose_event(widget, event); /* seems to cause a conflict flipping back so don't! */ /* set_GLOBALS(g_old); */ return(rc); } static int focus_in_local(GtkWidget *widget, GdkEventFocus *event) { #ifdef FOCUS_DEBUG_MSGS (void)event; printf("Focus in: %08x %08x\n", widget, GLOBALS->signalarea_event_box); #else (void)widget; (void)event; #endif GLOBALS->signalarea_has_focus = TRUE; signalarea_configure_event(GLOBALS->signalarea, NULL); return(FALSE); } static int focus_out_local(GtkWidget *widget, GdkEventFocus *event) { #ifdef FOCUS_DEBUG_MSGS (void)event; printf("Focus out: %08x\n", widget); #else (void)widget; (void)event; #endif GLOBALS->signalarea_has_focus = FALSE; signalarea_configure_event(GLOBALS->signalarea, NULL); return(FALSE); } GtkWidget * create_signalwindow(void) { GtkWidget *table; GtkWidget *frame; char do_focusing = 0; table = gtk_table_new(10, 10, FALSE); GLOBALS->signalarea=gtk_drawing_area_new(); gtk_widget_show(GLOBALS->signalarea); MaxSignalLength(); gtk_widget_set_events(GLOBALS->signalarea, GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK ); gtk_signal_connect(GTK_OBJECT(GLOBALS->signalarea), "configure_event", GTK_SIGNAL_FUNC(signalarea_configure_event_local), NULL); gtk_signal_connect(GTK_OBJECT(GLOBALS->signalarea), "expose_event",GTK_SIGNAL_FUNC(expose_event_local), NULL); sclick: if(GLOBALS->use_standard_clicking) { GtkTargetEntry target_entry[3]; target_entry[0].target = WAVE_DRAG_TAR_NAME_0; target_entry[0].flags = 0; target_entry[0].info = WAVE_DRAG_TAR_INFO_0; target_entry[1].target = WAVE_DRAG_TAR_NAME_1; target_entry[1].flags = 0; target_entry[1].info = WAVE_DRAG_TAR_INFO_1; target_entry[2].target = WAVE_DRAG_TAR_NAME_2; target_entry[2].flags = 0; target_entry[2].info = WAVE_DRAG_TAR_INFO_2; gtk_drag_dest_set( GTK_WIDGET(GLOBALS->signalarea), GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP, target_entry, sizeof(target_entry) / sizeof(GtkTargetEntry), GDK_ACTION_MOVE ); gtkwave_signal_connect(GTK_OBJECT(GLOBALS->signalarea), "drag_motion", GTK_SIGNAL_FUNC(DNDDragMotionCB), GTK_WIDGET(GLOBALS->signalarea)); gtkwave_signal_connect(GTK_OBJECT(GLOBALS->signalarea), "drag_begin", GTK_SIGNAL_FUNC(DNDBeginCB), GTK_WIDGET(GLOBALS->signalarea)); gtkwave_signal_connect(GTK_OBJECT(GLOBALS->signalarea), "drag_end", GTK_SIGNAL_FUNC(DNDEndCB), GTK_WIDGET(GLOBALS->signalarea)); gtk_drag_dest_set( GTK_WIDGET(GLOBALS->wavearea), GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP, target_entry, sizeof(target_entry) / sizeof(GtkTargetEntry), GDK_ACTION_MOVE ); gtkwave_signal_connect(GTK_OBJECT(GLOBALS->wavearea), "drag_motion", GTK_SIGNAL_FUNC(DNDDragMotionCB), GTK_WIDGET(GLOBALS->wavearea)); gtkwave_signal_connect(GTK_OBJECT(GLOBALS->wavearea), "drag_begin", GTK_SIGNAL_FUNC(DNDBeginCB), GTK_WIDGET(GLOBALS->wavearea)); gtkwave_signal_connect(GTK_OBJECT(GLOBALS->wavearea), "drag_end", GTK_SIGNAL_FUNC(DNDEndCB), GTK_WIDGET(GLOBALS->wavearea)); gtk_drag_source_set(GTK_WIDGET(GLOBALS->signalarea), GDK_BUTTON1_MASK | GDK_BUTTON2_MASK, target_entry, sizeof(target_entry) / sizeof(GtkTargetEntry), GDK_ACTION_PRIVATE); gtkwave_signal_connect(GTK_OBJECT(GLOBALS->signalarea), "button_press_event",GTK_SIGNAL_FUNC(button_press_event_std), NULL); gtkwave_signal_connect(GTK_OBJECT(GLOBALS->signalarea), "button_release_event", GTK_SIGNAL_FUNC(button_release_event_std), NULL); gtkwave_signal_connect(GTK_OBJECT(GLOBALS->signalarea), "motion_notify_event",GTK_SIGNAL_FUNC(motion_notify_event_std), NULL); g_timeout_add(100, mouseover_timer, NULL); #ifdef WAVE_ALLOW_QUARTZ_FLUSH_WORKAROUND #ifdef MAC_INTEGRATION g_timeout_add(100, osx_timer, NULL); #endif #endif #ifdef WAVE_USE_GTK2 gtkwave_signal_connect(GTK_OBJECT(GLOBALS->signalarea), "scroll_event",GTK_SIGNAL_FUNC(scroll_event), NULL); #endif do_focusing = 1; } else { fprintf(stderr, "GTKWAVE | \"use_standard_clicking off\" has been removed.\n"); fprintf(stderr, "GTKWAVE | Please update your rc files accordingly.\n"); GLOBALS->use_standard_clicking = 1; goto sclick; } gtk_table_attach (GTK_TABLE (table), GLOBALS->signalarea, 0, 10, 0, 9, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 3, 2); GLOBALS->signal_hslider=gtk_adjustment_new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); gtkwave_signal_connect(GTK_OBJECT(GLOBALS->signal_hslider), "value_changed",GTK_SIGNAL_FUNC(service_hslider), NULL); GLOBALS->hscroll_signalwindow_c_1=gtk_hscrollbar_new(GTK_ADJUSTMENT(GLOBALS->signal_hslider)); gtk_widget_show(GLOBALS->hscroll_signalwindow_c_1); gtk_table_attach (GTK_TABLE (table), GLOBALS->hscroll_signalwindow_c_1, 0, 10, 9, 10, GTK_FILL, GTK_FILL | GTK_SHRINK, 3, 4); gtk_widget_show(table); frame=gtk_frame_new("Signals"); gtk_container_border_width(GTK_CONTAINER(frame),2); gtk_container_add(GTK_CONTAINER(frame),table); if(do_focusing) { GLOBALS->signalarea_event_box = gtk_event_box_new(); gtk_container_add (GTK_CONTAINER (GLOBALS->signalarea_event_box), frame); gtk_widget_show(frame); GTK_WIDGET_SET_FLAGS (GTK_WIDGET(GLOBALS->signalarea_event_box), GTK_CAN_FOCUS | GTK_RECEIVES_DEFAULT); gtkwave_signal_connect(GTK_OBJECT(GLOBALS->signalarea_event_box), "focus_in_event", GTK_SIGNAL_FUNC(focus_in_local), NULL); gtkwave_signal_connect(GTK_OBJECT(GLOBALS->signalarea_event_box), "focus_out_event", GTK_SIGNAL_FUNC(focus_out_local), NULL); /* not necessary for now... */ /* gtkwave_signal_connect(GTK_OBJECT(GLOBALS->signalarea_event_box), "popup_menu",GTK_SIGNAL_FUNC(popup_event), NULL); */ if(!GLOBALS->second_page_created) { if(!GLOBALS->keypress_handler_id) { GLOBALS->keypress_handler_id = install_keypress_handler(); } } return(GLOBALS->signalarea_event_box); } else { return(frame); } } gint install_keypress_handler(void) { gint rc = gtk_signal_connect(GTK_OBJECT(GLOBALS->mainwindow), "key_press_event",GTK_SIGNAL_FUNC(keypress_local), NULL); return(rc); } void remove_keypress_handler(gint id) { gtk_signal_disconnect(GTK_OBJECT(GLOBALS->mainwindow), id); } gtkwave-3.3.66/src/ghw.c0000664000076400007640000007142312523241774014335 0ustar bybellbybell/* GHDL Wavefile reader interface. Copyright (C) 2005-2014 Tristan Gingold and Tony Bybell GHDL 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. GHDL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING. If not, write to the Free Software Foundation, 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. */ #include "globals.h" #include #include "ghw.h" #include "ghwlib.h" #include "tree.h" /************************ splay ************************/ /* * NOTE: * a GHW tree's "which" is not the same as a gtkwave "which" * in that gtkwave's points to the facs[] array and * GHW's functions as an alias handle. The following * (now global) vars are used to resolve those differences... * * static struct Node **nxp; * static struct symbol *sym_head = NULL, *sym_curr = NULL; * static int sym_which = 0; */ /* * pointer splay */ typedef struct ghw_tree_node ghw_Tree; struct ghw_tree_node { ghw_Tree * left, * right; void *item; int val_old; struct symbol *sym; }; long ghw_cmp_l(void *i, void *j) { uintptr_t il = (uintptr_t)i, jl = (uintptr_t)j; return(il - jl); } static ghw_Tree * ghw_splay (void *i, ghw_Tree * t) { /* Simple top down splay, not requiring i to be in the tree t. */ /* What it does is described above. */ ghw_Tree N, *l, *r, *y; int dir; if (t == NULL) return t; N.left = N.right = NULL; l = r = &N; for (;;) { dir = ghw_cmp_l(i, t->item); if (dir < 0) { if (t->left == NULL) break; if (ghw_cmp_l(i, t->left->item)<0) { y = t->left; /* rotate right */ t->left = y->right; y->right = t; t = y; if (t->left == NULL) break; } r->left = t; /* link right */ r = t; t = t->left; } else if (dir > 0) { if (t->right == NULL) break; if (ghw_cmp_l(i, t->right->item)>0) { y = t->right; /* rotate left */ t->right = y->left; y->left = t; t = y; if (t->right == NULL) break; } l->right = t; /* link left */ l = t; t = t->right; } else { break; } } l->right = t->left; /* assemble */ r->left = t->right; t->left = N.right; t->right = N.left; return t; } static ghw_Tree * ghw_insert(void *i, ghw_Tree * t, int val, struct symbol *sym) { /* Insert i into the tree t, unless it's already there. */ /* Return a pointer to the resulting tree. */ ghw_Tree * n; int dir; n = (ghw_Tree *) calloc_2(1, sizeof (ghw_Tree)); if (n == NULL) { fprintf(stderr, "ghw_insert: ran out of memory, exiting.\n"); exit(255); } n->item = i; n->val_old = val; n->sym = sym; if (t == NULL) { n->left = n->right = NULL; return n; } t = ghw_splay(i,t); dir = ghw_cmp_l(i,t->item); if (dir<0) { n->left = t->left; n->right = t; t->left = NULL; return n; } else if (dir>0) { n->right = t->right; n->left = t; t->right = NULL; return n; } else { /* We get here if it's already in the tree */ /* Don't add it again */ free_2(n); return t; } } /* * chain together bits of the same fac */ int strand_pnt(char *s) { int len = strlen(s) - 1; int i; int rc = -1; if(s[len] == ']') { for(i=len-1;i>0;i--) { if(((s[i]>='0') && (s[i]<='9')) || (s[i] == '-')) continue; if(s[i] != '[') break; return(i); /* position right before left bracket for strncmp */ } } return(rc); } void rechain_facs(void) { int i; struct symbol *psr = NULL; struct symbol *root = NULL; for(i=0;inumfacs;i++) { if(psr) { char *fstr1 = GLOBALS->facs[i-1]->name; char *fstr2 = GLOBALS->facs[i]->name; int p1 = strand_pnt(fstr1); int p2 = strand_pnt(fstr2); if(!root) { if((p1>=0)&&(p1==p2)) { if(!strncmp(fstr1, fstr2, p1)) { root = GLOBALS->facs[i-1]; root->vec_root = root; root->vec_chain = GLOBALS->facs[i]; GLOBALS->facs[i]->vec_root = root; } } } else { if((p1>=0)&&(p1==p2)) { if(!strncmp(fstr1, fstr2, p1)) { psr->vec_chain = GLOBALS->facs[i]; GLOBALS->facs[i]->vec_root = root; } else { root = NULL; } } else { root = NULL; } } } psr = GLOBALS->facs[i]; } } /* * preserve tree->t_which ordering so hierarchy children index pointers don't get corrupted */ #if 1 /* limited recursive version */ static void recurse_tree_build_whichcache(struct tree *t) { if(t) { struct tree *t2 = t; int i; int cnt = 1; struct tree **ar; while((t2 = t2->next)) { cnt++; } ar = malloc_2(cnt * sizeof(struct tree *)); t2 = t; for(i=0;ichild) { recurse_tree_build_whichcache(t2->child); } t2 = t2->next; } for(i=cnt-1;i>=0;i--) { t = ar[i]; if(t->t_which >= 0) { GLOBALS->gwt_ghw_c_1 = ghw_insert(t, GLOBALS->gwt_ghw_c_1, t->t_which, GLOBALS->facs[t->t_which]); } } free_2(ar); } } static void recurse_tree_fix_from_whichcache(struct tree *t) { if(t) { struct tree *t2 = t; int i; int cnt = 1; struct tree **ar; while((t2 = t2->next)) { cnt++; } ar = malloc_2(cnt * sizeof(struct tree *)); t2 = t; for(i=0;ichild) { recurse_tree_fix_from_whichcache(t2->child); } t2 = t2->next; } for(i=cnt-1;i>=0;i--) { t = ar[i]; if(t->t_which >= 0) { GLOBALS->gwt_ghw_c_1 = ghw_splay(t, GLOBALS->gwt_ghw_c_1); GLOBALS->gwt_corr_ghw_c_1 = ghw_splay(GLOBALS->gwt_ghw_c_1->sym, GLOBALS->gwt_corr_ghw_c_1); /* all facs are in this tree so this is OK */ t->t_which = GLOBALS->gwt_corr_ghw_c_1->val_old; } } free_2(ar); } } #else /* original fully-recursive version */ static void recurse_tree_build_whichcache(struct tree *t) { if(t) { if(t->child) { recurse_tree_build_whichcache(t->child); } if(t->next) { recurse_tree_build_whichcache(t->next); } if(t->t_which >= 0) GLOBALS->gwt_ghw_c_1 = ghw_insert(t, GLOBALS->gwt_ghw_c_1, t->t_which, GLOBALS->facs[t->t_which]); } } static void recurse_tree_fix_from_whichcache(struct tree *t) { if(t) { if(t->child) { recurse_tree_fix_from_whichcache(t->child); } if(t->next) { recurse_tree_fix_from_whichcache(t->next); } if(t->t_which >= 0) { GLOBALS->gwt_ghw_c_1 = ghw_splay(t, GLOBALS->gwt_ghw_c_1); GLOBALS->gwt_corr_ghw_c_1 = ghw_splay(GLOBALS->gwt_ghw_c_1->sym, GLOBALS->gwt_corr_ghw_c_1); /* all facs are in this tree so this is OK */ t->t_which = GLOBALS->gwt_corr_ghw_c_1->val_old; } } } #endif static void incinerate_whichcache_tree(ghw_Tree *t) { if(t->left) incinerate_whichcache_tree(t->left); if(t->right) incinerate_whichcache_tree(t->right); free_2(t); } /* * sort facs and also cache/reconstruct tree->t_which pointers */ static void ghw_sortfacs(void) { int i; recurse_tree_build_whichcache(GLOBALS->treeroot); for(i=0;inumfacs;i++) { char *subst; #ifdef WAVE_HIERFIX char ch; #endif int len; struct symbol *curnode = GLOBALS->facs[i]; subst=curnode->name; if((len=strlen(subst))>GLOBALS->longestname) GLOBALS->longestname=len; #ifdef WAVE_HIERFIX while((ch=(*subst))) { if(ch==GLOBALS->hier_delimeter) { *subst=VCDNAM_HIERSORT; } /* forces sort at hier boundaries */ subst++; } #endif } wave_heapsort(GLOBALS->facs,GLOBALS->numfacs); for(i=0;inumfacs;i++) { GLOBALS->gwt_corr_ghw_c_1 = ghw_insert(GLOBALS->facs[i], GLOBALS->gwt_corr_ghw_c_1, i, NULL); } recurse_tree_fix_from_whichcache(GLOBALS->treeroot); if(GLOBALS->gwt_ghw_c_1) { incinerate_whichcache_tree(GLOBALS->gwt_ghw_c_1); GLOBALS->gwt_ghw_c_1 = NULL; } if(GLOBALS->gwt_corr_ghw_c_1) { incinerate_whichcache_tree(GLOBALS->gwt_corr_ghw_c_1); GLOBALS->gwt_corr_ghw_c_1 = NULL; } #ifdef WAVE_HIERFIX for(i=0;inumfacs;i++) { char *subst, ch; subst=GLOBALS->facs[i]->name; while((ch=(*subst))) { if(ch==VCDNAM_HIERSORT) { *subst=GLOBALS->hier_delimeter; } /* restore back to normal */ subst++; } } #endif GLOBALS->facs_are_sorted=1; } /*******************************************************************************/ static struct tree * build_hierarchy_type (struct ghw_handler *h, union ghw_type *t, const char *pfx, unsigned int **sig); static void build_hierarchy_array (struct ghw_handler *h, union ghw_type *arr, int dim, const char *pfx, struct tree **res, unsigned int **sig) { union ghw_type *idx; struct ghw_type_array *base = arr->sa.base; char *name = NULL; if (dim == base->nbr_dim) { struct tree *t; sprintf (GLOBALS->asbuf, "%s]", pfx); name = strdup_2(GLOBALS->asbuf); t = build_hierarchy_type (h, base->el, name, sig); if (*res != NULL) (*res)->next = t; *res = t; return; } idx = ghw_get_base_type (base->dims[dim]); switch (idx->kind) { case ghdl_rtik_type_i32: { int32_t v; char *nam; struct ghw_range_i32 *r; /* struct tree *last; */ int len; /* last = NULL; */ r = &arr->sa.rngs[dim]->i32; len = ghw_get_range_length ((union ghw_range *)r); if (len <= 0) break; v = r->left; while (1) { sprintf(GLOBALS->asbuf, "%s%c"GHWLD, pfx, dim == 0 ? '[' : ',', v); nam = strdup_2(GLOBALS->asbuf); build_hierarchy_array (h, arr, dim + 1, nam, res, sig); free_2(nam); if (v == r->right) break; if (r->dir == 0) v++; else v--; } } return; case ghdl_rtik_type_e8: { int32_t v; char *nam; struct ghw_range_e8 *r; /* struct tree *last; */ int len; /* last = NULL; */ r = &arr->sa.rngs[dim]->e8; len = ghw_get_range_length ((union ghw_range *)r); if (len <= 0) break; v = r->left; while (1) { sprintf(GLOBALS->asbuf, "%s%c"GHWLD, pfx, dim == 0 ? '[' : ',', v); nam = strdup_2(GLOBALS->asbuf); build_hierarchy_array (h, arr, dim + 1, nam, res, sig); free_2(nam); if (v == r->right) break; if (r->dir == 0) v++; else v--; } } return; default: fprintf (stderr, "build_hierarchy_array: unhandled type %d\n", idx->kind); abort (); } } static struct tree * build_hierarchy_type (struct ghw_handler *h, union ghw_type *t, const char *pfx, unsigned int **sig) { struct tree *res; struct symbol *s; switch (t->kind) { case ghdl_rtik_subtype_scalar: return build_hierarchy_type (h, t->ss.base, pfx, sig); case ghdl_rtik_type_b2: case ghdl_rtik_type_e8: case ghdl_rtik_type_f64: case ghdl_rtik_type_i32: case ghdl_rtik_type_i64: case ghdl_rtik_type_p32: case ghdl_rtik_type_p64: s = calloc_2(1, sizeof(struct symbol)); if(!GLOBALS->firstnode) { GLOBALS->firstnode= GLOBALS->curnode=calloc_2(1, sizeof(struct symchain)); } else { GLOBALS->curnode->next=calloc_2(1, sizeof(struct symchain)); GLOBALS->curnode=GLOBALS->curnode->next; } GLOBALS->curnode->symbol=s; GLOBALS->nbr_sig_ref_ghw_c_1++; res = (struct tree *) calloc_2(1, sizeof (struct tree) + strlen(pfx) + 1); strcpy(res->name, (char *)pfx); res->t_which = *(*sig)++; s->n = GLOBALS->nxp_ghw_c_1[res->t_which]; return res; case ghdl_rtik_subtype_array: case ghdl_rtik_subtype_array_ptr: { struct tree *r; res = (struct tree *) calloc_2(1, sizeof (struct tree) + strlen(pfx) + 1); strcpy(res->name, (char *)pfx); res->t_which = WAVE_T_WHICH_UNDEFINED_COMPNAME; r = res; build_hierarchy_array (h, t, 0, "", &res, sig); r->child = r->next; r->next = NULL; return r; } case ghdl_rtik_type_record: { struct tree *last; struct tree *c; int i; res = (struct tree *) calloc_2(1, sizeof (struct tree) + strlen(pfx) + 1); strcpy(res->name, (char *)pfx); res->t_which = WAVE_T_WHICH_UNDEFINED_COMPNAME; last = NULL; for (i = 0; i < t->rec.nbr_fields; i++) { c = build_hierarchy_type (h, t->rec.el[i].type, t->rec.el[i].name, sig); if (last == NULL) res->child = c; else last->next = c; last = c; } return res; } default: fprintf (stderr, "build_hierarchy_type: unhandled type %d\n", t->kind); abort (); } } /* Create the gtkwave tree from the GHW hierarchy. */ static struct tree * build_hierarchy (struct ghw_handler *h, struct ghw_hie *hie) { struct tree *t; struct tree *t_ch; struct tree *prev; struct ghw_hie *ch; unsigned char ttype; switch (hie->kind) { case ghw_hie_design: case ghw_hie_block: case ghw_hie_instance: case ghw_hie_generate_for: case ghw_hie_generate_if: case ghw_hie_package: /* Convert kind. */ switch(hie->kind) { case ghw_hie_design: ttype = TREE_VHDL_ST_DESIGN; break; case ghw_hie_block: ttype = TREE_VHDL_ST_BLOCK; break; case ghw_hie_instance: ttype = TREE_VHDL_ST_INSTANCE; break; case ghw_hie_generate_for: ttype = TREE_VHDL_ST_GENFOR; break; case ghw_hie_generate_if: ttype = TREE_VHDL_ST_GENIF; break; case ghw_hie_package: default: ttype = TREE_VHDL_ST_PACKAGE; break; } /* For iterative generate, add the index. */ if (hie->kind == ghw_hie_generate_for) { char buf[128]; int name_len, buf_len; char *n; ghw_get_value (buf, sizeof (buf), hie->u.blk.iter_value, hie->u.blk.iter_type); name_len = strlen (hie->name); buf_len = strlen (buf); t = (struct tree *) calloc_2(1, sizeof (struct tree) + (2 + buf_len + name_len + 1)); t->kind = ttype; n = t->name; memcpy (n, hie->name, name_len); n += name_len; *n++ = '['; memcpy (n, buf, buf_len); n += buf_len; *n++ = ']'; *n = 0; } else { if(hie->name) { t = (struct tree *) calloc_2(1, sizeof (struct tree) + strlen(hie->name) + 1); t->kind = ttype; strcpy(t->name, (char *)hie->name); } else { t = (struct tree *) calloc_2(1, sizeof (struct tree) + 1); t->kind = ttype; } } t->t_which = WAVE_T_WHICH_UNDEFINED_COMPNAME; /* Recurse. */ prev = NULL; for (ch = hie->u.blk.child; ch != NULL; ch = ch->brother) { t_ch = build_hierarchy (h, ch); if (t_ch != NULL) { if (prev == NULL) t->child = t_ch; else prev->next = t_ch; prev = t_ch; } } return t; case ghw_hie_process: return NULL; case ghw_hie_signal: case ghw_hie_port_in: case ghw_hie_port_out: case ghw_hie_port_inout: case ghw_hie_port_buffer: case ghw_hie_port_linkage: { unsigned int *ptr = hie->u.sig.sigs; /* Convert kind. */ switch(hie->kind) { case ghw_hie_signal: ttype = TREE_VHDL_ST_SIGNAL; break; case ghw_hie_port_in: ttype = TREE_VHDL_ST_PORTIN; break; case ghw_hie_port_out: ttype = TREE_VHDL_ST_PORTOUT; break; case ghw_hie_port_inout: ttype = TREE_VHDL_ST_PORTINOUT; break; case ghw_hie_port_buffer: ttype = TREE_VHDL_ST_BUFFER; break; case ghw_hie_port_linkage: default: ttype = TREE_VHDL_ST_LINKAGE; break; } /* Convert type. */ t = build_hierarchy_type (h, hie->u.sig.type, hie->name, &ptr); if (*ptr != 0) abort (); if(t) { t->kind = ttype; } return t; } default: fprintf (stderr, "ghw: build_hierarchy: cannot handle hie %d\n", hie->kind); abort (); } } void facs_debug (void) { int i; struct Node *n; for (i = 0; i < GLOBALS->numfacs; i++) { hptr h; n = GLOBALS->facs[i]->n; printf ("%d: %s\n", i, n->nname); if (n->extvals) printf (" ext: %d - %d\n", n->msi, n->lsi); for (h = &n->head; h; h = h->next) printf (" time:"TTFormat" flags:%02x vect:%p\n", h->time, h->flags, h->v.h_vector); } } static void create_facs (struct ghw_handler *h) { int i; struct symchain *sc = GLOBALS->firstnode; GLOBALS->numfacs = GLOBALS->nbr_sig_ref_ghw_c_1; GLOBALS->facs=(struct symbol **)malloc_2(GLOBALS->numfacs*sizeof(struct symbol *)); i = 0; while(sc) { GLOBALS->facs[i++] = sc->symbol; sc = sc->next; } for (i = 0; i < h->nbr_sigs; i++) { struct Node *n = GLOBALS->nxp_ghw_c_1[i]; if (h->sigs[i].type) switch (h->sigs[i].type->kind) { case ghdl_rtik_type_b2: if (h->sigs[i].type->en.wkt == ghw_wkt_bit) { n->extvals = 0; break; } /* FALLTHROUGH */ case ghdl_rtik_type_e8: if (GLOBALS->xlat_1164_ghw_c_1 && h->sigs[i].type->en.wkt == ghw_wkt_std_ulogic) { n->extvals = 0; break; } /* FALLTHROUGH */ case ghdl_rtik_type_e32: case ghdl_rtik_type_i32: case ghdl_rtik_type_i64: case ghdl_rtik_type_f64: case ghdl_rtik_type_p32: case ghdl_rtik_type_p64: n->extvals = 1; n->msi = n->lsi = 0; break; default: fprintf (stderr, "ghw:create_facs: unhandled kind %d\n", h->sigs[i].type->kind); n->extvals = 0; } } } static void set_fac_name_1 (struct tree *t) { for (; t != NULL; t = t->next) { int prev_len = GLOBALS->fac_name_len_ghw_c_1; /* Complete the name. */ if(t->name[0]) /* originally (t->name != NULL) when using pointers */ { int len; len = strlen (t->name) + 1; if (len + GLOBALS->fac_name_len_ghw_c_1 >= GLOBALS->fac_name_max_ghw_c_1) { GLOBALS->fac_name_max_ghw_c_1 *= 2; if (GLOBALS->fac_name_max_ghw_c_1 <= len + GLOBALS->fac_name_len_ghw_c_1) GLOBALS->fac_name_max_ghw_c_1 = len + GLOBALS->fac_name_len_ghw_c_1 + 1; GLOBALS->fac_name_ghw_c_1 = realloc_2(GLOBALS->fac_name_ghw_c_1, GLOBALS->fac_name_max_ghw_c_1); } if(t->name[0] != '[') { GLOBALS->fac_name_ghw_c_1[GLOBALS->fac_name_len_ghw_c_1] = '.'; /* The NUL is copied, since LEN is 1 + strlen. */ memcpy (GLOBALS->fac_name_ghw_c_1 + GLOBALS->fac_name_len_ghw_c_1 + 1, t->name, len); GLOBALS->fac_name_len_ghw_c_1 += len; } else { memcpy (GLOBALS->fac_name_ghw_c_1 + GLOBALS->fac_name_len_ghw_c_1, t->name, len); GLOBALS->fac_name_len_ghw_c_1 += (len - 1); } } if (t->t_which >= 0) { struct symchain *sc = GLOBALS->firstnode; struct symbol *s = sc->symbol; s->name = strdup_2(GLOBALS->fac_name_ghw_c_1); s->n = GLOBALS->nxp_ghw_c_1[t->t_which]; if(!s->n->nname) s->n->nname = s->name; t->t_which = GLOBALS->sym_which_ghw_c_1++; /* patch in gtkwave "which" as node is correct */ GLOBALS->curnode = GLOBALS->firstnode->next; free_2(GLOBALS->firstnode); GLOBALS->firstnode = GLOBALS->curnode; } if (t->child) set_fac_name_1 (t->child); /* Revert name. */ GLOBALS->fac_name_len_ghw_c_1 = prev_len; GLOBALS->fac_name_ghw_c_1[GLOBALS->fac_name_len_ghw_c_1] = 0; } } static void set_fac_name (struct ghw_handler *h) { if (GLOBALS->fac_name_max_ghw_c_1 == 0) { GLOBALS->fac_name_max_ghw_c_1 = 1024; GLOBALS->fac_name_ghw_c_1 = malloc_2(GLOBALS->fac_name_max_ghw_c_1); } GLOBALS->fac_name_len_ghw_c_1 = 3; memcpy (GLOBALS->fac_name_ghw_c_1, "top", 4); GLOBALS->last_fac_ghw_c_1 = h->nbr_sigs; set_fac_name_1 (GLOBALS->treeroot); } static void add_history (struct ghw_handler *h, struct Node *n, int sig_num) { struct HistEnt *he; struct ghw_sig *sig = &h->sigs[sig_num]; union ghw_type *sig_type = sig->type; int flags; int is_vector = 0; #ifdef WAVE_HAS_H_DOUBLE int is_double = 0; #endif if (sig_type == NULL) return; GLOBALS->regions++; switch (sig_type->kind) { case ghdl_rtik_type_b2: if (sig_type->en.wkt == ghw_wkt_bit) { flags = 0; break; } /* FALLTHROUGH */ case ghdl_rtik_type_e8: if (GLOBALS->xlat_1164_ghw_c_1 && sig_type->en.wkt == ghw_wkt_std_ulogic) { flags = 0; break; } /* FALLTHROUGH */ case ghdl_rtik_type_e32: case ghdl_rtik_type_i32: case ghdl_rtik_type_i64: case ghdl_rtik_type_p32: case ghdl_rtik_type_p64: flags = HIST_STRING|HIST_REAL; if (HIST_STRING == 0) { if (!GLOBALS->warned_ghw_c_1) fprintf (stderr, "warning: do not compile with STRICT_VCD\n"); GLOBALS->warned_ghw_c_1 = 1; return; } break; case ghdl_rtik_type_f64: flags = HIST_REAL; break; default: fprintf (stderr, "ghw:add_history: unhandled kind %d\n", sig->type->kind); return; } if(!n->curr) { he=histent_calloc(); he->flags = flags; he->time=-1; he->v.h_vector=NULL; n->head.next=he; n->curr=he; n->head.time = -2; } he=histent_calloc(); he->flags = flags; he->time=h->snap_time; switch (sig_type->kind) { case ghdl_rtik_type_b2: if (sig_type->en.wkt == ghw_wkt_bit) he->v.h_val = sig->val->b2 == 0 ? AN_0 : AN_1; else { he->v.h_vector = (char *)sig->type->en.lits[sig->val->b2]; is_vector = 1; } break; case ghdl_rtik_type_e8: if (GLOBALS->xlat_1164_ghw_c_1 && sig_type->en.wkt == ghw_wkt_std_ulogic) { /* Res: 0->0, 1->X, 2->Z, 3->1 */ static const char map_su2vlg[9] = { /* U */ AN_U, /* X */ AN_X, /* 0 */ AN_0, /* 1 */ AN_1, /* Z */ AN_Z, /* W */ AN_W, /* L */ AN_L, /* H */ AN_H, /* - */ AN_DASH }; he->v.h_val = map_su2vlg[sig->val->e8]; } else { he->v.h_vector = (char *)sig_type->en.lits[sig->val->e8]; is_vector = 1; } break; case ghdl_rtik_type_f64: { #ifdef WAVE_HAS_H_DOUBLE he->v.h_double = sig->val->f64; is_double = 1; #else double *d = malloc_2(sizeof (double)); *d = sig->val->f64; he->v.h_vector = (char *)d; is_vector = 1; #endif } break; case ghdl_rtik_type_i32: case ghdl_rtik_type_p32: sprintf (GLOBALS->asbuf, GHWLD, sig->val->i32); he->v.h_vector = strdup_2(GLOBALS->asbuf); is_vector = 1; break; case ghdl_rtik_type_i64: case ghdl_rtik_type_p64: sprintf (GLOBALS->asbuf, GHWLLD, sig->val->i64); he->v.h_vector = strdup_2(GLOBALS->asbuf); is_vector = 1; break; default: abort (); } /* deglitch */ if(n->curr->time == he->time) { int gl_add = 0; if(n->curr->time) /* filter out time zero glitches */ { gl_add = 1; } GLOBALS->num_glitches_ghw_c_1 += gl_add; if(!(n->curr->flags&HIST_GLITCH)) { if(gl_add) { n->curr->flags|=HIST_GLITCH; /* set the glitch flag */ GLOBALS->num_glitch_regions_ghw_c_1++; } } #ifdef WAVE_HAS_H_DOUBLE if(is_double) { n->curr->v.h_double = he->v.h_double; } else #endif if(is_vector) { if(n->curr->v.h_vector && sig_type->kind != ghdl_rtik_type_b2 && sig_type->kind != ghdl_rtik_type_e8) free_2(n->curr->v.h_vector); n->curr->v.h_vector = he->v.h_vector; /* can't free up this "he" because of block allocation so assume it's dead */ } else { n->curr->v.h_val = he->v.h_val; } return; } else /* look for duplicate dumps of same value at adjacent times */ { if(!is_vector #ifdef WAVE_HAS_H_DOUBLE & !is_double #endif ) { if(n->curr->v.h_val == he->v.h_val) { return; /* can't free up this "he" because of block allocation so assume it's dead */ } } } n->curr->next=he; n->curr=he; } static void add_tail (struct ghw_handler *h) { int i; TimeType j; for (j = 1; j>=0 ; j--) /* add two endcaps */ for (i = 0; i < h->nbr_sigs; i++) { struct ghw_sig *sig = &h->sigs[i]; struct Node *n = GLOBALS->nxp_ghw_c_1[i]; struct HistEnt *he; if (sig->type == NULL || n == NULL || !n->curr) continue; /* Copy the last one. */ he = histent_calloc(); *he = *n->curr; he->time = MAX_HISTENT_TIME - j; he->next = NULL; /* Append. */ n->curr->next=he; n->curr=he; } } static void read_traces (struct ghw_handler *h) { int *list; int i; enum ghw_res res; list = malloc_2((GLOBALS->numfacs + 1) * sizeof (int)); while (1) { res = ghw_read_sm_hdr (h, list); switch (res) { case ghw_res_error: case ghw_res_eof: free_2(list); return; case ghw_res_ok: case ghw_res_other: break; case ghw_res_snapshot: if (h->snap_time > GLOBALS->max_time) GLOBALS->max_time = h->snap_time; /* printf ("Time is "GHWLLD"\n", h->snap_time); */ for (i = 0; i < h->nbr_sigs; i++) add_history (h, GLOBALS->nxp_ghw_c_1[i], i); break; case ghw_res_cycle: while (1) { int sig; /* printf ("Time is "GHWLLD"\n", h->snap_time); */ if (h->snap_time < LLDescriptor(9223372036854775807)) { if (h->snap_time > GLOBALS->max_time) GLOBALS->max_time = h->snap_time; for (i = 0; (sig = list[i]) != 0; i++) add_history (h, GLOBALS->nxp_ghw_c_1[sig], sig); } res = ghw_read_cycle_next (h); if (res != 1) break; res = ghw_read_cycle_cont (h, list); if (res < 0) break; } if (res < 0) break; res = ghw_read_cycle_end (h); if (res < 0) break; break; } } } /*******************************************************************************/ TimeType ghw_main(char *fname) { struct ghw_handler handle; int i; int rc; if(!GLOBALS->hier_was_explicitly_set) /* set default hierarchy split char */ { GLOBALS->hier_delimeter='.'; } handle.flag_verbose = 0; if ((rc=ghw_open (&handle, fname)) < 0) { fprintf (stderr, "Error opening ghw file '%s', rc=%d.\n", fname, rc); return(LLDescriptor(0)); /* look at return code in caller for success status... */ } GLOBALS->time_scale = 1; GLOBALS->time_dimension = 'f'; GLOBALS->asbuf = malloc_2(4097); if (ghw_read_base (&handle) < 0) { free_2(GLOBALS->asbuf); GLOBALS->asbuf = NULL; fprintf (stderr, "Error in ghw file '%s'.\n", fname); return(LLDescriptor(0)); /* look at return code in caller for success status... */ } GLOBALS->min_time = 0; GLOBALS->max_time = 0; GLOBALS->nbr_sig_ref_ghw_c_1 = 0; GLOBALS->nxp_ghw_c_1 =(struct Node **)calloc_2(handle.nbr_sigs, sizeof(struct Node *)); for(i=0;inxp_ghw_c_1[i] = (struct Node *)calloc_2(1,sizeof(struct Node)); } GLOBALS->treeroot = build_hierarchy (&handle, handle.hie); /* GHW does not contains a 'top' name. FIXME: should use basename of the file. */ create_facs (&handle); read_traces (&handle); add_tail (&handle); set_fac_name (&handle); free_2(GLOBALS->nxp_ghw_c_1); GLOBALS->nxp_ghw_c_1 = NULL; /* fix up names on aliased nodes via cloning... */ for(i=0;inumfacs;i++) { if(strcmp(GLOBALS->facs[i]->name, GLOBALS->facs[i]->n->nname)) { struct Node *n = malloc_2(sizeof(struct Node)); memcpy(n, GLOBALS->facs[i]->n, sizeof(struct Node)); GLOBALS->facs[i]->n = n; n->nname = GLOBALS->facs[i]->name; } } /* treeroot->name = "top"; */ { const char *base_hier = "top"; struct tree *t = calloc_2(1, sizeof(struct tree) + strlen(base_hier) + 1); memcpy(t, GLOBALS->treeroot, sizeof(struct tree)); strcpy(t->name, base_hier); /* scan-build false warning here, thinks name[1] is total length */ #ifndef WAVE_TALLOC_POOL_SIZE free_2(GLOBALS->treeroot); /* if using tree alloc pool, can't deallocate this */ #endif GLOBALS->treeroot = t; } ghw_close (&handle); rechain_facs(); /* vectorize bitblasted nets */ ghw_sortfacs(); /* sort nets as ghw is unsorted ... also fix hier tree (it should really be built *after* facs are sorted!) */ #if 0 treedebug(GLOBALS->treeroot,""); facs_debug(); #endif GLOBALS->is_ghw = 1; fprintf(stderr, "["TTFormat"] start time.\n["TTFormat"] end time.\n", GLOBALS->min_time*GLOBALS->time_scale, GLOBALS->max_time*GLOBALS->time_scale); if(GLOBALS->num_glitches_ghw_c_1) fprintf(stderr, "Warning: encountered %d glitch%s across %d glitch region%s.\n", GLOBALS->num_glitches_ghw_c_1, (GLOBALS->num_glitches_ghw_c_1!=1)?"es":"", GLOBALS->num_glitch_regions_ghw_c_1, (GLOBALS->num_glitch_regions_ghw_c_1!=1)?"s":""); return GLOBALS->max_time; } /*******************************************************************************/ gtkwave-3.3.66/src/debug.h0000664000076400007640000001141412341266475014640 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2012. * * 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. */ #ifndef WAVE_DEBUG_H #define WAVE_DEBUG_H #include #include #include #include #ifndef _MSC_VER #ifndef __MINGW32__ #include #else #include #endif #endif #define WAVE_MAX_CLIST_LENGTH 15000 /* * If you have problems viewing traces (mangled timevalues), * make sure that you use longs rather than the glib 64-bit * types... */ #ifdef G_HAVE_GINT64 typedef gint64 TimeType; typedef guint64 UTimeType; #ifndef _MSC_VER #define LLDescriptor(x) x##LL #define ULLDescriptor(x) x##ULL #ifdef __MINGW32__ #define TTFormat "%I64d" #define UTTFormat "%I64u" #else #if __WORDSIZE == 64 #define TTFormat "%ld" #define UTTFormat "%lu" #else #define TTFormat "%lld" #define UTTFormat "%llu" #endif #endif #else #define LLDescriptor(x) x##i64 #define ULLDescriptor(x) x##i64 #define TTFormat "%I64d" #define UTTFormat "%I64u" #endif #define WAVE_MINZOOM (LLDescriptor(-4000000000)) #else typedef long TimeType; typedef unsigned long UTimeType; #define TTFormat "%d" #define UTTFormat "%u" #define LLDescriptor(x) x #define ULLDescriptor(x) x #define WAVE_MINZOOM (LLDescriptor(-20000000)) #endif #ifdef _MSC_VER #define strncasecmp(s1, s2, n) _strnicmp(s1, s2, n) #define popen _popen #define pclose _pclose #endif #ifdef DEBUG_PRINTF #define DEBUG(x) x #else #define DEBUG(x) #endif #ifdef DEBUG_MALLOC_LINES void free_2(void *ptr, char *filename, int lineno); #define free_2(x) free_2((x),__FILE__,__LINE__) void *malloc_2(size_t size, char *filename, int lineno); #define malloc_2(x) malloc_2((x),__FILE__,__LINE__) void *realloc_2(void *ptr, size_t size, char *filename, int lineno); #define realloc_2(x, y) realloc_2((x),(y),__FILE__,__LINE__) void *calloc_2(size_t nmemb, size_t size, char *filename, int lineno); #define calloc_2(x, y) calloc_2((x),(y),__FILE__,__LINE__) #else void free_2(void *ptr); void *malloc_2(size_t size); void *realloc_2(void *ptr, size_t size); void *calloc_2(size_t nmemb, size_t size); #endif void free_outstanding(void); char *strdup_2(const char *s); char *strdup_2s(const char *s); char *tmpnam_2(char *s, int *fd); /* mimic functionality of tmpnam() */ TimeType atoi_64(const char *str); void gtk_tooltips_set_tip_2(GtkTooltips *tooltips, GtkWidget *widget, const gchar *tip_text, const gchar *tip_private); void gtk_tooltips_set_delay_2(GtkTooltips *tooltips, guint delay); GtkTooltips* gtk_tooltips_new_2(void); char *realpath_2(const char *path, char *resolved_path); enum WaveLoadingTitleType { WAVE_SET_TITLE_NONE, WAVE_SET_TITLE_MODIFIED, WAVE_SET_TITLE_LOADING }; void wave_gtk_window_set_title(GtkWindow *window, const gchar *title, int typ, int pct); #undef WAVE_USE_SIGCMP_INFINITE_PRECISION /* define this for slow sigcmp with infinite digit accuracy */ #define WAVE_OPT_SKIP 1 /* make larger for more accel on traces */ /* for source code annotation helper app */ #ifndef PATH_MAX #define PATH_MAX (4096) #endif #define WAVE_MATCHWORD "WAVE" enum AnnotateAetType { WAVE_ANNO_NONE, WAVE_ANNO_AE2, WAVE_ANNO_VZT, WAVE_ANNO_LXT2, WAVE_ANNO_FST, WAVE_ANNO_MAX }; #if !defined _MSC_VER && !defined __MINGW32__ #include #include struct gtkwave_annotate_ipc_t { char matchword[4]; /* match against WAVE_MATCHWORD string */ char time_string[40]; /* formatted marker time */ pid_t gtkwave_process; pid_t browser_process; TimeType marker; unsigned marker_set : 1; unsigned cygwin_remote_kill : 1; int aet_type; char aet_name[PATH_MAX+1]; char stems_name[PATH_MAX+1]; }; #else struct gtkwave_annotate_ipc_t { char matchword[4]; /* match against WAVE_MATCHWORD string */ char time_string[40]; /* formatted marker time */ #ifdef __MINGW32__ HANDLE browser_process; #endif TimeType marker; unsigned marker_set : 1; unsigned cygwin_remote_kill : 1; int aet_type; char aet_name[PATH_MAX+1]; char stems_name[PATH_MAX+1]; }; #endif #define DUAL_MATCHWORD "DUAL" struct gtkwave_dual_ipc_t { char matchword[4]; /* match against DUAL_MATCHWORD string */ TimeType left_margin_time; TimeType marker, baseline; gdouble zoom; unsigned use_new_times : 1; unsigned viewer_is_initialized : 1; }; enum GtkwaveFileTypes { G_FT_UNKNOWN, G_FT_LXT, G_FT_LXT2, G_FT_VZT, G_FT_FST }; int determine_gtkwave_filetype(const char *path); #endif gtkwave-3.3.66/src/vcd_keywords.c0000664000076400007640000001540412176064156016251 0ustar bybellbybell/* C code produced by gperf version 3.0.3 */ /* Command-line: /usr/bin/gperf -o -i 1 -C -k '1,$' -L C -H keyword_hash -N check_identifier -tT ./vcd_keywords.gperf */ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) /* The character set is not based on ISO-646. */ error "gperf generated tables don't work with this execution character set. Please report a bug to ." #endif #line 1 "./vcd_keywords.gperf" /* AIX may need this for alloca to work */ #if defined _AIX #pragma alloca #endif #include #include #include "vcd.h" struct vcd_keyword { const char *name; int token; }; #define TOTAL_KEYWORDS 33 #define MIN_WORD_LENGTH 2 #define MAX_WORD_LENGTH 14 #define MIN_HASH_VALUE 5 #define MAX_HASH_VALUE 69 /* maximum key range = 65, duplicates = 0 */ #ifdef __GNUC__ __inline #else #ifdef __cplusplus inline #endif #endif static unsigned int keyword_hash (str, len) register const char *str; register unsigned int len; { static const unsigned char asso_values[] = { 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 36, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 56, 51, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 26, 26, 1, 36, 1, 70, 36, 6, 70, 31, 1, 1, 70, 16, 1, 6, 1, 6, 1, 70, 70, 21, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70 }; return len + asso_values[(unsigned char)str[len - 1]] + asso_values[(unsigned char)str[0]+1]; } #ifdef __GNUC__ __inline #ifdef __GNUC_STDC_INLINE__ __attribute__ ((__gnu_inline__)) #endif #endif const struct vcd_keyword * check_identifier (str, len) register const char *str; register unsigned int len; { static const struct vcd_keyword wordlist[] = { {""}, {""}, {""}, {""}, {""}, #line 23 "./vcd_keywords.gperf" {"reg", V_REG}, #line 26 "./vcd_keywords.gperf" {"time", V_TIME}, {""}, #line 30 "./vcd_keywords.gperf" {"trireg", V_TRIREG}, #line 37 "./vcd_keywords.gperf" {"in", V_IN}, #line 22 "./vcd_keywords.gperf" {"realtime", V_REALTIME}, #line 36 "./vcd_keywords.gperf" {"port", V_PORT}, #line 29 "./vcd_keywords.gperf" {"trior", V_TRIOR}, #line 40 "./vcd_keywords.gperf" {"string", V_STRINGTYPE}, #line 45 "./vcd_keywords.gperf" {"longint", V_LONGINT}, #line 43 "./vcd_keywords.gperf" {"int", V_INT}, #line 18 "./vcd_keywords.gperf" {"parameter", V_PARAMETER}, #line 39 "./vcd_keywords.gperf" {"inout", V_INOUT}, {""}, #line 19 "./vcd_keywords.gperf" {"integer", V_INTEGER}, #line 44 "./vcd_keywords.gperf" {"shortint", V_SHORTINT}, #line 21 "./vcd_keywords.gperf" {"real_parameter", V_REAL_PARAMETER}, {""}, {""}, {""}, #line 38 "./vcd_keywords.gperf" {"out", V_OUT}, #line 34 "./vcd_keywords.gperf" {"wire", V_WIRE}, {""}, {""}, {""}, #line 35 "./vcd_keywords.gperf" {"wor", V_WOR}, #line 46 "./vcd_keywords.gperf" {"byte", V_BYTE}, #line 42 "./vcd_keywords.gperf" {"logic", V_LOGIC}, #line 28 "./vcd_keywords.gperf" {"triand", V_TRIAND}, {""}, #line 41 "./vcd_keywords.gperf" {"bit", V_BIT}, #line 20 "./vcd_keywords.gperf" {"real", V_REAL}, {""}, {""}, {""}, #line 27 "./vcd_keywords.gperf" {"tri", V_TRI}, #line 47 "./vcd_keywords.gperf" {"enum", V_ENUM}, {""}, {""}, {""}, {""}, #line 48 "./vcd_keywords.gperf" {"shortreal", V_SHORTREAL}, #line 17 "./vcd_keywords.gperf" {"event", V_EVENT}, {""}, {""}, {""}, #line 33 "./vcd_keywords.gperf" {"wand", V_WAND}, {""}, {""}, {""}, {""}, #line 32 "./vcd_keywords.gperf" {"tri1", V_TRI1}, {""}, {""}, {""}, {""}, #line 31 "./vcd_keywords.gperf" {"tri0", V_TRI0}, {""}, {""}, #line 25 "./vcd_keywords.gperf" {"supply1", V_SUPPLY1}, {""}, #line 49 "./vcd_keywords.gperf" {"$end", V_END}, {""}, {""}, #line 24 "./vcd_keywords.gperf" {"supply0", V_SUPPLY0} }; if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) { register int key = keyword_hash (str, len); if (key <= MAX_HASH_VALUE && key >= 0) { register const char *s = wordlist[key].name; if (*str == *s && !strcmp (str + 1, s + 1)) return &wordlist[key]; } } return 0; } #line 50 "./vcd_keywords.gperf" int vcd_keyword_code(const char *s, unsigned int len) { const struct vcd_keyword *rc = check_identifier(s, len); return(rc ? rc->token : V_STRING); } gtkwave-3.3.66/src/currenttime.c0000664000076400007640000004344512341266475016117 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2008. * * 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. */ #include "globals.h" #include #include #include "currenttime.h" #include "symbol.h" static char *time_prefix=WAVE_SI_UNITS; static char *maxtime_label_text="Maximum Time"; static char *marker_label_text ="Marker Time"; static char *maxtime_label_text_hpos="Max"; static char *marker_label_text_hpos ="Marker"; void fractional_timescale_fix(char *s) { char buf[32], sfx[2]; int i, len; int prefix_idx = 0; if(*s != '0') return; len = strlen(s); for(i=0;iuse_maxtime_display) { gtk_label_set(GTK_LABEL(GLOBALS->max_or_marker_label_currenttime_c_1), (!GLOBALS->use_toolbutton_interface) ? maxtime_label_text : maxtime_label_text_hpos); update_maxtime(GLOBALS->max_time); } else { gtk_label_set(GTK_LABEL(GLOBALS->max_or_marker_label_currenttime_c_1), (!GLOBALS->use_toolbutton_interface) ? marker_label_text : marker_label_text_hpos); update_markertime(GLOBALS->tims.marker); } } /* handles floating point values with units */ static TimeType unformat_time_complex(const char *s, char dim) { int i, delta, rc; unsigned char ch = dim; double d = 0.0; const char *offs = NULL, *doffs = NULL; rc = sscanf(s, "%lf %cs", &d, &ch); if(rc == 2) { ch = tolower(ch); if(ch=='s') ch = ' '; offs=strchr(time_prefix, ch); if(offs) { doffs=strchr(time_prefix, (int)dim); if(!doffs) doffs = offs; /* should *never* happen */ delta= (doffs-time_prefix) - (offs-time_prefix); if(delta<0) { for(i=delta;i<0;i++) { d=d/1000; } } else { for(i=0;iatoi_cont_ptr)) { while((ch=*(pnt++))) { if((ch==' ')||(ch=='\t')) continue; ich=tolower((int)ch); if(ich=='s') ich=' '; /* as in plain vanilla seconds */ offs=strchr(time_prefix, ich); break; } } if(!offs) return(rval); if((dim=='S')||(dim=='s')) { doffs = time_prefix; } else { doffs=strchr(time_prefix, (int)dim); if(!doffs) return(rval); /* should *never* happen */ } delta= (doffs-time_prefix) - (offs-time_prefix); if(delta<0) { for(i=delta;i<0;i++) { rval=rval/1000; } } else { for(i=0;i0; i--) { if(val%1000) break; val=val/1000; } if(i) { sprintf(buf, TTFormat" %cs", val, time_prefix[i]); } else { sprintf(buf, TTFormat" sec", val); } } void reformat_time(char *buf, TimeType val, char dim) { char *pnt; int i, offset, offsetfix; if(val < LLDescriptor(0)) { val = -val; buf[0] = '-'; buf++; } pnt=strchr(time_prefix, (int)dim); if(pnt) { offset=pnt-time_prefix; } else offset=0; for(i=offset; i>0; i--) { if(val%1000) break; val=val/1000; } if(GLOBALS->scale_to_time_dimension) { if(GLOBALS->scale_to_time_dimension == 's') { pnt = time_prefix; } else { pnt=strchr(time_prefix, (int)GLOBALS->scale_to_time_dimension); } if(pnt) { offsetfix = pnt-time_prefix; if(offsetfix != i) { int j; int deltaexp = (offsetfix - i); gdouble gval = (gdouble)val; gdouble mypow = 1.0; if(deltaexp > 0) { for(j=0;jdeltaexp;j--) { mypow /= 1000.0; } } gval *= mypow; if(GLOBALS->scale_to_time_dimension == 's') { sprintf(buf, "%.9g sec", gval); } else { sprintf(buf, "%.9g %cs", gval, GLOBALS->scale_to_time_dimension); } return; } } } if((i)&&(time_prefix)) /* scan-build on time_prefix, should not be necessary however */ { sprintf(buf, TTFormat" %cs", val, time_prefix[i]); } else { sprintf(buf, TTFormat" sec", val); } } void reformat_time_as_frequency(char *buf, TimeType val, char dim) { char *pnt; int offset; double k; static const double negpow[] = { 1.0, 1.0e-3, 1.0e-6, 1.0e-9, 1.0e-12, 1.0e-15, 1.0e-18, 1.0e-21 }; pnt=strchr(time_prefix, (int)dim); if(pnt) { offset=pnt-time_prefix; } else offset=0; if(val) { k = 1 / ((double)val * negpow[offset]); sprintf(buf, "%e Hz", k); } else { strcpy(buf, "-- Hz"); } } void reformat_time_blackout(char *buf, TimeType val, char dim) { char *pnt; int i, offset, offsetfix; struct blackout_region_t *bt = GLOBALS->blackout_regions; char blackout = ' '; while(bt) { if((val>=bt->bstart)&&(valbend)) { blackout = '*'; break; } bt=bt->next; } pnt=strchr(time_prefix, (int)dim); if(pnt) { offset=pnt-time_prefix; } else offset=0; for(i=offset; i>0; i--) { if(val%1000) break; val=val/1000; } if(GLOBALS->scale_to_time_dimension) { if(GLOBALS->scale_to_time_dimension == 's') { pnt = time_prefix; } else { pnt=strchr(time_prefix, (int)GLOBALS->scale_to_time_dimension); } if(pnt) { offsetfix = pnt-time_prefix; if(offsetfix != i) { int j; int deltaexp = (offsetfix - i); gdouble gval = (gdouble)val; gdouble mypow = 1.0; if(deltaexp > 0) { for(j=0;jdeltaexp;j--) { mypow /= 1000.0; } } gval *= mypow; if(GLOBALS->scale_to_time_dimension == 's') { sprintf(buf, "%.9g%csec", gval, blackout); } else { sprintf(buf, "%.9g%c%cs", gval, blackout, GLOBALS->scale_to_time_dimension); } return; } } } if((i)&&(time_prefix)) /* scan-build on time_prefix, should not be necessary however */ { sprintf(buf, TTFormat"%c%cs", val, blackout, time_prefix[i]); } else { sprintf(buf, TTFormat"%csec", val, blackout); } } void update_markertime(TimeType val) { #if !defined _MSC_VER if(GLOBALS->anno_ctx) { if(val >= 0) { GLOBALS->anno_ctx->marker_set = 0; /* avoid race on update */ if(!GLOBALS->ae2_time_xlate) { GLOBALS->anno_ctx->marker = val / GLOBALS->time_scale; } else { int rvs_xlate = bsearch_aetinfo_timechain(val); GLOBALS->anno_ctx->marker = ((TimeType)rvs_xlate) + GLOBALS->ae2_start_cyc; } reformat_time(GLOBALS->anno_ctx->time_string, val + GLOBALS->global_time_offset, GLOBALS->time_dimension); GLOBALS->anno_ctx->marker_set = 1; } else { GLOBALS->anno_ctx->marker_set = 0; } } #endif if(!GLOBALS->use_maxtime_display) { if(val>=0) { if(GLOBALS->tims.baseline>=0) { val-=GLOBALS->tims.baseline; /* do delta instead */ *GLOBALS->maxtext_currenttime_c_1='B'; if(val>=0) { *(GLOBALS->maxtext_currenttime_c_1+1)='+'; if(GLOBALS->use_frequency_delta) { reformat_time_as_frequency(GLOBALS->maxtext_currenttime_c_1+2, val, GLOBALS->time_dimension); } else { reformat_time(GLOBALS->maxtext_currenttime_c_1+2, val, GLOBALS->time_dimension); } } else { if(GLOBALS->use_frequency_delta) { reformat_time_as_frequency(GLOBALS->maxtext_currenttime_c_1+1, val, GLOBALS->time_dimension); } else { reformat_time(GLOBALS->maxtext_currenttime_c_1+1, val, GLOBALS->time_dimension); } } } else if(GLOBALS->tims.lmbcache>=0) { val-=GLOBALS->tims.lmbcache; /* do delta instead */ if(GLOBALS->use_frequency_delta) { reformat_time_as_frequency(GLOBALS->maxtext_currenttime_c_1, val, GLOBALS->time_dimension); } else { if(val>=0) { *GLOBALS->maxtext_currenttime_c_1='+'; reformat_time(GLOBALS->maxtext_currenttime_c_1+1, val, GLOBALS->time_dimension); } else { reformat_time(GLOBALS->maxtext_currenttime_c_1, val, GLOBALS->time_dimension); } } } else { reformat_time(GLOBALS->maxtext_currenttime_c_1, val + GLOBALS->global_time_offset, GLOBALS->time_dimension); } } else { sprintf(GLOBALS->maxtext_currenttime_c_1, "--"); } gtk_label_set(GTK_LABEL(GLOBALS->maxtimewid_currenttime_c_1), GLOBALS->maxtext_currenttime_c_1); } if(GLOBALS->named_marker_lock_idx>-1) { if(GLOBALS->tims.marker >= 0) { int ent_idx = GLOBALS->named_marker_lock_idx; if(GLOBALS->named_markers[ent_idx] != GLOBALS->tims.marker) { GLOBALS->named_markers[ent_idx] = GLOBALS->tims.marker; wavearea_configure_event(GLOBALS->wavearea, NULL); } } } } void update_basetime(TimeType val) { if(val>=0) { gtk_label_set(GTK_LABEL(GLOBALS->base_or_curtime_label_currenttime_c_1), (!GLOBALS->use_toolbutton_interface) ? "Base Marker" : "Base"); reformat_time(GLOBALS->curtext_currenttime_c_1, val + GLOBALS->global_time_offset, GLOBALS->time_dimension); } else { gtk_label_set(GTK_LABEL(GLOBALS->base_or_curtime_label_currenttime_c_1), (!GLOBALS->use_toolbutton_interface) ? "Current Time" : "Cursor"); reformat_time_blackout(GLOBALS->curtext_currenttime_c_1, GLOBALS->cached_currenttimeval_currenttime_c_1 + GLOBALS->global_time_offset, GLOBALS->time_dimension); } gtk_label_set(GTK_LABEL(GLOBALS->curtimewid_currenttime_c_1), GLOBALS->curtext_currenttime_c_1); } void update_maxtime(TimeType val) { GLOBALS->max_time=val; if(GLOBALS->use_maxtime_display) { reformat_time(GLOBALS->maxtext_currenttime_c_1, val + GLOBALS->global_time_offset, GLOBALS->time_dimension); gtk_label_set(GTK_LABEL(GLOBALS->maxtimewid_currenttime_c_1), GLOBALS->maxtext_currenttime_c_1); } } void update_currenttime(TimeType val) { GLOBALS->cached_currenttimeval_currenttime_c_1 = val; if(GLOBALS->tims.baseline<0) { GLOBALS->currenttime=val; reformat_time_blackout(GLOBALS->curtext_currenttime_c_1, val + GLOBALS->global_time_offset, GLOBALS->time_dimension); gtk_label_set(GTK_LABEL(GLOBALS->curtimewid_currenttime_c_1), GLOBALS->curtext_currenttime_c_1); } } /* Create an entry box */ GtkWidget * create_time_box(void) { GtkWidget *mainbox; GtkWidget *eventbox; GLOBALS->max_or_marker_label_currenttime_c_1=(GLOBALS->use_maxtime_display) ? gtk_label_new((!GLOBALS->use_toolbutton_interface) ? maxtime_label_text : maxtime_label_text_hpos) : gtk_label_new((!GLOBALS->use_toolbutton_interface) ? marker_label_text : marker_label_text_hpos); GLOBALS->maxtext_currenttime_c_1=(char *)malloc_2(40); if(GLOBALS->use_maxtime_display) { reformat_time(GLOBALS->maxtext_currenttime_c_1, GLOBALS->max_time, GLOBALS->time_dimension); } else { sprintf(GLOBALS->maxtext_currenttime_c_1,"--"); } GLOBALS->maxtimewid_currenttime_c_1=gtk_label_new(GLOBALS->maxtext_currenttime_c_1); GLOBALS->curtext_currenttime_c_1=(char *)malloc_2(40); if(GLOBALS->tims.baseline<0) { GLOBALS->base_or_curtime_label_currenttime_c_1=gtk_label_new((!GLOBALS->use_toolbutton_interface) ? "Current Time" : "Cursor"); reformat_time(GLOBALS->curtext_currenttime_c_1, (GLOBALS->currenttime=GLOBALS->min_time), GLOBALS->time_dimension); GLOBALS->curtimewid_currenttime_c_1=gtk_label_new(GLOBALS->curtext_currenttime_c_1); } else { GLOBALS->base_or_curtime_label_currenttime_c_1=gtk_label_new((!GLOBALS->use_toolbutton_interface) ? "Base Marker" : "Base"); reformat_time(GLOBALS->curtext_currenttime_c_1, GLOBALS->tims.baseline, GLOBALS->time_dimension); GLOBALS->curtimewid_currenttime_c_1=gtk_label_new(GLOBALS->curtext_currenttime_c_1); } if(!GLOBALS->use_toolbutton_interface) { mainbox=gtk_vbox_new(FALSE, 0); } else { mainbox=gtk_hbox_new(FALSE, 0); } gtk_widget_show(mainbox); eventbox=gtk_event_box_new(); gtk_container_add(GTK_CONTAINER(eventbox), mainbox); if(!GLOBALS->use_toolbutton_interface) { gtk_box_pack_start(GTK_BOX(mainbox), GLOBALS->max_or_marker_label_currenttime_c_1, TRUE, FALSE, 0); gtk_widget_show(GLOBALS->max_or_marker_label_currenttime_c_1); gtk_box_pack_start(GTK_BOX(mainbox), GLOBALS->maxtimewid_currenttime_c_1, TRUE, FALSE, 0); gtk_widget_show(GLOBALS->maxtimewid_currenttime_c_1); gtk_box_pack_start(GTK_BOX(mainbox), GLOBALS->base_or_curtime_label_currenttime_c_1, TRUE, FALSE, 0); gtk_widget_show(GLOBALS->base_or_curtime_label_currenttime_c_1); gtk_box_pack_start(GTK_BOX(mainbox), GLOBALS->curtimewid_currenttime_c_1, TRUE, FALSE, 0); gtk_widget_show(GLOBALS->curtimewid_currenttime_c_1); } else { GtkWidget *dummy; gtk_box_pack_start(GTK_BOX(mainbox), GLOBALS->max_or_marker_label_currenttime_c_1, TRUE, FALSE, 0); gtk_widget_show(GLOBALS->max_or_marker_label_currenttime_c_1); dummy=gtk_label_new(": "); gtk_widget_show (dummy); gtk_box_pack_start(GTK_BOX(mainbox), dummy, TRUE, FALSE, 0); gtk_box_pack_start(GTK_BOX(mainbox), GLOBALS->maxtimewid_currenttime_c_1, TRUE, FALSE, 0); gtk_widget_show(GLOBALS->maxtimewid_currenttime_c_1); dummy=gtk_label_new(" | "); gtk_widget_show (dummy); gtk_box_pack_start(GTK_BOX(mainbox), dummy, TRUE, FALSE, 0); gtk_box_pack_start(GTK_BOX(mainbox), GLOBALS->base_or_curtime_label_currenttime_c_1, TRUE, FALSE, 0); gtk_widget_show(GLOBALS->base_or_curtime_label_currenttime_c_1); dummy=gtk_label_new(": "); gtk_widget_show (dummy); gtk_box_pack_start(GTK_BOX(mainbox), dummy, TRUE, FALSE, 0); gtk_box_pack_start(GTK_BOX(mainbox), GLOBALS->curtimewid_currenttime_c_1, TRUE, FALSE, 0); gtk_widget_show(GLOBALS->curtimewid_currenttime_c_1); } return(eventbox); } TimeType time_trunc(TimeType t) { if(!GLOBALS->use_full_precision) if(GLOBALS->time_trunc_val_currenttime_c_1!=1) { t=t/GLOBALS->time_trunc_val_currenttime_c_1; t=t*GLOBALS->time_trunc_val_currenttime_c_1; if(ttims.first) t=GLOBALS->tims.first; } return(t); } void time_trunc_set(void) { gdouble gcompar=1e15; TimeType compar=LLDescriptor(1000000000000000); for(;compar!=1;compar=compar/10,gcompar=gcompar/((gdouble)10.0)) { if(GLOBALS->nspx>=gcompar) { GLOBALS->time_trunc_val_currenttime_c_1=compar; return; } } GLOBALS->time_trunc_val_currenttime_c_1=1; } /* * called by lxt/lxt2/vzt reader inits */ void exponent_to_time_scale(signed char scale) { switch(scale) { case 2: GLOBALS->time_scale = LLDescriptor(100); GLOBALS->time_dimension = 's'; break; case 1: GLOBALS->time_scale = LLDescriptor(10); case 0: GLOBALS->time_dimension = 's'; break; case -1: GLOBALS->time_scale = LLDescriptor(100); GLOBALS->time_dimension = 'm'; break; case -2: GLOBALS->time_scale = LLDescriptor(10); case -3: GLOBALS->time_dimension = 'm'; break; case -4: GLOBALS->time_scale = LLDescriptor(100); GLOBALS->time_dimension = 'u'; break; case -5: GLOBALS->time_scale = LLDescriptor(10); case -6: GLOBALS->time_dimension = 'u'; break; case -10: GLOBALS->time_scale = LLDescriptor(100); GLOBALS->time_dimension = 'p'; break; case -11: GLOBALS->time_scale = LLDescriptor(10); case -12: GLOBALS->time_dimension = 'p'; break; case -13: GLOBALS->time_scale = LLDescriptor(100); GLOBALS->time_dimension = 'f'; break; case -14: GLOBALS->time_scale = LLDescriptor(10); case -15: GLOBALS->time_dimension = 'f'; break; case -16: GLOBALS->time_scale = LLDescriptor(100); GLOBALS->time_dimension = 'a'; break; case -17: GLOBALS->time_scale = LLDescriptor(10); case -18: GLOBALS->time_dimension = 'a'; break; case -19: GLOBALS->time_scale = LLDescriptor(100); GLOBALS->time_dimension = 'z'; break; case -20: GLOBALS->time_scale = LLDescriptor(10); case -21: GLOBALS->time_dimension = 'z'; break; case -7: GLOBALS->time_scale = LLDescriptor(100); GLOBALS->time_dimension = 'n'; break; case -8: GLOBALS->time_scale = LLDescriptor(10); case -9: default: GLOBALS->time_dimension = 'n'; break; } } gtkwave-3.3.66/src/tcl_np.h0000664000076400007640000001046711637543354015041 0ustar bybellbybell/* * Copyright (c) 2003-2005 Active State Corporation. * See the file LICENSE.TXT for information on usage and redistribution * and for a DISCLAIMER OF ALL WARRANTIES. */ #ifndef WAVE_TCLNP_H #define WAVE_TCLNP_H #include #ifdef HAVE_LIBTCL #include /* ==== Np... Begin */ # define NpPlatformMsg(s1, s2) printf("TCLINIT | Platform: %s\n\t%s\n", s1, s2) # define NpLog(x,y) printf("TCLINIT | " x, y) # define NpLog3(x,y,z) printf("TCLINIT | " x, y, z) # define NpPanic(x) fprintf(stderr, "TCLINIT | "x) #include #if (TCL_MAJOR_VERSION < 8) \ || ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION < 4)) #error "Gtkwave requires Tcl 8.4+" #endif #ifndef TCL_TSD_INIT #define TCL_TSD_INIT(keyPtr) (ThreadSpecificData *)Tcl_GetThreadData((keyPtr), sizeof(ThreadSpecificData)) #endif #define TCL_OBJ_CMD(cmd) int (cmd)(ClientData clientData, \ Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) #ifdef HAVE_STDLIB_H #include /* for getenv */ #endif #ifdef WIN32 # include # define dlclose(path) ((void *) FreeLibrary((HMODULE) path)) # define DLSYM(handle, symbol, type, proc) \ (proc = (type) GetProcAddress((HINSTANCE) handle, symbol)) # define snprintf _snprintf # define HAVE_UNISTD_H 1 # ifndef F_OK # define F_OK 0 # endif # ifndef SHLIB_SUFFIX # define SHLIB_SUFFIX ".dll" # endif #elif (defined(__MACH__) && defined(__APPLE__)) /* Mac OS X */ # include /* # include */ /* Commented out: ajb 25sep11 */ # if HAVE_UNISTD_H # include # include # endif # ifndef SHLIB_SUFFIX # define SHLIB_SUFFIX ".dylib" # endif # include # define HMODULE void * # define DLSYM(handle, symbol, type, proc) \ (proc = (type) dlsym(handle, symbol)) # define HIBYTE(i) (i >> 8) # define LOBYTE(i) (i & 0xff) #else /* UNIX */ #ifdef __CYGWIN__ # define SHLIB_SUFFIX ".dll" #endif # include # define HIBYTE(i) (i >> 8) # define LOBYTE(i) (i & 0xff) # if HAVE_UNISTD_H # include # include # endif # if (!defined(HAVE_DLADDR) && defined(__hpux)) /* HPUX requires shl_* routines */ # include # define HMODULE shl_t # define dlopen(libname, flags) shl_load(libname, \ BIND_DEFERRED|BIND_VERBOSE|DYNAMIC_PATH, 0L) # define dlclose(path) shl_unload((shl_t) path) # define DLSYM(handle, symbol, type, proc) \ if (shl_findsym(&handle, symbol, (short) TYPE_PROCEDURE, \ (void *) &proc) != 0) { proc = NULL; } # ifndef SHLIB_SUFFIX # define SHLIB_SUFFIX ".sl" # endif # else # include # define HMODULE void * # define DLSYM(handle, symbol, type, proc) \ (proc = (type) dlsym(handle, symbol)) # ifndef SHLIB_SUFFIX # define SHLIB_SUFFIX ".so" # endif /* * FIX: For other non-dl systems, we need alternatives here */ # endif /* * Shared functions: */ #endif /* PLATFORM DEFS */ #ifndef MAX_PATH #define MAX_PATH 1024 #endif /* * Tcl Plugin version identifiers * (the 3 strings are computed from the 4 internal numbers) */ #define NPTCL_VERSION PACKAGE_VERSION #define NPTCL_PATCH_LEVEL PACKAGE_PATCHLEVEL #define NPTCL_INTERNAL_VERSION PACKAGE_PATCHLEVEL #define NPTCL_MAJOR_VERSION 3 #define NPTCL_MINOR_VERSION 0 #define NPTCL_RELEASE_LEVEL 0 #define NPTCL_RELEASE_SERIAL 1 #ifdef BUILD_nptcl #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLEXPORT #endif /* BUILD_nptcl */ /* * Netscape APIs (needs system specific headers) * AIX predefines certain types that we must redefine. */ #ifdef _AIX #define _PR_AIX_HAVE_BSD_INT_TYPES 1 #endif /* #include "npapi.h" */ /* * The following constant is used to tell Netscape that the plugin will * accept whatever amount of input is available on a stream. */ #define MAXINPUTSIZE 0X0FFFFFFF /* * Define the names of token tables used in the plugin: */ #define NPTCL_INSTANCE "npInstance" #define NPTCL_STREAM "npStream" #ifndef NP_LOG #define NP_LOG ((char *) NULL) #endif /* * Procedures shared between various modules in the plugin: */ /* * npinterp.c */ extern Tcl_Interp *NpCreateMainInterp(char *me, int install_tk); extern Tcl_Interp *NpGetMainInterp(void); extern void NpDestroyMainInterp(void); extern Tcl_Interp *NpGetInstanceInterp(int install_tk); extern void NpDestroyInstanceInterp(Tcl_Interp *interp); /* ==== Np... End */ #endif #endif gtkwave-3.3.66/src/search.c0000664000076400007640000011022612523241774015010 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2014. * * 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. */ /* AIX may need this for alloca to work */ #if defined _AIX #pragma alloca #endif #include "globals.h" #include #include #include "gtk12compat.h" #include "analyzer.h" #include "symbol.h" #include "vcd.h" #include "lx2.h" #include "ghw.h" #include "debug.h" #include "busy.h" #include "hierpack.h" static gint clist_sigcmp (GtkCList *clist, gconstpointer ptr1, gconstpointer ptr2) { char *text1 = NULL; char *text2 = NULL; int rc; GtkCListRow *row1 = (GtkCListRow *) ptr1; GtkCListRow *row2 = (GtkCListRow *) ptr2; switch (row1->cell[clist->sort_column].type) { case GTK_CELL_TEXT: text1 = GTK_CELL_TEXT (row1->cell[clist->sort_column])->text; break; case GTK_CELL_PIXTEXT: text1 = GTK_CELL_PIXTEXT (row1->cell[clist->sort_column])->text; break; default: break; } switch (row2->cell[clist->sort_column].type) { case GTK_CELL_TEXT: text2 = GTK_CELL_TEXT (row2->cell[clist->sort_column])->text; break; case GTK_CELL_PIXTEXT: text2 = GTK_CELL_PIXTEXT (row2->cell[clist->sort_column])->text; break; default: break; } if (!text2) return (text1 != NULL); if (!text1) return -1; rc = sigcmp(text1, text2); return (rc); } int searchbox_is_active(void) { return(GLOBALS->is_active_search_c_4); } static void enter_callback_e(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; G_CONST_RETURN gchar *entry_text; int len; char *vname=""; entry_text = gtk_entry_get_text(GTK_ENTRY(GLOBALS->entry_a_search_c_1)); entry_text = entry_text ? entry_text : ""; DEBUG(printf("Entry contents: %s\n", entry_text)); if(!(len=strlen(entry_text))) strcpy((GLOBALS->entrybox_text_local_search_c_2=(char *)malloc_2(strlen(vname)+1)),vname); /* make consistent with other widgets rather than producing NULL */ else strcpy((GLOBALS->entrybox_text_local_search_c_2=(char *)malloc_2(len+1)),entry_text); wave_gtk_grab_remove(GLOBALS->window1_search_c_2); gtk_widget_destroy(GLOBALS->window1_search_c_2); GLOBALS->window1_search_c_2 = NULL; GLOBALS->cleanup_e_search_c_2(); } static void destroy_callback_e(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; DEBUG(printf("Entry Cancel\n")); GLOBALS->entrybox_text_local_search_c_2=NULL; wave_gtk_grab_remove(GLOBALS->window1_search_c_2); gtk_widget_destroy(GLOBALS->window1_search_c_2); GLOBALS->window1_search_c_2 = NULL; } static void entrybox_local(char *title, int width, char *default_text, int maxch, GtkSignalFunc func) { GtkWidget *vbox, *hbox; GtkWidget *button1, *button2; GLOBALS->cleanup_e_search_c_2=func; /* fix problem where ungrab doesn't occur if button pressed + simultaneous accelerator key occurs */ if(GLOBALS->in_button_press_wavewindow_c_1) { gdk_pointer_ungrab(GDK_CURRENT_TIME); } /* create a new modal window */ GLOBALS->window1_search_c_2 = gtk_window_new(GLOBALS->disable_window_manager ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL); install_focus_cb(GLOBALS->window1_search_c_2, ((char *)&GLOBALS->window1_search_c_2) - ((char *)GLOBALS)); gtk_widget_set_usize( GTK_WIDGET (GLOBALS->window1_search_c_2), width, 60); gtk_window_set_title(GTK_WINDOW (GLOBALS->window1_search_c_2), title); gtkwave_signal_connect(GTK_OBJECT (GLOBALS->window1_search_c_2), "delete_event",(GtkSignalFunc) destroy_callback_e, NULL); vbox = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (GLOBALS->window1_search_c_2), vbox); gtk_widget_show (vbox); GLOBALS->entry_a_search_c_1 = gtk_entry_new_with_max_length (maxch); gtkwave_signal_connect(GTK_OBJECT(GLOBALS->entry_a_search_c_1), "activate",GTK_SIGNAL_FUNC(enter_callback_e),GLOBALS->entry_a_search_c_1); gtk_entry_set_text (GTK_ENTRY (GLOBALS->entry_a_search_c_1), default_text); gtk_entry_select_region (GTK_ENTRY (GLOBALS->entry_a_search_c_1),0, GTK_ENTRY(GLOBALS->entry_a_search_c_1)->text_length); gtk_box_pack_start (GTK_BOX (vbox), GLOBALS->entry_a_search_c_1, TRUE, TRUE, 0); gtk_widget_show (GLOBALS->entry_a_search_c_1); hbox = gtk_hbox_new (FALSE, 1); gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0); gtk_widget_show (hbox); button1 = gtk_button_new_with_label ("OK"); gtk_widget_set_usize(button1, 100, -1); gtkwave_signal_connect(GTK_OBJECT (button1), "clicked", GTK_SIGNAL_FUNC(enter_callback_e), NULL); gtk_widget_show (button1); gtk_container_add (GTK_CONTAINER (hbox), button1); GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT); gtkwave_signal_connect_object (GTK_OBJECT (button1), "realize", (GtkSignalFunc) gtk_widget_grab_default, GTK_OBJECT (button1)); button2 = gtk_button_new_with_label ("Cancel"); gtk_widget_set_usize(button2, 100, -1); gtkwave_signal_connect(GTK_OBJECT (button2), "clicked", GTK_SIGNAL_FUNC(destroy_callback_e), NULL); GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT); gtk_widget_show (button2); gtk_container_add (GTK_CONTAINER (hbox), button2); gtk_widget_show(GLOBALS->window1_search_c_2); wave_gtk_grab_add(GLOBALS->window1_search_c_2); } /***************************************************************************/ static char *regex_type[]={"\\(\\[.*\\]\\)*$", "\\>.\\([0-9]\\)*$", "\\(\\[.*\\]\\)*$", "\\>.\\([0-9]\\)*$", ""}; static char *regex_name[]={"WRange", "WStrand", "Range", "Strand", "None"}; static void regex_clicked(GtkWidget *widget, gpointer which) { (void)widget; int i; for(i=0;i<5;i++) GLOBALS->regex_mutex_search_c_1[i]=0; GLOBALS->regex_which_search_c_1=(int)((intptr_t)which); GLOBALS->regex_mutex_search_c_1[GLOBALS->regex_which_search_c_1] = 1; /* mark our choice */ DEBUG(printf("picked: %s\n", regex_name[GLOBALS->regex_which_search_c_1])); } /***************************************************************************/ /* call cleanup() on ok/insert functions */ static void bundle_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; if(GLOBALS->entrybox_text_local_search_c_2) { char *efix; efix=GLOBALS->entrybox_text_local_search_c_2; while(*efix) { if(*efix==' ') { *efix='_'; } efix++; } DEBUG(printf("Bundle name is: %s\n",GLOBALS->entrybox_text_local_search_c_2)); add_vector_selected(GLOBALS->entrybox_text_local_search_c_2, GLOBALS->selected_rows_search_c_2, GLOBALS->bundle_direction_search_c_2); free_2(GLOBALS->entrybox_text_local_search_c_2); } MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } static void bundle_callback_generic(void) { DEBUG(printf("Selected_rows: %d\n",GLOBALS->selected_rows_search_c_2)); if(GLOBALS->selected_rows_search_c_2>0) { entrybox_local("Enter Bundle Name",300,"",128,GTK_SIGNAL_FUNC(bundle_cleanup)); } } static void bundle_callback_up(GtkWidget *widget, gpointer data) { (void)widget; (void)data; GLOBALS->bundle_direction_search_c_2=0; bundle_callback_generic(); } static void bundle_callback_down(GtkWidget *widget, gpointer data) { (void)widget; (void)data; GLOBALS->bundle_direction_search_c_2=1; bundle_callback_generic(); } static void insert_callback(GtkWidget *widget, GtkWidget *nothing) { (void)nothing; search_insert_callback(widget, 0); /* native to search */ } void search_insert_callback(GtkWidget *widget, char is_prepend) { Traces tcache; struct symchain *symc, *symc_current; int i; gfloat interval; if(GLOBALS->is_insert_running_search_c_1) return; GLOBALS->is_insert_running_search_c_1 = ~0; wave_gtk_grab_add(widget); set_window_busy(widget); symc=NULL; memcpy(&tcache,&GLOBALS->traces,sizeof(Traces)); GLOBALS->traces.total=0; GLOBALS->traces.first=GLOBALS->traces.last=NULL; GTK_ADJUSTMENT(GLOBALS->pdata->adj)->upper = (gfloat)((GLOBALS->num_rows_search_c_2>1)?GLOBALS->num_rows_search_c_2-1:1); interval = (gfloat)(GLOBALS->num_rows_search_c_2/100.0); /* LX2 */ if(GLOBALS->is_lx2) { int pre_import=0; for(i=0;inum_rows_search_c_2;i++) { struct symbol *s, *t; s=(struct symbol *)gtk_clist_get_row_data(GTK_CLIST(GLOBALS->clist_search_c_3), i); if(get_s_selected(s)) { if((!s->vec_root)||(!GLOBALS->autocoalesce)) { if(s->n->mv.mvlfac) { lx2_set_fac_process_mask(s->n); pre_import++; } } else { t=s->vec_root; while(t) { if(t->n->mv.mvlfac) { lx2_set_fac_process_mask(t->n); pre_import++; } t=t->vec_chain; } } } } if(pre_import) { lx2_import_masked(); } } /* LX2 */ for(i=0;inum_rows_search_c_2;i++) { int len; struct symbol *s, *t; s=(struct symbol *)gtk_clist_get_row_data(GTK_CLIST(GLOBALS->clist_search_c_3), i); if(get_s_selected(s)) { GLOBALS->pdata->value = i; if(((int)(GLOBALS->pdata->value/interval))!=((int)(GLOBALS->pdata->oldvalue/interval))) { gtk_progress_set_value (GTK_PROGRESS (GLOBALS->pdata->pbar), i); gtkwave_main_iteration(); } GLOBALS->pdata->oldvalue = i; if((!s->vec_root)||(!GLOBALS->autocoalesce)) { AddNodeUnroll(s->n, NULL); } else { len=0; t=s->vec_root; set_s_selected(t, 1); /* move selected to head */ while(t) { if(get_s_selected(t)) { if(len) set_s_selected(t, 0); symc_current=(struct symchain *)calloc_2(1,sizeof(struct symchain)); symc_current->next=symc; symc_current->symbol=t; symc=symc_current; } len++; t=t->vec_chain; } if(len)add_vector_chain(s->vec_root, len); } } } while(symc) { set_s_selected(symc->symbol, 1); symc_current=symc; symc=symc->next; free_2(symc_current); } GLOBALS->traces.buffercount=GLOBALS->traces.total; GLOBALS->traces.buffer=GLOBALS->traces.first; GLOBALS->traces.bufferlast=GLOBALS->traces.last; GLOBALS->traces.first=tcache.first; GLOBALS->traces.last=tcache.last; GLOBALS->traces.total=tcache.total; if(is_prepend) { PrependBuffer(); } else { PasteBuffer(); } GLOBALS->traces.buffercount=tcache.buffercount; GLOBALS->traces.buffer=tcache.buffer; GLOBALS->traces.bufferlast=tcache.bufferlast; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); gtk_progress_set_value (GTK_PROGRESS (GLOBALS->pdata->pbar), 0.0); GLOBALS->pdata->oldvalue = -1.0; set_window_idle(widget); wave_gtk_grab_remove(widget); GLOBALS->is_insert_running_search_c_1=0; } static void replace_callback(GtkWidget *widget, GtkWidget *nothing) { (void)nothing; Traces tcache; int i; Trptr tfirst, tlast; struct symchain *symc, *symc_current; gfloat interval; if(GLOBALS->is_replace_running_search_c_1) return; GLOBALS->is_replace_running_search_c_1 = ~0; wave_gtk_grab_add(widget); set_window_busy(widget); tfirst=NULL; tlast=NULL; symc=NULL; memcpy(&tcache,&GLOBALS->traces,sizeof(Traces)); GLOBALS->traces.total=0; GLOBALS->traces.first=GLOBALS->traces.last=NULL; GTK_ADJUSTMENT(GLOBALS->pdata->adj)->upper = (gfloat)((GLOBALS->num_rows_search_c_2>1)?GLOBALS->num_rows_search_c_2-1:1); interval = (gfloat)(GLOBALS->num_rows_search_c_2/100.0); GLOBALS->pdata->oldvalue = -1.0; /* LX2 */ if(GLOBALS->is_lx2) { int pre_import=0; for(i=0;inum_rows_search_c_2;i++) { struct symbol *s, *t; s=(struct symbol *)gtk_clist_get_row_data(GTK_CLIST(GLOBALS->clist_search_c_3), i); if(get_s_selected(s)) { if((!s->vec_root)||(!GLOBALS->autocoalesce)) { if(s->n->mv.mvlfac) { lx2_set_fac_process_mask(s->n); pre_import++; } } else { t=s->vec_root; while(t) { if(t->n->mv.mvlfac) { lx2_set_fac_process_mask(t->n); pre_import++; } t=t->vec_chain; } } } } if(pre_import) { lx2_import_masked(); } } /* LX2 */ for(i=0;inum_rows_search_c_2;i++) { int len; struct symbol *s, *t; s=(struct symbol *)gtk_clist_get_row_data(GTK_CLIST(GLOBALS->clist_search_c_3), i); if(get_s_selected(s)) { GLOBALS->pdata->value = i; if(((int)(GLOBALS->pdata->value/interval))!=((int)(GLOBALS->pdata->oldvalue/interval))) { gtk_progress_set_value (GTK_PROGRESS (GLOBALS->pdata->pbar), i); gtkwave_main_iteration(); } GLOBALS->pdata->oldvalue = i; if((!s->vec_root)||(!GLOBALS->autocoalesce)) { AddNodeUnroll(s->n, NULL); } else { len=0; t=s->vec_root; while(t) { if(get_s_selected(t)) { if(len) set_s_selected(t, 0); symc_current=(struct symchain *)calloc_2(1,sizeof(struct symchain)); symc_current->next=symc; symc_current->symbol=t; symc=symc_current; } len++; t=t->vec_chain; } if(len)add_vector_chain(s->vec_root, len); } } } while(symc) { set_s_selected(symc->symbol, 1); symc_current=symc; symc=symc->next; free_2(symc_current); } tfirst=GLOBALS->traces.first; tlast=GLOBALS->traces.last; /* cache for highlighting */ GLOBALS->traces.buffercount=GLOBALS->traces.total; GLOBALS->traces.buffer=GLOBALS->traces.first; GLOBALS->traces.bufferlast=GLOBALS->traces.last; GLOBALS->traces.first=tcache.first; GLOBALS->traces.last=tcache.last; GLOBALS->traces.total=tcache.total; { Trptr t = GLOBALS->traces.first; Trptr *tp = NULL; int numhigh = 0; int it; while(t) { if(t->flags & TR_HIGHLIGHT) { numhigh++; } t = t->t_next; } if(numhigh) { tp = calloc_2(numhigh, sizeof(Trptr)); t = GLOBALS->traces.first; it = 0; while(t) { if(t->flags & TR_HIGHLIGHT) { tp[it++] = t; } t = t->t_next; } } PasteBuffer(); GLOBALS->traces.buffercount=tcache.buffercount; GLOBALS->traces.buffer=tcache.buffer; GLOBALS->traces.bufferlast=tcache.bufferlast; for(it=0;itflags |= TR_HIGHLIGHT; } t = tfirst; while(t) { t->flags &= ~TR_HIGHLIGHT; if(t==tlast) break; t=t->t_next; } CutBuffer(); while(tfirst) { tfirst->flags |= TR_HIGHLIGHT; if(tfirst==tlast) break; tfirst=tfirst->t_next; } if(tp) { free_2(tp); } } MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); gtk_progress_set_value (GTK_PROGRESS (GLOBALS->pdata->pbar), 0.0); GLOBALS->pdata->oldvalue = -1.0; set_window_idle(widget); wave_gtk_grab_remove(widget); GLOBALS->is_replace_running_search_c_1=0; } static void ok_callback(GtkWidget *widget, GtkWidget *nothing) { (void)nothing; int i; struct symchain *symc, *symc_current; gfloat interval; if(GLOBALS->is_append_running_search_c_1) return; GLOBALS->is_append_running_search_c_1 = ~0; wave_gtk_grab_add(widget); set_window_busy(widget); symc=NULL; GTK_ADJUSTMENT(GLOBALS->pdata->adj)->upper = (gfloat)((GLOBALS->num_rows_search_c_2>1)?GLOBALS->num_rows_search_c_2-1:1); interval = (gfloat)(GLOBALS->num_rows_search_c_2/100.0); GLOBALS->pdata->oldvalue = -1.0; /* LX2 */ if(GLOBALS->is_lx2) { int pre_import=0; for(i=0;inum_rows_search_c_2;i++) { struct symbol *s, *t; s=(struct symbol *)gtk_clist_get_row_data(GTK_CLIST(GLOBALS->clist_search_c_3), i); if(get_s_selected(s)) { if((!s->vec_root)||(!GLOBALS->autocoalesce)) { if(s->n->mv.mvlfac) { lx2_set_fac_process_mask(s->n); pre_import++; } } else { t=s->vec_root; while(t) { if(t->n->mv.mvlfac) { lx2_set_fac_process_mask(t->n); pre_import++; } t=t->vec_chain; } } } } if(pre_import) { lx2_import_masked(); } } /* LX2 */ for(i=0;inum_rows_search_c_2;i++) { int len; struct symbol *s, *t; s=(struct symbol *)gtk_clist_get_row_data(GTK_CLIST(GLOBALS->clist_search_c_3), i); if(get_s_selected(s)) { GLOBALS->pdata->value = i; if(((int)(GLOBALS->pdata->value/interval))!=((int)(GLOBALS->pdata->oldvalue/interval))) { gtk_progress_set_value (GTK_PROGRESS (GLOBALS->pdata->pbar), i); gtkwave_main_iteration(); } GLOBALS->pdata->oldvalue = i; if((!s->vec_root)||(!GLOBALS->autocoalesce)) { AddNodeUnroll(s->n, NULL); } else { len=0; t=s->vec_root; while(t) { if(get_s_selected(t)) { if(len) set_s_selected(t, 0); symc_current=(struct symchain *)calloc_2(1,sizeof(struct symchain)); symc_current->next=symc; symc_current->symbol=t; symc=symc_current; } len++; t=t->vec_chain; } if(len)add_vector_chain(s->vec_root, len); } } } while(symc) { set_s_selected(symc->symbol, 1); symc_current=symc; symc=symc->next; free_2(symc_current); } GLOBALS->traces.scroll_top = GLOBALS->traces.scroll_bottom = GLOBALS->traces.last; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); gtk_progress_set_value (GTK_PROGRESS (GLOBALS->pdata->pbar), 0.0); GLOBALS->pdata->oldvalue = -1.0; set_window_idle(widget); wave_gtk_grab_remove(widget); GLOBALS->is_append_running_search_c_1=0; } static void select_row_callback(GtkWidget *widget, gint row, gint column, GdkEventButton *event, gpointer data) { (void)widget; (void)column; (void)event; (void)data; struct symbol *s; s=(struct symbol *)gtk_clist_get_row_data(GTK_CLIST(GLOBALS->clist_search_c_3), row); DEBUG(printf("Select: %p %s\n",s, s->name)); set_s_selected(s, 1); GLOBALS->selected_rows_search_c_2++; } static void unselect_row_callback(GtkWidget *widget, gint row, gint column, GdkEventButton *event, gpointer data) { (void)widget; (void)column; (void)event; (void)data; struct symbol *s; s=(struct symbol *)gtk_clist_get_row_data(GTK_CLIST(GLOBALS->clist_search_c_3), row); DEBUG(printf("Unselect: %p %s\n",s, s->name)); set_s_selected(s, 0); GLOBALS->selected_rows_search_c_2--; } void search_enter_callback(GtkWidget *widget, GtkWidget *do_warning) { GtkCList *cl; G_CONST_RETURN gchar *entry_text; char *entry_suffixed; int i, row; char *s, *tmp2; gfloat interval; int depack_cnt = 0; char *duplicate_row_buffer = NULL; if(GLOBALS->is_searching_running_search_c_1) return; GLOBALS->is_searching_running_search_c_1 = ~0; wave_gtk_grab_add(widget); entry_text = gtk_entry_get_text(GTK_ENTRY(GLOBALS->entry_search_c_3)); entry_text = entry_text ? entry_text : ""; DEBUG(printf("Entry contents: %s\n", entry_text)); free_2(GLOBALS->searchbox_text_search_c_1); if(strlen(entry_text)) { GLOBALS->searchbox_text_search_c_1 = strdup_2(entry_text); } else { GLOBALS->searchbox_text_search_c_1 = strdup_2(""); } GLOBALS->num_rows_search_c_2=0; gtk_clist_freeze(cl=GTK_CLIST(GLOBALS->clist_search_c_3)); gtk_clist_clear(cl); entry_suffixed=wave_alloca(strlen(GLOBALS->searchbox_text_search_c_1 /* scan-build, was entry_text */)+strlen(regex_type[GLOBALS->regex_which_search_c_1])+1+((GLOBALS->regex_which_search_c_1<2)?2:0)); *entry_suffixed=0x00; if(GLOBALS->regex_which_search_c_1<2) strcpy(entry_suffixed, "\\<"); /* match on word boundary */ strcat(entry_suffixed,GLOBALS->searchbox_text_search_c_1); /* scan-build */ strcat(entry_suffixed,regex_type[GLOBALS->regex_which_search_c_1]); wave_regex_compile(entry_suffixed, WAVE_REGEX_SEARCH); for(i=0;inumfacs;i++) { set_s_selected(GLOBALS->facs[i], 0); } GTK_ADJUSTMENT(GLOBALS->pdata->adj)->upper = (gfloat)((GLOBALS->numfacs>1)?GLOBALS->numfacs-1:1); GLOBALS->pdata->oldvalue = -1.0; interval = (gfloat)(GLOBALS->numfacs/100.0); duplicate_row_buffer = (char *)calloc_2(1, GLOBALS->longestname+1); for(i=0;inumfacs;i++) { int was_packed = HIER_DEPACK_STATIC; char *hfacname = NULL; int skiprow; GLOBALS->pdata->value = i; if(((int)(GLOBALS->pdata->value/interval))!=((int)(GLOBALS->pdata->oldvalue/interval))) { gtk_progress_set_value (GTK_PROGRESS (GLOBALS->pdata->pbar), i); gtkwave_main_iteration(); } GLOBALS->pdata->oldvalue = i; hfacname = hier_decompress_flagged(GLOBALS->facs[i]->name, &was_packed); if(!strcmp(hfacname, duplicate_row_buffer)) { skiprow = 1; } else { skiprow = 0; strcpy(duplicate_row_buffer, hfacname); } depack_cnt += was_packed; if((!skiprow) && wave_regex_match(hfacname, WAVE_REGEX_SEARCH)) if((!GLOBALS->is_ghw)||(strcmp(WAVE_GHW_DUMMYFACNAME, hfacname))) { if(!GLOBALS->facs[i]->vec_root) { row=gtk_clist_append(cl,(gchar **)&(hfacname)); } else { if(GLOBALS->autocoalesce) { if(GLOBALS->facs[i]->vec_root!=GLOBALS->facs[i]) continue; tmp2=makename_chain(GLOBALS->facs[i]); s=(char *)malloc_2(strlen(tmp2)+4); strcpy(s,"[] "); strcpy(s+3, tmp2); free_2(tmp2); } else { s=(char *)malloc_2(strlen(hfacname)+4); strcpy(s,"[] "); strcpy(s+3, hfacname); } row=gtk_clist_append(cl,(gchar **)&s); free_2(s); } gtk_clist_set_row_data(cl, row,GLOBALS->facs[i]); GLOBALS->num_rows_search_c_2++; if(GLOBALS->num_rows_search_c_2==WAVE_MAX_CLIST_LENGTH) { /* if(was_packed) { free_2(hfacname); } ...not needed with HIER_DEPACK_STATIC */ break; } } /* if(was_packed) { free_2(hfacname); } ...not needed with HIER_DEPACK_STATIC */ } free_2(duplicate_row_buffer); if(depack_cnt) { gtk_clist_set_compare_func(cl, clist_sigcmp); gtk_clist_sort (cl); } gtk_clist_set_column_width(GTK_CLIST(GLOBALS->clist_search_c_3),0,gtk_clist_optimal_column_width(GTK_CLIST(GLOBALS->clist_search_c_3),0)); gtk_clist_thaw(cl); gtk_progress_set_value (GTK_PROGRESS (GLOBALS->pdata->pbar), 0.0); GLOBALS->pdata->oldvalue = -1.0; wave_gtk_grab_remove(widget); GLOBALS->is_searching_running_search_c_1=0; if(do_warning) if(GLOBALS->num_rows_search_c_2>=WAVE_MAX_CLIST_LENGTH) { char buf[256]; sprintf(buf, "Limiting results to first %d entries.", GLOBALS->num_rows_search_c_2); simplereqbox("Regex Search Warning",300,buf,"OK", NULL, NULL, 1); } } static void destroy_callback(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; if((!GLOBALS->is_insert_running_search_c_1)&&(!GLOBALS->is_replace_running_search_c_1)&&(!GLOBALS->is_append_running_search_c_1)&&(!GLOBALS->is_searching_running_search_c_1)) { GLOBALS->is_active_search_c_4=0; gtk_widget_destroy(GLOBALS->window_search_c_7); GLOBALS->window_search_c_7 = NULL; GLOBALS->clist_search_c_3 = NULL; } } static void select_all_callback(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; gtk_clist_select_all(GTK_CLIST(GLOBALS->clist_search_c_3)); } static void unselect_all_callback(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; gtk_clist_unselect_all(GTK_CLIST(GLOBALS->clist_search_c_3)); } /* * mainline.. */ void searchbox(char *title, GtkSignalFunc func) { int i; GtkWidget *menu, *optionmenu; GSList *group; GtkWidget *small_hbox; GtkWidget *scrolled_win; GtkWidget *vbox1, *hbox, *hbox0; GtkWidget *button1, *button2, *button3, *button3a, *button4, *button5, *button6, *button7; GtkWidget *label; gchar *titles[]={"Matches"}; GtkWidget *frame1, *frame2, *frameh, *frameh0; GtkWidget *table; GtkTooltips *tooltips; GtkAdjustment *adj; GtkWidget *align; /* fix problem where ungrab doesn't occur if button pressed + simultaneous accelerator key occurs */ if(GLOBALS->in_button_press_wavewindow_c_1) { gdk_pointer_ungrab(GDK_CURRENT_TIME); } if(GLOBALS->is_active_search_c_4) { gdk_window_raise(GLOBALS->window_search_c_7->window); return; } if(!GLOBALS->searchbox_text_search_c_1) GLOBALS->searchbox_text_search_c_1 = strdup_2(""); GLOBALS->is_active_search_c_4=1; GLOBALS->cleanup_search_c_5=func; GLOBALS->num_rows_search_c_2=GLOBALS->selected_rows_search_c_2=0; /* create a new modal window */ GLOBALS->window_search_c_7 = gtk_window_new(GLOBALS->disable_window_manager ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL); install_focus_cb(GLOBALS->window_search_c_7, ((char *)&GLOBALS->window_search_c_7) - ((char *)GLOBALS)); gtk_window_set_title(GTK_WINDOW (GLOBALS->window_search_c_7), title); gtkwave_signal_connect(GTK_OBJECT (GLOBALS->window_search_c_7), "delete_event",(GtkSignalFunc) destroy_callback, NULL); tooltips=gtk_tooltips_new_2(); table = gtk_table_new (256, 1, FALSE); gtk_widget_show (table); vbox1 = gtk_vbox_new (FALSE, 0); gtk_container_border_width (GTK_CONTAINER (vbox1), 3); gtk_widget_show (vbox1); frame1 = gtk_frame_new (NULL); gtk_container_border_width (GTK_CONTAINER (frame1), 3); gtk_widget_show(frame1); gtk_table_attach (GTK_TABLE (table), frame1, 0, 1, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); label=gtk_label_new("Signal Search Expression"); gtk_widget_show(label); gtk_box_pack_start (GTK_BOX (vbox1), label, TRUE, TRUE, 0); GLOBALS->entry_search_c_3 = gtk_entry_new_with_max_length (256); gtkwave_signal_connect(GTK_OBJECT(GLOBALS->entry_search_c_3), "activate", GTK_SIGNAL_FUNC(search_enter_callback),GLOBALS->entry_search_c_3); gtk_entry_set_text (GTK_ENTRY (GLOBALS->entry_search_c_3), GLOBALS->searchbox_text_search_c_1); gtk_entry_select_region (GTK_ENTRY (GLOBALS->entry_search_c_3),0, GTK_ENTRY(GLOBALS->entry_search_c_3)->text_length); gtk_widget_show (GLOBALS->entry_search_c_3); gtk_tooltips_set_tip_2(tooltips, GLOBALS->entry_search_c_3, "Enter search expression here. POSIX Wildcards are allowed. Note that you may also ""modify the search criteria by selecting ``[W]Range'', ``[W]Strand'', or ``None'' for suffix ""matching.",NULL); gtk_box_pack_start (GTK_BOX (vbox1), GLOBALS->entry_search_c_3, TRUE, TRUE, 0); /* Allocate memory for the data that is used later */ GLOBALS->pdata = calloc_2(1, sizeof(SearchProgressData) ); GLOBALS->pdata->value = GLOBALS->pdata->oldvalue = 0.0; /* Create a centering alignment object */ align = gtk_alignment_new (0.5, 0.5, 0, 0); gtk_widget_show(align); /* Create a Adjustment object to hold the range of the * progress bar */ adj = (GtkAdjustment *) gtk_adjustment_new (0.0, 0.0, (gfloat)((GLOBALS->numfacs>1)?GLOBALS->numfacs-1:1), 0, 0, 0); GLOBALS->pdata->adj = adj; /* Create the GtkProgressBar using the adjustment */ GLOBALS->pdata->pbar = gtk_progress_bar_new_with_adjustment (adj); /* Set the format of the string that can be displayed in the * trough of the progress bar: * %p - percentage * %v - value * %l - lower range value * %u - upper range value */ gtk_progress_set_format_string (GTK_PROGRESS (GLOBALS->pdata->pbar), "(%p%%)"); gtk_progress_set_show_text (GTK_PROGRESS (GLOBALS->pdata->pbar), TRUE); gtk_widget_show(GLOBALS->pdata->pbar); gtk_box_pack_start (GTK_BOX (vbox1), GLOBALS->pdata->pbar, TRUE, TRUE, 0); gtk_container_add (GTK_CONTAINER (frame1), vbox1); frame2 = gtk_frame_new (NULL); gtk_container_border_width (GTK_CONTAINER (frame2), 3); gtk_widget_show(frame2); gtk_table_attach (GTK_TABLE (table), frame2, 0, 1, 1, 254, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); GLOBALS->clist_search_c_3=gtk_clist_new_with_titles(1,titles); gtk_clist_column_titles_passive(GTK_CLIST(GLOBALS->clist_search_c_3)); gtk_clist_set_selection_mode(GTK_CLIST(GLOBALS->clist_search_c_3), GTK_SELECTION_EXTENDED); gtkwave_signal_connect_object (GTK_OBJECT (GLOBALS->clist_search_c_3), "select_row",GTK_SIGNAL_FUNC(select_row_callback),NULL); gtkwave_signal_connect_object (GTK_OBJECT (GLOBALS->clist_search_c_3), "unselect_row",GTK_SIGNAL_FUNC(unselect_row_callback),NULL); gtk_widget_show (GLOBALS->clist_search_c_3); #if WAVE_USE_GTK2 dnd_setup(GLOBALS->clist_search_c_3, GLOBALS->signalarea, 0); #endif scrolled_win = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_widget_set_usize( GTK_WIDGET (scrolled_win), -1, 300); gtk_widget_show(scrolled_win); /* gtk_scrolled_window_add_with_viewport doesn't seen to work right here.. */ gtk_container_add (GTK_CONTAINER (scrolled_win), GLOBALS->clist_search_c_3); gtk_container_add (GTK_CONTAINER (frame2), scrolled_win); frameh0 = gtk_frame_new (NULL); gtk_container_border_width (GTK_CONTAINER (frameh0), 3); gtk_widget_show(frameh0); gtk_table_attach (GTK_TABLE (table), frameh0, 0, 1, 254, 255, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); hbox0 = gtk_hbox_new (FALSE, 1); gtk_widget_show (hbox0); button6 = gtk_button_new_with_label (" Select All "); gtk_container_border_width (GTK_CONTAINER (button6), 3); gtkwave_signal_connect_object (GTK_OBJECT (button6), "clicked",GTK_SIGNAL_FUNC(select_all_callback),GTK_OBJECT (GLOBALS->window_search_c_7)); gtk_widget_show (button6); gtk_tooltips_set_tip_2(tooltips, button6, "Highlight all signals listed in the match window.",NULL); gtk_box_pack_start (GTK_BOX (hbox0), button6, TRUE, FALSE, 0); menu = gtk_menu_new (); group=NULL; small_hbox = gtk_hbox_new (TRUE, 0); gtk_widget_show (small_hbox); for(i=0;i<5;i++) { GLOBALS->menuitem_search[i] = gtk_radio_menu_item_new_with_label (group, regex_name[i]); group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (GLOBALS->menuitem_search[i])); gtk_menu_append (GTK_MENU (menu), GLOBALS->menuitem_search[i]); gtk_widget_show (GLOBALS->menuitem_search[i]); gtkwave_signal_connect(GTK_OBJECT (GLOBALS->menuitem_search[i]), "activate", GTK_SIGNAL_FUNC(regex_clicked), (void *)((intptr_t)i)); GLOBALS->regex_mutex_search_c_1[i]=0; } GLOBALS->regex_mutex_search_c_1[0]=1; /* "range" */ optionmenu = gtk_option_menu_new (); gtk_option_menu_set_menu (GTK_OPTION_MENU (optionmenu), menu); gtk_box_pack_start (GTK_BOX (small_hbox), optionmenu, TRUE, FALSE, 0); gtk_widget_show (optionmenu); gtk_tooltips_set_tip_2(tooltips, optionmenu, "You may " "modify the search criteria by selecting ``Range'', ``Strand'', or ``None'' for suffix " "matching. This optionally matches the string you enter in the search string above with a Verilog " "format range (signal[7:0]), a strand (signal.1, signal.0), or with no suffix. " "The ``W'' modifier for ``Range'' and ``Strand'' explicitly matches on word boundaries. " "(addr matches unit.freezeaddr[63:0] for ``Range'' but only unit.addr[63:0] for ``WRange'' since addr has to be on a word boundary. " "Note that when ``None'' " "is selected, the search string may be located anywhere in the signal name.",NULL); gtk_box_pack_start (GTK_BOX (hbox0), small_hbox, FALSE, FALSE, 0); button7 = gtk_button_new_with_label (" Unselect All "); gtk_container_border_width (GTK_CONTAINER (button7), 3); gtkwave_signal_connect_object (GTK_OBJECT (button7), "clicked",GTK_SIGNAL_FUNC(unselect_all_callback),GTK_OBJECT (GLOBALS->window_search_c_7)); gtk_widget_show (button7); gtk_tooltips_set_tip_2(tooltips, button7, "Unhighlight all signals listed in the match window.",NULL); gtk_box_pack_start (GTK_BOX (hbox0), button7, TRUE, FALSE, 0); gtk_container_add (GTK_CONTAINER (frameh0), hbox0); frameh = gtk_frame_new (NULL); gtk_container_border_width (GTK_CONTAINER (frameh), 3); gtk_widget_show(frameh); gtk_table_attach (GTK_TABLE (table), frameh, 0, 1, 255, 256, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); hbox = gtk_hbox_new (FALSE, 1); gtk_widget_show (hbox); button1 = gtk_button_new_with_label ("Append"); gtk_container_border_width (GTK_CONTAINER (button1), 3); gtkwave_signal_connect_object (GTK_OBJECT (button1), "clicked",GTK_SIGNAL_FUNC(ok_callback),GTK_OBJECT (GLOBALS->window_search_c_7)); gtk_widget_show (button1); gtk_tooltips_set_tip_2(tooltips, button1, "Add selected signals to end of the display on the main window.",NULL); gtk_box_pack_start (GTK_BOX (hbox), button1, TRUE, FALSE, 0); button2 = gtk_button_new_with_label (" Insert "); gtk_container_border_width (GTK_CONTAINER (button2), 3); gtkwave_signal_connect_object (GTK_OBJECT (button2), "clicked",GTK_SIGNAL_FUNC(insert_callback),GTK_OBJECT (GLOBALS->window_search_c_7)); gtk_widget_show (button2); gtk_tooltips_set_tip_2(tooltips, button2, "Add selected signals after last highlighted signal on the main window.",NULL); gtk_box_pack_start (GTK_BOX (hbox), button2, TRUE, FALSE, 0); if(GLOBALS->vcd_explicit_zero_subscripts>=0) { button3 = gtk_button_new_with_label (" Bundle Up "); gtk_container_border_width (GTK_CONTAINER (button3), 3); gtkwave_signal_connect_object (GTK_OBJECT (button3), "clicked",GTK_SIGNAL_FUNC(bundle_callback_up),GTK_OBJECT (GLOBALS->window_search_c_7)); gtk_widget_show (button3); gtk_tooltips_set_tip_2(tooltips, button3, "Bundle selected signals into a single bit vector with the topmost selected signal as the LSB and the lowest as the MSB.",NULL); gtk_box_pack_start (GTK_BOX (hbox), button3, TRUE, FALSE, 0); button3a = gtk_button_new_with_label (" Bundle Down "); gtk_container_border_width (GTK_CONTAINER (button3a), 3); gtkwave_signal_connect_object (GTK_OBJECT (button3a), "clicked",GTK_SIGNAL_FUNC(bundle_callback_down),GTK_OBJECT (GLOBALS->window_search_c_7)); gtk_widget_show (button3a); gtk_tooltips_set_tip_2(tooltips, button3a, "Bundle selected signals into a single bit vector with the topmost selected signal as the MSB and the lowest as the LSB.",NULL); gtk_box_pack_start (GTK_BOX (hbox), button3a, TRUE, FALSE, 0); } button4 = gtk_button_new_with_label (" Replace "); gtk_container_border_width (GTK_CONTAINER (button4), 3); gtkwave_signal_connect_object (GTK_OBJECT (button4), "clicked",GTK_SIGNAL_FUNC(replace_callback),GTK_OBJECT (GLOBALS->window_search_c_7)); gtk_widget_show (button4); gtk_tooltips_set_tip_2(tooltips, button4, "Replace highlighted signals on the main window with signals selected above.",NULL); gtk_box_pack_start (GTK_BOX (hbox), button4, TRUE, FALSE, 0); button5 = gtk_button_new_with_label (" Exit "); gtk_container_border_width (GTK_CONTAINER (button5), 3); gtkwave_signal_connect_object (GTK_OBJECT (button5), "clicked",GTK_SIGNAL_FUNC(destroy_callback),GTK_OBJECT (GLOBALS->window_search_c_7)); gtk_tooltips_set_tip_2(tooltips, button5, "Do nothing and return to the main window.",NULL); gtk_widget_show (button5); gtk_box_pack_start (GTK_BOX (hbox), button5, TRUE, FALSE, 0); gtk_container_add (GTK_CONTAINER (frameh), hbox); gtk_container_add (GTK_CONTAINER (GLOBALS->window_search_c_7), table); gtk_widget_show(GLOBALS->window_search_c_7); if(strlen(GLOBALS->searchbox_text_search_c_1)) search_enter_callback(GLOBALS->entry_search_c_3,NULL); } gtkwave-3.3.66/src/libbz2/0000775000076400007640000000000012546303363014557 5ustar bybellbybellgtkwave-3.3.66/src/libbz2/Makefile.in0000664000076400007640000004071512261434733016633 0ustar bybellbybell# Makefile.in generated by automake 1.13.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 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__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } 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 = : subdir = src/libbz2 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru AM_V_AR = $(am__v_AR_@AM_V@) am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) am__v_AR_0 = @echo " AR " $@; am__v_AR_1 = libbz2_a_AR = $(AR) $(ARFLAGS) libbz2_a_LIBADD = am_libbz2_a_OBJECTS = blocksort.$(OBJEXT) compress.$(OBJEXT) \ decompress.$(OBJEXT) randtable.$(OBJEXT) bzlib.$(OBJEXT) \ crctable.$(OBJEXT) huffman.$(OBJEXT) libbz2_a_OBJECTS = $(am_libbz2_a_OBJECTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f 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 = $(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 = SOURCES = $(libbz2_a_SOURCES) DIST_SOURCES = $(libbz2_a_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)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AET2_CFLAGS = @AET2_CFLAGS@ AET2_LDADD = @AET2_LDADD@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COCOA_GTK_CFLAGS = @COCOA_GTK_CFLAGS@ COCOA_GTK_LDADD = @COCOA_GTK_LDADD@ COCOA_GTK_LDFLAGS = @COCOA_GTK_LDFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTDEBUG = @EXTDEBUG@ EXTDEBUG2 = @EXTDEBUG2@ EXTDEBUG3 = @EXTDEBUG3@ EXTDEBUG4 = @EXTDEBUG4@ EXTLOAD_CFLAGS = @EXTLOAD_CFLAGS@ FASTTREE_CFLAGS = @FASTTREE_CFLAGS@ FSDB_CFLAGS = @FSDB_CFLAGS@ FSDB_LDADD = @FSDB_LDADD@ GCONF_CFLAGS = @GCONF_CFLAGS@ GCONF_LIBS = @GCONF_LIBS@ GEDITTEST = @GEDITTEST@ GEDIT_CFLAGS = @GEDIT_CFLAGS@ GPERF = @GPERF@ GREP = @GREP@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_CONFIG = @GTK_CONFIG@ GTK_LIBS = @GTK_LIBS@ GTK_MAC_CFLAGS = @GTK_MAC_CFLAGS@ GTK_MAC_LIBS = @GTK_MAC_LIBS@ GTK_UNIX_PRINT_CFLAGS = @GTK_UNIX_PRINT_CFLAGS@ GTK_UNIX_PRINT_LIBS = @GTK_UNIX_PRINT_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBBZ2_CFLAGS = @LIBBZ2_CFLAGS@ LIBBZ2_DIR = @LIBBZ2_DIR@ LIBBZ2_LDADD = @LIBBZ2_LDADD@ LIBJUDY_CFLAGS = @LIBJUDY_CFLAGS@ LIBJUDY_LDADD = @LIBJUDY_LDADD@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBXZ_CFLAGS = @LIBXZ_CFLAGS@ LIBXZ_LDADD = @LIBXZ_LDADD@ LIBZ_CFLAGS = @LIBZ_CFLAGS@ LIBZ_DIR = @LIBZ_DIR@ LIBZ_LDADD = @LIBZ_LDADD@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MINGW_LDADD = @MINGW_LDADD@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ 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@ POW_LIB = @POW_LIB@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ STRUCT_PACK = @STRUCT_PACK@ TCL_DEFADD = @TCL_DEFADD@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LDADD = @TCL_LDADD@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_MAJOR_VERSION = @TCL_MAJOR_VERSION@ TCL_MINOR_VERSION = @TCL_MINOR_VERSION@ TK_INCLUDE_SPEC = @TK_INCLUDE_SPEC@ TK_LDADD = @TK_LDADD@ TK_LIB_SPEC = @TK_LIB_SPEC@ UPDATE_DESKTOP_DATABASE = @UPDATE_DESKTOP_DATABASE@ UPDATE_MIME_DATABASE = @UPDATE_MIME_DATABASE@ VERSION = @VERSION@ XDGDATADIR = @XDGDATADIR@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ 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_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ 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@ 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@ noinst_LIBRARIES = libbz2.a libbz2_a_SOURCES = blocksort.c bzlib.h compress.c decompress.c randtable.c \ bzlib.c bzlib_private.h crctable.c huffman.c EXTRA_DIST = bzlib.h LICENSE all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(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) --foreign src/libbz2/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/libbz2/Makefile .PRECIOUS: 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__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libbz2.a: $(libbz2_a_OBJECTS) $(libbz2_a_DEPENDENCIES) $(EXTRA_libbz2_a_DEPENDENCIES) $(AM_V_at)-rm -f libbz2.a $(AM_V_AR)$(libbz2_a_AR) libbz2.a $(libbz2_a_OBJECTS) $(libbz2_a_LIBADD) $(AM_V_at)$(RANLIB) libbz2.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blocksort.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bzlib.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compress.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crctable.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/decompress.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/huffman.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/randtable.Po@am__quote@ .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 $< .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 `$(CYGPATH_W) '$<'` 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: $(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 $(LIBRARIES) installdirs: 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-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -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-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 -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic 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 maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am # 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: gtkwave-3.3.66/src/libbz2/huffman.c0000664000076400007640000001551711523063250016350 0ustar bybellbybell /*-------------------------------------------------------------*/ /*--- Huffman coding low-level stuff ---*/ /*--- huffman.c ---*/ /*-------------------------------------------------------------*/ /* ------------------------------------------------------------------ This file is part of bzip2/libbzip2, a program and library for lossless, block-sorting data compression. bzip2/libbzip2 version 1.0.6 of 6 September 2010 Copyright (C) 1996-2010 Julian Seward Please read the WARNING, DISCLAIMER and PATENTS sections in the README file. This program is released under the terms of the license contained in the file LICENSE. ------------------------------------------------------------------ */ #include "bzlib_private.h" /*---------------------------------------------------*/ #define WEIGHTOF(zz0) ((zz0) & 0xffffff00) #define DEPTHOF(zz1) ((zz1) & 0x000000ff) #define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3)) #define ADDWEIGHTS(zw1,zw2) \ (WEIGHTOF(zw1)+WEIGHTOF(zw2)) | \ (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2))) #define UPHEAP(z) \ { \ Int32 zz, tmp; \ zz = z; tmp = heap[zz]; \ while (weight[tmp] < weight[heap[zz >> 1]]) { \ heap[zz] = heap[zz >> 1]; \ zz >>= 1; \ } \ heap[zz] = tmp; \ } #define DOWNHEAP(z) \ { \ Int32 zz, yy, tmp; \ zz = z; tmp = heap[zz]; \ while (True) { \ yy = zz << 1; \ if (yy > nHeap) break; \ if (yy < nHeap && \ weight[heap[yy+1]] < weight[heap[yy]]) \ yy++; \ if (weight[tmp] < weight[heap[yy]]) break; \ heap[zz] = heap[yy]; \ zz = yy; \ } \ heap[zz] = tmp; \ } /*---------------------------------------------------*/ void BZ2_hbMakeCodeLengths ( UChar *len, Int32 *freq, Int32 alphaSize, Int32 maxLen ) { /*-- Nodes and heap entries run from 1. Entry 0 for both the heap and nodes is a sentinel. --*/ Int32 nNodes, nHeap, n1, n2, i, j, k; Bool tooLong; Int32 heap [ BZ_MAX_ALPHA_SIZE + 2 ]; Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ]; Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ]; for (i = 0; i < alphaSize; i++) weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8; while (True) { nNodes = alphaSize; nHeap = 0; heap[0] = 0; weight[0] = 0; parent[0] = -2; for (i = 1; i <= alphaSize; i++) { parent[i] = -1; nHeap++; heap[nHeap] = i; UPHEAP(nHeap); } AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 ); while (nHeap > 1) { n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1); n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1); nNodes++; parent[n1] = parent[n2] = nNodes; weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]); parent[nNodes] = -1; nHeap++; heap[nHeap] = nNodes; UPHEAP(nHeap); } AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 ); tooLong = False; for (i = 1; i <= alphaSize; i++) { j = 0; k = i; while (parent[k] >= 0) { k = parent[k]; j++; } len[i-1] = j; if (j > maxLen) tooLong = True; } if (! tooLong) break; /* 17 Oct 04: keep-going condition for the following loop used to be 'i < alphaSize', which missed the last element, theoretically leading to the possibility of the compressor looping. However, this count-scaling step is only needed if one of the generated Huffman code words is longer than maxLen, which up to and including version 1.0.2 was 20 bits, which is extremely unlikely. In version 1.0.3 maxLen was changed to 17 bits, which has minimal effect on compression ratio, but does mean this scaling step is used from time to time, enough to verify that it works. This means that bzip2-1.0.3 and later will only produce Huffman codes with a maximum length of 17 bits. However, in order to preserve backwards compatibility with bitstreams produced by versions pre-1.0.3, the decompressor must still handle lengths of up to 20. */ for (i = 1; i <= alphaSize; i++) { j = weight[i] >> 8; j = 1 + (j / 2); weight[i] = j << 8; } } } /*---------------------------------------------------*/ void BZ2_hbAssignCodes ( Int32 *code, UChar *length, Int32 minLen, Int32 maxLen, Int32 alphaSize ) { Int32 n, vec, i; vec = 0; for (n = minLen; n <= maxLen; n++) { for (i = 0; i < alphaSize; i++) if (length[i] == n) { code[i] = vec; vec++; }; vec <<= 1; } } /*---------------------------------------------------*/ void BZ2_hbCreateDecodeTables ( Int32 *limit, Int32 *base, Int32 *perm, UChar *length, Int32 minLen, Int32 maxLen, Int32 alphaSize ) { Int32 pp, i, j, vec; pp = 0; for (i = minLen; i <= maxLen; i++) for (j = 0; j < alphaSize; j++) if (length[j] == i) { perm[pp] = j; pp++; }; for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0; for (i = 0; i < alphaSize; i++) base[length[i]+1]++; for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1]; for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0; vec = 0; for (i = minLen; i <= maxLen; i++) { vec += (base[i+1] - base[i]); limit[i] = vec-1; vec <<= 1; } for (i = minLen + 1; i <= maxLen; i++) base[i] = ((limit[i-1] + 1) << 1) - base[i]; } /*-------------------------------------------------------------*/ /*--- end huffman.c ---*/ /*-------------------------------------------------------------*/ gtkwave-3.3.66/src/libbz2/randtable.c0000664000076400007640000000742411523063250016656 0ustar bybellbybell /*-------------------------------------------------------------*/ /*--- Table for randomising repetitive blocks ---*/ /*--- randtable.c ---*/ /*-------------------------------------------------------------*/ /* ------------------------------------------------------------------ This file is part of bzip2/libbzip2, a program and library for lossless, block-sorting data compression. bzip2/libbzip2 version 1.0.6 of 6 September 2010 Copyright (C) 1996-2010 Julian Seward Please read the WARNING, DISCLAIMER and PATENTS sections in the README file. This program is released under the terms of the license contained in the file LICENSE. ------------------------------------------------------------------ */ #include "bzlib_private.h" /*---------------------------------------------*/ Int32 BZ2_rNums[512] = { 619, 720, 127, 481, 931, 816, 813, 233, 566, 247, 985, 724, 205, 454, 863, 491, 741, 242, 949, 214, 733, 859, 335, 708, 621, 574, 73, 654, 730, 472, 419, 436, 278, 496, 867, 210, 399, 680, 480, 51, 878, 465, 811, 169, 869, 675, 611, 697, 867, 561, 862, 687, 507, 283, 482, 129, 807, 591, 733, 623, 150, 238, 59, 379, 684, 877, 625, 169, 643, 105, 170, 607, 520, 932, 727, 476, 693, 425, 174, 647, 73, 122, 335, 530, 442, 853, 695, 249, 445, 515, 909, 545, 703, 919, 874, 474, 882, 500, 594, 612, 641, 801, 220, 162, 819, 984, 589, 513, 495, 799, 161, 604, 958, 533, 221, 400, 386, 867, 600, 782, 382, 596, 414, 171, 516, 375, 682, 485, 911, 276, 98, 553, 163, 354, 666, 933, 424, 341, 533, 870, 227, 730, 475, 186, 263, 647, 537, 686, 600, 224, 469, 68, 770, 919, 190, 373, 294, 822, 808, 206, 184, 943, 795, 384, 383, 461, 404, 758, 839, 887, 715, 67, 618, 276, 204, 918, 873, 777, 604, 560, 951, 160, 578, 722, 79, 804, 96, 409, 713, 940, 652, 934, 970, 447, 318, 353, 859, 672, 112, 785, 645, 863, 803, 350, 139, 93, 354, 99, 820, 908, 609, 772, 154, 274, 580, 184, 79, 626, 630, 742, 653, 282, 762, 623, 680, 81, 927, 626, 789, 125, 411, 521, 938, 300, 821, 78, 343, 175, 128, 250, 170, 774, 972, 275, 999, 639, 495, 78, 352, 126, 857, 956, 358, 619, 580, 124, 737, 594, 701, 612, 669, 112, 134, 694, 363, 992, 809, 743, 168, 974, 944, 375, 748, 52, 600, 747, 642, 182, 862, 81, 344, 805, 988, 739, 511, 655, 814, 334, 249, 515, 897, 955, 664, 981, 649, 113, 974, 459, 893, 228, 433, 837, 553, 268, 926, 240, 102, 654, 459, 51, 686, 754, 806, 760, 493, 403, 415, 394, 687, 700, 946, 670, 656, 610, 738, 392, 760, 799, 887, 653, 978, 321, 576, 617, 626, 502, 894, 679, 243, 440, 680, 879, 194, 572, 640, 724, 926, 56, 204, 700, 707, 151, 457, 449, 797, 195, 791, 558, 945, 679, 297, 59, 87, 824, 713, 663, 412, 693, 342, 606, 134, 108, 571, 364, 631, 212, 174, 643, 304, 329, 343, 97, 430, 751, 497, 314, 983, 374, 822, 928, 140, 206, 73, 263, 980, 736, 876, 478, 430, 305, 170, 514, 364, 692, 829, 82, 855, 953, 676, 246, 369, 970, 294, 750, 807, 827, 150, 790, 288, 923, 804, 378, 215, 828, 592, 281, 565, 555, 710, 82, 896, 831, 547, 261, 524, 462, 293, 465, 502, 56, 661, 821, 976, 991, 658, 869, 905, 758, 745, 193, 768, 550, 608, 933, 378, 286, 215, 979, 792, 961, 61, 688, 793, 644, 986, 403, 106, 366, 905, 644, 372, 567, 466, 434, 645, 210, 389, 550, 919, 135, 780, 773, 635, 389, 707, 100, 626, 958, 165, 504, 920, 176, 193, 713, 857, 265, 203, 50, 668, 108, 645, 990, 626, 197, 510, 357, 358, 850, 858, 364, 936, 638 }; /*-------------------------------------------------------------*/ /*--- end randtable.c ---*/ /*-------------------------------------------------------------*/ gtkwave-3.3.66/src/libbz2/bzlib_private.h0000664000076400007640000003167411523063250017567 0ustar bybellbybell /*-------------------------------------------------------------*/ /*--- Private header file for the library. ---*/ /*--- bzlib_private.h ---*/ /*-------------------------------------------------------------*/ /* ------------------------------------------------------------------ This file is part of bzip2/libbzip2, a program and library for lossless, block-sorting data compression. bzip2/libbzip2 version 1.0.6 of 6 September 2010 Copyright (C) 1996-2010 Julian Seward Please read the WARNING, DISCLAIMER and PATENTS sections in the README file. This program is released under the terms of the license contained in the file LICENSE. ------------------------------------------------------------------ */ #ifndef _BZLIB_PRIVATE_H #define _BZLIB_PRIVATE_H #include #ifndef BZ_NO_STDIO #include #include #include #endif #include "bzlib.h" /*-- General stuff. --*/ #define BZ_VERSION "1.0.6, 6-Sept-2010" typedef char Char; typedef unsigned char Bool; typedef unsigned char UChar; typedef int Int32; typedef unsigned int UInt32; typedef short Int16; typedef unsigned short UInt16; #define True ((Bool)1) #define False ((Bool)0) #ifndef __GNUC__ #define __inline__ /* */ #endif #ifndef BZ_NO_STDIO extern void BZ2_bz__AssertH__fail ( int errcode ); #define AssertH(cond,errcode) \ { if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); } #if BZ_DEBUG #define AssertD(cond,msg) \ { if (!(cond)) { \ fprintf ( stderr, \ "\n\nlibbzip2(debug build): internal error\n\t%s\n", msg );\ exit(1); \ }} #else #define AssertD(cond,msg) /* */ #endif #define VPrintf0(zf) \ fprintf(stderr,zf) #define VPrintf1(zf,za1) \ fprintf(stderr,zf,za1) #define VPrintf2(zf,za1,za2) \ fprintf(stderr,zf,za1,za2) #define VPrintf3(zf,za1,za2,za3) \ fprintf(stderr,zf,za1,za2,za3) #define VPrintf4(zf,za1,za2,za3,za4) \ fprintf(stderr,zf,za1,za2,za3,za4) #define VPrintf5(zf,za1,za2,za3,za4,za5) \ fprintf(stderr,zf,za1,za2,za3,za4,za5) #else extern void bz_internal_error ( int errcode ); #define AssertH(cond,errcode) \ { if (!(cond)) bz_internal_error ( errcode ); } #define AssertD(cond,msg) do { } while (0) #define VPrintf0(zf) do { } while (0) #define VPrintf1(zf,za1) do { } while (0) #define VPrintf2(zf,za1,za2) do { } while (0) #define VPrintf3(zf,za1,za2,za3) do { } while (0) #define VPrintf4(zf,za1,za2,za3,za4) do { } while (0) #define VPrintf5(zf,za1,za2,za3,za4,za5) do { } while (0) #endif #define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1) #define BZFREE(ppp) (strm->bzfree)(strm->opaque,(ppp)) /*-- Header bytes. --*/ #define BZ_HDR_B 0x42 /* 'B' */ #define BZ_HDR_Z 0x5a /* 'Z' */ #define BZ_HDR_h 0x68 /* 'h' */ #define BZ_HDR_0 0x30 /* '0' */ /*-- Constants for the back end. --*/ #define BZ_MAX_ALPHA_SIZE 258 #define BZ_MAX_CODE_LEN 23 #define BZ_RUNA 0 #define BZ_RUNB 1 #define BZ_N_GROUPS 6 #define BZ_G_SIZE 50 #define BZ_N_ITERS 4 #define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE)) /*-- Stuff for randomising repetitive blocks. --*/ extern Int32 BZ2_rNums[512]; #define BZ_RAND_DECLS \ Int32 rNToGo; \ Int32 rTPos \ #define BZ_RAND_INIT_MASK \ s->rNToGo = 0; \ s->rTPos = 0 \ #define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0) #define BZ_RAND_UPD_MASK \ if (s->rNToGo == 0) { \ s->rNToGo = BZ2_rNums[s->rTPos]; \ s->rTPos++; \ if (s->rTPos == 512) s->rTPos = 0; \ } \ s->rNToGo--; /*-- Stuff for doing CRCs. --*/ extern UInt32 BZ2_crc32Table[256]; #define BZ_INITIALISE_CRC(crcVar) \ { \ crcVar = 0xffffffffL; \ } #define BZ_FINALISE_CRC(crcVar) \ { \ crcVar = ~(crcVar); \ } #define BZ_UPDATE_CRC(crcVar,cha) \ { \ crcVar = (crcVar << 8) ^ \ BZ2_crc32Table[(crcVar >> 24) ^ \ ((UChar)cha)]; \ } /*-- States and modes for compression. --*/ #define BZ_M_IDLE 1 #define BZ_M_RUNNING 2 #define BZ_M_FLUSHING 3 #define BZ_M_FINISHING 4 #define BZ_S_OUTPUT 1 #define BZ_S_INPUT 2 #define BZ_N_RADIX 2 #define BZ_N_QSORT 12 #define BZ_N_SHELL 18 #define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2) /*-- Structure holding all the compression-side stuff. --*/ typedef struct { /* pointer back to the struct bz_stream */ bz_stream* strm; /* mode this stream is in, and whether inputting */ /* or outputting data */ Int32 mode; Int32 state; /* remembers avail_in when flush/finish requested */ UInt32 avail_in_expect; /* for doing the block sorting */ UInt32* arr1; UInt32* arr2; UInt32* ftab; Int32 origPtr; /* aliases for arr1 and arr2 */ UInt32* ptr; UChar* block; UInt16* mtfv; UChar* zbits; /* for deciding when to use the fallback sorting algorithm */ Int32 workFactor; /* run-length-encoding of the input */ UInt32 state_in_ch; Int32 state_in_len; BZ_RAND_DECLS; /* input and output limits and current posns */ Int32 nblock; Int32 nblockMAX; Int32 numZ; Int32 state_out_pos; /* map of bytes used in block */ Int32 nInUse; Bool inUse[256]; UChar unseqToSeq[256]; /* the buffer for bit stream creation */ UInt32 bsBuff; Int32 bsLive; /* block and combined CRCs */ UInt32 blockCRC; UInt32 combinedCRC; /* misc administratium */ Int32 verbosity; Int32 blockNo; Int32 blockSize100k; /* stuff for coding the MTF values */ Int32 nMTF; Int32 mtfFreq [BZ_MAX_ALPHA_SIZE]; UChar selector [BZ_MAX_SELECTORS]; UChar selectorMtf[BZ_MAX_SELECTORS]; UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; Int32 code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; Int32 rfreq [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; /* second dimension: only 3 needed; 4 makes index calculations faster */ UInt32 len_pack[BZ_MAX_ALPHA_SIZE][4]; } EState; /*-- externs for compression. --*/ extern void BZ2_blockSort ( EState* ); extern void BZ2_compressBlock ( EState*, Bool ); extern void BZ2_bsInitWrite ( EState* ); extern void BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 ); extern void BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 ); /*-- states for decompression. --*/ #define BZ_X_IDLE 1 #define BZ_X_OUTPUT 2 #define BZ_X_MAGIC_1 10 #define BZ_X_MAGIC_2 11 #define BZ_X_MAGIC_3 12 #define BZ_X_MAGIC_4 13 #define BZ_X_BLKHDR_1 14 #define BZ_X_BLKHDR_2 15 #define BZ_X_BLKHDR_3 16 #define BZ_X_BLKHDR_4 17 #define BZ_X_BLKHDR_5 18 #define BZ_X_BLKHDR_6 19 #define BZ_X_BCRC_1 20 #define BZ_X_BCRC_2 21 #define BZ_X_BCRC_3 22 #define BZ_X_BCRC_4 23 #define BZ_X_RANDBIT 24 #define BZ_X_ORIGPTR_1 25 #define BZ_X_ORIGPTR_2 26 #define BZ_X_ORIGPTR_3 27 #define BZ_X_MAPPING_1 28 #define BZ_X_MAPPING_2 29 #define BZ_X_SELECTOR_1 30 #define BZ_X_SELECTOR_2 31 #define BZ_X_SELECTOR_3 32 #define BZ_X_CODING_1 33 #define BZ_X_CODING_2 34 #define BZ_X_CODING_3 35 #define BZ_X_MTF_1 36 #define BZ_X_MTF_2 37 #define BZ_X_MTF_3 38 #define BZ_X_MTF_4 39 #define BZ_X_MTF_5 40 #define BZ_X_MTF_6 41 #define BZ_X_ENDHDR_2 42 #define BZ_X_ENDHDR_3 43 #define BZ_X_ENDHDR_4 44 #define BZ_X_ENDHDR_5 45 #define BZ_X_ENDHDR_6 46 #define BZ_X_CCRC_1 47 #define BZ_X_CCRC_2 48 #define BZ_X_CCRC_3 49 #define BZ_X_CCRC_4 50 /*-- Constants for the fast MTF decoder. --*/ #define MTFA_SIZE 4096 #define MTFL_SIZE 16 /*-- Structure holding all the decompression-side stuff. --*/ typedef struct { /* pointer back to the struct bz_stream */ bz_stream* strm; /* state indicator for this stream */ Int32 state; /* for doing the final run-length decoding */ UChar state_out_ch; Int32 state_out_len; Bool blockRandomised; BZ_RAND_DECLS; /* the buffer for bit stream reading */ UInt32 bsBuff; Int32 bsLive; /* misc administratium */ Int32 blockSize100k; Bool smallDecompress; Int32 currBlockNo; Int32 verbosity; /* for undoing the Burrows-Wheeler transform */ Int32 origPtr; UInt32 tPos; Int32 k0; Int32 unzftab[256]; Int32 nblock_used; Int32 cftab[257]; Int32 cftabCopy[257]; /* for undoing the Burrows-Wheeler transform (FAST) */ UInt32 *tt; /* for undoing the Burrows-Wheeler transform (SMALL) */ UInt16 *ll16; UChar *ll4; /* stored and calculated CRCs */ UInt32 storedBlockCRC; UInt32 storedCombinedCRC; UInt32 calculatedBlockCRC; UInt32 calculatedCombinedCRC; /* map of bytes used in block */ Int32 nInUse; Bool inUse[256]; Bool inUse16[16]; UChar seqToUnseq[256]; /* for decoding the MTF values */ UChar mtfa [MTFA_SIZE]; Int32 mtfbase[256 / MTFL_SIZE]; UChar selector [BZ_MAX_SELECTORS]; UChar selectorMtf[BZ_MAX_SELECTORS]; UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; Int32 limit [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; Int32 base [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; Int32 perm [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; Int32 minLens[BZ_N_GROUPS]; /* save area for scalars in the main decompress code */ Int32 save_i; Int32 save_j; Int32 save_t; Int32 save_alphaSize; Int32 save_nGroups; Int32 save_nSelectors; Int32 save_EOB; Int32 save_groupNo; Int32 save_groupPos; Int32 save_nextSym; Int32 save_nblockMAX; Int32 save_nblock; Int32 save_es; Int32 save_N; Int32 save_curr; Int32 save_zt; Int32 save_zn; Int32 save_zvec; Int32 save_zj; Int32 save_gSel; Int32 save_gMinlen; Int32* save_gLimit; Int32* save_gBase; Int32* save_gPerm; } DState; /*-- Macros for decompression. --*/ #define BZ_GET_FAST(cccc) \ /* c_tPos is unsigned, hence test < 0 is pointless. */ \ if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \ s->tPos = s->tt[s->tPos]; \ cccc = (UChar)(s->tPos & 0xff); \ s->tPos >>= 8; #define BZ_GET_FAST_C(cccc) \ /* c_tPos is unsigned, hence test < 0 is pointless. */ \ if (c_tPos >= (UInt32)100000 * (UInt32)ro_blockSize100k) return True; \ c_tPos = c_tt[c_tPos]; \ cccc = (UChar)(c_tPos & 0xff); \ c_tPos >>= 8; #define SET_LL4(i,n) \ { if (((i) & 0x1) == 0) \ s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else \ s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4); \ } #define GET_LL4(i) \ ((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF) #define SET_LL(i,n) \ { s->ll16[i] = (UInt16)(n & 0x0000ffff); \ SET_LL4(i, n >> 16); \ } #define GET_LL(i) \ (((UInt32)s->ll16[i]) | (GET_LL4(i) << 16)) #define BZ_GET_SMALL(cccc) \ /* c_tPos is unsigned, hence test < 0 is pointless. */ \ if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \ cccc = BZ2_indexIntoF ( s->tPos, s->cftab ); \ s->tPos = GET_LL(s->tPos); /*-- externs for decompression. --*/ extern Int32 BZ2_indexIntoF ( Int32, Int32* ); extern Int32 BZ2_decompress ( DState* ); extern void BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*, Int32, Int32, Int32 ); #endif /*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/ #ifdef BZ_NO_STDIO #ifndef NULL #define NULL 0 #endif #endif /*-------------------------------------------------------------*/ /*--- end bzlib_private.h ---*/ /*-------------------------------------------------------------*/ gtkwave-3.3.66/src/libbz2/LICENSE0000664000076400007640000000355511523063250015564 0ustar bybellbybell -------------------------------------------------------------------------- This program, "bzip2", the associated library "libbzip2", and all documentation, are copyright (C) 1996-2010 Julian R Seward. All rights reserved. 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. 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. 3. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 4. 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. Julian Seward, jseward@bzip.org bzip2/libbzip2 version 1.0.6 of 6 September 2010 -------------------------------------------------------------------------- gtkwave-3.3.66/src/libbz2/decompress.c0000664000076400007640000005066711523063250017075 0ustar bybellbybell /*-------------------------------------------------------------*/ /*--- Decompression machinery ---*/ /*--- decompress.c ---*/ /*-------------------------------------------------------------*/ /* ------------------------------------------------------------------ This file is part of bzip2/libbzip2, a program and library for lossless, block-sorting data compression. bzip2/libbzip2 version 1.0.6 of 6 September 2010 Copyright (C) 1996-2010 Julian Seward Please read the WARNING, DISCLAIMER and PATENTS sections in the README file. This program is released under the terms of the license contained in the file LICENSE. ------------------------------------------------------------------ */ #include "bzlib_private.h" /*---------------------------------------------------*/ static void makeMaps_d ( DState* s ) { Int32 i; s->nInUse = 0; for (i = 0; i < 256; i++) if (s->inUse[i]) { s->seqToUnseq[s->nInUse] = i; s->nInUse++; } } /*---------------------------------------------------*/ #define RETURN(rrr) \ { retVal = rrr; goto save_state_and_return; }; #define GET_BITS(lll,vvv,nnn) \ case lll: s->state = lll; \ while (True) { \ if (s->bsLive >= nnn) { \ UInt32 v; \ v = (s->bsBuff >> \ (s->bsLive-nnn)) & ((1 << nnn)-1); \ s->bsLive -= nnn; \ vvv = v; \ break; \ } \ if (s->strm->avail_in == 0) RETURN(BZ_OK); \ s->bsBuff \ = (s->bsBuff << 8) | \ ((UInt32) \ (*((UChar*)(s->strm->next_in)))); \ s->bsLive += 8; \ s->strm->next_in++; \ s->strm->avail_in--; \ s->strm->total_in_lo32++; \ if (s->strm->total_in_lo32 == 0) \ s->strm->total_in_hi32++; \ } #define GET_UCHAR(lll,uuu) \ GET_BITS(lll,uuu,8) #define GET_BIT(lll,uuu) \ GET_BITS(lll,uuu,1) /*---------------------------------------------------*/ #define GET_MTF_VAL(label1,label2,lval) \ { \ if (groupPos == 0) { \ groupNo++; \ if (groupNo >= nSelectors) \ RETURN(BZ_DATA_ERROR); \ groupPos = BZ_G_SIZE; \ gSel = s->selector[groupNo]; \ gMinlen = s->minLens[gSel]; \ gLimit = &(s->limit[gSel][0]); \ gPerm = &(s->perm[gSel][0]); \ gBase = &(s->base[gSel][0]); \ } \ groupPos--; \ zn = gMinlen; \ GET_BITS(label1, zvec, zn); \ while (1) { \ if (zn > 20 /* the longest code */) \ RETURN(BZ_DATA_ERROR); \ if (zvec <= gLimit[zn]) break; \ zn++; \ GET_BIT(label2, zj); \ zvec = (zvec << 1) | zj; \ }; \ if (zvec - gBase[zn] < 0 \ || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \ RETURN(BZ_DATA_ERROR); \ lval = gPerm[zvec - gBase[zn]]; \ } /*---------------------------------------------------*/ Int32 BZ2_decompress ( DState* s ) { UChar uc; Int32 retVal; Int32 minLen, maxLen; bz_stream* strm = s->strm; /* stuff that needs to be saved/restored */ Int32 i; Int32 j; Int32 t; Int32 alphaSize; Int32 nGroups; Int32 nSelectors; Int32 EOB; Int32 groupNo; Int32 groupPos; Int32 nextSym; Int32 nblockMAX; Int32 nblock; Int32 es; Int32 N; Int32 curr; Int32 zt; Int32 zn; Int32 zvec; Int32 zj; Int32 gSel; Int32 gMinlen; Int32* gLimit; Int32* gBase; Int32* gPerm; if (s->state == BZ_X_MAGIC_1) { /*initialise the save area*/ s->save_i = 0; s->save_j = 0; s->save_t = 0; s->save_alphaSize = 0; s->save_nGroups = 0; s->save_nSelectors = 0; s->save_EOB = 0; s->save_groupNo = 0; s->save_groupPos = 0; s->save_nextSym = 0; s->save_nblockMAX = 0; s->save_nblock = 0; s->save_es = 0; s->save_N = 0; s->save_curr = 0; s->save_zt = 0; s->save_zn = 0; s->save_zvec = 0; s->save_zj = 0; s->save_gSel = 0; s->save_gMinlen = 0; s->save_gLimit = NULL; s->save_gBase = NULL; s->save_gPerm = NULL; } /*restore from the save area*/ i = s->save_i; j = s->save_j; t = s->save_t; alphaSize = s->save_alphaSize; nGroups = s->save_nGroups; nSelectors = s->save_nSelectors; EOB = s->save_EOB; groupNo = s->save_groupNo; groupPos = s->save_groupPos; nextSym = s->save_nextSym; nblockMAX = s->save_nblockMAX; nblock = s->save_nblock; es = s->save_es; N = s->save_N; curr = s->save_curr; zt = s->save_zt; zn = s->save_zn; zvec = s->save_zvec; zj = s->save_zj; gSel = s->save_gSel; gMinlen = s->save_gMinlen; gLimit = s->save_gLimit; gBase = s->save_gBase; gPerm = s->save_gPerm; retVal = BZ_OK; switch (s->state) { GET_UCHAR(BZ_X_MAGIC_1, uc); if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC); GET_UCHAR(BZ_X_MAGIC_2, uc); if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC); GET_UCHAR(BZ_X_MAGIC_3, uc) if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC); GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8) if (s->blockSize100k < (BZ_HDR_0 + 1) || s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC); s->blockSize100k -= BZ_HDR_0; if (s->smallDecompress) { s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) ); s->ll4 = BZALLOC( ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar) ); if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR); } else { s->tt = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) ); if (s->tt == NULL) RETURN(BZ_MEM_ERROR); } GET_UCHAR(BZ_X_BLKHDR_1, uc); if (uc == 0x17) goto endhdr_2; if (uc != 0x31) RETURN(BZ_DATA_ERROR); GET_UCHAR(BZ_X_BLKHDR_2, uc); if (uc != 0x41) RETURN(BZ_DATA_ERROR); GET_UCHAR(BZ_X_BLKHDR_3, uc); if (uc != 0x59) RETURN(BZ_DATA_ERROR); GET_UCHAR(BZ_X_BLKHDR_4, uc); if (uc != 0x26) RETURN(BZ_DATA_ERROR); GET_UCHAR(BZ_X_BLKHDR_5, uc); if (uc != 0x53) RETURN(BZ_DATA_ERROR); GET_UCHAR(BZ_X_BLKHDR_6, uc); if (uc != 0x59) RETURN(BZ_DATA_ERROR); s->currBlockNo++; if (s->verbosity >= 2) VPrintf1 ( "\n [%d: huff+mtf ", s->currBlockNo ); s->storedBlockCRC = 0; GET_UCHAR(BZ_X_BCRC_1, uc); s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); GET_UCHAR(BZ_X_BCRC_2, uc); s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); GET_UCHAR(BZ_X_BCRC_3, uc); s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); GET_UCHAR(BZ_X_BCRC_4, uc); s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1); s->origPtr = 0; GET_UCHAR(BZ_X_ORIGPTR_1, uc); s->origPtr = (s->origPtr << 8) | ((Int32)uc); GET_UCHAR(BZ_X_ORIGPTR_2, uc); s->origPtr = (s->origPtr << 8) | ((Int32)uc); GET_UCHAR(BZ_X_ORIGPTR_3, uc); s->origPtr = (s->origPtr << 8) | ((Int32)uc); if (s->origPtr < 0) RETURN(BZ_DATA_ERROR); if (s->origPtr > 10 + 100000*s->blockSize100k) RETURN(BZ_DATA_ERROR); /*--- Receive the mapping table ---*/ for (i = 0; i < 16; i++) { GET_BIT(BZ_X_MAPPING_1, uc); if (uc == 1) s->inUse16[i] = True; else s->inUse16[i] = False; } for (i = 0; i < 256; i++) s->inUse[i] = False; for (i = 0; i < 16; i++) if (s->inUse16[i]) for (j = 0; j < 16; j++) { GET_BIT(BZ_X_MAPPING_2, uc); if (uc == 1) s->inUse[i * 16 + j] = True; } makeMaps_d ( s ); if (s->nInUse == 0) RETURN(BZ_DATA_ERROR); alphaSize = s->nInUse+2; /*--- Now the selectors ---*/ GET_BITS(BZ_X_SELECTOR_1, nGroups, 3); if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR); GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15); if (nSelectors < 1) RETURN(BZ_DATA_ERROR); for (i = 0; i < nSelectors; i++) { j = 0; while (True) { GET_BIT(BZ_X_SELECTOR_3, uc); if (uc == 0) break; j++; if (j >= nGroups) RETURN(BZ_DATA_ERROR); } s->selectorMtf[i] = j; } /*--- Undo the MTF values for the selectors. ---*/ { UChar pos[BZ_N_GROUPS], tmp, v; for (v = 0; v < nGroups; v++) pos[v] = v; for (i = 0; i < nSelectors; i++) { v = s->selectorMtf[i]; tmp = pos[v]; while (v > 0) { pos[v] = pos[v-1]; v--; } pos[0] = tmp; s->selector[i] = tmp; } } /*--- Now the coding tables ---*/ for (t = 0; t < nGroups; t++) { GET_BITS(BZ_X_CODING_1, curr, 5); for (i = 0; i < alphaSize; i++) { while (True) { if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR); GET_BIT(BZ_X_CODING_2, uc); if (uc == 0) break; GET_BIT(BZ_X_CODING_3, uc); if (uc == 0) curr++; else curr--; } s->len[t][i] = curr; } } /*--- Create the Huffman decoding tables ---*/ for (t = 0; t < nGroups; t++) { minLen = 32; maxLen = 0; for (i = 0; i < alphaSize; i++) { if (s->len[t][i] > maxLen) maxLen = s->len[t][i]; if (s->len[t][i] < minLen) minLen = s->len[t][i]; } BZ2_hbCreateDecodeTables ( &(s->limit[t][0]), &(s->base[t][0]), &(s->perm[t][0]), &(s->len[t][0]), minLen, maxLen, alphaSize ); s->minLens[t] = minLen; } /*--- Now the MTF values ---*/ EOB = s->nInUse+1; nblockMAX = 100000 * s->blockSize100k; groupNo = -1; groupPos = 0; for (i = 0; i <= 255; i++) s->unzftab[i] = 0; /*-- MTF init --*/ { Int32 ii, jj, kk; kk = MTFA_SIZE-1; for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) { for (jj = MTFL_SIZE-1; jj >= 0; jj--) { s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj); kk--; } s->mtfbase[ii] = kk + 1; } } /*-- end MTF init --*/ nblock = 0; GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym); while (True) { if (nextSym == EOB) break; if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) { es = -1; N = 1; do { /* Check that N doesn't get too big, so that es doesn't go negative. The maximum value that can be RUNA/RUNB encoded is equal to the block size (post the initial RLE), viz, 900k, so bounding N at 2 million should guard against overflow without rejecting any legitimate inputs. */ if (N >= 2*1024*1024) RETURN(BZ_DATA_ERROR); if (nextSym == BZ_RUNA) es = es + (0+1) * N; else if (nextSym == BZ_RUNB) es = es + (1+1) * N; N = N * 2; GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym); } while (nextSym == BZ_RUNA || nextSym == BZ_RUNB); es++; uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ]; s->unzftab[uc] += es; if (s->smallDecompress) while (es > 0) { if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); s->ll16[nblock] = (UInt16)uc; nblock++; es--; } else while (es > 0) { if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); s->tt[nblock] = (UInt32)uc; nblock++; es--; }; continue; } else { if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); /*-- uc = MTF ( nextSym-1 ) --*/ { Int32 ii, jj, kk, pp, lno, off; UInt32 nn; nn = (UInt32)(nextSym - 1); if (nn < MTFL_SIZE) { /* avoid general-case expense */ pp = s->mtfbase[0]; uc = s->mtfa[pp+nn]; while (nn > 3) { Int32 z = pp+nn; s->mtfa[(z) ] = s->mtfa[(z)-1]; s->mtfa[(z)-1] = s->mtfa[(z)-2]; s->mtfa[(z)-2] = s->mtfa[(z)-3]; s->mtfa[(z)-3] = s->mtfa[(z)-4]; nn -= 4; } while (nn > 0) { s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--; }; s->mtfa[pp] = uc; } else { /* general case */ lno = nn / MTFL_SIZE; off = nn % MTFL_SIZE; pp = s->mtfbase[lno] + off; uc = s->mtfa[pp]; while (pp > s->mtfbase[lno]) { s->mtfa[pp] = s->mtfa[pp-1]; pp--; }; s->mtfbase[lno]++; while (lno > 0) { s->mtfbase[lno]--; s->mtfa[s->mtfbase[lno]] = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1]; lno--; } s->mtfbase[0]--; s->mtfa[s->mtfbase[0]] = uc; if (s->mtfbase[0] == 0) { kk = MTFA_SIZE-1; for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) { for (jj = MTFL_SIZE-1; jj >= 0; jj--) { s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj]; kk--; } s->mtfbase[ii] = kk + 1; } } } } /*-- end uc = MTF ( nextSym-1 ) --*/ s->unzftab[s->seqToUnseq[uc]]++; if (s->smallDecompress) s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]); nblock++; GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym); continue; } } /* Now we know what nblock is, we can do a better sanity check on s->origPtr. */ if (s->origPtr < 0 || s->origPtr >= nblock) RETURN(BZ_DATA_ERROR); /*-- Set up cftab to facilitate generation of T^(-1) --*/ /* Check: unzftab entries in range. */ for (i = 0; i <= 255; i++) { if (s->unzftab[i] < 0 || s->unzftab[i] > nblock) RETURN(BZ_DATA_ERROR); } /* Actually generate cftab. */ s->cftab[0] = 0; for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1]; for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1]; /* Check: cftab entries in range. */ for (i = 0; i <= 256; i++) { if (s->cftab[i] < 0 || s->cftab[i] > nblock) { /* s->cftab[i] can legitimately be == nblock */ RETURN(BZ_DATA_ERROR); } } /* Check: cftab entries non-descending. */ for (i = 1; i <= 256; i++) { if (s->cftab[i-1] > s->cftab[i]) { RETURN(BZ_DATA_ERROR); } } s->state_out_len = 0; s->state_out_ch = 0; BZ_INITIALISE_CRC ( s->calculatedBlockCRC ); s->state = BZ_X_OUTPUT; if (s->verbosity >= 2) VPrintf0 ( "rt+rld" ); if (s->smallDecompress) { /*-- Make a copy of cftab, used in generation of T --*/ for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i]; /*-- compute the T vector --*/ for (i = 0; i < nblock; i++) { uc = (UChar)(s->ll16[i]); SET_LL(i, s->cftabCopy[uc]); s->cftabCopy[uc]++; } /*-- Compute T^(-1) by pointer reversal on T --*/ i = s->origPtr; j = GET_LL(i); do { Int32 tmp = GET_LL(j); SET_LL(j, i); i = j; j = tmp; } while (i != s->origPtr); s->tPos = s->origPtr; s->nblock_used = 0; if (s->blockRandomised) { BZ_RAND_INIT_MASK; BZ_GET_SMALL(s->k0); s->nblock_used++; BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; } else { BZ_GET_SMALL(s->k0); s->nblock_used++; } } else { /*-- compute the T^(-1) vector --*/ for (i = 0; i < nblock; i++) { uc = (UChar)(s->tt[i] & 0xff); s->tt[s->cftab[uc]] |= (i << 8); s->cftab[uc]++; } s->tPos = s->tt[s->origPtr] >> 8; s->nblock_used = 0; if (s->blockRandomised) { BZ_RAND_INIT_MASK; BZ_GET_FAST(s->k0); s->nblock_used++; BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; } else { BZ_GET_FAST(s->k0); s->nblock_used++; } } RETURN(BZ_OK); endhdr_2: GET_UCHAR(BZ_X_ENDHDR_2, uc); if (uc != 0x72) RETURN(BZ_DATA_ERROR); GET_UCHAR(BZ_X_ENDHDR_3, uc); if (uc != 0x45) RETURN(BZ_DATA_ERROR); GET_UCHAR(BZ_X_ENDHDR_4, uc); if (uc != 0x38) RETURN(BZ_DATA_ERROR); GET_UCHAR(BZ_X_ENDHDR_5, uc); if (uc != 0x50) RETURN(BZ_DATA_ERROR); GET_UCHAR(BZ_X_ENDHDR_6, uc); if (uc != 0x90) RETURN(BZ_DATA_ERROR); s->storedCombinedCRC = 0; GET_UCHAR(BZ_X_CCRC_1, uc); s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); GET_UCHAR(BZ_X_CCRC_2, uc); s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); GET_UCHAR(BZ_X_CCRC_3, uc); s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); GET_UCHAR(BZ_X_CCRC_4, uc); s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); s->state = BZ_X_IDLE; RETURN(BZ_STREAM_END); default: AssertH ( False, 4001 ); } AssertH ( False, 4002 ); save_state_and_return: s->save_i = i; s->save_j = j; s->save_t = t; s->save_alphaSize = alphaSize; s->save_nGroups = nGroups; s->save_nSelectors = nSelectors; s->save_EOB = EOB; s->save_groupNo = groupNo; s->save_groupPos = groupPos; s->save_nextSym = nextSym; s->save_nblockMAX = nblockMAX; s->save_nblock = nblock; s->save_es = es; s->save_N = N; s->save_curr = curr; s->save_zt = zt; s->save_zn = zn; s->save_zvec = zvec; s->save_zj = zj; s->save_gSel = gSel; s->save_gMinlen = gMinlen; s->save_gLimit = gLimit; s->save_gBase = gBase; s->save_gPerm = gPerm; return retVal; } /*-------------------------------------------------------------*/ /*--- end decompress.c ---*/ /*-------------------------------------------------------------*/ gtkwave-3.3.66/src/libbz2/Makefile.am0000664000076400007640000000033711523063250016606 0ustar bybellbybell## -*- makefile -*- ## noinst_LIBRARIES= libbz2.a libbz2_a_SOURCES= blocksort.c bzlib.h compress.c decompress.c randtable.c \ bzlib.c bzlib_private.h crctable.c huffman.c EXTRA_DIST= bzlib.h LICENSE gtkwave-3.3.66/src/libbz2/crctable.c0000664000076400007640000001132211523063250016471 0ustar bybellbybell /*-------------------------------------------------------------*/ /*--- Table for doing CRCs ---*/ /*--- crctable.c ---*/ /*-------------------------------------------------------------*/ /* ------------------------------------------------------------------ This file is part of bzip2/libbzip2, a program and library for lossless, block-sorting data compression. bzip2/libbzip2 version 1.0.6 of 6 September 2010 Copyright (C) 1996-2010 Julian Seward Please read the WARNING, DISCLAIMER and PATENTS sections in the README file. This program is released under the terms of the license contained in the file LICENSE. ------------------------------------------------------------------ */ #include "bzlib_private.h" /*-- I think this is an implementation of the AUTODIN-II, Ethernet & FDDI 32-bit CRC standard. Vaguely derived from code by Rob Warnock, in Section 51 of the comp.compression FAQ. --*/ UInt32 BZ2_crc32Table[256] = { /*-- Ugly, innit? --*/ 0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L, 0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L, 0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L, 0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL, 0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L, 0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L, 0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L, 0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL, 0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L, 0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L, 0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L, 0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL, 0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L, 0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L, 0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L, 0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL, 0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL, 0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L, 0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L, 0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL, 0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL, 0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L, 0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L, 0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL, 0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL, 0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L, 0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L, 0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL, 0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL, 0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L, 0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L, 0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL, 0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L, 0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL, 0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL, 0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L, 0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L, 0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL, 0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL, 0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L, 0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L, 0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL, 0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL, 0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L, 0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L, 0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL, 0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL, 0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L, 0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L, 0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL, 0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L, 0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L, 0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L, 0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL, 0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L, 0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L, 0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L, 0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL, 0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L, 0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L, 0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L, 0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL, 0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L, 0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L }; /*-------------------------------------------------------------*/ /*--- end crctable.c ---*/ /*-------------------------------------------------------------*/ gtkwave-3.3.66/src/libbz2/bzlib.c0000664000076400007640000013165311523063250016026 0ustar bybellbybell /*-------------------------------------------------------------*/ /*--- Library top-level functions. ---*/ /*--- bzlib.c ---*/ /*-------------------------------------------------------------*/ /* ------------------------------------------------------------------ This file is part of bzip2/libbzip2, a program and library for lossless, block-sorting data compression. bzip2/libbzip2 version 1.0.6 of 6 September 2010 Copyright (C) 1996-2010 Julian Seward Please read the WARNING, DISCLAIMER and PATENTS sections in the README file. This program is released under the terms of the license contained in the file LICENSE. ------------------------------------------------------------------ */ /* CHANGES 0.9.0 -- original version. 0.9.0a/b -- no changes in this file. 0.9.0c -- made zero-length BZ_FLUSH work correctly in bzCompress(). fixed bzWrite/bzRead to ignore zero-length requests. fixed bzread to correctly handle read requests after EOF. wrong parameter order in call to bzDecompressInit in bzBuffToBuffDecompress. Fixed. */ #include "bzlib_private.h" /*---------------------------------------------------*/ /*--- Compression stuff ---*/ /*---------------------------------------------------*/ /*---------------------------------------------------*/ #ifndef BZ_NO_STDIO void BZ2_bz__AssertH__fail ( int errcode ) { fprintf(stderr, "\n\nbzip2/libbzip2: internal error number %d.\n" "This is a bug in bzip2/libbzip2, %s.\n" "Please report it to me at: jseward@bzip.org. If this happened\n" "when you were using some program which uses libbzip2 as a\n" "component, you should also report this bug to the author(s)\n" "of that program. Please make an effort to report this bug;\n" "timely and accurate bug reports eventually lead to higher\n" "quality software. Thanks. Julian Seward, 10 December 2007.\n\n", errcode, BZ2_bzlibVersion() ); if (errcode == 1007) { fprintf(stderr, "\n*** A special note about internal error number 1007 ***\n" "\n" "Experience suggests that a common cause of i.e. 1007\n" "is unreliable memory or other hardware. The 1007 assertion\n" "just happens to cross-check the results of huge numbers of\n" "memory reads/writes, and so acts (unintendedly) as a stress\n" "test of your memory system.\n" "\n" "I suggest the following: try compressing the file again,\n" "possibly monitoring progress in detail with the -vv flag.\n" "\n" "* If the error cannot be reproduced, and/or happens at different\n" " points in compression, you may have a flaky memory system.\n" " Try a memory-test program. I have used Memtest86\n" " (www.memtest86.com). At the time of writing it is free (GPLd).\n" " Memtest86 tests memory much more thorougly than your BIOSs\n" " power-on test, and may find failures that the BIOS doesn't.\n" "\n" "* If the error can be repeatably reproduced, this is a bug in\n" " bzip2, and I would very much like to hear about it. Please\n" " let me know, and, ideally, save a copy of the file causing the\n" " problem -- without which I will be unable to investigate it.\n" "\n" ); } exit(3); } #endif /*---------------------------------------------------*/ static int bz_config_ok ( void ) { if (sizeof(int) != 4) return 0; if (sizeof(short) != 2) return 0; if (sizeof(char) != 1) return 0; return 1; } /*---------------------------------------------------*/ static void* default_bzalloc ( void* opaque, Int32 items, Int32 size ) { void* v = malloc ( items * size ); return v; } static void default_bzfree ( void* opaque, void* addr ) { if (addr != NULL) free ( addr ); } /*---------------------------------------------------*/ static void prepare_new_block ( EState* s ) { Int32 i; s->nblock = 0; s->numZ = 0; s->state_out_pos = 0; BZ_INITIALISE_CRC ( s->blockCRC ); for (i = 0; i < 256; i++) s->inUse[i] = False; s->blockNo++; } /*---------------------------------------------------*/ static void init_RL ( EState* s ) { s->state_in_ch = 256; s->state_in_len = 0; } static Bool isempty_RL ( EState* s ) { if (s->state_in_ch < 256 && s->state_in_len > 0) return False; else return True; } /*---------------------------------------------------*/ int BZ_API(BZ2_bzCompressInit) ( bz_stream* strm, int blockSize100k, int verbosity, int workFactor ) { Int32 n; EState* s; if (!bz_config_ok()) return BZ_CONFIG_ERROR; if (strm == NULL || blockSize100k < 1 || blockSize100k > 9 || workFactor < 0 || workFactor > 250) return BZ_PARAM_ERROR; if (workFactor == 0) workFactor = 30; if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc; if (strm->bzfree == NULL) strm->bzfree = default_bzfree; s = BZALLOC( sizeof(EState) ); if (s == NULL) return BZ_MEM_ERROR; s->strm = strm; s->arr1 = NULL; s->arr2 = NULL; s->ftab = NULL; n = 100000 * blockSize100k; s->arr1 = BZALLOC( n * sizeof(UInt32) ); s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) ); s->ftab = BZALLOC( 65537 * sizeof(UInt32) ); if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) { if (s->arr1 != NULL) BZFREE(s->arr1); if (s->arr2 != NULL) BZFREE(s->arr2); if (s->ftab != NULL) BZFREE(s->ftab); if (s != NULL) BZFREE(s); return BZ_MEM_ERROR; } s->blockNo = 0; s->state = BZ_S_INPUT; s->mode = BZ_M_RUNNING; s->combinedCRC = 0; s->blockSize100k = blockSize100k; s->nblockMAX = 100000 * blockSize100k - 19; s->verbosity = verbosity; s->workFactor = workFactor; s->block = (UChar*)s->arr2; s->mtfv = (UInt16*)s->arr1; s->zbits = NULL; s->ptr = (UInt32*)s->arr1; strm->state = s; strm->total_in_lo32 = 0; strm->total_in_hi32 = 0; strm->total_out_lo32 = 0; strm->total_out_hi32 = 0; init_RL ( s ); prepare_new_block ( s ); return BZ_OK; } /*---------------------------------------------------*/ static void add_pair_to_block ( EState* s ) { Int32 i; UChar ch = (UChar)(s->state_in_ch); for (i = 0; i < s->state_in_len; i++) { BZ_UPDATE_CRC( s->blockCRC, ch ); } s->inUse[s->state_in_ch] = True; switch (s->state_in_len) { case 1: s->block[s->nblock] = (UChar)ch; s->nblock++; break; case 2: s->block[s->nblock] = (UChar)ch; s->nblock++; s->block[s->nblock] = (UChar)ch; s->nblock++; break; case 3: s->block[s->nblock] = (UChar)ch; s->nblock++; s->block[s->nblock] = (UChar)ch; s->nblock++; s->block[s->nblock] = (UChar)ch; s->nblock++; break; default: s->inUse[s->state_in_len-4] = True; s->block[s->nblock] = (UChar)ch; s->nblock++; s->block[s->nblock] = (UChar)ch; s->nblock++; s->block[s->nblock] = (UChar)ch; s->nblock++; s->block[s->nblock] = (UChar)ch; s->nblock++; s->block[s->nblock] = ((UChar)(s->state_in_len-4)); s->nblock++; break; } } /*---------------------------------------------------*/ static void flush_RL ( EState* s ) { if (s->state_in_ch < 256) add_pair_to_block ( s ); init_RL ( s ); } /*---------------------------------------------------*/ #define ADD_CHAR_TO_BLOCK(zs,zchh0) \ { \ UInt32 zchh = (UInt32)(zchh0); \ /*-- fast track the common case --*/ \ if (zchh != zs->state_in_ch && \ zs->state_in_len == 1) { \ UChar ch = (UChar)(zs->state_in_ch); \ BZ_UPDATE_CRC( zs->blockCRC, ch ); \ zs->inUse[zs->state_in_ch] = True; \ zs->block[zs->nblock] = (UChar)ch; \ zs->nblock++; \ zs->state_in_ch = zchh; \ } \ else \ /*-- general, uncommon cases --*/ \ if (zchh != zs->state_in_ch || \ zs->state_in_len == 255) { \ if (zs->state_in_ch < 256) \ add_pair_to_block ( zs ); \ zs->state_in_ch = zchh; \ zs->state_in_len = 1; \ } else { \ zs->state_in_len++; \ } \ } /*---------------------------------------------------*/ static Bool copy_input_until_stop ( EState* s ) { Bool progress_in = False; if (s->mode == BZ_M_RUNNING) { /*-- fast track the common case --*/ while (True) { /*-- block full? --*/ if (s->nblock >= s->nblockMAX) break; /*-- no input? --*/ if (s->strm->avail_in == 0) break; progress_in = True; ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) ); s->strm->next_in++; s->strm->avail_in--; s->strm->total_in_lo32++; if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++; } } else { /*-- general, uncommon case --*/ while (True) { /*-- block full? --*/ if (s->nblock >= s->nblockMAX) break; /*-- no input? --*/ if (s->strm->avail_in == 0) break; /*-- flush/finish end? --*/ if (s->avail_in_expect == 0) break; progress_in = True; ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) ); s->strm->next_in++; s->strm->avail_in--; s->strm->total_in_lo32++; if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++; s->avail_in_expect--; } } return progress_in; } /*---------------------------------------------------*/ static Bool copy_output_until_stop ( EState* s ) { Bool progress_out = False; while (True) { /*-- no output space? --*/ if (s->strm->avail_out == 0) break; /*-- block done? --*/ if (s->state_out_pos >= s->numZ) break; progress_out = True; *(s->strm->next_out) = s->zbits[s->state_out_pos]; s->state_out_pos++; s->strm->avail_out--; s->strm->next_out++; s->strm->total_out_lo32++; if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++; } return progress_out; } /*---------------------------------------------------*/ static Bool handle_compress ( bz_stream* strm ) { Bool progress_in = False; Bool progress_out = False; EState* s = strm->state; while (True) { if (s->state == BZ_S_OUTPUT) { progress_out |= copy_output_until_stop ( s ); if (s->state_out_pos < s->numZ) break; if (s->mode == BZ_M_FINISHING && s->avail_in_expect == 0 && isempty_RL(s)) break; prepare_new_block ( s ); s->state = BZ_S_INPUT; if (s->mode == BZ_M_FLUSHING && s->avail_in_expect == 0 && isempty_RL(s)) break; } if (s->state == BZ_S_INPUT) { progress_in |= copy_input_until_stop ( s ); if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) { flush_RL ( s ); BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) ); s->state = BZ_S_OUTPUT; } else if (s->nblock >= s->nblockMAX) { BZ2_compressBlock ( s, False ); s->state = BZ_S_OUTPUT; } else if (s->strm->avail_in == 0) { break; } } } return progress_in || progress_out; } /*---------------------------------------------------*/ int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action ) { Bool progress; EState* s; if (strm == NULL) return BZ_PARAM_ERROR; s = strm->state; if (s == NULL) return BZ_PARAM_ERROR; if (s->strm != strm) return BZ_PARAM_ERROR; preswitch: switch (s->mode) { case BZ_M_IDLE: return BZ_SEQUENCE_ERROR; case BZ_M_RUNNING: if (action == BZ_RUN) { progress = handle_compress ( strm ); return progress ? BZ_RUN_OK : BZ_PARAM_ERROR; } else if (action == BZ_FLUSH) { s->avail_in_expect = strm->avail_in; s->mode = BZ_M_FLUSHING; goto preswitch; } else if (action == BZ_FINISH) { s->avail_in_expect = strm->avail_in; s->mode = BZ_M_FINISHING; goto preswitch; } else return BZ_PARAM_ERROR; case BZ_M_FLUSHING: if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR; if (s->avail_in_expect != s->strm->avail_in) return BZ_SEQUENCE_ERROR; progress = handle_compress ( strm ); if (s->avail_in_expect > 0 || !isempty_RL(s) || s->state_out_pos < s->numZ) return BZ_FLUSH_OK; s->mode = BZ_M_RUNNING; return BZ_RUN_OK; case BZ_M_FINISHING: if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR; if (s->avail_in_expect != s->strm->avail_in) return BZ_SEQUENCE_ERROR; progress = handle_compress ( strm ); if (!progress) return BZ_SEQUENCE_ERROR; if (s->avail_in_expect > 0 || !isempty_RL(s) || s->state_out_pos < s->numZ) return BZ_FINISH_OK; s->mode = BZ_M_IDLE; return BZ_STREAM_END; } return BZ_OK; /*--not reached--*/ } /*---------------------------------------------------*/ int BZ_API(BZ2_bzCompressEnd) ( bz_stream *strm ) { EState* s; if (strm == NULL) return BZ_PARAM_ERROR; s = strm->state; if (s == NULL) return BZ_PARAM_ERROR; if (s->strm != strm) return BZ_PARAM_ERROR; if (s->arr1 != NULL) BZFREE(s->arr1); if (s->arr2 != NULL) BZFREE(s->arr2); if (s->ftab != NULL) BZFREE(s->ftab); BZFREE(strm->state); strm->state = NULL; return BZ_OK; } /*---------------------------------------------------*/ /*--- Decompression stuff ---*/ /*---------------------------------------------------*/ /*---------------------------------------------------*/ int BZ_API(BZ2_bzDecompressInit) ( bz_stream* strm, int verbosity, int small ) { DState* s; if (!bz_config_ok()) return BZ_CONFIG_ERROR; if (strm == NULL) return BZ_PARAM_ERROR; if (small != 0 && small != 1) return BZ_PARAM_ERROR; if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR; if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc; if (strm->bzfree == NULL) strm->bzfree = default_bzfree; s = BZALLOC( sizeof(DState) ); if (s == NULL) return BZ_MEM_ERROR; s->strm = strm; strm->state = s; s->state = BZ_X_MAGIC_1; s->bsLive = 0; s->bsBuff = 0; s->calculatedCombinedCRC = 0; strm->total_in_lo32 = 0; strm->total_in_hi32 = 0; strm->total_out_lo32 = 0; strm->total_out_hi32 = 0; s->smallDecompress = (Bool)small; s->ll4 = NULL; s->ll16 = NULL; s->tt = NULL; s->currBlockNo = 0; s->verbosity = verbosity; return BZ_OK; } /*---------------------------------------------------*/ /* Return True iff data corruption is discovered. Returns False if there is no problem. */ static Bool unRLE_obuf_to_output_FAST ( DState* s ) { UChar k1; if (s->blockRandomised) { while (True) { /* try to finish existing run */ while (True) { if (s->strm->avail_out == 0) return False; if (s->state_out_len == 0) break; *( (UChar*)(s->strm->next_out) ) = s->state_out_ch; BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch ); s->state_out_len--; s->strm->next_out++; s->strm->avail_out--; s->strm->total_out_lo32++; if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++; } /* can a new run be started? */ if (s->nblock_used == s->save_nblock+1) return False; /* Only caused by corrupt data stream? */ if (s->nblock_used > s->save_nblock+1) return True; s->state_out_len = 1; s->state_out_ch = s->k0; BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; k1 ^= BZ_RAND_MASK; s->nblock_used++; if (s->nblock_used == s->save_nblock+1) continue; if (k1 != s->k0) { s->k0 = k1; continue; }; s->state_out_len = 2; BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; k1 ^= BZ_RAND_MASK; s->nblock_used++; if (s->nblock_used == s->save_nblock+1) continue; if (k1 != s->k0) { s->k0 = k1; continue; }; s->state_out_len = 3; BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; k1 ^= BZ_RAND_MASK; s->nblock_used++; if (s->nblock_used == s->save_nblock+1) continue; if (k1 != s->k0) { s->k0 = k1; continue; }; BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; k1 ^= BZ_RAND_MASK; s->nblock_used++; s->state_out_len = ((Int32)k1) + 4; BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; s->nblock_used++; } } else { /* restore */ UInt32 c_calculatedBlockCRC = s->calculatedBlockCRC; UChar c_state_out_ch = s->state_out_ch; Int32 c_state_out_len = s->state_out_len; Int32 c_nblock_used = s->nblock_used; Int32 c_k0 = s->k0; UInt32* c_tt = s->tt; UInt32 c_tPos = s->tPos; char* cs_next_out = s->strm->next_out; unsigned int cs_avail_out = s->strm->avail_out; Int32 ro_blockSize100k = s->blockSize100k; /* end restore */ UInt32 avail_out_INIT = cs_avail_out; Int32 s_save_nblockPP = s->save_nblock+1; unsigned int total_out_lo32_old; while (True) { /* try to finish existing run */ if (c_state_out_len > 0) { while (True) { if (cs_avail_out == 0) goto return_notr; if (c_state_out_len == 1) break; *( (UChar*)(cs_next_out) ) = c_state_out_ch; BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch ); c_state_out_len--; cs_next_out++; cs_avail_out--; } s_state_out_len_eq_one: { if (cs_avail_out == 0) { c_state_out_len = 1; goto return_notr; }; *( (UChar*)(cs_next_out) ) = c_state_out_ch; BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch ); cs_next_out++; cs_avail_out--; } } /* Only caused by corrupt data stream? */ if (c_nblock_used > s_save_nblockPP) return True; /* can a new run be started? */ if (c_nblock_used == s_save_nblockPP) { c_state_out_len = 0; goto return_notr; }; c_state_out_ch = c_k0; BZ_GET_FAST_C(k1); c_nblock_used++; if (k1 != c_k0) { c_k0 = k1; goto s_state_out_len_eq_one; }; if (c_nblock_used == s_save_nblockPP) goto s_state_out_len_eq_one; c_state_out_len = 2; BZ_GET_FAST_C(k1); c_nblock_used++; if (c_nblock_used == s_save_nblockPP) continue; if (k1 != c_k0) { c_k0 = k1; continue; }; c_state_out_len = 3; BZ_GET_FAST_C(k1); c_nblock_used++; if (c_nblock_used == s_save_nblockPP) continue; if (k1 != c_k0) { c_k0 = k1; continue; }; BZ_GET_FAST_C(k1); c_nblock_used++; c_state_out_len = ((Int32)k1) + 4; BZ_GET_FAST_C(c_k0); c_nblock_used++; } return_notr: total_out_lo32_old = s->strm->total_out_lo32; s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out); if (s->strm->total_out_lo32 < total_out_lo32_old) s->strm->total_out_hi32++; /* save */ s->calculatedBlockCRC = c_calculatedBlockCRC; s->state_out_ch = c_state_out_ch; s->state_out_len = c_state_out_len; s->nblock_used = c_nblock_used; s->k0 = c_k0; s->tt = c_tt; s->tPos = c_tPos; s->strm->next_out = cs_next_out; s->strm->avail_out = cs_avail_out; /* end save */ } return False; } /*---------------------------------------------------*/ __inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab ) { Int32 nb, na, mid; nb = 0; na = 256; do { mid = (nb + na) >> 1; if (indx >= cftab[mid]) nb = mid; else na = mid; } while (na - nb != 1); return nb; } /*---------------------------------------------------*/ /* Return True iff data corruption is discovered. Returns False if there is no problem. */ static Bool unRLE_obuf_to_output_SMALL ( DState* s ) { UChar k1; if (s->blockRandomised) { while (True) { /* try to finish existing run */ while (True) { if (s->strm->avail_out == 0) return False; if (s->state_out_len == 0) break; *( (UChar*)(s->strm->next_out) ) = s->state_out_ch; BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch ); s->state_out_len--; s->strm->next_out++; s->strm->avail_out--; s->strm->total_out_lo32++; if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++; } /* can a new run be started? */ if (s->nblock_used == s->save_nblock+1) return False; /* Only caused by corrupt data stream? */ if (s->nblock_used > s->save_nblock+1) return True; s->state_out_len = 1; s->state_out_ch = s->k0; BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; k1 ^= BZ_RAND_MASK; s->nblock_used++; if (s->nblock_used == s->save_nblock+1) continue; if (k1 != s->k0) { s->k0 = k1; continue; }; s->state_out_len = 2; BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; k1 ^= BZ_RAND_MASK; s->nblock_used++; if (s->nblock_used == s->save_nblock+1) continue; if (k1 != s->k0) { s->k0 = k1; continue; }; s->state_out_len = 3; BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; k1 ^= BZ_RAND_MASK; s->nblock_used++; if (s->nblock_used == s->save_nblock+1) continue; if (k1 != s->k0) { s->k0 = k1; continue; }; BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; k1 ^= BZ_RAND_MASK; s->nblock_used++; s->state_out_len = ((Int32)k1) + 4; BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; s->nblock_used++; } } else { while (True) { /* try to finish existing run */ while (True) { if (s->strm->avail_out == 0) return False; if (s->state_out_len == 0) break; *( (UChar*)(s->strm->next_out) ) = s->state_out_ch; BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch ); s->state_out_len--; s->strm->next_out++; s->strm->avail_out--; s->strm->total_out_lo32++; if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++; } /* can a new run be started? */ if (s->nblock_used == s->save_nblock+1) return False; /* Only caused by corrupt data stream? */ if (s->nblock_used > s->save_nblock+1) return True; s->state_out_len = 1; s->state_out_ch = s->k0; BZ_GET_SMALL(k1); s->nblock_used++; if (s->nblock_used == s->save_nblock+1) continue; if (k1 != s->k0) { s->k0 = k1; continue; }; s->state_out_len = 2; BZ_GET_SMALL(k1); s->nblock_used++; if (s->nblock_used == s->save_nblock+1) continue; if (k1 != s->k0) { s->k0 = k1; continue; }; s->state_out_len = 3; BZ_GET_SMALL(k1); s->nblock_used++; if (s->nblock_used == s->save_nblock+1) continue; if (k1 != s->k0) { s->k0 = k1; continue; }; BZ_GET_SMALL(k1); s->nblock_used++; s->state_out_len = ((Int32)k1) + 4; BZ_GET_SMALL(s->k0); s->nblock_used++; } } } /*---------------------------------------------------*/ int BZ_API(BZ2_bzDecompress) ( bz_stream *strm ) { Bool corrupt; DState* s; if (strm == NULL) return BZ_PARAM_ERROR; s = strm->state; if (s == NULL) return BZ_PARAM_ERROR; if (s->strm != strm) return BZ_PARAM_ERROR; while (True) { if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR; if (s->state == BZ_X_OUTPUT) { if (s->smallDecompress) corrupt = unRLE_obuf_to_output_SMALL ( s ); else corrupt = unRLE_obuf_to_output_FAST ( s ); if (corrupt) return BZ_DATA_ERROR; if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) { BZ_FINALISE_CRC ( s->calculatedBlockCRC ); if (s->verbosity >= 3) VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC, s->calculatedBlockCRC ); if (s->verbosity >= 2) VPrintf0 ( "]" ); if (s->calculatedBlockCRC != s->storedBlockCRC) return BZ_DATA_ERROR; s->calculatedCombinedCRC = (s->calculatedCombinedCRC << 1) | (s->calculatedCombinedCRC >> 31); s->calculatedCombinedCRC ^= s->calculatedBlockCRC; s->state = BZ_X_BLKHDR_1; } else { return BZ_OK; } } if (s->state >= BZ_X_MAGIC_1) { Int32 r = BZ2_decompress ( s ); if (r == BZ_STREAM_END) { if (s->verbosity >= 3) VPrintf2 ( "\n combined CRCs: stored = 0x%08x, computed = 0x%08x", s->storedCombinedCRC, s->calculatedCombinedCRC ); if (s->calculatedCombinedCRC != s->storedCombinedCRC) return BZ_DATA_ERROR; return r; } if (s->state != BZ_X_OUTPUT) return r; } } AssertH ( 0, 6001 ); return 0; /*NOTREACHED*/ } /*---------------------------------------------------*/ int BZ_API(BZ2_bzDecompressEnd) ( bz_stream *strm ) { DState* s; if (strm == NULL) return BZ_PARAM_ERROR; s = strm->state; if (s == NULL) return BZ_PARAM_ERROR; if (s->strm != strm) return BZ_PARAM_ERROR; if (s->tt != NULL) BZFREE(s->tt); if (s->ll16 != NULL) BZFREE(s->ll16); if (s->ll4 != NULL) BZFREE(s->ll4); BZFREE(strm->state); strm->state = NULL; return BZ_OK; } #ifndef BZ_NO_STDIO /*---------------------------------------------------*/ /*--- File I/O stuff ---*/ /*---------------------------------------------------*/ #define BZ_SETERR(eee) \ { \ if (bzerror != NULL) *bzerror = eee; \ if (bzf != NULL) bzf->lastErr = eee; \ } typedef struct { FILE* handle; Char buf[BZ_MAX_UNUSED]; Int32 bufN; Bool writing; bz_stream strm; Int32 lastErr; Bool initialisedOk; } bzFile; /*---------------------------------------------*/ static Bool myfeof ( FILE* f ) { Int32 c = fgetc ( f ); if (c == EOF) return True; ungetc ( c, f ); return False; } /*---------------------------------------------------*/ BZFILE* BZ_API(BZ2_bzWriteOpen) ( int* bzerror, FILE* f, int blockSize100k, int verbosity, int workFactor ) { Int32 ret; bzFile* bzf = NULL; BZ_SETERR(BZ_OK); if (f == NULL || (blockSize100k < 1 || blockSize100k > 9) || (workFactor < 0 || workFactor > 250) || (verbosity < 0 || verbosity > 4)) { BZ_SETERR(BZ_PARAM_ERROR); return NULL; }; if (ferror(f)) { BZ_SETERR(BZ_IO_ERROR); return NULL; }; bzf = malloc ( sizeof(bzFile) ); if (bzf == NULL) { BZ_SETERR(BZ_MEM_ERROR); return NULL; }; BZ_SETERR(BZ_OK); bzf->initialisedOk = False; bzf->bufN = 0; bzf->handle = f; bzf->writing = True; bzf->strm.bzalloc = NULL; bzf->strm.bzfree = NULL; bzf->strm.opaque = NULL; if (workFactor == 0) workFactor = 30; ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k, verbosity, workFactor ); if (ret != BZ_OK) { BZ_SETERR(ret); free(bzf); return NULL; }; bzf->strm.avail_in = 0; bzf->initialisedOk = True; return bzf; } /*---------------------------------------------------*/ void BZ_API(BZ2_bzWrite) ( int* bzerror, BZFILE* b, void* buf, int len ) { Int32 n, n2, ret; bzFile* bzf = (bzFile*)b; BZ_SETERR(BZ_OK); if (bzf == NULL || buf == NULL || len < 0) { BZ_SETERR(BZ_PARAM_ERROR); return; }; if (!(bzf->writing)) { BZ_SETERR(BZ_SEQUENCE_ERROR); return; }; if (ferror(bzf->handle)) { BZ_SETERR(BZ_IO_ERROR); return; }; if (len == 0) { BZ_SETERR(BZ_OK); return; }; bzf->strm.avail_in = len; bzf->strm.next_in = buf; while (True) { bzf->strm.avail_out = BZ_MAX_UNUSED; bzf->strm.next_out = bzf->buf; ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN ); if (ret != BZ_RUN_OK) { BZ_SETERR(ret); return; }; if (bzf->strm.avail_out < BZ_MAX_UNUSED) { n = BZ_MAX_UNUSED - bzf->strm.avail_out; n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar), n, bzf->handle ); if (n != n2 || ferror(bzf->handle)) { BZ_SETERR(BZ_IO_ERROR); return; }; } if (bzf->strm.avail_in == 0) { BZ_SETERR(BZ_OK); return; }; } } /*---------------------------------------------------*/ void BZ_API(BZ2_bzWriteClose) ( int* bzerror, BZFILE* b, int abandon, unsigned int* nbytes_in, unsigned int* nbytes_out ) { BZ2_bzWriteClose64 ( bzerror, b, abandon, nbytes_in, NULL, nbytes_out, NULL ); } void BZ_API(BZ2_bzWriteClose64) ( int* bzerror, BZFILE* b, int abandon, unsigned int* nbytes_in_lo32, unsigned int* nbytes_in_hi32, unsigned int* nbytes_out_lo32, unsigned int* nbytes_out_hi32 ) { Int32 n, n2, ret; bzFile* bzf = (bzFile*)b; if (bzf == NULL) { BZ_SETERR(BZ_OK); return; }; if (!(bzf->writing)) { BZ_SETERR(BZ_SEQUENCE_ERROR); return; }; if (ferror(bzf->handle)) { BZ_SETERR(BZ_IO_ERROR); return; }; if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0; if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0; if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0; if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0; if ((!abandon) && bzf->lastErr == BZ_OK) { while (True) { bzf->strm.avail_out = BZ_MAX_UNUSED; bzf->strm.next_out = bzf->buf; ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH ); if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END) { BZ_SETERR(ret); return; }; if (bzf->strm.avail_out < BZ_MAX_UNUSED) { n = BZ_MAX_UNUSED - bzf->strm.avail_out; n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar), n, bzf->handle ); if (n != n2 || ferror(bzf->handle)) { BZ_SETERR(BZ_IO_ERROR); return; }; } if (ret == BZ_STREAM_END) break; } } if ( !abandon && !ferror ( bzf->handle ) ) { fflush ( bzf->handle ); if (ferror(bzf->handle)) { BZ_SETERR(BZ_IO_ERROR); return; }; } if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = bzf->strm.total_in_lo32; if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = bzf->strm.total_in_hi32; if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = bzf->strm.total_out_lo32; if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = bzf->strm.total_out_hi32; BZ_SETERR(BZ_OK); BZ2_bzCompressEnd ( &(bzf->strm) ); free ( bzf ); } /*---------------------------------------------------*/ BZFILE* BZ_API(BZ2_bzReadOpen) ( int* bzerror, FILE* f, int verbosity, int small, void* unused, int nUnused ) { bzFile* bzf = NULL; int ret; BZ_SETERR(BZ_OK); if (f == NULL || (small != 0 && small != 1) || (verbosity < 0 || verbosity > 4) || (unused == NULL && nUnused != 0) || (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED))) { BZ_SETERR(BZ_PARAM_ERROR); return NULL; }; if (ferror(f)) { BZ_SETERR(BZ_IO_ERROR); return NULL; }; bzf = malloc ( sizeof(bzFile) ); if (bzf == NULL) { BZ_SETERR(BZ_MEM_ERROR); return NULL; }; BZ_SETERR(BZ_OK); bzf->initialisedOk = False; bzf->handle = f; bzf->bufN = 0; bzf->writing = False; bzf->strm.bzalloc = NULL; bzf->strm.bzfree = NULL; bzf->strm.opaque = NULL; while (nUnused > 0) { bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++; unused = ((void*)( 1 + ((UChar*)(unused)) )); nUnused--; } ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small ); if (ret != BZ_OK) { BZ_SETERR(ret); free(bzf); return NULL; }; bzf->strm.avail_in = bzf->bufN; bzf->strm.next_in = bzf->buf; bzf->initialisedOk = True; return bzf; } /*---------------------------------------------------*/ void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b ) { bzFile* bzf = (bzFile*)b; BZ_SETERR(BZ_OK); if (bzf == NULL) { BZ_SETERR(BZ_OK); return; }; if (bzf->writing) { BZ_SETERR(BZ_SEQUENCE_ERROR); return; }; if (bzf->initialisedOk) (void)BZ2_bzDecompressEnd ( &(bzf->strm) ); free ( bzf ); } /*---------------------------------------------------*/ int BZ_API(BZ2_bzRead) ( int* bzerror, BZFILE* b, void* buf, int len ) { Int32 n, ret; bzFile* bzf = (bzFile*)b; BZ_SETERR(BZ_OK); if (bzf == NULL || buf == NULL || len < 0) { BZ_SETERR(BZ_PARAM_ERROR); return 0; }; if (bzf->writing) { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; }; if (len == 0) { BZ_SETERR(BZ_OK); return 0; }; bzf->strm.avail_out = len; bzf->strm.next_out = buf; while (True) { if (ferror(bzf->handle)) { BZ_SETERR(BZ_IO_ERROR); return 0; }; if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) { n = fread ( bzf->buf, sizeof(UChar), BZ_MAX_UNUSED, bzf->handle ); if (ferror(bzf->handle)) { BZ_SETERR(BZ_IO_ERROR); return 0; }; bzf->bufN = n; bzf->strm.avail_in = bzf->bufN; bzf->strm.next_in = bzf->buf; } ret = BZ2_bzDecompress ( &(bzf->strm) ); if (ret != BZ_OK && ret != BZ_STREAM_END) { BZ_SETERR(ret); return 0; }; if (ret == BZ_OK && myfeof(bzf->handle) && bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0) { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; }; if (ret == BZ_STREAM_END) { BZ_SETERR(BZ_STREAM_END); return len - bzf->strm.avail_out; }; if (bzf->strm.avail_out == 0) { BZ_SETERR(BZ_OK); return len; }; } return 0; /*not reached*/ } /*---------------------------------------------------*/ void BZ_API(BZ2_bzReadGetUnused) ( int* bzerror, BZFILE* b, void** unused, int* nUnused ) { bzFile* bzf = (bzFile*)b; if (bzf == NULL) { BZ_SETERR(BZ_PARAM_ERROR); return; }; if (bzf->lastErr != BZ_STREAM_END) { BZ_SETERR(BZ_SEQUENCE_ERROR); return; }; if (unused == NULL || nUnused == NULL) { BZ_SETERR(BZ_PARAM_ERROR); return; }; BZ_SETERR(BZ_OK); *nUnused = bzf->strm.avail_in; *unused = bzf->strm.next_in; } #endif /*---------------------------------------------------*/ /*--- Misc convenience stuff ---*/ /*---------------------------------------------------*/ /*---------------------------------------------------*/ int BZ_API(BZ2_bzBuffToBuffCompress) ( char* dest, unsigned int* destLen, char* source, unsigned int sourceLen, int blockSize100k, int verbosity, int workFactor ) { bz_stream strm; int ret; if (dest == NULL || destLen == NULL || source == NULL || blockSize100k < 1 || blockSize100k > 9 || verbosity < 0 || verbosity > 4 || workFactor < 0 || workFactor > 250) return BZ_PARAM_ERROR; if (workFactor == 0) workFactor = 30; strm.bzalloc = NULL; strm.bzfree = NULL; strm.opaque = NULL; ret = BZ2_bzCompressInit ( &strm, blockSize100k, verbosity, workFactor ); if (ret != BZ_OK) return ret; strm.next_in = source; strm.next_out = dest; strm.avail_in = sourceLen; strm.avail_out = *destLen; ret = BZ2_bzCompress ( &strm, BZ_FINISH ); if (ret == BZ_FINISH_OK) goto output_overflow; if (ret != BZ_STREAM_END) goto errhandler; /* normal termination */ *destLen -= strm.avail_out; BZ2_bzCompressEnd ( &strm ); return BZ_OK; output_overflow: BZ2_bzCompressEnd ( &strm ); return BZ_OUTBUFF_FULL; errhandler: BZ2_bzCompressEnd ( &strm ); return ret; } /*---------------------------------------------------*/ int BZ_API(BZ2_bzBuffToBuffDecompress) ( char* dest, unsigned int* destLen, char* source, unsigned int sourceLen, int small, int verbosity ) { bz_stream strm; int ret; if (dest == NULL || destLen == NULL || source == NULL || (small != 0 && small != 1) || verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR; strm.bzalloc = NULL; strm.bzfree = NULL; strm.opaque = NULL; ret = BZ2_bzDecompressInit ( &strm, verbosity, small ); if (ret != BZ_OK) return ret; strm.next_in = source; strm.next_out = dest; strm.avail_in = sourceLen; strm.avail_out = *destLen; ret = BZ2_bzDecompress ( &strm ); if (ret == BZ_OK) goto output_overflow_or_eof; if (ret != BZ_STREAM_END) goto errhandler; /* normal termination */ *destLen -= strm.avail_out; BZ2_bzDecompressEnd ( &strm ); return BZ_OK; output_overflow_or_eof: if (strm.avail_out > 0) { BZ2_bzDecompressEnd ( &strm ); return BZ_UNEXPECTED_EOF; } else { BZ2_bzDecompressEnd ( &strm ); return BZ_OUTBUFF_FULL; }; errhandler: BZ2_bzDecompressEnd ( &strm ); return ret; } /*---------------------------------------------------*/ /*-- Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp) to support better zlib compatibility. This code is not _officially_ part of libbzip2 (yet); I haven't tested it, documented it, or considered the threading-safeness of it. If this code breaks, please contact both Yoshioka and me. --*/ /*---------------------------------------------------*/ /*---------------------------------------------------*/ /*-- return version like "0.9.5d, 4-Sept-1999". --*/ const char * BZ_API(BZ2_bzlibVersion)(void) { return BZ_VERSION; } #ifndef BZ_NO_STDIO /*---------------------------------------------------*/ #if defined(_WIN32) || defined(OS2) || defined(MSDOS) # include # include # define SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY) #else # define SET_BINARY_MODE(file) #endif static BZFILE * bzopen_or_bzdopen ( const char *path, /* no use when bzdopen */ int fd, /* no use when bzdopen */ const char *mode, int open_mode) /* bzopen: 0, bzdopen:1 */ { int bzerr; char unused[BZ_MAX_UNUSED]; int blockSize100k = 9; int writing = 0; char mode2[10] = ""; FILE *fp = NULL; BZFILE *bzfp = NULL; int verbosity = 0; int workFactor = 30; int smallMode = 0; int nUnused = 0; if (mode == NULL) return NULL; while (*mode) { switch (*mode) { case 'r': writing = 0; break; case 'w': writing = 1; break; case 's': smallMode = 1; break; default: if (isdigit((int)(*mode))) { blockSize100k = *mode-BZ_HDR_0; } } mode++; } strcat(mode2, writing ? "w" : "r" ); strcat(mode2,"b"); /* binary mode */ if (open_mode==0) { if (path==NULL || strcmp(path,"")==0) { fp = (writing ? stdout : stdin); SET_BINARY_MODE(fp); } else { fp = fopen(path,mode2); } } else { #ifdef BZ_STRICT_ANSI fp = NULL; #else fp = fdopen(fd,mode2); #endif } if (fp == NULL) return NULL; if (writing) { /* Guard against total chaos and anarchy -- JRS */ if (blockSize100k < 1) blockSize100k = 1; if (blockSize100k > 9) blockSize100k = 9; bzfp = BZ2_bzWriteOpen(&bzerr,fp,blockSize100k, verbosity,workFactor); } else { bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode, unused,nUnused); } if (bzfp == NULL) { if (fp != stdin && fp != stdout) fclose(fp); return NULL; } return bzfp; } /*---------------------------------------------------*/ /*-- open file for read or write. ex) bzopen("file","w9") case path="" or NULL => use stdin or stdout. --*/ BZFILE * BZ_API(BZ2_bzopen) ( const char *path, const char *mode ) { return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0); } /*---------------------------------------------------*/ BZFILE * BZ_API(BZ2_bzdopen) ( int fd, const char *mode ) { return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1); } /*---------------------------------------------------*/ int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len ) { int bzerr, nread; if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0; nread = BZ2_bzRead(&bzerr,b,buf,len); if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) { return nread; } else { return -1; } } /*---------------------------------------------------*/ int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len ) { int bzerr; BZ2_bzWrite(&bzerr,b,buf,len); if(bzerr == BZ_OK){ return len; }else{ return -1; } } /*---------------------------------------------------*/ int BZ_API(BZ2_bzflush) (BZFILE *b) { /* do nothing now... */ return 0; } /*---------------------------------------------------*/ void BZ_API(BZ2_bzclose) (BZFILE* b) { int bzerr; FILE *fp; if (b==NULL) {return;} fp = ((bzFile *)b)->handle; if(((bzFile*)b)->writing){ BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL); if(bzerr != BZ_OK){ BZ2_bzWriteClose(NULL,b,1,NULL,NULL); } }else{ BZ2_bzReadClose(&bzerr,b); } if(fp!=stdin && fp!=stdout){ fclose(fp); } } /*---------------------------------------------------*/ /*-- return last error code --*/ static const char *bzerrorstrings[] = { "OK" ,"SEQUENCE_ERROR" ,"PARAM_ERROR" ,"MEM_ERROR" ,"DATA_ERROR" ,"DATA_ERROR_MAGIC" ,"IO_ERROR" ,"UNEXPECTED_EOF" ,"OUTBUFF_FULL" ,"CONFIG_ERROR" ,"???" /* for future */ ,"???" /* for future */ ,"???" /* for future */ ,"???" /* for future */ ,"???" /* for future */ ,"???" /* for future */ }; const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum) { int err = ((bzFile *)b)->lastErr; if(err>0) err = 0; *errnum = err; return bzerrorstrings[err*-1]; } #endif /*-------------------------------------------------------------*/ /*--- end bzlib.c ---*/ /*-------------------------------------------------------------*/ gtkwave-3.3.66/src/libbz2/blocksort.c0000664000076400007640000007374611523063250016736 0ustar bybellbybell /*-------------------------------------------------------------*/ /*--- Block sorting machinery ---*/ /*--- blocksort.c ---*/ /*-------------------------------------------------------------*/ /* ------------------------------------------------------------------ This file is part of bzip2/libbzip2, a program and library for lossless, block-sorting data compression. bzip2/libbzip2 version 1.0.6 of 6 September 2010 Copyright (C) 1996-2010 Julian Seward Please read the WARNING, DISCLAIMER and PATENTS sections in the README file. This program is released under the terms of the license contained in the file LICENSE. ------------------------------------------------------------------ */ #include "bzlib_private.h" /*---------------------------------------------*/ /*--- Fallback O(N log(N)^2) sorting ---*/ /*--- algorithm, for repetitive blocks ---*/ /*---------------------------------------------*/ /*---------------------------------------------*/ static __inline__ void fallbackSimpleSort ( UInt32* fmap, UInt32* eclass, Int32 lo, Int32 hi ) { Int32 i, j, tmp; UInt32 ec_tmp; if (lo == hi) return; if (hi - lo > 3) { for ( i = hi-4; i >= lo; i-- ) { tmp = fmap[i]; ec_tmp = eclass[tmp]; for ( j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4 ) fmap[j-4] = fmap[j]; fmap[j-4] = tmp; } } for ( i = hi-1; i >= lo; i-- ) { tmp = fmap[i]; ec_tmp = eclass[tmp]; for ( j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++ ) fmap[j-1] = fmap[j]; fmap[j-1] = tmp; } } /*---------------------------------------------*/ #define fswap(zz1, zz2) \ { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; } #define fvswap(zzp1, zzp2, zzn) \ { \ Int32 yyp1 = (zzp1); \ Int32 yyp2 = (zzp2); \ Int32 yyn = (zzn); \ while (yyn > 0) { \ fswap(fmap[yyp1], fmap[yyp2]); \ yyp1++; yyp2++; yyn--; \ } \ } #define fmin(a,b) ((a) < (b)) ? (a) : (b) #define fpush(lz,hz) { stackLo[sp] = lz; \ stackHi[sp] = hz; \ sp++; } #define fpop(lz,hz) { sp--; \ lz = stackLo[sp]; \ hz = stackHi[sp]; } #define FALLBACK_QSORT_SMALL_THRESH 10 #define FALLBACK_QSORT_STACK_SIZE 100 static void fallbackQSort3 ( UInt32* fmap, UInt32* eclass, Int32 loSt, Int32 hiSt ) { Int32 unLo, unHi, ltLo, gtHi, n, m; Int32 sp, lo, hi; UInt32 med, r, r3; Int32 stackLo[FALLBACK_QSORT_STACK_SIZE]; Int32 stackHi[FALLBACK_QSORT_STACK_SIZE]; r = 0; sp = 0; fpush ( loSt, hiSt ); while (sp > 0) { AssertH ( sp < FALLBACK_QSORT_STACK_SIZE - 1, 1004 ); fpop ( lo, hi ); if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) { fallbackSimpleSort ( fmap, eclass, lo, hi ); continue; } /* Random partitioning. Median of 3 sometimes fails to avoid bad cases. Median of 9 seems to help but looks rather expensive. This too seems to work but is cheaper. Guidance for the magic constants 7621 and 32768 is taken from Sedgewick's algorithms book, chapter 35. */ r = ((r * 7621) + 1) % 32768; r3 = r % 3; if (r3 == 0) med = eclass[fmap[lo]]; else if (r3 == 1) med = eclass[fmap[(lo+hi)>>1]]; else med = eclass[fmap[hi]]; unLo = ltLo = lo; unHi = gtHi = hi; while (1) { while (1) { if (unLo > unHi) break; n = (Int32)eclass[fmap[unLo]] - (Int32)med; if (n == 0) { fswap(fmap[unLo], fmap[ltLo]); ltLo++; unLo++; continue; }; if (n > 0) break; unLo++; } while (1) { if (unLo > unHi) break; n = (Int32)eclass[fmap[unHi]] - (Int32)med; if (n == 0) { fswap(fmap[unHi], fmap[gtHi]); gtHi--; unHi--; continue; }; if (n < 0) break; unHi--; } if (unLo > unHi) break; fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--; } AssertD ( unHi == unLo-1, "fallbackQSort3(2)" ); if (gtHi < ltLo) continue; n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n); m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m); n = lo + unLo - ltLo - 1; m = hi - (gtHi - unHi) + 1; if (n - lo > hi - m) { fpush ( lo, n ); fpush ( m, hi ); } else { fpush ( m, hi ); fpush ( lo, n ); } } } #undef fmin #undef fpush #undef fpop #undef fswap #undef fvswap #undef FALLBACK_QSORT_SMALL_THRESH #undef FALLBACK_QSORT_STACK_SIZE /*---------------------------------------------*/ /* Pre: nblock > 0 eclass exists for [0 .. nblock-1] ((UChar*)eclass) [0 .. nblock-1] holds block ptr exists for [0 .. nblock-1] Post: ((UChar*)eclass) [0 .. nblock-1] holds block All other areas of eclass destroyed fmap [0 .. nblock-1] holds sorted order bhtab [ 0 .. 2+(nblock/32) ] destroyed */ #define SET_BH(zz) bhtab[(zz) >> 5] |= (1 << ((zz) & 31)) #define CLEAR_BH(zz) bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31)) #define ISSET_BH(zz) (bhtab[(zz) >> 5] & (1 << ((zz) & 31))) #define WORD_BH(zz) bhtab[(zz) >> 5] #define UNALIGNED_BH(zz) ((zz) & 0x01f) static void fallbackSort ( UInt32* fmap, UInt32* eclass, UInt32* bhtab, Int32 nblock, Int32 verb ) { Int32 ftab[257]; Int32 ftabCopy[256]; Int32 H, i, j, k, l, r, cc, cc1; Int32 nNotDone; Int32 nBhtab; UChar* eclass8 = (UChar*)eclass; /*-- Initial 1-char radix sort to generate initial fmap and initial BH bits. --*/ if (verb >= 4) VPrintf0 ( " bucket sorting ...\n" ); for (i = 0; i < 257; i++) ftab[i] = 0; for (i = 0; i < nblock; i++) ftab[eclass8[i]]++; for (i = 0; i < 256; i++) ftabCopy[i] = ftab[i]; for (i = 1; i < 257; i++) ftab[i] += ftab[i-1]; for (i = 0; i < nblock; i++) { j = eclass8[i]; k = ftab[j] - 1; ftab[j] = k; fmap[k] = i; } nBhtab = 2 + (nblock / 32); for (i = 0; i < nBhtab; i++) bhtab[i] = 0; for (i = 0; i < 256; i++) SET_BH(ftab[i]); /*-- Inductively refine the buckets. Kind-of an "exponential radix sort" (!), inspired by the Manber-Myers suffix array construction algorithm. --*/ /*-- set sentinel bits for block-end detection --*/ for (i = 0; i < 32; i++) { SET_BH(nblock + 2*i); CLEAR_BH(nblock + 2*i + 1); } /*-- the log(N) loop --*/ H = 1; while (1) { if (verb >= 4) VPrintf1 ( " depth %6d has ", H ); j = 0; for (i = 0; i < nblock; i++) { if (ISSET_BH(i)) j = i; k = fmap[i] - H; if (k < 0) k += nblock; eclass[k] = j; } nNotDone = 0; r = -1; while (1) { /*-- find the next non-singleton bucket --*/ k = r + 1; while (ISSET_BH(k) && UNALIGNED_BH(k)) k++; if (ISSET_BH(k)) { while (WORD_BH(k) == 0xffffffff) k += 32; while (ISSET_BH(k)) k++; } l = k - 1; if (l >= nblock) break; while (!ISSET_BH(k) && UNALIGNED_BH(k)) k++; if (!ISSET_BH(k)) { while (WORD_BH(k) == 0x00000000) k += 32; while (!ISSET_BH(k)) k++; } r = k - 1; if (r >= nblock) break; /*-- now [l, r] bracket current bucket --*/ if (r > l) { nNotDone += (r - l + 1); fallbackQSort3 ( fmap, eclass, l, r ); /*-- scan bucket and generate header bits-- */ cc = -1; for (i = l; i <= r; i++) { cc1 = eclass[fmap[i]]; if (cc != cc1) { SET_BH(i); cc = cc1; }; } } } if (verb >= 4) VPrintf1 ( "%6d unresolved strings\n", nNotDone ); H *= 2; if (H > nblock || nNotDone == 0) break; } /*-- Reconstruct the original block in eclass8 [0 .. nblock-1], since the previous phase destroyed it. --*/ if (verb >= 4) VPrintf0 ( " reconstructing block ...\n" ); j = 0; for (i = 0; i < nblock; i++) { while (ftabCopy[j] == 0) j++; ftabCopy[j]--; eclass8[fmap[i]] = (UChar)j; } AssertH ( j < 256, 1005 ); } #undef SET_BH #undef CLEAR_BH #undef ISSET_BH #undef WORD_BH #undef UNALIGNED_BH /*---------------------------------------------*/ /*--- The main, O(N^2 log(N)) sorting ---*/ /*--- algorithm. Faster for "normal" ---*/ /*--- non-repetitive blocks. ---*/ /*---------------------------------------------*/ /*---------------------------------------------*/ static __inline__ Bool mainGtU ( UInt32 i1, UInt32 i2, UChar* block, UInt16* quadrant, UInt32 nblock, Int32* budget ) { Int32 k; UChar c1, c2; UInt16 s1, s2; AssertD ( i1 != i2, "mainGtU" ); /* 1 */ c1 = block[i1]; c2 = block[i2]; if (c1 != c2) return (c1 > c2); i1++; i2++; /* 2 */ c1 = block[i1]; c2 = block[i2]; if (c1 != c2) return (c1 > c2); i1++; i2++; /* 3 */ c1 = block[i1]; c2 = block[i2]; if (c1 != c2) return (c1 > c2); i1++; i2++; /* 4 */ c1 = block[i1]; c2 = block[i2]; if (c1 != c2) return (c1 > c2); i1++; i2++; /* 5 */ c1 = block[i1]; c2 = block[i2]; if (c1 != c2) return (c1 > c2); i1++; i2++; /* 6 */ c1 = block[i1]; c2 = block[i2]; if (c1 != c2) return (c1 > c2); i1++; i2++; /* 7 */ c1 = block[i1]; c2 = block[i2]; if (c1 != c2) return (c1 > c2); i1++; i2++; /* 8 */ c1 = block[i1]; c2 = block[i2]; if (c1 != c2) return (c1 > c2); i1++; i2++; /* 9 */ c1 = block[i1]; c2 = block[i2]; if (c1 != c2) return (c1 > c2); i1++; i2++; /* 10 */ c1 = block[i1]; c2 = block[i2]; if (c1 != c2) return (c1 > c2); i1++; i2++; /* 11 */ c1 = block[i1]; c2 = block[i2]; if (c1 != c2) return (c1 > c2); i1++; i2++; /* 12 */ c1 = block[i1]; c2 = block[i2]; if (c1 != c2) return (c1 > c2); i1++; i2++; k = nblock + 8; do { /* 1 */ c1 = block[i1]; c2 = block[i2]; if (c1 != c2) return (c1 > c2); s1 = quadrant[i1]; s2 = quadrant[i2]; if (s1 != s2) return (s1 > s2); i1++; i2++; /* 2 */ c1 = block[i1]; c2 = block[i2]; if (c1 != c2) return (c1 > c2); s1 = quadrant[i1]; s2 = quadrant[i2]; if (s1 != s2) return (s1 > s2); i1++; i2++; /* 3 */ c1 = block[i1]; c2 = block[i2]; if (c1 != c2) return (c1 > c2); s1 = quadrant[i1]; s2 = quadrant[i2]; if (s1 != s2) return (s1 > s2); i1++; i2++; /* 4 */ c1 = block[i1]; c2 = block[i2]; if (c1 != c2) return (c1 > c2); s1 = quadrant[i1]; s2 = quadrant[i2]; if (s1 != s2) return (s1 > s2); i1++; i2++; /* 5 */ c1 = block[i1]; c2 = block[i2]; if (c1 != c2) return (c1 > c2); s1 = quadrant[i1]; s2 = quadrant[i2]; if (s1 != s2) return (s1 > s2); i1++; i2++; /* 6 */ c1 = block[i1]; c2 = block[i2]; if (c1 != c2) return (c1 > c2); s1 = quadrant[i1]; s2 = quadrant[i2]; if (s1 != s2) return (s1 > s2); i1++; i2++; /* 7 */ c1 = block[i1]; c2 = block[i2]; if (c1 != c2) return (c1 > c2); s1 = quadrant[i1]; s2 = quadrant[i2]; if (s1 != s2) return (s1 > s2); i1++; i2++; /* 8 */ c1 = block[i1]; c2 = block[i2]; if (c1 != c2) return (c1 > c2); s1 = quadrant[i1]; s2 = quadrant[i2]; if (s1 != s2) return (s1 > s2); i1++; i2++; if (i1 >= nblock) i1 -= nblock; if (i2 >= nblock) i2 -= nblock; k -= 8; (*budget)--; } while (k >= 0); return False; } /*---------------------------------------------*/ /*-- Knuth's increments seem to work better than Incerpi-Sedgewick here. Possibly because the number of elems to sort is usually small, typically <= 20. --*/ static Int32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280, 9841, 29524, 88573, 265720, 797161, 2391484 }; static void mainSimpleSort ( UInt32* ptr, UChar* block, UInt16* quadrant, Int32 nblock, Int32 lo, Int32 hi, Int32 d, Int32* budget ) { Int32 i, j, h, bigN, hp; UInt32 v; bigN = hi - lo + 1; if (bigN < 2) return; hp = 0; while (incs[hp] < bigN) hp++; hp--; for (; hp >= 0; hp--) { h = incs[hp]; i = lo + h; while (True) { /*-- copy 1 --*/ if (i > hi) break; v = ptr[i]; j = i; while ( mainGtU ( ptr[j-h]+d, v+d, block, quadrant, nblock, budget ) ) { ptr[j] = ptr[j-h]; j = j - h; if (j <= (lo + h - 1)) break; } ptr[j] = v; i++; /*-- copy 2 --*/ if (i > hi) break; v = ptr[i]; j = i; while ( mainGtU ( ptr[j-h]+d, v+d, block, quadrant, nblock, budget ) ) { ptr[j] = ptr[j-h]; j = j - h; if (j <= (lo + h - 1)) break; } ptr[j] = v; i++; /*-- copy 3 --*/ if (i > hi) break; v = ptr[i]; j = i; while ( mainGtU ( ptr[j-h]+d, v+d, block, quadrant, nblock, budget ) ) { ptr[j] = ptr[j-h]; j = j - h; if (j <= (lo + h - 1)) break; } ptr[j] = v; i++; if (*budget < 0) return; } } } /*---------------------------------------------*/ /*-- The following is an implementation of an elegant 3-way quicksort for strings, described in a paper "Fast Algorithms for Sorting and Searching Strings", by Robert Sedgewick and Jon L. Bentley. --*/ #define mswap(zz1, zz2) \ { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; } #define mvswap(zzp1, zzp2, zzn) \ { \ Int32 yyp1 = (zzp1); \ Int32 yyp2 = (zzp2); \ Int32 yyn = (zzn); \ while (yyn > 0) { \ mswap(ptr[yyp1], ptr[yyp2]); \ yyp1++; yyp2++; yyn--; \ } \ } static __inline__ UChar mmed3 ( UChar a, UChar b, UChar c ) { UChar t; if (a > b) { t = a; a = b; b = t; }; if (b > c) { b = c; if (a > b) b = a; } return b; } #define mmin(a,b) ((a) < (b)) ? (a) : (b) #define mpush(lz,hz,dz) { stackLo[sp] = lz; \ stackHi[sp] = hz; \ stackD [sp] = dz; \ sp++; } #define mpop(lz,hz,dz) { sp--; \ lz = stackLo[sp]; \ hz = stackHi[sp]; \ dz = stackD [sp]; } #define mnextsize(az) (nextHi[az]-nextLo[az]) #define mnextswap(az,bz) \ { Int32 tz; \ tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \ tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \ tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; } #define MAIN_QSORT_SMALL_THRESH 20 #define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT) #define MAIN_QSORT_STACK_SIZE 100 static void mainQSort3 ( UInt32* ptr, UChar* block, UInt16* quadrant, Int32 nblock, Int32 loSt, Int32 hiSt, Int32 dSt, Int32* budget ) { Int32 unLo, unHi, ltLo, gtHi, n, m, med; Int32 sp, lo, hi, d; Int32 stackLo[MAIN_QSORT_STACK_SIZE]; Int32 stackHi[MAIN_QSORT_STACK_SIZE]; Int32 stackD [MAIN_QSORT_STACK_SIZE]; Int32 nextLo[3]; Int32 nextHi[3]; Int32 nextD [3]; sp = 0; mpush ( loSt, hiSt, dSt ); while (sp > 0) { AssertH ( sp < MAIN_QSORT_STACK_SIZE - 2, 1001 ); mpop ( lo, hi, d ); if (hi - lo < MAIN_QSORT_SMALL_THRESH || d > MAIN_QSORT_DEPTH_THRESH) { mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget ); if (*budget < 0) return; continue; } med = (Int32) mmed3 ( block[ptr[ lo ]+d], block[ptr[ hi ]+d], block[ptr[ (lo+hi)>>1 ]+d] ); unLo = ltLo = lo; unHi = gtHi = hi; while (True) { while (True) { if (unLo > unHi) break; n = ((Int32)block[ptr[unLo]+d]) - med; if (n == 0) { mswap(ptr[unLo], ptr[ltLo]); ltLo++; unLo++; continue; }; if (n > 0) break; unLo++; } while (True) { if (unLo > unHi) break; n = ((Int32)block[ptr[unHi]+d]) - med; if (n == 0) { mswap(ptr[unHi], ptr[gtHi]); gtHi--; unHi--; continue; }; if (n < 0) break; unHi--; } if (unLo > unHi) break; mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--; } AssertD ( unHi == unLo-1, "mainQSort3(2)" ); if (gtHi < ltLo) { mpush(lo, hi, d+1 ); continue; } n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n); m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m); n = lo + unLo - ltLo - 1; m = hi - (gtHi - unHi) + 1; nextLo[0] = lo; nextHi[0] = n; nextD[0] = d; nextLo[1] = m; nextHi[1] = hi; nextD[1] = d; nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1; if (mnextsize(0) < mnextsize(1)) mnextswap(0,1); if (mnextsize(1) < mnextsize(2)) mnextswap(1,2); if (mnextsize(0) < mnextsize(1)) mnextswap(0,1); AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)" ); AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)" ); mpush (nextLo[0], nextHi[0], nextD[0]); mpush (nextLo[1], nextHi[1], nextD[1]); mpush (nextLo[2], nextHi[2], nextD[2]); } } #undef mswap #undef mvswap #undef mpush #undef mpop #undef mmin #undef mnextsize #undef mnextswap #undef MAIN_QSORT_SMALL_THRESH #undef MAIN_QSORT_DEPTH_THRESH #undef MAIN_QSORT_STACK_SIZE /*---------------------------------------------*/ /* Pre: nblock > N_OVERSHOOT block32 exists for [0 .. nblock-1 +N_OVERSHOOT] ((UChar*)block32) [0 .. nblock-1] holds block ptr exists for [0 .. nblock-1] Post: ((UChar*)block32) [0 .. nblock-1] holds block All other areas of block32 destroyed ftab [0 .. 65536 ] destroyed ptr [0 .. nblock-1] holds sorted order if (*budget < 0), sorting was abandoned */ #define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8]) #define SETMASK (1 << 21) #define CLEARMASK (~(SETMASK)) static void mainSort ( UInt32* ptr, UChar* block, UInt16* quadrant, UInt32* ftab, Int32 nblock, Int32 verb, Int32* budget ) { Int32 i, j, k, ss, sb; Int32 runningOrder[256]; Bool bigDone[256]; Int32 copyStart[256]; Int32 copyEnd [256]; UChar c1; Int32 numQSorted; UInt16 s; if (verb >= 4) VPrintf0 ( " main sort initialise ...\n" ); /*-- set up the 2-byte frequency table --*/ for (i = 65536; i >= 0; i--) ftab[i] = 0; j = block[0] << 8; i = nblock-1; for (; i >= 3; i -= 4) { quadrant[i] = 0; j = (j >> 8) | ( ((UInt16)block[i]) << 8); ftab[j]++; quadrant[i-1] = 0; j = (j >> 8) | ( ((UInt16)block[i-1]) << 8); ftab[j]++; quadrant[i-2] = 0; j = (j >> 8) | ( ((UInt16)block[i-2]) << 8); ftab[j]++; quadrant[i-3] = 0; j = (j >> 8) | ( ((UInt16)block[i-3]) << 8); ftab[j]++; } for (; i >= 0; i--) { quadrant[i] = 0; j = (j >> 8) | ( ((UInt16)block[i]) << 8); ftab[j]++; } /*-- (emphasises close relationship of block & quadrant) --*/ for (i = 0; i < BZ_N_OVERSHOOT; i++) { block [nblock+i] = block[i]; quadrant[nblock+i] = 0; } if (verb >= 4) VPrintf0 ( " bucket sorting ...\n" ); /*-- Complete the initial radix sort --*/ for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1]; s = block[0] << 8; i = nblock-1; for (; i >= 3; i -= 4) { s = (s >> 8) | (block[i] << 8); j = ftab[s] -1; ftab[s] = j; ptr[j] = i; s = (s >> 8) | (block[i-1] << 8); j = ftab[s] -1; ftab[s] = j; ptr[j] = i-1; s = (s >> 8) | (block[i-2] << 8); j = ftab[s] -1; ftab[s] = j; ptr[j] = i-2; s = (s >> 8) | (block[i-3] << 8); j = ftab[s] -1; ftab[s] = j; ptr[j] = i-3; } for (; i >= 0; i--) { s = (s >> 8) | (block[i] << 8); j = ftab[s] -1; ftab[s] = j; ptr[j] = i; } /*-- Now ftab contains the first loc of every small bucket. Calculate the running order, from smallest to largest big bucket. --*/ for (i = 0; i <= 255; i++) { bigDone [i] = False; runningOrder[i] = i; } { Int32 vv; Int32 h = 1; do h = 3 * h + 1; while (h <= 256); do { h = h / 3; for (i = h; i <= 255; i++) { vv = runningOrder[i]; j = i; while ( BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv) ) { runningOrder[j] = runningOrder[j-h]; j = j - h; if (j <= (h - 1)) goto zero; } zero: runningOrder[j] = vv; } } while (h != 1); } /*-- The main sorting loop. --*/ numQSorted = 0; for (i = 0; i <= 255; i++) { /*-- Process big buckets, starting with the least full. Basically this is a 3-step process in which we call mainQSort3 to sort the small buckets [ss, j], but also make a big effort to avoid the calls if we can. --*/ ss = runningOrder[i]; /*-- Step 1: Complete the big bucket [ss] by quicksorting any unsorted small buckets [ss, j], for j != ss. Hopefully previous pointer-scanning phases have already completed many of the small buckets [ss, j], so we don't have to sort them at all. --*/ for (j = 0; j <= 255; j++) { if (j != ss) { sb = (ss << 8) + j; if ( ! (ftab[sb] & SETMASK) ) { Int32 lo = ftab[sb] & CLEARMASK; Int32 hi = (ftab[sb+1] & CLEARMASK) - 1; if (hi > lo) { if (verb >= 4) VPrintf4 ( " qsort [0x%x, 0x%x] " "done %d this %d\n", ss, j, numQSorted, hi - lo + 1 ); mainQSort3 ( ptr, block, quadrant, nblock, lo, hi, BZ_N_RADIX, budget ); numQSorted += (hi - lo + 1); if (*budget < 0) return; } } ftab[sb] |= SETMASK; } } AssertH ( !bigDone[ss], 1006 ); /*-- Step 2: Now scan this big bucket [ss] so as to synthesise the sorted order for small buckets [t, ss] for all t, including, magically, the bucket [ss,ss] too. This will avoid doing Real Work in subsequent Step 1's. --*/ { for (j = 0; j <= 255; j++) { copyStart[j] = ftab[(j << 8) + ss] & CLEARMASK; copyEnd [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1; } for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) { k = ptr[j]-1; if (k < 0) k += nblock; c1 = block[k]; if (!bigDone[c1]) ptr[ copyStart[c1]++ ] = k; } for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) { k = ptr[j]-1; if (k < 0) k += nblock; c1 = block[k]; if (!bigDone[c1]) ptr[ copyEnd[c1]-- ] = k; } } AssertH ( (copyStart[ss]-1 == copyEnd[ss]) || /* Extremely rare case missing in bzip2-1.0.0 and 1.0.1. Necessity for this case is demonstrated by compressing a sequence of approximately 48.5 million of character 251; 1.0.0/1.0.1 will then die here. */ (copyStart[ss] == 0 && copyEnd[ss] == nblock-1), 1007 ) for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK; /*-- Step 3: The [ss] big bucket is now done. Record this fact, and update the quadrant descriptors. Remember to update quadrants in the overshoot area too, if necessary. The "if (i < 255)" test merely skips this updating for the last bucket processed, since updating for the last bucket is pointless. The quadrant array provides a way to incrementally cache sort orderings, as they appear, so as to make subsequent comparisons in fullGtU() complete faster. For repetitive blocks this makes a big difference (but not big enough to be able to avoid the fallback sorting mechanism, exponential radix sort). The precise meaning is: at all times: for 0 <= i < nblock and 0 <= j <= nblock if block[i] != block[j], then the relative values of quadrant[i] and quadrant[j] are meaningless. else { if quadrant[i] < quadrant[j] then the string starting at i lexicographically precedes the string starting at j else if quadrant[i] > quadrant[j] then the string starting at j lexicographically precedes the string starting at i else the relative ordering of the strings starting at i and j has not yet been determined. } --*/ bigDone[ss] = True; if (i < 255) { Int32 bbStart = ftab[ss << 8] & CLEARMASK; Int32 bbSize = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart; Int32 shifts = 0; while ((bbSize >> shifts) > 65534) shifts++; for (j = bbSize-1; j >= 0; j--) { Int32 a2update = ptr[bbStart + j]; UInt16 qVal = (UInt16)(j >> shifts); quadrant[a2update] = qVal; if (a2update < BZ_N_OVERSHOOT) quadrant[a2update + nblock] = qVal; } AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 ); } } if (verb >= 4) VPrintf3 ( " %d pointers, %d sorted, %d scanned\n", nblock, numQSorted, nblock - numQSorted ); } #undef BIGFREQ #undef SETMASK #undef CLEARMASK /*---------------------------------------------*/ /* Pre: nblock > 0 arr2 exists for [0 .. nblock-1 +N_OVERSHOOT] ((UChar*)arr2) [0 .. nblock-1] holds block arr1 exists for [0 .. nblock-1] Post: ((UChar*)arr2) [0 .. nblock-1] holds block All other areas of block destroyed ftab [ 0 .. 65536 ] destroyed arr1 [0 .. nblock-1] holds sorted order */ void BZ2_blockSort ( EState* s ) { UInt32* ptr = s->ptr; UChar* block = s->block; UInt32* ftab = s->ftab; Int32 nblock = s->nblock; Int32 verb = s->verbosity; Int32 wfact = s->workFactor; UInt16* quadrant; Int32 budget; Int32 budgetInit; Int32 i; if (nblock < 10000) { fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb ); } else { /* Calculate the location for quadrant, remembering to get the alignment right. Assumes that &(block[0]) is at least 2-byte aligned -- this should be ok since block is really the first section of arr2. */ i = nblock+BZ_N_OVERSHOOT; if (i & 1) i++; quadrant = (UInt16*)(&(block[i])); /* (wfact-1) / 3 puts the default-factor-30 transition point at very roughly the same place as with v0.1 and v0.9.0. Not that it particularly matters any more, since the resulting compressed stream is now the same regardless of whether or not we use the main sort or fallback sort. */ if (wfact < 1 ) wfact = 1; if (wfact > 100) wfact = 100; budgetInit = nblock * ((wfact-1) / 3); budget = budgetInit; mainSort ( ptr, block, quadrant, ftab, nblock, verb, &budget ); if (verb >= 3) VPrintf3 ( " %d work, %d block, ratio %5.2f\n", budgetInit - budget, nblock, (float)(budgetInit - budget) / (float)(nblock==0 ? 1 : nblock) ); if (budget < 0) { if (verb >= 2) VPrintf0 ( " too repetitive; using fallback" " sorting algorithm\n" ); fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb ); } } s->origPtr = -1; for (i = 0; i < s->nblock; i++) if (ptr[i] == 0) { s->origPtr = i; break; }; AssertH( s->origPtr != -1, 1003 ); } /*-------------------------------------------------------------*/ /*--- end blocksort.c ---*/ /*-------------------------------------------------------------*/ gtkwave-3.3.66/src/libbz2/bzlib.h0000664000076400007640000001414511523063250016027 0ustar bybellbybell /*-------------------------------------------------------------*/ /*--- Public header file for the library. ---*/ /*--- bzlib.h ---*/ /*-------------------------------------------------------------*/ /* ------------------------------------------------------------------ This file is part of bzip2/libbzip2, a program and library for lossless, block-sorting data compression. bzip2/libbzip2 version 1.0.6 of 6 September 2010 Copyright (C) 1996-2010 Julian Seward Please read the WARNING, DISCLAIMER and PATENTS sections in the README file. This program is released under the terms of the license contained in the file LICENSE. ------------------------------------------------------------------ */ #ifndef _BZLIB_H #define _BZLIB_H #ifdef __cplusplus extern "C" { #endif #define BZ_RUN 0 #define BZ_FLUSH 1 #define BZ_FINISH 2 #define BZ_OK 0 #define BZ_RUN_OK 1 #define BZ_FLUSH_OK 2 #define BZ_FINISH_OK 3 #define BZ_STREAM_END 4 #define BZ_SEQUENCE_ERROR (-1) #define BZ_PARAM_ERROR (-2) #define BZ_MEM_ERROR (-3) #define BZ_DATA_ERROR (-4) #define BZ_DATA_ERROR_MAGIC (-5) #define BZ_IO_ERROR (-6) #define BZ_UNEXPECTED_EOF (-7) #define BZ_OUTBUFF_FULL (-8) #define BZ_CONFIG_ERROR (-9) typedef struct { char *next_in; unsigned int avail_in; unsigned int total_in_lo32; unsigned int total_in_hi32; char *next_out; unsigned int avail_out; unsigned int total_out_lo32; unsigned int total_out_hi32; void *state; void *(*bzalloc)(void *,int,int); void (*bzfree)(void *,void *); void *opaque; } bz_stream; #ifndef BZ_IMPORT #define BZ_EXPORT #endif #ifndef BZ_NO_STDIO /* Need a definitition for FILE */ #include #endif #ifdef _WIN32 # include # ifdef small /* windows.h define small to char */ # undef small # endif # ifdef BZ_EXPORT # define BZ_API(func) WINAPI func # define BZ_EXTERN extern # else /* import windows dll dynamically */ # define BZ_API(func) (WINAPI * func) # define BZ_EXTERN # endif #else # define BZ_API(func) func # define BZ_EXTERN extern #endif /*-- Core (low-level) library functions --*/ BZ_EXTERN int BZ_API(BZ2_bzCompressInit) ( bz_stream* strm, int blockSize100k, int verbosity, int workFactor ); BZ_EXTERN int BZ_API(BZ2_bzCompress) ( bz_stream* strm, int action ); BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) ( bz_stream* strm ); BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) ( bz_stream *strm, int verbosity, int small ); BZ_EXTERN int BZ_API(BZ2_bzDecompress) ( bz_stream* strm ); BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) ( bz_stream *strm ); /*-- High(er) level library functions --*/ #ifndef BZ_NO_STDIO #define BZ_MAX_UNUSED 5000 typedef void BZFILE; BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) ( int* bzerror, FILE* f, int verbosity, int small, void* unused, int nUnused ); BZ_EXTERN void BZ_API(BZ2_bzReadClose) ( int* bzerror, BZFILE* b ); BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) ( int* bzerror, BZFILE* b, void** unused, int* nUnused ); BZ_EXTERN int BZ_API(BZ2_bzRead) ( int* bzerror, BZFILE* b, void* buf, int len ); BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) ( int* bzerror, FILE* f, int blockSize100k, int verbosity, int workFactor ); BZ_EXTERN void BZ_API(BZ2_bzWrite) ( int* bzerror, BZFILE* b, void* buf, int len ); BZ_EXTERN void BZ_API(BZ2_bzWriteClose) ( int* bzerror, BZFILE* b, int abandon, unsigned int* nbytes_in, unsigned int* nbytes_out ); BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) ( int* bzerror, BZFILE* b, int abandon, unsigned int* nbytes_in_lo32, unsigned int* nbytes_in_hi32, unsigned int* nbytes_out_lo32, unsigned int* nbytes_out_hi32 ); #endif /*-- Utility functions --*/ BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) ( char* dest, unsigned int* destLen, char* source, unsigned int sourceLen, int blockSize100k, int verbosity, int workFactor ); BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) ( char* dest, unsigned int* destLen, char* source, unsigned int sourceLen, int small, int verbosity ); /*-- Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp) to support better zlib compatibility. This code is not _officially_ part of libbzip2 (yet); I haven't tested it, documented it, or considered the threading-safeness of it. If this code breaks, please contact both Yoshioka and me. --*/ BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) ( void ); #ifndef BZ_NO_STDIO BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) ( const char *path, const char *mode ); BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) ( int fd, const char *mode ); BZ_EXTERN int BZ_API(BZ2_bzread) ( BZFILE* b, void* buf, int len ); BZ_EXTERN int BZ_API(BZ2_bzwrite) ( BZFILE* b, void* buf, int len ); BZ_EXTERN int BZ_API(BZ2_bzflush) ( BZFILE* b ); BZ_EXTERN void BZ_API(BZ2_bzclose) ( BZFILE* b ); BZ_EXTERN const char * BZ_API(BZ2_bzerror) ( BZFILE *b, int *errnum ); #endif #ifdef __cplusplus } #endif #endif /*-------------------------------------------------------------*/ /*--- end bzlib.h ---*/ /*-------------------------------------------------------------*/ gtkwave-3.3.66/src/libbz2/compress.c0000664000076400007640000005012111523063250016545 0ustar bybellbybell /*-------------------------------------------------------------*/ /*--- Compression machinery (not incl block sorting) ---*/ /*--- compress.c ---*/ /*-------------------------------------------------------------*/ /* ------------------------------------------------------------------ This file is part of bzip2/libbzip2, a program and library for lossless, block-sorting data compression. bzip2/libbzip2 version 1.0.6 of 6 September 2010 Copyright (C) 1996-2010 Julian Seward Please read the WARNING, DISCLAIMER and PATENTS sections in the README file. This program is released under the terms of the license contained in the file LICENSE. ------------------------------------------------------------------ */ /* CHANGES 0.9.0 -- original version. 0.9.0a/b -- no changes in this file. 0.9.0c -- changed setting of nGroups in sendMTFValues() so as to do a bit better on small files */ #include "bzlib_private.h" /*---------------------------------------------------*/ /*--- Bit stream I/O ---*/ /*---------------------------------------------------*/ /*---------------------------------------------------*/ void BZ2_bsInitWrite ( EState* s ) { s->bsLive = 0; s->bsBuff = 0; } /*---------------------------------------------------*/ static void bsFinishWrite ( EState* s ) { while (s->bsLive > 0) { s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24); s->numZ++; s->bsBuff <<= 8; s->bsLive -= 8; } } /*---------------------------------------------------*/ #define bsNEEDW(nz) \ { \ while (s->bsLive >= 8) { \ s->zbits[s->numZ] \ = (UChar)(s->bsBuff >> 24); \ s->numZ++; \ s->bsBuff <<= 8; \ s->bsLive -= 8; \ } \ } /*---------------------------------------------------*/ static __inline__ void bsW ( EState* s, Int32 n, UInt32 v ) { bsNEEDW ( n ); s->bsBuff |= (v << (32 - s->bsLive - n)); s->bsLive += n; } /*---------------------------------------------------*/ static void bsPutUInt32 ( EState* s, UInt32 u ) { bsW ( s, 8, (u >> 24) & 0xffL ); bsW ( s, 8, (u >> 16) & 0xffL ); bsW ( s, 8, (u >> 8) & 0xffL ); bsW ( s, 8, u & 0xffL ); } /*---------------------------------------------------*/ static void bsPutUChar ( EState* s, UChar c ) { bsW( s, 8, (UInt32)c ); } /*---------------------------------------------------*/ /*--- The back end proper ---*/ /*---------------------------------------------------*/ /*---------------------------------------------------*/ static void makeMaps_e ( EState* s ) { Int32 i; s->nInUse = 0; for (i = 0; i < 256; i++) if (s->inUse[i]) { s->unseqToSeq[i] = s->nInUse; s->nInUse++; } } /*---------------------------------------------------*/ static void generateMTFValues ( EState* s ) { UChar yy[256]; Int32 i, j; Int32 zPend; Int32 wr; Int32 EOB; /* After sorting (eg, here), s->arr1 [ 0 .. s->nblock-1 ] holds sorted order, and ((UChar*)s->arr2) [ 0 .. s->nblock-1 ] holds the original block data. The first thing to do is generate the MTF values, and put them in ((UInt16*)s->arr1) [ 0 .. s->nblock-1 ]. Because there are strictly fewer or equal MTF values than block values, ptr values in this area are overwritten with MTF values only when they are no longer needed. The final compressed bitstream is generated into the area starting at (UChar*) (&((UChar*)s->arr2)[s->nblock]) These storage aliases are set up in bzCompressInit(), except for the last one, which is arranged in compressBlock(). */ UInt32* ptr = s->ptr; UChar* block = s->block; UInt16* mtfv = s->mtfv; makeMaps_e ( s ); EOB = s->nInUse+1; for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0; wr = 0; zPend = 0; for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i; for (i = 0; i < s->nblock; i++) { UChar ll_i; AssertD ( wr <= i, "generateMTFValues(1)" ); j = ptr[i]-1; if (j < 0) j += s->nblock; ll_i = s->unseqToSeq[block[j]]; AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" ); if (yy[0] == ll_i) { zPend++; } else { if (zPend > 0) { zPend--; while (True) { if (zPend & 1) { mtfv[wr] = BZ_RUNB; wr++; s->mtfFreq[BZ_RUNB]++; } else { mtfv[wr] = BZ_RUNA; wr++; s->mtfFreq[BZ_RUNA]++; } if (zPend < 2) break; zPend = (zPend - 2) / 2; }; zPend = 0; } { register UChar rtmp; register UChar* ryy_j; register UChar rll_i; rtmp = yy[1]; yy[1] = yy[0]; ryy_j = &(yy[1]); rll_i = ll_i; while ( rll_i != rtmp ) { register UChar rtmp2; ryy_j++; rtmp2 = rtmp; rtmp = *ryy_j; *ryy_j = rtmp2; }; yy[0] = rtmp; j = ryy_j - &(yy[0]); mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++; } } } if (zPend > 0) { zPend--; while (True) { if (zPend & 1) { mtfv[wr] = BZ_RUNB; wr++; s->mtfFreq[BZ_RUNB]++; } else { mtfv[wr] = BZ_RUNA; wr++; s->mtfFreq[BZ_RUNA]++; } if (zPend < 2) break; zPend = (zPend - 2) / 2; }; zPend = 0; } mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++; s->nMTF = wr; } /*---------------------------------------------------*/ #define BZ_LESSER_ICOST 0 #define BZ_GREATER_ICOST 15 static void sendMTFValues ( EState* s ) { Int32 v, t, i, j, gs, ge, totc, bt, bc, iter; Int32 nSelectors, alphaSize, minLen, maxLen, selCtr; Int32 nGroups, nBytes; /*-- UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; is a global since the decoder also needs it. Int32 code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; Int32 rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; are also globals only used in this proc. Made global to keep stack frame size small. --*/ UInt16 cost[BZ_N_GROUPS]; Int32 fave[BZ_N_GROUPS]; UInt16* mtfv = s->mtfv; if (s->verbosity >= 3) VPrintf3( " %d in block, %d after MTF & 1-2 coding, " "%d+2 syms in use\n", s->nblock, s->nMTF, s->nInUse ); alphaSize = s->nInUse+2; for (t = 0; t < BZ_N_GROUPS; t++) for (v = 0; v < alphaSize; v++) s->len[t][v] = BZ_GREATER_ICOST; /*--- Decide how many coding tables to use ---*/ AssertH ( s->nMTF > 0, 3001 ); if (s->nMTF < 200) nGroups = 2; else if (s->nMTF < 600) nGroups = 3; else if (s->nMTF < 1200) nGroups = 4; else if (s->nMTF < 2400) nGroups = 5; else nGroups = 6; /*--- Generate an initial set of coding tables ---*/ { Int32 nPart, remF, tFreq, aFreq; nPart = nGroups; remF = s->nMTF; gs = 0; while (nPart > 0) { tFreq = remF / nPart; ge = gs-1; aFreq = 0; while (aFreq < tFreq && ge < alphaSize-1) { ge++; aFreq += s->mtfFreq[ge]; } if (ge > gs && nPart != nGroups && nPart != 1 && ((nGroups-nPart) % 2 == 1)) { aFreq -= s->mtfFreq[ge]; ge--; } if (s->verbosity >= 3) VPrintf5( " initial group %d, [%d .. %d], " "has %d syms (%4.1f%%)\n", nPart, gs, ge, aFreq, (100.0 * (float)aFreq) / (float)(s->nMTF) ); for (v = 0; v < alphaSize; v++) if (v >= gs && v <= ge) s->len[nPart-1][v] = BZ_LESSER_ICOST; else s->len[nPart-1][v] = BZ_GREATER_ICOST; nPart--; gs = ge+1; remF -= aFreq; } } /*--- Iterate up to BZ_N_ITERS times to improve the tables. ---*/ for (iter = 0; iter < BZ_N_ITERS; iter++) { for (t = 0; t < nGroups; t++) fave[t] = 0; for (t = 0; t < nGroups; t++) for (v = 0; v < alphaSize; v++) s->rfreq[t][v] = 0; /*--- Set up an auxiliary length table which is used to fast-track the common case (nGroups == 6). ---*/ if (nGroups == 6) { for (v = 0; v < alphaSize; v++) { s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v]; s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v]; s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v]; } } nSelectors = 0; totc = 0; gs = 0; while (True) { /*--- Set group start & end marks. --*/ if (gs >= s->nMTF) break; ge = gs + BZ_G_SIZE - 1; if (ge >= s->nMTF) ge = s->nMTF-1; /*-- Calculate the cost of this group as coded by each of the coding tables. --*/ for (t = 0; t < nGroups; t++) cost[t] = 0; if (nGroups == 6 && 50 == ge-gs+1) { /*--- fast track the common case ---*/ register UInt32 cost01, cost23, cost45; register UInt16 icv; cost01 = cost23 = cost45 = 0; # define BZ_ITER(nn) \ icv = mtfv[gs+(nn)]; \ cost01 += s->len_pack[icv][0]; \ cost23 += s->len_pack[icv][1]; \ cost45 += s->len_pack[icv][2]; \ BZ_ITER(0); BZ_ITER(1); BZ_ITER(2); BZ_ITER(3); BZ_ITER(4); BZ_ITER(5); BZ_ITER(6); BZ_ITER(7); BZ_ITER(8); BZ_ITER(9); BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14); BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19); BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24); BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29); BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34); BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39); BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44); BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49); # undef BZ_ITER cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16; cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16; cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16; } else { /*--- slow version which correctly handles all situations ---*/ for (i = gs; i <= ge; i++) { UInt16 icv = mtfv[i]; for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv]; } } /*-- Find the coding table which is best for this group, and record its identity in the selector table. --*/ bc = 999999999; bt = -1; for (t = 0; t < nGroups; t++) if (cost[t] < bc) { bc = cost[t]; bt = t; }; totc += bc; fave[bt]++; s->selector[nSelectors] = bt; nSelectors++; /*-- Increment the symbol frequencies for the selected table. --*/ if (nGroups == 6 && 50 == ge-gs+1) { /*--- fast track the common case ---*/ # define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++ BZ_ITUR(0); BZ_ITUR(1); BZ_ITUR(2); BZ_ITUR(3); BZ_ITUR(4); BZ_ITUR(5); BZ_ITUR(6); BZ_ITUR(7); BZ_ITUR(8); BZ_ITUR(9); BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14); BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19); BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24); BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29); BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34); BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39); BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44); BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49); # undef BZ_ITUR } else { /*--- slow version which correctly handles all situations ---*/ for (i = gs; i <= ge; i++) s->rfreq[bt][ mtfv[i] ]++; } gs = ge+1; } if (s->verbosity >= 3) { VPrintf2 ( " pass %d: size is %d, grp uses are ", iter+1, totc/8 ); for (t = 0; t < nGroups; t++) VPrintf1 ( "%d ", fave[t] ); VPrintf0 ( "\n" ); } /*-- Recompute the tables based on the accumulated frequencies. --*/ /* maxLen was changed from 20 to 17 in bzip2-1.0.3. See comment in huffman.c for details. */ for (t = 0; t < nGroups; t++) BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]), alphaSize, 17 /*20*/ ); } AssertH( nGroups < 8, 3002 ); AssertH( nSelectors < 32768 && nSelectors <= (2 + (900000 / BZ_G_SIZE)), 3003 ); /*--- Compute MTF values for the selectors. ---*/ { UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp; for (i = 0; i < nGroups; i++) pos[i] = i; for (i = 0; i < nSelectors; i++) { ll_i = s->selector[i]; j = 0; tmp = pos[j]; while ( ll_i != tmp ) { j++; tmp2 = tmp; tmp = pos[j]; pos[j] = tmp2; }; pos[0] = tmp; s->selectorMtf[i] = j; } }; /*--- Assign actual codes for the tables. --*/ for (t = 0; t < nGroups; t++) { minLen = 32; maxLen = 0; for (i = 0; i < alphaSize; i++) { if (s->len[t][i] > maxLen) maxLen = s->len[t][i]; if (s->len[t][i] < minLen) minLen = s->len[t][i]; } AssertH ( !(maxLen > 17 /*20*/ ), 3004 ); AssertH ( !(minLen < 1), 3005 ); BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]), minLen, maxLen, alphaSize ); } /*--- Transmit the mapping table. ---*/ { Bool inUse16[16]; for (i = 0; i < 16; i++) { inUse16[i] = False; for (j = 0; j < 16; j++) if (s->inUse[i * 16 + j]) inUse16[i] = True; } nBytes = s->numZ; for (i = 0; i < 16; i++) if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0); for (i = 0; i < 16; i++) if (inUse16[i]) for (j = 0; j < 16; j++) { if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0); } if (s->verbosity >= 3) VPrintf1( " bytes: mapping %d, ", s->numZ-nBytes ); } /*--- Now the selectors. ---*/ nBytes = s->numZ; bsW ( s, 3, nGroups ); bsW ( s, 15, nSelectors ); for (i = 0; i < nSelectors; i++) { for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1); bsW(s,1,0); } if (s->verbosity >= 3) VPrintf1( "selectors %d, ", s->numZ-nBytes ); /*--- Now the coding tables. ---*/ nBytes = s->numZ; for (t = 0; t < nGroups; t++) { Int32 curr = s->len[t][0]; bsW ( s, 5, curr ); for (i = 0; i < alphaSize; i++) { while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ }; while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ }; bsW ( s, 1, 0 ); } } if (s->verbosity >= 3) VPrintf1 ( "code lengths %d, ", s->numZ-nBytes ); /*--- And finally, the block data proper ---*/ nBytes = s->numZ; selCtr = 0; gs = 0; while (True) { if (gs >= s->nMTF) break; ge = gs + BZ_G_SIZE - 1; if (ge >= s->nMTF) ge = s->nMTF-1; AssertH ( s->selector[selCtr] < nGroups, 3006 ); if (nGroups == 6 && 50 == ge-gs+1) { /*--- fast track the common case ---*/ UInt16 mtfv_i; UChar* s_len_sel_selCtr = &(s->len[s->selector[selCtr]][0]); Int32* s_code_sel_selCtr = &(s->code[s->selector[selCtr]][0]); # define BZ_ITAH(nn) \ mtfv_i = mtfv[gs+(nn)]; \ bsW ( s, \ s_len_sel_selCtr[mtfv_i], \ s_code_sel_selCtr[mtfv_i] ) BZ_ITAH(0); BZ_ITAH(1); BZ_ITAH(2); BZ_ITAH(3); BZ_ITAH(4); BZ_ITAH(5); BZ_ITAH(6); BZ_ITAH(7); BZ_ITAH(8); BZ_ITAH(9); BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14); BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19); BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24); BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29); BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34); BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39); BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44); BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49); # undef BZ_ITAH } else { /*--- slow version which correctly handles all situations ---*/ for (i = gs; i <= ge; i++) { bsW ( s, s->len [s->selector[selCtr]] [mtfv[i]], s->code [s->selector[selCtr]] [mtfv[i]] ); } } gs = ge+1; selCtr++; } AssertH( selCtr == nSelectors, 3007 ); if (s->verbosity >= 3) VPrintf1( "codes %d\n", s->numZ-nBytes ); } /*---------------------------------------------------*/ void BZ2_compressBlock ( EState* s, Bool is_last_block ) { if (s->nblock > 0) { BZ_FINALISE_CRC ( s->blockCRC ); s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31); s->combinedCRC ^= s->blockCRC; if (s->blockNo > 1) s->numZ = 0; if (s->verbosity >= 2) VPrintf4( " block %d: crc = 0x%08x, " "combined CRC = 0x%08x, size = %d\n", s->blockNo, s->blockCRC, s->combinedCRC, s->nblock ); BZ2_blockSort ( s ); } s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]); /*-- If this is the first block, create the stream header. --*/ if (s->blockNo == 1) { BZ2_bsInitWrite ( s ); bsPutUChar ( s, BZ_HDR_B ); bsPutUChar ( s, BZ_HDR_Z ); bsPutUChar ( s, BZ_HDR_h ); bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) ); } if (s->nblock > 0) { bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 ); bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 ); bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 ); /*-- Now the block's CRC, so it is in a known place. --*/ bsPutUInt32 ( s, s->blockCRC ); /*-- Now a single bit indicating (non-)randomisation. As of version 0.9.5, we use a better sorting algorithm which makes randomisation unnecessary. So always set the randomised bit to 'no'. Of course, the decoder still needs to be able to handle randomised blocks so as to maintain backwards compatibility with older versions of bzip2. --*/ bsW(s,1,0); bsW ( s, 24, s->origPtr ); generateMTFValues ( s ); sendMTFValues ( s ); } /*-- If this is the last block, add the stream trailer. --*/ if (is_last_block) { bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 ); bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 ); bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 ); bsPutUInt32 ( s, s->combinedCRC ); if (s->verbosity >= 2) VPrintf1( " final combined CRC = 0x%08x\n ", s->combinedCRC ); bsFinishWrite ( s ); } } /*-------------------------------------------------------------*/ /*--- end compress.c ---*/ /*-------------------------------------------------------------*/ gtkwave-3.3.66/src/print.c0000664000076400007640000023420712352350566014705 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2012. * * 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 module has been re-implemented by Udi Finkelstein. Since it is no * longer a PostScript-only module, it had been renamed "print.c". * * Much of the code has been "C++"-ized in style, yet written in C. We use * classes, virtual functions, class members, and "this" pointers written in * C. */ /* AIX may need this for alloca to work */ #if defined _AIX #pragma alloca #endif #include "globals.h" #include #include "currenttime.h" #include "analyzer.h" #include "symbol.h" #include "bsearch.h" #include "wavealloca.h" #include "debug.h" #include "strace.h" #include "print.h" /********************************************** * this is essentially wavewindow.c's rendering * engine modified to produce postscript **********************************************/ #define WAVE_COURIER_SCALE_FAC 1.6 /* more or less is the correct * pixel->ps scale mapping */ /* * PostScript device specific operations */ gtk_print_device ps_print_device = { ps_header, ps_trailer, ps_signal_init, ps_setgray, ps_draw_line, ps_draw_box, ps_draw_string }; /* * MIF device specific operations */ gtk_print_device mif_print_device = { mif_header, mif_trailer, mif_signal_init, mif_setgray, mif_draw_line, mif_draw_box, mif_draw_string }; /************************************************************************** * Shorthand routins * * * * These routines call the specific operations through the device pointer * **************************************************************************/ void pr_header (pr_context * prc) { (*prc->gpd->gpd_header) (prc); } void pr_trailer (pr_context * prc) { (*prc->gpd->gpd_trailer) (prc); } void pr_signal_init (pr_context * prc) { (*prc->gpd->gpd_signal_init) (prc); } void pr_setgray (pr_context * prc, gdouble gray) { (*prc->gpd->gpd_setgray) (prc, gray); } void pr_draw_line (pr_context * prc, gdouble _x1, gdouble _y1, gdouble x2, gdouble y2) { (*prc->gpd->gpd_draw_line) (prc, _x1, _y1, x2, y2); } void pr_draw_box (pr_context * prc, gdouble _x1, gdouble _y1, gdouble x2, gdouble y2) { (*prc->gpd->gpd_draw_box) (prc, _x1, _y1, x2, y2); } void pr_draw_string (pr_context * prc, int x, int y, char *str, int xsize, int ysize) { (*prc->gpd->gpd_draw_string) (prc, x, y, str, xsize, ysize); } /************************************************************************* * PostScript specific routines * *************************************************************************/ /* * Set current gray level, with 0.0 being white, and 1.0 being black. */ void ps_setgray (pr_context * prc, gdouble gray) { fprintf (prc->handle, "%f setgray\n", gray); } /* * Create a rectangular path */ void ps_box (pr_context * prc, gdouble t_x1, gdouble t_y1, gdouble tx2, gdouble ty2) { fprintf (prc->handle, "%f %f %f %f box\n", t_y1, t_x1, ty2, tx2); } /* * Draw a box */ void ps_draw_box (pr_context * prc, gdouble _x1, gdouble _y1, gdouble x2, gdouble y2) { gdouble t_x1, t_y1, tx2, ty2; t_x1 = _x1 * prc->xscale; t_y1 = _y1 * prc->yscale; tx2 = x2 * prc->xscale; ty2 = y2 * prc->yscale; ps_box (prc, t_x1, t_y1, tx2, ty2); fprintf (prc->handle, "fill\n"); } void ps_signal_init (pr_context * prc) { fprintf (prc->handle, "grestore\n" "gsave\n"); if (prc->fullpage) { ps_setgray (prc, 0.0); ps_box (prc, prc->MinX - 1, prc->MinY - 2, prc->MaxX + 1, prc->MaxY + 2); fprintf (prc->handle, "stroke\n"); ps_setgray (prc, 0.5); ps_box (prc, prc->MinX, prc->MinY - 1, prc->MaxX, prc->MaxY + 1); fprintf (prc->handle, "clip\n"); } fprintf (prc->handle, "%d %d translate\n" "1 1 scale\n" "0.5 setlinewidth\n" "stroke\n", prc->MinY, prc->MinX); } void ps_header (pr_context * prc) { gdouble ps_skip; ps_skip = prc->MinX + (prc->MaxX - prc->MinX) * (((gdouble) GLOBALS->pr_signal_fill_width_print_c_1) / prc->xtotal); fprintf (prc->handle, "%%!PS-Adobe-2.0 EPSF-1.2\n" "%%%%BoundingBox: %d %d %d %d\n" "%%%%Pages: 1\n" "%%%%EndComments\n" "%%%%Page: (1) 1\n" "/box { %% stack: _x1 _y1 x2 y2\n" "\tnewpath\n" "\t2 copy moveto %% x2 y2\n" "\t3 index 1 index lineto %% _x1 y2\n" "\t3 index 3 index lineto %% _x1 _y1\n" "\t1 index 3 index lineto %% x2 _y1\n" "\tpop pop pop pop\n" "\tclosepath\n" "} def\n" "/l { %% stack: _x1 _y1 x2 y2\n" "\tnewpath moveto lineto closepath stroke\n" "} def\n", prc->MinY, prc->MinX, (int) (prc->fullpage ? prc->MaxY : GLOBALS->ybound_print_c_1), prc->MaxX); if (!prc->fullpage) { ps_box (prc, prc->MinX - 1, prc->MinY - 1, prc->MaxX, GLOBALS->ybound_print_c_1); fprintf (prc->handle, "clip\n"); } fprintf (prc->handle, "/Courier findfont\n" "10 scalefont\n" "setfont\n" "2 setlinecap\n" "gsave\n" "1 1 scale\n" "0.5 setlinewidth\n" "stroke\n"); ps_setgray (prc, 0.75); ps_box (prc, ps_skip, prc->MinY - 1, prc->MaxX, prc->MaxY + 1); fprintf (prc->handle, "clip\n" "%d %f translate stroke\n", prc->MinY, ps_skip); } void ps_draw_line (pr_context * prc, gdouble _x1, gdouble _y1, gdouble x2, gdouble y2) { gdouble t_x1, t_y1, tx2, ty2; if (_x1 < -1.0) _x1 = -1.0; if (x2 < -1.0) x2 = -1.0; if (_x1 > 10000.0) _x1 = 10000.0; if (x2 > 10000.0) x2 = 10000.0; t_x1 = _x1 * prc->xscale; t_y1 = _y1 * prc->yscale; tx2 = x2 * prc->xscale; ty2 = y2 * prc->yscale; fprintf (prc->handle, "%f %f %f %f l\n", t_y1, t_x1, ty2, tx2); } void ps_draw_string (pr_context * prc, int x, int y, char *str, int xsize, int ysize) { int i; int len; len = strlen (str); if (!len) return; fprintf (prc->handle, "save\n%f %f moveto\n%f %f scale\n90 rotate\n(", (y - 1) * prc->yscale, x * prc->xscale, (ysize * prc->yscale) * WAVE_COURIER_SCALE_FAC / 10.0, (xsize * prc->xscale) / len * WAVE_COURIER_SCALE_FAC / 10.0); for (i = 0; i < len; i++) { char ch; ch = str[i]; if (ch < 32) { ch = 32; /* fix out of range signed chars */ } else if ((ch == '(') || (ch == ')') || (ch == '\\')) { fprintf (prc->handle, "\\"); /* escape parens or esc */ } fprintf (prc->handle, "%c", ch); } fprintf (prc->handle, ") show\n" "restore\n"); } void ps_trailer (pr_context * prc) { fprintf (prc->handle, "grestore showpage\n"); } /************************************************************************* * MIF specific routines * *************************************************************************/ /* * Generic maint functions missing in gcc */ #ifndef _MSC_VER static gdouble maxdbl (gdouble a, gdouble b) { return (a > b ? a : b); } static gdouble mindbl (gdouble a, gdouble b) { return (a < b ? a : b); } #endif /* * Set current gray level, with 0.0 being white, and 1.0 being black. */ void mif_setgray (pr_context * prc, gdouble gray) { prc->gray = gray; } /* * Set current gray level, with 0.0 being white, and 1.0 being black. */ void mif_translate (pr_context * prc, gdouble x, gdouble y) { prc->tr_x = x; prc->tr_y = y; } /* * Draw an empty box */ void mif_box (pr_context * prc, gdouble _x1, gdouble _y1, gdouble x2, gdouble y2) { fprintf (prc->handle, " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " > # end of Rectangle\n", (int) (10000 * (1 - prc->gray)), (int) (_y1), (int) (_x1), abs ((int) (y2 - _y1)), abs ((int) (x2 - _x1)), (int) (_y1), (int) (_x1), abs ((int) (y2 - _y1)), abs ((int) (x2 - _x1))); } /* * Draw a filled box */ void mif_draw_box (pr_context * prc, gdouble _x1, gdouble _y1, gdouble x2, gdouble y2) { gdouble t_x1, t_y1, tx2, ty2; int rx, ry, rw, rh; t_x1 = _x1 * prc->xscale + prc->tr_x; t_y1 = _y1 * prc->yscale + prc->tr_y; tx2 = x2 * prc->xscale + prc->tr_x; ty2 = y2 * prc->yscale + prc->tr_y; /* The exprssion below is derived from: */ /* rx = mindbl((prc->PageX * inch - t_x1), (prc->PageX * inch - tx2)) */ rx = (int) (prc->PageX * GLOBALS->inch_print_c_1 - maxdbl (tx2, t_x1)); ry = (int) mindbl (t_y1, ty2); rw = abs ((int) (tx2 - t_x1)); rh = abs ((int) (ty2 - t_y1)); fprintf (prc->handle, " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " > # end of Rectangle\n", (int) (10000 * (1 - prc->gray)), ry, rx, rh, rw, rx, ry, rh, rw); } void mif_signal_init (pr_context * prc) { if (prc->fullpage) { mif_setgray (prc, 0.0); mif_box (prc, prc->MinX - 1, prc->MinY - 2, prc->MaxX + 1, prc->MaxY + 2); mif_setgray (prc, 0.5); mif_box (prc, prc->MinX, prc->MinY - 1, prc->MaxX, prc->MaxY + 1); } mif_translate (prc, prc->MinX, prc->MinY); } void mif_header (pr_context * prc) { gdouble modified_skip; gdouble mif_skip; mif_skip = (prc->MaxX - prc->MinX) * (((gdouble) GLOBALS->pr_signal_fill_width_print_c_1) / prc->xtotal); modified_skip = prc->MinX + mif_skip; fprintf (prc->handle, " # Generated by GTKWave\n" " # MIF support by Udi Finkelstein \n" "MinY); } void mif_draw_line (pr_context * prc, gdouble _x1, gdouble _y1, gdouble x2, gdouble y2) { gdouble t_x1, t_y1, tx2, ty2; if (_x1 < -1.0) _x1 = -1.0; if (x2 < -1.0) x2 = -1.0; if (_x1 > 10000.0) _x1 = 10000.0; if (x2 > 10000.0) x2 = 10000.0; t_x1 = _x1 * prc->xscale + prc->tr_x; t_y1 = _y1 * prc->yscale + prc->tr_y; tx2 = x2 * prc->xscale + prc->tr_x; ty2 = y2 * prc->yscale + prc->tr_y; fprintf (prc->handle, " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " > # end of PolyLine\n", (int) (10000 * (1 - prc->gray)), (int) (t_y1), (int) (prc->PageX * GLOBALS->inch_print_c_1 - t_x1), (int) (ty2), (int) (prc->PageX * GLOBALS->inch_print_c_1 - tx2)); } void mif_draw_string (pr_context * prc, int x, int y, char *str, int xsize, int ysize) { int len; gdouble tx, ty; gdouble stretchx, stretchy; char *strfix; int i; if (x < -1.0) x = -1.0; if (x > 10000.0) x = 10000.0; tx = x * prc->xscale + prc->tr_x; ty = y * prc->yscale + prc->tr_y; len = strlen (str); if (!len) return; stretchy = (ysize * (1.52 * prc->yscale)); stretchx = (xsize / (len * stretchy)) * prc->xscale * WAVE_COURIER_SCALE_FAC * 100.00; strfix = strdup_2(str); for(i=0;i126)||(strfix[i]=='\'')) { strfix[i] = ' '; } } fprintf (prc->handle, " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " \n" " > # end of Font\n" " \n" " > # end of TextLine\n", (int) (ty), (int) (prc->PageX * GLOBALS->inch_print_c_1 - tx), stretchy, stretchx, strfix); free_2(strfix); } void mif_trailer (pr_context * prc) { fprintf (prc->handle, " \n" " \n" " > # end of Group\n" "> # end of Page\n"); } /**********************************************/ /* * Initialize print related constants */ static void pr_wave_init (pr_context * prc) { int wh = GLOBALS->waveheight; int yheight = 33 * GLOBALS->fontheight; prc->MinX = prc->LM * GLOBALS->inch_print_c_1; prc->MaxX = (prc->PageX - prc->RM) * GLOBALS->inch_print_c_1; prc->MinY = prc->BM * GLOBALS->inch_print_c_1; prc->MaxY = (prc->PageY - prc->TM) * GLOBALS->inch_print_c_1; if (!prc->fullpage) { if (wh < 2 * GLOBALS->fontheight) wh = 2 * GLOBALS->fontheight; } yheight = (wh < yheight) ? yheight : wh; yheight = yheight - (yheight % GLOBALS->fontheight); if (!prc->fullpage) { GLOBALS->ybound_print_c_1 = ((prc->MaxY - prc->MinY) / ((gdouble) yheight)) * ((gdouble) (wh - (wh % GLOBALS-> fontheight))) + prc->MinY; } prc->xtotal = (gdouble) (GLOBALS->wavewidth + GLOBALS->pr_signal_fill_width_print_c_1); prc->xscale = ((prc->MaxX - prc->MinX) / prc->xtotal); prc->yscale = (prc->MaxY - prc->MinY) / ((gdouble) yheight); } static int ps_MaxSignalLength (void) { Trptr t; int len = 0, maxlen = 0, numchars = 0; int vlen = 0; int i, trwhich, trtarget, num_traces_displayable; GtkAdjustment *sadj; char buf[2048]; bvptr bv; Trptr tscan; GLOBALS->ps_nummaxchars_print_c_1 = 7; /* allows a good spacing if 60 pixel default * is used */ sadj = GTK_ADJUSTMENT (GLOBALS->wave_vslider); trtarget = (int) (sadj->value); t = GLOBALS->traces.first; trwhich = 0; while (t) { if ((trwhich < trtarget) && (GiveNextTrace (t))) { trwhich++; t = GiveNextTrace (t); } else { break; } } num_traces_displayable = GLOBALS->signalarea->allocation.height / GLOBALS->fontheight; for (i = 0; (i < num_traces_displayable) && (t); i++) { char *subname = NULL; bv = NULL; tscan = NULL; if(t->flags & (TR_BLANK|TR_ANALOG_BLANK_STRETCH)) /* seek to real xact trace if present... */ { int bcnt = 0; tscan = t; while((tscan) && (tscan = GivePrevTrace(tscan))) { if(!(tscan->flags & (TR_BLANK|TR_ANALOG_BLANK_STRETCH))) { if(tscan->flags & TR_TTRANSLATED) { break; /* found it */ } else { tscan = NULL; } } else { bcnt++; /* bcnt is number of blank traces */ } } if((tscan)&&(tscan->vector)) { bv = tscan->n.vec; do { bv = bv->transaction_chain; /* correlate to blank trace */ } while(bv && (bcnt--)); if(bv) { subname = bv->bvname; if(GLOBALS->hier_max_level) subname = hier_extract(subname, GLOBALS->hier_max_level); } } } populateBuffer(t, subname, buf); if (!bv && (t->flags & (TR_BLANK | TR_ANALOG_BLANK_STRETCH))) /* for "comment" style blank traces */ { if (buf[0]) { len = font_engine_string_measure (GLOBALS->signalfont, buf); numchars = strlen (buf); if (len > maxlen) maxlen = len; if (numchars > GLOBALS->ps_nummaxchars_print_c_1) GLOBALS->ps_nummaxchars_print_c_1 = numchars; if(t->asciivalue) { free_2(t->asciivalue); t->asciivalue = NULL; } } } else if (buf[0] || subname) { len = font_engine_string_measure (GLOBALS->signalfont, buf); numchars = strlen (buf); if ((GLOBALS->tims.marker != -1) && (!(t->flags & TR_EXCLUDE))) { t->asciitime = GLOBALS->tims.marker; if (t->asciivalue) free_2 (t->asciivalue); if (bv || t->vector) { char *str, *str2; vptr v; Trptr ts; TraceEnt t_temp; if(bv) { ts = &t_temp; memcpy(ts, tscan, sizeof(TraceEnt)); ts->vector = 1; ts->n.vec = bv; } else { ts = t; bv = t->n.vec; } v = bsearch_vector (bv, GLOBALS->tims.marker - ts->shift); str = convert_ascii (ts, v); if (str) { int slen; str2 = (char *) malloc_2 (strlen (str) + 2); *str2 = '='; strcpy (str2 + 1, str); free_2 (str); t->asciivalue = str2; if ((slen = strlen (str2)) > GLOBALS->ps_maxveclen) { str2[GLOBALS->ps_maxveclen] = 0; str2[GLOBALS->ps_maxveclen - 1] = '+'; vlen = font_engine_string_measure (GLOBALS->signalfont, str2); numchars += GLOBALS->ps_maxveclen; } else { vlen = font_engine_string_measure (GLOBALS->signalfont, str2); numchars += slen; } } else { vlen = 0; t->asciivalue = NULL; } } else { char *str; hptr h_ptr; if ((h_ptr = bsearch_node (t->n.nd, GLOBALS->tims.marker - t->shift))) { if (!t->n.nd->extvals) { unsigned char h_val = h_ptr->v.h_val; if(t->n.nd->vartype == ND_VCD_EVENT) { h_val = (h_ptr->time >= GLOBALS->tims.first) && ((GLOBALS->tims.marker-GLOBALS->shift_timebase) == h_ptr->time) ? AN_1 : AN_0; /* generate impulse */ } str = (char *) calloc_2 (1, 3 * sizeof (char)); str[0] = '='; if (t->flags & TR_INVERT) { str[1] = AN_STR_INV[h_val]; } else { str[1] = AN_STR[h_val]; } t->asciivalue = str; vlen = font_engine_string_measure (GLOBALS->signalfont, str); numchars += 2; } else { char *str2; if (h_ptr->flags & HIST_REAL) { if (!(h_ptr->flags & HIST_STRING)) { #ifdef WAVE_HAS_H_DOUBLE str = convert_ascii_real (t, &h_ptr->v.h_double); #else str = convert_ascii_real (t, (double *) h_ptr->v. h_vector); #endif } else { str = convert_ascii_string ((char *) h_ptr->v. h_vector); } } else { str = convert_ascii_vec (t, h_ptr->v.h_vector); } if (str) { int slen; str2 = (char *) malloc_2 (strlen (str) + 2); *str2 = '='; strcpy (str2 + 1, str); free_2 (str); t->asciivalue = str2; if ((slen = strlen (str2)) > GLOBALS->ps_maxveclen) { str2[GLOBALS->ps_maxveclen] = 0; str2[GLOBALS->ps_maxveclen - 1] = '+'; vlen = font_engine_string_measure (GLOBALS->signalfont, str2); numchars += GLOBALS->ps_maxveclen; } else { vlen = font_engine_string_measure (GLOBALS->signalfont, str2); numchars += slen; } } else { vlen = 0; t->asciivalue = NULL; } } } else { vlen = 0; t->asciivalue = NULL; } } len += vlen; } if (len > maxlen) maxlen = len; if (numchars > GLOBALS->ps_nummaxchars_print_c_1) GLOBALS->ps_nummaxchars_print_c_1 = numchars; } t = GiveNextTrace (t); } maxlen += 6; /* endcap padding */ if (maxlen < 60) maxlen = 60; return maxlen; } /**********************************************/ static void pr_renderhash (pr_context * prc, int x, TimeType tim) { TimeType rborder; gdouble dx; gdouble hashoffset; int fhminus2; int rhs; int iter = 0; int s_ctx_iter; int timearray_encountered = (GLOBALS->ruler_step != 0); fhminus2 = GLOBALS->fontheight - 2; WAVE_STRACE_ITERATOR(s_ctx_iter) { GLOBALS->strace_ctx = &GLOBALS->strace_windows[GLOBALS->strace_current_window = s_ctx_iter]; if(GLOBALS->strace_ctx->timearray) { timearray_encountered = 1; break; } } pr_setgray (prc, 0.75); pr_draw_line (prc, x, 0, x, ((!timearray_encountered) && (GLOBALS->display_grid) && (GLOBALS->enable_vert_grid)) ? GLOBALS-> liney_max : fhminus2); if (tim == GLOBALS->tims.last) return; rborder = (GLOBALS->tims.last - GLOBALS->tims.start) * GLOBALS->pxns; DEBUG (printf ("Rborder: %lld, Wavewidth: %d\n", rborder, GLOBALS->wavewidth)); if (rborder > GLOBALS->wavewidth) rborder = GLOBALS->wavewidth; if ((rhs = x + GLOBALS->pixelsperframe) > rborder) rhs = rborder; pr_draw_line (prc, x, GLOBALS->wavecrosspiece, rhs, GLOBALS->wavecrosspiece); dx = x + (hashoffset = GLOBALS->hashstep); x = dx; while ((hashoffset < GLOBALS->pixelsperframe) && (x <= rhs) && (iter < 9)) { pr_draw_line (prc, x, GLOBALS->wavecrosspiece, x, fhminus2); hashoffset += GLOBALS->hashstep; dx = dx + GLOBALS->hashstep; if ((GLOBALS->pixelsperframe != 200) || (GLOBALS->hashstep != 10.0)) iter++; /* fix any roundoff errors */ x = dx; } } static void pr_renderblackout (pr_context * prc) { gfloat pageinc; TimeType lhs, rhs, lclip, rclip; struct blackout_region_t *bt = GLOBALS->blackout_regions; if (bt) { pageinc = (gfloat) (((gdouble) GLOBALS->wavewidth) * GLOBALS->nspx); lhs = GLOBALS->tims.start; rhs = pageinc + lhs; while (bt) { if((bt->bend < lhs) || (bt->bstart > rhs)) { /* nothing */ } else { lclip = bt->bstart; rclip = bt->bend; if (lclip < lhs) lclip = lhs; else if (lclip > rhs) lclip = rhs; if (rclip < lhs) rclip = lhs; lclip -= lhs; rclip -= lhs; if(rclip>((GLOBALS->wavewidth+1)*GLOBALS->nspx)) rclip = (GLOBALS->wavewidth+1)*(GLOBALS->nspx); pr_setgray (prc, 0.80); pr_draw_box (prc, (((gdouble) lclip) * GLOBALS->pxns), GLOBALS->fontheight, (((gdouble) (rclip)) * GLOBALS->pxns), GLOBALS->waveheight - GLOBALS->fontheight); } bt = bt->next; } } } static void pr_rendertimes (pr_context * prc) { int lastx = -1000; /* arbitrary */ TimeType tim, rem; int x, len, lenhalf; char timebuff[32]; gdouble realx; int s_ctx_iter; int timearray_encountered = 0; pr_renderblackout (prc); tim = GLOBALS->tims.start; GLOBALS->tims.end = GLOBALS->tims.start + (((gdouble) GLOBALS->wavewidth) * GLOBALS->nspx); /**********/ WAVE_STRACE_ITERATOR_FWD(s_ctx_iter) { GLOBALS->strace_ctx = &GLOBALS->strace_windows[GLOBALS->strace_current_window = s_ctx_iter]; if (GLOBALS->strace_ctx->timearray) { int pos, pos2; TimeType *t, tm; int y = GLOBALS->fontheight + 2; int oldx = -1; timearray_encountered = 1; pos = bsearch_timechain (GLOBALS->tims.start); top: if ((pos >= 0) && (pos < GLOBALS->strace_ctx->timearray_size)) { pr_setgray (prc, (s_ctx_iter==0) ? 0.90 : 0.75); t = GLOBALS->strace_ctx->timearray + pos; for (; pos < GLOBALS->strace_ctx->timearray_size; t++, pos++) { tm = *t; if (tm >= GLOBALS->tims.start) { if (tm <= GLOBALS->tims.end) { x = (tm - GLOBALS->tims.start) * GLOBALS->pxns; if (oldx == x) { pos2 = bsearch_timechain (GLOBALS->tims.start + (((gdouble) (x + 1)) * GLOBALS->nspx)); if (pos2 > pos) { pos = pos2; goto top; } else continue; } oldx = x; pr_draw_line (prc, x, y, x, GLOBALS->liney_max); } else { break; } } } } } } GLOBALS->strace_ctx = &GLOBALS->strace_windows[GLOBALS->strace_current_window = 0]; /**********/ if(GLOBALS->ruler_step && !timearray_encountered) { TimeType rhs = (GLOBALS->tims.end > GLOBALS->tims.last) ? GLOBALS->tims.last : GLOBALS->tims.end; TimeType low_x = (GLOBALS->tims.start - GLOBALS->ruler_origin) / GLOBALS->ruler_step; TimeType high_x = (rhs - GLOBALS->ruler_origin) / GLOBALS->ruler_step; TimeType iter_x, tm; int y=GLOBALS->fontheight+2; int oldx=-1; pr_setgray (prc, 0.90); for(iter_x = low_x; iter_x <= high_x; iter_x++) { tm = GLOBALS->ruler_step * iter_x + GLOBALS->ruler_origin; x=(tm-GLOBALS->tims.start)*GLOBALS->pxns; if(oldx==x) { gdouble xd,offset,pixstep; TimeType newcurr; xd=x+1; /* for pix time calc */ pixstep=((gdouble)GLOBALS->nsperframe)/((gdouble)GLOBALS->pixelsperframe); newcurr=(TimeType)(offset=((gdouble)GLOBALS->tims.start)+(xd*pixstep)); if(offset-newcurr>0.5) /* round to nearest integer ns */ { newcurr++; } low_x = (newcurr - GLOBALS->ruler_origin) / GLOBALS->ruler_step; if(low_x <= iter_x) low_x = (iter_x+1); iter_x = low_x; tm = GLOBALS->ruler_step * iter_x + GLOBALS->ruler_origin; x=(tm-GLOBALS->tims.start)*GLOBALS->pxns; } if(x>=GLOBALS->wavewidth) break; oldx=x; pr_draw_line (prc, x, y, x, GLOBALS->liney_max); } } /**********/ DEBUG (printf ("Ruler Start time: " TTFormat ", Finish time: " TTFormat "\n", GLOBALS->tims.start, GLOBALS->tims.end)); x = 0; realx = 0; if (tim) { rem = tim % GLOBALS->nsperframe; if (rem) { tim = tim - GLOBALS->nsperframe - rem; x = -GLOBALS->pixelsperframe - ((rem * GLOBALS->pixelsperframe) / GLOBALS->nsperframe); realx=-GLOBALS->pixelsperframe-((rem*GLOBALS->pixelsperframe)/GLOBALS->nsperframe); } } for (;;) { pr_renderhash (prc, realx, tim); if (tim + GLOBALS->global_time_offset) { if(tim != GLOBALS->min_time) { reformat_time (timebuff, time_trunc (tim) + GLOBALS->global_time_offset, GLOBALS->time_dimension); } else { timebuff[0] = 0; } } else { strcpy (timebuff, "0"); } len = font_engine_string_measure (GLOBALS->wavefont, timebuff) >> 1; lenhalf = len >> 1; if ((prc->gpd == &ps_print_device) || ((x - lenhalf >= 0) && (x + lenhalf < GLOBALS->wavewidth))) { pr_setgray (prc, 0.0); if ((x - lenhalf >= lastx) || (GLOBALS->pixelsperframe >= 200)) { pr_draw_string (prc, x - lenhalf, GLOBALS->wavefont->ascent + 1, timebuff, len, GLOBALS->wavefont->ascent); } } lastx = x + lenhalf; tim += GLOBALS->nsperframe; x += GLOBALS->pixelsperframe; realx+=GLOBALS->pixelsperframe; if ((x >= GLOBALS->wavewidth) || (tim > GLOBALS->tims.last)) break; } } /*************************************************/ static void pr_render_individual_named_marker ( pr_context * prc, int i, gdouble gray, int blackout) { gdouble pixstep; gint xl, y; TimeType t; if ((t = GLOBALS->named_markers[i]) != -1) { if ((t >= GLOBALS->tims.start) && (t <= GLOBALS->tims.last) && (t <= GLOBALS->tims.end)) { /* this needs to be here rather than outside the loop as gcc does some optimizations that cause it to calculate slightly different from the marker if it's not here */ pixstep = ((gdouble) GLOBALS->nsperframe) / ((gdouble) GLOBALS->pixelsperframe); xl = ((gdouble) (t - GLOBALS->tims.start)) / pixstep; /* snap to integer */ if ((xl >= 0) && (xl < GLOBALS->wavewidth)) { char nbuff[16]; make_bijective_marker_id_string(nbuff, i); pr_setgray (prc, gray); for (y = GLOBALS->fontheight - 1; y <= GLOBALS->liney_max - 5; y += 8) { pr_draw_line (prc, xl, y, xl, y + 5); } if((!GLOBALS->marker_names[i])||(!GLOBALS->marker_names[i][0])) { int xsize = font_engine_string_measure (GLOBALS->wavefont, nbuff); pr_setgray (prc, 0.00); pr_draw_string (prc, xl - (xsize >> 1) + 1, GLOBALS->fontheight - 1, nbuff, xsize, (prc->gpd == &ps_print_device) ? GLOBALS->wavefont-> ascent / 2 : GLOBALS->wavefont->ascent); } else { int boxheight = GLOBALS->wavefont-> ascent + GLOBALS->wavefont-> descent; int xsize = font_engine_string_measure (GLOBALS->wavefont, GLOBALS->marker_names[i]); int ysize = (prc->gpd == &ps_print_device) ? GLOBALS->wavefont-> ascent / 2 : GLOBALS->wavefont->ascent; int boxysize = (prc->gpd == &ps_print_device) ? boxheight / 2 : boxheight; if(blackout) /* blackout background so text is legible if overlaid with other marker labels */ { pr_setgray (prc, 1.00); pr_draw_box(prc, xl-(xsize>>1) + 1, GLOBALS->fontheight-2-ysize, (xl-(xsize>>1) + 1) + xsize, (GLOBALS->fontheight-2-ysize) + boxysize); } pr_setgray (prc, 0.00); pr_draw_string (prc, xl - (xsize >> 1) + 1, GLOBALS->fontheight - 1, GLOBALS->marker_names[i], xsize, ysize); } } } } } static void pr_draw_named_markers (pr_context * prc) { int i; for(i=0;inamed_marker_lock_idx) { pr_render_individual_named_marker(prc, i, 0.40, 0); } } if(GLOBALS->named_marker_lock_idx >= 0) { pr_render_individual_named_marker(prc, GLOBALS->named_marker_lock_idx, 0.65, 1); } } static void pr_draw_marker (pr_context * prc) { gdouble pixstep; gint xl; if (GLOBALS->tims.baseline != -1) { if ((GLOBALS->tims.baseline >= GLOBALS->tims.start) && (GLOBALS->tims.baseline <= GLOBALS->tims.last) && (GLOBALS->tims.baseline <= GLOBALS->tims.end)) { pixstep = ((gdouble) GLOBALS->nsperframe) / ((gdouble) GLOBALS->pixelsperframe); xl = ((gdouble) (GLOBALS->tims.baseline - GLOBALS->tims.start)) / pixstep; /* snap to integer */ if ((xl >= 0) && (xl < GLOBALS->wavewidth)) { pr_setgray (prc, 0.65); pr_draw_line (prc, xl, GLOBALS->fontheight - 1, xl, GLOBALS->liney_max); } } } if (GLOBALS->tims.marker != -1) { if ((GLOBALS->tims.marker >= GLOBALS->tims.start) && (GLOBALS->tims.marker <= GLOBALS->tims.last) && (GLOBALS->tims.marker <= GLOBALS->tims.end)) { pixstep = ((gdouble) GLOBALS->nsperframe) / ((gdouble) GLOBALS->pixelsperframe); xl = ((gdouble) (GLOBALS->tims.marker - GLOBALS->tims.start)) / pixstep; /* snap to integer */ if ((xl >= 0) && (xl < GLOBALS->wavewidth)) { pr_setgray (prc, 0.40); pr_draw_line (prc, xl, GLOBALS->fontheight - 1, xl, GLOBALS->liney_max); } } } } /*************************************************/ /* * draw single traces and use this for rendering the grid lines for * "excluded" traces */ static void pr_draw_hptr_trace (pr_context * prc, Trptr t, hptr h, int which, int dodraw, int kill_grid) { TimeType _x0, _x1, newtime; int _y0, _y1, yu, liney, ytext, ysiz; TimeType tim, h2tim; hptr h2, h3; char hval, h2val; char identifier_str[2]; int is_event = t && t->n.nd && (t->n.nd->vartype == ND_VCD_EVENT); GLOBALS->tims.start -= GLOBALS->shift_timebase; GLOBALS->tims.end -= GLOBALS->shift_timebase; liney = ((which + 2) * GLOBALS->fontheight) - 2; if ((t && (t->flags & TR_INVERT))&&(!is_event)) { _y0 = ((which + 1) * GLOBALS->fontheight) + 2; _y1 = liney - 2; } else { _y1 = ((which + 1) * GLOBALS->fontheight) + 2; _y0 = liney - 2; } yu = (_y0 + _y1) / 2; ytext = yu - (GLOBALS->wavefont->ascent / 2) + GLOBALS->wavefont->ascent; ysiz = GLOBALS->wavefont->ascent - 1; if ((GLOBALS->display_grid) && (GLOBALS->enable_horiz_grid) && (!kill_grid)) { pr_setgray (prc, 0.75); pr_draw_line (prc, (GLOBALS->tims.start < GLOBALS->tims.first) ? (GLOBALS->tims.first - GLOBALS->tims.start) * GLOBALS->pxns : 0, liney, (GLOBALS->tims.last <= GLOBALS->tims.end) ? (GLOBALS->tims.last - GLOBALS->tims.start) * GLOBALS->pxns : GLOBALS->wavewidth - 1, liney); } pr_setgray (prc, 0.0); if ((h) && (GLOBALS->tims.start == h->time)) { pr_draw_line (prc, 0, _y0, 0, _y1); } if (dodraw && t) for (;;) { if (!h) break; tim = (h->time); if ((tim > GLOBALS->tims.end) || (tim > GLOBALS->tims.last)) break; _x0 = (tim - GLOBALS->tims.start) * GLOBALS->pxns; if (_x0 < -1) { _x0 = -1; } else if (_x0 > GLOBALS->wavewidth) { break; } h2 = h->next; if (!h2) break; h2tim = tim = (h2->time); if (tim > GLOBALS->tims.last) tim = GLOBALS->tims.last; else if (tim > GLOBALS->tims.end + 1) tim = GLOBALS->tims.end + 1; _x1 = (tim - GLOBALS->tims.start) * GLOBALS->pxns; if (_x1 < -1) { _x1 = -1; } else if (_x1 > GLOBALS->wavewidth) { _x1 = GLOBALS->wavewidth; } if (_x0 != _x1) { if(is_event) { if(h->time >= GLOBALS->tims.first) { pr_draw_line(prc, _x0, _y0, _x0, _y1); pr_draw_line(prc, _x0, _y1, _x0+2, _y1+2); pr_draw_line(prc, _x0, _y1, _x0-2, _y1+2); } h=h->next; continue; } hval = h->v.h_val; h2val = h2->v.h_val; switch (hval) { case AN_0: /* 0 */ case AN_L: /* 0 */ pr_draw_line (prc, _x0, _y0, _x1, _y0); if (h2tim <= GLOBALS->tims.end) switch (h2val) { case AN_0: case AN_L: break; case AN_Z: pr_draw_line (prc, _x1, _y0, _x1, yu); break; default: pr_draw_line (prc, _x1, _y0, _x1, _y1); break; } break; case AN_X: /* X */ case AN_W: /* X */ case AN_U: /* X */ case AN_DASH: /* X */ pr_setgray (prc, 0.70); pr_draw_box (prc, _x0, _y0, _x1, _y1); pr_setgray (prc, 0.0); identifier_str[1] = 0; switch (hval) { case AN_X: identifier_str[0] = 0; break; case AN_W: identifier_str[0] = 'W'; break; case AN_U: identifier_str[0] = 'U'; break; default: identifier_str[0] = '-'; break; } if (identifier_str[0]) { int _x0_new = (_x0 >= 0) ? _x0 : 0; int width; int pixlen = 0; if ((width = _x1 - _x0_new) > GLOBALS->vector_padding) { if ((_x1 >= GLOBALS->wavewidth) || ((pixlen = font_engine_string_measure (GLOBALS->wavefont, identifier_str)) + GLOBALS->vector_padding <= width)) { pr_draw_string (prc, _x0 + 2, ytext, identifier_str, pixlen, ysiz); } } } if (_x0 >= 0) pr_draw_line (prc, _x0, _y0, _x0, _y1); pr_draw_line (prc, _x0, _y0, _x1, _y0); pr_draw_line (prc, _x0, _y1, _x1, _y1); if (h2tim <= GLOBALS->tims.end) pr_draw_line (prc, _x1, _y0, _x1, _y1); break; case AN_Z: /* Z */ pr_draw_line (prc, _x0, yu, _x1, yu); if (h2tim <= GLOBALS->tims.end) switch (h2val) { case AN_0: case AN_L: pr_draw_line (prc, _x1, yu, _x1, _y0); break; case AN_1: case AN_H: pr_draw_line (prc, _x1, yu, _x1, _y1); break; default: pr_draw_line (prc, _x1, _y0, _x1, _y1); break; } break; case AN_1: /* 1 */ case AN_H: /* 1 */ pr_draw_line (prc, _x0, _y1, _x1, _y1); if (h2tim <= GLOBALS->tims.end) switch (h2val) { case AN_1: case AN_H: break; case AN_0: case AN_L: pr_draw_line (prc, _x1, _y1, _x1, _y0); break; case AN_Z: pr_draw_line (prc, _x1, _y1, _x1, yu); break; default: pr_draw_line (prc, _x1, _y0, _x1, _y1); break; } break; default: break; } } else { pr_draw_line (prc, _x1, _y0, _x1, _y1); if(is_event) { pr_draw_line(prc, _x0, _y1, _x0+2, _y1+2); pr_draw_line(prc, _x0, _y1, _x0-2, _y1+2); } newtime = (((gdouble) (_x1 + WAVE_OPT_SKIP)) * GLOBALS->nspx) + GLOBALS->tims.start /*+ GLOBALS->shift_timebase*/; /* skip to next pixel */ h3 = bsearch_node (t->n.nd, newtime); if (h3->time > h->time) { h = h3; continue; } } h = h->next; } GLOBALS->tims.start += GLOBALS->shift_timebase; GLOBALS->tims.end += GLOBALS->shift_timebase; } /* * draw hptr vectors (integer+real) */ static void pr_draw_hptr_trace_vector_analog (pr_context * prc, Trptr t, hptr h, int which, int num_extension_clip, int num_extension) { TimeType _x0, _x1, newtime; int _y0, _y1, yu, liney, /* ytext, */ yt0, yt1; /* scan-build */ int _y0c; TimeType tim, h2tim; hptr h2, h3; int endcnt = 0; /* int ysiz; */ /* scan-build */ /* int type; */ /* scan-build */ /* int lasttype = -1; */ /* scan-build */ double mynan = strtod ("NaN", NULL); double tmin = mynan, tmax = mynan, tv, tv2; int is_nan = 0, is_nan2 = 0, is_inf = 0, is_inf2 = 0; int any_infs = 0, any_infp = 0, any_infm = 0; int skipcnt = 0; int line_in_range; liney = ((which + 2 + num_extension) * GLOBALS->fontheight) - 2; _y1 = ((which + 1) * GLOBALS->fontheight) + 2; _y0 = liney - 2; _y0c = (((which + 2 + num_extension_clip) * GLOBALS->fontheight) - 2) - 2; yu = (_y0 + _y1) / 2; /* ytext = yu - (GLOBALS->wavefont->ascent / 2) + GLOBALS->wavefont->ascent; */ /* scan-build */ /* scan-build : unused ysiz = GLOBALS->wavefont->ascent - 1; if (ysiz < 1) ysiz = 1; */ if (t->flags & TR_ANALOG_FULLSCALE) /* otherwise use dynamic */ { if((!t->minmax_valid)||(t->d_num_ext != num_extension)) { h3 = &t->n.nd->head; for (;;) { if (!h3) break; if ((h3->time >= GLOBALS->tims.first) && (h3->time <= GLOBALS->tims.last)) { tv = mynan; if (h3->flags & HIST_REAL) { #ifdef WAVE_HAS_H_DOUBLE if (!(h3->flags & HIST_STRING)) tv = h3->v.h_double; #else if (!(h3->flags & HIST_STRING) && h3->v.h_vector) tv = *(double *) h3->v.h_vector; #endif } else { if (h3->time <= GLOBALS->tims.last) tv = convert_real_vec (t, h3->v.h_vector); } if (!isnan (tv) && !isinf (tv)) { if (isnan (tmin) || tv < tmin) tmin = tv; if (isnan (tmax) || tv > tmax) tmax = tv; } else if (isinf (tv)) { any_infs = 1; if (tv > 0) { any_infp = 1; } else { any_infm = 1; } } } h3 = h3->next; } if (isnan (tmin) || isnan (tmax)) tmin = tmax = 0; if (any_infs) { double tdelta = (tmax - tmin) * WAVE_INF_SCALING; if (any_infp) tmax = tmax + tdelta; if (any_infm) tmin = tmin - tdelta; } if ((tmax - tmin) < 1e-20) { tmax = 1; tmin -= 0.5 * (_y1 - _y0); } else { tmax = (_y1 - _y0) / (tmax - tmin); } t->minmax_valid = 1; t->d_minval = tmin; t->d_maxval = tmax; t->d_num_ext = num_extension; } else { tmin = t->d_minval; tmax = t->d_maxval; } } else { h3 = h; for (;;) { if (!h3) break; tim = h3->time; if (tim > GLOBALS->tims.end) { endcnt++; if (endcnt == 2) break; } if (tim > GLOBALS->tims.last) break; _x0 = (tim - GLOBALS->tims.start) * GLOBALS->pxns; if ((_x0 > GLOBALS->wavewidth) && (endcnt == 2)) break; tv = mynan; if (h3->flags & HIST_REAL) { #ifdef WAVE_HAS_H_DOUBLE if (!(h3->flags & HIST_STRING)) tv = h3->v.h_double; #else if (!(h3->flags & HIST_STRING) && h3->v.h_vector) tv = *(double *) h3->v.h_vector; #endif } else { if (h3->time <= GLOBALS->tims.last) tv = convert_real_vec (t, h3->v.h_vector); } if (!isnan (tv) && !isinf (tv)) { if (isnan (tmin) || tv < tmin) tmin = tv; if (isnan (tmax) || tv > tmax) tmax = tv; } else if (isinf (tv)) { any_infs = 1; if (tv > 0) { any_infp = 1; } else { any_infm = 1; } } h3 = h3->next; } if (isnan (tmin) || isnan (tmax)) tmin = tmax = 0; if (any_infs) { double tdelta = (tmax - tmin) * WAVE_INF_SCALING; if (any_infp) tmax = tmax + tdelta; if (any_infm) tmin = tmin - tdelta; } if ((tmax - tmin) < 1e-20) { tmax = 1; tmin -= 0.5 * (_y1 - _y0); } else { tmax = (_y1 - _y0) / (tmax - tmin); } } pr_setgray (prc, 0.0); for (;;) { if (!h) break; tim = (h->time); if ((tim > GLOBALS->tims.end) || (tim > GLOBALS->tims.last)) break; _x0 = (tim - GLOBALS->tims.start) * GLOBALS->pxns; /* if (_x0 < -1) _x0 = -1; else if (_x0 > GLOBALS->wavewidth) break; */ h2 = h->next; if (!h2) break; h2tim = tim = (h2->time); if (tim > GLOBALS->tims.last) tim = GLOBALS->tims.last; /* else if (tim > GLOBALS->tims.end + 1) tim = GLOBALS->tims.end + 1; */ _x1 = (tim - GLOBALS->tims.start) * GLOBALS->pxns; /* if (_x1 < -1) _x1 = -1; else if (_x1 > GLOBALS->wavewidth) _x1 = GLOBALS->wavewidth; */ /* draw trans */ /* scan-build : unused type = (!(h->flags & (HIST_REAL | HIST_STRING))) ? vtype (t, h->v. h_vector) : AN_0; */ tv = tv2 = mynan; if (h->flags & HIST_REAL) { #ifdef WAVE_HAS_H_DOUBLE if (!(h->flags & HIST_STRING)) tv = h->v.h_double; #else if (!(h->flags & HIST_STRING) && h->v.h_vector) tv = *(double *) h->v.h_vector; #endif } else { if (h->time <= GLOBALS->tims.last) tv = convert_real_vec (t, h->v.h_vector); } if (h2->flags & HIST_REAL) { #ifdef WAVE_HAS_H_DOUBLE if (!(h2->flags & HIST_STRING)) tv2 = h2->v.h_double; #else if (!(h2->flags & HIST_STRING) && h2->v.h_vector) tv2 = *(double *) h2->v.h_vector; #endif } else { if (h2->time <= GLOBALS->tims.last) tv2 = convert_real_vec (t, h2->v.h_vector); } if ((is_inf = isinf (tv))) { if (tv < 0) { yt0 = _y0; } else { yt0 = _y1; } } else if ((is_nan = isnan (tv))) { yt0 = yu; } else { yt0 = _y0 + (tv - tmin) * tmax; } if ((is_inf2 = isinf (tv2))) { if (tv2 < 0) { yt1 = _y0; } else { yt1 = _y1; } } else if ((is_nan2 = isnan (tv2))) { yt1 = yu; } else { yt1 = _y0 + (tv2 - tmin) * tmax; } if ((_x0 != _x1) || (skipcnt < GLOBALS->analog_redraw_skip_count)) /* lower number = better performance */ { if(_x0==_x1) { skipcnt++; } else { skipcnt = 0; } if (h->next) { if (h->next->time > GLOBALS->max_time) { yt1 = yt0; } } if ((is_nan2) && (h2tim > GLOBALS->max_time)) is_nan2 = 0; /* clamp to top/bottom because of integer rounding errors */ if(yt0 < _y1) yt0 = _y1; else if(yt0 > _y0) yt0 = _y0; if(yt1 < _y1) yt1 = _y1; else if(yt1 > _y0) yt1 = _y0; /* clipping... */ { int coords[4]; int rect[4]; if(_x0 < INT_MIN) { coords[0] = INT_MIN; } else if(_x0 > INT_MAX) { coords[0] = INT_MAX; } else { coords[0] = _x0; } if(_x1 < INT_MIN) { coords[2] = INT_MIN; } else if(_x1 > INT_MAX) { coords[2] = INT_MAX; } else { coords[2] = _x1; } coords[1] = yt0; coords[3] = yt1; rect[0] = -10; rect[1] = _y1; rect[2] = GLOBALS->wavewidth + 10; rect[3] = _y0c; if((t->flags & (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP)) != TR_ANALOG_STEP) { line_in_range = wave_lineclip(coords, rect); } else { line_in_range = 1; if(coords[0] < rect[0]) coords[0] = rect[0]; if(coords[2] < rect[0]) coords[2] = rect[0]; if(coords[0] > rect[2]) coords[0] = rect[2]; if(coords[2] > rect[2]) coords[2] = rect[2]; if(coords[1] < rect[1]) coords[1] = rect[1]; if(coords[3] < rect[1]) coords[3] = rect[1]; if(coords[1] > rect[3]) coords[1] = rect[3]; if(coords[3] > rect[3]) coords[3] = rect[3]; } _x0 = coords[0]; yt0 = coords[1]; _x1 = coords[2]; yt1 = coords[3]; } /* ...clipping */ if (is_nan || is_nan2) { if(line_in_range) { if (is_nan) { pr_setgray (prc, 0.70); pr_draw_box (prc, _x0, _y1, _x1, _y0); pr_setgray (prc, 0.0); if ((t-> flags & (TR_ANALOG_INTERPOLATED | TR_ANALOG_STEP)) == (TR_ANALOG_INTERPOLATED | TR_ANALOG_STEP)) { pr_draw_line (prc, _x1 - 1, yt1, _x1 + 1, yt1); pr_draw_line (prc, _x1, yt1 - 1, _x1, yt1 + 1); pr_draw_line (prc, _x0 - 1, _y0, _x0 + 1, _y0); pr_draw_line (prc, _x0, _y0 - 1, _x0, _y0 + 1); pr_draw_line (prc, _x0 - 1, _y1, _x0 + 1, _y1); pr_draw_line (prc, _x0, _y1 - 1, _x0, _y1 + 1); } } if (is_nan2) { pr_draw_line (prc, _x0, yt0, _x1, yt0); if ((t-> flags & (TR_ANALOG_INTERPOLATED | TR_ANALOG_STEP)) == (TR_ANALOG_INTERPOLATED | TR_ANALOG_STEP)) { pr_setgray (prc, 0.70); pr_draw_line (prc, _x1, _y1, _x1, _y0); pr_setgray (prc, 0.0); pr_draw_line (prc, _x1 - 1, _y0, _x1 + 1, _y0); pr_draw_line (prc, _x1, _y0 - 1, _x1, _y0 + 1); pr_draw_line (prc, _x1 - 1, _y1, _x1 + 1, _y1); pr_draw_line (prc, _x1, _y1 - 1, _x1, _y1 + 1); } } } } else if (t->flags & TR_ANALOG_INTERPOLATED && !is_inf && !is_inf2) { if(line_in_range) { pr_draw_line (prc, _x0, yt0, _x1, yt1); if (t->flags & TR_ANALOG_STEP) { pr_draw_line (prc, _x0 - 1, yt0, _x0 + 1, yt0); pr_draw_line (prc, _x0, yt0 - 1, _x0, yt0 + 1); } } } else /* if (t->flags & TR_ANALOG_STEP) */ { if(line_in_range) { pr_draw_line (prc, _x0, yt0, _x1, yt0); pr_draw_line (prc, _x1, yt0, _x1, yt1); if ((t->flags & (TR_ANALOG_INTERPOLATED | TR_ANALOG_STEP)) == (TR_ANALOG_INTERPOLATED | TR_ANALOG_STEP)) { pr_draw_line (prc, _x0 - 1, yt0, _x0 + 1, yt0); pr_draw_line (prc, _x0, yt0 - 1, _x0, yt0 + 1); } } } } else { newtime = (((gdouble) (_x1 + WAVE_OPT_SKIP)) * GLOBALS->nspx) + GLOBALS->tims.start /*+ GLOBALS->shift_timebase*/; /* skip to next pixel */ h3 = bsearch_node (t->n.nd, newtime); if (h3->time > h->time) { h = h3; /* lasttype = type; */ continue; } } h = h->next; /* lasttype = type; */ } } static void pr_draw_hptr_trace_vector (pr_context * prc, Trptr t, hptr h, int which) { TimeType _x0, _x1, newtime, width; int _y0, _y1, yu, liney, ytext; TimeType tim /* , h2tim */; /* scan-build */ hptr h2, h3; char *ascii = NULL; int pixlen, ysiz; int type; int lasttype = -1; GLOBALS->tims.start -= GLOBALS->shift_timebase; GLOBALS->tims.end -= GLOBALS->shift_timebase; liney = ((which + 2) * GLOBALS->fontheight) - 2; _y1 = ((which + 1) * GLOBALS->fontheight) + 2; _y0 = liney - 2; yu = (_y0 + _y1) / 2; ytext = yu - (GLOBALS->wavefont->ascent / 2) + GLOBALS->wavefont->ascent; ysiz = GLOBALS->wavefont->ascent - 1; if (ysiz < 1) ysiz = 1; if ((GLOBALS->display_grid) && (GLOBALS->enable_horiz_grid)) { Trptr tn = GiveNextTrace(t); if ((t->flags & TR_ANALOGMASK) && (tn) && (tn->flags & TR_ANALOG_BLANK_STRETCH)) { } else { pr_setgray (prc, 0.75); pr_draw_line (prc, (GLOBALS->tims.start < GLOBALS->tims.first) ? (GLOBALS->tims.first - GLOBALS->tims.start) * GLOBALS->pxns : 0, liney, (GLOBALS->tims.last <= GLOBALS->tims.end) ? (GLOBALS->tims.last - GLOBALS->tims.start) * GLOBALS->pxns : GLOBALS->wavewidth - 1, liney); } } if ((t->flags & TR_ANALOGMASK) && (!(h->flags & HIST_STRING) || !(h->flags & HIST_REAL))) { Trptr te = GiveNextTrace(t); int ext = 0; int ext_total; int num_traces_displayable = GLOBALS->signalarea->allocation.height / GLOBALS->fontheight; while (te) { if (te->flags & TR_ANALOG_BLANK_STRETCH) { ext++; te = GiveNextTrace(te); } else { break; } } ext_total = ext; if (which + ext > num_traces_displayable - 2) { ext = num_traces_displayable - which - 2; if (ext < 0) ext = 0; /* just in case of a one-off */ } pr_draw_hptr_trace_vector_analog (prc, t, h, which, ext, ext_total); GLOBALS->tims.start -= GLOBALS->shift_timebase; GLOBALS->tims.end -= GLOBALS->shift_timebase; return; } pr_setgray (prc, 0.0); for (;;) { if (!h) break; tim = (h->time); if ((tim > GLOBALS->tims.end) || (tim > GLOBALS->tims.last)) break; _x0 = (tim - GLOBALS->tims.start) * GLOBALS->pxns; if (_x0 < -1) _x0 = -1; else if (_x0 > GLOBALS->wavewidth) break; h2 = h->next; if (!h2) break; /* h2tim = */ tim = (h2->time); /* scan-build */ if (tim > GLOBALS->tims.last) tim = GLOBALS->tims.last; else if (tim > GLOBALS->tims.end + 1) tim = GLOBALS->tims.end + 1; _x1 = (tim - GLOBALS->tims.start) * GLOBALS->pxns; if (_x1 < -1) _x1 = -1; else if (_x1 > GLOBALS->wavewidth) _x1 = GLOBALS->wavewidth; /* draw trans */ if(!(h->flags&(HIST_REAL|HIST_STRING))) { type = vtype(t,h->v.h_vector); } else { /* s\000 ID is special "z" case */ type = AN_0; if(h->flags&HIST_STRING) { if(h->v.h_vector) { if(!h->v.h_vector[0]) { type = AN_Z; } else { if(!strcmp(h->v.h_vector, "UNDEF")) { type = AN_X; } } } else { type = AN_X; } } } /* type = !(h->flags & (HIST_REAL | HIST_STRING))) ? vtype (t, h->v.h_vector) : AN_0; */ if (_x0 > -1) { if (GLOBALS->use_roundcaps) { if (type == AN_Z) { if (lasttype != -1) { pr_draw_line (prc, _x0 - 1, _y0, _x0, yu); pr_draw_line (prc, _x0, yu, _x0 - 1, _y1); } } else if (lasttype == AN_Z) { pr_draw_line (prc, _x0 + 1, _y0, _x0, yu); pr_draw_line (prc, _x0, yu, _x0 + 1, _y1); } else { if (lasttype != type) { pr_draw_line (prc, _x0 - 1, _y0, _x0, yu); pr_draw_line (prc, _x0, yu, _x0 - 1, _y1); pr_draw_line (prc, _x0 + 1, _y0, _x0, yu); pr_draw_line (prc, _x0, yu, _x0 + 1, _y1); } else { pr_draw_line (prc, _x0 - 2, _y0, _x0 + 2, _y1); pr_draw_line (prc, _x0 + 2, _y0, _x0 - 2, _y1); } } } else { pr_draw_line (prc, _x0, _y0, _x0, _y1); } } if (_x0 != _x1) { if (type == AN_Z) { if (GLOBALS->use_roundcaps) { pr_draw_line (prc, _x0 + 1, yu, _x1 - 1, yu); } else { pr_draw_line (prc, _x0, yu, _x1, yu); } } else { if (GLOBALS->use_roundcaps) { pr_draw_line (prc, _x0 + 2, _y0, _x1 - 2, _y0); pr_draw_line (prc, _x0 + 2, _y1, _x1 - 2, _y1); } else { pr_draw_line (prc, _x0, _y0, _x1, _y0); pr_draw_line (prc, _x0, _y1, _x1, _y1); } if (_x0 < 0) _x0 = 0; /* fixup left margin */ width = ((prc->gpd == &ps_print_device) || (_x1 < GLOBALS->wavewidth)) ? _x1 - _x0 : GLOBALS->wavewidth - _x0; /* truncate render * window for non-ps */ if (width > GLOBALS->vector_padding) { char *t_ascii; /* to skip past color ? ? string */ if (h->flags & HIST_REAL) { if (!(h->flags & HIST_STRING)) { #ifdef WAVE_HAS_H_DOUBLE ascii = convert_ascii_real (t, &h->v.h_double); #else ascii = convert_ascii_real (t, (double *) h->v.h_vector); #endif } else { ascii = convert_ascii_string ((char *) h->v.h_vector); } } else { ascii = convert_ascii_vec (t, h->v.h_vector); } if((*ascii=='?')&&((t_ascii=strchr(ascii+1, '?')))) { t_ascii++; } else { t_ascii = ascii; } if (((pixlen = font_engine_string_measure (GLOBALS->wavefont, t_ascii)) + GLOBALS->vector_padding <= width) || ((_x1 >= GLOBALS->wavewidth) && (prc->gpd == &ps_print_device))) { pr_draw_string (prc, _x0 + 2, ytext, t_ascii, pixlen, ysiz); } else { char *mod; mod = bsearch_trunc (t_ascii, width - GLOBALS->vector_padding); if (mod) { *mod = '+'; *(mod + 1) = 0; pr_draw_string (prc, _x0 + 2, ytext, t_ascii, GLOBALS->maxlen_trunc, ysiz); } } } } } else { newtime = (((gdouble) (_x1 + WAVE_OPT_SKIP)) * GLOBALS->nspx) + GLOBALS->tims.start /*+ GLOBALS->shift_timebase*/; /* skip to next pixel */ h3 = bsearch_node (t->n.nd, newtime); if (h3->time > h->time) { h = h3; lasttype = type; continue; } } if (ascii) { free_2 (ascii); ascii = NULL; } h = h->next; lasttype = type; } GLOBALS->tims.start += GLOBALS->shift_timebase; GLOBALS->tims.end += GLOBALS->shift_timebase; } /* * draw vector traces */ static void pr_draw_vptr_trace_analog (pr_context * prc, Trptr t, vptr v, int which, int num_extension_clip, int num_extension) { TimeType _x0, _x1, newtime; int _y0, _y1, yu, liney, /* ytext, */ yt0, yt1; /* scan-build */ int _y0c; TimeType tim, h2tim; vptr h, h2, h3; int endcnt = 0; /* int ysiz; */ /* scan-build */ /* int type; */ /* scan-build */ /* int lasttype = -1; */ /* scan-build */ double mynan = strtod ("NaN", NULL); double tmin = mynan, tmax = mynan, tv, tv2; int is_nan = 0, is_nan2 = 0, is_inf = 0, is_inf2 = 0; int any_infs = 0, any_infp = 0, any_infm = 0; int skipcnt = 0; int line_in_range; h = v; liney = ((which + 2 + num_extension) * GLOBALS->fontheight) - 2; _y1 = ((which + 1) * GLOBALS->fontheight) + 2; _y0 = liney - 2; _y0c = (((which + 2 + num_extension_clip) * GLOBALS->fontheight) - 2) - 2; yu = (_y0 + _y1) / 2; /* ytext = yu - (GLOBALS->wavefont->ascent / 2) + GLOBALS->wavefont->ascent; */ /* scan-build */ /* scan-build : unused ysiz = GLOBALS->wavefont->ascent - 1; if (ysiz < 1) ysiz = 1; */ if (t->flags & TR_ANALOG_FULLSCALE) /* otherwise use dynamic */ { if((!t->minmax_valid)||(t->d_num_ext != num_extension)) { h3 = t->n.vec->vectors[0]; for (;;) { if (!h3) break; if ((h3->time >= GLOBALS->tims.first) && (h3->time <= GLOBALS->tims.last)) { /* tv = mynan; */ /* scan-build */ tv = convert_real (t, h3); if (!isnan (tv) && !isinf (tv)) { if (isnan (tmin) || tv < tmin) tmin = tv; if (isnan (tmax) || tv > tmax) tmax = tv; } else if (isinf (tv)) { any_infs = 1; if (tv > 0) { any_infp = 1; } else { any_infm = 1; } } } h3 = h3->next; } if (isnan (tmin) || isnan (tmax)) tmin = tmax = 0; if (any_infs) { double tdelta = (tmax - tmin) * WAVE_INF_SCALING; if (any_infp) tmax = tmax + tdelta; if (any_infm) tmin = tmin - tdelta; } if ((tmax - tmin) < 1e-20) { tmax = 1; tmin -= 0.5 * (_y1 - _y0); } else { tmax = (_y1 - _y0) / (tmax - tmin); } t->minmax_valid = 1; t->d_minval = tmin; t->d_maxval = tmax; t->d_num_ext = num_extension; } else { tmin = t->d_minval; tmax = t->d_maxval; } } else { h3 = h; for (;;) { if (!h3) break; tim = h3->time; if (tim > GLOBALS->tims.end) { endcnt++; if (endcnt == 2) break; } if (tim > GLOBALS->tims.last) break; _x0 = (tim - GLOBALS->tims.start) * GLOBALS->pxns; if ((_x0 > GLOBALS->wavewidth) && (endcnt == 2)) { break; } tv = convert_real (t, h3); if (!isnan (tv) && !isinf (tv)) { if (isnan (tmin) || tv < tmin) tmin = tv; if (isnan (tmax) || tv > tmax) tmax = tv; } else if (isinf (tv)) { any_infs = 1; if (tv > 0) { any_infp = 1; } else { any_infm = 1; } } h3 = h3->next; } if (isnan (tmin) || isnan (tmax)) tmin = tmax = 0; if (any_infs) { double tdelta = (tmax - tmin) * WAVE_INF_SCALING; if (any_infp) tmax = tmax + tdelta; if (any_infm) tmin = tmin - tdelta; } if ((tmax - tmin) < 1e-20) { tmax = 1; tmin -= 0.5 * (_y1 - _y0); } else { tmax = (_y1 - _y0) / (tmax - tmin); } } pr_setgray (prc, 0.0); for (;;) { if (!h) break; tim = (h->time); if ((tim > GLOBALS->tims.end) || (tim > GLOBALS->tims.last)) break; _x0 = (tim - GLOBALS->tims.start) * GLOBALS->pxns; /* if (_x0 < -1) _x0 = -1; else if (_x0 > GLOBALS->wavewidth) break; */ h2 = h->next; if (!h2) break; h2tim = tim = (h2->time); if (tim > GLOBALS->tims.last) tim = GLOBALS->tims.last; /* else if (tim > GLOBALS->tims.end + 1) tim = GLOBALS->tims.end + 1; */ _x1 = (tim - GLOBALS->tims.start) * GLOBALS->pxns; /* if (_x1 < -1) _x1 = -1; else if (_x1 > GLOBALS->wavewidth) _x1 = GLOBALS->wavewidth; */ /* draw trans */ /* type = vtype2 (t, h); */ /* scan-build */ tv = convert_real (t, h); tv2 = convert_real (t, h2); if ((is_inf = isinf (tv))) { if (tv < 0) { yt0 = _y0; } else { yt0 = _y1; } } else if ((is_nan = isnan (tv))) { yt0 = yu; } else { yt0 = _y0 + (tv - tmin) * tmax; } if ((is_inf2 = isinf (tv2))) { if (tv2 < 0) { yt1 = _y0; } else { yt1 = _y1; } } else if ((is_nan2 = isnan (tv2))) { yt1 = yu; } else { yt1 = _y0 + (tv2 - tmin) * tmax; } if((_x0!=_x1)||(skipcnt < GLOBALS->analog_redraw_skip_count)) /* lower number = better performance */ { if(_x0==_x1) { skipcnt++; } else { skipcnt = 0; } if (h->next) { if (h->next->time > GLOBALS->max_time) { yt1 = yt0; } } if ((is_nan2) && (h2tim > GLOBALS->max_time)) is_nan2 = 0; /* clamp to top/bottom because of integer rounding errors */ if(yt0 < _y1) yt0 = _y1; else if(yt0 > _y0) yt0 = _y0; if(yt1 < _y1) yt1 = _y1; else if(yt1 > _y0) yt1 = _y0; /* clipping... */ { int coords[4]; int rect[4]; if(_x0 < INT_MIN) { coords[0] = INT_MIN; } else if(_x0 > INT_MAX) { coords[0] = INT_MAX; } else { coords[0] = _x0; } if(_x1 < INT_MIN) { coords[2] = INT_MIN; } else if(_x1 > INT_MAX) { coords[2] = INT_MAX; } else { coords[2] = _x1; } coords[1] = yt0; coords[3] = yt1; rect[0] = -10; rect[1] = _y1; rect[2] = GLOBALS->wavewidth + 10; rect[3] = _y0c; if((t->flags & (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP)) != TR_ANALOG_STEP) { line_in_range = wave_lineclip(coords, rect); } else { line_in_range = 1; if(coords[0] < rect[0]) coords[0] = rect[0]; if(coords[2] < rect[0]) coords[2] = rect[0]; if(coords[0] > rect[2]) coords[0] = rect[2]; if(coords[2] > rect[2]) coords[2] = rect[2]; if(coords[1] < rect[1]) coords[1] = rect[1]; if(coords[3] < rect[1]) coords[3] = rect[1]; if(coords[1] > rect[3]) coords[1] = rect[3]; if(coords[3] > rect[3]) coords[3] = rect[3]; } _x0 = coords[0]; yt0 = coords[1]; _x1 = coords[2]; yt1 = coords[3]; } /* ...clipping */ if (is_nan || is_nan2) { if(line_in_range) { if (is_nan) { pr_setgray (prc, 0.70); pr_draw_box (prc, _x0, _y1, _x1, _y0); pr_setgray (prc, 0.0); if ((t-> flags & (TR_ANALOG_INTERPOLATED | TR_ANALOG_STEP)) == (TR_ANALOG_INTERPOLATED | TR_ANALOG_STEP)) { pr_draw_line (prc, _x1 - 1, yt1, _x1 + 1, yt1); pr_draw_line (prc, _x1, yt1 - 1, _x1, yt1 + 1); pr_draw_line (prc, _x0 - 1, _y0, _x0 + 1, _y0); pr_draw_line (prc, _x0, _y0 - 1, _x0, _y0 + 1); pr_draw_line (prc, _x0 - 1, _y1, _x0 + 1, _y1); pr_draw_line (prc, _x0, _y1 - 1, _x0, _y1 + 1); } } if (is_nan2) { pr_draw_line (prc, _x0, yt0, _x1, yt0); if ((t-> flags & (TR_ANALOG_INTERPOLATED | TR_ANALOG_STEP)) == (TR_ANALOG_INTERPOLATED | TR_ANALOG_STEP)) { pr_setgray (prc, 0.70); pr_draw_line (prc, _x1, _y1, _x1, _y0); pr_setgray (prc, 0.0); pr_draw_line (prc, _x1 - 1, _y0, _x1 + 1, _y0); pr_draw_line (prc, _x1, _y0 - 1, _x1, _y0 + 1); pr_draw_line (prc, _x1 - 1, _y1, _x1 + 1, _y1); pr_draw_line (prc, _x1, _y1 - 1, _x1, _y1 + 1); } } } } else if ((t->flags & TR_ANALOG_INTERPOLATED) && !is_inf && !is_inf2) { if(line_in_range) { pr_draw_line (prc, _x0, yt0, _x1, yt1); if (t->flags & TR_ANALOG_STEP) { pr_draw_line (prc, _x0 - 1, yt0, _x0 + 1, yt0); pr_draw_line (prc, _x0, yt0 - 1, _x0, yt0 + 1); } } } else /* if (t->flags & TR_ANALOG_STEP) */ { if(line_in_range) { pr_draw_line (prc, _x0, yt0, _x1, yt0); pr_draw_line (prc, _x1, yt0, _x1, yt1); if ((t->flags & (TR_ANALOG_INTERPOLATED | TR_ANALOG_STEP)) == (TR_ANALOG_INTERPOLATED | TR_ANALOG_STEP)) { pr_draw_line (prc, _x0 - 1, yt0, _x0 + 1, yt0); pr_draw_line (prc, _x0, yt0 - 1, _x0, yt0 + 1); } } } } else { newtime = (((gdouble) (_x1 + WAVE_OPT_SKIP)) * GLOBALS->nspx) + GLOBALS->tims.start /*+ GLOBALS->shift_timebase*/; /* skip to next pixel */ h3 = bsearch_vector (t->n.vec, newtime); if (h3->time > h->time) { h = h3; /* lasttype = type; */ /* scan-build */ continue; } } h = h->next; /* lasttype = type; */ /* scan-build */ } GLOBALS->tims.start += GLOBALS->shift_timebase; GLOBALS->tims.end += GLOBALS->shift_timebase; } static void pr_draw_vptr_trace (pr_context * prc, Trptr t, vptr v, int which) { TimeType _x0, _x1, newtime, width; int _y0, _y1, yu, liney, ytext; TimeType tim /* , h2tim */; /* scan-build */ vptr h, h2, h3; char *ascii = NULL; int pixlen, ysiz; int type; int lasttype = -1; GLOBALS->tims.start -= GLOBALS->shift_timebase; GLOBALS->tims.end -= GLOBALS->shift_timebase; liney = ((which + 2) * GLOBALS->fontheight) - 2; _y1 = ((which + 1) * GLOBALS->fontheight) + 2; _y0 = liney - 2; yu = (_y0 + _y1) / 2; ytext = yu - (GLOBALS->wavefont->ascent / 2) + GLOBALS->wavefont->ascent; ysiz = GLOBALS->wavefont->ascent - 1; if (ysiz < 1) ysiz = 1; if ((GLOBALS->display_grid) && (GLOBALS->enable_horiz_grid)) { Trptr tn = GiveNextTrace(t); if ((t->flags & TR_ANALOGMASK) && (tn) && (tn->flags & TR_ANALOG_BLANK_STRETCH)) { } else { pr_setgray (prc, 0.75); pr_draw_line (prc, (GLOBALS->tims.start < GLOBALS->tims.first) ? (GLOBALS->tims.first - GLOBALS->tims.start) * GLOBALS->pxns : 0, liney, (GLOBALS->tims.last <= GLOBALS->tims.end) ? (GLOBALS->tims.last - GLOBALS->tims.start) * GLOBALS->pxns : GLOBALS->wavewidth - 1, liney); } } h = v; if (t->flags & TR_ANALOGMASK) { Trptr te = GiveNextTrace(t); int ext = 0; int ext_total; int num_traces_displayable = GLOBALS->signalarea->allocation.height / GLOBALS->fontheight; while (te) { if (te->flags & TR_ANALOG_BLANK_STRETCH) { ext++; te = GiveNextTrace(te); } else { break; } } ext_total = ext; if (which + ext > num_traces_displayable - 2) { ext = num_traces_displayable - which - 2; if (ext < 0) ext = 0; /* just in case of a one-off */ } pr_draw_vptr_trace_analog (prc, t, v, which, ext, ext_total); GLOBALS->tims.start+=GLOBALS->shift_timebase; GLOBALS->tims.end+=GLOBALS->shift_timebase; return; } pr_setgray (prc, 0.0); for (;;) { if (!h) break; tim = (h->time); if ((tim > GLOBALS->tims.end) || (tim > GLOBALS->tims.last)) break; _x0 = (tim - GLOBALS->tims.start) * GLOBALS->pxns; if (_x0 < -1) _x0 = -1; else if (_x0 > GLOBALS->wavewidth) break; h2 = h->next; if (!h2) break; /* h2tim = */ tim = (h2->time); /* scan-build */ if (tim > GLOBALS->tims.last) tim = GLOBALS->tims.last; else if (tim > GLOBALS->tims.end + 1) tim = GLOBALS->tims.end + 1; _x1 = (tim - GLOBALS->tims.start) * GLOBALS->pxns; if (_x1 < -1) _x1 = -1; else if (_x1 > GLOBALS->wavewidth) _x1 = GLOBALS->wavewidth; /* draw trans */ type = vtype2 (t, h); if (_x0 > -1) { if (GLOBALS->use_roundcaps) { if (type == 2) { if (lasttype != -1) { pr_draw_line (prc, _x0 - 1, _y0, _x0, yu); pr_draw_line (prc, _x0, yu, _x0 - 1, _y1); } } else if (lasttype == 2) { pr_draw_line (prc, _x0 + 1, _y0, _x0, yu); pr_draw_line (prc, _x0, yu, _x0 + 1, _y1); } else { if (lasttype != type) { pr_draw_line (prc, _x0 - 1, _y0, _x0, yu); pr_draw_line (prc, _x0, yu, _x0 - 1, _y1); pr_draw_line (prc, _x0 + 1, _y0, _x0, yu); pr_draw_line (prc, _x0, yu, _x0 + 1, _y1); } else { pr_draw_line (prc, _x0 - 2, _y0, _x0 + 2, _y1); pr_draw_line (prc, _x0 + 2, _y0, _x0 - 2, _y1); } } } else { pr_draw_line (prc, _x0, _y0, _x0, _y1); } } if (_x0 != _x1) { if (type == 2) { if (GLOBALS->use_roundcaps) { pr_draw_line (prc, _x0 + 1, yu, _x1 - 1, yu); } else { pr_draw_line (prc, _x0, yu, _x1, yu); } } else { if (GLOBALS->use_roundcaps) { pr_draw_line (prc, _x0 + 2, _y0, _x1 - 2, _y0); pr_draw_line (prc, _x0 + 2, _y1, _x1 - 2, _y1); } else { pr_draw_line (prc, _x0, _y0, _x1, _y0); pr_draw_line (prc, _x0, _y1, _x1, _y1); } if (_x0 < 0) _x0 = 0; /* fixup left margin */ width = ((prc->gpd == &ps_print_device) || (_x1 < GLOBALS->wavewidth)) ? _x1 - _x0 : GLOBALS->wavewidth - _x0; /* truncate render * window for non-ps */ if (width > GLOBALS->vector_padding) { char *t_ascii; ascii = convert_ascii (t, h); if((*ascii=='?')&&((t_ascii=strchr(ascii+1, '?')))) { t_ascii++; } else { t_ascii = ascii; } if (((pixlen = font_engine_string_measure (GLOBALS->wavefont, t_ascii)) + GLOBALS->vector_padding <= width) || ((_x1 >= GLOBALS->wavewidth) && (prc->gpd == &ps_print_device))) { pr_draw_string (prc, _x0 + 2, ytext, t_ascii, pixlen, ysiz); } else { char *mod; mod = bsearch_trunc (t_ascii, width - GLOBALS->vector_padding); if (mod) { *mod = '+'; *(mod + 1) = 0; pr_draw_string (prc, _x0 + 2, ytext, t_ascii, GLOBALS->maxlen_trunc, ysiz); } } } } } else { newtime = (((gdouble) (_x1 + WAVE_OPT_SKIP)) * GLOBALS->nspx) + GLOBALS->tims.start /*+ GLOBALS->shift_timebase*/; /* skip to next pixel */ h3 = bsearch_vector (t->n.vec, newtime); if (h3->time > h->time) { h = h3; lasttype = type; continue; } } if (ascii) { free_2 (ascii); ascii = NULL; } h = h->next; lasttype = type; } GLOBALS->tims.start += GLOBALS->shift_timebase; GLOBALS->tims.end += GLOBALS->shift_timebase; } static void pr_rendertraces (pr_context * prc) { if (!GLOBALS->topmost_trace) { GLOBALS->topmost_trace = GLOBALS->traces.first; } if (GLOBALS->topmost_trace) { Trptr t = GLOBALS->topmost_trace; Trptr tback = t; hptr h; vptr v; int i = 0, num_traces_displayable; int iback = 0; num_traces_displayable = GLOBALS->wavearea->allocation.height / (GLOBALS->fontheight); num_traces_displayable--; /* for the time trace that is * always there */ /* ensure that transaction traces are visible even if the topmost traces are blanks */ while(tback) { if(tback->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH)) { tback = GivePrevTrace(tback); iback--; } else if(tback->flags & TR_TTRANSLATED) { if(tback != t) { t = tback; i = iback; } break; } else { break; } } for (; ((i < num_traces_displayable) && (t)); i++) { if (!(t->flags & (TR_EXCLUDE | TR_BLANK | TR_ANALOG_BLANK_STRETCH))) { GLOBALS->shift_timebase = t->shift; if (!t->vector) { h = bsearch_node (t->n.nd, GLOBALS->tims.start - t->shift); DEBUG (printf ("Start time: " TTFormat ", Histent time: " TTFormat "\n", GLOBALS->tims.start, (h->time + GLOBALS->shift_timebase))); if (!t->n.nd->extvals) { if(i>=0) pr_draw_hptr_trace (prc, t, h, i, 1, 0); } else { if(i>=0) pr_draw_hptr_trace_vector (prc, t, h, i); } } else { Trptr t_orig, tn; bvptr bv = t->n.vec; v = bsearch_vector (bv, GLOBALS->tims.start - t->shift); DEBUG (printf ("Vector Trace: %s, %s\n", t->name, t->n.vec->bvname)); DEBUG (printf ("Start time: " TTFormat ", Vectorent time: " TTFormat "\n", GLOBALS->tims.start, (v->time + GLOBALS->shift_timebase))); if(i>=0) pr_draw_vptr_trace (prc, t, v, i); if((bv->transaction_chain) && (t->flags & TR_TTRANSLATED)) { t_orig = t; for(;;) { tn = GiveNextTrace(t); bv = bv->transaction_chain; if(bv && tn && (tn->flags & (TR_BLANK|TR_ANALOG_BLANK_STRETCH))) { i++; if(itims.start - t->shift); if(i>=0) pr_draw_vptr_trace(prc, t_orig,v,i); t = tn; continue; } } break; } } } } else { int kill_dodraw_grid = t->flags & TR_ANALOG_BLANK_STRETCH; if (kill_dodraw_grid) { Trptr tn = GiveNextTrace(t); if (!tn) { kill_dodraw_grid = 0; } else if (!(tn->flags & TR_ANALOG_BLANK_STRETCH)) { kill_dodraw_grid = 0; } } if(i>=0) pr_draw_hptr_trace (prc, NULL, NULL, i, 0, kill_dodraw_grid); } t = GiveNextTrace (t); } } pr_draw_named_markers (prc); pr_draw_marker (prc); } /**********************************************/ static int pr_RenderSig (pr_context * prc, Trptr t, int i) { int texty, liney; int retval; char buf[2048]; char *subname = NULL; buf[0] = 0; if(t->flags & (TR_BLANK|TR_ANALOG_BLANK_STRETCH)) /* seek to real xact trace if present... */ { Trptr tscan = t; int bcnt = 0; while((tscan) && (tscan = GivePrevTrace(tscan))) { if(!(tscan->flags & (TR_BLANK|TR_ANALOG_BLANK_STRETCH))) { if(tscan->flags & TR_TTRANSLATED) { break; /* found it */ } else { tscan = NULL; } } else { bcnt++; /* bcnt is number of blank traces */ } } if((tscan)&&(tscan->vector)) { bvptr bv = tscan->n.vec; do { bv = bv->transaction_chain; /* correlate to blank trace */ } while(bv && (bcnt--)); if(bv) { subname = bv->bvname; if(GLOBALS->hier_max_level) subname = hier_extract(subname, GLOBALS->hier_max_level); } } } populateBuffer(t, subname, buf); UpdateSigValue (t); /* in case it's stale on nonprop */ liney = ((i + 2) * GLOBALS->fontheight) - 2; texty = liney - (GLOBALS->signalfont->descent); retval = liney - GLOBALS->fontheight + 1; if (t->flags & TR_HIGHLIGHT) pr_setgray (prc, 0.75); else pr_setgray (prc, 0.95); pr_draw_box (prc, 2, retval + 1, GLOBALS->pr_signal_fill_width_print_c_1 - 2, retval + GLOBALS->fontheight - 3); pr_setgray (prc, 0.75); pr_draw_line (prc, 0, liney, GLOBALS->pr_signal_fill_width_print_c_1 - 1, liney); /* if (!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH))) */ { int maxwidth = 0; maxwidth = strlen (buf); if ((t->asciivalue) && (!(t->flags & TR_EXCLUDE))) maxwidth += strlen (t->asciivalue); if (maxwidth) { gdouble realwidth; char *cbuf; cbuf = wave_alloca (maxwidth + 1); cbuf[0] = 0; if (buf[0]) { strcpy (cbuf, buf); } if ((t->asciivalue) && (!(t->flags & TR_EXCLUDE))) strcat (cbuf, t->asciivalue); realwidth = maxwidth * GLOBALS->ps_chwidth_print_c_1; if (maxwidth == 0) return (retval); pr_setgray (prc, 0.0); pr_draw_string (prc, 3, texty - 1, cbuf, realwidth, GLOBALS->signalfont->ascent - GLOBALS->signalfont->descent); } } return (retval); } static void pr_RenderSigs (pr_context * prc, int trtarget) { Trptr t; int i, trwhich /* , width */; /* scan-build */ int num_traces_displayable; /* GtkAdjustment *hadj; */ /* scan-build */ /* gint xsrc; */ /* scan-build */ /* hadj = GTK_ADJUSTMENT (GLOBALS->signal_hslider); */ /* scan-build */ /* xsrc = (gint) hadj->value; */ /* scan-build */ num_traces_displayable = GLOBALS->signalarea->allocation.height / (GLOBALS->fontheight); num_traces_displayable--; /* for the time trace that is always * there */ pr_setgray (prc, 0.75); pr_draw_line (prc, 0, GLOBALS->fontheight - 1, GLOBALS->pr_signal_fill_width_print_c_1 - 1, GLOBALS->fontheight - 1); pr_setgray (prc, 0.0); pr_draw_string (prc, 3, GLOBALS->fontheight, "Time", (/* width = */ /* scan-build */ font_engine_string_measure (GLOBALS->wavefont, "Time")) * 2, GLOBALS->fontheight); GLOBALS->ps_chwidth_print_c_1 = ((gdouble) (GLOBALS->pr_signal_fill_width_print_c_1 - 6)) / ((gdouble) (GLOBALS->ps_nummaxchars_print_c_1)); t = GLOBALS->traces.first; trwhich = 0; while (t) { if ((trwhich < trtarget) && (GiveNextTrace (t))) { trwhich++; t = GiveNextTrace (t); } else { break; } } GLOBALS->topmost_trace = t; if (t) { for (i = 0; (i < num_traces_displayable) && (t); i++) { pr_RenderSig (prc, t, i); t = GiveNextTrace (t); } } } /**********************************************/ void print_image (pr_context * prc) { GtkAdjustment *sadj; int trtarget; if ((GLOBALS->traces.total + 1) * GLOBALS->fontheight > GLOBALS->wavearea->allocation.height) GLOBALS->liney_max = GLOBALS->wavearea->allocation.height; else GLOBALS->liney_max = (GLOBALS->traces.total + 1) * GLOBALS->fontheight; GLOBALS->pr_signal_fill_width_print_c_1 = ps_MaxSignalLength (); pr_wave_init (prc); pr_header (prc); pr_rendertimes (prc); pr_rendertraces (prc); pr_signal_init (prc); sadj = GTK_ADJUSTMENT (GLOBALS->wave_vslider); trtarget = (int) (sadj->value); pr_RenderSigs (prc, trtarget); pr_trailer (prc); } void print_ps_image (FILE * wave, gdouble px, gdouble py) { pr_context prc; prc.gpd = &ps_print_device; prc.PageX = px; /* Legal page width */ prc.PageY = py; /* Legal page height */ prc.LM = 1; /* Left Margin (inch) */ prc.RM = 1; /* Right Margin (inch) */ prc.BM = 1; /* Bottom Margin (inch) */ prc.TM = 1; /* Top Margin (inch) */ prc.handle = wave; prc.fullpage = GLOBALS->ps_fullpage; print_image (&prc); } void print_mif_image (FILE * wave, gdouble px, gdouble py) { pr_context prc; prc.gpd = &mif_print_device; prc.PageX = px; /* Legal page width */ prc.PageY = py; /* Legal page height */ prc.LM = 1; /* Left Margin (inch) */ prc.RM = 1; /* Right Margin (inch) */ prc.BM = 1; /* Bottom Margin (inch) */ prc.TM = 1; /* Top Margin (inch) */ prc.tr_x = 0; prc.tr_y = 0; prc.handle = wave; prc.fullpage = GLOBALS->ps_fullpage; print_image (&prc); } gtkwave-3.3.66/src/ae2.c0000664000076400007640000011450612361631225014211 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2004-2011. * * 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. */ #include "globals.h" #include #include #ifndef _MSC_VER #include #endif #include #include #include #include "ae2.h" #include "symbol.h" #include "vcd.h" #include "lxt.h" #include "lxt2_read.h" #include "fgetdynamic.h" #include "debug.h" #include "busy.h" #include "hierpack.h" /* * select appropriate entry points based on if aet2 * support is available */ #ifndef AET2_IS_PRESENT const char *ae2_loader_fail_msg = "Sorry, AET2 support was not compiled into this executable, exiting.\n\n"; TimeType ae2_main(char *fname, char *skip_start, char *skip_end) { (void)fname; (void)skip_start; (void)skip_end; fprintf(stderr, "%s", ae2_loader_fail_msg); exit(255); return(0); /* for vc++ */ } void ae2_import_masked(void) { fprintf(stderr, "%s", ae2_loader_fail_msg); exit(255); } #else /* * iter mask manipulation util functions */ int aet2_rd_get_fac_process_mask(unsigned int facidx) { if((int)facidxnumfacs) { int process_idx = facidx/8; int process_bit = facidx&7; return( (GLOBALS->ae2_process_mask[process_idx]&(1<numfacs) { int idx = facidx/8; int bitpos = facidx&7; GLOBALS->ae2_process_mask[idx] |= (1<numfacs) { int idx = facidx/8; int bitpos = facidx&7; GLOBALS->ae2_process_mask[idx] &= (~(1<ae2, name, &f2)); } #endif static void *alloc_fn(size_t size) { void *pnt = calloc_2(1, size); return(pnt); } static void free_fn(void* ptr, size_t size) { (void)size; if(ptr) { free_2(ptr); } } /* * dynamic alias allocator (memory written to is converted to refer to facidx instead) */ #ifdef AET2_ALIASDB_IS_PRESENT static void *adb_alloc_2(size_t siz) { if(GLOBALS->adb_alloc_pool_base) { if((siz + GLOBALS->adb_alloc_idx) <= WAVE_ADB_ALLOC_POOL_SIZE) { unsigned char *m = GLOBALS->adb_alloc_pool_base + GLOBALS->adb_alloc_idx; GLOBALS->adb_alloc_idx += siz; return((void *)m); } else if(siz >= WAVE_ADB_ALLOC_ALTREQ_SIZE) { return(calloc_2(1, siz)); } } GLOBALS->adb_alloc_pool_base = calloc_2(1, WAVE_ADB_ALLOC_POOL_SIZE); GLOBALS->adb_alloc_idx = 0; return(adb_alloc_2(siz)); } #endif /* * dynamic alias support on reads */ #ifdef AET2_ALIASDB_IS_PRESENT static unsigned long ae2_read_symbol_rows_2(AE2_HANDLE handle, unsigned long symbol_idx) { if(symbol_idx <= GLOBALS->ae2_num_facs) { unsigned long r = (unsigned long)((unsigned int)ae2_read_symbol_rows(handle, symbol_idx)); if(r > AE2_MAX_ROWS) r = AE2_MAX_ROWS; return(r); } else { return(1); } } static void ae2_read_value_2a(AE2_HANDLE handle, unsigned long idx, uint64_t cycle, char* value, int tot_length) { int i; int numTerms = GLOBALS->adb_num_terms[--idx]; int length; int offs = 0; if(numTerms) { for(i=0;iadb_aliases[idx][i]; AE2_FACREF fr2; fr2.s = at->id; fr2.row = 0; fr2.row_high = 0; fr2.offset = at->first; if(at->last >= at->first) { fr2.length = length = at->last - at->first + 1; } else { fr2.length = -(length = at->first - at->last + 1); } if(fr2.s) { ae2_read_value(handle, &fr2, cycle, value+offs); } else { memset(value+offs, 'Z', fr2.length); /* should never happen except when alias is superset of available model facs */ } offs += length; } } else { /* should never happen except when alias is superset of available model facs */ memset(value, 'Z', tot_length); } value[tot_length] = 0; } static uint64_t ae2_read_next_value_2a(AE2_HANDLE handle, unsigned long idx, uint64_t cycle, char* value, int tot_length) { uint64_t cyc = GLOBALS->max_time + 1; uint64_t t_cyc; int i; int numTerms = GLOBALS->adb_num_terms[--idx]; int length; int offs = 0; int nonew = 0; if(numTerms) { for(i=0;iadb_aliases[idx][i]; AE2_FACREF fr2; fr2.s = at->id; fr2.row = 0; fr2.row_high = 0; fr2.offset = at->first; if(at->last >= at->first) { fr2.length = length = at->last - at->first + 1; } else { fr2.length = -(length = at->first - at->last + 1); } if(fr2.s) { t_cyc = ae2_read_next_value(handle, &fr2, cycle, value+offs); /* simply want to calculate next value change time */ } else { /* should never happen except when alias is superset of available model facs */ t_cyc = cycle; } if(t_cyc != cycle) { if(t_cyc < cyc) { cyc = t_cyc; } } else { nonew++; } offs += length; } if(nonew == numTerms) { cyc = cycle; } ae2_read_value_2a(handle, idx+1, cyc, value, tot_length); /* reread at that calculated value change time */ } else { /* should never happen except when alias is superset of available model facs */ memset(value, 'Z', tot_length); value[tot_length] = 0; cyc = cycle; } return(cyc); } static void ae2_read_value_2(AE2_HANDLE handle, AE2_FACREF* fr, uint64_t cycle, char* value) { if(fr->s <= GLOBALS->ae2_num_facs) { ae2_read_value(handle, fr, cycle, value); } else /* complex alias... */ { unsigned long idx = fr->s - GLOBALS->ae2_num_facs; ae2_read_value_2a(handle, idx, cycle, value, fr->length); } } static uint64_t ae2_read_next_value_2(AE2_HANDLE handle, AE2_FACREF* fr, uint64_t cycle, char* value) { if(fr->s <= GLOBALS->ae2_num_facs) { return(ae2_read_next_value(handle, fr, cycle, value)); } else /* complex alias... */ { unsigned long idx = fr->s - GLOBALS->ae2_num_facs; return(ae2_read_next_value_2a(handle, idx, cycle, value, fr->length)); } } #else #define ae2_read_symbol_rows_2(a,b) ae2_read_symbol_rows((a),(b)) #define ae2_read_value_2(a,b,c,d) ae2_read_value((a),(b),(c),(d)) #define ae2_read_next_value_2(a,b,c,d) ae2_read_next_value((a),(b),(c),(d)) #endif /* * fast itoa for decimal numbers */ static char* itoa_2(int value, char* result) { char* ptr = result, *ptr1 = result, tmp_char; int tmp_value; do { tmp_value = value; value /= 10; *ptr++ = "9876543210123456789" [9 + (tmp_value - value * 10)]; } while ( value ); if (tmp_value < 0) *ptr++ = '-'; result = ptr; *ptr-- = '\0'; while(ptr1 < ptr) { tmp_char = *ptr; *ptr--= *ptr1; *ptr1++ = tmp_char; } return(result); } /* * preformatted sprintf statements which remove parsing latency */ static int sprintf_2_1d(char *s, int d) { char *s2 = s; *(s2++) = '['; *(s2++) = '0'; *(s2++) = ':'; s2 = itoa_2(d, s2); *(s2++) = ']'; *s2 = 0; return(s2 - s); } #ifdef AET2_ALIASDB_IS_PRESENT static int sprintf_2_2d(char *s, int d1, int d2) { char *s2 = s; *(s2++) = '['; s2 = itoa_2(d1, s2); *(s2++) = ':'; s2 = itoa_2(d2, s2); *(s2++) = ']'; *s2 = 0; return(s2 - s); } #endif /* * mainline */ TimeType ae2_main(char *fname, char *skip_start, char *skip_end) { unsigned int i; int match_idx; struct Node *n; struct symbol *s; TimeType first_cycle, last_cycle /* , total_cycles */; /* scan-build */ int total_rows = 0; int mono_row_offset = 0; struct Node *monolithic_node = NULL; struct symbol *monolithic_sym = NULL; #ifdef AET2_ALIASDB_IS_PRESENT unsigned long kw = 0; unsigned char *missing = NULL; #endif char buf[AE2_MAX_NAME_LENGTH+1]; ae2_read_set_max_section_cycle(65536); ae2_initialize(error_fn, msg_fn, alloc_fn, free_fn); if ( (!(GLOBALS->ae2_f=fopen(fname, "rb"))) || (!(GLOBALS->ae2 = ae2_read_initialize(GLOBALS->ae2_f))) ) { if(GLOBALS->ae2_f) { fclose(GLOBALS->ae2_f); GLOBALS->ae2_f = NULL; } return(LLDescriptor(0)); /* look at GLOBALS->ae2 in caller for success status... */ } GLOBALS->time_dimension = 'n'; if(!GLOBALS->fast_tree_sort) { GLOBALS->do_hier_compress = 0; } init_facility_pack(); /* SPLASH */ splash_create(); sym_hash_initialize(GLOBALS); #ifdef AET2_ALIASDB_IS_PRESENT if(!GLOBALS->disable_ae2_alias) { kw = ae2_read_locate_keyword(GLOBALS->ae2, "aliasdb"); } if(kw) { GLOBALS->adb_alias_stream_file = ae2_read_keyword_stream(GLOBALS->ae2, kw); GLOBALS->adb = adb_open_embed(GLOBALS->adb_alias_stream_file, NULL, alloc_fn, free_fn, adb_msg_fn, error_fn); if(GLOBALS->adb) { unsigned long fn; GLOBALS->ae2_num_aliases = adb_num_aliases(GLOBALS->adb); GLOBALS->adb_max_terms = adb_max_alias_terms(GLOBALS->adb); GLOBALS->adb_terms = calloc_2(GLOBALS->adb_max_terms + 1, sizeof(ADB_TERM)); GLOBALS->adb_aliases = calloc_2(GLOBALS->ae2_num_aliases, sizeof(ADB_TERM *)); GLOBALS->adb_num_terms = calloc_2(GLOBALS->ae2_num_aliases, sizeof(unsigned short)); GLOBALS->adb_idx_first = calloc_2(GLOBALS->ae2_num_aliases, sizeof(unsigned short)); GLOBALS->adb_idx_last = calloc_2(GLOBALS->ae2_num_aliases, sizeof(unsigned short)); fn = adb_map_ids (GLOBALS->adb, symbol_fn, GLOBALS->ae2); /* iteratively replaces all .id with FACIDX */ fprintf(stderr, AET2_RDLOAD"Encountered %lu aliases referencing %lu facs.\n", GLOBALS->ae2_num_aliases, fn); } } #endif GLOBALS->ae2_num_sections=ae2_read_num_sections(GLOBALS->ae2); GLOBALS->ae2_num_facs = ae2_read_num_symbols(GLOBALS->ae2); GLOBALS->numfacs = GLOBALS->ae2_num_facs + GLOBALS->ae2_num_aliases; GLOBALS->ae2_process_mask = calloc_2(1, GLOBALS->numfacs/8+1); GLOBALS->ae2_fr=calloc_2(GLOBALS->numfacs, sizeof(AE2_FACREF)); GLOBALS->ae2_lx2_table=(struct lx2_entry **)calloc_2(GLOBALS->numfacs, sizeof(struct lx2_entry *)); match_idx = 0; for(i=0;iae2_num_facs;i++) { int idx = i+1; GLOBALS->ae2_fr[match_idx].facname = NULL; GLOBALS->ae2_fr[match_idx].s = idx; GLOBALS->ae2_fr[match_idx].row = ae2_read_symbol_rows(GLOBALS->ae2, idx); if(GLOBALS->ae2_fr[match_idx].row > AE2_MAX_ROWS) { GLOBALS->ae2_fr[match_idx].row = AE2_MAX_ROWS; ae2_read_find_symbol(GLOBALS->ae2, buf, &GLOBALS->ae2_fr[match_idx]); fprintf(stderr, AET2_RDLOAD"Warning: Reduced array %s to %d rows.\n", buf, AE2_MAX_ROWS); } total_rows += (GLOBALS->ae2_fr[match_idx].row > 0) ? GLOBALS->ae2_fr[match_idx].row : 1; if(GLOBALS->ae2_fr[match_idx].row == 1) GLOBALS->ae2_fr[match_idx].row = 0; GLOBALS->ae2_fr[match_idx].length = ae2_read_symbol_length(GLOBALS->ae2, idx); GLOBALS->ae2_fr[match_idx].row_high = 0; GLOBALS->ae2_fr[match_idx].offset = 0; match_idx++; } #ifdef AET2_ALIASDB_IS_PRESENT missing = calloc_2(1, (GLOBALS->ae2_num_aliases + 7 + 1) / 8); /* + 1 to mirror idx value */ for(i=0;iae2_num_aliases;i++) { unsigned long numTerms; unsigned int idx = i+1; unsigned int ii; int midx, mbit; int mcnt; total_rows++; if((numTerms = adb_load_alias_def(GLOBALS->adb, idx, GLOBALS->adb_terms))) { if(GLOBALS->adb_terms[0].first > GLOBALS->adb_terms[0].last) { GLOBALS->ae2_fr[match_idx].length = GLOBALS->adb_terms[0].first - GLOBALS->adb_terms[0].last + 1; } else { GLOBALS->ae2_fr[match_idx].length = GLOBALS->adb_terms[0].last - GLOBALS->adb_terms[0].first + 1; } GLOBALS->adb_idx_first[i] = GLOBALS->adb_terms[0].first; GLOBALS->adb_idx_last[i] = GLOBALS->adb_terms[0].last; GLOBALS->ae2_fr[match_idx].s = idx + GLOBALS->ae2_num_facs; /* bias aliases after regular facs */ GLOBALS->ae2_fr[match_idx].facname = NULL; GLOBALS->ae2_fr[match_idx].row = 0; GLOBALS->ae2_fr[match_idx].row_high = 0; GLOBALS->ae2_fr[match_idx].offset = 0; GLOBALS->adb_num_terms[i] = numTerms; GLOBALS->adb_aliases[i] = adb_alloc_2(numTerms * sizeof(ADB_TERM)); mcnt = 0; for(ii=0;ii<(numTerms);ii++) { GLOBALS->adb_aliases[i][ii].id = GLOBALS->adb_terms[ii+1].id; if(!GLOBALS->adb_aliases[i][ii].id) { mcnt++; } GLOBALS->adb_aliases[i][ii].first = GLOBALS->adb_terms[ii+1].first; GLOBALS->adb_aliases[i][ii].last = GLOBALS->adb_terms[ii+1].last; } if(mcnt) { midx = idx / 8; mbit = idx & 7; missing[midx] |= (1 << mbit); } } else { unsigned long id = GLOBALS->adb_terms[0].id; if(id) { memcpy(&GLOBALS->ae2_fr[match_idx], &GLOBALS->ae2_fr[id-1], sizeof(AE2_FACREF)); GLOBALS->adb_idx_first[i] = 0; GLOBALS->adb_idx_last[i] = GLOBALS->ae2_fr[match_idx].length - 1; } else /* not in model */ { midx = idx / 8; mbit = idx & 7; missing[midx] |= (1 << mbit); GLOBALS->ae2_fr[match_idx].length = 1; GLOBALS->adb_idx_first[i] = 0; GLOBALS->adb_idx_last[i] = 0; GLOBALS->ae2_fr[match_idx].s = idx + GLOBALS->ae2_num_facs; /* bias aliases after regular facs */ GLOBALS->ae2_fr[match_idx].facname = NULL; GLOBALS->ae2_fr[match_idx].row = 0; GLOBALS->ae2_fr[match_idx].row_high = 0; GLOBALS->ae2_fr[match_idx].offset = 0; GLOBALS->adb_num_terms[i] = 0; } } match_idx++; } #endif monolithic_node = calloc_2(total_rows, sizeof(struct Node)); monolithic_sym = calloc_2(match_idx, sizeof(struct symbol)); fprintf(stderr, AET2_RDLOAD"Finished building %d facs.\n", match_idx); /* SPLASH */ splash_sync(1, 5); first_cycle = (TimeType) ae2_read_start_cycle(GLOBALS->ae2); last_cycle = (TimeType) ae2_read_end_cycle(GLOBALS->ae2); /* total_cycles = last_cycle - first_cycle + 1; */ /* scan-build */ /* do your stuff here..all useful info has been initialized by now */ if(!GLOBALS->hier_was_explicitly_set) /* set default hierarchy split char */ { GLOBALS->hier_delimeter='.'; } match_idx = 0; for(i=0;i<(unsigned int)GLOBALS->numfacs;i++) { char *str; int idx; int typ; long len, clen; int row_iter, mx_row, mx_row_adjusted; #ifdef AET2_ALIASDB_IS_PRESENT if(i < GLOBALS->ae2_num_facs) #endif { idx = i+1; len = ae2_read_symbol_name(GLOBALS->ae2, idx, buf); typ = (GLOBALS->ae2_fr[match_idx].row <= 1) ? ND_GEN_NET : ND_VCD_ARRAY; } #ifdef AET2_ALIASDB_IS_PRESENT else { idx = i - GLOBALS->ae2_num_facs + 1; typ = (missing[idx/8] & (1 << (idx & 7))) ? ND_GEN_MISSING : ND_GEN_ALIAS; len = adb_alias_name(GLOBALS->adb, idx, buf) - 1; /* it counts the null character */ } #endif if(GLOBALS->ae2_fr[match_idx].length>1) { int len2; #ifdef AET2_ALIASDB_IS_PRESENT if(i < GLOBALS->ae2_num_facs) #endif { len2 = sprintf_2_1d(buf+len, GLOBALS->ae2_fr[match_idx].length-1); } #ifdef AET2_ALIASDB_IS_PRESENT else { len2 = sprintf_2_2d(buf+len, GLOBALS->adb_idx_first[i - GLOBALS->ae2_num_facs], GLOBALS->adb_idx_last[i - GLOBALS->ae2_num_facs]); } #endif clen = (len + len2 + 1); if(!GLOBALS->do_hier_compress) { str=malloc_2(clen); } else { str = buf; } if(clen > GLOBALS->longestname) GLOBALS->longestname = clen; if(!GLOBALS->alt_hier_delimeter) { if(!GLOBALS->do_hier_compress) strcpy(str, buf); } else { strcpy_vcdalt(str, buf, GLOBALS->alt_hier_delimeter); } s = &monolithic_sym[match_idx]; symadd_name_exists_sym_exists(s, str,0); } else { clen = (len+1); if(!GLOBALS->do_hier_compress) { str=malloc_2(clen); } else { str = buf; } if(clen > GLOBALS->longestname) GLOBALS->longestname = clen; if(!GLOBALS->alt_hier_delimeter) { if(!GLOBALS->do_hier_compress) strcpy(str, buf); } else { strcpy_vcdalt(str, buf, GLOBALS->alt_hier_delimeter); } s = &monolithic_sym[match_idx]; symadd_name_exists_sym_exists(s, str,0); } mx_row = (GLOBALS->ae2_fr[match_idx].row < 1) ? 1 : GLOBALS->ae2_fr[match_idx].row; mx_row_adjusted = (mx_row < 2) ? 0 : mx_row; n=&monolithic_node[mono_row_offset]; s->n = n; mono_row_offset += mx_row; if(GLOBALS->do_hier_compress) { s->name = compress_facility((unsigned char *)str, clen - 1); } for(row_iter = 0; row_iter < mx_row; row_iter++) { n[row_iter].vartype = typ; n[row_iter].nname=s->name; n[row_iter].mv.mvlfac = (struct fac *)(GLOBALS->ae2_fr+match_idx); /* to keep from having to allocate duplicate mvlfac struct */ /* use the info in the AE2_FACREF array instead */ n[row_iter].array_height = mx_row_adjusted; n[row_iter].this_row = row_iter; if(GLOBALS->ae2_fr[match_idx].length>1) { #ifdef AET2_ALIASDB_IS_PRESENT if(i < GLOBALS->ae2_num_facs) #endif { n[row_iter].msi = 0; n[row_iter].lsi = GLOBALS->ae2_fr[match_idx].length-1; } #ifdef AET2_ALIASDB_IS_PRESENT else { n[row_iter].msi = GLOBALS->adb_idx_first[i - GLOBALS->ae2_num_facs]; n[row_iter].lsi = GLOBALS->adb_idx_last[i - GLOBALS->ae2_num_facs]; } #endif n[row_iter].extvals = 1; } n[row_iter].head.time=-1; /* mark 1st node as negative time */ n[row_iter].head.v.h_val=AN_X; } match_idx++; } #ifdef AET2_ALIASDB_IS_PRESENT if(GLOBALS->adb_idx_last) { free_2(GLOBALS->adb_idx_last); GLOBALS->adb_idx_last = NULL; } if(GLOBALS->adb_idx_first) { free_2(GLOBALS->adb_idx_first); GLOBALS->adb_idx_first = NULL; } if(missing) { free_2(missing); missing = NULL; } #endif freeze_facility_pack(); /* SPLASH */ splash_sync(2, 5); GLOBALS->facs=(struct symbol **)malloc_2(GLOBALS->numfacs*sizeof(struct symbol *)); if(GLOBALS->fast_tree_sort) { for(i=0;i<(unsigned int)GLOBALS->numfacs;i++) { GLOBALS->facs[i]=&monolithic_sym[i]; } /* SPLASH */ splash_sync(3, 5); fprintf(stderr, AET2_RDLOAD"Building facility hierarchy tree.\n"); init_tree(); for(i=0;i<(unsigned int)GLOBALS->numfacs;i++) { int was_packed = HIER_DEPACK_STATIC; /* no need to free_2() afterward then */ char *sb = hier_decompress_flagged(GLOBALS->facs[i]->name, &was_packed); build_tree_from_name(sb, i); } /* SPLASH */ splash_sync(4, 5); treegraft(&GLOBALS->treeroot); fprintf(stderr, AET2_RDLOAD"Sorting facility hierarchy tree.\n"); treesort(GLOBALS->treeroot, NULL); /* SPLASH */ splash_sync(5, 5); order_facs_from_treesort(GLOBALS->treeroot, &GLOBALS->facs); GLOBALS->facs_are_sorted=1; } else { for(i=0;i<(unsigned int)GLOBALS->numfacs;i++) { #ifdef WAVE_HIERFIX char *subst; char ch; #endif GLOBALS->facs[i]=&monolithic_sym[i]; #ifdef WAVE_HIERFIX while((ch=(*subst))) { if(ch==GLOBALS->hier_delimeter) { *subst=VCDNAM_HIERSORT; } /* forces sort at hier boundaries */ subst++; } #endif } /* SPLASH */ splash_sync(3, 5); fprintf(stderr, AET2_RDLOAD"Sorting facilities at hierarchy boundaries.\n"); wave_heapsort(GLOBALS->facs,GLOBALS->numfacs); #ifdef WAVE_HIERFIX for(i=0;inumfacs;i++) { char *subst, ch; subst=GLOBALS->facs[i]->name; while((ch=(*subst))) { if(ch==VCDNAM_HIERSORT) { *subst=GLOBALS->hier_delimeter; } /* restore back to normal */ subst++; } } #endif GLOBALS->facs_are_sorted=1; /* SPLASH */ splash_sync(4, 5); fprintf(stderr, AET2_RDLOAD"Building facility hierarchy tree.\n"); init_tree(); for(i=0;i<(unsigned int)GLOBALS->numfacs;i++) { build_tree_from_name(GLOBALS->facs[i]->name, i); } /* SPLASH */ splash_sync(5, 5); treegraft(&GLOBALS->treeroot); treesort(GLOBALS->treeroot, NULL); } if(GLOBALS->ae2_time_xlate) /* GLOBALS->ae2_time_xlate is currently unused, but could be again in the future */ { GLOBALS->min_time = GLOBALS->ae2_time_xlate[0]; GLOBALS->max_time = GLOBALS->ae2_time_xlate[last_cycle - first_cycle]; } else { GLOBALS->min_time = first_cycle; GLOBALS->max_time=last_cycle; } GLOBALS->ae2_start_cyc = GLOBALS->ae2_start_limit_cyc = first_cycle; GLOBALS->ae2_end_cyc = GLOBALS->ae2_end_limit_cyc = last_cycle; GLOBALS->is_lx2 = LXT2_IS_AET2; if(skip_start || skip_end) { TimeType b_start, b_end; TimeType lim_idx; if(!skip_start) b_start = GLOBALS->min_time; else b_start = unformat_time(skip_start, GLOBALS->time_dimension); if(!skip_end) b_end = GLOBALS->max_time; else b_end = unformat_time(skip_end, GLOBALS->time_dimension); if(b_startmin_time) b_start = GLOBALS->min_time; else if(b_start>GLOBALS->max_time) b_start = GLOBALS->max_time; if(b_endmin_time) b_end = GLOBALS->min_time; else if(b_end>GLOBALS->max_time) b_end = GLOBALS->max_time; if(b_start > b_end) { TimeType tmp_time = b_start; b_start = b_end; b_end = tmp_time; } GLOBALS->min_time = b_start; GLOBALS->max_time = b_end; if(GLOBALS->ae2_time_xlate) /* GLOBALS->ae2_time_xlate is currently unused, but could be again in the future */ { for(lim_idx = first_cycle; lim_idx <= last_cycle; lim_idx++) { if(GLOBALS->ae2_time_xlate[lim_idx - first_cycle] <= GLOBALS->min_time) { GLOBALS->ae2_start_limit_cyc = lim_idx; } if(GLOBALS->ae2_time_xlate[lim_idx - first_cycle] >= GLOBALS->min_time) { break; } } for(; lim_idx <= last_cycle; lim_idx++) { if(GLOBALS->ae2_time_xlate[lim_idx - first_cycle] >= GLOBALS->max_time) { GLOBALS->ae2_end_limit_cyc = lim_idx; break; } } } } fprintf(stderr, AET2_RDLOAD"["TTFormat"] start time.\n"AET2_RDLOAD"["TTFormat"] end time.\n", GLOBALS->min_time, GLOBALS->max_time); /* SPLASH */ splash_finalize(); return(GLOBALS->max_time); } /* * ae2 callback */ static void ae2_callback(uint64_t *tim, unsigned int *facidx, char **value, unsigned int row) { struct HistEnt *htemp = histent_calloc(); struct lx2_entry *l2e = &GLOBALS->ae2_lx2_table[*facidx][row]; AE2_FACREF *f = GLOBALS->ae2_fr+(*facidx); static int busycnt = 0; busycnt++; if(busycnt==WAVE_BUSY_ITER) { busy_window_refresh(); busycnt = 0; } /* fprintf(stderr, "%lld %d %d %s\n", *tim, *facidx, row, *value); */ if(f->length>1) { htemp->v.h_vector = (char *)malloc_2(f->length); memcpy(htemp->v.h_vector, *value, f->length); } else { switch(**value) { case '0': htemp->v.h_val = AN_0; break; case '1': htemp->v.h_val = AN_1; break; case 'H': case 'Z': case 'z': htemp->v.h_val = AN_Z; break; default: htemp->v.h_val = AN_X; break; } } if(!GLOBALS->ae2_time_xlate) { htemp->time = (*tim); } else { htemp->time = GLOBALS->ae2_time_xlate[(*tim) - GLOBALS->ae2_start_cyc]; } if(l2e->histent_head) { l2e->histent_curr->next = htemp; l2e->histent_curr = htemp; } else { l2e->histent_head = l2e->histent_curr = htemp; } l2e->numtrans++; } int ae2_iterator(uint64_t start_cycle, uint64_t end_cycle) { unsigned int i, j, r; uint64_t cyc, ecyc, step_cyc; struct ae2_ncycle_autosort *deadlist=NULL; struct ae2_ncycle_autosort *autofacs=NULL; char buf[AE2_MAXFACLEN+1]; autofacs = calloc_2(GLOBALS->numfacs, sizeof(struct ae2_ncycle_autosort)); for(i=0;i<(unsigned int)GLOBALS->numfacs;i++) { if(aet2_rd_get_fac_process_mask(i)) { unsigned int nr = ae2_read_symbol_rows_2(GLOBALS->ae2,GLOBALS->ae2_fr[i].s); if(!nr) nr = 1; for(r=0;rae2_lx2_table[i][r].np; np->mv.value = calloc_2(1, GLOBALS->ae2_fr[i].length+1); } } } for(j=0;jae2_num_sections;j++) { struct ae2_ncycle_autosort **autosort = NULL; const uint64_t *ith_range = ae2_read_ith_section_range(GLOBALS->ae2, j); cyc = *ith_range; ecyc = *(ith_range+1); if(ecycend_cycle) break; if((ecycnumfacs;i++) { if(aet2_rd_get_fac_process_mask(i)) { int nr = ae2_read_symbol_rows_2(GLOBALS->ae2,GLOBALS->ae2_fr[i].s); if(nr<2) { nptr np = GLOBALS->ae2_lx2_table[i][0].np; ae2_read_value_2(GLOBALS->ae2, GLOBALS->ae2_fr+i, cyc, buf); if(strcmp(np->mv.value, buf)) { strcpy(np->mv.value, buf); ae2_callback(&cyc, &i, &np->mv.value, 0); } } else { unsigned long sf = ae2_read_symbol_sparse_flag(GLOBALS->ae2, GLOBALS->ae2_fr[i].s); if(sf) { unsigned int rows = ae2_read_num_sparse_rows(GLOBALS->ae2, GLOBALS->ae2_fr[i].s, cyc); if(rows) { for(r=1;rae2, GLOBALS->ae2_fr[i].s, cyc, r); GLOBALS->ae2_fr[i].row = row; np = GLOBALS->ae2_lx2_table[i][row].np; ae2_read_value_2(GLOBALS->ae2, GLOBALS->ae2_fr+i, cyc, buf); if(strcmp(np->mv.value, buf)) { strcpy(np->mv.value, buf); ae2_callback(&cyc, &i, &np->mv.value, row); } } } } else { unsigned int rows = ae2_read_symbol_rows_2(GLOBALS->ae2, GLOBALS->ae2_fr[i].s); if(rows) { for(r=0;rae2_fr[i].row = row; np = GLOBALS->ae2_lx2_table[i][row].np; ae2_read_value_2(GLOBALS->ae2, GLOBALS->ae2_fr+i, cyc, buf); if(strcmp(np->mv.value, buf)) { strcpy(np->mv.value, buf); ae2_callback(&cyc, &i, &np->mv.value, row); } } } } } } } deadlist=NULL; for(i=0;i<(unsigned int)GLOBALS->numfacs;i++) { uint64_t ncyc; nptr np; int nr; if(!aet2_rd_get_fac_process_mask(i)) continue; nr = ae2_read_symbol_rows_2(GLOBALS->ae2,GLOBALS->ae2_fr[i].s); if(nr < 2) { np = GLOBALS->ae2_lx2_table[i][0].np; ncyc = ae2_read_next_value_2(GLOBALS->ae2, GLOBALS->ae2_fr+i, cyc, np->mv.value); } else { unsigned long sf = ae2_read_symbol_sparse_flag(GLOBALS->ae2, GLOBALS->ae2_fr[i].s); if(sf) { unsigned int rows = ae2_read_num_sparse_rows(GLOBALS->ae2, GLOBALS->ae2_fr[i].s, cyc); uint64_t mxcyc = end_cycle+1; for(r=1;rae2, GLOBALS->ae2_fr[i].s, cyc, r); GLOBALS->ae2_fr[i].row = row; /* np = GLOBALS->ae2_lx2_table[i][row].np; */ ncyc = ae2_read_next_value_2(GLOBALS->ae2, GLOBALS->ae2_fr+i, cyc, buf); if((ncyc > cyc) && (ncyc < mxcyc)) mxcyc = ncyc; } if(mxcyc != (end_cycle+1)) { ncyc = mxcyc; } else { ncyc = cyc; } } else { unsigned int rows = ae2_read_symbol_rows_2(GLOBALS->ae2, GLOBALS->ae2_fr[i].s); uint64_t mxcyc = end_cycle+1; for(r=0;rae2_fr[i].row = row; /* np = GLOBALS->ae2_lx2_table[i][row].np; */ ncyc = ae2_read_next_value_2(GLOBALS->ae2, GLOBALS->ae2_fr+i, cyc, buf); if((ncyc > cyc) && (ncyc < mxcyc)) mxcyc = ncyc; } if(mxcyc != (end_cycle+1)) { ncyc = mxcyc; } else { ncyc = cyc; } } } if(ncyc!=cyc) { int offset = ncyc-cyc; struct ae2_ncycle_autosort *t = autosort[offset]; autofacs[i].next = t; autosort[offset] = autofacs+i; } else { struct ae2_ncycle_autosort *t = deadlist; autofacs[i].next = t; deadlist = autofacs+i; } } for(step_cyc = cyc+1 ; step_cyc <= ecyc ; step_cyc++) { int offset = step_cyc-cyc; struct ae2_ncycle_autosort *t = autosort[offset]; if(step_cyc > end_cycle) break; if(t) { while(t) { uint64_t ncyc; struct ae2_ncycle_autosort *tn = t->next; nptr np; int nr; i = t-autofacs; nr = ae2_read_symbol_rows_2(GLOBALS->ae2,GLOBALS->ae2_fr[i].s); if(nr<2) { np = GLOBALS->ae2_lx2_table[i][0].np; ae2_callback(&step_cyc, &i, &np->mv.value, 0); ncyc = ae2_read_next_value_2(GLOBALS->ae2, GLOBALS->ae2_fr+i, step_cyc, np->mv.value); } else { unsigned long sf = ae2_read_symbol_sparse_flag(GLOBALS->ae2, GLOBALS->ae2_fr[i].s); if(sf) { unsigned int rows = ae2_read_num_sparse_rows(GLOBALS->ae2, GLOBALS->ae2_fr[i].s, step_cyc); uint64_t mxcyc = end_cycle+1; for(r=1;rae2, GLOBALS->ae2_fr[i].s, step_cyc, r); GLOBALS->ae2_fr[i].row = row; npr = GLOBALS->ae2_lx2_table[i][row].np; ae2_read_value_2(GLOBALS->ae2, GLOBALS->ae2_fr+i, step_cyc, buf); if(strcmp(buf, npr->mv.value)) { strcpy(npr->mv.value, buf); ae2_callback(&step_cyc, &i, &npr->mv.value, row); } ncyc = ae2_read_next_value_2(GLOBALS->ae2, GLOBALS->ae2_fr+i, step_cyc, buf); if((ncyc > step_cyc) && (ncyc < mxcyc)) mxcyc = ncyc; } if(mxcyc != (end_cycle+1)) { ncyc = mxcyc; } else { ncyc = step_cyc; } } else { unsigned int rows = ae2_read_symbol_rows_2(GLOBALS->ae2, GLOBALS->ae2_fr[i].s); uint64_t mxcyc = end_cycle+1; for(r=0;rae2_fr[i].row = row; npr = GLOBALS->ae2_lx2_table[i][row].np; ae2_read_value_2(GLOBALS->ae2, GLOBALS->ae2_fr+i, step_cyc, buf); if(strcmp(buf, npr->mv.value)) { strcpy(npr->mv.value, buf); ae2_callback(&step_cyc, &i, &npr->mv.value, row); } ncyc = ae2_read_next_value_2(GLOBALS->ae2, GLOBALS->ae2_fr+i, step_cyc, buf); if((ncyc > step_cyc) && (ncyc < mxcyc)) mxcyc = ncyc; } if(mxcyc != (end_cycle+1)) { ncyc = mxcyc; } else { ncyc = step_cyc; } } } if(ncyc!=step_cyc) { int offset2 = ncyc-cyc; struct ae2_ncycle_autosort *ta = autosort[offset2]; autofacs[i].next = ta; autosort[offset2] = autofacs+i; } else { struct ae2_ncycle_autosort *ta = deadlist; autofacs[i].next = ta; deadlist = autofacs+i; } t = tn; } } } if(autosort) free_2(autosort); } for(i=0;i<(unsigned int)GLOBALS->numfacs;i++) { if(aet2_rd_get_fac_process_mask(i)) { unsigned int nr = ae2_read_symbol_rows_2(GLOBALS->ae2,GLOBALS->ae2_fr[i].s); if(!nr) nr = 1; for(r=0;rae2_lx2_table[i][r].np; free_2(np->mv.value); np->mv.value = NULL; } } } free_2(autofacs); return(0); } /* * actually import an ae2 trace but don't do it if it's already been imported */ void import_ae2_trace(nptr np) { struct HistEnt *htemp, *histent_tail; int len, i; AE2_FACREF *f; int txidx; int r, nr; if(!(f=(AE2_FACREF *)(np->mv.mvlfac))) return; /* already imported */ txidx = f - GLOBALS->ae2_fr; nr = ae2_read_symbol_rows_2(GLOBALS->ae2, f->s); /* new stuff */ len = f->length; if((1)||(f->row <= 1)) /* sorry, arrays not supported yet in the viewer */ { int flagged = HIER_DEPACK_STATIC; char *str = hier_decompress_flagged(np->nname, &flagged); fprintf(stderr, "Import: %s\n", str); if(nr<1) nr=1; if(!GLOBALS->ae2_lx2_table[txidx]) { GLOBALS->ae2_lx2_table[txidx] = calloc_2(nr, sizeof(struct lx2_entry)); for(r=0;rae2_lx2_table[txidx][r].np = &np[r]; } } aet2_rd_set_fac_process_mask(txidx); ae2_iterator(GLOBALS->ae2_start_limit_cyc, GLOBALS->ae2_end_limit_cyc); aet2_rd_clr_fac_process_mask(txidx); } else { int flagged = HIER_DEPACK_STATIC; char *str = hier_decompress_flagged(np->nname, &flagged); fprintf(stderr, AET2_RDLOAD"Skipping array: %s (%d rows)\n", str, f->row); if(nr<1) nr=1; if(!GLOBALS->ae2_lx2_table[txidx]) { GLOBALS->ae2_lx2_table[txidx] = calloc_2(nr, sizeof(struct lx2_entry)); for(r=0;rae2_lx2_table[txidx][r].np = &np[r]; } } } for(r = 0; r < nr; r++) { histent_tail = htemp = histent_calloc(); if(len>1) { htemp->v.h_vector = (char *)malloc_2(len); for(i=0;iv.h_vector[i] = AN_Z; } else { htemp->v.h_val = AN_Z; /* z */ } htemp->time = MAX_HISTENT_TIME; htemp = histent_calloc(); if(len>1) { htemp->v.h_vector = (char *)malloc_2(len); for(i=0;iv.h_vector[i] = AN_X; } else { htemp->v.h_val = AN_X; /* x */ } htemp->time = MAX_HISTENT_TIME-1; htemp->next = histent_tail; if(GLOBALS->ae2_lx2_table[txidx][r].histent_curr) { GLOBALS->ae2_lx2_table[txidx][r].histent_curr->next = htemp; htemp = GLOBALS->ae2_lx2_table[txidx][r].histent_head; } if(len>1) { np[r].head.v.h_vector = (char *)malloc_2(len); for(i=0;itime = -1; if(len>1) { htemp2->v.h_vector = htemp->v.h_vector; } else { htemp2->v.h_val = htemp->v.h_val; } htemp2->next = htemp; htemp = htemp2; GLOBALS->ae2_lx2_table[txidx][r].numtrans++; } np[r].head.time = -2; np[r].head.next = htemp; np[r].numhist=GLOBALS->ae2_lx2_table[txidx][r].numtrans +2 /*endcap*/ +1 /*frontcap*/; np[r].curr = histent_tail; np[r].mv.mvlfac = NULL; /* it's imported and cached so we can forget it's an mvlfac now */ } } /* * pre-import many traces at once so function above doesn't have to iterate... */ void ae2_set_fac_process_mask(nptr np) { AE2_FACREF *f; int txidx; int r, nr; if(!(f=(AE2_FACREF *)(np->mv.mvlfac))) return; /* already imported */ txidx = f - GLOBALS->ae2_fr; if((1)||(f->row <= 1)) /* sorry, arrays not supported */ { aet2_rd_set_fac_process_mask(txidx); nr = f->row; if(!nr) nr=1; GLOBALS->ae2_lx2_table[txidx] = calloc_2(nr, sizeof(struct lx2_entry)); for(r=0;rae2_lx2_table[txidx][r].np = &np[r]; } } } void ae2_import_masked(void) { int txidx, i, cnt=0; for(txidx=0;txidxnumfacs;txidx++) { if(aet2_rd_get_fac_process_mask(txidx)) { cnt++; } } if(!cnt) return; if(cnt>100) { fprintf(stderr, AET2_RDLOAD"Extracting %d traces\n", cnt); } set_window_busy(NULL); ae2_iterator(GLOBALS->ae2_start_limit_cyc, GLOBALS->ae2_end_limit_cyc); set_window_idle(NULL); for(txidx=0;txidxnumfacs;txidx++) { if(aet2_rd_get_fac_process_mask(txidx)) { struct HistEnt *htemp, *histent_tail; AE2_FACREF *f = GLOBALS->ae2_fr+txidx; int r, nr = ae2_read_symbol_rows_2(GLOBALS->ae2, f->s); int len = f->length; if(nr<1) nr=1; for(r = 0; r < nr; r++) { nptr np = GLOBALS->ae2_lx2_table[txidx][r].np; histent_tail = htemp = histent_calloc(); if(len>1) { htemp->v.h_vector = (char *)malloc_2(len); for(i=0;iv.h_vector[i] = AN_Z; } else { htemp->v.h_val = AN_Z; /* z */ } htemp->time = MAX_HISTENT_TIME; htemp = histent_calloc(); if(len>1) { htemp->v.h_vector = (char *)malloc_2(len); for(i=0;iv.h_vector[i] = AN_X; } else { htemp->v.h_val = AN_X; /* x */ } htemp->time = MAX_HISTENT_TIME-1; htemp->next = histent_tail; if(GLOBALS->ae2_lx2_table[txidx][r].histent_curr) { GLOBALS->ae2_lx2_table[txidx][r].histent_curr->next = htemp; htemp = GLOBALS->ae2_lx2_table[txidx][r].histent_head; } { struct HistEnt *htemp2 = histent_calloc(); htemp2->time = -1; if(len>1) { htemp2->v.h_vector = htemp->v.h_vector; } else { htemp2->v.h_val = htemp->v.h_val; } htemp2->next = htemp; htemp = htemp2; GLOBALS->ae2_lx2_table[txidx][r].numtrans++; } if(len>1) { np->head.v.h_vector = (char *)malloc_2(len); for(i=0;ihead.v.h_vector[i] = AN_X; } else { np->head.v.h_val = AN_X; /* x */ } np->head.time = -2; np->head.next = htemp; np->numhist=GLOBALS->ae2_lx2_table[txidx][r].numtrans +2 /*endcap*/ +1 /*frontcap*/; np->curr = histent_tail; np->mv.mvlfac = NULL; /* it's imported and cached so we can forget it's an mvlfac now */ } free_2(GLOBALS->ae2_lx2_table[txidx]); GLOBALS->ae2_lx2_table[txidx] = NULL; aet2_rd_clr_fac_process_mask(txidx); } } } #endif /* ...of AET2_IS_PRESENT */ gtkwave-3.3.66/src/entry.h0000664000076400007640000000070311523063250014675 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2010 * * 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. */ #ifndef WAVE_ENTRY_H #define WAVE_ENTRY_H void entrybox(char *title, int width, char *dflt_text, char *comment, int maxch, GtkSignalFunc func); #endif gtkwave-3.3.66/src/logfile.h0000664000076400007640000000063211523063250015156 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2010 * * 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. */ #ifndef WAVE_LOGFILE_H #define WAVE_LOGFILE_H void logbox(char *title, int width, char *default_text); #endif gtkwave-3.3.66/src/fgetdynamic.c0000664000076400007640000000424412341266475016042 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2013. * * 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. */ #include "globals.h" #include #include #include #include "fgetdynamic.h" #include "debug.h" char *fgetmalloc(FILE *handle) { struct vlist_t *v; char *pnt = NULL; int i, ch; v = vlist_create(sizeof(char)); do { for(;;) { ch=fgetc(handle); if((ch==EOF)||(ch==0x00)||(ch=='\n')||(ch=='\r')) break; pnt = (char *)vlist_alloc(&v, 0); *pnt = (char)ch; } } while(!pnt && ((ch=='\n')||(ch=='\r'))); /* fix for \n\r on \n systems */ GLOBALS->fgetmalloc_len = vlist_size(v); if(!GLOBALS->fgetmalloc_len) { pnt = NULL; } else { pnt=malloc_2(GLOBALS->fgetmalloc_len+1); for(i=0;ifgetmalloc_len;i++) { pnt[i] = *((char *)vlist_locate(v, i)); } pnt[i] = 0; } vlist_destroy(v); return(pnt); } /* * remove any leading and trailing spaces */ static char *stripspaces(char *s) { int len; if(s) { char *s2 = s + strlen(s) - 1; while(isspace((int)(unsigned char)*s2) && (s2 != s)) { *s2 = 0; s2--; } s2 = s; while(*s2 && isspace((int)(unsigned char)*s2)) { s2++; } if((len = strlen(s2))) { char *s3 = malloc_2(len + 1); strcpy(s3, s2); free_2(s); s = s3; GLOBALS->fgetmalloc_len = len; } else { free_2(s); s = NULL; GLOBALS->fgetmalloc_len = 0; } } return(s); } char *fgetmalloc_stripspaces(FILE *handle) { char *s = fgetmalloc(handle); return(stripspaces(s)); } /* * variants for tcl argument passing which really aren't fgetdynamic-ish functions... * the struct wave_script_args * passed in was generated in tcl_helper.c. */ char *wave_script_args_fgetmalloc(struct wave_script_args *w) { char *pnt; if((!w)||(!w->curr)) return(NULL); pnt = malloc_2(strlen(w->curr->payload)+1); strcpy(pnt, w->curr->payload); w->curr = w->curr->next; return(pnt); } char *wave_script_args_fgetmalloc_stripspaces(struct wave_script_args *w) { char *s = wave_script_args_fgetmalloc(w); return(stripspaces(s)); } gtkwave-3.3.66/src/splash.c0000664000076400007640000143041512372010236015030 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2005-2012 * * 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. */ #include "globals.h" #include #include "symbol.h" #include "pixmaps.h" /* requires further testing */ /* #if !defined _MSC_VER && !defined __MINGW32__ && !defined __CYGWIN__ */ #define SPLASH_ADDED_LOADER_MESSAGES /* #endif */ #ifdef WAVE_USE_GTK2 /* XPM */ static const char * wave_splash_xpm[] = { "512 384 257 2", " c None", ". c #020202", "+ c #7CB5A1", "@ c #042B1B", "# c #0A673D", "$ c #459371", "% c #8AC8B1", "& c #5D5D5D", "* c #5C897C", "= c #C0E1E5", "- c #5C7B67", "; c #AB9485", "> c #4A3A31", ", c #2C865D", "' c #124F39", ") c #DFDEDD", "! c #809486", "~ c #A68A79", "{ c #E3EDEF", "] c #052216", "^ c #957F71", "/ c #2A7653", "( c #BDC7BA", "_ c #5B6C5E", ": c #24282A", "< c #A7B09D", "[ c #3C5E51", "} c #051E13", "| c #353562", "1 c #868681", "2 c #817267", "3 c #22473B", "4 c #85AAA1", "5 c #817D70", "6 c #96948E", "7 c #0B1A15", "8 c #E5FAFC", "9 c #CACBC9", "0 c #485C5B", "a c #706D6E", "b c #747A79", "c c #CDB5A1", "d c #03160B", "e c #434369", "f c #728674", "g c #538172", "h c #D69D86", "i c #89A69F", "j c #486653", "k c #5C7463", "l c #223C34", "m c #3D765D", "n c #A6B8A7", "o c #849C8A", "p c #174939", "q c #09120F", "r c #826357", "s c #474A61", "t c #59977C", "u c #F6F6F4", "v c #2C5347", "w c #6E7E7A", "x c #34345E", "y c #CE9A7F", "z c #CBD5D4", "A c #D6F4F8", "B c #748695", "C c #675143", "D c #B3B8B5", "E c #D0E2E4", "F c #8BB29E", "G c #979C8D", "H c #658086", "I c #CA987E", "J c #50745E", "K c #154030", "L c #304540", "M c #6A6D72", "N c #BCDAE0", "O c #484842", "P c #3C6853", "Q c #070E0B", "R c #66746E", "S c #39312F", "T c #716158", "U c #4D6E58", "V c #448063", "W c #AAA190", "X c #657C6B", "Y c #96C2BB", "Z c #8E948E", "` c #649683", " . c #23312F", ".. c #9ECAC5", "+. c #61545F", "@. c #7E8A83", "#. c #8E9E96", "$. c #5E635F", "%. c #BF806F", "&. c #D5D5D3", "*. c #646A70", "=. c #CA8B77", "-. c #ECECEB", ";. c #B17465", ">. c #BCD6DA", ",. c #49736E", "'. c #51665A", "). c #1D5F42", "!. c #F0FDFD", "~. c #D3EEF3", "{. c #143A2C", "]. c #313C3A", "^. c #7A9496", "/. c #70A895", "(. c #9A8A7F", "_. c #97A496", ":. c #8BB3B3", "<. c #5C4A3D", "[. c #1C2224", "}. c #505073", "|. c #191E20", "1. c #F2F2F1", "2. c #7F9C9A", "3. c #738B78", "4. c #E3E4E3", "5. c #B5BFAC", "6. c #39805F", "7. c #90AAA6", "8. c #A6A7A6", "9. c #FCFDFC", "0. c #070A09", "a. c #ACD7D6", "b. c #97BEBC", "c. c #B9B0B4", "d. c #2A6E4E", "e. c #676567", "f. c #70A291", "g. c #3E4268", "h. c #A27167", "i. c #8A9494", "j. c #37524A", "k. c #1E1A1C", "l. c #132A23", "m. c #62747C", "n. c #96897E", "o. c #445256", "p. c #5D7486", "q. c #74969C", "r. c #2C324D", "s. c #668278", "t. c #54646A", "u. c #BCD2D4", "v. c #B47D6D", "w. c #4D5346", "x. c #D2EAEF", "y. c #656E74", "z. c #727465", "A. c #4F8E72", "B. c #889C9B", "C. c #52746F", "D. c #3E4646", "E. c #ACCAB2", "F. c #15362A", "G. c #A6B9BA", "H. c #748087", "I. c #4F5458", "J. c #9AB1B2", "K. c #2E3232", "L. c #5C7C78", "M. c #678876", "N. c #6E7F91", "O. c #286A4B", "P. c #7E8082", "Q. c #535C60", "R. c #72948A", "S. c #7A8C82", "T. c #1F1616", "U. c #333C53", "V. c #C49479", "W. c #393156", "X. c #878D96", "Y. c #547A74", "Z. c #E6BAA6", "`. c #D9DAD9", " + c #5C656C", ".+ c #7E8C91", "++ c #97A4A4", "@+ c #378964", "#+ c #667C79", "$+ c #215142", "%+ c #BC8B73", "&+ c #1B1217", "*+ c #A7C2C3", "=+ c #C59D84", "-+ c #DAE0DF", ";+ c #99BABB", ">+ c #BEC0BD", ",+ c #566E69", "'+ c #678885", ")+ c #829495", "!+ c #807399", "~+ c #2D2227", "{+ c #E1CBBF", "]+ c #8A9485", "^+ c #957267", "/+ c #526A6B", "(+ c #B2B1AD", "_+ c #AC7E6D", ":+ c #ADCACD", "<+ c #364752", "[+ c #5D6B71", "}+ c #728682", "|+ c #3B3D39", "1+ c #62656A", "2+ c #3A3C65", "3+ c #99B1A0", "4+ c #758C94", "5+ c #5E5E6B", "6+ c #56473A", "7+ c #3F6962", "8+ c #719E89", "9+ c #5C7471", "0+ c #2F1E1F", "a+ c #738C85", "b+ c #A7B0AF", "c+ c #928A81", "d+ c #2E5D4D", "e+ c #3E6060", "f+ c #BDC9CA", "g+ c #2E2848", "h+ c #5C827A", "i+ c #C5C0BD", "j+ c #B9A7A8", "k+ c #969D9C", "l+ c #486762", "m+ c #153226", "n+ c #697379", "o+ c #B5C0BF", "p+ c #AFD2D6", "q+ c #EBE5E4", "r+ c #89A29E", "s+ c #C4EBEC", "t+ c #0F0505", "u+ c #4F8A6F", "v+ c #448A69", "w+ c #4C6E68", "x+ c #3A4543", "y+ c #3B525A", "z+ c #707579", "A+ c #9AAAA5", "B+ c #111616", "C+ c #8EA0A5", "D+ c #160E0E", "E+ c #748079", "F+ c #2F664D", "G+ c #868D86", "H+ c #7A8683", "P P F+F+P F+P F+O.F+F+/ d./ d./ / / d./ / / / / / / / / / / / / 6.6.6.6., / , , 6., , 6., 6., , 6., , @+, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , @+6.@+V v+v+u+u+* A.* A.A.u+u+u+v+v+v+V v+6.@+6.V V V V V Y.m ,.,.7+l+l+w+,+,+,+[+9+9+9+9+9+9+m.m.R n+n+m.9+m.y.n+m.y.y.n+m.y.n+n+n+y.y.y.y.y.y.y.y.m.y.y.y.y.y.y.y.y.y.y.[+y.[+*.*.*.*.*.*.*.*.*.*.*.y.[+y.*.*.*.*.*.y.y.y.y.M y.y.M *.*.*.y.y.y.y.y.y.y.y.y.y.y.y.y.*.y.y.M y.y.M M y.y.M y.y.y.y.y.M M y.y.y.y.y.y.y.y.y.y.y.*.*.y.*.y.y.y.*.*.*.*.y.y.y.y.*.y.[+*.*.[+*.*.*.y.[+1+ +[+*.1+*.1+e.1+[+ + + + + + + +1+ + + + +[+t.*.[+ + + + + +t. + + + + + + + + + +[+[+m.y.y.9+p.9+,+,+/+7+7+e+d+d+v ).$+$+$+$+$+' p 3 3 3 v j.[ j '._ M z+b w P.P.1 X.G+c+X.G+G+1 1 1 1 P.1 1 1 G+X.i.B.k+k+++++8.++++++k+B.)+@.N.X C.l+[ v $+p K F.F.@ @ @ @ @ @ @ ] @ @ ] @ @ @ m+F.].x+O w.& T a 2 2 5 5 5 5 5 z+z.R y.y._ $.'.$._ y.R z.b b 5 P.b 5 z+z.a *.$.+.w.O |+K.: [.k.q 0.0.. . . . . . . . t+. t+. . t+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "F+F+P d.F+d.P / 7+d./ d./ / / / / / / / / / / / / / / / / 6./ , / , / , , , , / , 6., , 6., , 6., 6.6., , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , 6.6.6.6.6.v+V g g u+* M.` * A.A.A.u+u+V v+v+V u+V v+v+V g V m Y.Y.J w+,.l+l+'./+[+,+,+y.,+y.m.y.R y.m.y.y.y.y.y.y.y.y.*.n+y.y.y.R y.y.y.a M y.y.y.y.m.y.y.y.y.y.y.y.y.y.y.[+y.[+*.y.*.y.[+*. +*.*.[+[+[+[+[+y. +y.y.y.[+[+*.*.*.*.*.[+[+y.y.*.M *.*.*.y.y.*.y.*.*.*.*.M *.y.*.M *.M *.*.y.y.M y.*.y.y.y.M M y.y.y.y.y.R m.y.y.y.*.*.*.y.*.*.e.*.*.y.y.*.M *.*.*.*.*.*.*.*.*.[+y.*.*.[+*.*.*.*. +*.[+[+1+ +1+[+[+[+ +*. + +[+ + +[+ + +[+t. + + + + + + +t. + + +1+ + + + +[+/+[+[+p.p.[+y.p.C./+w+l+l+P e+[ d+d+d+d+).v $+$+$+$+3 $+$+v j.0 '. +_ _ R z+b P.P.1 1 1 1 1 1 1 1 P.P.1 P.P.P.1 1 G+i.Z k+k+++++++8.k+k+k+i..+a+H C.l+P d+' ' K {.{.{.{.@ {.@ @ @ @ @ @ @ @ @ @ m+l L O w.C T T r 2 5 ^ ^ ^ 5 5 5 z.z.z.y.*._ $._ *.R z.b 5 5 5 5 P.5 5 2 z.a & Q.I.O |+S : [.7 D+0.. . . . . . . . . . . . t+. . . . . . . . . . . . . . . . . . . . . . . t+. . . . . . . . . . . . . . ", "d.7+/ m / / d./ m / m / / / / / / / / / / / m / / 6./ 6./ , 6., / , , / , , , , , , 6., , , , , , , , 6., , , , , , , , , , , / , , / , , , , , , , , , , , , , , , , 6., 6.6.6.6.6.V g V h+M.M.g M.* M.* u+u+u+u+V u+g u+V g u+V Y.g Y.Y.J w+/+l+j 0 0 t.$.t.[+[+[+[+y.,+M y.y.R y.y.n+R y.M M *.n+y.y.y.y.y.n+y.y.M M y.y.*.y.y.*.y.y.*.*.y.*.y.y.*.y.[+*.[+*.*.[+y.[+[+1+[+1+[+[+ +[+*. +*.[+y.[+*.y.*.*.*.*.*.*.y.*.*.[+y.[+y.y.*.y.y.y.*.*.M *.M *.M *.M M M y.n+y.M n+y.y.n+R y.y.R M y.y.y.y.y.*.y.*.y.M *.*.*.M *.*.*.y.y.M y.*.*.a *.*.y.y.y.y.y._ y.[+y.[+[+y.*.1+1+[+*.[+*.[+ +[+ +[+[+ +/+ + + + +1+[+ + + + + +[+ + +[+ + + +[+ + +[+ +[+[+[+[+[+p.p.p.p.C.,+w+/+l+7+7+P e+F+F+d+F+d+d+$+$+$+3 L 3 v v j.0 j $.$._ M R b b P.P.1 P.P.P.P.P.5 P.5 P.P.1 P.1 1 X.Z k+k+k+k+++8.++k+C+)+^.a+s.L.w+7+F+$+' ' K {.{.K {.{.{.{.{.{.{.{.K K K K l L O w.w.T T a 2 2 ^ 5 ^ ^ ^ P.P.b R R a _ _ *._ a a z.z.5 5 1 1 1 P.P.b z.a T I.w.D.|+K.: [.B+q 0.. . . . . . . . . t+. . . . . . . . . . . . . . . . . t+. . . . . . . . . . . . . . . . . . . . . . . ", "m / / / / m / / / / / / , / , / , / , 6., / , , , / , , , / , , , , , , , , , , , , , 6., , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , 6., , , 6.6.6.6.V m - V g - - X M.A.M.M.* * M.* * u+g u+g g g g g Y.J J J U /+/+/+0 0 0 Q.t.t.$. + +[+*.*.y.y.y.y.y.y.*.*.y.*.m.y.y.y.y.y.y.n+y.M y.y.y.y.y.y.y.[+y.y.[+y.y.y.y.*.*.y.[+*.[+*.[+[+ +[+ + +*. +[+ + +[+*.[+*.1+1+*.y.*.e.*.y.*.*.[+[+[+[+[+y.*.y.[+y.y.*.y.*.y.y.y.y.y.y.y.y.y.M M M y.*.n+y.y.n+y.y.y.y.M y.R y.y.y.y.y.y.M *.1+*.*.*.e.M *.y.*.*.y.*.y.y.*.*.*.*.*.*.y.*.R *.y.y.M *.*.*.y.y.1+[+*.*.1+1+1+[+[+ +[+[+t.[+[+ + + +*.*.[+ +[+ +[+ + + +1+[+ +[+*.t.[+[+[+y.[+p.p.9+9+p.p.p.p.,+w+w+w+w+7+7+P F+F+F+d+d+d+v v $+$+3 3 j.j.j.0 j $._ $.y.R z.b 5 P.5 P.P.5 P.5 5 P.P.P.P.P.@.X.X.i.B.k+++k+++k+C+B.B.4+a+'+L.,.7+F+).).' ' ' ' K K ' K K ' K K ' K K K K 3 j.w.& $.T 2 2 2 ^ ^ ^ ^ ^ 5 1 5 5 z.z.z._ a _ e._ z.z.b 5 1 1 ^ c+c+P.5 2 z.e.& w.O ].S : |.B+q 0.. . . . . . . . . . . t+. . t+. . . . . . . . . . . . t+. . . . t+. . . . . . . . . . . . . . . . . . ", "m / m / 6., / 6.6./ , / / , / , , / , / , , / , , , / 6., , / , , 6., , , 6., , 6., , , , , , 6., , , , , , , , , / , , / , , , , , , , , , , , , , , , , , , , , 6.6.6.6.6.m m Y.V J - - - - X M.M.M.M.M.M.* * g * g g u+g g Y.Y.J ,.,+/+_ t.'.t.0 o.o.I.Q.Q.Q.$.$.$.1+*.[+y.[+[+y.M M y.y.y.n+*.M y.y.M y.y.M a y.y.y.y.y.m.y.y.y.n+[+y.*.y.[+y.y.*.*.e.*.*.e.*. +[+[+ +*. +[+ + + +[+ +[+*. +1+ +*.*.1+*.y.[+[+[+*.y.[+[+*.*.*.[+[+y.M M *.y.M *.M M M y.y.M y.M n+*.y.y.y.M M n+M m.y.y.R R y.R *.y.y.*.y.*.M *.y.*.*.*.y.a y.y.M *.*.M M M y.y.y.y.*.y.M y.y.M y.R *.y.a *.y.*.*.*.*.[+ + +[+ +[+ +1+*.[+*.[+ +[+[+[+[+[+[+ +*.y.1+y.[+y.p.y.p.*.y.p.n+m.n+n+m.z+m.m.#+p.p.C.C.C.,.U w+P P P P F+F+d+v $+$+3 l 3 3 L L j.j.0 0 & $._ *.y.z.b 2 5 !+b z+5 P.b P.P.P.P..+.+X.B.6 C+++C+k+C+B.2.^.a+'+h+Y.7+d.).).' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' $+x+w.w.T T z.2 ^+^ ^ ^ n.n.^ ^ P.5 b z.R R k _ z.a z.z.z.5 5 5 1 1 ^ 1 ^ P.!+z.e.& w.O |+: [.|.q Q 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . t+. . . . . . . . . . . . . . . . ", ", 6., , 6./ , , , , , , , , , , / , , , , , , , / , , , 6., , 6., , , , , , , , , , , 6.@+, , , , 6., , 6., , , , , , , , , , , , , , , , , , , , , , , 6., 6., 6., 6.6.6./ m m J U J J k - X X X X M.M.M.* M.s.* g - h+h+X - k k C.U /+'.t.'.Q.0 o.y+O o.o.I.I.Q.Q.5+$. + +[+[+y.*.y.y.y.y.M y.M M M M y.M y.n+n+y.y.y.y.*.*.y.y.y.*.y.y.y.*.M y.*.y.*.*.*.1+[+[+*.1+ +[+ + + +[+ +*. +[+1+1+*.*.*.[+*.[+*.*.[+[+n+[+*.*.*.[+y.y.y.y.*.*.*.y.y.y.y.*.y.M y.y.R M R *.R M y.y.M M M R M n+y.y.y.y.M y.y.*.y.*.*.*.*.*.*.y.y.*.M *.M y.y.y.y.y.y.M M *.M y.y.y.y.R R R y.y.y.y.y.*.y.y.*.y.1+[+[+[+[+ +*.*.[+ +p.[+p.[+[+1+p.[+y.y.p.y.p.y.y.m.M m.p.p.m.m.#+b N.b N.N.H.N.n+#+#+m.C.C.,+,.m J m P P [ [ d+d+v $+3 3 l K l l l l L L x+w.w.w.t.$.e.y.M z.z.z+z+z+b n+#+w E+E+B .+)+)+B.B.C+r+B.#.)+R.a+M.g Y.V 7+d.# ' # ' ' ' ' ' ' ' ' ' ' ' ' ' p v d+[ $._ z.2 ^ ^ ^ _+~ ~ n.n.^ 5 5 5 z.X z.a k z.z.z.2 5 2 ^ 1 ^ 1 1 ^ 5 5 z.a e.& w.O |+K.[.7 d Q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "6.6., 6., , 6./ , / , / , / , , , , , / , , / , , , @+, , , , , , 6., , , 6.6., , , , , , , @+6., , , , , , , , , , , , , , , , , , , , , , , , , , , , 6., 6.6.6.6.6./ m m m m U U U k _ _ z.k X E+3.3.3.M.* * h+g - - - - - k k /+/+/+/+'.Q.Q.o.j.x+x+x+O o.s I.I.Q.& $.& + +*.*.*.[+*.y.*.y.*.y.M M *.M *.y.y.y.y.y.y.y.M y.y.y.y.M *.M y.*.y.*.*.*.*.y. + + +1+1+ + +_ +1+ +*.[+ +*.[+*.[+[+*.*.*.*.[+*.M *.*.*.M *.y.y.y.y.*.*.M M M M *.*.y.R y.*.M y.m.*.y.*.y.y.M y.n+y.y.y.y.R y.y.y.y.y.y.y.*.y.*.y.*.*.*.1+*.*.y.M M M M y.y.y.M M y.M y.M M R M y.y.M M n+M n+n+y.y.*.*.y.y.y.p.*.*.p.[+p.*.p.M *.y.p.m.p.n+M y.p.y.n+n+z+z+n+n+z+!+N.N.N.N.N.N.b N.P.N.b N.H.#+b #+m.L.9+,+C.,.U m P P P [ d+v $+$+3 K l {.F.F. .F.l l L O O O w.0 w.& $.$.$.1+_ _ *.y.R R n+E+H.@.4+^.^.)+2.2.o ^.a+'+M.L.Y.m d.d.# # # # # ' # ' # ' # # ' # ).).$+d+w.j T z.^+^ ^ ~ ~ ~ ~ ~ ~ (.(.^ 5 5 b z.R k a z.z.5 2 5 5 ^ 5 ^ ^ 1 1 ^ P.b a e.& w.O ].K.[.7 q 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . t+. . . . . . . . . . . . . . ", ", 6.@+@+6.@+6., , , , , , , , , , , , , , , , , 6., 6.@+, , 6., , , , 6., , @+, @+@+, , , , , , , , 6., , , , , , , , , , , , , , , , , , , , , , , @+@+@+6.@+, 6.6.m V m m m P U j '.'._ _ _ z.E+f 3.R.R.R.R.M.s.- - s.X L.k C.,+/+/+'.'.Q.Q.o.j.L ].].U.x+x+D.O s I.I.I.5+$.$.$. +e.*.*.[+y.y.*.*.*.y.M M y.y.*.*.y.M *.y.M *.y.*.*.y.M M *.y.*.y.y.[+*. +*.*.*. +[+[+[+ +[+ +*. +*. + + +[+1+*.[+1+*.[+*.M *.[+y.*.*.y.y.M *.*.y.y.y.y.y.M M M M M *.M y.*.y.y.y.y.y.y.M y.y.y.y.R y.*.M y.y.y.y.y.y.M *.y.y.y.*.*.n+*.y.M *.*.*.R M y.y.y.y.R y.y.M R y.n+M n+m.n+n+n+n+M n+p.n+n+y.M y.n+y.p.y.M n+z+z+p.n+n+p.z+N.z+N.N.z+z+N.N.z+N.!+z+z+b b b N.b N.N.N.H.H.H.H.b N.b N.b H p.9+9+C.J J m m P P P [ d+v 3 3 K K F.m+l.@ : l. . .K.].L |+O O O O 0 w.w.0 Q.0 $.'.,+,+9+X #+E+H+a+R.a+.+! a+R.M.h+V J m d.O.# # ' # # # # # # # ' # # ).).).).[ j _ z.2 ^ ~ ~ %+; ; %+; ; ~ n.n.1 5 5 z.z.k z.z.z.5 5 ^ 5 ^ ^ 1 ^ ^ 1 2 2 a e.& +.w.x+S .[.7 q Q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . t+. t+. . . . . . . . . . . ", "v+A.v+$ v+$ @+v+@+, , , , , , / , , , , , , , @+, , , @+@+, , , , , , , @+, , , , @+, , , , @+, , , , , , , , , , , , , , , , , , , , , , , , , @+6.6.6.6.6.6.6.6.6.m m m P m P j j [ & '.$._ z.X @.@.! ! R.3.3.M.M.- - - - k ,+,+/+'.t.t.0 0 j.].l r. .K.r.].L x+D.s I.I.I.Q.Q. + +1+1+*.[+e.*.*.*.M y.y.M *.y.M y.M y.y.M M M M M y.y.y.M M y.*.*.y.*.y.*.*.1+*.e.1+*.[+ + +1+[+*.*. + +1+*.*.*.y.*.*.y.*.*.*.y.y.M *.y.*.y.y.*.M y.y.M M M *.y.*.M y.M y.y.y.y.y.y.y.y.M y.y.y.y.y.y.y.M M M y.y.[+y.*.*.*.*.y.*.*.y.[+y.y.M y.y.y.y.y.*.R M M M M M R R R n+z+n+n+n+n+z+z+z+z+z+z+z+n+n+N.n+z+p.n+n+N.z+N.N.N.z+N.N.z+N.b H.N.!+b z+N.N.H.N.N.N.N.H+H.H.H.P.H.B H+B b N.N.N.H.N.H #+#+X Y.C.J U U P P [ [ v $+3 l l {.F.m+@ l.l.l.m+: .].K.].].].].|+L x+x+O j.j.j.0 j e+U ,+C.Y.L.h+h+H * '+* h+g m m d.O.O.# # # # # # ' # # # # # ).O.O.F+F+j _ z.^ ^ ^ _+%+%+V.V.V.%+; ; (.n.1 b E+z.z._ k z.2 ^ 5 c+^ (.^ (.n.^ 1 5 2 a e.& w.O x+K. .|.d q Q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . t+t+. . . . . . . . . ", "$ * t A.A.A.A.$ $ $ @+, , , , , , , , , @+, @+@+@+@+@+@+@+@+@+@+, @+, 6.6.@+@+, @+, @+@+, , , @+, , , , , , , , , , , , , , , , , , , , , @+, @+6.@+6.6.@+6.6.6.m 6.V m m P P P [ d+w.[ w.$._ R E+H+G+! ! ! R.R.a+s.s.#+- 9+_ k /+'.'.'.0 0 <+L . .[.l.[. . .r.].|+x+D.o.I.I.Q.Q.Q.$. + +1+*.*.*.*.*.*.*.y.y.y.y.y.y.M M M *.y.y.n+y.M y.y.y.M M M *.*.*.y.*.*.1+*.e.1+1+*.*.*.[+ +y.*.*.*.[+[+y.[+[+[+[+y.y.[+y.y.*.y.*.y.y.y.M y.M M M *.y.y.y.M y.*.*.y.y.M y.M y.M y.*.y.M M M y.y.M y.M M *.y.y.y.M M y.M *.y.*.y.y.[+y.[+k _ R y.M z.M R y.R n+n+n+n+n+n+z+b H.H.z+N.z+N.H.N.N.N.!+z+z+N.N.N.z+N.N.N.!+b N.H.b H.N.!+b H.H.N.N.H.H.b P.b b N.H.B X..+B B 1 1 X.1 P.N.N.P.B a+H.#+#+#+X h+Y.J J U j j d+d+v $+p K {.F.m+m+@ l.l.l.l. . .K.K.S ].].].K.K.].l ].].l L j.v j.[ 0 P U U ,.,.J ,.U m U m d.O.# O.).# # # # # # # # # # # # # O.O.d.U z.5 ^ _+~ ~ %+%+%+; %+; %+; ~ (.n.1 z.z.z.k z.z.z.5 1 ^ (.(.~ (.(.n.^ ^ 2 a e.& w.O L K. .@ } d Q 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . t+. . . . t+. t+. . . . . . ", "t ` ` ` ` ` t * A.$ $ @+, , , , , , @+@+@+$ @+$ $ @+v+@+@+@+@+@+, @+, , , @+@+, @+@+, @+@+@+, @+, , , , , , , , , , , , , , , , , , , , @+6.@+6.6.6.V V V V 6.V m m m m P P [ F+d+[ j.[ 0 '.k X w f 3.S.S.! ! ! R.M.* - X - k k _ t.'.'.o.j.]. .l.7 |.} } |.[.: .r.|+|+<+D.s I.I.Q.Q.Q. + +1+1+[+[+*.y.*.y.y.*.y.M n+y.M M *.y.y.M M M M y.y.y.M M y.M e.*.*.y.[+*.*.*.[+*.*.*.y.*.[+1+*.*.*.*.*.*.y.y.y.y.y.y.y.y.a y.y.M M a y.y.y.M M M M *.M y.R M *.a *.*.M y._ a y.y.y.y.y.a y.y.M y.R M y.y.y.y.y.*.*.M *.y.y.*.y.y.R y.n+y.R R n+n+n+n+a z+z+z+z+b b #+z+b b P.P.H.H.P.H.P.H.H.N.H.b b b N.N.b b H.b N.H.B H.H.H.N.H.P.P.H.b b H.P.P.B H.H.B .+X.X.B B B 4+X.)+.+N.B B H+.+H+N.N.H.#+s.h+- - J U U [ d+j.$+$+K {.{.F.@ m+@ m+@ l.m+ . . .K.K. .K.l . .m+l l l {.3 L j.v j.v d+d+F+F+[ P P F+F+F+F+O.O.).# # # # # # # # # # # # # O.O.O.P J X ^ ^ ~ _+%+~ %+%+V.%+%+_+(.n.^ 1 5 f z._ _ z.z.5 ^+^ (.~ (.~ ~ ^ (.^ 1 5 2 T +.w.O ].K. .] } d q 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . t+. t+. t+. . . . . . ", "R.R.R.q.` q.` ` ` t A.$ @+, , , , @+v+$ $ $ $ $ A.$ $ $ $ $ @+@+@+, @+v+@+@+@+@+v+v+@+$ @+@+@+@+, , , , , , , , , , , , , , , , @+, @+@+, @+6.6.V 6.6.6.V m 6.m 6.m m m P P P [ d+v d+[ [ U ,+_ X w E+S.i.i.B.B.2.3.#+- C.k C.,+,+'.j y+j.l F.l.7 d q q q 7 } |.l. . .].].x+D.O I.o.Q.5+Q.$.t. +*.*.[+[+*.*.M y.*.M y.y.y.y.y.y.y.*.n+M M n+y.n+y.M M M M M y.y.*.*.y.y.y.*.*.*.*.*.*.*.*.M *.y.y.*.*.y.[+y.y.y.y.M *.M M a *.M y.y.y.n+n+R y.y.y.*.y.*.*.y.a y.R M R y.M R y.y.*.y.y.y.y.y.M *.y.y.y.y.y.y.y.n+M y.n+y.R m.n+n+m.m.n+n+z+z+z+z+b z+b b b b H.b b H.P.H.P.H.H.H.P.H.H.P.H.b N.!+b H.P.H.B H.H.P.B P.B P.H.P.N.4+.+P.B H.N.B X..+P.B H+4+)+)+X.X..+.+)+)+X..+4+.+4+.+.+4+a+}+}+M.s.- - V J U P [ v v $+p p K {.{.{.F.m+m+F.m+m+F. . . .K.l . .F. .m+F.{.l l p 3 3 j.v j.v j.d+F+d+[ F+F+F+O.).O.O.O.# O.# # # # # # # # # O.# O.O.U k f ~ ~ _+~ %+%+%+%+%+%+%+_+^ ^ 5 5 z.z.k z._ _ z.2 5 ^ ^ ~ ~ ~ ~ ~ (.1 ^ 5 2 *.& w.x+L . .l.} d q d Q 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . t+. . . t+. . . ", "o 8+o o 2.8+8+R.` * A.u+v+6.V v+v+v+A.A.` ` t t t t t t $ $ $ v+v+@+@+@+v+v+$ A.$ $ v+$ $ $ @+v+@+@+, , , , , , , , , , , , , , @+, , @+@+@+V @+V V 6.V V V V m m m P m P P [ F+d+d+v d+[ j U ,+- s.H+! )+B.r+r+8+* Y.Y.J ,.7+U j [ [ L 3 m+] } q . . . . Q q q 7 |.l.: r.].L x+D.s w.I.Q.Q. +t. +*.*.[+y.*.*.M y.M M y.y.y.y.y.M y.n+n+y.M y.y.M M M *.*.*.*.*.y.*.*.*.y.*.y.[+*.y.*.*.*.*.*.*.p.*.y.y.y.p.y.M n+y.n+M M a y.M *.M M M y.y.y.y.R *.M M a R *.*.y.y.y.y.y.y.*.R a M y.m.[+y.n+y.M M y.n+y.y.n+m.n+n+m.n+n+z+#+z+n+#+n+b w H.b b N.b N.b N.H.H.H.H.H.P.H.P.H.P.H.H.H.H.P.H.H.H.b N.H.P.1 P.H.H.N..+.+.+1 B P.B B X.B P.B P.B X.X..+B 1 .+)+B.)+)+^.)+)+B.B.X..+.+^..+^..+.+4+S.a+'+s.s.h+g J m F+d+v v $+3 p K K {.{.{.F.{. .l l l l l .l {. .{.F.F.{.l K 3 3 $+3 v v d+d+[ d+d+d+[ d+F+F+O.O.# O.# d.# # / # # # # # # # # # O.O.P J z.~ ~ %+%+%+%+%+%+%+%+_+_+_+^+5 z.z._ _ _ _ _ z.2 ^ ^ ^ ^ _+^ _+^ ^ 5 5 z.z.e.& w.x+L F.m+] ] } d d q Q 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "G o o o o #.! 2.R.R.* v+v+V 6.v+u+u+* ` ` 8+8+8+8+t 8+` t t A.v+v+v+@+v+v+A.A.t t t t t $ A.t $ @+$ , , , , , , , , , , , , , , @+, 6., 6.v+6.V 6.6.6.m V m m 6.6.m m d.m d.P F+F+d+d+F+P l+,.C.#+H.a+)+B.r+i r+` * Y.U P P e+F+[ j.L 3 m+l.} Q 0.. . . . . 0.Q q d 7 [.: : K.r.|+x+s o.o.Q.Q.$. + + +*.[+y.y.y.y.y.y.y.y.n+n+y.y.M M y.y.y.y.y.y.y.y.M M y.y.y.y.M y.y.y.y.y.y.y.*.y.y.y.y.y.m.y.y.y.m.y.y.y.y.y.M a M y.M a M M y.y.y.y.y.R y.M M n+y.y.y.y.R y.M y.R y.m.y.m.n+n+n+M R n+n+n+b n+z+n+n+n+m.b m.b z+n+z+#+b w H.b N.b b b H.H.H.H.b H.b H.H.H.H.P.H.H.H.H+.+B P.H.H.N.1 B H.N.b H.B B .+1 P.P.B .+.+X.B H+B .+)+X.X.B B X.X.)+X.X..+)+)+2.2.i.i.B.2.B.)+)+i.)+)+^.q.^.2.)+^.^.R.M.M.* g - J m P d+d+$+$+' ' K p K K K l K l l {.l {.l .F.K {.K K {.K K 3 3 $+$+d+d+v [ d+d+F+F+F+F+F+F+O.O.O./ # / # / # # , # # # # d.# ).# O.P J 5 ]+%+%+V.%+V.V.V.%+%+%+_+^ ^ 2 z.T _ $.'.$.z.z.2 2 ^+^ ^ ~ _+^ ^ ^ 2 2 a T $.0 w.D.]. .m+@ @ ] } d d d q q Q 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . t+. t+. . . . . ", "G G G #.G o ! ! 3.` * g V g u+u+* ` 3.R.8+o o f.o 8+8+8+t ` t A.v+v+v+u+A.` M.8+` 8+f.8+8+t t t $ $ @+, , , , , , , , , , , , , , @+@+@+6.@+6.6.6.6.V 6.V 6.m m 6.m m m m d.P F+F+F+F+F+P U Y.- '+}+R.2.r+4 i f.` g J m P [ [ j.j.$+3 l l.] } Q 0.. . . . . . . 0.Q q B+[.[. . .].].x+o.w.I.I.t.$.[+ +[+*.*.y.y.y.M M y.y.y.y.y.y.y.y.y.n+M M y.m.*.M n+n+R M M y.y.n+y.y.y.y.y.y.y.y.y.y.y.*.y.y.y.y.y.[+y.y.y.y.y.y.M n+M M n+M M n+M R y.M y.R y.n+M M R n+n+n+n+R n+n+m.n+n+n+z+b #+n+n+n+n+z+b b b #+z+#+b z+N.b #+b b b N.b N.H.b b H.b P.H.H.b H.b H.P.B H.P.H.H.H.P..+.+P.H.H.H.P..+1 H.H.B 1 .+X..+.+B X..+)+X.X..+X..+)+)+)+X..+^.)+^.)+i.)+)+i.B.C+C+C+C+C+C+2.)+B.B.B.)+2.^.^.2.)+^.8+a+* * * u+- V m F+F+d+$+$+' ' ' $+p p 3 K K l 3 K l 3 K l K K K K K p p p $+$+v d+d+d+d+F+F+F+F+F+F+[ F+O.d.O.O.# / # / # # , # , # # # # O.# ).O.U X ~ ; V.V.V.V.V.V.V.%+~ ~ ^ 5 z.z._ _ '._ '._ 2 ^ ^ ^+^+^ ^ _+^ h.^+2 r $.& w.O j.L K .F.@ @ ] ] ] } d d d q q Q 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . t+. . . . . . . ", "6 G G 6 6 ]+]+G+@.M.s.h+g g u+M.3.3.! ]+o o _.i i i 8+o R.` ` A.u+u+u+A.` 3.` o 8+o 8+8+8+8+` t A.$ v+, , , , , , , , , , , @+, , , 6.@+6.6.6.6.6.m 6.m 6.6.6.6.m 6./ / m / d.d.F+F+F+P m Y.- h+'+q.^.r+4 4 /.8+* g J l+P [ [ d+j.L 3 F.m+] d Q 0.. . . . . . . . 0.Q Q q [.[. . .].].x+s o.0 I.t.t. +1+[+y.y.y.M y.n+y.y.M y.y.y.y.n+M M y.y.y.y.y.y.y.y.y.R n+y.y.y.y.y.y.y.y.y.y.M p.y.y.y.y.n+y.y.m.m.y.9+y.y.M y.M M a n+M M M M R m.M n+R n+n+n+#+#+n+z+n+z+z+z+#+b b b z+b w !+b H.N.z+b b b N.b b #+b b N.b b N.z+N.b b w H.N.H.N.b H.N.H.B P.H.H.H.H.B .+P.P.B H..+.+B .+B P.B 4+X.1 B P.B 4+4+X.)+X.X.4+^.)+B.)+)+)+^.2.)+)+2.)+)+)+B.)+)+)+C+C+C+2.C+2.C+2.C+C+2.^.q.q.2.^.^.^.^.^.8+q.` ` M.* u+- V m m F+F+d+).).).$+$+$+$+3 3 $+3 3 $+p 3 3 3 l K K p p 3 $+$+v ).).d+F+F+F+j F+F+F+P F+d.d.O.O.O.d./ # / # , # # / # # / # # ).).).F+P - 5 ; V.V.I y y V.V.%+~ _+^+^+z.$.T '.w.j $._ z.^+2 ^ ^ _+^ ^ ^ ^ ^+2 a T C w.j.|+L l {.F.@ @ @ @ @ @ ] ] ] } d d Q q 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . t+. . . . . ", "6 6 6 ]+c+G+S.@.E+s.- h+M.s.3.3.! ! o G _._._._.G _.o o ! 3.` M.g M.* M.` ! o o _.o 4 o o 8+8+t ` A.v+v+, , , , , , , , , , , , , @+, @+6.6., m , 6.6.6.6.6.6.6.m 6.6.6./ 6./ / d.d.d.m m 6.* M.R.8+f.i 4 + f.` u+V ,.U P [ [ j.j.j.l F.m+] } q 0.. . . . . . . . . . 0.Q q 7 |.: .K.].D.O I.I.Q.$. +1+1+*.*.*.y.y.n+y.n+y.n+y.y.y.n+y.y.y.y.y.y.y.m.y.y.y.y.n+*.y.n+*.n+y.y.y.m.y.y.y.y.y.y.*.p.[+y.y.9+y.m.[+m.M n+M n+n+M z+z+n+n+n+n+w b #+#+n+b b H.E+H.b n+N.b N.H.N.H.w N.H.H.H.H.P.b N.b N.z+b N.b #+z+n+z+b N.b b z+b b N.H.P.H.P.H.H.H+.+1 B P.B P.B X.4+B 1 P.B X..+.+.+1 .+4+4+.+X.X.1 X.^.X.)+)+i.i.)+B.B.B.B.C+)+B.B.)+C+2.C+2.C+B.2.q.)+2.2.2.2.2.q.2.2.q.q.4+4+4+^.^.^.^.q.^.q.q.R.` * * A.* u+V V m d.F+).d+).$+d+v ).$+v $+$+$+$+3 $+p $+$+$+p $+' $+$+$+d+d+F+F+F+P F+P d.P P d.d.P d.O.d.d./ d./ # / # , # / # / # # # ).).).).F+U z.n.V.y V.y y y V.%+~ ~ ^ 2 z.$.Q.j w.j j _ 2 ^ ^+^+^ ^ ~ _+^ ^ ^+2 z.T w.w.x+L l l K {.{.{.{.@ @ @ @ @ @ @ ] ] d d d Q 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "c+c+G+c+1 1 f 5 E+X X X f 3.3.]+]+G G _.W W _._._.G o o o 8+M.M.M.M.3.3.]+o G _._._._.i o o ! R.` * v+@+, , , , , , , , , , , , , , , , , , 6.6., 6.6.6.6.6.6./ , , , / , / / / / d./ / 6.u+u+` q.2././././.` t u+V m m U P [ [ v L 3 l @ @ } d q 0.. . . . . . . . . . . Q q 7 |.: .].L x+o.I.I.Q.t. +[+[+[+y.y.y.y.n+y.m.y.n+y.y.y.M M *.n+y.y.n+y.y.n+y.m.y.m.m.y.y.y.m.p.n+y.y.y.[+p.y.y.y.[+m.9+y.[+m.n+m.n+m.n+n+z+n+b z+z+z+z+z+b H.H.H.N.N.b H.P.H.H.H.H.b H.P.P.P.H.P.b H.P.b P.N.N.N.z+b b N.b N.b N.z+N.z+b P.N.N.N.w H.H+B .+H.H.H.B 4+.+H+B B H+.+.+)+X..+X..+4+^.^.X.X.X.X.)+X..+X.)+)+)+^.)+B.B.C+C+C+B.)+^.B.2.C+2.2.q.q.q.)+2.2.)+q.q.q.q.C+q.q.2.4+^.)+^.4+4+'+4+^.2.q.^.8+q.R.8+8+` ` t M.u+A.V m m d.d.F+F+F+).F+d+).v d+v v v ).$+v $+$+$+$+$+$+v d+).d+F+F+P d.m d.m m / m / d.d.d.d./ # / # / , # / # , # / / d.d.# # ).).F+F+j k f %+V.y h I =+V.V.%+~ ^+2 T $.[ w.j.j.w.'.k 2 ^ ^ ^ ^ ^ (.n.^+5 2 r _ & w.j.j.l 3 {.K {.{.K K K {.{.{.@ @ @ @ @ @ ] } q q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "1 5 5 5 5 z.z.z.z.E+f 3.! ]+G G G W G W _._.W G G G ]+o ! 3.3.M.M.3.! ]+]+G _.W 3+_._._.o o o 3.` * g 6.6., , , , , , , , , , , , , , 6.6.6., / , 6.6., , , , 6., , , , , , / / / / / / 6.v+A.t 8+/././.f.t t A.v+V J m U m P [ d+v 3 l m+@ } d d Q 0.. . . . . . . . . . 0.0.d 7 7 : .].|+O o.I.Q.Q.t.$.*.*.*.y.y.y.y.y.n+y.n+y.y.n+y.n+y.*.y.y.y.y.*.y.y.y.y.y.m.m.y.y.*.m.y.y.y.y.y.p.*.p.n+[+m.9+n+n+m.z+n+#+z+b z+b b N.H.b N.#+N.N.H.H.B H.}+N.H.H+H+H.P.H.P.H.H.H.P.H.H.P.b P.H.P.H.H.H.b N.z+N.b H.H.P.b b N.N.H.H.H.H.H.H.B H+.+H+.+P..+4+X..+.+X..+X.4+^.X.^.i.)+)+^.)+^.i.)+B.)+)+^.)+X.)+B.^.)+q.)+2.2.2.C+2.q.^.q.B.2.2.)+^.)+q.)+2.)+q.)+q.)+B.B.^.^.^.4+.+q.4+4+'+a+a+2.q.2.2.8+8+q.8+` ` t t A.A.u+V 6.m m d.d.F+F+F+F+F+F+d+d+d+d+d+).d+d+).d+).).).).d+F+F+F+d.U d.m m / m / m / / / / # / / / / # / / , # / / # / # d.# O.).).F+F+j '.z.n.%+V.h y y I V.~ ~ ^ z.T & w.[ j.j.j.w.'.2 ^ _+^ ^ ~ ^ ^ ^ 2 2 a $.& w.j.L 3 3 K K K K K K K K {.K K {.{.@ {.@ @ ] } d q 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "5 2 z.a a a z.5 5 c+]+]+G G G _.W < W W W G W G G G G ]+! 3.f 3.3.]+]+G G W W W W _.W W G ]+! 3.M.g V 6., / , , , , , , , , , , , , , , , , , , , , / 6., , , , , , , , , , , , , , / @+6.v+@+$ t t t t t t A.v+V V V m m U j F+v v 3 K F.@ ] ] d d Q Q . . . . . . . . . . 0.Q q 7 l.: .].].x+s w.0 & Q.$. + +*.*.[+y.y.y.m.y.m.n+y.M y.y.y.M y.y.m.y.9+y.y.y.n+m.y.y.y.n+n+n+n+p.p.n+m.n+n+n+#+m.z+#+#+#+b H.N.N.b #+b b P.P.H.P.H.w H.H+H+H+a+B P.H+H+P.H+.+B 4+P.P.H.H+H+H+B P.H.P.H.P.H.H.H.b H.b H.H.N.H.N.b H.H.H.H.H.P.P.a+B 4+.+.+.+X..+.+4+)+)+)+)+)+)+^.2.)+i.B.)+)+)+)+2.2.2.2.q.^.^.q..+.+B.)+q.q.)+q.2.)+q.)+X.X.^.)+)+q.^.4+q.2.B.2.)+q.q.2.)+2.)+.+^.^.)+)+^.4+4+4+R.R.2.8+2.8+2.8+8+f.` t t A.A.v+v+6.6.m m m d.m d.P F+F+P F+F+d+F+F+F+).F+).F+F+F+F+F+F+P d.d.m m m m 6.6./ / , / / , # / / / , # , # , # / / / / d.O.O.).).d+F+P j k k X n.~ =+=+=+=+=+; ^ ^ z.$.0 w.j.O L j.w.[ _ z.^+^ ^ ^ n.n.^ 5 2 2 _ 0 w.w.j.L p K ' K ' K ' ' ' K ' ' ' p p K K F.m+l.] d Q Q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "a T T & $.T a 5 1 (.W G W W < < W < < _.G G G 6 ]+]+]+]+S.@.c+]+]+; G G W W _.W W W G ]+]+]+3.f - J m / 6./ , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , / , , , , @+@+$ $ $ $ $ $ $ v+v+V V V m m m P [ d+v 3 K K @ @ @ ] } d d Q 0.. . . . . . . . . . Q q |.[.l. .].L x+o.o.Q.Q.Q.$. + +[+[+y.y.y.y.y.[+y.y.y.y.y.m.y.n+y.9+y.m.*.n+n+y.n+m.m.m.m.n+n+n+n+n+n+n+n+n+z+N.w b b #+b b H.H.H.N.b N.N.H.P.P.H.H.H.H.P..+H+H+4+H+H+B 1 P.H+H+.+H+.+H.1 B P..+P.H.B B B B P.H.H.H.H.P.H.H.H.}+H.H.}+B H+B H+1 @..+H+4+X.)+i.)+)+)+)+)+i.B.B.B.2.)+2.)+B.B.2.2.^.^.^.)+2.^.^.4+4+^.4+^.)+q.)+)+^.B.)+)+^.^.^.^.B.2.)+^.^.^.q.)+B.B.q.q.q.2.C+C+)+)+^.)+)+)+^.4+a+4+8+q.8+2.r+f.8+8+f.8+t t t t v+u+V 6.6.m 6.m m m m U / m P d.U F+P O.P O.F+F+d.F+d.d.d.m m 6.6.6.6.6.6./ 6./ , / , / , / # , # , / / / , / / / / d.O.O.F+O.d+F+P j U k X f 3.; G W W G ~ 1 5 z.$.& w.j.j.x+x+O w.& _ 2 ^ ^ ^ ~ ^ ^ 5 2 a T j w.j.v v 3 3 p ' ' ' ' ' ' ' ' ' ' ' $+L L l K .l.l.d d q 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "& w.w.<.w.T 2 ^ G G W < < < < < c < W W G n.n.]+n.]+c+1 c+]+(.]+; G G W W W W G G G (.]+n.f z.k k ,.m m , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , @+@+@+@+@+$ $ $ $ @+v+@+@+V V V m m P F+F+v $+3 K K {.@ @ ] ] } d q q Q Q . . . . . . . 0.Q d } [.: .K.|+x+O o.I.Q.Q.Q. + +1+ +y.[+y.y.m.y.y.y.*.y.y.m.[+y.y.y.9+n+M n+R m.n+w n+#+n+b N.N.H.H.b #+b w H.H.H.b N.b H.H.P.H+H.N.#+H.H.H.H+B B }+.+B B H+.+.+B 1 .+B .+1 B 4+H+1 B 1 .+4+B H+B H+H+H+B B B P.H.P.H+}+H+B H+.+H+}+H.B @..+.+.+.+^.^.^.)+)+2.2.2.^.)+^.2.)+)+2.2.^.2.)+^.)+2.^.4+.+4+^.)+)+4+4+4+4+)+)+)+^..+)+^.2.2.)+)+^.^.2.2.2.C+)+)+q.2.2.C+B.2.2.2.2.2.C+)+2.)+2.B.B.)+^.R.R.q.2./.r+f./.f.8+f.t t t A.$ u+v+@+6.6.6.V 6.V 6.6.m m m m m m m m / m m m m m m m 6./ 6.V 6.6.6.6.6.@+, , , , / , , , , / , / / , / / / / / d.d.d.O.O.F+O.j j k k z.X 5 f n.]+G G G c+1 z.z._ '.w.w.w.O j.O w.w.& z.5 ^ n.n.1 ^ 5 5 z._ '.[ j.j.v 3 $+' p ' ' ' ' ' ' ' ).).d+d+d+j.j.L l .l.l.d d Q Q 0.0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "D.|+> 6+w.r 5 6 ; W W < =+< c < j+< < G ]+1 5 5 5 5 c+c+n.G G W G W W W G _.G 6 n.c+5 5 z.z._ _ j j P m / , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , @+@+@+$ $ @+$ @+v+$ @+V @+6.V 6.6.m / P P F+d+d+$+3 3 K {.{.@ @ ] ] } d q q Q 0.0.. 0.0.. 0.0.Q q } |.l. .r.].x+<+D.o.0 I.Q.$. + + + +*.*.y.n+y.n+m.y.y.n+m.m.m.m.m.#+n+z+z+w b H.N.#+#+b H.N.H.H.b N.b N.b H.H.N.N.#+b N.P.P.P.H.H.P.H.P.P.H+B B H+H+.+H+B .+4+.+.+1 .+.+.+.+.+X..+X..+4+B H+.+.+X..+a+B @..+.+.+.+B H+B B .+.+4+a+4+B a+4+.+.+4+^.4+^.)+)+)+2.2.2.^.^.2.)+^.2.^.^.)+^.)+2.2.^.^.^.^.)+)+)+.+4+4+^.2.)+2.)+)+)+2.C+2.B.B.^.2.2.C+r+2.2.2.2.2.2.2.2.2.f.r+r+r+C+B.2.2.2.2.2.)+q.R.q.8+q.8+f.f./.t f.t t t $ $ v+v+@+V 6.V 6.V V V 6.V 6.m m V m m 6.m m m m 6.6.6.6.6.V V V v+v+v+@+v+, , , , , , # , # , # , / / / , / , / / m d.P P P F+P j U k k X f 5 ]+]+]+; G ]+]+1 5 z.e.$.w.w.j.O O w.w.& $.T z.z.^ n.c+n.5 5 z.y.$.'.w.j.j.$+$+$+' ' ' ' ' # ' ).d+F+[ [ j w.j.j.L l .l.] d d q Q Q Q Q 0.0.. . . . . . . . . . . . . . . . . . . . . . . . . . ", "S S |+6+& z.n.6 W W < W < < < (+< W < G 3.5 z.z.z.5 c+n.G ; W W W W W W W G ; ]+f 5 z.z.T $.& w.0 j 7+m m , , , , , , , , $ , , , @+@+, @+, , , , , , , , , , , , , , , @+, , , , @+, @+@+@+@+$ @+v+$ v+@+@+v+V @+6.6.6.m m d.m F+F+d+v v $+L 3 K K F.F.@ ] ] ] d d d q q Q 0.0.0.0.0.q B+7 [.: . .].x+<+D.D.o.o.I.Q.Q.t.[+*.y.y.y.m.y.m.m.n+n+m.n+m.b b z+n+m.b N.P.P.H.N.b #+E+B H.P.H.N.n+b b H.B H.w N.H.H.H.H+H+}+N.H.H+B @.B H+a+4+H+.+X..+.+4+4+.+X.X.X.4+B .+X.i.X.X..+4+.+)+)+)+.+.+@..+4+^.4+.+R.4+a+B a+4+a+4+a+a+H.B a+4+4+4+^.4+)+^.^.2.B.^.)+)+)+2.2.2.2.)+)+^.)+2.B.B.)+^.^.^.)+)+^.X.^.)+^.C+B.2.)+)+^.2.C+C+2.C+B.2.2.2.C+2.2.2.r+f.r+r+r+q.2.2.2.B.B.)+2.o )+! 2.! q.q.R.f.f.t f.f.f./.t t t $ $ $ v+@+v+6.@+V V V V V V V V V V V 6.6.6.6.V 6.V 6.V V v+V v+v+v+v+v+v+v+@+, , , , , , , , , , / , , / , / m 6.6.m m U d.P j P U U k - 5 5 f 1 G+]+G ; 6 ]+c+5 z.z._ $.w.w.w.w.6+w.w.& $.e.a 5 H+G+c+G+5 E+R _ '.j [ [ j.v $+$+$+' ).).' ).).F+P U j j U w.j.D.L . .l.] d d q Q Q Q Q 0.Q . . . . . . . . . . . . . . . . . . . . . . . . . ", ": K.S 6+T z.n.]+G W W W W W W < j+W _.]+k '.& $.z.5 n.; G W ; W W W G G ; G ]+^ 5 z.T $.w.w.w.w.w.[ P m m 6., , @+$ , , , , $ , $ @+, @+, @+@+, @+, , , , , , , $ , , $ , @+@+@+@+@+@+@+@+@+@+@+$ @+$ $ v+v+@+v+@+@+6.6.6.m m d.P P P [ d+j.v v 3 l K K F.m+@ @ ] ] } d d q q Q 0.0.0.Q Q q d ] : : m+K.].L <+D.o.o.I.Q.Q. +1+*.y.m.m.n+#+m.m.n+n+b #+H.H.b n+n+n+b P.P.B H.b #+b B H+H.H.w b b b H.H+P.w N.E+P.B H+P.B N.H.1 H+H+4+B B @..+X..+^..+4+4+)+i.)+)+.+@.4+.+)+)+)+i.^.4+^.^.^.^.q.4+.+a+.+4+.+.+a+a+N.a+H+B }+'+4+}+N.}+4+@.4+^.4+)+)+)+)+B.B.)+)+2.2.2.2.B.2.2.2.B.2.2.C+B.)+^.2.2.2.2.)+q.)+)+2.2.C+C+2.B.2.2.C+2.2.2.2.r+2.r+2.2.f.2.f.f.q.f.2.q.2.2.q.2.)+^.2.! ^.2.^.2.R.R.` q.t t t t t t t $ $ $ 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+$ $ $ @+$ @+@+, , , , , , , / , / , 6.6.V 6.V m m m m m P U U U U _ k X f E+1 c+]+]+G G ]+]+1 5 z.a T $.w.w.6+w.w.w.C $.T _ a z.E+@.]+Z 1 H+E+R _ _ j [ [ v d+v ).$+' ).$+).d+F+P U U _ U Q.[ O x+L .m+l.} d d d q q q Q q Q Q 0.. . . . . . . . . . . . . . . . . . . . . . ", "|.: > O T z.5 ^ G+]+]+G G _.G _.W _.o k w.O O T 2 ^ c+G ; G G G W G W G G 6 ]+5 z.$.T w.6+O j.x+[ [ P m m 6.@+, , $ , $ $ @+@+@+@+@+@+$ , $ @+@+$ , $ , $ , $ , $ , , @+@+, @+, @+@+@+@+@+@+v+@+$ $ v+$ v+v+v+@+v+V @+6.6.6.m m m P P [ [ [ [ j.v j.$+l K {.F.m+m+l.l.] ] } d q q Q Q 0.Q q q B+} [.[.m+ . .K.].x+<+y+o.Q. +[+[+[+y.#+b H.w n+m.n+n+z+b N.b z+z+z+N.P.H+P.N.z+b N.P.H+@.B N.N.H.P.P.H.B H.H.B H+H+1 a+}+}+B H+X..+@.@.B 4+)+)+)+)+4+4+4+X.)+)+^.q.^.4+^..+)+^.^.^.R.4+4+^.^..+^.a+4+@.a+.+S..+a+a+H.H.H.}+a+'+B }+H }+4+.+^.)+.+)+)+2.B.B.r+C+B.B.2.r+r+B.B.2.2.2.i r+r+r+2.2.2.2.r+C+2.2.2.2.2.r+2.r+B.2.r+2.r+r+r+2.2.f.f.2.f.q.2.q.q.q.f.q.q.q.q.^.^.2.! ! ^.R.S.^.R.` q.` ` t t t t t $ t $ $ $ $ $ v+@+@+@+@+v+V v+6.V V V V V V V v+v+v+V v+v+v+v+A.v+A.$ A.v+$ $ $ $ $ $ $ , , , , , , , / , 6.6.m V 6.J V m m J P m U U J J z.z.b 5 H+@.c+]+6 6 6 6 G+G+P.z.a a & & w.O O <.w.w.& T e.M z.b @.G+6 ]+1 E+w X _ _ j [ [ [ d+v ).$+).).).).P P U k k _ _ w.w.j.L l .l.] } } d d q q d q q q Q q q Q 0.. . . . . . . . . . . . . . . . . . ", "k.: ].O w._ z.z.f 5 5 @.1 G+c+]+o 3.- j.|+O 6+$.z.5 c+c+]+(.G 6 G 6 ; ]+(.]+1 z._ w.w.6+O > O O j.[ j m m V @+@+$ @+$ @+@+$ $ @+$ $ @+$ @+$ , $ @+$ , $ , $ , $ , $ , @+@+@+@+, @+6.@+v+@+v+$ v+u+v+$ A.$ A.v+v+v+v+V @+V V V m J J U U P j j [ [ j.v v L l K l {.F.F.l.l.] } d d q Q Q Q 0.Q Q q d 7 |.[.l. . .r.x+y+O o.Q.t. +[+y.n+n+H.E+#+y.m.n+z+P.H.N.#+#+b H.P.H+H+B N.H.H.H+H+H+H+H.b H.H.H+H+H.H.H.H+.+)+X.@.B H.H+.+X.X.^..+.+4+^.)+)+)+^.q.4+.+^.4+R.a+a+a+4+B .+^.^..+4+a+a+@.a+.+^.^.4+S.a+@.4+@.4+a+H+B H.}+B a+4+4+H.B a+.+^.B.)+B.B.2.C+C+r+C+B.r+r+r+i i C+r+r+2.r+r+r+r+2.2.2.2.2.2.2.2.2.q.2.r+2.2.B.2.2.2.2.2.2.q.2.q.2.q.2.f.q.f.q.` q.q.R.a+R.a+a+a+a+a+a+R.S.S.a+a+R.R.` ` t $ $ $ $ $ $ v+$ @+@+$ v+v+v+v+v+V v+V v+V v+V v+v+V v+V v+v+V v+u+u+v+A.A.$ A.A.$ $ $ $ $ @+$ , $ , , , , , 6.6./ 6.6.V 6.V V J m m U P U U k - X E+5 1 1 c+G+Z G G 6 6 c+G+1 z.z.T T w.C w.<.w.C C w.& & T a z.H+G+Z k+G+@.w X X k k j [ [ [ d+d+d+v d+F+F+P U U - X k _ '.w.O L l m+ .l.} } d d d d d d d d d q q q q Q . . . . . . . . . . . . . . . . . ", "B+~+K.|+w.w.w.$.'._ k z.X z.E+f E+U L ].K.|+w.T z.z.5 5 5 c+c+c+n.G+]+]+]+G+X k C w.O 6+|+|+x+j.w.[ P 7+m V @+@+$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ , $ $ , $ , $ $ @+$ @+@+v+@+@+@+v+v+v+v+u+v+A.u+$ A.A.v+v+v+v+v+v+V V - V V V J J U U j j [ [ [ j.v j.L 3 l ].l l m+l.l.] d d d Q 0.Q 0.0.Q Q Q q 7 7 [.m+ . .].j.o.0 Q.t.t.y.n+b w H.m.R m.#+z+b H.H.b m.N.H.P.P.H+H.w H.H+1 1 .+H+N.w H.@.X..+@.a+N.P..+X.)+.+a+B B 4+.+^.4+^.a+a+4+4+4+^.^.4+4+a+}+a+4+4+4+a+B H+a+@..+^.S.^.4+4+G+)+S.^.^.^..+4+.+^..+.+S.B a+}+}+a+^.@.a+4+4+^.^.B.C+B.B.B.r+i r+i i C+2.r+2.4 4 r+2.r+f.f./.r+r+2.8+2.8+q.2.2.q.2.q.q.2.2.2.)+^.^.^.q.2.2.q.q.q.q.q.q.` q.` ` '+'+'+'+'+3.M.a+'+a+a+3.a+3.S.a+a+R.R.'+` t t A.$ v+$ $ v+$ $ @+@+@+@+@+@+v+6.v+6.@+6.V v+V v+v+u+v+u+v+v+v+u+A.u+v+A.$ $ $ $ $ $ $ $ $ @+@+, @+, @+6.6.6.6.6.6.6.V V V V m J d.U U U k X b E+@.G+G+]+Z G 6 k+#.6 6 1 5 z.a _ T & w.w.<.<.O C C & & $.1+z.E+G+i.Z Z G+@.f w X k k j j [ [ v d+).).d+F+P U - k E+b z._ Q.w.D.].l l.l.] } } } } } } d } } } } d d d q q Q . . . . . . . . . . . . . . . ", "D+|.[.: l |+L x+O w.w.j $.U $.'.0 x+K. .K.|+O & $.T z.z.z.z.X 5 5 5 5 5 1 f _ $.w.6+6+|+|+> x+x+O v P P m V v+v+$ $ $ $ $ $ t t t t t t t $ /.$ $ $ $ $ $ $ $ $ $ $ $ @+$ @+v+v+@+v+V v+v+v+v+u+A.A.A.A.A.A.A.A.v+u+u+u+v+v+V - - - V - - J J J j j j [ v j.j.j.j.L L L l .m+l.] 7 d d Q 0.Q 0.. . . Q q q B+} l.m+].<+<+o.o.t.Q.[+m.b H.E+#+9+y.z+b H.H.H.b n+w B .+X.@.H.H.H.P..+X.X.S.}+H.H.@..+.+.+S.a+H.4+4+4+.+4+}+'+}+B a+4+4+4+a+}+a+}+a+a+a+'+B }+}+a+4+B a+a+H+B .+.+.+a+^.^.^..+)+)+)+)+2.)+! ^.R.^.^.)+4+4+4+B 4+R.^.^.R.4+q.q.2.B.C+B.B.B.i r+r+r+r+B.r+2.2.f.2.r+2.2.q.2.8+2.2.8+q.2.q.q.8+^.q.R.R.q.R.2.q.R.^.^.a+a+a+a+R.R.a+` a+* '+` a+* a+M.s.s.s.s.3.f 3.3.a+@.a+! a+a+R.R.` * t A.A.A.v+A.@+$ @+v+$ $ @+@+v+@+@+6.v+@+@+v+6.@+v+u+v+u+v+$ u+v+v+v+A.v+v+$ A.$ $ $ @+$ , $ , $ , $ , @+@+@+@+6.v+6.V V 6.V m V m U m U U J k E+E+1 c+6 6 6 6 k+G k+k+6 G+c+1 2 a T T & C C w.<.<.w.C C & C $.*.b H+i.B.Z G+@.}+E+X X k J U P P d+d+d+F+[ P m U - X s.E+b z._ w.j.x+l F.l.@ ] } } d } } } ] ] ] |.] } } d d q Q 0.. . . . . . . . . . . . . ", "q B+|.[.: K.K.l l L |+x+O j.j.j.|+ .: [.[. .].x+w.& w.'.T _ _ z.z.z.z.z.z._ $.$.w.w.> > |+|+|+x+j.[ [ 7+Y.V u+t A.t t t f.t /././././.+ /././.+ /././././.$ /.$ $ $ $ $ $ $ v+v+v+u+v+u+v+u+* A.* t * t t A.A.A.A.A.u+v+u+u+u+u+- M.- - - - J J U P j j F+[ d+j.j.j.j.3 3 l l m+l.] ] d d d Q 0.0.0.0.. 0.Q q q 7 l. .].<+<+o.0 t.y.#+b H.w m.y.m.n+H.P.P.N.b b b P.@..+.+@.H.H.@..+^.^..+a+N.B a+.+.+^.4+4+}+B }+a+a+a+a+}+'+H.a+a+4+a+4+'+}+H }+B 4+a+'+B }+H+H+4+4+4+^.S..+S.^.^.! )+)+! X.)+)+B.B.)+)+)+^.)+! ^.)+.+4+a+a+4+a+4+4+^.^.^.)+2.2.r+r+r+q.2.r+2.4 2.2.q.f.q.f.8+q.8+q.8+q.8+q.^.8+R.R.q.R.R.R.R.a+a+'+3.a+a+3.f 3.M.3.'+3.M.'+a+'+R.'+'+'+M.* s.M.s.s.s.s.}+3.S.S.a+S.a+S.R.3.R.R.` 3.` A.A.v+v+v+v+v+v+@+@+$ @+@+@+v+@+@+@+@+@+v+v+V v+v+$ u+v+A.v+A.v+v+$ $ v+$ @+$ $ $ $ $ $ , $ , @+@+, @+v+6.@+@+6.V 6.6.6.V m m m P m U k k E+f 1 c+X.6 ; k+k+; G 6 6 c+1 5 5 a e.T & C w.<.w.<.<.<.C C & & e.z.P.G+6 Z i.G+S.f M.X - k U j j j [ F+P P P U Y.- E+f 3.f X R '.0 j.L l {.l.@ @ ] ] ] ] ] ] ] l.l.l.l.] } d d q Q Q Q . . . . . . . . . . 0.", "0.q B+[.[.l. . . . .].].].|+].]. .m+[.7 ] [. .S |+O O O w.w.w.0 '._ _ _ $.T $.$.w.w.O > |+|+x+x+x+d+[ P V V A.t f./././././.+ /.+ + + + + + + + + + + /./.+ /././././.t t t $ A.$ A.A.A.A.A.t t * t ` t t t ` A.v+u+u+u+u+u+- u+M.- u+M.- - - J J U P j j [ j [ [ [ j.j.v L l l {.m+@ ] } d d q Q 0.0.. . 0.Q 0.Q } l. .L x+o.0 t.y.b B @.B m.m.R z+H.H+H+H.H.H.H.4+@.4+.+@.H+H.}+H+4+a+B a+'+H }+4+H+a+.+a+}+H }+B B .+a+B a+N.H+@.4+a+4+a+a+'+a+B 4+a+a+a+4+a+H+}+.+4+^.^.^.^..+^.^.)+2.B.i.)+)+2.2.B.2.B.o 2.2.q.8+^.R.a+4+a+` R.R.^.^.q.^.q.2.2.2.B.2.2.2.q.f.2.2.q.q.R.q.R.` a+'+* * ` '+'+a+` '+'+'+'+'+'+a+* '+f s.'+f s.f E+E+s.f M.M.M.M.M.'+M.M.M.M.- s.- - - X s.M.3.a+S.S.R.3.a+a+3.3.` * * A.A.u+u+v+v+v+v+v+v+@+$ @+@+@+@+v+v+@+@+v+@+v+v+v+v+$ A.A.v+A.v+A.v+$ $ $ $ $ , $ , $ , $ , $ , @+, @+@+V V V v+V V 6.V V m m m P m U k k X 5 G+G+c+6 k+G k+6 k+(.X.1 5 2 z.a T & C C C <.<.w.C <.w.<.C & T R b @.Z k+G ]+S.S.E+s.X - k U U j P P P U U J - M.3.S.@.H+E+R _ 0 j.L 3 K {.m+F.m+@ @ ] @ l.F.m+ .: l.[.l.7 ] 7 d d q q Q 0.0.0.0.. 0.Q Q Q ", "0.Q B+] [.: l. . .K.K.K.K.]. . .: l.7 B+B+|.: K.K.|+|+|+|+|+O O O w.w.w.& & '.& w.O |+> > |+|+|+j.j.[ ,.,.* t f.f./.+ + + % + + % % + % % % % % + % + % + + + + + /./././././.t f.t t t t t ` t 8+` ` ` t t A.A.A.u+u+u+u+u+u+M.u+f f - M.X - J J J U U j j j j j [ [ j.j.j.L L l F.F.m+] ] } d d q Q Q 0.. . . 0.q ] m+ .<+o.Q.[+m.H.H+@.}+H.n+n+#+w B }+H+w w w w '+H+a+B }+}+H H.H.H.a+a+H.N.H.H.}+4+.+4+4+a+}+}+@.4+a+a+}+a+B @.H+.+4+4+4+4+a+}+B a+4+R.4+.+4+4+R.R.q.2.^.)+^.)+)+2.B.2.B.2.2.B.2.2.2.B.^.2.q.R.^.R.^.a+a+'+'+'+a+a+R.4+4+^.^.q.2.q.q.q.2.^.q.8+R.R.a+'+* '+* * '+* * * * h+* M.M.M.M.f M.M.M.M.s.s.s.s.w s.s.E+s.X s.E+s.M.M.M.M.M.M.M.h+M.h+s.- X - X M.3.3.3.a+3.3.a+3.3.` 3.M.3.M.u+u+u+V v+v+v+v+v+v+@+$ @+$ @+@+@+v+@+@+v+$ @+v+v+v+$ A.A.$ $ v+A.@+@+@+, $ $ $ , $ , , $ , @+, @+@+6.V v+V v+V u+V V V V V m m U U J - s.f G+G+6 6 W 6 W W 6 6 1 5 5 z.z.T $.T w.<.<.<.<.6+6+<.<.C C C $.a 5 G+i.G 6 #.]+G+3.3.X - - J U U P U U J V - M.3.^.! S.3.f b *.'.[ j.L 3 3 K l l .F.F.m+F. .l l . .m+: l.] [.] ] } d 7 d q Q Q q q Q Q D+", "0.q q |.[.m+: K.].K.].].].].S m+: [.7 B+B+B+[.K.S ].|+|+|+|+L |+x+O w.w.& w.$.'.6+O |+].S K.|+].L j.F+m u+` f./.+ + :.% b.% % % % % % % % % % % % % % % % % % + % + + + + /./././././././.f./.f././.8+8+t t t t t A.u+u+A.M.A.M.M.M.M.- - - J - J J J U U m U j j j j [ j.[ j.j.L 3 l {.F.l.] ] 7 d q q Q Q 0.. . Q 7 m+L o.Q. +n+b B 4+S.@.}+w n+#+#+w H }+w #+L.m.#+w }+}+'+H w w N.H+}+4+a+}+}+H+@.^..+.+a+4+4+a+.+.+4+4+4+a+.+.+4+@.4+4+4+4+4+4+a+a+4+4+R.^..+.+4+^.q.^.^.2.^.q.^.^.)+2.i.B.o 2.2.2.2.r+2.^.^.R.a+R.R.a+'+'+H H '+'+'+'+'+'+a+R.R.R.a+a+R.a+a+'+'+* * '+h+h+g g g g L.- g L.h+s.h+s.s.s.M.s.E+s.M.X s.s.s.X s.X s.s.s.s.X X M.* M.s.s.s.- - - - J - Y.- L.M.3.3.M.a+a+a+a+M.M.M.* M.- M.V u+V V u+v+v+v+v+v+v+@+$ $ @+$ @+$ @+@+$ $ v+$ v+v+$ v+u+v+$ A.$ $ $ $ , $ , $ $ $ , , , @+, 6.6.6.6.V V V V V V V V J V U m U U J R X E+H+G+c+6 6 6 6 6 6 c+1 2 z+T e.T C w.<.<.<.<.6+6+<.<.<.<.w.& T a z.G+c+#.k+#.G ! 3.3.f M.- - J m P J - - * M.8+2.r+r+o a+'+s.k _ j [ j.j.j.3 L 3 L 3 l K K L L x+].]. . . .: l.l.l.l.l.l.7 7 7 d q B+q B+B+", "0.Q B+] [. .K.l ].|+|+x+|+|+K. .[.[.B+q q k.[.~+ .K.].|+].].].|+L O O w.w.& & Q.w.O > S K.K.].L L [ 7+Y.* f.4 :.:.b.Y ........p+a.a.a.a.a.a.a.% a.a.% % % % % % % % % % + % + + + + + + + + 4 + + + + + /.f.8+8+t $ t t A.A.3.A.M.u+- - V - J V J m J J U U U U U j j j j w.[ j.j.v L l ].{. .m+] ] } d q Q 0.0.0.Q 7 l.l y+t.,+m.s.}+@.4+4+a+H #+m.m.#+s.w N.#+L.#+#+w H.}+B H.N.s.H.B @.@.H+a+B B @..+)+^.4+4+a+^..+4+4+R.a+4+)+^..+^.^.^.R.R.^.4+4+a+4+R.a+^.R.q.^.R.R.R.q.^.^.! R.R.R.^.2.)+^.^.! R.2.R.2.2.R.a+a+'+* '+'+L.h+h+h+g * * * * '+h+s.s.M.3.}+f M.f M.s.L.L.Y.Y.Y.g Y.Y.- - - h+X h+s.s.s.s.s.s.s.s.X s.X X X X X X X X - X X X - - X - X - - - - - J J J J Y.g * M.'+3.M.` M.M.* M.M.- M.- - - V - V V V v+v+v+v+v+@+@+@+@+, $ @+v+@+@+v+v+v+A.v+v+A.v+v+@+@+$ , $ , $ $ , , , $ , , , 6., 6.6.6.6.m V V V V V V m m m m P U J k X E+@.G+X.6 6 6 6 6 c+1 5 z.a T & w.C 6+6+6+6+6+> 6+6+6+6+<.<.C T a 2 P.G+Z #.G ]+o o 3.3.X - J J U m V * 3.` 2.B.F ;+A+B.o a+s.L.,+/+j e+[ j.j.j.j.j.L L L 3 L L j.D.x+x+K.K. . . .F. .m+ . .l.[.|.7 7 B+B+|.", "q q 7 l.: .].|+O O O O |+|+|+K.l.] q q q B+[.: K.S |+S ].S |+|+|+x+O O w.& w.0 w.|+S S . .].L v P C.* q.4 :.Y ....p+p+a.N a.a.= = s+a.s+a.s+s+a.a.s+a.s+a.a.a.% a.% % ..% % ..% % % b.% % Y % b.+ + + + /./.t t t t A.t u+u+M.u+- u+- V - J J U J J J J J J U U U j j j [ F+w.[ j.j.j.L l l l m+l.@ ] } d d d q d } m+L y+t.9+n+N.B @.@.4+.+'+#+m.n+n+H w w N.#+m.#+H N.}+a+}+N.}+H.H+.+.+.+a+@.4+^.)+4+^.q.R.4+^.^.^..+! ^.a+^.^.^..+)+4+R.4+R.4+a+4+'+'+4+a+^.^.R.R.R.a+R.R.R.4+a+'+a+a+R.! )+R.^.a+R.R.a+R.` '+'+'+L.L.L.L.Y.Y.Y.C.C.Y.L.L.h+h+h+w w #+s.E+s.X X s.- Y.J J J J J Y.J - J - - - - X s.h+s.s.X s.X X s.X - X X X X X - X X X - - X - - - - - J - J J J J J J - s.h+M.M.M.M.* s.g g - - - - - V - V u+- V u+u+u+u+v+v+$ @+$ @+$ v+$ v+v+$ v+v+v+v+v+$ v+$ $ , $ , $ , $ $ , $ , , , , , / m m m m m m m m J m V J m m U P U U J - w P.@.G+1 6 c+X.X.1 1 5 a a C & <.6+6+> > > 6+> > > 6+6+6+6+& T a 2 5 1 G+]+o ]+]+! 3.M.M.- g J m U V ` ! f.4 7.n *+G.A+r+2.M.h+J ,.w+l+j l+j 0 0 0 [ j.j.j.j.j.j.o.O D.|+|+L L L <+].].l K. .l.[.[.[.[.|.[.", "d 7 7 l. .].x+x+O O 6+O O 6+|+S .|.d q d 7 [.: S ].|+|+|+|+|+|+|+L O O w.w.0 w.O |+S .S .].j.e+C.* q.+ :.Y ..p+a.N = = = = s+= s+s+s+s+a.s+s+s+s+s+a.s+a.s+a.a.a.a.a.a.a.a...a.................% % % % + + /./.t t $ M.A.A.u+v+- - V J J m J J U J J J J J J J U U U U U j j [ j.w.j.j.j.L ].l l m+l.l.] ] d d } l. .L y+'.m.w H+.+)+)+)+)+.+s.#+m.w w N.}+s.N.#+#+H.}+B H+B a+}+.+.+.+4+4+.+4+^.^.)+)+R.^.^.q.q.)+^.R.4+a+4+R.^.)+.+4+q.'+4+4+R.R.'+a+a+'+R.^.^.q.R.4+` '+'+'+'+'+'+'+'+'+'+3.a+a+a+a+a+M.'+s.M.'+L.L.- - Y.C.k C.Y.Y.C.k Y.- L.X s.X s.s.X X X L.k g k Y.Y.J J J ,.J J J - k - - - - X - - s.X X X k - - k - J k - Y.k k k k k k - - X - J - J J J J U J J V - h+h+- * * h+h+g g V - V J J - V - V - V - V u+V v+u+@+v+v+v+@+v+@+v+$ V $ v+v+v+v+v+$ @+, $ , , , $ , $ , , , , , 6./ 6.m m m m m U m m m J m m P P P P P U U k X E+}+H+H+1 G+G+1 P.5 z.a T & w.<.6+6+> > > > > > > > > > 6+C T a z.5 5 P.H+S.R.! 8+3.3.X g - m J J V ` 2.7.3+Y *+*+( G.A+B.2.'+g C.C.k C./+/+,+/+'.'.'.j 0 [ 0 0 I.w.o.O x+x+x+j.y+o.j.O x+].K. .: [.[.[.[.", "} ] .m+].O O w.w.w.w.w.6+O |+].: ] d q d 7 [. .S ].|+|+|+|+|+|+O O O j.w.w.w.w.|+S : : K.].x+0 ,+h+q.r+:.;+..p+= = s+s+s+s+s+s+s+s+s+s+s+s+s+s+s+s+s+s+s+s+s+s+s+s+= = = = a.a.= a.= a.a.a.a.a.a.E.E.% % % + + /.t t $ A.u+M.u+V V V V J m J m J J J J U m J J J J U U U j j j j j w.w.j.j.j.x+L L l {. .@ l.l.] l.F.3 o.0 ,+#+P.@..+B.i.B.B.^.a+'+L.#+E+}+}+N.H.H H B @.S.@.}+a+4+R.^.^.^.^.^.^.^.2.q.^.^.q.R.R.R.R.q.R.a+'+'+'+4+q.R.a+R.a+'+'+'+` '+'+'+a+a+R.a+R.R.a+'+'+* * g L.L.h+h+h+#+w w E+M.s.E+s.E+s.#+X L.- 9+9+Y.C.J C.J C.C.- C.- - - X w X w X X X - k k J J J J J U J J J k J k k - - - X - - - - - X k k - k k - J J - J - k - X k k - - - - - - k J J U J J Y.- g h+h+- h+- g - J J U m J J U J J V - V - - V - u+v+u+v+u+v+v+v+v+V v+v+v+v+v+v+v+@+@+@+@+@+$ , $ , $ , , , , , , 6./ / m d.m P m m P m m m U U m U P U P j l+,+- #+E+H+H.P.P.P.b b a e.$.& w.<.O > > |+> > > > > > > 6+> 6+<.T 2 2 1 ^ 1 P.H+3.f 3.` 3.X - - J m J V ` 4 ;+b.E.p+:+u.:+b+i o R.* g L.#+- X X X X R _ '.U '.'.0 Q.0 0 I.I.O o.o.Q.Q.Q.Q.I.w.D.|+].K. .~+: [.", "] @ .l x+w.w.$.& & w.C w.w.O ]. .] } d 7 ] l. .].|+|+O 6+O > O |+x+O O w.O w.x+|+K. .K.].j.j C.H q.2.7.;+:+p+N E = x.= s+x.s+s+s+A s+s+A s+s+s+s+s+s+s+s+s+s+s+s+s+s+s+s+s+s+s+s+s+s+s+= = = a.= a.a.a.E.% + + /.8+t A.v+u+v+V v+V V m m J m U J m U J J J - U J J J U k U U '.j j j j [ [ w.j.j.L L L l l l l F.{.l j.[ ,+9+H.@..+i.B.C+C+B.)+4+'+w w }+B H+}+a+a+}+H+^..+.+4+a+4+4+^.)+^.)+^.4+R.a+q.2.R.q.'+'+'+a+a+R.'+'+'+'+'+'+` '+'+'+'+* '+'+'+'+'+a+'+'+'+'+'+'+'+'+h+g Y.Y.Y.Y.m.9+L.X #+s.w E+s.s.s.w s.s.X L.- - k C.C.,+C.Y.k k - 9+- X X X X X w X X - k k J ,+J J J J U U U U k k J k k k - k - - - - - X - k J J J U U J J J J k k - - R k - - J k - J V J m U J J Y.g - g - V J J m U m U P U U J k J V J V u+V - u+V u+V u+u+u+u+v+u+u+u+v+u+v+v+v+v+@+$ , , $ , , $ , $ , , , , / / m / m P P P j P U P j P m m U P P e+j e+j l+,+9+#+b w b R z.R M $.& w.O O |+].S S S S S > S > > > > > 6+<.C T z.5 1 1 1 1 E+M.M.M.M.X - - m J m u+` 4 Y E.p+>.>.u.u.*+;+4 q.a+* * '+'+s.s.E+}+w R m.k y._ _ '.& Q.Q.I.I.o.0 '. +e. +$.I.w.O |+K.S .~+: ", "m+F.l ].O w.T _ T & & & C w.O |+l l.} d } [. . .|+O O O O O O O O O O O L j.x+L K. .].L j.'.,+H 4+r+7.;+*+u.N = s+= s+= = = s+s+s+s+s+A s+A s+A s+A s+s+s+s+s+s+s+s+A s+s+A s+s+s+s+s+s+s+s+= s+= s+a.a.a.E.% + /.t t v+v+V v+V V @+V V m m J m J J J J U J J k U k k k J J J U _ U '.'.'.j j w.[ [ w.j.j.L L L l L v o./+m.w B )+B.k+C+A+A+++2.)+a+'+a+4+.+^.@.@.a+a+a+.+R.)+@.4+4+4+^.^.^.^.R.a+4+R.R.q.R.` a+'+'+'+'+'+* '+H * h+h+* h+H h+h+h+h+h+* s.'+'+'+'+'+'+'+'+s.h+L.g C.C.C.J k 9+- X X X w w E+w s.s.X X X X - - C.k J J k J Y.Y.- - 9+L.X X X X R X R X k k k k ,+J U J J ,+J U J k k k - k - k - - - Y.- k - k k J J J U ,.U J J J k - - - X - - - k - J - J V J m U m J V Y.J V m m U P P P U P U U U U J J - J - V - - - u+- - u+V - V u+V V v+V v+v+v+@+@+@+$ , , $ , , , , , , 6./ m m P P U P j j j P P j j P P U P j e+0 [ [ [ j '.C.[+9+R *.1+'.Q.w.O O |+S S : ~+~+~+0+0+0+~+S S S > > > 6+C T 2 5 1 c+G+G+3.E+s.M.M.- - J J m U u+` 4 ..a.= E E z >.u.*+F f.2.` '+` a+4+4+! i..+a+b #+R R [+/+$.Q.& w.I.I.Q.9+R z+z.a e.& w.O |+S K.: K.", "F.l L v O & _ T $.$.C & w.6+O L l l.] ] ] l. .].|+O w.w.w.O 6+O O O w.w.O L l K.l ].L 0 '.p.4+q.C+J.;+o+u.>.N a.N a.N N = = N = = = s+s+s+s+s+s+s+s+A s+A s+A A A A A A A A A A A s+s+s+s+s+s+s+s+s+s+a.a.E.% % + t $ v+V @+V @+V 6.6.m V V 6.m m m J U J U J J - J J k k k k J k U k _ _ '.'.j j 0 [ w.j.j.x+j.j.j.[ j k w }+i.Z C+++A+J.J.7.r+2.q.a+a+^.R.^.^.4+a+B a+R.^..+^.S.R.a+a+^.^.q.4+R.'+'+` '+'+'+'+'+* h+h+h+h+g h+L.h+L.L.g L.L.g L.L.h+L.h+* M.a+3.M.'+s.s.'+H L.L.g C.C.C.9+k k R R b X w X s.s.w s.s.L.X L.k - Y.k C.k k k k k k X X X X X X X X X R X X k k J k k J J J k k k - k - k - k - - - - - k - k k k J U U U U U J J J - k k - - k - - J - - J J J J J J J m U m m 7+w+7+F+P F+F+P P P j U U U U J J J - - - - - u+V - u+V u+- u+u+- V V 6.6.$ , , , , , , , $ , , , 6.6.m d.d.P F+j [ 0 [ 0 0 j j j j j j P j e+[ o.[ y+0 0 '.'. +'.'.Q.w.O |+]. .[.[.[.|.k.k.k.0+k.0+0+0+0+0+0+S > > 6+& T 2 1 G+G+! G+3.M.s.- g - J m U m g ` + Y >.= x.x.E N u.:+;+7.8+q.8+R.R.^.! B.i.B.i.S.}+s.b X *._ +Q.I.I.I.t.m.H.P.P.b a T +.w.> |+S S : ", "l L L O 0 $._ _ T '.& & w.w.O L L m+] ] @ m+l L x+w.C & w.w.w.C w.w.w.w.j.|+l l L j.0 ,+#+4+)+++J.*+p+p+>.p+p+p+....:+:+p+p+a.a.a.a.a.N a.= = = = s+s+s+s+s+s+A A A A A A A A A A A s+s+s+s+s+s+s+s+= = a.E.% + /.$ $ 6.6.6.6.@+6.6.6.6.m m 6.J m J m J J U k U k - k - k k k k k k k k U k _ _ _ '.j j j j w.j 0 0 '.,+#+3..+#.C+++A+J.J.J.7.r+2.R.a+a+^.! ^.q.R.R.a+@.a+R.R.R.4+a+R.a+R.'+R.'+'+` '+* * h+h+h+H g L.Y.Y.,.C.L.Y.g C.C.L.Y.Y.L.g - h+s.s.M.3.3.a+3.a+}+'+M.'+s.L.L.C.J J ,+[+k R R X X w w X s.X X X #+X X - R - - k - k - - - - - R - X X X X X X b X X X X k - X k X k k k k - k - k - k - J - - - - k k J k J J J 7+m U U J U J - k - X - X - - J - V - J m U U m m P 7+P F+F+F+F+F+d+F+d+[ P P j j U U U J J J V J - J - - V - V V V m V V V V 6.6.6., , , , , , , , , , , / 6./ m P P [ j [ w.0 [ w.0 0 0 0 j 0 [ [ 0 0 o.0 j.0 o.0 0 0 I.w.w.D.L K.: [.T.q D+0.0.t+t+D+D+D+&+k.0+0+0+0+S S > <.& a 5 c+]+o ]+S.3.M.- g - J U P m V ` /.b.p+= E ~.E N p+:+Y :.4 8+q.8+q.o B.r+r+#.B.]+! H+E+w n+y.$. +Q.Q.I.t.#+B X.c+1 P.a e.+.O > ].S S ", "L L L w.w.$.'.'.& w.w.w.w.O j.L l l.@ @ F. .].|+w.w.$.& T w.C w.& w.w.w.j.3 L D.[ /+9+N.q.C+J.G.u.>.N N a...Y b.Y Y Y *+Y *+..:+:+p+..p+a.a.a.N a.a.N = s+s+s+s+A A A A A A A A s+A A ~.s+A ~.~.~.s+= = a...% + t u+6.6.6.6.6.6.@+6.@+6.V 6.6.V V m J J J J k J k J J k J - - k - k k k - k k k U k k _ '.'.j j '.U k X }+S.o B.++J.J.J.J.:.7.i 2.)+R.R.R.! ^.^.a+a+a+a+S.a+a+a+a+a+a+a+'+* * * '+* h+* L.Y.Y.Y.Y.g Y.C.C.Y.Y.C.9+C.L.- Y.L.L.X L.- h+s.f M.3.a+3.a+3.a+a+'+M.s.s.L.- J C.J C.k k X z.X X X X E+X s.s.s.X L.X - - k X k - R k R X k X - X X X X X X X X X X X X - X X - - - - - - X X X - - - h+X - X X - - k k k J J J U J J J J J - - k - - - - g J - J J Y.J m U U P m P P F+F+d+d+).d+d+d+d+d+[ F+F+j j U J U k J J J - V - J V J J J m J m J V m m 6.6., , , , , , , , , / / m d.P P e+[ [ 0 o.o.o.0 w.o.o.[ 0 y+0 [ [ o.[ y+o.o.o.o.o.w.w.O x+|+S K.: T.Q 0.0.. t+. . 0.. t+. t+D+D+&+T.0+~+> > 6+& *.H+6 Z ! a+}+s.- C.w+U 7+P 7+Y.` /.;+E.= x.x.x.N u...b.:./.8+f.q.8+2.o i _.C+#.B.i..+S.E+b R *.$.& Q.Q.t.#+H+X.i.c+1 2 *.$.I.O |+K.K.", "].L L w.w.j w.w.w.w.w.w.w.w.j.L K F.l.m+{.l L x+w.'.$.& w.& w.C & w.& Q.j.j.j.0 ,+- a+)+i G.:+u.N E = p+..:.b.:.b.:.b.:.;+;+;+b.;+*+Y Y ......p+p+a.a.a.= = s+s+A A A A A A A A s+s+s+s+s+s+~.x.s+s+>.a.E.% F f.t V d.m / 6.6.6.6.6.6.@+6.6.V 6.6.V m V J U J J k k k - k k - k - - - - X X k X k k - k k k k k k k X s.a+! #.i ++J.3+J.3+7.4 i 8+)+^.^.^.R.R.R.R.a+R.a+R.a+a+a+a+a+a+a+'+h+'+H H * H h+L.L.L.C.Y.Y.Y.Y.C.,.Y.Y.C.L.Y.L.L.- h+s.M.s.M.M.f '+a+a+a+! R.R.R.a+M.M.M.L.L.C.k k k k k X R w X f X s.X X X X s.- X X X - X X - X X X X - X - X X X X X X X X X X s.X X X X X s.X X X s.X - X s.X X - s.h+s.s.X s.X X X k - J J J J J - - - - - - - - - - - J J J J J J m P P P F+d+d+).$+).$+d+v d+d+d+d+F+F+[ P P U U U U J U J J J J J J m m m m m m m m / m / / 6., , , , / / m m d.d.m P e+[ o.o.y+o.w.o.o.o.o.o.o.o.o.o.y+o.o.o.j.D.j.j.O j.O j.D.|+]. .[.7 D+0.t+. . . . . . . . . . t+t+t+D+T.0+S S > 6+$.X G+]+]+}+E+s.- C.,.7+P F+P J * 8+F Y N = E E N f+Y ;+4 /.f.` 8+8+2.r+i A+++r+B.B.! .+f b z+*.$.Q.I.Q.t.L..+6 i.6 X.P.2 e.+.w.D.S S ", "l L L L j.w.j.j.j.O w.j.j.D.L L F.m+F.F.l l v w.& $.'.$.'.Q.& w.w.Q.& _ j 0 '.L.'+^.B.J.G.:+>.N = = ....:.:.4 4 :.:.:.:.4 :.:.:.:.:.;+;+;+b.Y Y ....p+a.N = s+s+s+A A A s+s+s+s+= s+= = s+s+s+= = >.N p+..F /.t V m P d./ / / m 6.6.6.6.v+6.6.V 6.J V J V J J U U k J J k - - z.- z.- X X z.X X 5 X X 5 X X X X X w s.f R.! r+i 7.3+J.J.3+4 r+8+^.8+R.! R.! R.3.a+a+S.a+3.M.f f 3.3.a+3.M.'+}+M.'+'+'+s.s.L.H s.L.L.Y.Y.Y.- Y.- L.- Y.X h+s.s.s.s.M.s.M.3.3.3.! ! S.! ! ! R.a+f s.M.X - k k k X k X X X w X f X s.s.E+E+X s.s.s.X X s.X X X X X X X X X X X s.X s.s.s.E+X w X f s.s.M.s.f E+s.f E+s.s.M.X * M.M.s.f s.s.M.s.s.s.w X X X k - - - - - - X X X X X X - - - J - J J J U m 7+P P F+d+$+d+).$+v ).d+d+d+v d+d+[ [ F+j j j U U U k J J J J m U U m m U d.m d.m m / / / d./ d./ / / / m P P F+[ [ [ 0 j.o.o.o.o.o.w.o.w.o.o.o.y+o.o.o.y+O j.x+x+<+x+D.x+|+].K.: [.|.q . . . . . . . . . . . . . t+t+t+D+T.0+0+> > C M }+.+@.}+s.#+9+C.w+7+P d+F+,.* R.r+b.E.N E E z u.*+:.4 f.` ` ` q.r+#.i ++7._.r+2.o ! H+E+X a 1+& Q.I.$.N.4+k+k+6 6 1 b a & <.O |+K.", " .l L L l L ].].L L x+L L L l l .m+m+l l L j.j _ _ $.$.j w.Q.& w.$._ C.,.9+H 4+)+++J.o+>.N E N N a...+ :./.4 2.2.4 r+/.2.q.2.C+4 4 :.:.:.;+;+b.....p+a.a.= s+s+s+~.s+s+s+s+s+= N = = N = = = = N u.E...F /.t m O.F+O.O.d.d./ 6.6.6.6.6.6.6.6.6.6.6.V m V J J V k J U k k k J - - - z.X - f X f f X f f f 5 f E+f E+3.3.R.! o i 7.7.F 4 i r+2.8+! R.R.! R.R.R.3.3.S.S.3.S.a+3.a+a+3.}+a+f a+}+S.3.f a+a+a+E+'+M.s.h+X h+h+- h+X - #+s.X M.s.M.M.M.f f M.a+S.! ! o ! o ! R.8+R.R.M.M.s.X - X X X X X b b X X f X f s.s.f s.s.f f f w f f f w E+X X E+X s.s.X X X f X s.X f f X f s.f f s.M.f f M.f f s.M.s.s.s.s.s.f f M.f M.s.s.s.X X s.- X X X X X M.X M.M.X M.X - - - J J J J J U U P P F+d+d+).$+).$+d+v v d+d+d+d+d+d+[ [ j j j U U '.U _ U U U U m P P P P P d.F+d.d.d.P / d./ d.m d.P d.P O.F+F+d+j.j.o.j.j.O O o.o.o.o.s O o.O D.o.O y+j.D.D.<+x+L L x+].].K. .[.7 D+0.. . . . . . . . . . . . . . t+t+t+0+0+0+S > w.e.E+G+@.B w L.C.,+w+7+e+d+d+7+h+R.o 3+*+u.>.>.a.:+Y 7./.q.` ` q.R.2.B.i ++i ++r+2.)+! H+P.R y._ t.Q.Q.t.n+4+k+k+k+6 1 P.M $.w.O |+K.", "l. .m+ .F.m+F.F.K.].l ].l l .m+F.m+F. .L j.w.k - X k _ 0 j w.0 $.y.s.H H 4+^.C+J.*+u.N E = N N p+Y b.:.4 C+r+f.2.2.C+q.q.q.q.q.q.q.2.4 :.:.b.b.b.....p+>.>.= = s+s+A s+s+s+a.= a.a.N = N N N u.p+:+Y :.f.* m F+v d+d+F+F+d.d.d./ 6.6.6.6.@+@+6.6.6.V V V V J J J J J J J k - k - - - - X X f X f f X f f f f f f 3.3.3.! ! o o o i r+r+o 8+! R.R.! R.! ! S.S.R.R.S.S.a+S.S.S.S.@.@.S.H+@.H+G+S.@.3.S.3.S.a+f M.s.s.M.s.s.M.X * s.M.s.M.M.f f f 3.3.a+3.3.R.3.! ! o 2.o o ! ! R.3.3.M.s.s.X w X X X s.E+E+s.X f s.s.M.s.E+f f s.f f f f f f f f M.f X f s.f s.s.X f s.s.X f f f f s.s.f f s.s.f s.f f f M.M.M.M.3.M.M.f M.s.M.s.f M.f s.s.M.X X M.f X f X M.f f M.X h+X - - J U U U ,.P P [ [ v d+v d+).d+d+d+[ d+[ d+[ d+d+F+[ F+j j j U U U j j j P P P P P F+F+F+P F+F+O.d.F+d.P d.F+d.F+F+F+[ j.j.j.j.<+x+x+D.<+D.O O O O D.s D.O y+D.<+O D.D.x+x+].].K. .l . .l.|.7 Q . . . . . . . . . . . . . . . t+t+t+t+0+0+S > w._ E+.+i.a+H.#+9+w+l+P e+v v e+C.a+)+#.n *+f+:+*+Y :.4 q.q.* t '+R.^.2.r+7.i r+B.#.i.)+@.E+b y. +& Q.Q. +N.B k+8.8.6 1 P.z+5++.O |+S ", "|.] l.[.] [.[.l.[. .l. .l.l.l.l.l. .F.l L j k @.! 3.- k '.j 0 j _ H R.'+^.C+J.G.f+z E s+s+= a.p+..;+;+:.:.4 2.q.q.C+2.q.q.h+H * B q.q.2.4 :.:.b.Y :+..p+a.N = s+x.s+s+= N a.N a.= N >.>.>.a.p+E...Y :.q.u+7+v $+$+$+).d+).O.d.d./ / 6.6.6.6.V @+@+6.V 6.V V V J J J J J J k J k - - X X X X f 5 f f f 5 f f f 3.@.@.S.3.! ! o 8+o o o 8+! o ! ! ! ! ! R.! ! G+S.! ! S.G+G+S.G+3.H+H+@.H+@.@.S.S.S.S.S.a+S.S.a+3.3.f M.M.s.M.s.s.s.f f E+M.3.M.3.3.a+3.R.S.! R.! o o o o o o ! 8+3.S.3.f 3.f f f f E+f X f s.s.f f f f M.M.f 3.f 3.f 3.3.3.f 3.f 3.3.f M.X f X X X f X M.s.s.s.f f f f M.f f f f f M.f f f 3.3.M.3.3.f f 3.f 3.f M.M.f f f f f f f f f f f f f f f f M.X - - k J U U U j P [ F+[ d+d+v v d+d+d+d+[ d+[ d+[ [ F+[ F+P j [ j j j j j j [ P d+F+d+F+d+F+d+).F+F+F+F+O.F+F+F+F+d+d+v v v v L L L |+L |+x+|+2+x+x+D.D.D.<+x+D.O y+D.<+x+x+].].]. . . .m+[.] B+d Q . . . . . . . . . . . . . . . . t+t+&+T.0+S |+w._ f ! i.2.4+s.L.,.l+l+[ d+d+[ J '+]+Z A+n 5.o+b+7.i 8+'+* g h+* ` R.2.B.C+_.r+2.2.i.! @.E+b R *.Q.& Q.t.#+B k+k+k+6 (.1 2 e.+.O |+K.", "} 7 d B+d 7 7 } 7 7 |.} [.] l.[.l.l. .L 0 _ f i F o 3.- J j /+9+H R.q.2.C+J.o+>.N x.x.= = p+p+:+*+*+;+:.:.7.4 2.2.C+2.q.* g H H * B q.f.C+:.b.Y ....p+p+a.>.= x.s+s+= = = a.N = N >.u.u.u.p+p+..;+4 ` V [ $+3 $+p $+$+$+d+).O.d.d./ 6.6.6.6.V @+@+@+v+V V 6.V V V J J J J U J k U k - - X - X X 5 f 5 3.f H+3.3.3.S.S.! 3.S.! ! ! ! o o 2.! ! ! ! R.! ! ! R.! ! S.S.! S.G+G+@.@.3.3.3.3.f H+H+H+@.@.S.! ! ! ! ! R.3.f 3.M.M.3.3.3.M.f 3.3.3.3.3.3.R.R.3.! R.! ! o o o o o o o ! ! ! R.S.S.f f 3.f f f f s.f f s.f f f 3.f 3.3.@.3.S.3.3.G+3.S.3.3.3.3.3.3.f f f M.f f X f f f f f f f f f M.f 3.f f 3.3.f f M.3.f 3.3.3.3.3.3.f f 3.f f M.f 3.3.f 3.3.f 3.f 3.f 3.f f f s.X - k J ,.U j j P [ F+d+d+d+d+d+v d+[ d+[ [ d+d+[ [ [ [ d+[ P j j j j j [ j [ [ [ d+d+v v d+).v ).$+).).d+).d+d+v v v $+3 3 L l ].].K.].K.].|+U.U.|+|+x+|+U.x+x+x+<+U.x+U.].].K. . .l.[.|.7 d 0.. . . . . . . . . . . . . . . . . t+t+t+&+0+~+].w.,+E+)+C+#.^.a+H C.,.l+[ j.j.[ +#+@.o G C+;+n J.i 2.R.'+g Y.g '+'+a+^.o r+B.B.o 2.! )+S.E+R a e. +Q.Q. +N..+k+8.8.6 X.P.z+e.& O x+S ", "7 7 d q 0.0.Q Q q q Q q q q } d } ] m+<+'.w G D E.F 8+'+Y.,.C.* a+2.C+J.G.f+z E x.x.s+N a.p+:+:+..;+;+J.:.7.C+C+C+4 2.q.B H H '+q.q.q.7.:.;+*+:+:+p+p+p+N = = x.= = N a.a.a.a.>.a.p+u.u.p+:+b.:./.* 7+d+3 3 3 3 $+$+$+).).F+).F+d.P / 6.6.6.6.6.v+6.v+6.V V V V V 6.V J J J J J - J - - X - X X X M.f f f E+f f 3.S.3.S.! 3.! ! R.! ! ! o R.! R.! ! ! R.! S.S.S.! @.! S.! @.@.@.H+H+5 f f H+H+f 1 @.S.! o ! ! ! ! ! 3.3.3.3.3.3.3.3.3.3.3.a+a+R.S.3.! S.! ! o o o r+#.o #.o o o ! ! ! 3.S.S.3.3.3.f f f f f f f f f f 3.3.@.3.G+G+G+! S.! ! ! ! 3.! 3.3.f 3.M.f s.f M.f f X f f X f f M.f f M.f f f 3.3.3.f 3.M.M.3.3.3.3.3.3.3.3.3.3.3.3.3.3.3.3.! 3.3.]+3.S.3.3.f f f f X X X k J J U U j j j [ [ [ [ d+[ j.d+[ [ [ d+[ d+[ [ [ [ j [ j P [ j [ [ [ [ d+d+v $+d+v $+$+$+d+$+$+$+v $+v v $+3 3 l ]. . . . . .m+ .g+K.K.K.K.r.x ].].K.].].].].].].].].]. . .: l.] ] d q Q . . . . . . . . . . . . . . . . . . t+D+D+: : |+w.J M.^.r+i C+^.a+L.C.w+F+d+j.0 $.R P.G+6 6 B.A+A+B.q.a+* Y.,.C.g '+'+R.)+o 2.2.)+2.^.^.S.P.b R 1+$.5+t./+N.B C+++8.k+6 ^ z+e.& 6+D.S ", "] 7 d 0.. . . . . . 0.. 0.0.Q q d l.l [ [+.+++9 u.*+4 R.* g * 4+2.7.;+o+u.N s+x.= = a.p+:+:+:+:+*+;+:.J.7.:.7.7.7.4 q.q.'+H B B q.C+7.J.*+*+:+p+a.>.N = = = s+= = a.a.N N N N >.u.>.u.:+:+b.:.f.h+O.v 3 3 p 3 $+p 3 ' $+v ).).F+F+d.d.m / 6.6.6.6.v+@+v+@+v+V 6.V m J 6.J J J J U J J J - - - X X - X X X f E+f f f f 3.3.S.3.3.! R.! R.! ! R.! R.R.3.S.3.@.@.S.@.G+@.G+@.@.@.3.H+f E+E+E+5 P.H+@.S.! ]+B.B.o o o R.3.R.3.S.S.3.S.S.S.S.3.S.R.S.S.S.3.R.! R.! ]+o G o _.#.#.#.o o ! ! ! ! 3.3.3.3.S.f 3.3.f s.f f f f f @.3.! 3.! ! ! ]+! ! ! ! ! ! ! 3.3.3.f f f f f f f f f f f X f f s.X f f M.f f f M.3.f 3.3.M.3.3.3.3.3.3.3.3.3.3.f ! 3.3.3.3.! ! 1 3.]+S.@.3.3.H+f f f X X X k k U U U j j j j [ [ [ d+[ [ d+d+[ d+[ d+d+[ [ [ j [ [ j [ j [ [ d+[ d+d+d+v v ).$+$+$+$+$+$+$+$+$+3 3 l l .m+l.l.[.[.|.[.[.: [.: : : . .: K.r.K.r.K.].l l r.]. .l . .m+l.7 d d 0.. . . . . . . . . . . . . . . . . . . 0.B+|.: L 0 R }+^.2.r+B.q.R.* g w+e+[ j.[ _ R b 1 ]+6 G+! 2.2.a+* L.Y.,.,.- h+'+a+^.2.2.^.2.! ^.@.a+}+z+y.*. +Q.Q.[+N.X.k+++W k+6 X.2 a +.o.> |+", " .l.[.q . . . . . . . . . . 0.0.q ] <+Q.b Z D -+= :+:.f.q.` q.i J.G.f+>.E E s+= a.a.:+:+:+:+p+:+;+:.7.:.J.J.J.J.:.r+q.q.q.B q.q.C+4 J.*+p+p+>.= = = = E s+x.= = a.N a.N a.>.N >.p+p+f+:+b.:.` V e+v 3 3 $+$+3 $+$+$+$+$+$+d+d+).F+F+d.m m m 6.V 6.@+V v+V v+V 6.V 6.V 6.V m m m J J J J - J V - - - - X h+- s.X f f 3.f 3.3.3.f 3.3.3.3.3.S.3.3.3.3.3.3.3.@.H+f H+@.3.1 3.5 f E+E+f b b X E+E+E+H+G+! ]+#._.#.o o o S.! 3.3.S.S.! ! R.! ! 3.R.3.S.S.@.3.! ! ! ! o #.#.o #.o o #.o ! ! R.R.! 3.3.3.3.3.f 3.3.f f f f 3.1 f 3.3.3.]+! o o o o ]+o ! 3.! 3.3.3.3.3.f f f f f f f f f f X f f s.M.X f M.X f f M.f f 3.f M.f 3.3.3.f 3.3.3.3.3.3.! ! ! G+3.3.]+3.G+3.G+@.@.3.1 f f E+X X - - k ,+J U U U j U j j [ [ w.d+d+[ j.[ [ F+[ [ F+j P [ j [ [ [ [ [ j.d+d+d+d+v $+v $+$+$+$+$+p p p l K F.F.: l.[.} 7 k.B+B+B+|.k.|.[.|.k.[.[.[.: : : .: . . .].l ].l K. .m+l.} d q 0.. . . . . . . . . . . . . . . . . 0.0.D+] .L [ X 3.^.q.f.2.2.R.'+g ,.P [ [ 0 _ z.z.5 1 G+G+P.E+M.s.g C.J J ,.Y.h+a+a+R.^.2.R.R.R.R.@.H.E+w z.*. +$.t.[+N.^.k+++8.6 6 (.!+a & +.|+|+", "j.L l ] q . . . . . . . . . . 0.Q : j.[+b k+9 { E >.*+:.f.2.:.*+:+N E E s+s+= a.p+:+:+:+:+p+..b.:.:.7.J.J.J.;+:.4 4 q.q.q.q.q.4 7.;+:+p+>.= E x.x.x.x.~.s+= = = N N = N N >.p+>.u.p+..;+4 ` ,.d+v 3 j.v L $+v v v $+v $+).v d+F+[ F+d.P d./ 6.6.6.6.v+6.v+v+v+v+v+V V m 6.m V V m m m m m J V J V J V - - X X s.X s.s.s.M.f f f f 3.f 3.3.f 3.f f 3.E+E+E+E+E+H+f 5 E+f E+E+f E+E+z.X z.X b X 5 H+@.]+i.o #.r+#.o ! R.3.3.S.S.3.3.3.S.3.3.S.3.R.3.3.3.3.3.3.! ! ]+G o _.#.G #.o o o R.3.3.3.3.3.3.3.3.3.3.f f f f f f f 3.3.! 3.! ]+]+o ]+o o o ! o o ! ! G+3.3.3.f f f f f E+f X f f f X f X M.X X M.s.X s.s.s.s.M.f M.f f f @.f 3.3.3.3.3.3.3.G+3.! G+3.]+3.3.3.3.@.3.@.H+f f E+f X k X k k k _ U U '.j j j j [ [ [ [ [ d+[ [ F+[ [ P [ j [ j [ [ [ [ [ [ j.d+v d+d+v $+$+$+3 p 3 3 3 K l l.l.l.7 d B+q Q Q D+Q 0.Q B+D+&+k.7 k.k.7 [.[.[.: : .l ].].L L ].K. . .@ ] d q Q 0.. . . . . . . . . . . . . . . 0.q 7 [.m+L j #+a+R.^.2.q.R.q.* g ,.7+[ [ j _ z.b P.P.1 G+1 w R J ,.,.,.w+k C.h+M.a+! R.! ^.R.a+R.a+}+b z+n+y. +Q.t.[+N.)+C+8.8.k+6 c+^ a & <.D.> ", "t.j y+l ] Q . . . . . . . . . . B+ .y+[+1 8.&.A s+a.Y :.:.;+*+>.E x.A ~.s+N p+....*+:+:+:+:+Y b.:.C+7.:.:.;+:.4 2.2.f.q.q.2.7.:.G.:+>.N E x.x.~.A A ~.s+s+= N = a.= N N >.>.>.>.p+:+;+/.'+,.e+v v v v v v j.v v j.d+d+v d+v d+d+F+[ F+d.P U / 6.V 6.v+v+v+u+v+v+v+V 6.6.6.m m m m m m m J m m m J J m J V - J g - X h+s.s.s.s.s.s.M.E+s.E+E+E+E+w E+E+w E+E+E+E+E+E+E+E+E+X X z.- R R y._ z.R E+E+S..+]+o 2.o #.o o R.R.3.3.S.S.S.3.S.S.3.S.3.3.3.3.3.3.S.3.R.! ! ]+o G o o o ]+! ! 3.3.3.3.3.3.3.f f f f f f f f f f f f f ! 3.]+o ]+o G G ]+o ! ! 3.! 3.3.3.@.3.3.3.@.f 3.f f f E+X f X X X X X X X X X - X X X X X s.M.f f f f 1 3.S.3.3.3.3.]+3.G+3.f G+3.G+3.3.1 3.3.f f f f E+f X X R k - k k k k k '.j j j j [ [ [ j [ j j j j j j j F+j F+[ [ [ [ d+[ d+v j.d+v v $+$+$+3 3 3 l {.F. .[.7 B+q Q t+t+. t+t+t+0.0.0.0.t+0.D+q D+d B+7 [.[.: .U.L x+<+<+L ].l l m+] ] d d d Q 0.. . . . . . . . . 0.0.Q q d } l.{.3 j h+4+2.! 2.8+a+` * u+,.m P P _ _ z.5 1 1 c+G+@.E+X J U U m ,.C.k L.M.a+a+^.R.^.! )+a+H+}+w R y.[+[+Q.t.p.B )+++b+8.k+; X.^ a T }.O S ", "4+w w+j. .B+0.. . . . . . . . . d l y+m.i.o+E ~.= a.Y b.*+u.E { A 8 A s+N a...*+Y :+..p+:+..;+;+:.7.7.J.:.:.:.4 :.4 q.C+2.:.:.G.:+>.= E x.x.{ A A A ~.s+= = = = = = = >.z >.u.p+:+;+f.* w+[ j.j.j.j.j.[ j.d+[ d+[ [ d+[ d+[ d+[ [ P P F+m m m m 6.V V V v+v+u+v+v+v+v+V V V 6.m V m m V m J m m m m 6.m J V J g g - - h+h+L.X L.X X #+X X w X #+#+X X R R R z.b b E+E+b b z.R R _ _ _ $._ $.R b E+H+! )+)+o 2.o o o ! 3.3.3.3.3.@.S.S.G+3.3.f 3.M.E+s.E+f 3.3.! ! o G ]+#.G ]+! ! R.3.3.M.M.3.M.f 3.f f f X M.X f f X f f 3.3.! o ]+]+o o G o o o ! ! 3.! 3.S.3.3.3.3.@.@.f f f f 5 f X X X X g - - - - - - - - X X s.X f X f f f f 3.f 3.1 3.3.f 3.f 3.3.3.3.f 3.3.3.3.1 3.E+f f f X E+X X X z.X k k _ k k k _ j j j j j [ P j j j j P j j j [ [ [ [ [ [ [ [ [ [ d+v v v v v 3 $+3 K l l m+l.] |.d q Q Q 0.t+0.t+. t+t+. . t+t+. 0.0.0.Q Q q 7 : l L O j.o.o.j.j.L l l {.m+@ ] } d d d q Q 0.Q Q q q d q d d d } ] l.{.3 [ g R.2.B.2.q.` '+* L.V ,.m U _ z.5 5 1 G+G+1 @.H+w k w+7+J C.X #+w E+a+a+S.a+R.R.^..+a+H.b n+*.y. + +Q.p.N.C+C+b+8.8.6 c+P.2 T +.O > ", "++B.H e+L l.q . . . . . . . . 0.7 U.e+#+C+:+= = a.p+..:+>.E ~.8 8 A A = a...Y *+*+:+:+p+....Y ;+;+;+:.7.7.7.7.:.7.4 C+4 7.J.*+:+>.N E s+x.~.~.~.~.s+s+= = = = = = = N N >.>.p+*+:.2.h+7+0 [ o.[ [ [ 0 [ 0 [ w.[ [ [ [ [ [ [ P [ P P j P j U U m V V V u+u+u+u+A.A.v+v+V V 6.V m m V m m m m m m m m m 6.m m V V V g - g g g X - 9+- m.R 9+R R m.9+R R R R R n+z.z.z.z.R X R R R y._ $.'.'. +_ X b H.B G+)+)+2.2.)+^.3.3.M.E+f f 3.f f f f f E+s.s.s.s.X f f }+S.S.! ]+]+]+o ! R.3.3.s.s.s.s.M.s.X X X M.X f f - X X X M.f f 3.3.]+o ]+G o ]+]+]+! R.! 3.3.3.3.f f f @.f f 3.f 5 M.X f f X X X - - - k - k k - - - - X - f X f X f 5 f f f f f 3.f 1 3.f 1 f 3.f f 5 f f f f f X f f X E+f X X X X z.X k z.k k k _ U U j j U j j j j j j j j j P j F+[ j [ [ [ [ [ [ [ j.v v $+3 3 3 K l m+: l.] 7 7 B+D+D+&+D+D+D+D+D+t+D+0.0.t+. . t+t+. . 0.B+l.r.j.o.Q.'.Q.Q.0 y+j.L L l {.m+l.l.] } } d d } d ] ] ] ] ] l.] ] @ m+K $+d+Y.R.2.C+r+2.8+'+* * Y.Y.V k J X E+f c+]+c+G+3.f M.- J ,.V h+s.M.3.a+! )+S.a+'+a+R.a+S.E+#+R *.1+$.Q.t.p.N.q.8.8.8.k+6 X.^ 2 e.+.O O ", ":+;+2.Y.y+ .7 . . . . . . . . 0.} l 0 H r+*+a.a.p+..p+N x.A 8 8 A A s+= p+..*+b.*+....:+:+..*+*+;+;+:.:.7.:.J.:.:.J.:.;+*+*+:+>.N = = x.~.~.A s+~.s+= = s+s+s+E E N N >.>.p+*+;+q.h+/+0 o.0 [ 0 0 j 0 Q.j j j j 0 j j [ j [ j j [ j j j P m U J J J V - u+M.t t t A.u+u+u+V V V V m V V 6.m 6.6./ 6.6.m 6.V m - V g g h+- - g - 9+k R 9+R [+y.[+y.y.y.m.R n+M n+R R n+z.M R y.y.[+_ _ $.t. +m.z+#+E+@..+X.)+i.)+! a+3.s.w f s.f E+f f f E+X s.w X X X s.w s.E+3.S.@.]+S.! S.R.3.M.M.h+X X X X - M.X M.- X - - M.- - - - - f 3.3.3.3.! o ]+]+]+o 3.3.3.3.3.f f f f f f 1 f f f f f f X z.f X - - - k J k J J J k - k X X X f X f X f X f f f f f f f f f f f f f 3.f f f f f f f X X f X X f f 5 X X z.X k k k k k U _ U U j _ U U U U U U j j P j j j [ P [ j j 0 [ [ d+j.j.v $+3 p l F.m+l.[.] 7 k.B+k.k.T.0+k.k.k.T.k.T.T.T.D+D+D+. t+. . . q l.].y+o.t. +,+/+U '.0 [ j.L L l {.F.l.l.l.] @ ] @ @ l.m+F.F.m+{.F.{.{.p $+d+,.* 8+4 i i q.8+* u+V g L.* M.f G+]+o G ]+G+H+f s.g V Y.g * a+a+S.i.)+i.i.R.'+a+'+a+a+H.R m.y.[+t. +t.[+4+2.++c.8.8.6 1 5 a e.+.6+> ", "u.:+i '+e+3 ] 0.. . . . . . . Q ] l e+'+f.;+Y ..:+>.E ~.A A A A A s+= a.p+p+..:+*+..:+:+:+:+:+*+b.*+;+J.;+J.;+;+;+*+*+:+:+>.N E x.x.s+x.A ~.~.s+s+x.x.s+x.= = = = z >.u.p+*+:.q.Y./+j '.Q.'.'.j j j '.'.'.'.'.'.'.'.j j U j j j j '.U j j U U U m J V - u+M.t 8+t t M.A.u+v+V u+V V J V V V m V V m 6.V V g v+g u+g g g - - C.C.,+,+*._ [+[+[+k ,+y.[+[+*.R y.y.y.y.y.y.M y.*.y. + + +t. + +y.z+w H.H+.+.+)+^.^.a+}+s.w #+w b f b E+5 E+f b X X X X - X #+X w f f }+S.S.S.3.f M.s.- - - - - - - - - - - - - - - - - - - - M.f 3.]+]+]+]+]+]+3.]+3.3.f s.X s.X f f f f f f f f f 5 f X X X X - k - J k k _ k J k - X X X E+X X f X f X M.M.f f M.f f f f f f f f M.M.X f X f f f f X f f X X f f f X f X z.X k k k U k k J J _ k J k k U J U U j j j j j j j j j 0 [ [ j.j.v 3 3 3 K l {.m+l.[.[.B+k.k.k.0+0+~+0+0+~+~+0+~+~+~+0+T.T.D+0.t+. . Q l.].o.Q._ y.z.9+,+/+U j [ j.j.L l 3 {.{.F.{.F.{.{.K l l ].].].l K l 3 p v d+m u+R./.4 4 f.8+` * u+u+* R.R.o #._.A+8._.o @.M.h+g g V h+* a+q.! B.#.#.6 )+R.R.R.a+a+H.#+R [+*.t.$. +p.B C+J.b+c.8.6 (.!+2 e.+.6+> ", "N :+:.H e+3 ] 0.. . . . . . 0.q l.3 7+* f.:.Y :+>.x.A A A ~.s+s+= = = N p+:+:+:+:+:+:+p+>.p+:+:+:+*+*+*+b.;+;+*+*+:+p+>.N N = = x.~.~.~.~.s+s+s+s+s+x.x.s+x.E N >.N u.:+G.i R.Y.'.'.$.$.'.'.'.'._ U '._ _ U '.U _ './+j '.'.j _ '.'.'._ j j '.U U J U u+M.3.` ! 8+8+t M.u+u+u+g u+g V g V V g V V V v+V g u+u+u+* M.g h+g Y.- k ,+,+[+ +[+[+[+[+[+[+[+*.*.[+*.y.[+[+[+y.*.*.*. +*. + +$. +y.y.#+w H.B a+.+@.B }+}+H #+X R z.X R E+X E+X X w X X 9+- 9+9+9+L.#+#+s.E+}+}+}+}+s.X - g J J J - J - J - J V - V J J J V J V - - X f f G+3.G+]+G+G+f 3.s.X X - X - - X X X - f f X X X X f X X X - - k k U _ J _ k k z.X 5 X 5 f X f f X X X - X X X f X M.f X f X f - X M.X M.X X - X X X X f f X f X 5 X X X z.- z.- k k U k k k k k k k k k k U U j j j j j j j j j 0 w.[ d+j.v $+3 K K m+l.l.7 7 |.|.[.0+0+S S S > S > S S : S ~+0+0+T.D+D+. 0.q l.].o.t.[+z+n+z+R k U '.'.[ w.d+j.L 3 3 K K K K 3 3 L L v L v O 3 v $+d+F+P U g '+8+4 i r+8+` t u+* ` 8+i 7.F n 5.*+n ++o a+M.- g g h+` 2.! B.#.C+++r+i.! S.S..+H+}+E+R y.[+ +t.t.p.B C+++b+b+j+k+c+1 a T +.O 6+", "a.b.f.H e+{.] Q . . . . 0.Q d ] K e+p.4+4 *+p+E x.A A ~.= = a.N N N N a.p+p+:+..:+p+u.N N N p+p+:+:+:+:+..*+*+:+u.>.= = = E x.~.A A A A s+s+x.s+x.s+x.x.x.= = N z >.:+b.4 * p./+$._ _ _ _ _ _ _ _ k _ U _ _ _ '._ U '.U '._ '._ U '.j '.'.'.'.$._ U k - M.3.8+o 8+8+8+A.M.M.g - u+g u+u+g u+g u+v+u+u+u+u+* * * * * M.g - - k 9+[+/+_ +[+*.1+1+*.*.[+[+*._ [+[+[+*.[+_ _ +_ 1+*. +_ y.*.y.y.m.#+H.H.B }+B H.w w m.#+m.n+z+b R b X b b X b k X R R 9+9+k 9+R #+w #+w s.s.s.s.- - - Y.J J J J J - J J J J - J - J J U J J - M.X f f ]+S.S.! f s.X - J - - - - - - - X X - X X f f X X f X X X - - k J ,+J k k X R X E+E+5 f X 5 X X X X X M.X - M.- M.X - f X X M.X X X M.X X M.- M.X - X X X X f f f X X z.X z.- k k k k - k X k X - k k k _ U U j U U '.'.'.'.'.j [ [ j.j.j.L 3 l {.m+l.] l.7 |.[.~+S S S > > > > > > > > > S S 0+0+&+D+0.Q q l.].y+'.m.#+w w w #+Y.J U U [ [ [ j.v v $+3 3 3 v v v j.j.j.j.j.j.j.v d+P U U g M.R.i i f.o ` * A.t 8+4 F ;+o+*+:+f+( b+4 2.` * u+* M.` 2.#.#.++++A+++#.^.q.R.^.@.H.w b M *.$. +t.p.N.C+J.b+b+++k+(.1 2 e.+.6+> ", "..:.q.,.$+F.} Q q Q 0.Q q 7 @ K d+,.'+C+;+f+-+x.~.A s+N a.....p+p+p+p+:+p+:+p+p+p+>.N = N N N p+p+p+p+:+:+*+:+p+N x.= x.x.~.A 8 8 8 A ~.~.x.s+x.x.x.x.s+E = N N >...:.f.h+,+_ _ _ _ k _ _ J k k J _ k J _ J k _ U /+U _ U '.U _ _ _ '.'.'.'.w.j 0 j U J X f ! o i 4 8+` u+u+u+- g - g - g g g * u+* A.` ` ` 3.` ` M.s.M.s.L.9+,+[+*. +*. +[+[+[+*.1+[+[+[+*. + +$. + +1+$. +$. + +[+1+1+*.y.n+n+z+n+b N.b N.b z+m.z+n+R z+R z+X R R b R X R R R 9+9+9+9+9+9+#+R #+#+b w s.s.#+#+k J J J J - k J J - - J J U J J J J J J J - - X f f f f 3.f f X - J U U U U J k J - - - - X - - X f X X E+X b X R k k J ,+J R X E+f E+f f 5 5 X X X - - - - X X - - - X - - M.- X X - - - - - - - - X X X f X f X X 5 f f X X X z.k - z.k k X z.- - z.- z.k U k _ U U '.'.j '.'.j j w.[ j.v j.3 3 K F.m+l.l.7 7 [.: 0+S > > > <.<.<.C <.<.<.6+> S S 0+T.&+Q 0.q l.].y+t.[+n+w H #+X - k J U U j j [ [ [ j.v j.v j.j.[ w.j [ j w.[ [ [ P U J J - h+M.` o 8+R.` A.* t f.4 b.*+:+>.u.u.u.o+7.r+R.* * * ` 8+2.i ++A+3+8.3+C+r+! S.! )+H.#+z+R [+1+Q.t.p.4+C+J.b+j+8.6 6 5 a T +.O O ", "4 q.V 7+p @ } d q q q d } @ 3 e+Y.q.4 G.>.E { A ~.s+a...Y Y b.b.Y :+:+:+..:+:+u.N E = = = = = >.>.>.>.p+p+p+u.N E s+x.s+~.{ 8 8 8 A A s+~.~.A ~.~.~.x.E = E >.p+:+:.q.H C. +_ k R k k k _ k k k k J k k k _ k _ _ J _ ,+,+_ '.'.'._ '.'.Q.Q.w.j w.j _ k f f ! o o i 8+3.M.X - M.- - u+X u+M.g M.` ` ` R.8+8+8+3.` 3.M.s.w X R [+ +*. +*.1+*.[+ +y.*.[+ +1+*.*. +t.t.5+t.t.$.'.t.$. + + +[+y.M M n+n+#+#+z+z+n+z+m.n+z+n+z+R n+z+z+n+R z+z+R m.R m.R y.9+m.9+9+R #+#+w H #+#+X X R J J J J J J k J k J - J J J U U J U J J - - X f f 5 E+E+- - J J U P j U U U J J - J - - - - - X - X X X X X X X k k k _ k R X 5 E+5 1 E+f f 5 X X - - - J - - - - - - - - - - - - X - - - - - X - X u+X X X M.f f X X X X z.X X z.X - X z.- X z.X z.X - k k k _ '.U '.j j '.'.0 j [ [ j.v L 3 L l l m+l.l.7 |.: : S > > 6+<.C C C C C C C C <.> > S 0+T.&+Q q l. .j.Q.,+m.w H H - L.C.J J U U U U j j j [ [ [ [ d+[ j j '.j j j j j P J J - - M.f 3.3.R.3.M.* * t /.:...>.N N N >.>.p+G.4 f.` ` * 8+8+2.i _.8.b+b+< C+i 2.)+.+! H+w n+n+[+$.5+t.p.B B.J.G.c.8.k+(.^ z+T +.6+> ", "* Y.e+p F.@ } } } } ] @ F.$+F+p.q.7.*+>.x.~.A s+= a...:.:.4 4 :.;+b...*+*+*+:+>.E s+= = = = = N N N N = N >.= = s+x.x.8 8 !.8 8 8 A A { A A A A { x.x.E N u.p+b.4 R.Y./+_ ,+k k k k R - X k k - - R k k k k J J k _ ,+_ ,+U k U '.'.'.Q.j [ w.j.w.w.'._ z.3.! o o o 8+` A.- - - u+- - X g M.` M.` R.o 8+o o o R.! a+M.E+#+9+[+_ *.[+1+ +[+ +[+y.[+1+*.*.y.1+_ + +Q.t.Q.Q.t.Q.t.Q.'. +_ [+y.y.n+n+z+n+n+n+n+b m.z+n+n+n+n+M n+n+n+n+R M n+R R m.R 9+[+R [+9+n+#+#+n+#+#+#+H L.C.9+k k k J k k J k U k U k J J J J U J J J - - - X X s.E+X X C.U U U j P U j U U J J k - J - - - k - X X f w X X k 9+k C.C.k X X E+E+f 5 1 5 f f X X k k k - J - - - - - - - - - - - - - - - - - - - X X M.M.X f X X X X X X X X X X X X X X X X X X X f z.z.z.k _ k _ _ '.j Q.j w.[ j.j.j.L v 3 3 l {. .l.] l.[.k.S S > > <.C C r C r C C r C C <.> > 0+0+T.q q |.F.<+e+t.9+p.#+L.9+Y.Y.J J J - - k k k U U P [ P j j j _ _ _ _ U j U U J J - X M.3.3.3.3.M.M.h+h+` /.+ ..N E x.x.`.a.:+*+:.r+q.` ` ` 2.o _.++J.b+b+++i 2.r+)+! .+.+P.z+a e.1+t.t.p.B C+J.b+b+8.6 c+1 2 5+<.O 6+", "7+).$+K m+@ @ ] ] ] m+K v ,.'+q.;+:+z x.A ~.s+a...b.:.:./.f.q.2.:.;+;+*+b.*+:+>.E = = = = = = = N E = s+= E s+x.x.A A 8 !.8 8 8 8 A 8 8 8 8 { A { x.E = >.:+;+i '+C.J _ k k k R R X k X X X X - X X - - - k R k k k k J k _ _ _ U _ j '.w.[ x+v j.w.j k R E+! o o ! R.M.X - - k - - - M.X M.3.! o o o o #.o o ! R.3.f b m.R *. + +*.*.1+*.e.y.[+[+*.*.1+_ 1+$.t.t.Q.Q.Q.Q.Q.Q.Q.Q. +$. + +[+M M n+m.z+n+n+n+z+m.n+n+M n+n+n+n+n+z.a n+n+n+M n+y.y.m.m.9+y.m.y.n+#+n+#+n+#+n+9+9+,+,+,+_ J k k _ k J k J k J J k U J J U J k k k z.k - R R k ,+w+l+7+P P P j J U k J J J J J J J - - X - X X w X R R k C.k R z.w E+5 @.f 1 5 5 X z.- - U J J k - J - - - J - - - J - - - J - - - - - X X X f X E+f E+E+X X X X - - k X X X z.X X X z.X X X X X z.k U U _ '.j j 0 [ [ [ j.v j.3 3 3 L l l F.: ] [.: : > > <.C C r C r r r r r C r <.> > 0+0+T.d d 7 l.l y+e+/+C.C.C.,.J m J J J - - - - X - - J U P U U U - X - X - J V J J - - X M.M.3.M.M.M.- u+h+` /.Y p+= ~.A A x.= p+..:.4 8+` ` 8+f.r+i ++3+< n A+_.o 2.o )+a+a+H.w n+*.e.Q.t.p.B )+8.b+8.8.k+c+P.2 e.<.O > ", "$+p K {.@ @ @ @ F.K p e+,.B C+;+p+E ~.A s+s+N p+..:.:.4 2.q.q.C+:.;+b.;+;+*+:+u.= = = N = = = = x.x.~.x.s+s+x.x.A 8 !.8 !.8 8 8 8 8 8 !.!.8 8 A ~.E = p+:+:.2.* 9+C.k k k R X X X #+X X w #+X s.s.s.X #+X X X X X X X R R k k k U _ '.'.[ j.j.O j.0 '.R E+3.S.! ! R.3.M.- k k J k k - h+M.R.R.o o #._._.#.r+#.]+@.a+H R m.[+_ *.*.[+[+*.*.[+*.*.y.*.e.y.1+ +$.t.t.t.0 0 0 Q.Q.Q.5+$.$. +[+*.y.M n+n+n+z+z+n+n+n+n+n+n+n+n+M a M M n+M n+M n+n+R 9+y.n+y.n+y.n+n+n+m.n+m.m.R R m.m.m.9+R y.k k k k k k k U k _ J k J k k k R k X X R R k 9+,+,+l+l+j j j j U U U U U J J J J - J k k - X X w X m.R m.9+9+k k X E+f @.1 1 1 f f X - - k J J J J J J V - J - J - J - J - k - k J - - X s.M.f f f E+X E+E+X X k - k - - - - - X X X X z.X X X z.k k z.k _ _ '.j [ j w.[ j.j.j.L $+v 3 v 3 L ].l . . .S > <.C C C r r r r r r r C r C 6+6+S : |.B+B+7 l.F.3 v e+l+l+w+l+7+7+m m J - - M.M.M.X - - J J V - X f f 3.3.3.M.M.- - M.- X M.3.3.3.X s.h+- h+t + Y p+s+A 8 !.1.x.>...:.+ f.` 8+8+r+i _.A+J.n b+< ++#.2.)+^.@.H.H.b z+M 1+t.t.p.B C+J.b+c.k+6 c+5 a 5++.O D.", "p K {.K {.{.{.K p $+7+H q.4 *+>.x.A A A = a.....b.:.:.:.4 q.2.7.:.:.:.;+;+*+:+>.>.N N = = = E x.~.A A ~.~.s+~.{ 8 !.!.!.!.8 8 8 !.8 8 8 !.8 8 x.x.= >.:+:.q.H 9+R R X X X w E+s.E+s.M.M.f 3.f M.M.M.s.s.w X w w E+w f E+E+X X R X k k _ Q.w.w.w.j.0 _ k X f a+a+R.R.M.h+- J J k - - s.M.3.! o _._.A+A+A+_._.o ]+H+w #+y.y.1+ + +1+*._ *.*.[+*.*.*.y.*.y.*. +1+$.Q.t.Q.Q.Q.Q.Q.Q.Q.Q. + +1+*.y.y.M n+M n+n+n+n+M n+n+M n+n+n+n+n+n+n+n+n+M M n+n+n+y.R *.y.y.y.m.n+n+n+n+n+n+y.y.[+R [+R [+y._ k _ _ _ R _ k k J _ _ J _ J k R R X m.R 9+9+,+,+w+U l+j U U '.J k J k k k J U J J - k - X X X #+X 9+R 9+9+m.X b E+E+@.@.@.1 5 f - k J U J J J - J - - J - J J J - J J - U J J J - - X X X E+f E+f X X X z.X k k k k k k k - - - z.- z.X - - - X k k _ _ '.j & w.[ [ [ v v $+L v j.j.j.L x+j.L |+].|+> 6+6+<.C r r r r r r r r r C C <.6+> ~+0+7 d d ] m+K 3 v d+d+[ [ F+P 7+m J V h+M.f f M.X - - J - u+3.8+o o o o ! ` ` M.M.- X X M.f 3.M.s.u+- * t /.Y a.E 8 8 !.!.{ = p+Y /.f.f.` f.r+i 7.A+< G.b+3+++r+o ! ^.S.}+w b m.*.1+t.t.m.B B.++G.8.8.X.1 !+a +.<.6+|+", "K K K K K K p $+e+,.'+q.J.o+N ~.A A s+= a.....Y ;+;+:.:.4 r+C+7.:.:.:.;+b.*+:+p+>.N N N N = x.{ { A A A A ~.8 8 !.!.8 8 !.8 8 !.8 8 8 !.A { ~.x.= u.*+7.^.s.X X X w X w E+s.f f f 3.}+3.3.3.3.3.f f f E+f E+E+f E+f 5 H+H+E+E+E+5 f z.k U j 0 0 w.0 /+k #+H.}+a+a+M.M.h+J k J k - s.f 3.! G _._.3+< 8.8._.k+i.S.H.z+y.*.[+[+*.1+[+1+1+[+*.*.*.*.*.y.M [+*.*.t.$. +Q.t.Q.t.Q.Q.Q.Q.$. + +*.*.y.M n+n+n+M n+n+n+n+M n+n+M M n+n+M n+n+n+n+z+n+M M n+n+y.y.n+n+R y.n+n+n+n+y.y.R 9+R y.m.y.R y.9+9+m.m.9+[+9+k ,+,+k k [+k k 9+9+m.m.R #+9+9+C.,+w+/+'.'.j '.U _ U k U U U _ U k J J k k - X m.X m.9+9+9+C.- R X 5 f 5 1 1 3.E+X - k J U U J J U J k J J V J - J - J J J J J J J - - X f E+E+f E+E+f X X X k k k U _ U k k k k J - - - k k k k k z.k U _ '.j j [ j.v v L v 3 3 $+v j.[ [ j.j.w.j.O O 6+6+C C C C r r r r r r r r r C <.> > S [.|.7 ] ] @ m+K p $+$+$+v v d+P m J g M.M.3.3.M.M.- - - u+M.R.o G F F 3+i o ! ` M.M.X - X f 3.3.3.M.* '+/.:.% a.s+A 8 !.8 { E p+b.+ f.` 8+2.r+i _.3+J.D b+A+i r+r+#.! a+}+b n+M *. +Q. +p.B C+8.b+c.8.6 c+5 T $.<.D.> ", "3 $+p 3 $+v F+,.g 4+4 ;+p+E { 8 A A s+a.....*+:+*+*+;+;+J.:.:.:.7.J.J.;+*+:+:+:+u.>.= E E x.x.A { A A A 8 8 !.!.!.!.!.8 !.8 8 8 8 8 A A A { = N p+b.4 R.#+X b b w E+E+f f f 3.3.a+a+S..+! ^.! S.S.S.3.f 3.f H+f 1 f 1 c+@.1 f 1 f 1 @.5 X _ _ '._ _ _ k X s.'+'+a+M.s.- k k k X X 3.S.o #._.8.< < (+< 8._.Z X.E+R M *. + + +[+1+[+*.*.[+*.*.y.*.M *.M *.*.*.[+ + + + +t.t.t.5+$. +5+t. +*.*.y.M M n+n+M n+n+n+z+n+n+n+n+M n+n+M n+n+n+n+n+n+n+y.a n+n+y.m.m.n+y.y.n+y.n+m.m.y.y.y.y.R y.m.y.*.M y.y.9+[+m.y.n+y.y.m.R [+9+[+m.R #+n+m.9+9+C.,+w+/+'.,+U _ J k U k k k J k U _ J J J k - #+X R R 9+9+R 9+- X X E+H+1 f E+f X X k U U U U U U J J J J J k J J J J J J J J U J U J - - X E+E+E+X X E+X - - k J k k U k U k k k k k k k k k k k U k k _ U '.j [ w.[ j.v 3 $+$+$+v j.[ j '.'.j Q.Q.w.w.w.C C C r r r r r r r r r r T C C 6+|+]. .l.[.@ l.l.m+F.{.K 3 p 3 $+d+P ,.- M.R.R.o ! 3.M.u+- M.M.` 8+i _.F 3+n F i o ! M.g - - - M.3.o R.o 8+f.:.Y ..a.s+A 8 8 A ~.E p+b.+ f.t t 8+i 4 7.3+< n b+8.#.8+o 2.i.@.}+H.b y.1+$.Q. +n+B B.++b+8.++X.1 !+e.& <.D.> ", "y+v y+d+e+,.Y.'+q.:.*+p+E ~.~.A A s+a.:+..:+..:+:+:+:+*+:.7.:.J.:.J.;+*+:+:+:+:+:+p+>.= x.x.A 8 8 8 8 8 !.!.!.!.!.!.8 !.!.8 8 8 A A A ~.x.x.N :+;+r+R.E+E+E+E+f f 3.3.H+S.@.a+3.S.! ]+o ]+]+]+o ! G+@.@.f 3.f 1 f 1 1 1 1 1 1 @.c+G+G+! f z.z.k k _ R X s.s.f }+M.'+X X - - s.X 3.! o G _.< n (+(+D < 8.B.^.H+#+R *._ *.*.*.1+[+1+*.*.*.*.*.*.*.M y.y.*.y.y.*.y.*. +$.$. + + +t. +[+1+*.y.*.M n+n+n+n+n+n+n+M n+y.n+n+M M n+n+z+n+n+M M n+n+n+n+n+y.y.y.y.M y.n+n+y.m.n+y.y.n+n+R m.y.m.y.m.n+n+y.R y.R M y.y.m.9+y.[+m.n+R m.n+m.n+n+p.9+[+,+,+/+,+/+,+_ _ _ _ k _ k k U k J ,+_ C.9+m.m.9+#+#+m.9+9+9+R R z.X 5 E+E+E+b X k J U U P U U U J J J J J J J J k U J U J U U U J J k z.X X b E+b X X X k k J k k U k k U _ _ k U k U J k k U k J _ _ U '.j j [ [ j.v v v 3 3 v v e+j _ _ _ $.e._ $.$.$.T T T r r r r r r r r r T r T & <.w.|+]. . .m+m+{.{.K K {.{.K K p d+P J g M.3.o o o 8+R.M.M.g ` 8+f.F 3+b.n b.3+3+o o ` M.- J J - R.R.r+C+C+4 :...p+= s+A 8 A ~.s+N p+;+/.f.t 8+f.i 7.7.J.b+n n 3+r+o 2.)+)+@.H.w z+y.*.t.Q.t.p.B B.8.c.8.W X.P.z+e.& 6+O |+", "[ e+7+,.p.'+q.7.G.f+N x.A s+s+s+s+= a.p+:+p+p+p+>.p+:+*+;+J.J.J.J.G.*+:+p+p+:+:+:+>.>.= x.~.A 8 8 !.!.!.!.!.!.!.!.!.!.!.8 8 8 8 ~.x.x.x.= p+..:.8+'+f f S.@.@.@.@.@.S.@.@.@.S.! ! ! o #._.#.G 6 o ! G+S.3.H+f E+5 f n.1 f 5 5 1 G+]+G o ]+f E+z.f X E+X E+f 3.}+}+M.M.#+s.E+3.S.S.o _.8.< D D 5.D < A+B.G+H.n+y.y.*.[+_ +_ 1+*.1+1+*.*.y.*.*.y.*.*.y.*.M y.y.[+*.*.*.e. + +1+ +1+*.*.*.M y.y.n+n+M n+M n+n+n+n+n+n+n+n+n+n+n+n+n+z+n+z+M n+n+n+n+n+n+n+m.n+n+n+n+n+y.n+n+n+n+y.y.R y.n+y.y.y.n+y.M M y.n+n+y.y.9+n+y.m.n+y.n+n+n+R n+n+9+m.y.m.[+,+[+9+[+k k _ ,+_ _ _ _ _ J k _ C.k k 9+9+9+9+9+9+9+9+9+X R b b E+E+X X R k U j U j U U U U J J J J J J U J J U U U U U U U J - k w E+E+f b X R - k k J k U k _ U k U U U k U k U _ J U k U U _ U j j j d+j.j.j.3 L 3 3 v [ j /+_ R R R z.z.e._ e.a T 2 r 2 2 2 2 2 2 z.2 a a T $.& I.w.y+<+3 U.3 3 l l K 3 l K 3 3 d+7+Y.M.R.! o o #.o 8+3.` * ` 4 F Y E.E.E.:+G.3+i o 3.h+Y.J J - 3.8+r+7.3+;+*+:+u.N E A A { = >...% :./.` A.t f.4 i 3+n G.*+b+3+++r+2.! ^..+P.b z+y.1+ +Q. +y.B )+J.b+b+8.(.1 z+e.I.6+|+|+", "w+C.L.'+q.7.;+:+>.E x.~.s+s+= a.a.N a.p+:+p+p+>.N a.:+*+b.b.;+;+;+*+:+u.p+p+:+:+p+p+N E ~.8 !.8 !.!.!.!.9.!.!.!.!.!.!.!.!.8 8 A x.E E >.p+*+F q.3.f 3.G+S.! ]+G+! ! ! S.R.S.! S.! o ]+o #._.G o ]+! 3.@.f f E+E+5 z.5 5 z.5 5 1 c+G G #.o ! 3.3.E+H+f @.S.S.S.a+a+}+M.M.f a+S.]+k+C+< n D D 5.D b+8.#.)+}+b R *.1+*.1+1+1+1+*.[+[+y.*.*.*.M *.M y.*.M M y.M *.M y.y.M y.y.y.*.*.y.y.y.M M n+M n+M n+M n+M n+M n+n+y.n+n+y.y.n+n+n+n+n+n+n+n+n+M n+n+n+n+n+n+y.n+n+n+n+n+z+n+n+n+n+M n+n+R n+n+y.y.n+n+n+y.y.y.n+y.y.n+y.m.n+y.n+n+n+9+m.M [+y.*.y.y.R _ m.[+[+R ,+k C.k k _ ,+/+C.[+9+,+y.m.[+9+[+9+9+[+9+R R X X b b w R k _ J P U P U U U U J J J U U J J J U J U J P U j U J k X X E+w E+w b X k J U U U U U J U k k U k U U k J U k U U U U _ j j [ w.[ [ v v v 3 $+$+v [ j C.#+X w w b z.5 z.z.z.z.z.5 2 5 5 5 5 5 5 5 5 z.z.M *.1+Q.0 y+y+v y+<+$+3 3 3 K 3 p v F+m - M.3.8+o _.F i o o 3.` /.4 Y E.>.N = = u.*+3+2.a+- J U 7+g R.2.i 7.J.*+*+:+>.N s+x.A A E p+..:./.f.t A.t 8+i 7.7.J.n D n 3+4 o o ! ^.a+E+w z+y.1+Q.Q.t.p.B C+8.G.c.8.6 1 z.e.I.O |+|+", "L.'+q.i J.*+>.E ~.A A s+= a...p+p+p+p+..:+p+p+N N N p+:+*+*+;+;+b.*+p+>.N N p+p+p+p+N { { 8 !.!.!.!.!.9.9.9.9.9.9.!.!.!.8 8 ~.~.E = >.:+;+4 R.'+S.G+! ! ]+! ! ! ! R.! S.3.3.R.S.! ]+]+G G _.G G ]+]+@.f f E+X z.X z._ _ T z.z.f c+G _.#.G o o ]+]+]+]+]+o 6 G ! ! S.3.3.! ! #.i 8.3+(+D >+o+5.G.3+#..+E+R y.[+*.1+*.*.[+ + +*.*.1+*.*.*.*.y.*.M y.y.M M M M M y.M M *.[+y.y.y.*.y.M M *.y.n+*.M n+y.p.M y.m.M M n+M n+n+n+n+y.n+M n+n+n+n+n+n+n+m.n+n+n+n+n+n+n+n+n+n+n+n+n+a n+n+n+M n+n+n+y.n+y.y.y.n+n+m.y.n+n+m.y.y.m.n+n+y.n+M y.n+n+y.n+y.y.y.y.y.y.y.[+y.y.*.,+,+y.[+y.[+_ ,+[+9+[+m.y.9+,+[+9+9+9+#+R z+z+X X X R k ,+J j U j U U U U J J J J U U U J U U U P U U U U k - X w E+w E+X R k k J j j U U U U U k U _ U k U U k U U k U U U j j j j d+d+d+j.v $+3 3 $+d+[ l+k b E+E+P.1 P.P.5 5 5 5 5 E+^ 5 c+1 1 5 1 5 1 P.P.b R n+*./+/+e+e+e+y+y+$+<+3 3 3 p v [ J - M.8+o i o 4 4 f.o 8+8+/.b...N s+~.{ x.E u.*+4 q.'+,.w+7+Y.R.i :.;+*+*+u.u.u.>.N = s+~.x.p+Y + /.` t A.t f./.7.7.;+;+o+G.A+i r+2.! a+}+s.b n+y.[+Q.Q.Q.p.4+C+b+b+b+8.X.1 a 5++.O |+> ", "q.r+J.*+u.N x.A 8 A s+s+a.a...*+..:+....:+:+p+>.a.:+..:+..b.;+;+G.o+u.N = N a.a.p+>.E A !.!.!.!.!.9.!.9.!.!.9.!.!.!.!.!.8 8 x.x.= p+..:.8+a+f S.! ! ]+o o ! o ! ! ! R.! S.R.S.R.! ]+o G W W G ]+]+1 f f z.X k k '.& w.w.w.$.z.5 G+o o #.#._._.i G G _._._._.G o o ! ! ! B.#._.< n D 5.>+o+o+D 3+#..+E+#+9+[+[+ +[+[+_ [+*.y.e.*.*.*.*.*.*.*.[+y.*.*.y.y.y.M M *.y.*.M n+[+y.y.y.M y.y.n+y.y.M m.y.M M m.M M n+n+n+n+y.n+n+y.n+M z+n+n+n+n+M n+M n+n+n+z+n+z+n+z+z+n+z+n+n+n+z+z+n+n+z+n+n+n+m.n+n+m.m.n+m.y.m.n+m.n+M n+y.y.y.n+n+m.n+n+n+y.y.n+y.m.n+y.R y.R y.[+y.y.y.[+[+y.[+y.*.m.[+9+y.[+y.[+9+/+m.,+y.R w w w n+m.9+k k U U j U _ J J J U U J U k J U U U U U U U U U J k R X w X b b z.X k U U U U j j U k U U U U U k U U _ U J U U U U U j j [ [ j.j.L v v $+v $+v P w+9+w a+@.@.G+G+G+H+H+E+E+5 1 1 c+1 c+c+G+c+G+1 G+H+H+P.z+n+m.p.p./+t.e+d+y+y+$+3 3 3 d+P U M.M.! 8+4 f.o 8+f.8+8+/.+ % E.= ~.A 8 8 x.E :+J.r+'+C.7+7+g 8+4 *+*+:+N >.>.>.p+u.a.N = = p+;+:.f.` u+u+t 8+i F 3+n G.G.D 3+#.2.^.^..+N.#+#+M *. +5+I.t.p.4+C+J.c.j+8.6 P.z.$.I.O |+K.", "7.;+:+>.x.{ 8 A A s+s+a.p+Y b.b.Y Y Y *+..p+a.>.p+b.b.*+b.:.:.:.;+:+>.= = = = = = = { 8 !.!.!.9.!.9.!.9.9.!.9.9.9.!.!.8 { { E N p+b.4 R.'+3.a+! ]+o o o o ! o ! ! ! R.3.3.3.3.3.S.]+6 G W W G ]+! 3.f f X k '.& w.O L x+O w._ k E+3.^.]+#._._.7._._.W _._._._.G _.r+#.#._.3+< n 5.>+>+>+5.n 8.B.^.E+n+y.y.y.[+1+1+1+1+*. +*.*.y.*.*.*.y.[+y.[+y.M M M a M y.M M M M y.n+y.y.y.y.M M M y.y.n+M y.n+y.y.y.y.M M M n+n+y.m.n+n+m.n+M n+M n+z+n+n+n+n+n+z+z+z+n+z+z+z+z+b z+n+z+z+z+z+n+z+n+n+z+n+n+y.y.y.n+n+n+y.n+y.n+m.n+n+n+m.y.n+n+n+n+n+y.n+n+M y.n+y.n+y.m.y.y.m.y.m.m.[+m.[+*.*.y.*.[+m.,+9+[+[+[+[+9+m.m.R #+w w R [+,+[+,+,+'.'._ _ J k U U J J _ U k U U U U j U U U U k X R b X b w z.R k ,+U j U U U j U U k U U U U U J J U k J J U U U P j [ [ d+d+v v $+3 v v [ e+w+9+w }+@.G+G+G+G+@.G+1 @.@.@.G+G+G+G+6 X.Z Z X.X.X..+.+B N.H p.p.p.p.t.0 e+y+$+$+$+$+d+j Y.M.` o f.F o /.o 8+t 8+8+F % a.= ~.A 8 8 8 E >.G.4 * h+w+7+g f.;+:+>.= E x.x.`.p+:+..........b./.f.t v+u+t f.4 :.;+n *+*+G.J.++o 2.R.! E+n+m.9+[+t.Q.I.Q.p.B C+G.G.c.++6 ^ !+& I.O |+S ", ":+u.N x.A A 8 A A = a.p+..Y b.b.;+*+b.b.*+>.p+..;+:.;+b.:.4 C+7.G.:+N E = = = s+E ~.8 !.!.9.!.9.9.9.9.9.9.9.!.!.!.!.!.8 ~.x.N :+;+/.a+'+3.S.! ! o o ! o o o ! ! ! ! R.R.3.3.R.S.! ! G _.W _.G ]+@.@.f X k _ '.[ j.x+].l l j.[ /+R w 3.! o _.i _._._.W 8.< < W 8._._.A+_.3+b+G.>+>+>+>+5.G.A+r+@.w R y.1+[+[+*.[+1+y.[+*.y.y.*.*.*.*.*.*.[+y.y.y.y.y.M y.n+M n+y.M M M M M *.M y.M y.M n+n+y.y.y.y.m.M y.n+y.n+n+M M n+n+y.n+n+n+n+n+n+n+n+M n+n+n+z+n+z+z+z+z+z+z+z+#+z+z+z+z+z+z+z+z+n+z+n+n+n+n+n+n+n+y.n+m.n+m.y.n+n+n+n+n+n+z+z+n+M n+n+M n+n+n+n+n+y.y.y.y.y.y.*.*.*.y.[+y.y.y.[+y.y.[+[+[+y.y.[+y.[+y.m.m.n+9+p.9+p.,+,+/+/+_ _ U J _ U k k _ _ U k U _ J '.U U U U U C.k k X b z.X z+R J _ '.P P j j U U U U U J U U k U U J U U U U U U j j j [ [ d+v d+v v v $+v d+j /+C.#+E+@.S.G+G+]+@.@.S.@.G+G+G+i.Z Z i.k+i.i.i.i.i.)+^..+@.B 4+4+N.#+p./+e+y+y+v $+$+[ m - M.! o F _.F 4 8+8+` 8+/.+ % a.s+A A 8 8 A E >.b.4 R.g 7+w+g 2.;+u.E x.A { { x.N p+Y + + + /./.f.* u+V g t 8+/.3+:.n *+D *+3+7.r+2.R.a+}+#+m.y.t.Q.0 0 0 w+4+C+J.c.c.8.6 P.z.e.6+O |+|+", "N x.x.A A 8 A A s+a.a.....b.:.b.b.b.:.*+*+p+p+:.i J.;+;+4 q.C+7.o+>.= x.s+x.~.~.A 8 !.!.!.9.9.!.9.9.9.9.!.9.9.!.!.8 { ~.= u...:.q.a+M.3.! ! o o o o o o o o o ! ! ! ! R.3.3.S.! ! ]+_._.8.G ]+]+]+S.S.f X k _ & w.O L x+L x+[ '.k #+a+! B.r+_.i #._.< 8.< 3+A+3+8.3+3+< n D 5.( f+( o+n A+B.@.w m.y.y.*.*._ 1+[+[+*.[+*.*._ y.y.y.*.*.[+*.y.y.*.y.n+M a M M M n+M M M M M y.n+M M y.M M y.p.y.y.y.m.y.m.M M M n+n+M M n+M M n+M M n+M n+n+M n+n+M n+n+z+z+z+b b H.!+b z+z+z+b b z+z+z+z+z+z+z+z+n+n+n+m.n+n+m.n+n+n+n+n+n+n+n+n+n+z+n+n+n+z+n+n+n+n+m.n+n+y.y.m.y.n+y.y.n+n+y.y.y.9+,+y.[+y.y.[+[+[+[+y.,+[+m.R y.m.y.[+9+[+[+[+/+_ _ _ k _ _ _ J _ _ _ _ J _ U _ './+/+,+,+C.R R X X #+z+#+R k w+U j j U j U U U U U U U U U U U k U U J U U P U P P F+[ [ v d+v v v v v [ e+U k R E+}+a+@.@.@.}+H+H+@..+.+)+i.i.Z i.B.6 B.B.)+B.)+2.^.^..+4+4+4+N.m.[+/+e+v j.v v P U g 3.8+o F F F _./.8+8+8++ b...a.s+A A A A s+N p+b.4 '+Y.d.,.* f.b.p+E { 8 !.!.{ E p+Y 4 f.t $ v+v+6.6.,.6.u+f.4 :.3+;+G.*+G.J.i r+o ! a+H.b R y. +t.Q.0 Q.p.'+C+G.G.c.8.k+P.z+$.}.O |+S ", "x.s+~.A A A s+s+= a.p+p+....:.:.b.:.:.;+:+p+Y 4 q.C+:.:.2.q.2.J.:+p+= E x.A 8 8 8 !.!.!.9.9.!.9.9.9.9.9.9.!.!.!.!.{ x.= u.Y 4 R.M.E+3.! ! o ! o 2.o o o o o o o 8+! ! ! R.! ! ! ]+o _._._.G G ]+]+]+G+3.f X _ '.j w.w.j.w.j.0 ,+k E+a+! o r+r+o _.A+8.< < < 8.8.< 3+b+n 5.o+( ( ( >+(+++B.@.w n+y.y.*.*.[+*.*.y.1+_ *.*.*.*.*.*.*.y.y.y.y.*.y.y.*.*.y.y.n+y.M M M M M y.M M M M M n+y.M y.y.y.p.n+y.M M n+n+n+M M n+n+n+n+n+M n+n+M m.M n+m.n+M z+n+z+z+z+N.z+z+z+b b b b b z+z+z+b b z+z+z+b n+b n+n+b R n+n+n+m.n+m.n+m.z+z+N.z+z+z+z+z+z+n+n+n+M M y.n+n+M M n+y.n+n+y.y.[+y.y.y.y.y.y.y.*.y.m.y.y.y.m.m.[+[+y.y.[+m.[+y.[+,+y.,+[+[+_ J _ _ _ _ _ _ _ _ _ _ _ U _ ,+/+,+,+C.9+#+#+R #+R 9+,+,+U U j j j '.U k U J U U U J U U k U U U U U j P j [ [ [ [ [ j.d+[ [ j.[ d+e+l+,+9+#+E+S.@.}+}+f }+N.H.a+)+i.i.B.B.C+i.B.)+)+B.q.B.B.B.i.2.2.2.4+B H p./+e+y+v v d+P J - 3.o o _.3+F F F 4 /./.F % a.= A A 8 8 ~.s+a...:.f.* ,.7+,.* f.:.:+= ~.{ 8 8 8 E p+..+ f.t g 6.,.m m m 6.A.` f.F :.n n *+G.3+++2.2.2.@.'+#+R [+[+Q.Q.}.e+p.B C+G.D c.8.6 P.a & w.D.|+].", "s+s+s+s+A A s+s+a.a.p+p+..Y b.b.b.:.:.*+:+p+b.4 2.:.J.:.2.q.C+J.*+p+N x.{ 8 !.!.!.!.!.!.!.9.9.9.9.!.!.9.9.!.!.8 A x.= :+;+2.'+'+3.3.! o o o o ! 8+o ! o o o o o o ]+o ]+! ! ! o o G _.G _._.G G ]+]+]+]+S.3.X z.U _ w.[ j j '.k X E+a+^.o o r+o _._.< < 8.< 3+< < n n o+:+>+( >+o+n A+)+a+H m.R *.*.*.[+*.[+_ *.e.1+*.y.y.*.*.y.*.*.y.M y.*.M M y.y.M M n+y.M M M M M y.M M m.M M M n+M y.m.M *.M n+n+M a M n+n+M a M n+M n+M M n+M m.M M M n+p.n+n+n+n+n+b z+b b b #+z+z+b b b z+z+b b b z+b z+b #+z+z+b z+z+z+n+n+z+z+#+b n+z+z+z+z+z+z+z+z+z+z+n+n+n+n+m.n+y.n+n+y.m.y.n+m.y.y.y.y.y.y.y.y.*.y.[+y.[+y.m.y.[+y.y.y.y.y.m.*.y.y.y.[+[+,+[+9+y._ ,+y._ *.y._ ,+[+[+ +_ /+,+[+9+9+m.w #+#+n+m.,+_ l+U j U '.U j U _ U U k U _ U _ U U U U U U j j P [ [ [ [ [ [ j.[ [ j.j.[ [ j U C.X w w E+w b X X s.H.a+.+)+B.)+B.2.)+2.)+^.^.^.^.^.2.B.)+2.2.^.4+H 9+/+l+[ v v [ U J M.M.8+4 _.F _.F 4 F F b.% a.= s+A 8 8 8 8 x.>.b.i ` g 7+F+d.'+2.;+:+N ~.{ { ~.x.= u.*+:.q.A.,.6.,.O.d.7+m * ` 4 7.;+;+*+G.*+3+i r+2.^.S.}+#+R *. +Q.Q.I.Q.,+4+C+J.G.c.8.6 P.a $.<.D.S |+", "= = = s+s+s+s+a.N = = a.p+Y Y b.;+:.;+*+p+..;+4 :.7.:.:.:.C+i ;+..p+E ~.8 !.!.!.!.9.9.9.9.9.9.9.9.9.9.!.!.!.8 A x.N :+:.q.'+f f S.! ! ! ! ]+! o ! R.o ! o o o _.o _.#._.#.o o o o o o ]+G W G G G ]+G G G ]+3.X z.k z._ _ _ k k s.3.3.! o o o o _.A+< < 3+8.< n n 5.>+>+( f+>+o+G.++)+a+n+R y.*.y.y.1+ +*.1+*.[+*.*.[+_ *.*.*.*.e.M *.*.*.M M y.y.M M M M M y.y.y.M p.M y.y.M M *.n+M M n+y.y.y.n+m.a n+z+n+M n+n+n+n+M n+M M n+M m.M n+n+n+n+M n+n+n+n+N.z+z+z+z+n+z+z+z+n+z+z+b b b z+b b b b b z+z+b z+#+b b z+b n+b z+z+N.b z+z+#+N.b n+b z+n+b z+n+z+n+n+n+n+M n+M n+n+M y.n+y.n+y.y.y.*.M y.y.[+n+*.[+y.m.[+m.y.[+y.y.y.y.y.*.m.[+y.[+[+[+y.[+[+y.[+[+[+[+y.[+[+ +[+[+,+9+9+m.#+z+z+n+9+[+,+U j j '._ _ _ _ k U _ U _ U U U U U U U U U j j P P [ [ [ [ w.[ [ w.0 [ [ [ e+'.,+9+X b R R R ,+,+9+L.E+a+S.)+)+^.)+q.4+4+4+4+4+4+^.4+^.^.^.^.a+}+h+p./+e+[ d+d+F+U - M.3.o o 4 F o /./.+ b.Y E.a.A A 8 !.9.9.8 ~.N *+4 q.g 7+d+m * /.;+:+N x.8 8 x.= a...b./.q.u+6./ 7+d.7+d.m u+` f.F ;+n G.*+n :.4 r+o 2.)+}+w R y.$.Q.0 }.0 [+B C+G.G.b+8.6 1 z.5+I.D.|+S ", "a.a.a.s+s+s+a.N = s+s+= a.....*+..Y :+:+p+:+b.:.;+;+;+:.:.:.:.;+:+>.x.8 !.9.9.9.!.9.!.9.9.!.9.9.9.!.!.!.!.8 ~.E >.*+4 a+w w f @.G+! 2.! o ! ! ! ! ! R.R.! o _._.3+3+3+3+_._.o o ]+o G G G G G ]+]+]+]+G W _.o 3.3.f X z.X X f X f 3.a+! 2.8+o o o #.r+i 3+A+3+D 5.*+( ( f+( o+b+++i.H.w y.y.y.[+*._ [+y.[+*.*.1+*.*.*.*.*.*.y.y.*.*.y.M e.*.M *.y.M y.M M M M y.m.M n+M n+M M n+M M M y.M n+y.y.y.n+M M z+z+a M n+M n+M n+z+M n+M n+M M M a n+M m.n+n+n+n+m.n+n+z+z+z+z+z+m.b z+b N.z+z+b b b n+z+b z+z+z+b n+#+n+b z+n+b z+z+z+N.z+b n+b N.n+b z+n+#+z+n+n+z+n+n+n+z+n+M n+n+M y.y.y.y.y.y.y.M y.y.y.y.y.y.y.y.*.y.m.y.*.y.[+*.y.*.y.m.y.y.y.[+y.*.[+[+[+[+y.[+*.*.y.*.[+y./+[+9+9+9+m.m.y.9+[+/+t._ _ '._ U U _ U U _ U _ U _ _ U k _ j U j U j [ j [ [ [ [ [ 0 [ [ w.[ j.[ [ j '.,+k R y._ [+/+'.k 9+#+s.}+4+S.4+a+4+a+H '+h+'+s.}+'+B a+a+'+B w L.C.t.[ j.[ v F+U J M.3.o o F 4 /.F _.F % E.a.s+A A !.!.9.9.!.8 = :+7.q.Y.7+d+d.'+2.;+p+E x.{ !.-.E p+*+:./.q.V ,.7+O.F+F+7+/ * q.2.7.;+n *+*+G.7.r+f.B.^.S.H+w R y. +Q.Q.0 Q.p.B 2.b+G.b+8.6 1 z+& s O |+].", "..a.N = s+= a.= = s+s+= a.:+:+p+p+p+p+>.a.p+:+*+*+:+*+*+;+;+G.:+u.E 8 !.9.!.!.9.9.9.9.9.9.9.9.!.9.9.!.!.8 A E a.b.4 }+#+X E+@.S.! ! R.! S.a+a+3.R.3.R.! o o _.< < < < < < < _.G o ]+]+]+6 G ]+S.n.6 G W _.3+G o G+G+S.@.@.f f S.S.3.! S.R.! ! ! o o o #._.3+n 5.o+( f+f+( o+b+++! E+#+y.y.[+[+*.1+y.1+[+*.*.1+y.*.*.*.y.M *.*.*.y.y.*.*.y.*.*.M *.n+M M y.M n+M M M *.M M M n+M M M y.y.m.y.n+m.m.n+n+n+M a z+n+M !+n+p.n+y.M M n+M p.n+n+n+n+m.y.y.M M n+n+z+z+z+z+n+n+n+n+n+z+z+z+H.b N.b b b b z+b b b z+b z+z+z+z+N.b b b b z+z+b b b b H.N.b b z+z+z+z+z+z+z+z+n+n+n+n+y.n+n+n+m.n+M n+M y.y.y.*.y.y.y.y.y.n+y.y.*.m.y.y.y.y.y.[+y.y.*.y.y.*.*.*.*.e.y.y.[+[+*.[+[+y.*.*.[+y.y.[+9+[+,+/+[+/+/+t.$.'.'.$._ '.'._ '._ j '._ _ j _ U U '.j j j j j P w.j w.j Q.0 w.0 j.0 [ [ [ j '._ _ _ _ '.Q.Q.t.9+m.#+#+}+}+}+'+s.L.Y.C.9+C.C.9+#+L.H H s.H #+C./+l+d+d+v d+P J u+M.8+o /._.F i f.F F Y a.= s+8 8 !.9.!.!.!.{ N *+:.q.,.7+v F+g q.;+:+= A !.!.u { = p+Y /.q.v+m d.e+F+F+O.7+V ` f.i 3+;+G.G.G.A+r+r+2.2.a+H.H.M y. +Q.Q.I.0 p.B C+J.c.b+8.6 P.a & w.D.|+S ", "..p+= s+s+= a.N E s+~.= N a.>.= = = = N N p+p+:+>.>.p+p+:+p+p+N E { 8 !.9.9.9.9.9.9.!.9.9.9.9.9.!.!.!.A ~.= p+:.q.h+R X E+f S.3.S.S.S.R.S.S.3.3.f f f 3.! o G 8.5.(+(+< < W _.o o ! @.G+]+1 5 X 5 c+G W < 3+_.o o o ]+]+! G+]+! ]+! R.! R.! R.! o 8+i 7.3+< *+o+>+( ( o+D J.#..+H.n+y.[+*.*. +[+1+[+*.1+e.y.*.*.*.*.*.*.M *.M *.*.*.*.y.[+y.*.y.*.M n+M y.M M y.*.M y.m.n+y.n+y.p.a y.y.n+y.y.m.M n+M n+n+n+M n+M n+n+n+n+n+n+y.n+M M M M M M n+M n+m.M n+n+n+n+n+n+n+n+z+n+n+z+b b b !+b b b b N.z+z+z+n+z+z+z+b #+z+z+z+b z+H.b z+N.z+z+z+z+b z+z+b z+z+z+z+z+n+n+z+z+z+z+n+n+n+n+M n+M n+y.M n+n+y.n+y.y.n+y.y.y.y.y.y.n+y.y.y.y.y.[+*.y.[+y.*.*.[+y.1+*.y.y.[+[+[+[+ +[+[+[+/+p.[+9+y.*.[+1+ +[+/+[+1+_ $._ _ '._ '._ _ '.U _ '.'.'.U _ '.j '.j 0 j [ j 0 '.Q.j 0 j w.o.j.0 [ j 0 /+ +$.t.Q.0 j.0 '.[+R #+H s.w H L.9+,.w+w+w+w+,+C.9+9+9+9+9+C.,+l+e+d+v d+d+P J M.3.o /.F F F F /.F Y E.a.= A 8 !.9.9.!.8 8 s+N *+/.` ,.O.v 7+g ` ;+p+E A !.!.9.!.x.= p+:.f.* g 7+F+F+F+7+7+V '+2.i J.;+G.*+;+7.r+2.2.#.@.H.w n+y. +Q.Q.0 Q.,+B C+G.G.c.k+X.!+M & <.e |+S ", "..a.N = N N a.N = s+= = = = = E = s+x.x.x.= >.u.N = E N = E x.x.8 8 !.!.!.!.9.9.9.9.9.9.9.9.9.9.!.!.8 ~.N :+4 '+C.9+X w f 3.a+3.3.3.3.3.a+a+M.f M.M.M.3.R.]+_.< 5.( (+< < _._.]+! @.f 5 z._ T _ z.5 ]+_.7._._._._.o o o ]+G o G o o o ! o ! ! o o r+_.3+b+n 5.( f+( o+5.3+#.4+w R *._ *.*.*.M *.*.*.[+[+*._ *.y.*.*.*.y.*.*.*.y.y.*.*.*.y.*.y.y.y.y.M y.M *.M y.y.M y.M y.y.M M M M M M y.M m.y.n+M z+n+n+M z+n+z+n+z+p.n+n+n+n+M n+n+n+n+y.M M n+m.M n+M M n+y.M n+n+n+n+n+n+n+#+n+b b b b b b z+b b b b z+z+n+n+z+b b b P.z+z+z+b b #+b b b b b b z+N.b #+n+#+z+z+n+z+n+n+n+n+n+a n+M n+M n+n+*.y.n+m.n+n+y.n+n+m.p.y.n+M n+m.y.y.*.m.y.*.*.*.[+[+[+*.y.[+*.*.[+y.*.*.y.y.[+[+[+[+[+*.[+*.1+[+[+ + + + +t.'.'.$.$.'.$.'.'._ '.$.$.'._ '.'.'.'.j 0 '.0 j Q.'.Q.'.Q.j 0 0 0 [ j.o.[ 0 [ '.0 w.w.o.j.j.[ t.9+n+#+#+m.9+k J l+P [ [ j l+/+k k 9+k C./+l+7+d+v v d+F+J - A.! o o _.F 3+F F F Y E.N x.8 8 9.9.9.!.8 A = p+;+2.* ,.d+).F+g ` :.:+= A !.9.9.9.!.x.N p+:.f.* ,.7+F+F+7+7+g ` f.i 7.n *+;+J.7.r+2.2.2.X.w w n+*. + +0 0 Q.p.4+C+J.b+b+8.c+P.a & w.D.|+].", ":+p+N = a.a.p+p+p+a.N = = = = x.s+x.x.~.s+= >.>.E x.x.x.~.~.A 8 !.!.!.9.9.9.9.9.9.9.9.9.9.!.!.!.!.A E N ../.* w+/+R w E+E+3.3.3.3.3.f 3.f f s.s.s.M.M.3.R.]+_.D i+5.< < W _.G ! f f k j w.O w.w._ z.H+]+o #._.3+3+3+_._._._._._._._.i o o 8+! o i 7.A+n 5.5.>+f+( >+n b+B.a+m.y.[+*. +1+ +1+1+1+1+1+*._ *.[+*.*.y.*.M y.y.y.*.*.*.*.*.*.*.*.*.*.*.*.y.*.M y.y.y.y.*.y.y.p.M m.y.y.m.M y.y.M n+p.n+m.M M n+n+M n+z+n+N.M z+M n+n+M n+n+M n+z+n+M M M M p.n+y.n+n+y.y.n+m.n+n+m.n+z+z+b z+z+b b b b #+n+n+n+b #+z+z+z+z+z+N.!+b b n+n+z+z+z+z+b b #+N.n+z+z+b z+n+z+n+n+z+n+n+n+z+n+z+z+M z+M y.n+n+m.M n+n+n+n+n+n+M m.n+n+n+n+M y.m.y.y.y.y.*.y.*.y.y.*.*.[+*.[+[+*.*.[+ +y.[+*.[+*.[+ +[+[+ +*.[+[+[+t. + +$.t.t.$.Q.$.& '.Q.'.$.$.'.$.'.'.'.'.'.j '.Q.j Q.'.'.$.'.$.'.0 0 [ [ o.[ j.j.0 0 o.j.x+x+L 3 [ /+n+n+9+9+,+/+7+e+[ [ y+[ e+j /+,+/+/+l+l+e+e+d+$+$+d+P J M.M.8+o F _.F F F F + Y a.= ~.8 !.9.9.9.9.!.{ E :+J.q.Y.7+y+d+7+* f.:.p+E A !.!.9.9.9.8 x.p+b.4 t u+,.7+F+7+m g q.2.A+J.J.G.G.7.4 f.2.! ^.! P.b n+M $.Q.I.0 t.p.B C+G.c.b+k+6 P.a 5+<.e > S ", "..p+a.N a.p+..b.b...p+N N s+= = x.x.A A ~.s+N >.= x.A 8 !.8 !.!.!.!.!.!.!.9.!.9.!.9.!.9.!.9.!.!.A x.a.b.q.Y.l+U k X E+f M.M.3.M.f M.}+M.E+M.E+s.s.s.f 3.G+#.8.c 5.< < W _.G ]+3.f k j O L ].l L w.'.k E+3.o _.< < n < < _.W < W < _._._.o o o i _.3+n G.o+( ( ( >+D ++)+H+m.R *.[+1+e. +1+ + +[+*.e.*.*._ y.*.*.*.M *.*.y.y.M M M *.M *.*.*.y.y.y.M y.M M y.M m.*.M M M M m.M M M M n+y.n+n+M n+n+n+n+n+n+a z+z+n+n+z+z+n+z+n+M m.!+M n+n+n+n+n+n+n+n+n+n+y.n+y.n+y.y.y.y.n+n+n+m.n+z+b b b z+z+z+n+#+n+#+n+n+#+b z+z+b z+b z+N.b z+n+#+m.n+n+z+n+m.z+n+z+n+n+b n+z+z+n+n+z+M z+M a n+z+M n+n+M n+n+z+n+n+n+z+n+n+z+m.n+n+n+M n+M M y.y.y.[+y.*.*. +[+ +[+*.*.y.y.[+*.*.y.[+[+[+[+y. +[+*.*.[+[+ + + + + +t.t.Q.Q.Q.Q.0 Q.Q.'.Q.Q.'.& t.& $.t.t.t.'.Q.'.Q.Q.j Q.'.& Q.Q.Q.w.0 o.[ o.0 o.j.j.j.<+L l l 3 $+e+,+,+,+,+/+j e+d+d+j.v v [ d+e+U l+j P [ [ d+v $+$+F+U J M.3.o o F F _.4 F F + E.a.s+A !.9.9.9.9.9.9.{ = f+:.q.h+7+e+$+7+h+2.;+:+E ~.!.9.9.9.9.u { N *+:.f.t V m m 7+,.u+q.r+i A+G.G.*+b+r+2.2.2.R.a+B b M [+t.Q.Q.Q.Q.p.4+++G.o+c.k+i.P.M & w.D.|+|+", ":+p+N N a.p+b.+ :.:.b.p+N = >.N = s+~.A ~.= p+p+E { 8 !.!.8 8 8 8 8 8 8 8 !.!.!.!.9.9.9.!.!.8 A E >.;+8+C./+_ _ R E+M.f E+E+M.}+}+3.}+3.}+3.3.f 3.a+S.! ]+_.< n n < < < G o ]+@.5 k '.w.l .l l L [ j R f ! _.< n 3+< _.< < < W < W < i i _.#.3+3+< 5.o+( 9 >+5.n A+)+H+n+*.[+e. +1+1+ +*._ +_ *.1+*.e.[+*.*.*.y.*.y.e.*.*.*.*.*.*.*.y.y.1+*.*.y.y.m.y.y.y.M y.y.M y.y.*.y.M M M *.M y.y.y.M M y.m.m.n+p.n+n+!+z+z+z+z+z+!+n+n+n+n+n+n+n+!+n+N.z+n+m.n+n+n+m.n+n+n+n+m.y.n+n+n+z+z+n+z+z+N.z+z+z+n+n+n+z+n+n+n+b b z+b z+z+n+n+m.n+n+n+b n+m.z+z+n+#+n+n+z+n+m.n+n+n+n+n+z+n+z+n+n+z+n+n+n+n+M n+m.n+z+n+z+z+z+n+z+n+n+n+z+n+z+M n+y.y.y.*.[+y.*.[+[+*. +*.[+[+[+*.*.[+*.y.y.*.[+y.[+[+[+y.[+[+*.1+ +t.t.Q.t.t.Q.0 I.0 I.I.Q.Q.Q.Q.Q.t.Q.Q.t.t.t. +$.t.$.t.$.Q.'.'.$.'.Q.0 0 w.[ j.j.j.x+L L 3 3 l F. .K v e+/+l+l+l+e+[ v v $+v $+L d+v [ j [ [ d+v v v $+v F+J k f 3.o _.F 3+F 8+F F % E.= s+8 !.9.9.9.9.9.9.{ x.:+;+q.H 7+e+v 7+* f.*+a.E A !.!.9.9.9.!.{ N :+:.2.` u+,.m m V * 8+r+7.J.n G.G.J.C+)+^.)+.+}+s.E+a e.Q.I.I.0 Q.p.B 7.G.o+D 8.X.5 *.5+w.O |+S ", "p+a.a.= a...:./.r+:.;+:+>.a.p+p+N = s+A s+= a.p+E 8 !.8 8 8 8 A A 8 A 8 8 8 8 !.!.9.!.!.!.!.~.E p+:.R.C.,+_ k b E+M.E+M.}+3.3.3.3.a+3.a+R.! )+! ! ! ! ! o _._._._.< W W G ]+]+G+G+f X _ j.L ].L x+j.'.- E+o _.3+n 3+< < W < < < W < _.3+i _.7.A+n 5.>+f+( >+o+b+C+)+}+R y.*.1+[+ + +1+e. +1+*.*.[+*.e.y.*.M *.*.*.y.*.y.*.*.e.*.*.*.*.*.*.y.*.y.y.[+y.y.y.y.y.y.y.y.y.y.M M p.y.y.y.y.M y.y.n+m.n+y.n+M n+n+n+z+n+z+N.z+z+n+N.n+n+n+z+n+n+z+z+z+n+n+n+n+z+M m.n+m.y.y.M m.y.n+n+m.z+z+b z+z+z+n+n+z+z+n+n+n+n+n+n+n+z+b b z+z+n+n+n+n+m.n+z+n+n+z+n+n+n+z+n+n+n+n+y.m.n+M n+n+n+n+n+M M n+m.n+m.n+n+z+n+z+n+z+n+z+z+n+z+n+z+z+n+z+M n+y.*.p.*.*.*.*.[+[+*.[+1+p.*. +p.[+ + +[+[+[+ +1+[+*. +[+[+*. + +t.5+t.0 o.I.o.I.I.I.I.o.I.o.I.I.Q.Q.$.Q.t.$.t.t. +'.t.t. +Q.& Q.Q.Q.Q.o.0 w.[ w.x+v L 3 l F.F.{.F.l K v e+e+7+e+[ v v v $+p v $+v v v v d+[ v v $+$+3 $+[ U - M.3.o _.< 3+F 4 F 3+% E.s+A 8 9.9.9.9.9.9.!.8 E :+:.q.H e+d+v 7+* 4 Y >.x.8 !.9.9.9.9.9.{ E :+;+/.f.u+V V m g ` q.4 7.A+J.G.G.J.++i.8+q.)+H+b b M +t.Q.0 Q.t.p..+C+G.o+c.8.c+!+a & +.6+D.S ", "p+a.p+N a.p+:.q.q.7.J.:+>.a.....p+N x.A s+= a.N x.8 8 8 8 A s+~.~.~.s+A A 8 8 8 !.!.!.!.8 ~.E p+:.a+k k z.b X E+f 3.f 3.S.3.a+S.S.! ! ]+r+r+_._._._.i r+o o o o G G < W G ]+]+]+]+G ]+3.U [ j.j.j.j _ s.3.! _.A+n < _.< W < < W < < W 3+3+_.3+n D o+( ( f+5.b+_.G+w R y.*.*. +*. + +_ 1+1+1+1+*.[+[+*.*.*.y.*.a *.*.*.*.*.y.e.*.*.*.1+1+*.y.[+[+y.[+y.y.y.y.*.y.y.y.y.y.y.M M M M M y.*.y.y.y.y.M M n+M n+n+z+z+n+z+z+b z+z+z+z+n+z+z+z+z+z+z+z+z+z+z+n+z+n+m.n+n+a m.n+n+m.m.n+n+z+n+#+z+z+z+n+n+n+z+m.n+n+n+n+n+n+n+z+z+z+z+n+n+M n+n+y.n+n+n+y.n+n+M M y.y.y.n+y.n+n+M n+M n+n+m.z+y.M n+m.n+n+n+z+n+b n+z+n+#+z+n+z+n+z+z+z+z+n+m.n+*.y.[+p.1+[+ +[+*. + +[+y.*.1+*.*.*.[+[+y.[+[+[+y.[+*.[+*.[+ +t.Q.Q.0 0 o.s o.y+y+y+o.o.o.I.}.Q.Q.t.Q.t.5+$.t.$.$.t.t. +t.t.Q.t.0 Q.0 o.o.j.j.j.3 3 l 3 {.{.{.{.K 3 $+d+[ e+y+[ d+v v $+$+$+$+v v d+v v d+v v $+$+$+$+d+U - f ! o F < 3+3+F F E.E.a.s+A !.9.9.9.9.9.9.!.A E :+:.q.L.7+d+d+,.* /...N ~.8 !.9.9.9.9.9.u x.p+;+/.q.$ ,.6.V u+t /.:.:.b+G.n J.7.r+2.^.R.)+.+H.#+n+ +Q.I.o.I. +m..+C+G.o+c.8.6 5 M & I.O |+|+", "a.p+p+p+p+Y 4 2.2.7.;+p+N a.p+..p+= ~.s+A = = x.A 8 8 8 A s+a.N s+s+s+s+A A A 8 !.!.!.8 x.= :+4 3.X R b f f @.S.@.a+S.@.S.S.@.S.! ! #._.A+< n n n n < 3+i o ]+]+6 G G G G+n.]+6 G G < o X '.'.j j '.- E+S.]+_._.3+_._.< W < < W _._.< A+3+3+n D ( 9 ( ( D b+C+.+w R y.*.1+ +1+ +1+1+1+[+[+ +*. +*.y.[+y.M a M y.*.a *.*.*.1+y.1+*.*.y.*.1+1+*.*.*.y.[+[+*.*.y.y.y.y.M M y.M y.*.M M M M M y.y.M n+n+y.n+y.n+n+#+b b b b b z+z+z+z+n+z+z+z+z+n+!+z+N.z+z+n+z+n+z+n+z+n+n+n+n+n+n+n+n+n+n+n+z+n+z+n+n+m.n+m.m.n+M z+z+z+n+b n+n+z+n+n+M y.n+m.y.y.m.y.y.m.n+n+m.y.*.y.y.y.n+M M y.M n+y.n+m.y.y.y.y.n+n+n+n+b n+z+n+n+z+m.z+n+n+n+n+M y.*.y.[+[+[+[+[+[+[+[+[+[+*.[+[+y.[+[+[+ +[+[+*.*.[+[+[+[+1+[+ + +t.Q.Q.I.}.o.y+<+<+D.D.<+y+s o.I.I.I.Q.Q.5+t. +t.t. +$.t.$.5+$. +Q.Q.Q.Q.Q.o.w.j.j.j.L 3 K K {.K K 3 3 L v [ [ e+[ d+d+v v v v v d+v d+v d+d+d+v d+v v v F+U - f 3.o _.3+5.n n Y E.a.E A 8 9.9.9.9.9.9.!.!.~.N :+:.q.g e+d+e+,.'+4 ..N A !.!.9.9.9.9.9.!.{ >.b./.q.u+v+m m u+8+4 :.n *+G.G.G.7.2.R.R.a+R.G+P.z+n+1+5+0 o.0 Q.N.4+++G.o+c.8.X.P.a $.<.O > S ", "p+p+p+a.p+Y :.2.C+:.G.:+a.p+p+p+= s+A ~.A s+s+~.A 8 A s+s+= a.a.N N >.= A A A 8 8 8 A x.>.*+4 * X E+H+@.@.G+G+! S.! S.S.a+S.S.@.S.! #.A+n D >+5.5.5.5.< _.o ! c+G+6 ]+1 5 ^ c+]+; < 5.3+o M.X k R - s.S.! o _.A+_._._._._._._._._._.3+3+< n 5.5.( ( ( >+b+#.a+#+y.*.*.[+*._ +1+$.e.e.1+*. +y.1+*.*.*.M M y.a M *.*.*.[+[+*.*.e.*.1+*.y.y.M *.y.y.y.*.*.*.y.*.y.y.M y.M M n+M n+n+y.p.M y.y.M M M n+n+n+M M n+z+z+b N.!+b b z+z+z+z+z+b b b b b z+z+z+z+n+z+n+z+n+n+n+n+n+z+m.n+n+z+n+n+n+z+n+z+n+n+b n+n+n+n+n+n+n+n+n+n+z+n+n+y.n+n+y.y.m.y.y.m.y.y.y.y.y.m.y.*.*.y.y.y.y.M n+y.m.y.y.y.m.p.n+y.m.[+n+n+n+m.n+m.n+z+R n+n+n+z+y.n+n+y.p. +[+[+ +[+ + +[+ +[+[+p.[+[+*.*.[+[+ +[+[+*.*.*.[+*.[+[+[+ +t.Q.0 }.o.o.o.y+<+<+D.<+<+y+o.y+o.}.Q.Q.5+5+t. +t.t. +t.$.5+t.t.t.t.Q.0 o.y+y+j.j.L v L K p K 3 3 3 v <+v y+[ e+e+[ [ d+d+d+d+v d+d+d+d+d+v d+d+d+v d+j.F+P J X 3.o _.n n 5.Y E.E.= E 8 !.9.9.9.9.9.9.!.1.E p+b.4 q.g 7+e+m h+q.:.:+= A !.!.9.9.9.9.9.!.A >.*+:.t u+V m V A.f.4 ;+n G.*+5.G.J.r+q.R.4+a+a+@.P.n+ +5+0 I.o.t.p.4+J.G.o+G.8.X.b e.Q.}.O D.> ", "p+p+>.a.a.Y :.4 7.;+:+p+>.N = E x.A s+A A A A 8 A A s+s+= N p+>.N N N E { A 8 { 8 A x.p+b.q.'+X E+3.G+]+G+! ! S.S.3.! a+3.a+3.3.S.! G _.(+( ( ( i+i+5.n 3+o 3.f f 1 5 z.z.5 1 c+W D 5.n o o ! 3.M.f G+S.o o _.4 _.o _.o o o o _._.A+3+< n n >+( i+>+D A+B.a+m.*.1+1+1+1+1+ +1+1+1+*. +*. +*.*.*.1+*.*.y.y.M y.M *.*.*.*.*.1+M *.*.M M *.*.1+M *.*.*.y.y.y.*.y.*.M p.M n+n+y.!+y.M n+M M M M n+n+n+n+y.n+z+z+n+z+z+z+z+b b z+z+z+z+z+z+N.b b z+#+b b z+z+b z+n+n+z+n+z+z+n+n+z+n+n+n+M m.m.n+n+n+R z+n+z+n+n+n+n+z+n+n+a n+n+n+M n+m.*.m.[+[+y.m.y.y.y.m.y.*.*.y.*.y.y.y.p.m.m.y.y.M M y.y.*.y.y.y.y.m.y.n+n+n+n+n+m.n+n+n+y.n+M n+M y.*.[+y.[+*.*. +[+[+[+[+ + +[+[+[+[+[+*.*.*. +[+ + + + +[+1+ + + + +t.Q.0 o.s y+D.<+y+<+<+<+<+s o.0 0 Q.Q.t.t. + + + + +t.5+ +Q.Q.Q.Q.Q.I.0 I.o.y+y+j.j.v v $+v 3 <+<+3 j.j.j.y+[ [ e+e+[ [ d+d+F+[ d+[ d+d+[ d+j.[ d+d+[ [ j J - f ! o F n 5.5.5.u.z x.{ !.9.9.9.9.9.9.!.{ E u.*+4 q.H ,.7+,.'+2.;+>.s+8 !.!.!.9.9.9.!.8 ~.N ..4 f.u+v+V V A.8+4 :.;+*+*+*+o+n C+^.R.^.H+#+s.w n+y.Q.I.o.I.t.p.q.++G.>+D 8.X.b ++.<.O |+|+", "a.N N = a.:+Y ;+;+*+:+>.= E s+~.A 8 A A A 8 A 8 A s+a.N N >.>.>.E E = x.{ A 8 { x.= p+:.R.w b E+@.S.! S.S.S.! ! S.S.S.a+3.M.M.f 3.a+]+_.D 9 9 ( 5.i+5.n o ! f z.z._ w.<.& T X 1 G < ;+3+3+3+4 o ! o #.#._.3+_.F G o o o ]+]+o o _._.3+< 5.5.>+o+D b+++i.N.z+y.y.[+ +*. +e.1+ +1+ +1+1+*.1+*.[+*.*.y.y.*.M M y.y.*.a *.y.y.*.y.*.*.1+M *.M e.M *.*.*.*.*.y.p.y.y.M n+M M n+M n+n+M n+n+M y.M M M M n+M n+n+n+z+z+z+b z+z+z+z+N.n+z+N.z+z+z+z+z+z+n+b m.z+b z+z+n+n+z+n+z+z+n+n+n+n+n+n+n+n+n+n+n+n+z+R n+z+z+n+m.n+n+z+a n+n+n+M M n+M n+n+m.y.y.n+y.M y.n+*.M y.y.y.y.y.y.y.*.y.y.p.M y.m.y.y.n+y.m.y.y.p.m.R n+y.R [+y.n+y.n+y.y.y.y.*.[+[+[+[+*. +*. + +[+ + + +[+*.*.[+ +*.*.*.*.p.*.*.[+[+[+[+ + + +t.Q.}.I.o.o.o.o.o.y+D.y+y+<+s I.0 Q.Q. +t. + +t. + +t. +t.t.t.5+Q.t.Q.0 o.I.0 [ j e+e+[ v d+d+j.j.j.y+j.[ 0 [ e+e+j [ P P [ [ [ [ [ [ d+F+[ d+[ d+[ [ [ [ U J - 3.! _.F n 5.E.E.z = { !.9.9.9.9.9.9.!.{ E u.o+7.q.'+p.,.g q.:.*+N ~.8 !.9.9.9.!.!.8 A s+a.Y /.t u+6.6.u+t /.+ 3+b.5.*+*+*+J.i ^.R.^.X.H.#+z+n+*.$.Q.0 I.Q.m.^.7.G.i+c.8.6 5 1+I.w.O > |+", "N s+= = >.p+p+:+:+:+>.= E x.~.A A 8 8 8 8 8 A A s+= a.>.= = N E x.x.x.{ 8 8 ~.x.>...4 '+X w f S.S.R.3.! ! ! 3.3.S.a+a+3.M.'+#+M.}+S.]+8.i+( 5.5.5.(+n < o M.k j w.x+|+L O w._ E+]+2.#.A+n E.n F A+A+< n n n < < 3+_.o o o o o _.7.3+3+G.D o+5.D J.#.! E+R [+*. +1+[+ +*.1+*.*.*.1+e. +e.*.1+e.*.y.*.a *.M *.*.y.*.e.y.*.*.*.1+M M *.*.M *.y.*.*.*.y.y.*.*.y.y.y.n+y.n+n+n+z+n+z+n+!+M n+n+z+n+n+z+n+n+n+M z+M n+m.n+z+z+z+z+z+z+n+n+n+z+z+z+z+n+b n+b n+n+z+n+z+z+n+z+z+z+z+z+z+n+n+n+n+n+n+z+n+b z+z+z+n+n+n+z+n+n+n+n+z+z+n+z+n+M M y.y.y.y.M M M y.y.y.y.y.y.y.y.y.y.y.y.p.y.y.y.y.y.y.*.y.y.[+y.[+y.y.y.y.y.9+[+m.m.y.y.y.y.y. +p.[+[+*.[+ +[+[+ +*.*. +[+*.[+ +[+[+[+*.[+[+ +*.*.*.[+ +[+ + +*. + + +5+0 Q.Q.I.o.o.o.o.o.s o.o.0 }.0 Q.t.5+ + + + +t.t. +t.5+t.Q.Q.Q.Q.I.0 o.0 l+,+[+,+l+/+l+e+[ [ 0 [ 0 o.[ 0 j j l+l+U 7+U m 7+d.P F+P [ [ d+[ d+[ d+[ P [ j U - M.o #.A+3+D 5.E.E.>.= A 8 9.9.9.9.9.!.{ E z o+(+C+4+Y.,.h+8+:.f+z { !.9.9.9.9.9.9.8 s+a...+ /.t u+6.V v+8+/.3+Y G.*+*+*+*+7.r+2.a+a+^.P.n+R y.[+5+I.I.o.t.p.4+++G.D D 8.c+5 1+Q.6+e |+S ", "= s+= = N = N >.p+>.N = x.A 8 8 8 8 8 8 8 A s+s+s+= >.N E = x.x.A A ~.{ { A x.>.b.2.L.k X H+S.! S.R.3.R.S.! ! ! S.3.3.f f M.s.M.3.! Z A+5.n n < < < 8._.3.X '.j.L l : m+K.l j.j X a+)+b+o+:+( E.n n 5.5.i+5.5.n n < o o o o i _._.< D D >+D b+8.B.H+#+n+*. +*. +1+ +*._ +1+e.*.[+e.[+1+1+*.*.e.*.*.y.a a M *.*.y.*.y.*.*.*.*.*.y.*.*.M M y.M M *.*.M *.*.*.y.y.n+n+m.z+n+z+n+z+M n+M z+a z+n+M n+z+z+z+M n+n+z+n+z+b z+z+z+n+z+b n+z+z+z+z+N.z+z+#+z+n+n+z+z+n+z+z+N.n+z+z+z+z+z+n+n+n+n+R n+n+n+b z+z+z+n+z+n+n+z+z+n+z+M z+n+n+n+n+n+n+y.n+n+M n+n+y.n+y.*.y.y.*.m.y.y.*.y.m.M p.M M y.p.*.y.y.p.y.y.y.y.y.*.9+[+y.y.y.[+*.y.y.*.*.[+*.*.[+ +[+[+[+ +[+ +[+[+[+[+[+ +[+ + +y. + +[+[+[+ +[+[+ + + + +t. + +Q.0 Q.Q.I.}.Q.I.Q.I.I.0 Q.t.Q.t.t. +[+ + + +t. + +t.t.t.Q.Q.Q.Q.0 o.t.[+#+N.H H L.C.,+/+j '.0 0 0 0 j j j w+C.Y.Y.J - J J U j P F+F+[ [ d+[ [ [ [ P P U k f ! _.< < *+D ( o+E.E.z s+{ !.!.!.!.{ x.E u.:+G.++2.'+L.* 2.;+p+E A 9.9.9.9.9.9.9.8 E p+Y /.f.v+V ,.6.u+f.+ Y E.*+E.( :+E.J.r+8+q.'+a+4+w m.M *.t.Q.I.0 Q.p.4+++G.o+c.++X.!+1+I.O D.|+S ", "= E = >.= E s+= = N x.x.A A 8 8 8 8 8 8 A ~.s+x.s+= = = E ~.{ 8 8 { 8 8 A E p+;+q.L.- X E+S.G+S.! ! R.! R.! R.! ! R.a+a+3.'+}+f 3.! o A+A+A+_._._._._.]+3.k '.w.L . .: : .].j.l+#+)+++G.:+E.E.5.5.i+( 5.i+5.5.5.n F o o i _.7.n n D 5.5.n A+i.P.m.y. +*.*. + + +1+ +e.1+[+1+1+*.1+1+*.e.*.e.*.*.y.*.*.M *.y.*.*.y.y.*.y.*.*.*.*.y.*.*.*.e.M M *.*.*.M M y.M y.M n+n+n+n+z+z+z+z+z+n+a z+a z+n+z+n+a n+n+z+n+n+z+m.z+z+z+b z+b n+z+n+n+n+n+z+n+z+z+m.z+n+n+n+z+n+z+n+z+z+z+n+n+n+M M R n+n+z+z+b z+z+#+n+z+n+z+z+z+n+z+z+z+z+z+a n+y.M y.n+n+M n+n+y.n+y.y.p.y.y.y.y.M y.M y.M y.*.y.y.n+y.y.y.[+y.y.y.y.[+y.p.[+y.[+y.[+y.y.*.*.*. +*. +*.[+[+*. + +p. +[+ +[+[+[+[+*.*.p.*.*.[+*. +[+ +*.[+ +p.[+t.[+[+ + +t.t.t.Q.t.Q.Q.Q.Q.5+t.Q.Q.5+t.t. + + + + + + + + + + +t.t.t.0 }.o.t./+#+4+^.)+4+}+s.Y.J '.j '.'.j '.j '.U J - X X s.M.#+- k U P [ [ d+[ [ [ d+[ F+[ [ U k f ! G 8.n 5.o+D G.b+;+Y Y a.N = s+x.E N u.u.o+G.8.)+B * * 8+:.:+E 8 !.9.9.9.9.9.9.u E p+b./.q.A.V 6.V v+f.+ ..E.E.:+:+f+:+G.i q.^.s.'+'+b R R 1+5+I.o.}.t.p.q.J.G.o+b+k+1 z+$.I.O > |+S ", "= = N p+= x.~.s+x.= x.~.A 8 8 8 8 8 8 A A s+s+x.x.x.= E x.{ 8 8 !.8 { x.E :+:.R.X X w S.S.! ! ! S.! ! ! ! ! ]+! o o o ! ]+! ! R.! ! o o o G _._._.]+]+3.5 X X '.[ x+3 l .l L j./+#+! ++n o+( *+D 5.9 z ( ( ( 5.5.n F F o F _.< n 5.o+D b+++o }+R [+y.e.[+*.*.1+ +e.[+*.1+*.*.1+*.1+*.*.1+*._ *.*.*.*.*.M *.y.y. +*.*.*.*.*.*.*.*.*.*.*.y.*.*.*.y.y.M y.y.y.M M M n+n+z+n+z+n+n+z+z+z+n+z+z+z+z+n+z+M z+n+n+n+n+z+n+z+N.n+b b z+n+z+n+z+n+z+z+n+z+z+n+#+n+z+n+z+n+z+z+n+z+z+z+n+z+z+n+M n+n+z+n+#+b z+z+z+z+z+z+z+z+z+z+z+z+n+z+M n+n+n+M M n+M n+z+n+n+n+y.M y.y.y.y.n+p.M y.n+M y.y.y.y.y.y.n+y.[+y.m.n+y.*.y.[+y.[+y.y.[+*.y.[+y.*.*. +[+[+[+[+ +y.*.*.y. +[+ +[+[+ + +[+ +[+[+[+[+[+[+*. + + +*. + +[+[+ + +t.t. + +t. +Q. +5+t.t.t. + + +[+1+1+ + + + + +t.t. +Q.Q.t.Q.0 0 t.p.4+B.++C+C+^.a+'+L.k U _ '.'.'.j /+,+k s.M.f f f w X k U U F+[ d+d+v j.v d+d+[ [ U k X @.#.W b+D 5.D b+++r+2.8+/./.+ :.% Y *+*+*+D D 8.B..+'+* ` 4 ..N A !.9.9.9.9.9.9.8 E p+b.:.t A.g 6.V A./.+ b.*+:+( f+:+( *+3+r+2.@.#+L.w m.[+ +5+Q.I.I.t.y.4+J.o+o+D 8.X.z+5+I.O |+K.K.", "N N a.p+= x.A A ~.A A 8 8 8 8 8 8 8 A ~.s+= x.~.~.x.= x.~.8 8 !.8 1.x.= *+4 a+s.f H+H+G+! ! ! ! ! ]+! ! o G o o #.#.r+#.o o o ]+! ]+! ]+o G G W ]+]+@.c+G+c+]+@.k j w.j.j.j.j.[ U s.R.B.J.b.5.n 5.( 9 9 ( 5.5.( 5.n 3+4 _.A+n 5.5.o+D n ++i.H.n+R y.[+*.*.*.[+[+*. + +*.[+[+1+*.1+*. +1+*.*.*.*.*.*.*.*.*.*.*.y.[+*.*.y.*.*.*.*.*.*.[+*.*.M *.M *.*.*.*.y.n+M n+n+M a n+M n+n+a M M z+z+z+a z+a n+z+n+n+M n+M n+n+z+n+z+z+z+n+N.z+z+n+n+z+M z+z+n+b z+n+z+n+a n+n+n+z+z+n+n+n+n+m.z+n+n+n+z+n+z+n+n+z+z+n+z+n+z+n+z+z+z+z+z+n+z+z+n+n+n+n+n+M n+z+n+n+n+m.M p.y.p.*.y.*.M n+n+M n+n+n+M M y.y.y.*.y.*.y.y.*.y.*.y.[+y.[+y.[+p.[+*.[+[+[+[+[+[+[+ +[+[+[+*.[+y.y.[+[+ +p.[+ +p. + + + +*. + + +*.[+ +[+[+ + +*.1+ +[+ + + + +5+ + + + +t. + + + +[+ +[+ +[+ + + + +t.t.Q.Q.0 }.0 /+H 2.J.G.b+J.i 2.R.'+L.k J U /+U '.l+,+X w E+H+a+@.f #+k U j [ d+v $+).$+v v v v d+P J s..+i.++8.(+(+8._.#.^.a+L.g g g * A.` f.7.A+;+b+A+r+! '+M.* f.F p+E A !.!.!.!.!.!.8 E p+b.:.f.A.u+g g A.f.4 ;+E.*+E.:+E.*+;+3+i 8+)+}+m.9+R m.*.t.Q.0 }. +p.q.++G.f+c.k+1 z+& O 2+S K.: ", "= >.p+>.E x.A A 8 8 8 8 8 8 8 8 8 A s+~.~.x.~.A x.s+E x.A u 8 8 A x.>.*+4 R.P.@.G+]+! ]+]+G o #.o o G ! o #.r+_.3+< < < < _.A+#.o ]+! ]+]+]+G G n.5 1 c+]+G G _.3.k '.j Q.0 0 j J #+! o A+;+3+3+D ( ( 5.5.5.< 5.5.n F F 3+< D 5.o+5.b+A+)+a+m.*.*.*._ 1+ +1+1+*.1+*.1+1+e.*.e.*.*.*.*.1+*._ *.e.*.*.*.*.*.*.1+y.y.y.e.*.[+[+*.*.*.1+[+e.*.1+*.*.*.M M y.y.y.a M n+M M n+a n+z+n+z+n+a z+z+z+z+n+n+n+n+m.M n+n+n+n+z+z+b z+!+b z+z+n+z+z+z+z+z+z+n+z+z+z+z+n+z+z+z+m.n+n+z+z+z+n+n+n+n+n+n+z+z+z+z+z+z+n+n+z+n+z+z+z+z+b z+n+n+z+n+n+z+n+n+z+n+z+z+z+z+n+n+M n+M M y.y.y.y.M n+n+n+M n+p.n+y.y.y.*.y.y.y.m.y.m.y.y.y.y.[+[+y.*.y.*.[+[+*. +[+[+[+[+y.[+[+*.[+[+[+y.[+[+ +[+[+ +[+[+p. +[+[+ + + + + +[+[+[+ +[+1+ +[+t.[+ +[+ + +1+ + +[+[+/+[+ +[+ + + + +[+ +t.t.t.t.5+Q.0 o.e+p.B r+G.o+o+G.G.++i 8+a+'+X C.U U l+U J k w E+f @.@.H+w R /+j [ v $+p ' p p $+$+$+v d+U X a+Z k+8.8.b+k+6 ^.3.h+C.,.w+7+,.,.Y.H ^.B.++++++_.! a+M.* ` f...>.E A A A 8 A A ~.= :+;+/.f.t t A.* ` 4 + ;+;+*+..E.*+3+F r+r+2.^.S.b R 9+[+*.t.Q.0 0 t.p.B.++G.o+D k+X.a 5+O |+K.: : ", "N N >.N = x.~.A 8 8 8 8 8 8 8 A A s+x.s+x.~.~.~.x.s+x.{ { 8 8 { E u.;+r+! G+]+o G G #.#.#.#.#.o o o o o ]+o r+A+n D 5.5.D D < < #.o ! S.G+(.G ]+5 5 5 c+~ W (+n o f X k k k k k X f S.o i 7.F _.3+n F 3+3+< n 3+n 3+3+< 3+D o+o+D b+A+)+}+z+n+y.*.*.*.*.*.[+1+1+*.1+*.*.[+y.*.e.*.y.1+*.1+*.*.*.*.e.e.*.*.*.*. +*.*.*.*.*.*.y.*.*.[+*.*.*.*.*.*.*.y.M M M M n+M n+n+R a n+M M n+n+n+z+z+z+z+z+z+n+n+n+n+z+m.M a z+z+z+z+b b z+!+z+n+z+z+z+z+n+z+z+n+z+z+n+z+n+n+n+n+n+n+n+n+n+z+n+n+a z+n+a n+z+z+n+a z+n+n+n+n+#+z+z+z+n+z+M z+a n+n+n+M z+z+z+z+z+b z+z+n+m.y.p.*.y.M M n+M M p.z+M M M m.y.y.y.y.y.y.M y.y.y.p.*.p.y.y.[+p.*.[+p.[+[+p. +[+[+[+*.*.[+[+y.[+[+*.[+1+p. +[+*. + + +[+[+[+[+[+ +[+[+t. +[+[+ +[+[+[+[+[+[+ +*. +*.*.[+ +[+[+ +[+ +/+ + + + + + + +Q.Q.Q.Q.}.0 t.#+^.J.G.f+f+o+*+b.J.4 r+2.R.a+s.9+C.,+C.- w f S.G+G+@.E+R U [ [ v $+p p p p p p 3 3 v [ ,+w .+Z k+8.8.k+i.H+s.- ,.7+7+7+7+,.L.s.}+! r+C+_.B.2.M.* h+* 8+F Y a.z N N a.= a.N p+b.:.f.q.` ` q.8+f.4 F ;+;+J.n *+*+n i 8+8+2.^.H+w #+z.R 1+ +t.5+Q.t.N.q.b+G.D c.k+1 M +.D.S ~+: [.", "N a.>.N E x.x.A 8 8 8 8 8 A A A s+= = x.x.s+x.x.x.x.x.{ 8 { A = :+J.#.i.G+6 G G _.r+#.G #.G #.o Z i.! o )+#._.< 5.9 9 ( 5.5.5.D 3+o ! @.@.1 1 5 T z.2 5 6 < c 5.i ! 3.f f X E+E+f S..+o B.r+r+r+o i o o o _.3+3+F 3+3+n D 5.5.D b+8.o H.R y.*.*.*.*.*._ 1+*.*.*.*.[+*.*.1+y.*.e.e.y.y.y.e.e.*.1+*.*.*.*.*.*.*.[+*.*.1+*.y.*.*.*.*.*.*.*.y.*.y.*.*.*.*.n+n+M n+a M y.y.y.n+y.M M M n+n+n+z+a z+z+n+z+n+n+n+n+n+M z+z+z+z+z+b z+z+n+z+z+!+z+z+z+!+z+z+z+z+n+n+n+z+n+z+n+n+b z+z+z+z+z+n+a n+n+z+a n+n+n+n+n+z+n+n+z+z+n+z+n+z+n+n+n+n+a n+n+n+n+z+b z+z+z+z+z+M n+y.*.y.y.M n+!+n+M z+n+n+M y.m.y.y.y.m.n+n+n+n+y.y.y.*.y.y.y.y.*.y.y.*.*.*.*.*. + +[+ +*.*.*.*.[+*.*.*.[+ +[+[+[+y. + +[+ + + + + +[+[+ + +*. + +[+1+ +*.*. +*. + +[+[+ + +[+ +[+ +[+[+[+t. +[+ +t. +5+t.Q.0 0 /+B B.G.o+f+u.f+:+:+*+;+J.7.7.i 2.R.h+m.k - #+E+f H+G+H+E+R _ j [ d+$+$+p p K K K p 3 3 v e+_ f @.i.B.++C+X.E+#+C.U 7+P 7+,.g '+}+@.i.#.G B.o R.a+* h+* R.4 n *+( 5.b.;+b.+ :.b.+ f.f.q.q.f.2.4 i F 3+n F 3+7.:.n J.C+R.R.^.! 3.H+E+z+n+*. +t.t.t.t.p.^.++c.G.8.k+!+*.s |+K.: [.[.", "= N N = = = x.A 8 8 8 A s+s+s+s+= N E E = E = x.x.x.{ 8 { x.N *+4 o i.Z G #._.r+G _.#.r+o #.B.o o ! ! ^.R.o r+< ( &.&.9 9 ( i+5.n #.3.E+5 z.k T w.& T 2 n._.n n _.F o 3.@.f 3.f ! ]+o o o o o o o ! ! ! o 8+o #.7.3+n D o+D b+n ++i.w #+R y.*.y.*.[+*.e.*.*.*.1+*.e.e.*.*.1+y.y.y.*.*.*.*.1+_ *.*.*.*.*.1+*.*.*.1+*.y.*.*.*.*.*.*.*.*.*.*.[+*.y.y.y.y.y.M n+n+z+n+M n+n+y.n+y.n+z+M z+M n+z+a z+z+n+n+M z+n+z+z+n+z+z+b z+z+z+!+z+n+n+n+z+b z+b b !+z+z+z+n+n+n+z+n+n+n+z+z+z+z+z+z+M z+n+M a z+z+z+z+z+n+z+n+z+n+n+n+n+z+z+z+z+n+n+n+n+n+z+n+n+z+n+b z+n+n+n+y.y.p.y.n+n+n+n+n+z+M M n+n+M M M M m.n+M n+n+M y.p.y.p.y.y.p.p.y.M p.[+[+[+*.[+*.*.*.[+[+[+*.[+*. +*.*.*.[+[+[+[+[+[+[+[+ + +[+[+t. + +[+ +[+[+*.[+[+*. +[+*.*. +[+*. + +p.[+[+ +[+ + + + +[+t. +t.t.t.Q.}.0 t.p.4+7.*+f+u.u.u.u.u.:+:+:+*+*+;+7.o q.'+#+9+9+X w E+f @.E+R _ j j.v 3 p 3 K p K p K 3 L j.y+j _ z+H.H+.+)+S.s.k w+7+j P P J h+a+]+! #.G i.R.a+` * g - - R.o A+n n < i 2.8+/.t ` q.` * '+8+2.r+i 7.7.7.3+3+i i r+7.7.r+a+R.^.)+X.G+@.1 b z+e. +t.5+ +p.B 7.G.c.b+6 P.$.w.|+: [.] [.", "= = = = = s+x.A 8 8 8 s+= = E = N N = E = = E x.{ A { A x.u.;+B.S.G+]+G k+#._._.#.o G #.o #.#.! o ! ! a+! o _.(+9 `.9 i+( i+( i+5._.3.X a $.& w.6+O w._ 5 ]+r+i 8.*+3+o R.S.! ]+o G _.A+#.#.o o R.o ! ! o o o i A+< 5.5.5.D 8._..+w y.*.*.y._ *.e.1+*.*. +*.*.*.y.*.*.*.y.*.M *.*.*.*._ *.e.*.*.e.*.*.*.*.y.*.*.*.[+*.*.[+*.*.*.*. +*.*.*.*.[+y.y.y.y.n+a n+z+n+n+a y.n+y.n+y.n+n+n+z+n+n+z+z+n+z+z+n+n+a n+n+z+z+z+z+z+z+z+n+n+n+n+z+n+z+z+z+z+z+z+n+z+n+n+n+n+n+n+n+n+z+z+z+z+z+z+n+n+n+z+n+n+z+n+z+z+z+z+n+z+n+z+z+n+n+M M a n+n+m.n+n+n+n+n+z+n+z+n+z+n+n+y.y.n+p.y.n+M n+n+n+z+M n+m.y.p.y.M M n+M m.n+z+M y.M y.y.y.y.y.*.*.y.y.*.[+*.[+[+[+ +p.1+[+*.[+*.*.[+[+*.[+*.*. +[+*.*.[+[+[+ +[+[+ +t.[+ +*.[+ +[+[+[+*.[+ +*.*. +[+[+ + +[+[+[+ +[+ + +t.t. + +t.5+l+0 }.0 t.H )+b+*+f+9 z u.u.>.>.u.u.u.f+:+G.7.2.R.s.Y.,.k - X - s.s.R /+j j.j.$+3 p K p K K 3 $+v w.0 Q.'.$.y.k 9+L.H L.C./+P [ e+j J M.! Z Z #.k+6 ^.3.h+g g g g ` r+7.< n 8._.^.a+` * t * * u+'+^.#._.3+3+3+++#.#.2.R.R.R.2.o 3.a+a+o i.i.i.X.P.b M + +5+t.p.N.q.C+8.++6 P.5+O S [.|.|.} ", "= = x.s+~.x.A 8 8 A A s+N >.s+x.N N x.= = = x.{ 8 { x.N :+7.R.a+G+! Z #.#._.#.#.#.r+#.#.#.#.B.o i.! ! ! ^.o _.D &.z ( 5.5.i+9 &.5._.G+z.z.k $.0 O |+|+w.,+w G+#.< E.Y 4 o ! ! G _.8.< n < F o ! ! ! 8+R.o o r+_.3+5.5.5.b+< r+a+w R y.*.[+*.*.*.*.*.*.*.y.*.*.*. +*.*.M *.*.*.*.*.y.y.y.*.[+*.*.y._ *.*.1+1+ +*.1+1+[+*.1+M 1+*.*.y.*.*.[+*.y.y.*.n+n+M n+z+z.z.n+z+n+M n+y.n+y.M n+n+n+z+z+a z+z+z+n+M n+n+M n+n+n+n+z+z+n+z+z+a n+n+z+z+z+z+z+n+z+a z+n+n+n+n+M n+z+z+z+z+!+z+z+n+z+n+n+n+n+z+z+z+z+n+z+z+a n+n+n+n+n+z+z+z+z+n+z+n+n+n+n+n+z+n+n+n+n+M y.M p.y.y.M m.y.z+M n+n+M m.y.y.y.*.m.n+n+n+b b z+n+n+n+M p.p.y.y.y.y.p.M M y.*.*.*.*.*.*.*. +[+ +*.[+*.1+p.*.*.[+ +*.*. +[+*. +[+ +[+ +[+[+ + + + +[+ +[+[+ +*.[+ +[+[+*. +[+[+ + +[+[+[+ + + +t.t.t.5+5+Q.Q.}.0 C.N.7.G.f+>.>.>.>.= = E E E E = z :+G.C+^.s.C.w+w+,+,+,+J ,+U j [ [ v 3 p 3 p p 3 3 3 v 0 '._ *.M n+z+H.#+L.L.C.J U 7+j P U Y.f ! G k+++8.B.G+M.X Y.Y.g * a+o _.J.< 3+B.R.a+* * u+L.g * 3.o _.3+< D < 8.#.^.a+M.- g L.s.#+h+a+S.i.i.Z X.G+b y. +t.t. +*.p.B )+C+6 c+z+5+|+K.[.k.7 k.", "E x.x.x.A 8 A A s+s+s+>.u.z E = N E E E E x.x.{ A x.>.*+4 ! E+S.G+o B.o #.o #.#.G r+G #.#.#.G #.#.#.r+r+_.7.< 5.5.n < < (+5.{+z 5.G ]+1 1 G+G+5 j |+].L 0 _ H+#.b+f+E.F i o G G 8.< D 5.5.n F o ! ! o o o r+A+< D 5.>+5.++#.@.n+y.[+,+*._ [+e.*.*._ 1+*.y.M *._ *.*.*.*.*.*.*.*.*.*.*.*.*.*.[+*.*.1+*.*.*.*.*.*.*.1+*.*.1+*.*.*.*.*.*.*.*.*.*.M *.y.m.n+z+n+z+z+n+M n+a n+n+n+n+M z+z+z+z+b z+z+z+z+z+n+n+n+z+n+z+z+n+z+n+a n+n+M M n+M n+n+z+z+n+z+n+n+n+n+n+n+M n+z+z+z+b z+z+z+n+M n+m.n+m.n+z+z+z+n+z+z+z+n+n+n+n+n+z+z+z+z+n+z+n+n+n+n+M n+n+n+n+n+n+p.m.y.p.p.M p.n+m.n+n+n+y.n+y.y.y.y.y.y.n+M n+m.n+M n+n+M M n+y.n+n+y.y.y.*.y.y.[+[+[+[+ +*.[+[+*.*.[+1+1+[+ +*.*.*.*.*.[+ +*.[+ +[+ + + +[+[+ +[+[+ + + +[+ +[+[+[+[+ +[+ +[+[+[+[+[+ +[+ + +5+t.t.t.t.t.0 e+0 0 p.q.A+*+f+>.u.>.>.N E x.x.{ { { 4.z *+A+2.'+C.l+P l+U '.'.'./+j j [ d+v $+$+$+$+p $+j.j ,+_ b E+H+! B.B.B.4+'+L.,.J P j j l+- w S.i.G k+W k+G+'+L.J ,.g M.! #.++8.A+++Z a+'+* h+u+- g M.R.]+_.b+D 5.5.b+G f X C.C.U ,+C.C.- '+a+i.i.B.6 X.z+M +t.t. +[+p.N.N.4+X.B a & |+: k.7 7 7 ", "= x.~.8 8 A A s+= = = N >.= = `.N >.= E x.{ { x.E u.*+i )+@.! i.#.++_.Z ]+]+#.#._._.A+_._._._._.< < < < < n n n n _._.W < < {+9 < G ]+(.G W W < X j.].x+o.,+H.k+J.5.*+;+i G _.W < D c i+( 5.3+i R.o o r+_.A+< n 5.D D b+B.H+R [+y.*. +1+1+_ + +*.*.y.*.*.y.M *.*.*.*.*.y.y.y.y.*.*.y.*.1+[+*.*.*.y.*.*.a *.*.y.y.*.*.*.*.*.*.*.*.y.*.*.*.*.y.y.M n+n+a z.n+n+n+n+n+R n+M M M M n+n+z+n+z+n+z+z+!+z+z+n+n+z+z+z+n+z+a z+n+n+M M n+m.M m.n+M n+#+n+z+n+n+n+n+M n+z+n+n+R z+n+z+n+#+n+n+n+n+y.z+n+n+n+z+a z+z.n+z+n+z+n+z+z+z+z+z+z+z+n+M n+M M n+n+n+M m.m.n+M n+p.n+n+n+m.m.n+y.y.n+y.y.y.y.[+m.m.M n+n+z+n+n+n+y.m.y.y.m.y.!+M p.M p.*.p.[+[+ +[+[+ + +p. +[+*.*.1+*.*. +[+[+[+[+[+ + +[+[+ +[+ + + + +[+ + +[+[+[+ +[+[+ +[+[+*.[+[+ +[+ + +[+[+ + + + + +t.t.t.5+t.}.0 /+p.2.G.f+u.u.>.z = E x.x.{ A 8 8 { -+u.;+2.'+C.7+[ e+j l+'.'.0 j [ 0 j.d+d+d+F+[ d+[ e+_ R w P.G+6 ++b+D A+B.R.'+L.J ,.U J k k s.S.]+Z G k+#.S.w - J ,.Y.'+S.i.++++++k+i.E+- g g - u+- M.! #.++< D o+D (+k+H+9+/+j j j l+/+,.h+R.)+B.6 i.X.b [+t.0 Q.Q.Q.t.p.p.N.b n+1+I.|+: k.B+7 |.", "x.x.A 8 A A E = u.>.z N z E = >.>.z `.x.{ ~.x.z :+;+r+o i.i.#.8.(+< ++B.]+6 G k+_.< b+J.++C+A+< D i+( i+5.c 5.5.< _._.#.W j+5.< (.(.n.; W c ( ( ! j j.j.0 J E+o A+n b.3+#.G W < j+(+( 9 {+( n 4 o o _.3+n 5.5.D o+D ++B.}+n+R [+[+*.[+[+ +[+*.*.*.*.*.*.*.*.*.a a *.*.*.*.*.*.M _ *.*.y.*.1+*.*.*.M *.*.*.*.*.*.y.*.*.*.*.*.*.M *.M *. +*.y.y.n+M a n+y.a z+n+n+n+M M a M n+z+M n+z+z+z+z+z+z+b z+z+z+z+z+z+n+z+z+z+z+a n+z+z+M n+n+n+n+n+z+n+z+m.z+n+n+n+n+M m.n+n+z+z+z+n+z+z+n+n+n+M n+n+n+z+z+z+z+z+a n+n+a n+z+n+z+z+b z+z+z+z+z+n+n+n+M M M n+m.M p.n+M M y.n+M M n+m.n+n+y.y.p.y.p.[+y.y.m.M M M n+n+n+y.y.y.y.y.m.y.n+M M M p.y.*.*.*.*.p. +*.*.*.*.*.*.*.*.*.*.*.[+*.[+*.*.*.p. + + +[+[+[+[+t.[+y. +[+ +p.t.[+[+[+[+t.[+t.[+[+[+ +[+[+ +[+ +[+t. +t.5+t.t.0 e+e+p.'+7.*+f+9 z >.>.= E x.A 1.8 8 !.u 4.u.G.C+'+,.7+d+[ e+e+'.'.t.'.j j 0 [ U ,.J ,+'._ _ X P.G+6 k+8.(+o+>+G.++)+R.h+Y.J /+,+k X s.S.G+G+i.i.i.}+L.,.l+,.Y.a+)+B.++8.++B..+#+C.J Y.V - - f ! G W 8.(+D D (+k+1 9+j [ d+e+j '.k w a+i.B.k+k+X.b t.[ y+y+e+[ 0 l+/+m.n+*.5+w.|+: 7 d B+7 ", "x.A { A x.s+= :+f+>.= >.>.N E = N E x.4.x.x.N :+3+#.B.#.#._.++b+>+5.A+i.i.i.G ++b+D f+( ;+4 ++< i+9 9 i+5.i+( ( n _.o o ]+G G 1 5 5 5 c+W 5.{+E.o s.j 0 '.k '+o C+3+n F #._.8.j+< < (+5.5.E.n 3+i _.< D >+( >+D b+A+B.H.R M *.*.*.*.1+*.*. +1+1+*.1+*.M *.a *.M *.a *.*.*.*.a *.*.y.*.*.*.y.y.*.M M a a M y.M y.M y.y.M *.M y.y.*.*.*.y.y.y.M *.y.n+y.n+n+n+a n+M M n+n+n+n+a n+z+z+z+z+z+z+b z+b z+b z+z+z+z+z+!+z+z+n+z+a n+n+a n+n+M N.n+z+n+b m.n+y.n+n+z+n+n+z+n+n+R n+n+n+n+n+n+m.n+n+n+n+n+z+n+n+z+M n+n+n+n+z+b b z+b z+z+n+n+M n+M n+z+p.y.y.n+y.n+p.p.p.n+n+p.y.m.p.y.y.y.y.*.y.[+[+y.y.n+n+n+M M M n+y.y.y.y.n+y.n+n+M M M M *.[+[+[+*.p.*.*. +[+*.[+[+p.*.*.*.*. +[+*. + +[+*.[+ + + + +[+[+ + +p. +[+ + +[+[+[+[+[+ +p.t.[+[+[+ +[+*. + +[+ +t.5+t.t.t.Q.0 t.p.q.++f+u.N >.>.N = E { { 8 u 8 8 8 x.z *+4 * ,.e+d+d+P 0 j 0 '.t.'.j j l+Y.w #+z.R y.R P.]+#.8.b+D o+f+f+D A+2.a+'+- J ,+J k R w E+f H+S.S.3.s.k w+7+w+L.a+B.C+8.b+++k+G+#+l+7+m J g k L.! B.W 8.8.(+c.k+G+E+[+[ j.j.v d+j [+#+H.X.i.k+k+X.n+t.y+3 3 3 <+v j.[ '. + +& O |+: B+q q 7 ", "{ 8 A x.= >.p+*+:+u.>.u.z N -+E E -+x.x.`.u.*+3+r+B.#._.++_.8.D >+*+#.G+.+]+i._.G.9 E E *+7._.D 9 &.9 5.i+c i+( 5._.! G+3.f z.T $.T z.^ 6 (+5.n #.o 3.X R X a+2._.3+3+7._._._._._.< < 5.5.n n i _.3+>+9 ( 9 ( D A+]+s.m.y.[+*._ +_ e.*._ _ 1+e.*.*.y.*.*.a e.*.a *.*.M *.*.a M *.*.*.1+*.*.y.*.M *.M a M M a M M M y.M y.y.y.*.y.*.y.y.*.y.y.y.y.a M M a n+a M n+y.n+y.M n+n+n+z+n+n+n+z+z+z+z+b z+b z+z+z+z+z+z.z+z+z+!+n+n+z+M z+z+m.z+b N.n+n+m.n+n+y.n+n+n+n+z+n+z+n+n+n+n+n+M n+M M z+z+n+n+n+z+n+n+n+n+M n+z+z+z+b b z+z+z+n+n+M m.y.n+y.n+n+m.n+y.n+n+M n+p.M n+y.y.p.m.y.y.n+M y.m.[+y.9+y.y.n+n+m.M y.y.y.p.y.y.M p.n+y.y.p.M p.y.*.*.*. +*.p.*.[+[+[+*.1+*.*.[+*.[+[+ +p.1+[+ +*.[+ +[+ +[+[+ + +[+ +[+[+[+t.[+t.[+ +[+ +[+[+ +*.[+ +[+ + + +5+t.t.t.Q.0 Q.0 /+H 2.G.f+z z >.>.N s+x.x.{ 8 u !.!.{ E u.*+4 4+m e+d+[ P e+'.'.'._ ,+/+U ,+M.S.}+P.b z.b P.6 8.(+D o+u.>.z f+G.i ^.'+Y.C.,+_ U _ k R X X w w #+k /+P e+,.X a+B.++A+b+b+8.i.w w+e+P 7+Y.J C.}+Z ++W 8.8.(+; P.R t.y+L 3 3 v e+_ b E+1 .+)+i.H+y.0 j.3 {.K l K 3 3 [ o.o.w.x+K.[.B+q Q q ", "A A E = u.:+:+*+:+u.>.>.z N E x.{ x.E >.:+n C+#.#.#._.A+_.++++(+D ++G+@.G+G+)+k+D `.-.4.>.F _.D 9 9 5.< < c i+( 5._.3.E+z._ w.w.<.w.$.z.@.Z B.B._.3+4 R.3.a+! _.3+3+n _.3+_._.G o o _._.3+n 3+3+3+5.( 9 z ( D ++)+E+M *._ 1+ + +[+e.*.[+*.1+1+*.*.y.*.a *.*.*.*.*.*.*.y.M M *.a *.M e.y.*.y.*.y.y.n+*.R M y.M M M n+n+M a M y.M *.y.y.y.y.*.n+M y.m.M M y.M M y.*.y.y.n+n+n+n+a a n+n+n+z+z+z+z+z+z+n+z+z+b z+z+z+z+z+z+z+z+z+z+z+n+#+z+z+z+n+b b z+m.n+n+n+z+z+z+z+z+z+z+n+n+n+y.n+M z+z+M z+n+z+n+z+M n+M M n+n+n+n+z+z+z+z+z+z+z+n+y.M n+y.m.y.p.M y.n+p.M p.M M p.n+n+y.p.y.m.p.y.y.y.y.y.[+y.y.n+y.y.M M y.y.n+M n+n+n+M p.!+M M y.M *.p.[+p.*.*.[+ +p.*.[+[+!+ +[+*.[+*.*.1+p.1+p. +[+ + + +[+ + +[+p. +[+ +p.t.[+[+1+[+[+ +[+ +[+*. +[+1+[+[+t. + +t.t.t.t.Q.0 e+p.4+7.*+u.>.>.z >.= E ~.{ 8 8 !.!.!.{ E p+;+2.* m 7+P 7+P l+l+/+_ ,+k k k C.'+! G+1 5 5 z.P.Z (+D D o+f+u.= 9 *+7.2.'+#+J '.'.'.'.'./+_ _ k J k J 7+l+7+w+#+H+)+C+A+b+;+8.i.E+/+e+d+P U /+l+- a+i.k+k+8.8.k+b _ j j.L 3 3 3 v l+R H.H+1 X.X.5 +y+<+{.m+m+F.F.F.3 3 j.D.L ]. .|.d 0.Q d ", "~.x.= p+u.:+*+*+:+u.>.u.>.`.E x.E N u.:+J.#.B.#.#.C+++++_.++#.++B..+H+H+.+X.Z k+>+`.{ E >.n A+D 5.n _.G W < (+5.3+o f z.$.w.6+|+> > O w._ R P.i.8.G.G.7.r+_.< D 5.5.5.5.5.3+i ! ! o o i 4 4 3+n 5.f+z 9 9 5.3+]+w n+y.*.1+*.*.*. +*.e. +*.[+1+ +*.*._ e.*.y.y.*.y.*.a y.y.*.e.M 1+y.*.y.y.y.*.*.*.M M M a a n+a M a n+n+z+M M M y.*.y.M M M n+n+M y.n+M y.n+y.y.n+y.M a M M n+n+a n+n+n+a z+z+z+z+z+z+z+z+b z+z+z+z+z+z+!+z+z+z+n+z+z+#+b b b z+z+z+n+n+n+n+z+z+z+z+z+z+z+n+n+n+n+n+n+n+n+n+z+z+n+n+n+M M n+a n+n+n+z+z+z+n+z+z+n+n+z+n+y.y.y.m.M n+n+n+y.n+y.n+y.y.n+m.m.y.[+y.y.*.*.y.[+y.y.y.m.y.y.n+n+m.n+n+y.n+n+M n+n+n+y.y.y.n+y.M M p.*.y.*.p.*.p.1+*.*.[+ +*.*.*.[+[+[+*. +*.*. +*. + + +p. +[+ +[+ +[+[+[+[+ +*. + + +[+t.[+ +*.*. +*. + +[+[+t.t.t.5+e+}.0 t.p.q.J.f+u.z >.>.>.= x.{ 8 !.!.u !.!.{ -+p+;+4 '+V 7+7+w+,.U /+U C.R #+#+X R a+B.k+6 G+1 2 5 G+8.D D G.*+:+p+:+*+7.2.` L.C. +t.'.'.t.'.j j t.j j l+U l+j k s.@.i.k+k+++8.++)+w ,+[ v v d+j 0 j y.w H+G+)+B.6 H.[+j j.L 3 v x+v [ _ z+H.P.X..+b 5+y+].{.m+@ m+m+l.m+{.L l ]. .l.|.Q 0.0.q ", "E = u.:+:+f+:+o+f+z E N E E E E z f+;+7.G B.#.A+++A+n n A+B.)+G+@.@.@.)+Z B.B.++D f+E = u.G.i A+i o ! ]+_._.< _.]+3.X _ j O x+].].|+S O w.$.#+G+++D E.G.n 5.( 9 9 i+9 9 ( 5._.8+3.3.! 8+o r+3+n ( z 9 ( D A+.+b n+a [+*.*. +_ 1+y.1+1+*.1+1+*.*.e.a *.y.y.*.*.*.*.*.*.*.a y.y.*.*.*.*.y.*.y.M y.y.M M a z+n+M n+n+y.a a a a n+n+M n+n+n+M n+a a M n+a M M y.y.M M n+n+y.n+n+R n+n+a M n+n+a n+n+z+z+z+z+z+z+z+z+z+z+n+z+b n+z+z+z+z+b z+z+b b b z+z+n+n+b z+z+b b b b b z+z+z+z+M M M n+z+z+n+n+z+n+z+z+z+M M n+n+n+n+n+n+b z+z+z+M n+y.y.M n+M n+y.y.y.M p.n+M y.m.n+y.m.p.n+m.[+p.y.*.*.y.y.y.y.y.n+M n+n+M n+n+m.n+z+n+n+M y.!+M M M y.M M p.*.p.*.p.*.p.*.[+p.[+ +[+[+ +[+[+[+*.[+[+ +[+*. + + +p.[+[+[+ +p. +[+[+ +[+ +[+ + +[+ +[+ +[+*. +[+ +t. +[+t.t.t.5+e+0 w+B 2.G.f+u.z >.u.N E x.A 1.8 !.!.!.u { `.u.;+r+` Y.,.,.J U U J U w+k - w b s.3.B.W k+(.n.5 5 1 ++D G.b+J.:.;+Y + 4 q.* g J ,+'.j Q.'.0 0 j j e+j 7+P U /+C.b H+)+6 k+k+++k+1 9+l+v $+$+v j.j.w.Q.Q.*.y.n+#+H.#+/+0 j.3 3 L x+L j.0 [+n+#+b P.z+Q.<+3 m+m+@ @ @ m+m+F. . . . .l.7 d . 0.q ", ">.u.:+o+f+:+*+*+>.z E E x.E z u.*+7.#.i.i.#.k+_._.8.G.o+++]+4+@..+i.k+++(+b+J.C+A+G.o+o+:+*+o o ! ! ! S.o o o ! 3.E+X _ w.j.x+].].l K.|+x+w.R @.k+b+*+5.n ( &.) &.{+&.{+z ( F ` M.M.3.o o 8.n ( 9 ( ( 5.C+S.#+n+y.*.*.*.e.1+[+ +y.*. +1+1+1+*.*.e.a *.a *.*.*.a *.*.*.*.*.*.y.y.*.y.y.R y.y.M y.R y.n+M a n+y.y.n+n+z+z+z+a M y.M M a z+z.M M M a n+M M *.y.y.*.y.y.n+y.M a M M n+n+a n+n+M M n+z+n+n+N.n+z+z+n+z+z+n+b b z+z+b z+z+z+b z+z+b b z+z+m.n+n+b z+b b z+b z+z+z+z+n+z+z+n+n+n+z+b n+z+!+z+n+z+n+n+n+n+n+n+z+n+z+n+n+n+n+n+n+y.M n+y.p.n+n+p.n+p.n+n+y.p.n+M y.y.*.y.y.y.y.p.1+[+*.*.y.y.n+M M n+n+n+z+n+z+n+n+z+n+n+y.y.p.!+[+p.n+M !+y.!+*.M *.p. +*. +p. + +[+[+ +[+[+[+ +*. +1+*. +[+ + +*.p. + +[+ + +[+[+[+ + +[+5+[+ + +[+ +[+ +[+ +t. + +5+t.0 }.e+p.4+7.*+u.z z >.>.N E ~.{ u 8 !.8 !.8 x.z *+J.2.q.h+- C.- k C.k C.J J Y.- #+s.! B.k+G (.n.5 2 1 k+b+D J.7.4 f.f.f.t * g ,.w+/+'.j 0 '.j 0 [ j e+P P 7+l+j '.9+E+@.)+6 k+k+k+P.[+0 j.3 l 3 L v j.Q.w.w.w.I.0 [ '.j d+j.3 3 v x+x+D.w.Q.Q./+[+[+[+Q.D.l .@ @ @ l.@ l.m+F. .l.[.7 d q 0.. Q ", "u.u.:+:+f+f+f+f+u.E 4.E E z u.*+i )+! B.#.#._._.++8.n b+B.@.i.X.i.6 8.D f+u.G.7.^.B.3+b+D ;+2.^.R.S.3.S.3.3.3.M.E+X k _ [ w.x+|+].].].].x+w._ H.^.7.J.n 5.9 q+) &.9 9 9 &.( 3+* - M.R.o A+n i+9 ( ( n r+@.#+y.*.M *.*.*.*.[+*._ +*. +[+_ *.1+*.e.*.*.e.y.*.*.*.*.[+*.*.*.[+e.y.y.*.y.y.*.*.y.M y.M M M n+M M y.M z+M z+n+n+M n+n+z+#+a n+n+n+z+n+a M n+y.y.*.y.y.n+M n+n+n+R n+y.M y.M n+m.z+a z+z+n+n+n+n+n+n+n+n+n+n+n+m.N.n+n+N.b z+N.#+z+N.n+b n+n+b z+z+b b b z+b z+z+n+z+n+n+z+n+n+z+z+z+b n+!+n+n+n+M n+n+z+n+n+n+z+z+z+n+!+n+y.n+y.y.y.y.y.!+y.y.n+y.p.n+y.y.n+y.m.y.[+p.[+[+*.p.*.y.y.M n+n+n+n+z+z+n+z+b n+!+n+n+z+n+M y.*.n+M n+y.p.y.p.p.!+*.p.*.p.[+*.*.*. + +[+ +[+[+[+[+*. +*. + +[+*. +*.*.[+[+[+*. + + +[+ + + +[+[+ +[+[+[+ + + +[+ + +t.t.0 }.e+t.p.^.;+f+9 z >.p+>.= x.{ 8 !.!.8 u 8 -.x.z *+:.2.a+M.X w X w X - - k Y.- L.#+w ! Z 6 X.1 5 2 2 5 6 ++G.b+7.2.` * * g V ,.m U 7+j j 0 0 0 j j e+j P e+U l+'.j $.R n+H..+.+.+X.P.t.[ <+l K 3 3 j.o.w.+.w.I.o.D.<+j.j.j.$+j.$+3 j.D.j.w.w.w.0 o.y+<+v 3 r.m+m+l.@ @ l.@ l.l.l.l.l.} q Q . 0.0.", ">.z :+f+:+f+p+u.`.`.E `.N u.;+A+o )+i.B.#.#.C+o #.++b+#.X.G+i.6 6 6 8.>+9 z :+n ^.^.B.A+b+3+o ! ! ! ! S.S.S.f f M.w R _ j 0 j.x+L L L L L j./+- a+r+7.3+D 9 ) z E.5.5.5.5.E.i - - 3.o A+D ( ( ( 5.n C+a+n+M y.y.y.*.*.*.*.*.e.*.*.*.1+e.1+y.e.*.*.*.M *.*.*.y._ *.[+1+[+*.y.1+*.y.M y.y.y.y.M M y.y.n+*.M z.M y.a z+n+M M n+M n+n+n+z+n+z+z+z.a z+a M M M y.R y.a n+a a a a y.n+m.n+m.y.n+n+n+z+n+z+n+n+n+n+n+M n+n+z+b z+z+z+n+#+z+n+z+z+n+z+b n+b m.z+z+z+b !+z.H.z+b z+!+z+n+z+z+z+z+#+z+#+z+b z+z+n+z+n+n+n+n+z+z+b z+z+n+z+!+n+n+n+n+n+n+y.n+p.m.n+M n+M !+y.n+y.M y.p.y.y.[+[+[+*. +*.y.p.M M n+n+M a n+z+z+b n+z+z+n+n+z+n+n+n+M !+p.M !+n+n+n+p.M y.y.p. +[+[+[+[+[+ + +[+ +[+[+[+[+ +p.1+*.*.[+[+ +[+ + + + + +[+[+ +t. +[+5+[+ +t. + + +[+t. +t.t.t.t.}.0 /+N.C+G.>.z z u.u.>.E ~.{ 8 u !.!.u { { N f+G.7.q.'+s.w X b X b X - L.- M.h+s.s.! k+6 c+5 a T a 5 G+6 J.G.J.2.q.* g Y.,.,.,.U P P P [ P [ e+j j P 7+P U ,+'.t.Q.$.$. +R m.#+H #+t.y+v K l j.[ o.j $.e.e.$.t.0 j.j.j.j.j.L v j.j.w.Q.I.w.O O D.x+]. .{.m+l.l.m+l.@ l.l.@ l.l.} 7 } d q . . . ", "z >.f+f+f+>.z N E E z u.o+J.i i.i.B.#.#.++++++++k+6 B.i.i.i.X.i.i.i.8.>+9 f+o+J..+.+B.C+A+i B.i.o i.! ! ! ! ! a+f E+E+X _ _ 0 [ j.v L v v 0 j ,+'+)+f.#.n ( E.E.n 3+< < 3+i ` g 3.o A+D ( ( ( D b+i.}+n+M *.*.1+*.*.*.*.*.1+*.*.*.*.*.e._ *.y.*.a *.M *.M *.*.y.[+e.[+*.*. +*.*.*.y.*.*.*.R y.*.y.y.M a R *.M M y.a M a n+y.M y.n+n+z+a z.n+n+z+n+y.y.*.*.y.y.n+n+a n+z+n+n+n+y.y.y.M n+n+n+z+z+b z+n+z+n+M M n+n+n+z+n+N.z+#+N.z+n+z+z+z+z+n+n+n+n+z+n+z+b z+b b z+b z+b z+n+z+z+z+z+z+z+b z+b z+z+z+n+n+n+n+n+z+n+b z+b z+z+z+n+n+n+n+y.n+n+n+M y.n+n+n+n+n+n+p.M y.n+n+y.y.p.y.y.y.y.p.y.*.y.y.M M n+n+z+n+n+#+z+b z+z+z+n+!+n+n+p.m.M n+z+z+n+!+y.!+p.M [+!+p.*.[+ +[+[+[+ +[+[+*.[+*. +1+*. +[+[+[+*.*.*.[+ + +*. +t.[+ +t.5+[+t. +[+ +[+t. + +t.t.t.5+Q.0 }.0 p.q.J.f+>.z u.u.p+>.E ~.8 !.8 u !.8 { E >.:+:.f.a+'+#+X R X b E+w X s.M.M.}+s.H..+Z 6 1 5 2 T T z.X.i.C+J.r+q.'+* g ,.Y.m 7+U P j j P [ [ P [ e+P P j w+k k $.$.I.I.w.I.I.0 0 [ [ v 3 {.3 [ '._ _ b E+b z.y.Q.j.j.j.j.v v j.j.j _ _ *.5+w.o.x+]. .m+m+l.@ @ @ @ l.] @ ] ] ] ] ] } q Q 0.0.. ", "u.u.:+f+f+z `.E `.N f+*+J.k+B.#.#._.A+J.;+J.< 8.++G )+G+G+i.@.X.X.X.C+G.G.G.G.J.^.)+#.k+++++#.B.B.G o i.i.i.]+i.! @.E+E+X k _ j Q.[ [ j.j.j /+9+'+R.R.o 3+n n F o o 8+o 8+M.h+s.3._.D ( ( i+*+++)+w y.y.*.1+[+e.*.a *.*.*.*._ *._ *.y.*.*.*.*.e.*.y.M *.*.*.*.[+[+*.*.*.*.*.[+*.*.M y.y.*.y.M *.y.y.R M M *.M y.y.R y.y.M n+y.M n+R n+y.M a n+z+M y.y.y.y.y.M n+n+z.a n+a z.M M n+n+a n+n+n+z+z+b z+n+z+z+n+y.n+n+n+n+n+z+z+n+n+b n+n+n+n+N.n+n+m.m.z+n+z+z+z+z+n+z+n+n+#+z+n+n+z+z+z+b z+z+n+z+z+n+z+n+n+n+n+z+z+z+z+z+b b b z+z+z+M n+!+n+n+n+n+n+p.n+n+n+n+M n+n+p.y.M y.y.y.y.*.y.[+[+p. +y.y.y.M M M n+n+z+n+n+n+n+n+n+n+n+n+n+n+n+n+n+z+z+z+n+M y.y.M p.*.*.*. +[+[+[+ +p.5+[+ +*.*.*.[+[+[+[+[+ + + +[+ +[+ + +[+ + +t.p.t.t. +[+t. +[+t. + + +t.t.t.t.0 }.e+p.)+G.u.z z >.f+a.N x.{ 1.8 !.!.1.{ x.z :+;+r+q.h+L.R R k R R X w X h+3.3.a+3.a+.+i.X.1 2 *.& T *.5 i.C+A+i q.'+L.g ,.,.m J ,.7+P P P P [ F+P [ [ P 7+J L.E+R M $.Q.0 w.O L L 3 3 l {.{.3 l+y.R b E+G+G+X.P.y.0 j.L j.j.j.j.[ ,+X P.b a e.O U.K. .l.l.l.@ l.l.] l.l.@ l.@ ] } d } d q Q 0.. ", "N >.>.u.z N = z >.f+*+A+B.B.B.#._.++J.J.3+b+b+++G G+@.P.H.P.H+P.H+@.X.)+k+++A+r+2.C+6 i.#.B.#.G k+k+G #.#.#.#.o ]+]+]+@.5 f X _ '.j j j j l+/+9+3.* M.8+4 F F /.o ` h+- - g M.S._.n >+f+>+5.3+! w y.*.e.[+_ 1+*.e.*.*.*.*.*.*.*.y.*.*.*.*.a *.M *.*.*.*.*.*.[+[+[+*.*.*.e.1+*.y.M *.M y.M *.n+y.y.M M M *.a y.y.*.*.y.y.y.y.y.n+M y.M n+n+n+a M n+y.[+y.y.y.R R n+n+z+a n+M M R y.M n+a z+z+#+#+z+b b n+n+n+n+M M z+z+z+b z+b b N.z+z+n+z+m.z+n+n+z+n+n+n+n+z+z+z+m.n+z+n+z+M n+z+n+#+z+z+z+z+z+n+z+n+n+n+n+n+n+n+n+N.b n+n+z+z+z+z+n+n+n+m.!+z+z+n+n+n+n+n+M n+n+M y.M n+M y.y.*.y.p.y.y.y.y.y.y.y.M y.n+y.M n+n+n+z+z+n+n+M n+m.n+n+n+n+z+z+M z+n+n+n+p.*.!+*.*.p.5+p. +[+ +[+ +p.*.[+ +[+ +[+ +[+[+[+[+ +*.5+p. + + + +t. + +t. + +t.[+t. +t.t.t. +t.t.5+0 }.0 t.B C+o+>.z z u.p+p+= x.A !.!.8 8 8 { `.:+G.4 ` h+C.C.J C._ k k z.X - s.M.}+a+G+]+B.Z G+E+a & w.w.& z+H+C+J.7.q.'+g ,.,.J J J J m U j P [ P [ [ [ P [ w+C.f S.f 5 a a 1+$.I.D.].l l l {.{.3 w+#+E+H.! i.C+++i.z.'.j.v L v j.d+/+s.@.G+1 P.z+& s l .l.@ l.@ l.] l.@ l.] ] ] |.] ] d d q Q Q Q ", "E E z E E `.E u.f+G.++k+#._.A+A+J.b+D 5.D n < k+C+Z H+w b H.}+H.}+w b B X.)+i ++B.#.B.B.B.i.B.B.i ++#.#.Z Z G #.#.]+]+! @.f f X k _ U l+l+w+C.L.* h+M.! 4 4 /.8+` - m U k X ^._.D >+i+( D A+a+n+R M y.1+e.1+1+*.e.e.*.*.*.*.y.*.*.a *.a *.*.*.*.*.y.*._ [+[+y._ [+*.*.y.*.*.*.*.M y.y.m.y.y.a M *.M *.a y.*.M M y.y.*.y.y.y.y.n+n+n+M n+R m.n+M n+y.y.*.M y.M M M z.n+M n+n+y.M m.M n+n+z.z+a z+z+z+z+n+n+M n+n+n+z+z+z+b z+z+z+z+z+z+n+n+n+n+n+n+z+M n+n+n+n+z+z+n+n+n+n+z+n+n+z+n+n+b m.z+n+z+n+M n+y.n+y.n+z+z+n+n+z+b n+z+n+a n+n+n+z+N.n+b !+n+z+n+n+n+y.M p.n+m.n+z+n+m.n+y.p.*.y.y.y.*.[+*.y.*.y.y.m.y.[+n+y.y.M M n+y.y.n+n+n+n+n+n+z+n+z+z+z+y.M y.*.[+y.*.*. +*.[+[+p.[+[+*.*.*.[+[+[+[+ +[+[+ + +*.[+5+ +p.5+[+[+t. + + +t. +t. + + +[+ +5+t.t.5+e+}.e+p.4+J.f+N E >.u.u.>.E x.{ 8 u 8 1.{ x.E *+J.2.h+,.m l+w+w+/+,+,+k X R w E+f .+i.#.++++6 E+1+w.> |+D.0 9+^.;+J.2.` H Y.,.,.Y.Y.J J m l+P P P [ [ [ F+[ ,.s.@.1 @.@.P.5 b a $.o.L l l K {.{.3 7+}+@..+o r+A+J.k+z+t.o.$+L $+j.v k }+Z 6 X.G+P.1+s U. .l.l.l.l.l.@ l.l.] l.l.] ] } ] d d d q Q q ", "E E E E -+z u.f+b+A+++A+b+b+D D 5.f+f+>+>+c.k+++7.7.)+G+}+a+E+}+G+E+}+m.B ^.C+C+)+i.)+)+i.i.i.B.C+C+G B.i.o ]+#.]+G o ]+1 @.@.3.f - 9+k ,.C.Y.L.h+* M.8+o /.4 8+` g J Y.s.S.k+D >+( ( G.A+a+n+R *.y.[+1+*. +1+1+*.y.*._ *.*.*.y.*.*.*.*.y.*.*.*.*.*.*.*.y.[+*.y.*.*.*.*.*.*.e.*.*.*.y.y.y.M n+y.M a n+y.M *.*.y.*.*.M *.*.*.M *.M M M M y.R y.n+y.n+*.y.y.y.R R n+M n+n+M M *.M y.n+a z+n+z+b z+z+z+z+z+n+n+n+M z+n+b N.b b b #+z+z+z+z+n+M n+n+n+n+n+z+M n+n+n+M n+n+n+n+n+n+n+n+z+n+n+z+z+z+n+n+n+y.m.y.m.n+n+z+n+n+n+n+z+n+M z+a M M z+z+b n+N.z+n+y.!+n+n+n+y.p.n+n+n+z+n+M n+y.y.p.y.y.y.y.y.y.y.y.y.y.m.m.y.*.m.n+n+n+m.m.y.M n+n+M M n+M n+y.M n+M M p.p.*.*.*. +[+[+ +[+ +p.[+[+[+ + +[+[+ + +[+[+ + + +[+5+ +[+ +[+ +t./+5+p. + + +t. +t.t.t.5+t.Q.}.0 0 p.q.G.u.`.`.u.p+p+= x.{ 8 u 8 { 8 { E u.G.4 '+g 7+7+w+J ,+J J J ,+k k X f a+]+_.8.D (+G 5 _ O ].l ].D.e+* i :.r+^.* g Y.J J k X C.J U P [ [ F+F+e+[ [ ,.a+B.6 G+]+G+G+H+b e.Q.D.L 3 K l l K [ L.4+)+B.i 7.J.8.P._ [ L 3 L 3 v ,.4+B.k+c+Z P.n+& <+U.r.m+@ l.@ l.] @ l.@ @ ] ] ] } ] } d d d |.", "4.E E E z f+*+;+++++8.(+D D o+f+f+( z ( ( >+b+8.k+A+7.k+P.b n+N.w z+w H r+A+++B.B.i.B.)+)+B.#.r+3+k+G o )+)+i.o ]+]+]+o G+G+G+S.@.s.X - C.C.g Y.g * ` 8+F 8+8+8+` M.X f ! ++D o+5.>+n r+3.#+y.M *.y.[+*.*. +1+*.*.*.*.*.*.M *.*.*.M y.*.*.*.a *.*.*.y.y.*._ *.*.*.*.*.*.M M M M n+y.M z.y.y.n+M M a M M a M M y.y.y.y.y.y.y.y.y.*.y.y.y.y.R y.y.y.y.M M M M M M a a M R y.M y.y.R n+a z+a n+z+z+z+z+z+n+n+M n+M n+n+z+b b b z+b n+n+n+M n+n+p.M M p.y.n+y.n+M n+M y.y.n+n+n+z+n+z+z+n+n+n+n+n+M n+n+n+y.y.p.n+n+n+n+n+n+n+n+n+n+n+y.n+n+n+z+z+z+!+z+n+n+M m.y.n+M n+z+a n+z+z+!+n+n+n+y.n+y.y.m.M y.y.y.y.[+*.*.[+*.y.y.y.y.y.m.y.M M M n+M n+M n+M y.*.*.y.*.*.*.[+[+p. + +p. +[+*. +*. +[+*. + +[+[+t. + + +p.5+ +[+5+ +t.t. +p.5+t.t.[+5+t. +5+t.t.5+t.e+}.e+t.N.r+*+z N z >.p+p+= x.8 8 8 u 8 { x.`.:+J.2.'+,.,.,.C.k X R R k 9+C.C.Y.#+R.#.< o+( >+W 1 _ O K. . .L j.L.q.2.2.q.a+s.9+k k k X k C.l+P [ d+d+d+d+d+d+7+M.B.6 i.i.Z Z X.P.*.Q.o.y+j.v v L 3 v w+'+^.B.7.7.7.J.X.y.j j.3 L 3 v P * q.k+X.)+X.n+ +o.x+l . .m+l.l.l.l.@ l.@ l.] ] } } } } ] [.: ", "4.4.E z u.:+D 8.8.8.8.(+D o+o+f+f+9 f+>+D D 5.b+A+J.B.G H+w w s.H+B .+B.G.D D k+B._.B.#.++3+++C+++#.i.B.)+! ! )+! ]+]+]+o ! G+]+! S.'+L.L.Y.Y.- - 3.8+o /.4 /.o 8+R.^.#.8.(+>+( 5.n _.}+n+M M *.*.*.y.e.*.*.*.e.*.M *.*.y.M *.y.*.y.*.*.*.*.*.y._ y.[+_ [+*.*.*.*.y.*.a *.M M M M M a M M a *.n+M a n+y.y.y.y.*.y.y.y.y.*.*.y.y.y.*.y.y.M *.m.[+[+y.M y.y.y.y.*.y.y.R y.y.y.a M y.y.a a n+z.n+n+z.z+n+n+M n+M n+n+n+z+z+z+z+b z+n+n+p.M n+M p.n+n+M m.y.n+y.y.M z+n+m.n+n+!+n+z+z+n+b n+z+M n+n+M y.y.n+n+y.m.n+n+n+m.M n+n+n+n+p.y.m.n+z+z+b z+z+n+z+n+n+M y.y.M M n+z+z+n+n+n+n+n+n+n+y.M y.y.M n+y.y.*.n+y.y.y.y.[+[+[+y.y.y.n+y.n+n+M n+y.y.*.M p.y.y.*.*.*. + + + + +[+ +p. +p.*.[+*. +[+ + + +[+t. +5+5+ +[+ + +[+[+ +p.}.[+ + +t.t.[+t.t.t.5+t.t.Q.}.0 0 ,+4+7.f+N -+N p+p+>.E ~.1.8 1.8 { { E u.*+:.4+Y.,.,.C.9+X #+#+#+b X - k J - a+r+o+9 `.9 D c+_ j.l .F.].[ p.4+q.a+a+'+#+R R R w w z._ l+[ d+v v $+$+v d+P g 2.C+i.)+i.)+)+X.n+$.e+/+w+/+e+y+L L [ C.3.q.2.i i i ! m.'.j.j.3 <+v v C.'+^..+.+.+H.M 5+e L U. .m+m+l.l.l.l.l.l.@ l.] ] ] @ |.: .K.", "`.>.9 o+G.A+A+8.G.o+>+D o+o+o+o+( f+( >+b+8.8.8.G X..+)+.+}+B 4+R.@.4+7.f+f+9 D b+8.8.A+b+b+< b+;+C+)+B.r+B.! )+! ! Z G ]+o ]+G+o ]+! 3.X L.- * M.8+o F 8+/.o f.o i _.< 5.5.>+>+J.)+H.z+M M y.[+*.*.*.1+1+e.*.*.M M y.*.*.M *.M M a *.*.a e.*.*.y.*.y.*.*.y.y.y.[+y.y.y.n+y.M y.M n+a n+y.n+y.y.n+a M n+M n+y.[+[+R y.M M M y.y.*.y.*.y.y.M n+n+y.y.y.y.M *.y.[+[+*.M R y.y.n+*.M M n+a M n+z+M n+n+n+R *.y.y.M n+n+n+z+z+z+n+n+z+M n+y.M M n+n+m.M y.y.y.y.p.M M M M n+n+z+z+N.z+z+z+n+n+M n+n+n+n+m.n+n+n+y.n+n+n+n+y.n+y.y.M y.M y.m.n+n+z+z+n+n+z+a n+M y.n+y.M m.M z+z+z+z+z+a n+n+M y.y.y.M M n+n+y.n+*.y.y.[+m.y.y.y.M y.n+n+n+n+y.n+n+M y.y.*.*.[+[+ +*.1+ +*.p. +[+ +*.*.5+*.p.5+p. +[+ + + +t.p.5+ +[+5+ +p.5+t.t.[+ +[+t.t. +[+5+t. +t.t.t.t.0 }.0 t.p.^.G.f+z N z :+p+= x.A !.8 u 8 A { N f+;+2.* ,.w+C.X #+w f E+E+w #+- - J Y.M.#.n 9 `.&.i+G z.O K. .F.l j.w+'+^.'+H s.X 9+R z.X E+b _ '.[ v $+$+' ' $+$+v 7+h+4+.+@..+.+4+.+b /+/+#+}+b [+0 y+<+j.l+M.8+2.q.^.q.a+#+'.0 0 e+[ [ v 7+h+'+4+'+B H.n+*.I.<+L ].F.F.m+m+m+m+F.m+m+l.l.@ l.m+m+K.K.S ", "f+o+o+J.A+++8.G.( z 9 f+o+G.G.b+G.o+D o+D b+A+++C+#.^.^.^.)+.+^.C+^.C+*+9 9 9 z 9 D ++8.b+b+b+b+o+< C+C+A+#.)+^.! )+o Z o G #.o Z ]+! a+M.M.* M.8+8+_./.o /.o 4 3+n 5.o+( >+D b+B.E+b n+n+R *.e.e.e. + +1+*.*.M M a *.*._ y.*.*.y.*.a *.*.y.M y.y.y.*.*.M *.*.*.y.M *.*.y.M y.M n+y.n+M M a y.a y.M n+a n+M y.R R y.y.y.y.y.M *.*.y.y.*.*.y.y.y.M n+y.M *.*.y.M y.y.y.y.y.y.*.y.y.9+*.y.n+M y.M n+M M y.y.y.M y.M M z+n+z+z+n+M M y.M M p.y.y.*.M y.y.*.m.y.M y.y.n+n+n+z+z+z+z+!+z+z+n+z+n+M n+M n+M M M n+n+n+n+y.y.n+M n+y.p.M m.n+n+n+n+z+m.z+n+n+z+n+p.y.y.y.y.M n+M M a a z+n+M M y.p.n+n+n+n+n+M y.y.[+y.y.y.*.y.y.n+n+n+n+n+M n+M y.n+p.y.y.y.*.[+[+*.*.*.5+ +[+ +[+ +p. +*. +*.[+[+ + +[+[+[+}.[+t.5+[+t.5+ +t.5+[+ +t. + +[+t.t.[+ +t.t. +t.Q.Q.e+}.l+B C+*+z N z u.p+u.N x.{ !.!.8 { -.x.N f+J.q.g 7+w+k 9+X E+P.@.@.E+b X k w+U s.o b+( &.9 i+k+E+[ l m+l 3 3 e+L.'+s.H - 9+R _ R R E+b k j d+$+$+3 3 p p 3 $+v 7+V L.L.L.L.s.N.b [+C.a+.+P.M 1+w.j.O j M.2.o o R.E+#+C.t.'./+/+/+e+e+7+Y.h+h+#+H #+z+1+Q.o.D.<+]. .m+F.l 3 3 l l l F.m+ . .K.K.S S ", "b+A+++k+k+++8.D f+`.9 i+5.(+b+8.J.G.b+b+b+8.b+J.++++++J.n 8.C+C+J.A+8.G.9 9 9 f+o+D k+k+A+D (+n G.b+++A+++A+++B.^..+o Z Z #.G o #.B.o o ! M.M.3.o 4 F /.o o i 3+(+( f+>+( >+3+)+}+n+M M M y.y.*.y.y.*.*.*.*.*.*.*.*.*.M *.*.*.a e.*.M *.*.y.M y.y.*.M y.*.*.y.*.y.y.M *.y.y.M y.M M z+n+y.M y.M n+M y.n+M M M y.y.R n+y.y.*.M y.M M *.M M M *.y.*.y.y.y.y.*.y.y.y.y.*.*.y.M y.M *.[+y.*.y.M n+*.M y.y.y.y.m.M n+y.y.M M M n+n+n+n+m.n+M M M y.y.y.y.y.*.M *.y.y.*.M M z+z+z+b z+b b z+n+n+n+y.m.M n+n+n+n+n+n+m.n+n+y.p.y.y.y.p.M n+n+M M n+n+n+n+z+n+n+y.n+y.y.p.n+M z+n+n+z+n+a z+M y.y.M a M z+M z+n+M n+y.y.y.y.y.[+y.y.n+M n+z+M z+n+n+z+a y.y.[+y.p. +[+ +!+ +[+ + +p.5+ + +*. +p.5+[+[+ +[+ +[+ + +[+t. +[+5+t.[+t. +t. + + +t. +t.5+5+5+t.5+5+0 0 }.e+p.q.J.f+`.z u.:+:+>.E { 8 !.!.!.{ { -+u.*+C+4+,.7+l+C.X #+w E+H+S.E+w X k ,+l+- ! ++D ( i+D i.E+j L l l 3 $+v 7+Y.,.C.,./+/+'.'._ k z.R '.0 v $+p p 3 p 3 $+p v d+d+e+e+7+w+C.L.,+,+4+k+1 z+*.& w.O j a+r+]+! S.#+*.'.'.'.k w X ,.,.C.H #+L.H R 9+#+1+t.I.D.<+L ].l L j.[ /+j [ o.x+].l ].K.K. .K.", "B.B.B.C+A+b+b+(+5.i+D D b+b+8.++++++A+J.G.J.A+A+;+b+J.A+J.A+J.++C+C+A+D o+G.G.8.++++k+Z #.8.8.(+b+A+A+8.b+A+++B.S.^.)+! B.#.#.G #.Z i.]+! ! 3.3.o o _.F f._.3+n ( z 9 ( D < B.E+z+z+R n+R M *.y.y.*.y.*.y.a *.M M a *._ *.*.M _ M a *.*._ y.y.M y.M M *.a M M *.*.*.y.y.y.y.y.y.M M y.M M y.y.M *.M a y.n+y.y.a n+y.M y.M a *.*.M *.M e.M *.M M y.y.y.y.y.y.*.*.y.y.y.y.[+y.y.m.*.y.y.y.y.y.y.y.n+y.*.y.y.y.m.y.n+y.n+M n+y.y.n+M M y.y.n+y.y.y.M p.M p.y.p.*.[+y.y.n+n+z+z+!+b z+z+z+z+M M M y.y.M M z+n+n+n+n+n+M p.y.y.y.n+n+m.n+M n+n+z+n+z+n+n+p.y.n+y.y.M n+M n+m.M y.y.n+n+M M y.*.*.M n+M z+n+n+m.y.y.y.y.[+y.y.y.M a n+z+n+n+n+M M !+p.!+p.[+[+[+*.[+ + +p. +[+5+[+[+5+p.5+ +[+[+5+p. + +5+[+ +t.[+ + +t.[+t. +[+ +[+ + + + +t.[+[+t.t.5+t.5+0 0 0 l+H C+*+>.`.N u.:+p+N x.A !.!.!.u 8 { E u.G.2.H w+F+w+C.R X X X s.E+f w R - J J 9+}+B.A+D D 8.! s.U [ $+3 3 $+$+v F+7+P e+[ [ [ [ [ j J /+j [ j.$+3 3 3 3 $+3 3 3 3 $+$+$+$+d+7+/+,+/+a+B.6 z.T I.O D.Q.S.++B.G+H+z._ t.Q.,+#+a+E+k J * R.H.9+w #+R n+_ Q.o.o.j.x+l ].j.'.#+E+P.z+$.w.D.|+].K.K.: .", "k+6 B.++b+G.G.(+b+D D 8.7.J.++++A+++C+++G.G.b+8.A+J.G.b+A+b+G.b+8.A+b+J.b+G.8.6 i.)+C+C+)+C+A+8.A+++k+8.8.A+C+B.)+! 2.i.#._.r+_._._.B.#.#.o o o o o F _.F < n ( 9 9 f+( A+i.H.w z+z.n+a y.*.*.*.M *.y.*.*.*.*.M *.*.M M *.*.*._ *.M M *.*.M _ M y._ M *.M *.M a *.a a *.*.y.M y.y.M y.n+M y.y.M y.y.M y.R M y.M n+n+M y.y.M M *.y.y.M *.y.M *.M *.y.*.y.[+y.*.y.*.y.y.y.y.y.*.[+y.*.y.*.y.*.y.*.M y.y.y.y.y.y.y.m.y.n+*.y.y.y.m.m.M y.y.y.y.y.*.y.y.*.*.M *.y.[+y.M y.n+!+z+z+z+!+n+n+n+M y.y.y.p.y.n+M z+n+n+n+m.M M n+p.M y.M n+!+n+z+n+n+n+n+n+n+n+M n+p.y.M n+n+M n+M n+M M n+n+y.*.p.y.*.n+n+M M M n+n+y.y.y.p.*.y.n+n+z+a z+a M n+n+M M M y.y.y.[+[+[+[+[+ + + +*.[+ +[+ +[+5+[+ + +p.5+ +p.5+[+t.[+5+ + + +t.t.t. + + + + +t. + + +t. +t.t.Q.t.}.e+}.C.4+J.p+`.= z :+:+p+N x.1.u !.8 8 { { z :+J.q.L.7+7+/+k R X X R - - - - 9+C.k C.R w }+)+i 7.i ! M.J j [ j.$+$+$+3 $+$+$+$+v v j.j.v j.[ [ [ j.v v v v v v v v v v 3 3 p 3 3 v l+l+/+/+#+)+Z P.T C O > w.a+8.k+H+E+R +Q.0 /+X ^..+X Y.* o G+R B b y.R 1+& o.D.D.<+<+<+[ p.^.Z Z G+z.& w.|+].K. . . .", "A+b+b+b+G.b+b+b+D D b+b+b+A+A+A+++++C+7.J.G.G.++B.B.A+8.G.b+b+A+A+G.G.G.J.8.C+i.)+C+C+A+b+++++J.A+++A+++C+C+++++++r+B.B.B.#._._._._.#.o G o o o o _.3+< 5.5.( 9 z f+5.b+B.E+P.b b n+n+n+n+a M M M R y.y.*.a M *.a y.*._ y.*.*.*.R z.z.z.z.z+z.R M 1+*.*.*.M M y.y.*.*.y.M y.y.y.M n+y.y.m.M y.n+y.M M y.*.y.M y.n+y.*.y.[+y.*.y.y.y.y.y.y.*.y.y.M M M *.*.*.*.*.*.*.y.y.y.y.y.y.*.y.*.M y.y.y.y.*.y.*.*.*.y.m.y.y.y.y.y.n+y.M M y.M M y.M y.y.p.*.y.y.y.*.p.*.p.y.n+n+z.z+z+z.z+z+a z+a m.m.y.y.y.M n+z+z+z+!+n+z+n+n+M M p.y.n+z+z+z+n+!+z+z+z+z+n+M y.M m.n+n+M n+m.n+n+n+y.n+M y.y.y.y.y.y.y.y.y.n+n+y.y.y.y.y.*.y.*.y.M M n+M y.n+y.y.n+n+n+p.p.*.[+[+*. +p.*. +p. + +t.t. +[+ +p. +5+[+ + +5+[+t.t.[+t.[+5+ + +t. + + +t.5+ +t. +5+ +t.5+t.5+Q.0 y+e+e+p.2.G.u.E `.>.:+:+p+E { 8 !.8 u 8 A 4.N *+i 4+C.w+l+,+k R R R R k 9+9+C.J J Y.X X w E+w H+a+R.M.s.- J j [ v v $+$+p p ' $+3 $+$+$+v v v [ [ [ d+d+[ v [ [ [ [ j.v j.v <+$+v l+l+'.'.y.w S.@.z+$.O > |+O L.C+k+@.#+_ Q.0 o.j k a+^.s.J u+2.X.b }+H+n+*.[+Q.s o.D.<+<+y+t.#+C+b+8.6 5 & w.|+S : K.: K.", "b+b+8.J.8.b+G.D D o+G.G.b+8.++k+C+C+J.++A+G.b+k+i.C+:.A+G.b+G.b+b+b+b+b+b+++C+8.C+C+++b+(+D G.D o+G.b+J.++A+A+++++_.r+r+#.B.k+_.++_._.#._._._._._.< < 5.( ( ( i+f+5._.i.P.b b b z+n+z.a n+M a y.M *.y.y.*.*.M y.*.*.*.*.1+*.a a z+b P.5 P.5 5 z+R e.1+*.y.y.*.*._ y.*.*.1+y.y.*.*.y.y.*.y.n+y.y.R M y.y.M *.y.*.y.y.y.y.y.y.*.[+y.m.y.*.y.*.*.*.*.y.*.M *.*.*.y.*.y.y._ y.*.M y.*.y.y.a *.[+*.M y.y.M M M y.y.y.y.y.p.[+p.y.y.p.n+n+y.p.*.y.y.y.y.y.p.y.p.[+*.y.[+n+y.n+z+n+n+n+n+M n+M M y.y.y.m.M z+z+b z+z+z+z+a p.m.y.p.n+n+z+z+z+z+z+b z+z+n+n+m.m.n+n+n+z+z+M M n+n+z+y.m.y.y.p.[+[+y.y.y.y.y.y.y.y.n+y.y.y.y.y.*.M n+a M M *.M M *.M M M M *.*.*.[+[+*. +*.p.5+ + + +p.5+ +5+5+[+t.[+ +p. + +[+ +t. +p.5+5+t.t. +5+5+t.t.5+t.[+5+5+[+t.5+t.Q.Q.}.y+l+N.4 :+E E N u.:+:+p+E x.{ 8 u 8 { { x.z *+r+* ,.w+J R R z.R R R R R k C.J Y.- s.#+E+E+P.H.s.'+* * * - J P d+v p $+p $+p $+3 $+v v d+j.[ [ [ 0 [ [ j j 0 '.'.'.j 0 0 [ j.d+[ l+[+ +'.R E+H+b e.+.O > S O k o B.@.#+/+0 w.v j.l+Y.M.s.C.g R.S.b w H.b M +Q.o.D.D.<+o.o. +N.i D (+8.c+e.<.D.].K.K. . .", "b+G.J.b+J.b+G.D G.(+D o+b+++++C+C+++J.++++;+o+8.C+C+J.8.b+*+o+G.8.b+(+b+8.C+C+C+J.o+A+A+b+D c.G.o+>+D b+++8.8.A+++++A+_.C+C+C+_.++_._._._.8._.3+3+n 5.9 9 9 9 ( D 3+i.H+H.P.b b z+z+n+z+R R n+R y.y.y.M M *.*.*.a *.*. +t.1+*.M z+z+z+z+z+z+z+a e.$.1+_ *.*.y.y.*.1+1+*.*.M *.*.*.*.*.y.y.y.R y.y.n+M y.M y.y.M M *.*.y.[+[+y.*.*.*.*.M y.y.*.y.*.y.y.*.*.*.[+y.y.*.y.y.*.[+y.*.*.y.y.*.y.n+y.y.*.*.*.*.*.M y.y.y.*.[+y.*.p.y.M y.y.*.M p.p.M p.y.y.*.*.y.y.y.y.y.y.y.M R n+a y.n+m.y.y.y.*.y.y.M z+a z+z+z+b b z+n+y.M M y.y.n+n+z+z+z+z+z+z+z+z+n+n+n+n+z+z+z+z+z+z+n+n+n+n+M p.*.*.[+y.*.*.[+y.y.[+y.p.y.y.[+p.y.y.y.M *.M n+M M *.*.y.y.*.*.p.*.[+*.[+ +p.*.5+[+5+p. +5+ +[+[+[+5+p. +t. +[+5+p. +5+ +5+ + + +t.5+ +t.t.t.t.t.}.t.t.t.t.}.t.5+Q.y+0 e+p.q.J.f+E E z :+:+:+>.x.{ { { { { 8 { -+>.;+2.g ,.w+C.X E+E+b b b X R R - Y.Y.- L.s.#+E+a+H+H.3.R.` ` ` g ,.d+v $+p p p 3 v j.d+[ [ 0 j 0 j j '.'./+/+/+_ _ _ ,+'.'.'.0 '.j 7+C.R _ +9+P.G+z.$.<.S S S w.R .+)+^.w ,+j j.j.j.[ l+Y.Y.J ,.* a+}+w w b y.1++.o.<+D.D.y+Q.y.4+C+G.D 8.6 z+Q.|+S S . .K.", ">+D b+J.J.b+b+G.o+f+o+b+8.C+++C+7.C+++C+C+J.:+o+G.b+G.G.8.o+o+o+8.C+k+i.J.J.b+J.J.b+G.*+o+G.(+b+D G.b+A+++A+b+A+++++A+3+A+A+_.++++++_.A+8.< < n (+5.( z z 9 9 n _.)+@.P.P.b b !+z+z+n+z+M n+M z.y.y.y.y.M *.M _ a a *._ t.Q.t.Q.t.5+Q.Q.Q.Q.5+t.Q.t.1+*.*.*._ y.*.y._ *.1+*.*.*.y.[+*.y.y.M M y.y.y.y.M M *.*.e.M y.y.y.y.*.*.y.n+y.y.y.y.y.y.y.M e.*.y.*.e.*.y.y.y.y.*.y.*.*.*.e.*.y.y.y.y.y.M y.M y.y.y.y.*.*.y.y.*.y.[+*.y.n+n+y.p.M *.*.M *.[+y.*.p.[+p.*.y.y.n+n+y.y.y.y.*.y.m.[+[+y.[+y.y.M n+a n+n+n+n+n+n+n+n+y.y.n+n+n+n+n+n+z+z+b b b n+n+M n+z+z+z+z+m.z+n+n+z+!+M y.y.y.y.p.y.n+M y.y.m.*.y.*.y.y.[+y.[+y.y.y.y.y.m.m.y.y.*. +[+*.*.[+*.[+*.[+[+ +*.[+[+ + + + +[+t. +[+[+5+ +p.5+[+ +5+[+ + + + +t. + +t.5+t.t.t.}./+t.t.5+5+t.t.t.Q.0 }.y+0 H C+*+`.E E u.:+:+:+N x.~.A { { x.{ { -+u.;+r+* ,.C.X E+E+5 b X b E+X R k J - - L.L.L.X a+! )+2.r+o 8+R.- J F+v $+p p $+v [ [ [ 0 j j _ '._ _ _ _ _ k k _ _ _ k _ '.U '.U '.U - #+R 1+k w P.2 & 6+> S S w.E+G+E+}+M.,+j [ j.v v d+e+P P l+g s.a+@.w #+n+ +Q.w.x+x+D.o.Q.n+.+A+G.o+b+6 !+& D.S K. .: .", "o+D A+b+b+G.o+:+f+f+u.o+G.++C+C+C+++J.J.J.G.o+o+D o+f+c.G.G.G.G.++++++J.G.o+o+D G.b+b+o+D b+b+b+G.b+J.A+b+J.A+A+b+J.b+< 8.++3+8._.8._.8.3+< D D 5.9 z z 9 ( 5.A+)+1 H+H+P.P.b b b z+z+n+n+R n+M R *.R M y.M n+M *.*.*. +t.t.o.o.y+y+<+o.<+y+o.I.Q.$.1+*.*.*._ *.*.*.*.[+[+*.R [+y.y._ y.y.y.n+M M y.y.*.*.*.*.y.*.y.*.y.*.*.y.y.*.y.y.*.y.y.y.*.*.y.M M *.y.*.*.*.[+*.*.*.[+y.*.y.y.y.y.y.y.y.n+y.y.*.y.*.M [+y.y.y.y.y.*.y.M y.y.y.*.M M p.*.p.*.*.y.y.y.y.y.y.9+y.*.y.y.[+*.M *.[+[+y.[+p.y.*.y.y.M M R M n+n+n+y.y.M y.y.*.y.y.M n+a z+z+z+z+z+n+n+n+z+z+z+n+z+n+n+n+n+n+n+n+[+p.[+y.n+n+n+n+*.*.y.y.y.[+y.[+[+y.p.[+y.y.y.*.*.*.[+*.[+[+ +[+p. +*. + + +p. + + +p. + +[+ + +t. +[+ +5+[+[+[+ +[+5+p. +t.t.5+ +5+ + +5+t.5+[+}.t.t.t.t.5+Q.Q.Q.o.}.y+l+N.7.:+-+E E >.*+:+>.E x.{ { x.x.x.~.{ x.f+;+2.'+g - s.E+E+5 X z.z.b b k - Y.Y.Y.g L.9+Y.'+i.#.7.3+F o 8+* J e+d+$+p $+v [ 0 j j '._ _ _ k y.k _ k k _ y.k _ k U _ U _ U _ U ,+9+s.R _ $.y.R y.<.> S S ~+w.w i.P.E+}+k /+j 0 j.d+d+d+[ d+P Y.#+.+i.H.b n+ +& s x+x+<+y+t.m.C+G.f+f+D G b & O ].K.K.K.K.", "f+D b+G.G.o+o+o+f+f+f+o+o+o+G.G.G.J.o+f+f+f+>+D G.o+f+o+G.D o+D J.J.G.o+o+o+o+c.++++7.J.c.b+D D D b+b+b+G.b+b+D D b+n b+< 8.3+8.++_.++8.< < 5.>+9 &.9 z 9 n k+X.X.P.P.H.P.P.H.H.b 5 z+b z+a z+n+z.M M y.*.y.R M y.M *.1+$.'.Q.I.w.o.o.o.o.o.I.Q.$.[+1+*.y.*.*.y.*.*.*.*.*.*.y.[+y.M y.y.y.M R n+M y.y.*.*.M 1+*.*.y.*.*.y.[+y.[+y.y.y.*.y.[+y.*.*.*.M M *.*.*.*.y.*.y.y.y.*.y.*.*.y.*.y.y.*.*.M y.p.*.y.*.M *.y.y.y.[+y.p.y.M y.y.p.*.y.*.*.*.*.y.*.m.y.y.y.y.y.*.y.y.y.y.y.y.y.M [+*. +[+*.*.*.*.y.[+y.*.[+y.y.y.y.M M y.y.*.y.[+y.n+M n+n+n+n+n+n+M n+z+z+z+n+n+n+n+n+z+n+M M y.*.*.y.n+n+n+z+n+M y.y.y.[+y.*.*.*.M y.M M n+y.*.*.*.[+ +[+ +*. +[+ +*.p. + +*. +p.5+ + + + + +p.5+[+[+ + + +[+[+ +[+5+ +p.5+t.p.}. + +t.t.5+t.t.t.}.t.5+t.t.}.0 }.y+y+/+4+G.z x.-+z :+*+:+N x.x.x.4.x.E E x.{ -+u.G.2.'+* - M.f f E+z.k _ k k J J J J U m m w+,.h+2.7.3+< 3+i o u+J F+v $+3 $+d+0 j '._ _ k k _ R _ k y._ _ _ _ U /+j U j j j j '.U k s.f #+/+0 0 Q.0 O > 0+0+~+|+k .+H+N.a+#+_ U j 0 [ [ d+j.d+P '+#+a+C+H+H.#+[+& I.<+D.<+y+l+#+C+o+i+9 i+; !+& O S K.K.K.].", "f+i+o+o+f+f+f+f+o+f+o+o+o+o+o+f+o+{ ) c.o+c.o+D f+) 9 9 o+o+o+c.o+o+D o+D D o+c.++J.k+C+C+b+D G.o+o+G.G.b+b+b+b+G.D (+D b+A+8.3+8.8.< b+n D >+( 9 &.9 ( 5.k+G+.+H+1 1 H+H+P.P.b P.b b z+z+z+n+z.n+z.R a a M y.y.M y.y.y.[+[+ +$.t.Q.I.Q.& 5+$. + +1+*._ 1+*.*.*._ *.*.*.*.e.y.*.y.y.M y.*.y.a y.y.y.y.y.M *.y.y.*.*.y.M 1+y.[+y.y.y.M y.y.*.y.M y.y.*.*.M *.*.y.*.y.y.*.[+y.*.y.M y.M y.y.y.y.M *.M M *.*.*.[+[+y.y.y.*.y.y.p.M y.y.n+y.y.p.y.y.y.y.*.p.y.y.n+y.y.y.1+y.y.*.[+[+[+y.*.y.*.*.*.y.y.y.m.[+*.y.[+p.y.M p.y.*.[+y.[+y.y.*.y.M n+y.n+M M n+n+n+n+n+n+n+z+m.z+n+n+n+n+y.m.y.m.n+n+z+n+z+n+M y.*.*.*.y.y.y.y.y.n+n+M n+M M +*.[+[+[+ + +[+*. +*. +[+[+ +[+ +[+[+ + +5+p.t. +[+ +p. +5+p. +[+t.5+t.[+5+ +[+t.5+t.t.t.5+5+t.t.Q.Q.0 t.Q.Q.y+y+y+p.C+*+&.x.E >.:+*+p+E ~.{ { ~.-+x.x.4.x.E f+;+4 R.M.M.M.M.f w X k J /+U U U U 7+7+P P F+P Y.^.3+n 5.3+_.R.X m [ $+3 $+$+[ j j '.k k k k k _ k _ _ '.U '.j [ [ [ [ [ [ [ [ P j Y.M.w R '.j.D.].l .[.0+k.: K.y+- E+w a+E+X k J U j j j j e+P }+z+w ++X.H.n+*.t.I.o.D.<+s 0 H J.o+&.9 i+W P.5+O |+K.].].|+", "z 9 9 o+f+f+f+f+o+o+o+o+o+D o+o+f+9 9 i+o+b+G.o+`.) &.9 f+o+o+G.D o+o+o+8.C+G.f+G.*+b+8.7.G.(+G.o+o+D b+b+G.G.8.b+b+b+b+D b+b+b+3+b+n D >+9 9 9 9 z 9 D _.P.P.1 H+B 1 H.H.P.P.H.P.H.b b b z+z+z+z+z+n+n+z.a n+*.y.*.*.*.*.y.*.1+e.1+$.$.$.1+1+*.[+*.e.[+*.*.*.*.y.*.y.y.y.*.y.y.y.y.M M a *.*.M *.*.y.y.M M *.y.[+e.y.n+*.*.[+[+*.y.*.*.y.*.y.*.*.y.y.[+M *.[+y.*.*.y.y.y.y.*.*.*.m.y.M y.*.[+*.y.M y.y.*.*.*.[+y.*.y.y.p.y.y.y.y.y.p.M y.y.M y.p.y.y.p.y.y.y.y.y.y.*.*.[+*.*.*.*.y.[+y.p.*.y.y.[+*.[+[+*.[+[+[+[+y.*.y.*.[+y.y.[+*.y.y.y.y.*.y.y.M a n+a n+y.n+n+n+n+n+a M y.y.y.y.y.M M n+a n+M z+M y.y.[+[+*.p.y.m.n+z+n+M M *.*. + +[+ +[+ +[+[+[+*.*.p. + +*. +p.5+ + +[+t.5+ +p.5+ + + +[+5+[+ +[+[+t.t.t. + +t.t.t.5+t.t.t.t.Q.t.t.Q.Q.Q.}.y+o.0 H i p+x.4.N :+*+*+N x.8 8 { ~.{ E { { -+E f+J.r+R.3.M.3.M.M.f X k J U l+P P P F+d+d+v d+P L.! A+*+o+n _.R.- P d+$+p $+v j U _ j k k _ _ J /+U '.'.j [ [ [ [ d+v d+v v d+v d+d+m M.w y.Q.j.]. .[.7 q t+D+D+ .K.d+w+C.s.}+E+X k k J _ j U j J '+P.w )+X.H.#+n+[+I.o.y+D.o.t.p.4 :+9 9 i+W !+& D.|+x |+|+|+", "f+f+f+z f+f+u.f+f+o+o+o+o+G.o+o+o+f+i+o+o+o+:+f+u.9 -+&.9 9 f+o+o+o+o+o+f+c.G.f+o+f+f+o+o+G.b+(+G.D G.G.G.b+D D J.b+J.b+b+b+b+b+b+n D >+( z &.z ( >+>+n H+n+P.1 1 1 P.P.P.P..+P.H.P.P.z+z+z+2 z+b z+z.z+n+M M z.y.a M *.[+*.*.*.1+1+ + +*.*.*.*.*.*.*.*.*.*.y.y.*.*.*.*.*.*.*.*.*.y.M R M *.M y.*.M y.y.*.M *.*.y.y.y.y.*.*.*.[+[+y.y.*.*.y.*.*.[+*.[+e.*.*.y.y.y.[+y.y.*.[+[+y.*.*.*.y.y.y.y.y.y.y.p.y.p.*.y.y.[+y.[+[+y.*.y.y.y.y.M y.M y.M M M y.M y.y.n+y.y.[+[+*.*.*.[+y.*.*.[+*.y.M n+M *.*.[+*.*.*.*.y.*.*.*.*.p.y.[+*.*.1+*.*.[+[+y.[+*.*.*.*.M y.M n+a y.y.y.M m.[+y.y.y.y.M y.n+n+a z+z+M z+M y.*.1+y.[+[+y.n+n+z+z+M *.[+[+[+t.[+[+ + +*. +*. +*.[+*. +[+ +[+ + +[+ +[+ +t.[+[+ +t.[+t.[+t.t.[+t. +[+ + + + +t.t.5+5+t.t.}.5+t.5+0 0 y+s y+/+q.J.z x.4.N p+b...= ~.u !.8 A { A { x.E u.*+J.2.R.M.M.M.s.w X X k _ J U U P e+[ d+v $+$+e+#+! _.n 5.3+i R.J P v $+p p d+U '.'.U - _ _ j j e+e+[ y+d+v j.v $+$+$+$+' $+$+$+$+v P M.E+_ w.x+{.[.7 Q 0.. . Q } .l j.P w+- w X X X k k k ,+k 9+M.}+a+a+4+H.n+y. +Q.o.s y+0 [+N.2.G.:+o+b+k+b +.O |+x+|+|+K.", "o+o+o+D >+f+u.9 f+f+o+o+o+o+o+o+o+f+f+>+o+o+o+f+9 { u -.&.`.9 f+f+f+>+f+f+f+f+f+f+9 f+>+f+c.J.G.G.G.D G.G.G.G.o+G.b+b+J.b+b+b+(+b+D f+9 z z z ( n 8.8.B.y.1+M b P.X.1 B H.P.H.P.P.b P.b b b z+z+z+z+z+z+z+z.M a n+n+M M y.y.*.*.*.*.*.*.*.y.*.M y.*.*.*.*.*.*.y.*.M M M *.a M M M M *.R M y.y.M *.*.M y.y.y.y.M y.y.*.[+*.*.1+1+[+*.y.y.*.y.*.y.y.y.[+*.y.*.*.y.R *.*.*.y.y.y.y.y.[+y.y.*.*.M M y.*.M y.y.*.*.y.*.p.*.*.y.p.y.y.y.*.y.p.M *.M y.M y.n+m.y.n+y.y.m.[+y.[+[+[+[+[+*.y.y.[+M y.n+M y.y.[+*.*.*.[+y.y.p.1+[+*.[+*.p.*.y.y.*.[+[+[+*. +y.*.y.y.M y.y.y.*.y.*.[+[+[+[+[+y.y.M M n+M n+n+M n+M *.y.*.*.y.M M z+z+z+z+M *.[+ + + +[+ + + +*.*.!+ +*.*.*.*. + + + +[+t. +t. +[+t. + +p.5+t.t.[+t.t. + +t. + +[+5+t.[+t.5+t.5+t.Q.Q.Q.Q.}.o.y+0 p.C+*+E x.E u.:+*+p+x.A !.!.u 8 { 8 -.x.z f+:.r+R.a+M.M.s.X X - k J ,+/+/+U U P P d+d+$+$+[ w 6 W 8.b+#.S.s.l+F+$+3 $+$+[ U _ $.'.- k j [ F+d+d+d+v v $+$+3 $+3 p $+' 3 $+$+$+$+d+m s._ j L F.l.d q 0.. . 0.d ] l L j.e+U k - k - - k k J - L.E+}+B.X.a+N.p.,+ +Q.o.<+y+0 p.B C+G.:+*+8.6 b Q.s D.|+|+K.K.", "o+o+o+o+o+f+9 f+f+>+o+o+f+o+o+*+f+9 f+f+o+o+f+f+f+9 9 9 9 9 9 9 9 9 f+>+f+f+f+>+o+f+9 o+9 f+o+o+o+o+o+o+o+9 &.D o+D b+b+n D G.D o+f+9 z z &.9 D Z i.G+b $.5+ +M N.P.P.P.1 P.H.P.H.P.H.b z+z+b z+!+a z+z+z+n+n+n+M a R a *.y.*.y.y.M M M M *.*.*.*.M a a y.M M y.a y.y.y.y.y.y.*.*.y.M *.R *.M M M M *.M *.*.y.*.a y.y.[+[+*.y.*.[+y.y.[+y.y.*.y.y.n+n+y.*.*.y.*.[+y.y.*.M *.*.*.1+m.y.y.M M n+M M p.y.*.y.y.y.*.[+y.[+p.y.y.M y.*.y.M *.[+y.y.y.M y.M M y.y.*.y.y.y. +[+*.1+*.*.*.*.*.y.*.y.y.M p.y.y.*.*.[+*.[+[+*.y.[+*.y.[+[+[+[+[+[+*.*.*.[+[+[+*.*.M *.*.[+y.*.*.[+[+ +[+*.y.[+y.y.y.y.M a M M M M *. + +*.y.y.a a b z+z+n+y.*. +[+[+ +[+ +*. + +[+*.*.*.[+*.*.[+ + + +[+5+p. + +t.t.5+[+ + +[+t.[+ + + +t.t. +t.[+t.t.t.t.t.t.5+Q.t.5+0 }.y+y+e+B J.f+-+4.E :+b.*+u.x.!.9.!.8 8 8 8 u -+p+:.2.R.'+3.f f f f X k R J U U ,+_ U U l+P d+j.v [ m.c+6 ++8.6 E+k P v 3 ' K $+[ k _ U U _ _ j [ v v $+$+$+$+$+$+$+3 $+p p p $+3 p ' p $+P J k 0 j.l l.] q q Q Q q d ] l.3 j.d+P U U k J J k J J J s.E+}+C+i.H+E+y.[+t.0 D.<+<+o.p.4+J.o+u.o+b+i.z+& }.> x+S ]. .", "o+o+o+o+o+f+>+>+o+o+f+f+o+f+o+f+f+f+f+9 f+f+f+9 9 f+9 f+f+f+f+u.9 9 9 f+f+f+z 9 f+f+9 9 f+9 9 f+o+f+>+f+9 o+9 >+>+>+D G.b+G.D o+( 9 &.&.z `.( _.E+E+w y.t.Q.Q. +*.b H.b B P.P.P.b P.N.b !+z+!+z+z.z+z+z+n+z+n+z+n+M n+M *.y.*.*.y.y.M M z.n+y.y.M R *.a M M *.R R *.*.*.*.M y.M a y.M *.y.M M y.y.*.M M M M n+M *.*.y.[+y.*.y.*.y.*.y.[+[+*.*.y.*.y.n+y.[+*.*.y.y.[+y.*.*.[+y.y.*.y.y.y.y.M M n+y.n+y.y.y.M *.y.*.y.[+[+*.*.y.y.*.p.*.*.[+p.*.M *.*.y.*.y.y.*.[+[+y.[+[+*.*.[+[+p.[+*.y.y.*.y.y.y.y.y.[+*.*.*.*.y.y.y.y.*.*.y.[+[+[+1+*.*.[+ + +[+y.[+*.*.y.*.*.*.[+ + +[+ +[+[+y.*.*.y.*.y.*.*.M y.[+1+ +*.[+*.y.n+n+a z+z+a z+M *. +t.t.[+ + +1+*.*.[+*.p.*.*.*.*. + +[+[+ + +5+t. +5+[+t. +t.t. + + +t. +[+ +t. +5+[+t. +t.t.t.t.t.t.Q.5+0 o.y+y+p.^.*+N x.E >.:+*+:+= A 8 !.!.!.!.!.!.8 E f+4 * g '+S.1 1 @.@.E+X _ U /+j J ,+_ J /+j e+d+j.[ _ 1 c+i.B..+X /+[ v p p p v j k _ _ U k _ j d+v $+$+$+3 $+3 $+$+3 3 $+3 p p 3 3 $+$+d+U J k _ 0 j.l l.} d q d d ] ] m+3 j.j.[ e+e+j j l+j l+l+J h+S.}+i ++X.H+n+*.t.Q.o.x+<+y+[+q.*+z `.z D k+5 5+w.|+|+U.].K.", "G.o+G.G.*+o+f+o+o+f+u.f+i+o+o+f+f+f+9 f+9 >+x.4.9 9 9 f+f+z -+9 z 9 f+9 f+9 z 9 9 9 z 9 f+f+f+f+9 9 9 i+o+>+>+f+f+>+D o+(+G.D D f+9 9 9 z 9 D i.E+P.P.R $.Q.Q.5+ +e.M M z+z+z+z+z+z+z+b b b b z+z+z+z+z+z+n+z+n+M y.M R M *.[+y.M M M M *.M *.y.m.y.M *.a *.M a y.*.*.y.*.*.*.*.*.M y.y.M y.R M *.M M *.*.*.y.y.[+m.y.y.[+y.[+*.*.y.*.*.*.[+y.*.y.a M y.y.*.[+[+[+y.y.[+y.y.*.*.y.*.y.y.p.M y.m.y.y.y.*.y.y.y.y.y.*.[+*.[+*.*.*.*.*.[+*.*.*.y.*.y.*.*.y.*. +*.*. +[+ + +[+[+[+[+*.[+p.[+p.y.M y.*.[+1+p.[+[+*.*.p.*.[+[+*.y.*.[+*.[+y.*.[+1+1+[+ +[+y.y.M M *.*.*.1+*.[+ +*.1+*.*.y.[+[+*.[+y.*.*.[+1+1+[+ +[+[+*.*.M n+M M z+M M [+ + + + + + + + +*.*.1+*.*.*. +[+ + +5+p.t.t. +t.t.t.t.t. + + + + + +t.5+t. +t.t.t.t.5+t.t. +5+5+Q.t.Q.Q.}.}.y+0 H ++f+-+x.E p+b.b.p+E 8 !.9.!.!.!.!.!.1.N ;+q.g Y.f 1 c+]+c+c+E+R k e+P [ P l+,+J J U j [ [ 0 _ a z.z.w #+w+e+v $+3 ' p v j z._ $.k k '.[ d+$+p p p $+$+$+$+v d+v v $+3 $+p $+p $+d+_ f f X X _ j.l l.] ] ] l.] @ {.$+P 7+U j P [ F+P [ F+[ e+g i.@..+C+i..+b *.5+I.o.<+y+y+l+4+*+N ) &.9 W P.& O D.x+x+].K.", "J.b+G.J.G.*+o+>+o+o+f+o+f+o+o+o+f+f+f+f+u.f+u.&.&.9 u.9 f+u.&.&.9 9 f+u.9 9 9 o+o+o+z z 9 9 f+9 z z z 9 f+f+f+f+( D D G.(+b+D D f+f+z 9 z o+A+@.b P.P.z+y.$.Q.Q.5+Q.& I.5++.$.1+ +1+*.y.y.M M a M z+z+z+z.a a y.n+y.a M R *.*.y.y.M y.y.*.z.*.*.y.y.y.y.y.M *.a y.y.*.*.*.*.*.*.*.*.y._ M *.*.y.y.*.a M M *.y.*.*.*.*.*.y.y.[+[+*.*.y.*.y.*.y.y.*.y.*.1+[+*.*.*.[+[+[+[+[+y.[+[+y.*.*.*.*.y.y.y.n+M M *.y.y.[+[+y.[+*.*.*.[+*.*.*.*.*.[+p.*.[+*.*.*.*.*.*. +[+*.1+y.*.1+*.*.*.[+*.*.*.[+*.y.y.y.*.p. +1+ +[+1+*.*.*.M *. +[+[+*.y.[+p.*.*.*.1+p.1+[+y.*.*.*. +*.*.1+1+*.[+*.*.y.[+*.1+ +1+ +[+*.1+[+[+ +[+ + +[+[+ +*.M M M M *.*. + +5+t.5+ + +1+*.1+*.*.*. + +*. + + + + +5+t. + + +5+t. +t.t. +5+ + +t. +5+t.t.t.t. +5+ +t.t.t.5+e+t.5+0 }.o.y+[+4+J.N { x.z :+b...>.x.!.!.!.!.!.!.!.9.u z ;+q.Y.C.3.]+6 6 G ; 1 z.'.[ d+v ).F+j /+J ,+U j j '.$.a a R R _ e+v v p p 3 $+d+_ z._ $.k k j [ d+$+' ' p 3 p $+d+0 j 0 [ [ j.$+p 3 p $+[ - E+]+]+o 5 j j.l m+l.F.l K K v P ` ! M.- J U P P [ d+d+d+C.B.i.H.^.X.1 H.M $.I.s O o.o.l+B b.&.`.&.i+8.!+& s O D.O x+S ", "A+A+J.J.G.G.*+*+*+o+o+o+o+f+>+>+f+f+f+f+9 u.9 u.9 z z z 9 z z 9 9 9 9 9 f+f+i+>+o+o+u.9 &.9 f+9 9 z 9 9 f+9 z 9 f+>+D G.b+b+b+b+b+D ( 9 >+D G P.z+b w b z+ +& I.I.w.}.o.s o.O s O s w.I.I.Q.Q.Q.1+e.e.e.a M M M *.y.M M *.y.*.M y.y.y.*.y.*.*.y.M y.*.y.y.y.*.*.M M *.y.*.e.*.*.*.M *.M y.y.*.y.M M 1+*.M M *.*.[+[+*.y.*.y.M 1+[+*.1+*.*.[+*.*.[+*.*.[+1+ +[+*.*.1+*.*.1+[+*.*.*.y.y.y.*.*.M y.M n+y.y.M *.*.y.[+*.*.*.*.*. +[+ +[+*.*.*.*.*.*.*.*.y.[+*.*.1+[+[+*.*.*.[+p.*.p.y.p.y.y.y.y.y.y.y.[+*.p.y.[+[+p.*.*. + +p.*.1+p.[+[+*.[+[+*.[+[+y.[+[+y.*.p.*.[+*.*.*.[+*. +*.[+*. +*.*.[+[+1+ +[+ + + + + + + + +[+ + +1+ +*.*. +[+t.[+5+5+ + +5+[+*.*. + + + + +5+ + +t.t.[+t. +5+ +t.5+5+t.5+ + +5+ + +t.t.5+t.5+t.5+t.t.5+5+t.5+t.Q.Q.Q.y+s 0 p.2.:+E 4.x.>.*+;+:+= A !.!.!.!.!.!.!.!.{ p+:.'+Y.X E+]+6 G ; 6 c+R /+j.v $+$+$+d+[ j U j j '.'.1+_ a E+w [+j v 3 3 p 3 3 [ z._ _ U z._ j [ v $+p p 3 p ' v j k T _ $.j [ v p p 3 $+[ - 3.G < < 6 e.w.O ].l 3 [ j e+7+` 3+8.6 3.X s.s.- U F+v [ ,.8+i.@.s.H+H.b n+ +Q.I.o.}.Q. +N.7.u.9 f+(+k+b +.o.I.w.D.x+K.", "b+G.;+G.G.o+o+o+:+o+o+o+o+o+o+o+f+>+u.9 f+9 z -+z z 9 z 9 z z z 9 9 9 f+f+f+o+o+o+f+u.9 z 9 9 z 9 z &.9 9 9 9 9 f+>+D D ++++++++++8.G.o+n k+i.w z.z.n+z+E+R Q.I.w.O O O O D.D.D.|+|+D.D.|+|+D.x+D.o.o.o.I.I.Q.$.& [+$.e.1+*.*.e.*.*.*.e.*.*.e._ *.*.$.*.1+*.e.*.R a *.*._ 1+*.M _ *.y.*.*.y.*.*.*.y.e.*.*.M *.M *.R y.y.*.y.M M *.y.*.*.*.*.*.y. +*.[+[+[+1+[+[+,+*.1+y.*.[+*.[+[+y.y.*.*.*.y.y.*.M *.y.y.*.[+[+y.*. +p.*.*.[+p.*. +p.*.*.*.*.*.p.*.y.*.*.*.1+[+[+*. +*.*.*.*.*.[+y.y.y.p.[+y.y.y.[+[+[+*.*.[+*.*.p.*.[+[+1+*.*.[+y.[+y.[+*.*.[+*.[+*.[+*. +1+*.*.*.*.*.y.*.1+[+y.[+1+1+ +y. + +[+ +1+ +t. + + + + + + +1+ + +*. + +t. +t.5+5+[+ + +[+ + +t.[+5+ +5+ +t.t. +5+t.t.5+t. +t.t.t.t.5+t.t. +5+t.[+ +t.t.t.t.t.t.t.e+5+t.t.5+Q.}.y+<+e+B J.u.x.{ E :+;+;+p+x.1.!.!.!.!.!.!.9.!.4.:+4 * Y.- E+G+]+]+]+]+c+k '.d+v $+$+$+$+$+d+[ e+e+U '.$._ z+G+H+n+l+v 3 p p $+$+j z.z.$._ k k j w.$+$+p p p p $+j._ z.5 z.2 z.& [ $+$+3 $+d+k 3._.D D G 5 & <.O O j 3.o M.M.i *+5.W 6 @.! ]+! s.J P ,.- R.i.i.H.E+b M [+Q.I.I.o.Q. +*.B C+*+*+*+b+i.b $.I.I.w.> ].K.", "*+o+o+f+o+f+o+f+f+u.f+f+f+f+o+o+o+f+9 u.z z &.z `.&.&.&.z 9 9 9 u.9 f+9 9 9 f+f+f+f+9 f+9 9 u.u.9 &.z 9 u.f+f+f+>+>+D 8.k+++++B.i.k+A+G.W Z )+E+n+n+R b P.z+1+& I.w.s w.e O O > |+|+|+S |+].S K.S K.r.K.K.L U.x+D.D.s o.I.& & t.e.& $.*.1+ +*.$._ +*.1+_ 1+*.1+*.y.y.*.1+_ *.M *.y.*.y.M *.a *.y.*.*.*.*.e.*.*.[+[+*.y.y.*.y.*.*.y.*.*.*.[+*.1+*.*.e.1+*.[+1+1+*.[+*. +[+*.1+*.*.*.*.y. +[+ +p.y.*.y. +[+[+*.y.*.[+*.*.*.[+[+[+*.*.*.[+*.*.*.*.*.y. +[+*. +[+*.[+[+*.*.[+p.y.y.[+n+y.[+*.y.*.p.*.[+p.[+1+p.*.*.*.*.y.[+[+y.*.p.y.[+p.[+*.[+[+*.*.*.*.*. +[+[+ + + + +p.*.*.*. + +1+[+[+*.1+[+ + + +[+ + +t.5+ + + + + + + +*. +[+t. +t.t.5+ + + + + +[+5+t.t.t.5+5+t.t.5+ + +t.t. +t.5+t.5+t.t.t.t.t.5+[+ +t.t.5+5+5+t.5+t.5+t.Q.Q.Q.Q.Q.I.o.y+/+4+G.`.{ { N :+;+*+>.~.!.9.!.!.!.!.9.!.1.E *+r+* J g X f f 1 f f z.k j j.$+$+$+$+$+$+$+v v d+0 t.'.t.X )+X.y.'.d+p 3 K 3 j.U z.T _ _ z._ j [ $+p p ' p ' p d+_ 5 5 5 1 z._ w.v 3 $+$+d+U X o n (+c+z._ <.w.O _ 3+o+++r+F o+i+W ]+G+G < 3+]+h+J * R.a+S.)+@.H.z+y.& 0 o.o.o.0 t.p.4+J.*+:+o+A+X.z+ +5+I.O |+].].", "f+f+o+o+f+u.o+f+9 u.i+f+u.f+f+f+f+f+u.f+9 z `.`.z `.z &.9 z 9 f+9 f+f+f+f+f+f+f+f+i+9 f+z 9 i+u.9 z &.9 9 i+f+f+f+>+b+k+k+B.k+B.i.k+k+k+k+Z i.H+z+z+R R z+z+n+e.& I.w.w.O O s O D.|+|+|+S ].S K.K.K.: : : : : : .K.: K.S |+x+D.O o.I.Q.Q.Q.& $. +$.1+1+ + +1+$. +e.*._ *.*._ *. +*.*.1+*.*.M *.y. +[+1+M M *.*.*.y.[+*.*.*.[+*.*.y.*.y.*.*.*.[+ +[+[+1+1+[+[+ +*.[+y. + +[+ +*.*.*.*.*.1+*.[+*.*.*.y.[+*.y.[+y.y.y.[+*.*.*.*.*.y.y.M *.*.*.*.y.*.y.*. +y.*.[+1+*.[+[+*.[+y.[+p.[+y.y.y.*.[+*.*.*.y.*.y.[+ +[+*.*.[+[+[+y.*.*.*.[+*.[+p.1+y.y.y.*.[+[+p.*.*.*.*.[+[+ + +*.[+[+[+*. + +[+y.[+1+1+1+ +[+ + +t.t.t. + + + + + + +1+ + + +t.5+5+t.5+ + +t.t. +5+t. +t.t.t.t.t.t.5+t.t. + +t.t.t.t.t.5+t. +/+5+ +5+[+t.t.t.5+t.Q.5+}.Q.t.Q.Q.Q.y+<+y+p.2.f+x.~.{ u.*+;+:+= A !.!.!.!.!.!.9.9.8 >.;+q.* J J - - X X k - '.P d+$+$+' 3 ' $+$+$+$+v $+j.[ o.0 ,+.+X.m.l+v 3 p 3 p d+z.f z.U k z.'.j v v $+p $+p $+$+d+U 5 1 G+c+5 z.[ j.3 $+v [ P ,+s.o G 1 e.w.<.6+6+_ *+&.b+C+F n b+W G+@.G D D _.M.g ` _.]+}+r+X.w n+1+I.w.y+D.o.o.t.p.q.o+z z 9 (+i.!+1+& s x+K.].L ", "f+f+f+f+u.9 u.z &.f+>.f+z -+9 f+>.z 9 &.z z z z &.9 9 9 i+i+>+f+f+i+i+f+f+9 9 i+f+o+f+z 9 9 9 f+9 9 u.9 >+f+f+>+>+D b+k+C+k+6 B.B.i.i.)+X.)+@.P.b z+n+z.R R M *.& & I.+.I.I.w.}.O e D.|+|+U.S K.K.S g+: : : : : [.[.[.[.[.: : : .K.K.K.].|+D.s I.Q.Q.& Q.$.t.$.$. +1+_ +*.1+e._ 1+*.1+e.*.*.M *.y. +*.M n+*.*.*.*.*.1+[+*.1+ +y.*.*.[+y.*. +1+_ *.1+1+*. + +*. +*. +[+*.1+*.[+*.*.*.*.y.*.*.[+*.y.[+[+*.[+[+y.p.*.*.p.M *. +p.M p.*.p.*.[+*.*.p.*.*.p.[+*.[+y.p.[+*.[+*.[+y.M y.p.y.y.p.y.1+p.y.*.p.*.*.p.*.*.*.y.[+*.[+[+*.y.M y.*. +p.*.[+*.[+*.*.*.[+[+[+ + +[+[+*.p.*.*.[+ +t.[+[+[+*.*.[+ +[+ + +t.t.t. + + + + + + +[+ + + +t.t.t. +t. + +5+t.t.t.t.t.5+t.5+t.t.t.t.t.5+t.t.5+t.t.}.t.t.t.5+t.t.t.t.t.t.t.t.t.5+Q.t.Q.5+0 Q.Q.0 Q.o.<+e+H J.N { { E p+;+;+p+E 8 !.!.!.8 !.!.9.!.4.u.:.` g V J J J J J U j F+d+d+$+' $+p $+p p 3 $+3 3 $+j.j.j.e+h+a+m.l+v $+p 3 $+d+z.z.$._ k z._ [ v $+p p p ' p p $+j - 1 f 3.f z.[ j.p $+F+C.U /+,+#+3.z.w.O > > |+0 7.z c.#.2.2.o G+X z.3.< n A+3.v+8+3+6 H.2.G P.n+$.I.O O <+o.0 t.p.C+p+-+) &.D 6 P.$.6+D.K.].x+w.", "f+f+f+f+9 i+f+f+9 9 z z 9 z 9 9 z z z z `.4.&.z f+f+f+o+(+b+b+G.f+u.9 f+f+f+u.9 o+o+z &.9 9 f+9 9 z 9 z >+D D D (+W 1 H.H..+N.C+6 .+.+)+H+H.4+b b R *. +1+1+$.Q.Q.Q.I.I.& *.n+*.w.O O s O x+|+S K.S K.S ~+: ~+[.~+[.|.k.B+T.k.B+k.k.k.|.k.[.: .K.].].x+x+O o.o.I.Q.& $. +1+$.$.1+$.e. +1+e.1+ +1+*. +1+e.1+e.y.*. +[+1+1+e.*.*.y.[+e. +*.*.*.*.*.[+*.1+*.*. +1+1+*. + +[+[+*.[+[+1+*.[+[+ +*.[+*.*.1+[+*.[+ +*.[+*.y.*.M y.*.1+*.*.*.*.*.*.*.*.*.*.*.*.[+y.p.[+[+[+[+p.[+y.[+y.y.*.y.y.[+y.*.*.[+*.*.*.y.*.[+p.*.*.*.*.*.*.*.*.y.p.y.*.*.*.*.*.*.*. +*.[+[+[+p. + +[+*. + +[+[+p. +[+ +[+ +*.*. + + + +t. + + +t. + + + + + + +[+ +5+ +5+ + + + + + +5+ + + +t.5+5+t.5+t.5+t.t.t.t.t. +5+t.t.5+t.}. +5+ +5+5+5+5+t.5+t.5+}.5+Q.Q.Q.0 }.o.o.y+/+^.o+E { { E b.J.b.>.x.!.9.9.!.8 8 !.!.!.E *+2.'+Y.- - - J U P P F+d+v $+$+$+' p $+$+' p $+3 3 p 3 3 $+v e+,.l+e+$+3 p 3 3 [ 5 z._ _ z.k '.[ v $+p ' p $+$+$+p d+U f f 5 X k j d+d+d+g s.R '._ }+E+R w.> ~+S S x+s.;+G.k+'+s.L.J '.j _ ! i #.3.g A.:.k+E+R.C+1 z+ +Q.O O s w.0 t.L.2.p+x.) &.D 6 a +.D.|+].x+o.I.", "f+u.u.9 u.u.f+u.u.z z z E ) 9 u.z z &.z E -+`.9 D o+f+D G.G.b+G.o+f+f+9 u.9 9 9 9 z 9 u.9 f+9 9 z &.z &.9 (+6 B B.H.H.N.4+4+^.B X.)+H.H.H..+#.P.z+n+R y.'.t.Q.Q.I.I.I.Q.P.(+D B.Q.O [+#+n+O |+x+D.|+].S .S : : [.[.[.k.|.k.T.B+&+B+q D+Q &+Q q B+k.|.[.[.l.[. .K.].x+D.o.I.I.Q.Q.& $. +$. + + +t.t. + + +1+[+1+ + +1+1+*.*. + +1+*.*.*.1+y.1+1+*.*.1+*.1+ +1+[+1+[+[+y.*.[+*.y.1+*.1+1+ +[+[+*.[+1+*.1+*.*.[+ +*.*.*.M *.*.*.*.*.*.*.*. +*.*.*.[+*.*.*.*. +[+*.y.*.1+*.y.1+*.*.*.y.y.y.y.y.*.*.*.[+p.[+[+*.*.*.*.*.p.*.[+ +p.y.*.*.p.*.*.[+[+ +p.*.p.[+[+[+ +*. +[+ + +[+[+ + +1+p. +[+ +*. + + + +[+ + +1+ + + + + + + + +t.t. + +t.t.5+5+ + + +5+ +5+ +5+[+t.t.t.t.t.t.t.5+t.5+t.5+ +t.5+t. + +t.}.t.5+ +t.t.t.5+t.5+t.0 5+}.Q.Q.}.0 o.<+y+L.++u.{ !.x.>.;+;+*+= 8 9.!.!.u 8 !.!.!.{ z ;+q.h+s.M.3.3.s.- J [ d+).d+).' $+$+' p p p p p $+p 3 p 3 3 3 $+d+d+v v 3 v 3 $+P z.z._ U z.z.'.[ v p ' p p p p p $+v P - f M.- J U P d+F+` P.R t.L._._.1 & > S S S ].j R.r+2.w ,+'.j.v j.j J M.M.L.,.g 8+i.w #+^.@.b [+I.o.D.o.0 t.p.B 2.*+z z >+8.1 e.s ].K.x+O I.w.", "f+9 f+9 z z u.9 z 9 z 9 9 9 9 z `.`.z &.`.`.&.&.9 9 f+i+o+o+f+f+u.9 f+f+9 z z z 9 9 z &.`.E `.z z &.&.9 f+f+k+X.C+)+B 4+B }+.+.+.+B.)+i.H+B @.B.P.R R y._ $.Q.& Q.Q.I.1+8.9 `.7.Q.z+D &.:+Q.O *.@.b O K.K.|+].: ~+: : k.[.|.k.k.B+B+B+&+Q B+D+Q Q Q q q q B+q 7 7 7 [.: : K.K.|+x+g.}.I.I.Q.& & & 5+$. + +$. +$.$.$.1+1+ +*. +*.e.1+*.*.1+*.[+$.1+*.1+e.1+[+ +[+1+ +[+[+*.*.1+M *.[+*.[+1+[+[+1+*.[+[+*.[+*.[+ +[+*.*.*.p.1+*.*.p. + +[+[+[+p.*.[+*.[+y.y.*.p.[+[+p.[+*.p. +*.p. +[+*.*.y.y.y.p.*.[+*.*.p.[+ +*.*.*.*.*.y.*. +y.y.y.M p.*.*.*. + +[+[+*.[+[+[+*.*.p.[+*.[+ +[+[+[+[+ +[+ + + +[+ + +[+t.t. + + + + +t. + + + + + + + + +5+t.5+ +[+5+[+5+p.t.t. + + +5+t.}.t.t.t.t.t. + +5+t.5+t.5+t.t.t.5+5+t.5+t.t.t.5+Q.t.5+Q.Q.Q.}.o.y+y+e+'+J.N { { E :+J.;+p+x.8 9.!.!.{ 8 !.!.8 x.:+4 ` h+f G+]+6 G+E+- j d+v $+$+' $+' ' ' $+' 3 p p 3 3 p p 3 $+3 $+$+$+' $+3 3 $+U 5 z.$.U z.z.j j.$+3 $+$+p ' $+$+$+$+F+J X M.- J U U P U ` S.R '.'+n >+G a w.> S S O k B.B.4+#+'.[ j.L $+j.d+P P 7+j 7+u+a+m.9+s.@.b *.I.D.U.o.Q.,+#+.+C+:.*+:+J.k+b 5+O |+L o.O O |+", "o+f+z u.u.9 9 z f+z z z 9 u.u.z E `.`.E -+-+&.&.-+-+`.`.`.-+9 z z z z `.`.&.9 &.9 &.z `.&.&.&.&.&.9 &.&.9 i+D ++++k+B.B.)+B.B.^.H+4+.+^.)+.+4+B w b n+,+t.Q.Q.t.Q.$. +z+8.*+o+}+5+6 &.{ u.Q.a D 4.z /+|+$.w b w.K.: K.K.: |.|.k.k.k.T.B+B+&+Q D+D+D+0.D+0.D+Q Q Q Q Q Q B+B+|.|.[.: K.K.U.x+D.D.o.I.I.Q.Q.& & Q. +5+ +1+1+$.e.e. +[+ +t.[+ +$. +[+*.*.*.*. + +1+$.1+1+1+1+[+*.[+[+*.*.1+[+1+ +*.*.[+*. +[+ + +[+ + + +*.*.y.*.*.*.*.[+*.[+*.*.*.p.[+y.*.y.*.*. +*.*.[+*.*.*.1+[+p.*.*.p.*.p.*.*.*.[+[+y.*.*.y.[+[+*.*.y.*.[+*.p.y.*.y.y.y. + +p.[+*.[+*.*.*. +[+*.*. +*. + +p.*.[+[+*.[+[+[+[+ + + + + +t.5+ +5+ +5+ + + +[+[+ + +[+t.t.t.t.t.5+t.5+5+t. +5+ + +5+t.t.t.t.5+t.}.t.5+[+ +t.t.t.5+[+t.t.5+t. +t.t.5+5+5+5+t.0 Q.Q.Q.Q.0 y+g.<+/+2.f+x.8 { N *+:.*+z ~.!.9.9.!.{ 8 !.!.{ u.:.` g g 3.]+G G ; ]+5 k P d+$+).$+' $+' p p $+' p p $+p p p 3 p $+' $+' $+3 v 3 d+k 5 T _ k X k 0 d+$+' p 3 ' p p $+$+d+U - M.- X - - V J Y.` ! R l+#+G.i+W 2 C <.6+> O ]+D b+@.}+,+j v $+L 3 v $+v d+v d+w+L.s.H.#+P.b 1+Q.s ].L o.t.N.^.7.J.G.;+A+)+b $.s O O s O ].K.", "o+f+f+9 z z 9 z 9 z z z 9 9 z z &.&.`.&.`.-+-+`.`.-+`.&.z &.&.z &.&.&.`.`.`.z &.z `.z `.`.`.`.&.&.9 f+i+9 >+D ++++++k+i.B.i.A+G.++B.B.i.B.i.k+B.@.}+#+n+[+ +Q.t.Q.Q.$.z+k+++.+Q.M k+>+u.^.I.6 `.1.E '.e.i+4.z X ].Q.S.! 0 [.[. .K.[.k.B+&+B+B+B+Q B+0.D+0.D+0.0.D+0.0.t+0.0.0.Q d Q k.7 |.[.[.: : .r.].|+e I.I.& & Q.5+1+ +5+1+$. + + + + + + + + +_ 1+*.*.1+1+1+*.[+[+*.[+[+ +[+ +y.*.[+*. + + +[+y.*.*.y.[+y.,+y.*.*.*.*.[+*.[+*.[+[+[+*. +*.*. +p.*.y.y.y.[+[+[+[+[+y.y.[+*.[+y.y.y.*.*.*.p.1+*.p.*.[+p.*.*.[+[+*.p.*.p.*.y.y.*.*.[+p.*. +*.[+*.*.[+[+ +[+*. +*. +*.[+ + +*.[+[+*. + + + +[+ +*. +*. + +t.5+t.5+5+ + +[+5+ + + + + + + + +5+t.t. + +[+5+ +t. +5+5+t.t.t.5+t.[+t.5+t.t.5+t.t.t.5+5+t.5+5+ + +t.5+t.Q.Q.Q.Q.Q.Q.Q.}.y+L y+p.7.u.{ !.{ u.;+:.p+x.8 9.9.!.8 { 8 !.!.~.:+i g ,.,.f c+; G W ; G+k j d+v $+$+' ' ' ' p p $+' p p p 3 p p p 3 $+p p ' p $+$+[ X z._ j k z._ [ v p ' ' p ' p $+d+[ U X f f - - J U J - g * R.w j /+^.< 6 M w.6+> 6+w.i 9 D H+.+R '.[ v v v 3 $+3 $+$+d+p.R '+)+}+H.b *.Q.D.].l <+0 p.q.J.:+u.f+D 8.X.z+& I.w.O |+: : ", "f+f+z z 9 u.u.z z N `.z z z z z z -+&.E `.`.-+-+) `.E `.`.`.&.z `.`.`.`.z &.`.&.&.&.`.&.z &.`.&.9 9 D ++++8.8.8.J.J.6 B.++7.J.o+k+i.)+C+B.C+i.i.^.X.G+H.b n+R y.n+n+M P.W Z [+5+1+6 k+X.Q.5+6 D u.B.s 1 `.u x.'.w.(+-.-.R. .I.@.k+C.[.[. .K.: 7 &+D+B+D+Q D+Q D+0.0.0.Q t+0.0.t+t+0.0.Q . Q Q D+B+B+7 k.[.: K.].K.x+O }.I.I.Q.Q.Q.t.$.$. + + + + +1+$. +*. +1+1+*.e.1+ +[+ + +[+t. +1+1+1+ +*.*.*.[+*.*.[+*.1+*.y. +*.[+[+[+[+ +*.*.p.[+[+*.y. + +*.*.[+y.*.*.[+[+[+*.[+[+[+[+[+t.[+[+[+y.*.*.1+p.y.[+[+*.*.*. +[+[+ +[+1+*.y.y.y.[+p.*.*.*.y.*.y.[+[+*.[+y. +*.*. + +*.[+[+[+ +[+ + +[+ +[+*.*.[+ + +*. + +t. + + +5+ +t. +[+[+ +5+t. +t.5+[+ +t.5+ +t. + + + +t.t.t.}.t.5+t.t.5+t.t. +t.t.t.5+t.t.t.t.5+t.5+5+5+t.5+5+Q.Q.0 Q.Q.I.o.<+<+e+4+;+E 8 { = *+J.:.p+{ !.!.!.1.{ ~.{ 9.!.x.*+` Y.P J X @.c+n.]+G 1 b l+F+$+).$+$+p $+p $+$+p $+p 3 p p $+3 p $+' 3 $+p ' p 3 j z.5 T j X z.'.[ v $+3 p p ' $+v [ k 5 3.]+! f - U U m J * 8+R.s.'.y+l+9+_ w.> S > S |+^.o+>+G+R.E+J j j [ j.d+j.v v $+e+a+b }+8.P.H.n+$.I.s U.U.3 <+l+B J.>.E E &.f+W P.e.& O K.K. .l ", "z u.z `.z 9 z z z `.`.z 9 z z `.z -+4.-+-+`.-+`.z &.-+`.`.&.`.`.`.E `.E `.E `.`.-+`.`.&.&.z `.z f+j+k+k+++++++A+b+o+b+++A+A+A+b+8.++i ++C+C+++++++k+X.H+H+P.z+*.*.1+1+b 6 X.Q.Q.e.6 6 +}.& 6 k+@.o.s P.b+o+2.x+e.( 1.{ #+x+W -.9.*+ .D.)+b+B .k.[. . .|.Q B+D+q D+0.Q 0.0.Q 0.0.t+0.0.0.0.0.. t+0.0.0.0.Q B+&+k.|.[.: K.K.x D.O y+o.I.I.Q.& t.Q.$.1+$. +[+1+[+ +*.*.[+e.*. + +[+[+1+1+*.1+1+ +e.[+1+1+ +*.1+[+y.*.*.*. + +y.*.[+*.[+[+[+*.y.p. +*.*.*.p.[+[+[+*.y.[+*.y.*.p.y.y.[+[+[+[+*.y.*.*.y.y.*.*.[+*.[+[+[+[+p. +*.[+[+*.[+[+p.*.*.*.*.*.y.[+*.[+*.[+[+p.*.[+*. +*.*.[+[+[+ +[+ +[+ +*. +*. +[+ + + + + +[+ + +t.t.[+t.[+ +5+t.[+t. +5+/+t. + +[+t. +t.5+t.[+t. +t.5+t.t.5+t. +5+ + +t.5+}.t.5+t.5+t.t.Q.t.5+Q.t.Q.Q.}.0 }.y+<+<+/+^.:+x.!.8 N ;+7.;+= 8 9.9.!.8 { ~.8 !.1.>.:.* 7+F+7+J X f z.5 3.1 k j d+$+$+$+$+$+' ' ' $+p $+' $+p p p 3 p p ' p 3 p $+$+$+U f z.'.j X - j d+$+' p p p p $+d+U 5 n.; G G 1 - P d+F+P ` i o w '.x+L L . .k.k.0+0+K.'.o ++H+a+}+s.k _ J j j j [ [ [ ,.f.1 #+++X.H.n+$.I.o.|+].l <+y+Y.J.z { -.q+&.j+c+e.}.|+K.K.].D.", "9 9 u.z z z 9 z N z &.z u.z z z E -+-+-+4.`.`.&.`.E -+-+-+4.-+`.-+&.-+`.&.&.z z &.`.`.&.z &.`.&.D k+i.)+B 4+J.G.++C+o+o+++k+k+C+++A+b+++k+++k+k+Z G+H+H.b y. +$.t.t. +b 6 E+Q.I.e.c+1 w.o.+.c+; [+O w.P.G B o.|+a ++G.r+U.+.D 1.u 2.].c+-.9.N L r.H.J.++U.B+: ]. .|.q D+D+D+0.0.0.0.0.t+0.. 0.0.0.. 0.. t+t+0.0.0.0.D+&+B+k.|.[.[.: . .].].x+s I.I.I.& & 5+ + + + + +*.[+ + +[+ + +*.*.1+1+1+e./+1+ +*.*.[+y. + +*. +*.[+[+*.*.*.[+[+[+[+1+*.*.p.*. + +*.*. +1+t.y.[+y.[+[+*.[+[+[+ +*.[+*.y.y.*.*.*.[+[+*.*. +*.*.[+[+[+ +*.*. +*.*.*.*.p.*.p.*.*.*.*.*. +*.*.y. +*. + +*. +*.*. + + +[+ +[+ +[+ +*.*. + +*. + + +*.t. + + +[+ + +[+ + +t.5+[+5+t. +5+[+ + + +t.t. +t.5+5+t.5+t.[+5+ + +5+t. +t.t.t.t.t.t.t.5+t.Q.t.Q.Q.5+5+Q.Q.o.<+y+y+H 7.>.{ u x.u.:.7.:+E !.!.9.!.{ x.x.{ { { :+2.g F+d+F+P j U k k k k ,+[ d+d+$+$+' $+$+$+$+' $+p 3 p p p 3 p p p 3 p $+$+3 p v U 5 z._ _ z._ j v $+' p ' ' ' $+j.- ^ n.~ W W (.k [ ).$+).` 3+o E+Q.l m+] 7 Q D+t+D+D+[.].e+C.9+Y.s.f s.f X - J U U j J h+C+1 *.'+X.B n+ +Q.o.D.g.<+y+e+/+2.u.4.4.) &.j+P.& |+K.K.D.6+w.", "u.9 z 9 z z z z z `.`.&.z E E &.z -+-+-+-+-+-+`.-+-+) -+E 4.`.-+-+`.4.) `.`.`.`.E `.`.9 z 9 9 9 c.++b+++C+*+D 6 X.C+)+X.X..+.+4+^.)+++i.1 .+B .+H..+B ^.H.R [+t.t.[+n+H+X.z+Q.Q.y.X.P.w.o.5+6 (.t.O }.5 W a |+x+e.; H+y+K.& 6 b+4 <+D.8.4.1.J.K.2 q+9.8 [ : P.D J.0 B+|. .].: Q Q 0.Q 0.0.t+. 0.t+0.0.. 0.. . t+0.. 0.t+0.. 0.0.Q D+B+B+7 |.[.: K.K.U.x+D.I.I.I.5+$. + + + +$.$.1+1+1+1+1+*.1+1+ +[+ + + +*.*.*.[+*.*. +[+[+[+*.*. +[+[+p.1+*.1+[+*.*.*.*.y.y.y.[+*.p. +1+[+*.*.[+p. + +p.*.[+*.p.*.*.*.[+ +*. +*.*.*.*.[+[+[+[+ +[+p.*.y.[+ +y.[+*.[+[+[+[+[+*.*.[+y.*.*.*. +[+[+[+[+ +[+[+/+[+ + + +[+[+ +[+[+ + + + +[+t. + + +[+5+ + +t.[+ +5+5+[+t. +t. + + + +t.[+t.t. + +t./+t.5+t.t.t.t.t. +t.Q.t.5+t.Q.t.5+Q.Q.t.Q.5+Q.Q.o.g.<+e+4+;+x.!.!.E *+:.J.p+x.!.9.9.!.{ { ~.A x.z ;+'+7+).).$+).F+d+[ P j j [ d+v $+).$+' $+$+' $+' $+$+' $+$+$+p p $+p $+3 3 $+$+$+d+X 5 k j k X _ [ v $+$+' ' p p p v U f 5 n.]+W ; k [ $+p $+* ++G+R w. .|.d Q . . . . . q [.l L [ U Y.M.f f f s.s.X X k - M.B.1 +9+'+.+H.[+Q.I.o.w.o.Q. +p.4+;+f+f+f+(+6 a I.D.x+o.I.I.w.", "9 u.f+u.u.z z z z N `.z z z &.z `.E -+`.-+-+-+`.`.4.4.) ) -+4.) ) -+4.) 4.-+`.`.`.&.z `.`.`.&.9 8.b+o+f+8.:+(+X.X.^..+4+)+)+^.4+2.C+)+C+C+.+.+w N.N.^.++Z y.[+[+[+[+H+B.B.m.0 t.z+]+n+Q.I.e.6 G+I.O I.^ 6 & |+D.2 ; b |+K.+.6 G+o.K.D.c+++B.y+ .X.&.{ :+r.+.) 9.!.H [.*.D o+#+|.k. .U. .q 0.Q Q . t+. 0.0.. 0.. . t+. . . . t+. 0.t+t+0.D+D+D+D+D+B+B+|.[.: K.K.U.<+I.}.I.& Q.Q.5+Q.5+5+1+1+ + +1+1+t.[+[+1+ +[+[+*.*.*. +*.*.[+ +*. + +*.y.*.*.*.p.*.[+[+ +[+[+ +y.*.*.[+ +[+*. +[+ + + +[+*.*.*.p.[+*.*. + +[+*.[+*.*. + +*.[+*.*.*.y.[+y.y.y.[+[+[+[+[+[+[+*.[+ + + +*.[+ +*.[+[+ +p.[+ + + + + + +[+ +[+ +[+ +*. +[+t.[+ +t. +[+ + +5+t.5+ +t.t. + + + +t.t.5+5+5+t.t.t.5+ +[+t. +t.t.t.t.t. +t.t.5+e+5+5+t.}.t.t.Q.0 Q.t.}.o.y+<+y+/+2.f+x.8 { N ;+7.*+N { !.9.9.!.{ { { { x.:+2.g F+v $+v ).v ).).d+).d+d+d+).' $+$+' $+$+$+$+v $+v $+$+3 p $+$+p $+p $+$+$+$+v [ f 5 T j z.X '.F+$+$+p ' p p ' $+$+[ _ z.z.5 ]+c+_ j.$+p ' m 8+X '.L l.} q 0.. 0.. . . q } l.l 3 [ J - - X s.s.s.f s.#+f S.a+H.m.p.m.}+P.*.Q.s s o.Q. +y.b B 2.++J.k+B.P.e.& I.Q.& & }.|+", "z z 9 9 z z z `.`.&.E `.E -+-+`.-+-+-+`.`.-+4.-+-+4.4.4.4.4.4.4.-+-+4.4.-+-+-+&.z `.&.z z z &.9 o+C+++G.8.u.8.i.)+)+X.C+^.B.C+C+C+i.)+C+A+.+w B 4+4+4+.+H+n+[+/+p..+J.(+J.H t.[+)+++w Q.Q.z+G H+I.o.Q.n.c+Q.D.D.2 ; e.|+K.+.; ^ K.: D.n.(.I.: K.z.k+B.0 : e.f+4.E <+U.i+9.9.7.l.I.D 9 ++ .B+: s L |.0.0.t+0.0.0.. . . . . . . . . . t+. t+0.t+0.t+0.D+0.0.D+B+k.|.|.: K.K.U.|+g.O s Q.5++.Q.5+Q.1+5+ +5+t. + + + + + +[+ + + +*. +*.*.*.*.*.*.*.*.*.*.*.*.*.*.y.*.[+1+*.1+ + +[+ +[+[+*.*.[+y.*.*.*.*.*.*. +*.1+*.[+*.p.*.*.*.[+[+*.[+[+p.*.*.*.[+[+[+ +*.*.y.[+[+[+[+*.y.[+ + + +[+ + +p. +[+ + + + +[+ + +[+ +*. +p. +[+ +t.t. +t.5+t. +t.5+t. +t.5+t.t.t.5+t.t.t.t.t.t.t. + + +5+ + +5+5+t.t.t.t.t.5+t.t.t.t.t.t.Q.Q.Q.5+5+Q.}.<+<+e+N.:.E !.!.{ :+7.:.p+x.!.9.9.!.!.{ 8 { { z G.'+7+).v $+).$+v $+$+v $+).$+$+).$+).$+$+$+' $+v ).$+v $+$+$+$+$+$+3 $+$+3 v v d+[ j f 5 _ [ X z.j [ $+p p ' ' p p ' ' v F+j j j k k j j.$+p ' d+,.w+d+l @ d d Q . . . . . Q d } m+3 j.j U J J k - - - X - '+a+w #+a+.+#+#+b *.Q.w.D.o.Q.*.N.P.X.i.i.i.X.P.z+ +1+e.$.& C ]. .", "9 z `.E `.&.&.`.E `.E -+-+-+) x.4.4.4.-+4.4.4.4.4.) 4.{ 4.4.4.4.{ 4.4.) ) ) `.`.-+-+&.&.z `.-+`.&.9 8.C+k+b+C+J.k+q.q.)+B.2.C+C+X.X.A+++X..+4+4+)+B N.H b #+p.#+)+b+b+G.J.m.p..+b+f+a+t.[+i.D )+Q.w.e.G+G+Q.O I.5 G & |+|+$.~ a K.K.6+~ (.|+: g+2 ; $.: [.& 6 B.,+[.s b+-+E ,+: 6 u 9.E .r.k+z ( y+0.[.L <+: 0.t+Q Q 0.0.. . . t+. . . . . t+. . t+t+t+t+t+D+&+D+Q D+&+T.k.|.[.: .r.<+D.D.s }.I.5+Q.Q.5+5+5+ + + + + +t.t.5+ +*. + + + + + +*.*. + + +*.*.*.*. +1+[+*. +[+ +*. + +*.p.[+*.*.p.*.*.y.*.*.*.[+ + +*.p.*.*. +*. + +[+*.y.y.*.p.*. +[+ +[+ +[+[+y.[+*. + +[+[+[+ +[+[+*. + +/+ + + +[+ +*. + + +[+ +*. +[+ +[+t.[+5+t.t.5+ +}.t. +}.t.t.t.t.5+t.t.}.t.}.t.5+5+ + + + + +t.t.t.t.t.5+t.5+t.t.5+t.5+5+5+t.t.Q.Q.5+Q.o.<+<+e+q.o+-+!.8 E *+C+:.z A !.9.9.!.{ A { 8 { >.7.L.F+$+$+$+$+$+).$+).$+v $+$+).$+$+$+$+$+$+$+$+v v d+d+v d+$+$+v $+v v v [ [ [ j _ z.f 5 _ U X z.j v $+$+' p p p p ' p ' $+v d+j.[ [ d+$+' ' p ' ).d+3 {.] ] d q q Q 0.0.Q q q } @ l v v [ F+P P j j /+J C.- ^.#+,+i ++P.m.m.$.o.D.x+<+y+Q.m.4+i.J.b+b+++i.H+a a *.& w.|+K.K.", "`.E -+-+`.`.`.-+`.`.) ) -+4.4.4.4.4.4.4.{ 4.4.4.x.) 4.{ q+{ 4.4.4.4.4.-+`.-+`.`.-+4.`.-+-+-+-+-+`.&.9 f+8.C+:+9 X.X.q.C+C+7.2.J.)+q.J.*+b+J.A+C+B H.N.N.N.N.B )+J.b+b+J.^.n+H.8.o+;+m.[+H.o+z i Q.Q.X.D 8.t.w.5+(.G Q.D.|+a (.& S K.I.(.5 S : K.2 ~ O [.: T ; 2 .[.D.c+B.m.: K.6 u.-+^.|.*.q+9.u 0 : P.z x.}+q k.x+I.L q t+Q q q Q t+. . . . t+t+t+t+. t+t+t+D+t+t+0.D+D+0.0.Q q B+k.[.|.: .K.K.|+2+O }.I.Q.5+ +5+ + +5+Q.5+5+t.t. + + +[+ + +*. +[+*.*.*.*.*. + + +[+ +[+ +*. + +*.*.[+[+*.[+p.*.*.y.[+*.*. + +*.*.*.*. +y.p.*.*.y.y.y.M *.*.[+ +[+ +[+ +[+*.[+ +[+ + +[+ +*. + +[+[+ + + +[+ + + + + +1+*. +[+ +[+ +[+t.t.t.t.t.t.}.t.}.t.}.t.}.t.}./+}.t.t.t.t.t.t.t. + + + + + + +5+t.t.t.t.t. + +t.5+t.t.t.t.t.Q.t.Q.0 }.<+<+y+p.C+>.A !.{ u.:.i b.= 8 9.!.9.!.8 8 { !.{ f+2.,.v $+$+$+' $+$+$+$+$+$+$+$+$+$+).$+$+).$+v $+$+$+v d+v d+v d+e+[ j j j _ _ z.k z.f 5 z.- k f z.[ v p 3 ' ' p p p ' p p $+' $+$+$+$+$+' 3 $+p p ' $+p {.@ ] } } d d d q q d d ] m+K $+v v $+d+d+d+d+[ [ P l+R.G+ +2.b+1 #+[+ +o.D.x+x+<+y+Q.#+C+f+z 9 9 D k+5 *.& w.|+K.K.|+", "`.`.) -+-+-+-+-+`.E 4.-+4.4.4.4.4.4.{ { q+4.{ 4.4.-+4.4.4.4.4.4.4.4.4.) -+) ) `.`.`.&.-+-+4.4.4.) `.&.&.9 8.>.&.c.B.7.G.J.C+++)+)+;+8.k+k+8.b+*+++.+H.H B 4+)+++b+b+J.++N.N.i.G.G.2.n+N.b+f+f+^. +H.D `.*+$.Q.@.>+5.& D.w.5 6 & ].|+& (.a K.K.|+^ n.|+~+: a =+r |.k.O ~ ^ r.B+K.5 6 w .|.M o+z ;+[.x+9 9.9.i 7 5+f+{ o+l.B+].Q.Q.: . 0.Q D+t+. t+t+. t+. . t+t+t+t+t+t+t+t+t+t+t+0.0.Q D+&+&+T.k.k.[.: .].r.U.s I.}.Q.Q.Q.Q.5+5+t.t.5+ + + +t.5+*.1+ + +1+ +*. + +[+ + +*.[+[+[+*. +[+ + + + + +y.[+[+y.*.*.*. +*.p.*.*.*.*.y.[+*.p.*.p.*.p.*.[+t.[+[+[+ + + +[+ +[+[+[+ + +[+ +[+ + + +[+ + +t.5+[+ + +5+ + + + +[+t.[+t.5+t.}.t.}.0 }.y+}.y+}.y+y+}.y+y+}.}.}.}.t.}.t.5+ + + +5+t.5+[+t.t.t. + +t.5+t.t.t.t.5+t.Q.5+0 Q.Q.s <+U.y+H b+N 1.!.~.p+:.4 :+x.!.9.9.!.!.!.!.!.!.x.;+4+7+$+$+$+$+$+).$+$+).$+$+$+$+$+$+$+$+v $+d+v v d+d+d+d+e+7+l+/+U k k k z.X z.5 f 5 f 3.5 z.- X U [ v $+' p p p ' ' p p ' p p p ' p $+$+' ' p $+' p ' 3 K @ @ @ ] ] ] } } ] ] ] @ K L v v v d+$+$+v v v v v d+8+k+*.p.^.b y.[+ +Q.I.s D.x+<+y+w+2.u.4.q+&.9 j+5 & O S K.x+D.o.", ") `.-+-+4.4.4.4.) 4.-.4.4.4.4.{ 4.q+q+{ { q+q+4.4.x.q+4.4.-+4.4.-+-+4.{ 4.-+-+`.`.`.`.`.E 4.-+) ) ) `.`.&.9 b+c.C+++J.J.b+C+8.++G.i.n+N.N.'+.+J.z 8.n+B ^.C+J.J.J.G.J.)+N..+8.*+G.4+N.k+f+f+7.p.n+8.z z 7.t.n+D 4.u.$.s z+>+z n+|+D.z.W k K.S D.^ 5 ].: S 2 ; C [.[.<.; 5 ~+k.K.^ ~ D.B+|.& G+N.3 D+s 8.u.:+<+[.W u 9.z l.|+D -.-+'.. : 0 y.|+0.. 0.D+D+t+. 0.0.. t+. t+t+t+t+t+t+t+t+t+t+D+D+0.D+D+T.&+q k.[.[.l.: .r.U.L g.s o.Q.Q.Q.t. + +t.5+5+ +5+ +5+ + +1+ + + + + + + + + + +[+[+[+ +*.[+[+y.y.y. +y.M + +*.*.*.[+[+*.*.p.*.y.*.*.[+*.[+[+[+[+ +*.*. +*. +[+ +[+t.[+ +[+[+ + +t. +t. +[+[+5+[+ +*. + +[+ +t.t.[+t.t.t.}.}.y+y+g.U.3 2+U.U.U.3 g.<+y+y+y+}.t.}.t.5+5+5+t.t.[+t.5+t.5+t.t. +t.t.5+t.5+t.t.t.Q.t.Q.}.Q.s L L t.q.:+x.u { z ;+7.:.p+x.!.9.9.!.!.9.9.9.9.4.;+H d+$+$+$+$+$+$+$+$+$+$+).$+$+v $+v d+v $+d+e+e+e+e+/+w+,+k R X X b E+f f f f f 1 3.5 f X z.z.k '.[ $+3 p p ' ' K ' ' p p p ' p $+3 p 3 p p p p 3 p p K K {.@ F.F.F.@ @ @ @ @ m+{.v j J J j [ [ d+v $+$+v $+v q.b+a D.e+e+t.t.t.t.Q.Q.I.O D.s e+4+*+N `.9 D 6 a s K. .<+w.w.O ", "`.`.`.`.E 4.-+4.) E 4.-+4.4.{ q+4.{ q+4.q+q+{ 4.4.4.-+-+4.-+`.-+-+4.4.4.-+-+-+-+`.`.&.`.&.-+&.`.-+) ) &.`.9 o+o+D i.i.J.G.c.i.)+G.6 H.H N.B 4+C+b+k+4+i 8.i.++b+G.G.b+X.B C+b+G.++B B b+o+*+.+m.X.o+z *+4+n+8.-+E i t.[+(+{ 4.#+x+$.b+z ! ].].$.G 5 |+: |+2 n.D.[.~+& ~ & [.|.S ^ ~ K.T.k.T ~ I.B+q > G+G+0 B+l..+*+z H q a q+9.8 e+|.Z 4.1.A+B+B+y+,+I.k.. 0.Q B+0.. t+t+t+t+t+t+. . t+. t+t+t+t+D+t+t+t+t+B+k.q B+q B+7 B+l.: .r.g.<+s I.}.}.0 Q.5+5+5+ +5+ + + + + + + + + + + +*. +y. +[+ +[+*. + +*.*.[+*.*.*.[+ +p.[+[+*.*.y.*.y.[+p.*.p.y. +p.*.p.*.*. +[+ + +[+t. +[+[+ +[+[+[+[+[+[+ + +t.[+[+ + +[+ +[+[+[+t. +[+}.0 y+<+<+U.U.3 U.3 U.3 U.l g.3 U.g.3 <+}.}.t.t.t.t.5+[+ +t.[+ +t.5+ +t.t.5+Q.t.t.t.5+t.5+0 Q.0 o.<+U.<+p.J.z 8 !.A u.:.C+G.N 8 !.9.!.!.!.!.9.9.!.= i p.v $+$+$+$+$+$+).v $+$+v $+d+v d+d+d+e+7+7+l+/+,+9+R #+X w E+1 f 1 f 1 3.5 f f f 5 X z.k _ j j [ v $+p ' ' ' p ' ' p $+p $+K p ' $+$+p ' 3 $+p $+p 3 3 p K K {.$+P F+$+{.{.F.l j.f G _.W ]+f k U P [ d+v $+d+* A+n+y+U.3 L j.o.Q. + +& I.o.}.0 H B.G.(+8.6 5 & x+].].Q.& s |+", "-+-+E ) -+-+-+4.) 4.4.4.x.4.q+{ 4.4.4.4.{ 4.4.4.4.4.{ 4.q+4.4.x.4.q+4.4.) ) `.&.z -+-+-+-+4.4.-+-+4.4.&.&.&.z &.>+k+J.G.o+o+D G.b+P.4+B N.H N.N.B 1 q.4+.+X.C+J.G.G.++.+C+C+++7.4+N.i.G.G.*+.+N.++o+:+7.N..+f+`.:+#+[+6 -+{ *+t.Q.k+-.{ ^.x+s 8.-+B.|+K.w.G+6 O : .T ; w.~+: O 5 r : B+|.r ; > &+q 6+~ 2 [.0.~+a G+t.|.q 1+b+u.7.] 2+9 9.!.7.7 e.`.u E l Q ].*.R ].0.Q B+B+D+. 0.t+0.. . t+. t+t+t+t+. t+t+0.0.D+&+D+t+0.t+D+0.q B+B+|.[. .F.r.U.e }.I.}.t.5+t. + +5+5+ + + + + + +*. +*. +[+y.[+ +[+[+[+ +[+[+[+ +p.*.*.p.[+ +y.y.[+[+*.p.*.*.*.y.*.*.[+[+*.[+ + +[+ +[+ +*.[+ +[+[+[+t.t.t.[+*.p. + +*. +[+t.[+ + +[+[+ +t.0 y+g.<+3 U.l U.3 U.3 U.3 U.L U.3 U.3 <+y+}.e+t.t.[+ +5+t.5+t. + +5+t.t.t.t.5+5+5+t.t.5+Q.Q.}.o.L 3 [ H ;+E !.9.E :+7.7.:+x.8 9.9.!.u 8 !.9.9.9.E 4 Y.d+v v v d+d+v v d+d+d+d+d+e+e+7+l+p.,+9+#+#+#+w E+E+H+@.S.3.1 3.f f f f f X X k U U U j P [ d+v $+p p p p ' p p ' $+p $+$+' p $+$+$+$+p $+3 p 3 p p 3 p p K p g 3+#.R w.j.j.w._ W ( {+c < W G ]+3.s.J F+d+7+'+^.w o.x+K.F.L L y+0 $. +$.& $. +n+B 4+X.B z+ +I.o.O O Q.w.|+[.", "-+-+4.4.`.-+-+-+4.4.4.) 4.q+-.4.4.{ q+4.q+4.4.q+{ q+4.{ { q+4.4.4.{ 4.-+4.-+`.`.-+-+`.-+-+-+) `.`.) `.`.z `.&.9 9 f+u.u.z 9 u.9 9 k+B N.N.H N.#+B 4+C+b+C+^.X.C+J.++C+C+b+G.++C+.+)+J.b+b+.+N.i.o+f+*+4+N.A+9 >.7.m.N.f+4.>.4+t.X.&.{ N p.o..+-+1.r+].x+P.&.u.o.: x+H+W & : K.<.1 e.: |.: 2 ^ K.B+&+6+V.r &+0.: ^+_+K.0.q +.1 M r.t+|+Z D G.<+|.k+-.9.-+ .].>+u 1.a+Q [.Q.#+o.k.. Q B+B+Q . . . . t+. . . . . t+0.t+t+. . t+t+t+t+0.t+t+D+D+Q B+} [. .r.K.U.<+s }.I.}. +t.5+5+ + +5+ + + + + +[+ +[+ + +*.[+ +[+*.*.[+[+ +[+[+[+[+[+*. +[+*.p.*.*.*.p.[+p. +[+ + + +5+[+[+[+[+[+[+[+[+[+[+t.t. + +*.*.[+ + +[+[+ +[+ +t.t.t.t.}.y+<+g.3 3 U.l l U.l U.l U.l L U.U.U.3 g.y+}.t.5+ + +[+t.[+5+5+ + +t.5+5+Q.t.t.t.5+5+5+Q.0 o.<+U.<+t.C+u.A 8 8 N :.4 ;+>.A !.9.9.u ~.A 8 !.9.u z 7.h+l+d+v v v v d+d+d+d+P l+l+,+9+R R b w E+E+f @.@.@.S.G+3.@.f f f E+X k k U U j P j [ d+v v v v v $+$+p p p p p ' 3 ' $+$+$+d+v $+$+v $+p 3 p $+$+$+$+$+$+3 3 $+F x.`._.5 _ T _ 5 5.) {+i+c j+j+< _.7.M.J m ` ! ^.M./+I.s D.x+|+L <+y+Q.5+[+y.b B )+B.)+P.z+*.$.5+& I.O |+[.q ", "4.4.4.4.4.) `.-+4.4.1.4.4.{ -.q+4.4.{ 4.q+4.4.4.{ -.q+q+{ q+4.4.) -+`.`.&.&.z `.`.-+-+4.4.-+-+-+`.-+`.{ ) `.`.&.`.`.&.`.&.9 9 f+u.9 8.4+N.2.A+)+)+)+2.*+c.b+J.C+C+++C+C+G.G.++B B i.J.++C+N.^.b+o+o+7.B C+f+u.f+4+N.A+`.E ..#+N.D q+E i /+b 9 1.E H <+y.9 1.N j.K._ z E R : ].M _.E+~+|.S 2 ^ : B+k.+.~ 6+B+D+g+^ ^+k.0.B+T V.w.0.. K.2 P.L Q k.z+b+:+w Q $.`.9.!.H 7 G+-.9.u. .q O w b K.0.. Q q 0.t+. . . . t+. . . . . . . t+t+. t+. 0.t+t+0.0.0.B+d B+B+7 |.: .x ].<+<+y+}.Q.}.Q.5+5+ + +*. + + +t. +*. + +[+ + +[+ +y.*. +[+ +*.*.*.*.*.[+[+*.p.1+*.[+ + +t.p.5+ + +[+[+[+[+ +*. +[+ +[+[+[+[+[+ +[+ +[+*.[+ + + + +5+t.e+y+<+L U.l 3 U.l U.l l 3 U.U.3 U.3 U.<+<+y+}.t.t. +5+t.t.t.t. +t.t. +t.5+t.5+t.5+t.t.Q.}.Q.o.<+U.v C.7.`.!.!.x.:+7.4 *+= !.9.9.9.u ~.{ !.9.!.{ f+C+4+9+U P e+P P 7+w+C.C.k X X w E+f H+@.@.]+@.G+G+@.3.3.f E+f X k k J J U j F+d+d+v ).$+v $+$+$+p $+p $+$+$+' $+p $+p $+$+v P J m U j [ d+d+$+3 p $+$+$+$+v v v d+3+8 q+< ^ ^ 5 2 n.9 u q+5.; G < c 5.( o h+g F n b+i.R Q.+.I.+.D.S ].].<+I.t.n+4+++o+o+o+8.k+1 z.a & O g+|.k.7 ", "{ -.-.{ 4.-+`.&.x.4.4.4.4.4.4.-+4.-+4.4.4.4.4.{ -.{ q+{ -.q+{ 4.4.) -+`.`.&.-+-+-+) E 4.4.) -+4.-+`.&.&.`.`.`.`.&.) 4.&.9 >+o+9 z &.9 b+J.:+D 1 !+N.7.o+++++G.++C+B.C+C+G.f+6 N.B )+C+q.N.B )+J.G.J.4+C+o+f+f+:.4+B.u.z `.7.p.++-+{ N H n+b+{ { :.t.t.8.{ { i o.0 8.1.A C.].Q.f+-.J.: : Q.k+]+K.k.[.e.^ O &+q S ^ T B+t+B+T %+> . 0.S ~ r 7 . B+& n.$.[.0.D.B.G.A+l. .j+!.9.f+7 s 9 u u #+0. .$.z+o.q . 0.&+Q . . . . . . . t+. . . . . . . . . . t+t+t+t+D+0.0.Q Q q q B+|.[.: r.U.2+g.}.}.5+5+5+ + +1+ +t. + +t.[+[+ + + + + + + +[+ +p.[+[+*.*.*.y.*.[+p. +[+ +[+[+[+ +*.*.p.y.p. + +[+[+ + + + + + +[+*. + + + + + +t. +t.Q.Q.y+<+g.<+U.U.l U.3 U.l 3 U.3 U.3 <+<+<+y+e+t.t.t.t.5+ + +t. +1+ +t.t.t.5+t.5+5+Q.5+Q.0 }.<+L U.Q.q.*+s+8 !.-+;+2.7.p+x.!.9.9.!.8 A 8 !.9.u E ;+2.a+E+k ,+J C.R X X w E+3.f @.@.S.G+G+G+3.3.S.3.f f f X X - J J J l+j P [ [ v $+$+$+$+' $+p p p $+p p $+3 p $+p ' 3 $+$+$+g 8+3+o 3.! 3.M.U d+$+$+3 $+$+$+d+[ 0 j /.-+9 G 5 2 ^+5 (.z 9.u W X z._.5.5.( _.* A.+ z 9 8.P._ $.T & 6+|+K.].l <+0 [+4+*+x.{ 4.&.i+6 5 5+O : d q B+|.", "-.-.-.-.{ ) `.`.E -+{ 4.`.`.-+-+4.4.4.4.4.x.q+{ q+-.-.-.-.q+{ 4.4.4.`.E 4.-+-+) 4.4.4.4.x.4.4.-+4.4.4.`.-+-+`.-+`.) &.9 f+>+f+z 9 &.9 9 >+8.C+z+p.H ;+8.X.X.C+C+)+B.i.C+J.k+P.N.B 4+q.4+B B .+^.q.4+B 8.o+f+o+q.i.f+z z *+4+)+z -+-+:+#+)+-+{ 4.q.t.N.9 A u.H o.)+-+{ G.0 y+k+u !.7. .|+k+q+:+x+[.O 6 8.w.7 [.w.^ $.D+0.k.r ^ : . t+|+~ T t+. &+r %+|+. 0.> n.a .0.: H.A+G.l+0.M ) !.1.0 |.8.u 9.( [.|.Q.G+H. .. . Q B+Q . . . . . . . . . . . . . . . . . . . t+. 0.. Q 0.Q q q B+|.[.l. .r.U.g.s }.5+Q.5+5+t.t.t.5+t.5+t. +[+ + + +[+*.*. +p. +y.p.*.*. +[+*.*. +*. + +y.*. +*.*.[+t. +[+*. +t.[+ +5+ + + + + + +*. + +[+ + +t.Q.y+<+<+3 <+g.L U.L U.<+<+<+<+<+<+y+<+s }.t.t.t.t. +t.5+t.5+ +5+ + + +t.t. +t.5+t.0 Q.}.<+L <+w+C+z u !.A p+J.C+:.N { 9.9.9.!.8 u !.9.9.1.:+/.a+'+S.M.w E+E+f @.S.! G+! ]+]+]+3.3.3.f E+s.X - - J k ,.U P P P 7+P d+d+d+$+$+$+$+$+$+$+' $+' p p $+p $+$+$+$+3 $+p 3 $+F+i ( 5.< G W < n _.- d+3 p 3 v P J u+X X 4 ( _.5 $.T T T z.5.1.-.W T '.X W _.3+o * u++ E { 5.c+z.*.e.& I.o.x+x+x+x+j.0 B *+{ 9.!.q+&.W !+6+: Q . 0.7 [.", "-.-.-.-.q+4.-+z `.`.-+{ 4.-+-+E { 4.4.4.4.{ 1.-.-.{ q+{ -.-.q+4.4.q+4.4.-+) ) 4.4.4.4.4.4.) `.-+-+-+) -+-+-+&.9 &.`.`.9 i+f+z &.&.z &.9 8.B .+2.C+J.o+X.N.B B.C+C+C+^.C+++1 N.p.N.N.4+N.B ^..+4+B B 4+7.J.J.2.)+A+f+z u.C+.+f+`.-+E )+4+o+4.4.N N.#+o+{ -.*+t.N.>+x.= q.y+H.4.u E Y.U.b ) u *+y+].i.u { l+k. .1 ( @.7 Q .5 2 : 0.Q 6+^ 6+0.. k.^+_+~+. . 6+%+T 0.. 0+a 5 D.Q Q O i.8.^.B+r.D 1.9.J.q I.4.9.!./+. K.M B I.q . 0.B+q . . . . . . . . . . . . . . . . . . . . . t+0.0.0.Q 0.q q B+|.l.m+U.U.g.0 }.}.5+5+Q.t.5+5+5+ +t. + +t.5+ +*. + + + +[+*.[+ +[+5+*.[+ + +[+ +t.[+*.*. +*.[+5+ +[+ +t.5+p. +[+*. +[+[+[+ + + + + +t.o.o.s 3 <+<+<+<+<+<+<+<+<+<+y+y+0 y+t.}.t.t.t.t. +t.t. + + + + + + + + +5+Q.Q.Q.o.y+U.<+y+H :.p+A 8 { *+4 :...s+!.9.9.9.!.8 !.!.9.9.!.u.r+R.3.3.3.3.3.! S.! ! S.! G+3.3.f f w X k J J U 7+w+7+7+F+e+d+F+e+d+d+d+).v ).).$+$+$+$+$+$+$+' $+$+p $+$+$+$+3 v $+$+$+p P 3+i+5.G 1 G 5.) 9 G j $+3 p d+R.:.n G.3+n 5.]+z.w.6+> 6+w.f 3+5.5 j w.U X M.M.* J Y.f.>.-+D i.H+@.b M $.& I.I.I.s o.0 [+B.f+`.&.9 8.5 O [.Q . . . q B+", "u -.-.-.-.q+4.4.-+-+E 4.4.4.) 4.4.{ 4.4.q+4.-.-.-.-.-.-.-.-.-.{ 4.4.4.-+x.4.4.-+4.4.q+4.4.) -+`.) ) ) `.`.) `.`.`.&.&.`.&.z -+-+) `.`.&.9 >+*+*+u.f+8.X.4+J.C+C+q.B.q.C+C+B N.L.N.C+i.N.B B B ^.N.B ^.2.q.4+4+)+J.;+*+4 4+4+*+u.z ;+)+o+E 4.E i H.++-+-.x.2.[+G.-.1.N m. +b+{ ~.;+t.0 o+{ x.r+y+t.&.9.~.e+l.[+4.9.n 7 k.I.8._.K.0.B++.5 D.0.0.: ^+2 D+. 0.<._+6+. . : ^ ^+[.. 0.D.^ & [.. : w B.C+L B+#+4.9.-.y+[.8.9.9.f+7 |.t.k+.+ .. . Q B+Q . . . . . . . . . . . . . . . . t+. . t+. 0.. t+0.0.0.0.7 B+l. . .r.g.<+s }.e+Q.5+ + +5+[+5+5+ +5+ +[+ +5+ +[+[+[+t.*.5+[+[+[+*.[+ + + + + +[+5+ + + +[+ +5+ + +*.p.5+[+*.[+ +*. +1+ +t.Q.0 }.y+<+y+y+<+y+y+y+o.}.o.Q.5+t.t.t.}.t.5+t. + + + + + + +[+ +5+ + +t.5+t.5+I.<+<+L e+k+u.{ A s+>.;+C+;+p+{ !.9.9.9.!.!.!.!.9.!.{ :+#.M.M.s.s.s.f 3.3.S.S.3.f s.X X J J U j P e+[ [ d+,.* 8+* * ,.7+d+d+v $+).$+).).F+O.O.).).).d+$+$+v $+v v d+d+v v v v $+3 F+o _.6 E+'._ #.) q+5.X $+$+$+j 2.G.9 z z z z 5.W 1 6+S : O j.U J j w.[ d+w.P [ P [ F+Y./.G.k+H.@.++6 P.b n+*. +*.*.[+t.t.L.q.C+B.X.!+5+r.D+. . . . 0.Q ", "-.1.-.-.{ -.-+&.-+) `.x.4.4.q+4.4.4.{ { { 4.{ 4.{ { { -.{ -.4.q+4.4.) -+4.-+4.-+4.4.{ 4.4.-+4.q+4.4.-+4.) -+`.`.&.&.-+`.&.-+-+) 4.`.`.&.&.9 9 D D c.X.B C+)+X.)+2.C+C+++8.k+B B 4+.+B 4+B B ^.++B.B.2.4+N.N..+2.2.J.:.2.4+H q.2.2.q.++*+E E *+4+C+&.x.4.*+N.C+) -.-.;+[+)+`.1.E q.t.k+4.{ u.'+0 8.u !.A+y+y+b+9.8 2.l.r.D 9.~.<+Q |+k+( '.0.B+S 5 a B+. q C ^ S . . ~+_+r D+. 0.C ~ 6+0.. k.2 ^ U.0.0.}.X.J.'+q .b+{ !.7.B+I.{ 9.!.C.0.r.#+X.t.q . 0.B+|.0.. . . . . . . . . . . . . . t+. . . . . . . . 0.0.0.Q q B+|.l.x r.2+2+s }.5+5+t. +5+ + +t.t.t.5+ +[+ + + + + + +[+5+[+t. + + + +5+[+t.5+ + + +*.[+5+5+*.[+ +[+ + +[+*. +t.t.t.5+Q.Q.0 I.Q.0 Q.0 0 0 t.t.e+t.5+t.t.t.t.t.t.t. +t.t.[+*.*. +1+ + + +t.5+Q.Q.y+<+U.y+/+q.:+1.9.{ Y r+4 ;+= !.9.9.9.!.!.!.9.9.9.8 z J.R.* J J J - - X X s.s.- J J U P P F+d+d+$+d+d+v v ` *+u.u.:+:.'+F+).d+d+F+O.P P m m m V m P P P P F+F+,.* * * J 7+[ v v ' d+g E+k w.j.0 f E.-.&.3.P $+v 0 L.2.i J.o+f+9 ( ( (+C 0+~+].|+j.L j.j j.v $+3 $+3 v $+v 7+g C.e+p.k+X.H.H.H.b E+H+.+)+b [+[+p.N.m.n+$.e [.0.. . . . . . ", "-.1.-.-.-.-.{ 4.-+4.4.-+-+{ { 4.{ q+q+q+-.-.-.1.q+-.-.q+{ -.{ { 4.) ) -+4.4.4.4.4.4.4.4.4.`.4.4.4.) ) -+-+) -+`.&.`.) 4.4.4.) `.`.`.&.9 `.9 9 9 c.k+B )+B B q.q.2.C+B.C+++++C+++)+4+4+i.++++b+o+8.A+J.i '+B 4+B.C+C+;+7.2.'+H 4+4+2.J.:.;+;+^.4+J.`.E :+^.)+`.{ { >.'+.+z { { *+p.B -+!.!.G.,+X.4.!.E C.<+H.1.9.N e+U.a+1.9.E y+l.X.1.!.9+Q |.R D _.[.. [.a 5 K.. . K.^ +.0.. 0.+._+S . . [._+_+|.. 0.6+^ & |.. : z+i.C+L Q y.`.!.-.<+[.D 9.9.f+7 B+t.)+G+ .. . 0.B+q . . . . . . . . . . . . . . . . . . . . . . t+. t+D+B+q B+7 7 [.r.U.g.g.}.}.Q.}.t.[+5+ + + + +5+t. +t.t.t.5+t.[+ + + + +5+ +t.5+5+t. + + +t. +[+[+[+ + +[+ + +t.t.t.[+Q.t.t.Q.t. +t.t.t.Q. + +t.5+5+t.t.t.5+t.5+t.5+t.[+ +p.!+p.1+ + +5+t.Q.0 }.y+<+<+t.B.:+x.~.A = ;+2.i :+~.!.9.9.9.!.8 !.9.9.9.~.Y ` V m 7+P P P P U U m J U P P d+d+v v $+).$+$+v v v 3.( -+-.4.z ++C.7+d.m m V v+u+A.t M.A.A.u+g - - X 3.7.E.f+( _.^.M.P v $+$+d+j j w.j.& X < ( ( o J F+j 0 t.9+p.H 4+B.r+C+A+_.& ~+|. .l x+ .K U _ [ v 3 3 K l K {.K K p l 3 ,.9+t.[+[+m.H.X.++G.k+N.z+n+N.H.b *.& S &+. . . . . . ", "{ -.1.1.-.-.q+{ 4.4.-+4.4.4.4.{ 4.-.{ 4.{ -.1.-.-.q+{ -.q+{ q+4.4.4.4.-+`.`.{ { 4.{ q+4.) `.x.{ 4.4.) `.) ) -+4.E 4.-+-+) 9 9 ) `.9 i+i+9 &.&.9 o+f+c.J.C+J.b+B.4+C+)+q.7.7.++++B.X.i.B.C+C+C+b+J.++b+J.2.B 4+4+^.B.r+7.7.2.4+4+)+A+J.:.r+a+4+B.J.*+i 4+B ++N 4.= 7.4+f+-.1.x.q.N.f+1.u x.B N.z 9.9.p+t.t.`.9.!.i <+0 9 9.8 i v Q.&.9.{ e+d j.9 9.u.l q x+8.5.y+0.B+O n._ Q . B+T 2 : . . : ^ r D+. t+& _+> . . ~+2 a U.. 0.s P.C+H B+K.D { !.J.q o.4.9.!.m.0. .m.H.I.B+. 0.q q 0.. . 0.0.0.D+. . . . . . . . . . . . . . . t+0.0.Q 7 B+q B+7 |.l.r.| 2+s }.}.5+5+t.5+5+ +5+5+5+ +5+[+*. + +t.t.5+t.}.t.5+ +5+t.5+t.[+[+[+ +[+ +t.*. +t. + + + +t.[+t.5+ +t. + + + +t.t.t.[+t.t.t.}.t.t.5+5+ + +*.*.M + +5+t.Q.Q.Q.o.<+l y+p.2.f+u !.8 p+i 2.:.u.A 9.9.9.!.8 !.!.9.9.9.{ ;+'+V U m d.P P O.O.P 7+P F+d+d+d+v ).$+$+$+$+$+$+$+v @.n 9 9 &.9 < M.u+g u+u+t t ` ` ` ` ` ` M.` 3.3.o _.5.&.&.9 (+3+G 9+j [ [ d+d+v v v j - 3.3+F o ` g J _ Q.t.[+/+y.m.n+m.z+R w.|.7 .m+L l L - i M.[ j.K 3 K l @ @ @ ] @ @ F.p 3 3 [ e+,+N.)+++6 H.N.B .+k+X.1 b +W.q . . . . 0.", "-.{ -.-.-.-.-.-.-+-+4.{ 4.4.4.-.4.q+{ 4.4.-.1.-.{ 4.4.-.q+4.4.{ 4.4.) -+-+`.) { q+{ q+4.4.-+4.4.-+4.q+-+) 4.) `.-+q+4.-+-+&.`.`.`.4.{ 9 9 z &.9 f+f+f+>+f+f+8.X.N.q.^.)+++A+C+B.)+C+C+i.i.)+B B 4+i.J.b+C+N.4+4+4+^.r+7.7.r+^.2.C+7.3+3+4 ^.@.++J.n 7.a+.+A+*+J.q.N.^.f+x.x.G.B ++-.1.u :.N.G.u !.u i /+++!.9.{ H y+A+8 9.E p.y+A+9.8 4 l : 2.u 9.*+l.l.X.1.!.9+} .i.9 ++B+0.: b 2 : . 0.S n.C 0.. Q & ^+: . . K._+r B+. . 6+5 I.7 . |.b X.^.U.Q *.`.!.u y+|.8.!.9.u.|.Q I.6 i.U.. Q B+|.B+|.Q . . . . . . . . . . . . . . . . . . D+B+. 0.t+t+D+Q Q Q [.g+g+U.| g.y+}.5+t.t.5+t.5+5+5+5+ + +t.t.t.t.}.t.t.t.t. +t. +*.*. +[+ + + +*.[+ + + + + + +t.t. + + + + + + +t.t. +t.[+t.[+t.t.5+t. + +*. +*. +t.t.t.t.}.Q.s L U.y+'+J...N A 8 f+2.2.:.E 8 9.9.9.9.{ 8 9.9.9.9.u :+q.* h+- g V J m U P d.7+P d+d+).d+v d+).$+).$+d+d+v ! 5.( 5.5.D < 8+` * t ` ` ` ` ` ` 3.M.A.M.M.3.3.]+W W < 8.W G ++++@.k l+U P P d+v v v P - 3.` 8+8+8+X k m.[+[+[+[+[+[+ +$.Q.K.q 7 [.] l ].j.R.N < h+j v <+3 l @ @ ] } } } ] @ @ m+l 3 v e+C.'+N.p.n+n+B X.X..+1 !+I.g+0.. . . 0.", "-.-.-.-.1.1.1.-.4.4.4.4.{ { { { -.{ q+{ { -.-.q+4.4.{ { 4.4.4.q+4.-+) ) ) -+4.q+{ q+{ 4.4.4.4.4.) 4.) `.-+) 4.`.-+4.) -.u -.`.`.`.1.q+&.9 f+&.`.&.&.9 f+o+f+D J.J.J.G.J.J.A+++7.C+B.C+C+4+N.B B !+B C+A+B.B '+4+^.2.2.r+2.)+2.X.B.#.++7.i 2.^.k+++A+J.B.)+8.n n 4+4+C+o+*+2.H a+G.x.~.u.4+X.4.u u = H ^.{ 9.!.>./+b { 9.9.u.e+B 1.9.x.C. .Q.&.9.~.Y.l.I.f+u { p.l.H u 9.f+m+B+ +>+o+K.. 0.O 1 $.0.. D+& 2 |.. . |+^ +.0.. 0.& _+|+. . |.2 2 K.0.. x+.+C+4+} [.++{ !.G.q <+4.9.9.B 0.r.n+)+p.g+0.0.q |.0.. . . . . . . . . . . . . . D+t+. . . . . . 0.0.Q q Q Q q B+|.l.g+F.2+e e }.5+ +5+5+5+5+ +t.5+t.t.t.t. + +t.[+ + +[+ + + +*.[+ + +[+*.*.[+[+*.t.t.[+ + +[+ +[+ +5+[+ +[+[+t. +t.t.t.t. + + + + + +t.5+t.Q.o.y+U.U.y+2.z !.!.s+p+;+f.i ;+E 9.9.9.9.!.8 8 8 !.9.!.4.*+f.R.` ` R.3.` M.* h+g ,.m 7+O.F+F+).d+d+F+F+P P P [ _.`.4.) z 9 n o 8+` t M.A.M.t M.` ` M.- J J - - f @.@.b X k 9+g o B.3.M.s.M.- J P d+d+d+d+m g * ` 7.a+2.A+A+C+^.H.#+n+[+ +w.: q d } } l.L e+` A f+#.s.J [ j.U.m+@ @ ] @ ] ] @ @ l.m+F.3 <+$+v e+e+e+/+[+L.,+[+/+ +|+[.Q 0.Q q Q ", "-.-.1.-.-.1.-.-.-.{ { 4.-.q+4.-.-.{ -.-.{ { 1.{ 4.4.q+{ 4.-+{ q+) 4.4.) -+-+4.4.{ q+{ -.-.4.4.-+-+) -+`.`.-+`.-+4.-+`.-.q+4.`.z f+z 9 z 9 f+9 &.&.&.&.9 9 f+i+f+f+D c.++J.8.X.C+.+^.2.7.++J.f+b+.+.+)+2.4+B B ^.2.2.r+i 2.^.^..+++3+3+b+7.o ^.B.k+A+A+3+r+)+++3+_.! #.b+n i }+B.b+f+i '+H C+E { E C+N.>+9.9.1.'+m.f+9.9.{ '+[+u.9.9.N 0 <+7.1.!.*+y+g.k+{ A *+e+<+o+9.9.:+l <+9 9.x.l 0.: G+&.]+d Q : 2 a k.. 0.O n.6+. . 0.& ^+: . . ~+(.^+B+. . > ^ I.|.. [.a X..+<+0.Q.u.1.u t.q k+9.9.{ <+q <+.+i.<+. . 0.B+D+. . . . . . . . . B+. . . . . . . . . . . t+t+. . 0.0.0.Q 7 ] g+l.| | g.}.}.}.}.t.t.t. +5+t.}.t. +5+5+t. + + + +[+[+[+ + + +[+ + + + + +t.[+ + + +*. +t.5+t.[+5+t.5+t.5+ +t. +5+ + + +5+t.5+t.Q.y+<+L L e+'+4 = 8 !.>.2.2.:.:+= 8 9.9.9.8 8 8 !.9.!.s+*+f.` ` R.` 8+8+R.R.8+3.R.M.* * g Y.m ,.m ,.Y.V g u+- j 3.( &.`.`.`.5.o u+g V V V J u+M.! o o f - U P P j U '.0 '.w B.4 n ;+r+2.3.` 3.M.- U [ d+$+v P U u+! 3.*+{ 1.{ E f+o+J.C+B t. .d d d } @ K e+R.s+z b.r+R.X /+j.3 m+@ @ @ @ @ @ m+F.{.F.{.l 3 3 3 <+j.[ y+y+y+<+l U.l.7 0.. 0.0.0.", "{ 1.1.-.{ { 1.1.-.4.-.-.-.-.4.{ -.-.-.-.-.-.-.-.-.-.{ q+q+) -+{ -+) -+) &.-+-+4.4.{ 4.4.4.{ 4.) ) -+`.`.-+`.4.) -+`.&.-+4.q+`.`.9 >+>+9 9 i+f+>+z `.9 &.`.f+9 9 9 f+f+o+G.i.)+^.^.q.C+7.;+o+D k+C+^.4+B '+'+R.4+^.2.2.)+^..+)+2.++b+D o+>+f+o+G.A+++A+A+8.#.i._.3+_.i.C+< < i.B.< G.b+a+.+A+( ;+a+H .+( A x.;+H C+u 9.!.;+/+b+u 9.9.7.y+p.{ 9.!.2.y+4+-+9.x.'+3 H { 9.~.^.r..+!.9.*+l.q Q.) 9.;+B+} R ( 3+[.. Q & (.I.. . &+T 2 [.. . : ^+T Q . 0.w._+O . . |.r 2 U.0.. ].P.^.B .|.k+4.9.E F.: 9 9.9.(+Q B+Q.)+m.[.. . Q |.B+. . . B+0.. . . . . . . . . . . . . . . . . . . 0.. 0.0.Q q 7 @ r.r.r.2+}.}.}.t.t.t.t.t.}.5+t.t. + + +/+t.t. +t.t.t. +t. + +[+t.t.[+ + + +t.t.t.[+t.t.t. + +t.5+t.t.t.5+ +t.t.Q.t.0 <+U.U.y+)+N { s+N N :+2.r+;+>.A 8 !.9.9.9.!.8 !.!.u *+'+,.m J g M.M.3.` R.o 8+8+o 8+R.R.R.` * M.A.M.M.M.* R.X _ X ! o #.7._.- m P F+F+P d.M.]+; W ; n.5 5 k j [ [ v j.l+R.*+z E z u.;+3.M.t ` ` u+J P d+$+' d+e+C.,+A+E { u 9.9.!.1.{ z .+ .} ] } } m+3 w+:.~.!.{ z o+3+G+n+0 3 l F.F.F.F.{.F.F.F.{.{.{.l l K v 0 o.0 y+<+ .l.7 Q 0.. . . . . ", "{ { -.-.u -.-.{ -.4.{ { -.-.q+-.-.-.-.-.-.{ -.-.{ q+4.4.4.4.4.4.4.) -+-+&.-+4.-+q+q+4.-+4.q+q+) ) ) -+`.4.) -+-+-+4.) -+4.4.) ) `.9 o+z f+f+f+o+z -+`.9 i+9 z u.&.&.&.z 9 f+o+G.J.*+u.z z o+i..+i.B B 4+B 4+^.q.^.2.2.)+)+)+i.C+G.o+*+o+o+o+>+f+f+>+k+r+C+A+o i.++A+A+! C+3+< #.#.3+< A+G+++n G.a+9+.+n *+R.L.4+J.E { p+'+H.-+9.9.x.,+N.u.9.9.E l+t.z 9.9.>.0 p.`.!.9.*+e+y+>+9.{ p.|.r.b+!.8 '+7 L f+9.z .0.F.b+-+#+. . : 5 5 [.. 0.S 2 <.0.. 0.<.^+K.. . |.^ _+k.. . |+^ & |.0.q Q.H.B.t.0.g.f+u !.B.0.y.1.9.u o.0.r.B 8.[+Q . 0.: r.0.. . t+. . . . . . . . . . . . . . . . . . . . . . . 0.Q q 7 ] l.r.| 2+g.}.e+}.5+t.5+t.Q.5+t.Q.t.t.5+t.t.t. +/+t.t. +5+5+t.t. + + +t.[+t.t.t. +[+5+5+0 5+t.Q.t.5+t.0 t.0 <+3 <+y+p.;+x.9.!.N 2.2.7.*+= !.!.9.!.!.!.9.9.!.!.8 b.'+w+P P d.m J J V g M.3.R.R.R.8+R.8+8+8+8+8+` ` M.- 3.z.Q.w.j.o.[ [ l+e+d+d+v ).v 7+E+c+^ ^ ^ ^+^ ~ ^ z.'.[ v $+[ ` ;+..a.N >.*+M.J * M.t t M.V j $+p p $+v [ L.^.q.i *+u.-+{ 1.!.c.<+] ] ] ] {.3 /+n { u 9.9.9.u -+D 1 0 y+3 U.{.{.{.F.{.F.l F.l {.l 3 y+t.Q.Q.I.o.r.7 q 0.0.0.0.. . . ", "-.-.-.-.1.1.q+-.{ -.q+-.-.{ 4.{ -.-.-.-.-.-.4.4.4.) `.-+-+4.4.4.4.) ) ) E 4.`.-+4.-+`.`.) -+) -+`.&.`.`.-+) ) 4.4.{ 4.4.4.q+-.q+) `.9 o+&.4.9 o+i+D f+>+G.o+f+9 z 9 z &.z i+f+f+f+9 &.&.9 8.i.B m.N.H ^..+^.B 4+2..+4+a+a+4+4+i.(+b+8.B..+.+B k+>+f+G.H+_.++< ]+i._.< _.)+k+3+< ! ]+8.n o ! _.n r+s.i.n J.a+a+< ;+;+i '+N.B.z 8 x.r+#+b+9.9.!.2.t.b+!.9.u 2.y+++9.9.!.q.0 i.{ 9.:+v l.t.4.!.u.y+l.N.-.!.2.l.7 #+u 9.B.Q q '.i+o+ .. Q O 1 & 0.. q +.2 : . . ~+^ r T.. . O %++.0.. 0.T 2 U.Q . [.P.)+)+r.0.z+-+!.{ U.Q 8.9.9.z |.0.<+++J.g.. . 0.B+B+. . . . . . . . . . . . . . . . . . . . . . . . . . 0.0.Q q 7 |.[.l.r.| g.y+}.5+Q.Q.t.5+t.t.t.t.t.t.5+t.}.[+t.t.[+ + +t. +t. + + +t. +t.t.t.5+t.Q.t.t.Q.Q.}.y+U.<+y+L.:.:.b.p+A x.r+2.;+>.~.8 !.9.9.!.8 A !.9.9.u :+R.g Y.J ,.U m P U P m J g - M.M.3.3.R.R.` ` ` * - J J k _ w.O x+x+L $+v $+$+' $+).P w b 1+I.O O +._+; n.E+k P d+7+f.b.+ % Y Y + h+F+m - ` t t t J v 3 3 3 L 3 #+)+/+y+0 e+C.'+2.;+4+U.m+@ @ @ F.3 w.@._.n ( z -+-+{ -.>+P.[+0 0 y+<+p U.{.{.l {.F.F.F.l j _ Q.o.I.w.U.[.d Q q 7 B+0.. . ", "-.-.1.{ -.1.-.-.1.-.-.-.-.4.4.{ -.-.-.-.-.-.-.4.4.) `.4.) -+4.4.4.4.-+`.`.) `.&.`.`.-+`.`.`.`.4.) `.) `.`.-+) ) `.4.4.q+4.{ { -.q+) &.9 &.) i+o+>+D f+D D D G.f+f+9 >+D (+b+G.f+f+f+9 &.i+k+++J.A+C+B 7.B.X.H 2.*+i.#+L.L.#+H 4+7.2.#+p.[+p.[+m.)+b+A+H )+k+b+i ! )+3+++^.i.n A+2.! < < B.i.< < o ! A+3+2.R._.3+2.B.3+3+A+3+;+7.4+#+B.:+x.A :+C.m.`.9.!.>.l+H { 9.9.u.e+p.&.9.9.J.l y+D x.{ ;+y+0 f+9.= e+7 L f+9.!.'+d r.*+9.-+ .. l.G+9 i.q 0.m+z.5 l.. . S ~ T Q . . <._+O . . Q a _+: . . [.^ 1+: . 0.s 1 )+p.0.|.++{ !.o+Q r.&.9.9.C+. B+5+k+p.|.. . B+B+0.. . . . . . . . . . . . . . . . . . . . . . . . . . 0.0.Q q B+|.[.r.| g.y+}.Q.5+t.t.Q.}.t.t.t. +5+t.}.[+ +5+5+ + +[+5+t.t.[+5+t.t.Q.Q.t.0 0 0 }.y+U.<+y+H u.!.!.~.b.:.2.C+;+= !.9.!.!.8 !.9.!.8 !.!.{ *+q.M.* s.- - - Y.J J m 7+U P 7+m Y.Y.g M.M.* - J l+[ j R e.+.w.w.o.j.v ).$+d+$+$+v d+'.$.w.O x+|+x+a 6 ~ G 3.h+Y.` ..a.a.% % b./.g d+d+m A.` t 3.V v {.K l L L '+( P.D.U.l l l r.3 v {.{.F.F.F.F.l x+z.1 c+c+]+6 k+8.(+++P.!+z+n+y. +t.v l l F.{.{.{.{.l y+'.Q.0 w.w.].[.d } ] K.S q . . ", "{ { -.-.-.-.4.`.4.-.4.{ -.-.{ 4.-.-.{ -.{ 4.) `.`.`.-+-+4.4.4.4.4.) 4.4.4.) 4.4.`.4.) 4.`.-+-+`.`.) -+) `.`.`.4.q+{ { -.-.q+q+q+4.) &.&.z 9 9 i+>+f+f+c.J.G.b+o+i+u.f+D b+i.f+9 9 9 9 z 9 D 8.7.b+i.H.B B 4+H 2.i.H.#+H N.#+L.B 2.B..+B B B )+)+)+B.4+'+a+#.++o 4+_._.#.! _.3+r+i.< < r+! < < r+! < 3+o R._.F r+R.3+3+A+i ++b+D 5.c ( 9 z ;+h+[+L.2.....'+e+C+u 9.!.4+0 b+!.9.8 H <+4+1.9.A '+t.b+1.!.u.U.|.[+4.!.= 0 ] H 1.9.b.l.Q 0 4.9.7.q 7 m.9 G.K.. 0.j.^ $.Q . Q & ^ |+. . B+2 ^ [.. . : ^ T 0.. . +.^ s q . q 1+B )+y+. x+f+1.9..+0.*.u 9.1.s . g+B ++t.0.. 0.D+B+0.. . . . . . . . . . . . . . . . . . . . . . . . . . 0.Q q q 7 |.r.U.g.g.}.t.5+t.5+t.5+5+t.5+}.5+t.5+5+5+t.t.5+ +t.t.5+t.5+t.Q.Q.0 y+L l <+e+C.h+4 s+!.x.2.4+i o+N 8 !.9.9.!.8 !.!.9.9.!.8 ..f.R.` M.* h+* X X X f R.R.R.` M.g m U ,.,.w+P P e+v M.E+_ $.*.$.$.'.7+P O.F+F+F+v v [ d+w.w.O w.w.$.2 P.f f L.L.:.A !.8 8 A s+a.k v v P t 8+t t J 3 K F.F.F.L 9+o+1 o.K.K.r. .l.[.m+K K K K {.K l.x+a 5 ^ 1 ^ ^ 2 2 P.2 e.e.5+5+1+z+X.p.<+| F.F.F.F.F.K $+w.Q.Q.Q.I.|+[.} d l.x+|+k.. . ", "q+4.{ -.{ 4.`.&.z -+4.{ -.4.&.&.-+{ -.q+-.4.4.-+-+) &.&.-+4.-+-+) 4.4.q+{ 4.`.`.) 4.4.q+4.`.`.-+`.`.-+`.4.) `.4.q+q+-.-.-.-.-.-.q+-.4.`.`.9 9 f+>+9 o+b+J.f+(+G.b+D f+f+f+o+o+9 f+f+>+o+9 >+X.q.r+B.N.H B 4+^.^.B N.4+4+L.p.Y.H q.^.^.B.#.r+C+B.^.4+H 4+_.#.B..+)+i B.! #.A+r+! _.J.i ! _.n i ! A+< i ! A+3+#.S._.< r+! 3+) u q+`.{+{+`.1.u 8+w H.s.L.Y.p./+h+4 Y :.l+H E 9.9.>.0 N.-+9.9.*+e+p.{ 9.9.b.L U.J.1.8 *+L <+b+u x.p.} .7.9.8 C.d l z 9.x.l . B+E+&.Z q 0.|.a 1 |+. . k.2 a T.. . K.^ C . . . e.V.> . . q a r r.0.. : n+)+i U.7 B 4.!.u U.Q b+9.9.`.7 . g..+X.2+. . 0.q q . . . . . . . . . . . . . . . . . . . . . . . . . 0.. Q Q d d 7 [.g+r.| y+}.y+Q.e+}.}.t.}.t.}.t.t.5+t.5+t.t.t.}.0 y+}.o.s U.l <+'+E 1.x...:.*+q.q.J.p+{ !.8 8 !.!.!.8 8 !.!.9.u E.f.o 8+` M.J J C.- s.3+( 4.1.{ x.E b.` ,.7+P d+d+d+Y.:+_.w R b f _.R.u+u+V V V V J l+0 j.j.j.0 w.w.j j '.U U ,.w+` E !.9.9.9.9.u B v v m t 8+8+t J 3 F.m+m+F.L /+i.P.w.S r.|+ .l.7 l.{.K K 3 l K : x+z.^ ^ 5 5 5 5 2 a T +.O K.K.U.I.G+1 Q.l {.F.F.F.F.l j.o.o.w.w.Q.O [.d q ] ].|+B+. . ", "4.4.4.4.4.`.&.z z `.`.) `.&.`.&.z ) { -.4.4.) ) `.-+-+-+`.&.&.&.`.-+4.q+-.-.-.4.) -+-+{ q+4.) `.4.`.`.4.) 4.4.4.4.4.-.-.1.-.-.-.q+{ q+q+`.`.`.9 o+9 >+c.z 9 G.++++G.b+f+&.o+o+o+>+f+c.X.:+(+X.2.G.8..+4+4+^.4+b N.L.H n+p.C.p.'+4+'+'+a+4+4+H '+w L.s.)+B.! .+o r+B.)+#.++_.i.r+3+7.o _.n A+]+_.n 3+! #.n 7.! _.n r+R.3.`.) &.< H+z.2 6 ) 9.`./+a+}+L.,.7+7+7+7+7+7+e+'+u.= p+h+y+)+1.9.8 '+0 G.9.9.1.H y+B -.9.u '+y+4+x.!.u.y+[.o.&.!.u.<+} p.1.9.f+l q L `.9.J.B+Q y+>+-+t.. . K.1 z.|.. t+|+^ O . . Q a ~ : . . T.^ 2 k.. . : ^ I.g+0.: }.H+C+4+0.|.G.-.9.9 q g+`.9.9.i.. 0.Q.i.p.|.. . 0.D+0.. . . . . . . . . . . . . . . . . . . . . . B+B+B+Q Q Q Q q 7 [.g+r.2+<+y+}.t.Q.t.}.t.}.0 +t.t.0 }.y+U.L r. .F.U.3 e+h+u.!.!.E q.4+C+J.:+A 9.9.!.x.= !.9.9.9.!.!.~.;+f.8+o 8+R.g P F+P Y.E.4.u 9.9.9.9.9.{ 7.Y.e+[ d+d+* z b+P.#+S.3+= *+f.t t * ` R.3.S.E+X k _ j j [ j.j.v v v v v l+B.:.N ~.{ 8 4.b d+[ V 8+t 8+` U 3 l m+m+l j.R 5 z+6+K.: K.].[.7 l.{.K p K K F.l.w._.5.D D j+W 6 ^ 5 T & O K.l.: ._ P.Q.3 F.F.m+F.F.{.j.w.0 w.Q.+.D.: B+d ] ].O B+. . ", "4.-+4.4.) &.9 9 9 z &.z 9 &.z &.&.&.&.`.`.-+) ) `.) -+-+-+`.`.`.-+`.4.4.-.-.-.-.4.) 4.{ q+q+4.4.4.) ) 4.-+4.4.-+4.-+4.q+-.-.-.-.-.-.{ -.) ) 9 i+f+9 f+o+G.c.8.++G.b+++f+f+f+o+G.o+D c.8.*+8.C+G.(+k+}+^.4+B..+H N.H N.H H H H '+'+4+4+a+4+'+N.H H H a+)+B.^.i.C+#.)+B.++C+#._.3+++B._.< 3+r+_.n A+#.#.n 3+]+o D 3+3.3.S.&.D b |+K.: .|+G 9.{ j U C.,.,.7+7+7+7+l+/+p.2.n * 7+[ e+C.2.:.q.e+L.E 9.9.u.0 p.x.9.9.p+y+/+o+9.9.:.L l C+E { J.U.<+G.!.{ L.l.[.4+{ { L.] ] C+9.!.H d 7 m.&.D [.. q I.1 D.0.. B+2 2 k.. . |.^+r Q . . > ~ O 0.. B+C 2 D.B+. q n+^.J.Q.0.y+z 1.9.X.. }.1.9.!.}.. |.*.X.Q.0.. . 0.0.. . . . . . . . . . . . . . . . . 0.0.B+[.B+. . . . 0.0.0.q q |.|.r.| <+2+}.0 }.y+}.y+<+U. .[.] 7 7 : <+L.J.4 q.f.:+x.i '+7.*+>.s+A !.!.{ *+..s+A 9.9.9.= F r+o /.4 f.3.P v d+,.f+-+z ( 5.5.E u 9.4.^.l+[ d+e+,.2.q.,+,+a+*+E *+` ` ` ` R.8+o W c 5.(+W ]+f k j [ d+j.j.v 3 v #+w ^.i 7.4 q.l+d+[ u+t /.8+A.j 3 l m+K j.Q.a 2 e.O |+K.: K.|.] F.K l p 3 K F.l.k -+9.9.9.1.-.) i+8.5 e.I.D.|+K.].j.$.o.l F.F.F.F.{.{.<+o.w.I.0 w.S [.7 d ] ].> B+. . ", ") 4.-+-+&.9 9 9 z z z &.&.9 z z `.&.E `.4.4.4.) `.-+) `.`.`.-+-+`.-+) { -.-.-.q+4.q+{ -.q+{ 4.q+4.4.) -+4.4.4.4.) `.`.-+4.4.-.-.-.-.) { -.) `.9 f+o+o+f+f+b+B C+J.G.G.b+D o+i+&.6 B q.7.o+>+G.z 9 k+^.^.^.4+'+N.#+H H p.L.N.4+4+R.R.4+q.4+H.'+'+H 4+)+)+B.B.C+#.i.i._.A+#.B.++< #.B.A+n #.#._.D _.]+8.< n ! G < 5.! X 3.]+_.E+w.|+|+> e.{+9.z J 7+7+w+7+,.7+7+w+l+C.f #.3+i l+v d+7+7+7+e+e+H :+= p+'+o.A+9.9.!.4+e+b+!.9.8 N.l [+-+9.!.H y+B.u 9.>.y+[.<+G.{ p+y+7 y+u.9.{ t.7 <+z 9.E .0.S k+( +. . [.5 1 : . . .^ C 0.. . D.^ > . . 0.e.%+g+. . Q 2 e.r.0.. : b )+C+U.0.H+4.9.!.s . k+!.9.z [.. |.*.!+| . . . 0.0.. . . . . . . . . . . . . . . [.. . . . . . . . . . . 0.7 d 7 [.l U.F.g+] } 7 Q Q 0.. 0.@ U.[+u.!.!.E 4 B 4+q.J.*+x.!.!.8 E E 8 8 s+s+= = E n /.o f.o /.4 8+g F+v P F ( _.C.j.$+P F !.9.b+7+d+[ d+d+P e+v e+7+'+8+'+g V * 3.3.]+o < c c.(+< 8.< 5.F '+w+[ v j.L e+R m.H.)+X.L.[ v v F+M.t 8+t M.F+l . .L '.R a e.C I.6+6+S : 7 F.L v v $+3 3 m+m+k z u 9.9.9.9.9.9.q+D b I.x+l l l ].3 l F.F.F.m+F.F.F.K L x+D.x+]. .} d } ] l ].B+. . ", "`.-+) -+-+`.z 9 9 &.&.`.&.&.z &.`.`.z -+4.{ 4.4.4.) 4.4.) `.-+4.q+4.-.q+-.1.-.-.-.1.-.1.-.-.-.{ -.{ 4.-+4.{ 4.4.4.q+4.) 4.-+q+4.q+-.) -.-.) `.&.9 D o+o+b+X.7.J.G.i+8.8.J.G.X.X.8.X.^.;+G.>+b+8.D k+A+^.q.B 4+H H H #+#+B i J.)+4+q.4+'+'+B B 4+4+)+B..+X.)+C+#.)+k+++< i.++++3+A+6 A+< n G A+< 5._.o 8.< n S.G < n ! - X E+5 1 G+W n 5.) { n m m ,.,.,.,.,.,.,.,.C.k 3.o 3+}+l+7+7+7+7+v l+#.3+R.7+d+e+i E = :.0 C.-+9.9.>.0 0 f+9.9.N y+0 z 9.9.u.3 .4+x.-.;+l m+4+u 8 ;+<+[.4+1.9.G. .] B 9.9.H . q t.( 9 |+. . |+1 & . . t+w.2 |+. . Q a ^+|.. . k.^ r B+. . : 2 I.[.. . <+H+A+C+q B+D u 9.) B+D+o+!.9.8.0.0.| z+n+[.. . . 0.0.. . . . . . . . . B+. . . . . . . . . . . . . . . . Q q Q 0.0.0.0.0.0.0.0.0.d m+m+l L.*+x.E 4+p.4 ;+>.N A !.9.{ :+x.9.9.9.8 i '+* * * M.` 8+8+4 R.- F+[ V ! ]+E+y.Q.o.s.E 1.b+l+d+y+d+v v p p v d+F+e+O.e+F+7+J J s.3.G 1 _ $.'._ G -.1.N 4 C.e+e+Y.2.i.}+w .+)+n+j.3 3 F+A.8+8+8+u+[ v l .j S.]+5 a e.e.e.e.O K.|.3 j U U U j j.].].[ f ! 7.*+f+E { !.9.q+6 o.l l F.{.F.K {.F.F.F.m+F.F.F.F.{.l {. .m+l.] 7 } ] .[.Q . . ", "z `.-+-+-+`.&.z z 9 9 z &.&.&.`.z `.-+-+{ -.q+4.`.`.-+4.4.4.4.4.-.{ q+-.-.-.u u u -.1.1.1.-.-.1.-.-.q+4.) ) 4.4.4.q+-+4.`.4.4.4.{ -.-.-.-.4.&.9 i+>+f+o+c.J.f+f+f+f+b+G.b+D )+4+q.)+B 4+*+u.9 f+D i..+2.i 4+'+4+2.C+N.N.B 4+)+)+)+)+4+4+N.N.B 4+.+)+B.)+^.B.C+++B.B.C+++n B.++++< A+k+3+< 5.]+A+< 5._.! 3+< n ! G n n f _ '.k X G+G n 5.Y E.b.- ,.Y.g h+* L.C.C.C.C.C._ #.A+R.C.7+l+7+e+e+3.7.q.C.d+v L.F 4 '+7+[ p.:+x.p+'+e+b { 9.9.2.y+r+!.9.!.q.U.0 ) 9.!.r+r.t.`.u u 4+m+U.o+!.8 N.l.U.b+9.E o.q [.o+9.{ y+0.Q y.9 Z 0.. d & 1 ].. . T.2 T k.. . [.^+& 0.. . S ^ O 0.. . |+a s |.. 0.p.)+G.B . r.z 9.9.b+. : `.!.u y.. 0.g.n+5+B+. . . 0.. . . . 0.. . . . . . . . . . . . . . . . . . . . 0.. . . [.g+. . Q l.[.7 m+3 w+4+'+p.7.:+!.{ s+~.A A x.= s+~.8 { ^.l+[ P P U J M.R.o 4 8+M.P F+P J k X b y.S.b+*+2.,.e+d+v y+3 p p $+$+p ' $+d+d+).[ F+[ U 3.z.0 x+K.l U E 9.9.E q.g * F z G.X.#+^.J.b L 3 3 [ /.E.= E.5.! k 0 [ ;+E >+8.6 G+G+G+G+e.K.l.v m g - J U [ L L O <+L L j.y+t.#+q.J.*+b x+l F.{.l F.F.F.{.{.m+F.F.F.F.F.m+ .m+m+l.l.} } d ] ] d q 0.. ", "z z z z z 9 9 9 9 z 9 z 9 `.z &.E -+`.) 4.4.4.q+q+4.`.`.) 4.4.q+q+{ q+{ -.-.u 1.u -.-.1.u 1.1.1.1.-.-.-.-.) -+) { q+4.4.4.4.4.) q+-.1.-.-.`.4.`.9 f+i+f+o+o+f+f+o+o+c.G.o+D b+)+4+7.B.4+C+b+9 >+>+k+B B '+q.4+4+2.B 4+B B 4+.+^.)+)+)+^.q.4+4+4+4+)+)+B.6 X.B.k+++B.k+C+8.8.B.++A+< A+k+8.n n ]+A+< ( ]+o _.n < f G < < E+_ _ _ - o 3+F % 3+% R.- - L.L.'+s.#+#+#+X J G+n o a+Y.,./+7+P L.F o M.,.e+,+i 4 a+C.d+7+! 3+r+'+p./+N.2.:.++,+t.z 9.9.x.t.0 G.9.9.E 7+l C+!.9.8 /+<+B.u 9.x./+r.B 1.u i r.d t.{ 9.`.<+q F.`.9.G.0.. : ++9 o.. . : z.a B+. . : 2 6+0.. . |+^+> . . . +.^ S 0.. 0.e.e.2+Q . |.b C+o+o.0.Q.4.9.9.M . }.{ 9.-.2+. Q s p.2+0.. . B+B+. . . . . . . . . . . . . . . . . . . . . 0.. 2+o.q Q |.l.7 } @ l.F.p w+B i :+x.!.9.!.x.N !.9.!.!.~.:.p.d+v d+d+F+F+J g M.8+i o 3.m v d+[ [ j j U '+;+f+*+2.C./+e+y+d+d+$+$+$+$+$+v v $+v v v d+P _ _ $.j '.k i u.x.>.o M.R.4 b.7.}+[+a+;+b L 3 $+[ o z A !.!.!.1.-+9 { 9.!.z u.f+>+>+f+(+I. .d+J J - J U j j.x+x+]. . .F.l l U.L y+y+U.l {.l F.F.F.{.{.{.{.{.{.{.l {.l F. .m+m+l.l.} } } d } d Q Q 0.", "9 z 9 9 9 u.9 z u.9 9 9 z 9 z z `.4.) -+-+) 4.{ 1.-.q+4.4.4.{ { -.-.-.1.u u 1.1.1.1.u -.-.u 1.1.-.1.-.-.q+4.) -+4.{ 4.`.-+4.4.4.4.q+q+1.q+`.-.) &.9 f+>+f+f+f+i+f+o+o+G.f+o+o+b+B 4+G.k+^.*+z 9 D G+H L.H :.o+B..+N.4+N.B C+B n+B 4+^.)+4+4+N.B B .+)+)+B.A+i.i.k+++i.B.#.3+_.i.#.A+n #.#.< 5._.]+< E._.! #.5.< f ]+9 -.4.9 5.G ]+3+% n % n 4 R.M.s.M.M.'+f 3.! S.X E+n i ! s.Y.,.,.w+U 3+i '+Y.w+j ! 7.a+* C.e+s.3+4 2.i.G+@.H.p.w+C.H 2.*+~.= 2.e+B.8 9.9.r+y+H { 9.9.G.L 0 &.9.9.u.y+,+`.9.!.4+l.[.++!.8 2. .7 B u !.B Q Q +u 9.t.. q 0 b+( : . . |+5 }.0.. . 6+2 |+. . . +.r r.. . B+^+^+k.. . k.2 +.r.0.. U.B ++f+r.. B.1.9.9.r.. !+-.u >+B+. B+0 [+g+. . . . 0.. . . . . . . . . . . . . 0.0.q Q r.<+g+|.l.7 Q d } m+ .m+y+B J.{ x.= A 9.!.>...N A !.u C+e+v d+v v d+d+F+P J M.R.i o R.V [ d+d+v v v '+{ 9.9.-+G c+G+H.p.p.7+e+d+v $+$+v $+$+$+$+3 $+d+w.j w.j '.J M.8+a+g g L.* * h+C.l+w+g /+3 3 L [ U X R.o n z E { !.9.9.9.9.9.!.!.8 !.u W ].v P j [ [ [ O L x+l .m+[. . .].<+L <+l m+l l K {.{.K {.{.{.K K K l 3 K l F.l F. .m+@ ] } } ] d d d d 7 ", "&.z z 9 9 f+z &.z z z &.z z z z `.E &.`.4.4.4.) 4.{ q+{ q+q+-.-.q+{ q+-.-.1.1.1.1.-.u 1.-.1.1.1.-.1.-.-.-.-.q+4.4.4.4.) -+`.-+) 4.`.&.&.&.&.4.q+q+&.i+o+o+i+9 f+>+b+b+b+o+f+9 >+b+7.C+i.7.G.u.&.f+k+)+^.H q.b+i.q.B 4+N.B X.B N.N.N.N.N.H }+n+N.N.B B 4+B.f+++X.B.++i.)+6 ++C+)+i.< A+#.#.n < r+o (+n _.o n n o S.< c ) q+1.u 9.u E.n E.E.F 8+R.M.s.M.}+a+S.S.3.w E+< < o 3.M.s.- w+J r+3+! M.,.7+M.3+8+* C.w+R 3+i ! o B.]+S.E+b @.r+7.7.7.7.'+C.'+F a.~.= Y.y+7.9.9.!.L.<+J.!.9.!.H <+4+8 9.!.#+l.y+o+1.{ p.7 <+f+9.>.j.0.l.D 9.z .. : :+9.8 : . Q M 9 1 . . B+5+5 |+. . Q e.T : . . : ^+C &+. . : %++.0.. . S 2 s l.. . o.)+o+o+0.0.o+9.9.) D+0.k+-.u ++0.. r.5+Q.[.. . . . . . . . . . . 0.B+r.r.B+0.q q Q q 7 q 7 7 @ @ l.<+H r+~.9.!.~.= E 8 x.E N a.*+B e+v d+d+d+v d+d+e+P ,.g M.8+#.8+s.j d+d+j.j.'+z !.9.4.++W ; W G 8.:+J.'+d+v d+v $+v $+v $+3 $+$+$+v j.d+j.d+e+d+d+F+e+P e+7+7+7+7+d+v 3 $+v j.[ _ k k X E+a+.+^.7.J.= 8 u 9.9.9.9.9.4.*.y+L 3 K L l l l ]. .l.l.: m+U.j.o.y+x+r.m+{.l l K l K K K 3 v y+[ 0 0 j.j.L L l . .m+@ ] ] l.l.l.m+ . .", "`.&.&.9 f+f+E -+`.`.-+&.9 9 f+9 z `.4.-+-+) ) 4.4.q+{ q+4.-.-.-.-.-.{ -.-.-.-.-.u 1.1.-.-.-.1.1.u 1.1.1.-.-.-.4.4.q+4.4.) `.) -+`.`.&.9 `.) `.) 4.`.i+f+f+f+f+f+>+D G.f+D f+9 i+b+(+i.4+)+++o+&.9 D k+^.q.N.4+^.C+4+4+N.'+B N.N.N.N.H m.N.4+4+^.4+4+B .+)+B.X.)+k+C+)+i.A+A+C+k+A+b+++k+< < A+G < n _.o < n 7.! W (+(+j+c c i+&.-.( % E.F i o a+3.3.S.^.S.]+P.E+]+< n o f L.X #+k J 3.3+o a+- ,.X 3+i R.L.J J _.A+! ! }+]+++D 9 z &.i+#.'+2.B.3.R.;+Y ..b.` 7+e+L.:.*+7.0 e+`.9.9.`.e+t.z 9.9.z y+r.)+9.9.x.y+ .B.z u :+r.Q Q.{ !.r+] 0.0 { 9.z .. .z 9.C+0.. [.Z 9 s . . B+e.T [.D+Q K.5 C 0.. . g+_+C t+. . > ^ > 0.. . > a I.: . Q n+k+u.k+. |.-+9.9.>+. Q o+1.q+M . . . . . . . . . 0.q q Q [.|.. . 0.. 0.q q q 7 ] l.l.] 3 7.:+p+x.!.9.9.:+:+{ !.9.u ;+p.d+v v y+v d+v d+F+P P 7+Y.M.R.o _.R.,.d+e+j Q.m.^.C+@.5 6 ; W 8.`.9.!.f+l+$+v v d+$+d+v $+v $+v v v v j.v v v d+d+d+).v d+F+F+e+e+v v $+3 v j.0 '.t. +1+[+y.9+y.[+p.* /.Y >.x.{ x.A z [+x+l .F.m+F.l.l.l m+ . . .K.0 _ $.o.U.l.m+l K 3 K 3 $+v [ e+U U J k k k _ '.0 0 j.L ].].l l l ].L L |+L ", "-+&.`.&.9 u.&.-+`.&.z `.9 z `.z z `.`.-+-+-+) ) 4.4.4.-.-.-.-.-.1.1.1.u 1.1.-.-.1.1.-.1.1.1.1.1.1.1.-.1.1.-.-.q+4.{ ) 4.) 4.4.) `.&.&.&.E 4.4.`.`.`.9 i+i+9 &.i+9 9 z 9 c.G.f+f+c.J.G.B.C+4+7.f+i+8.)+B.w H a+a+H '+R.4+'+'+'+B N.B 4+4+N.B B B B 4+B )+)+)+X.B.B.B.i.++++C+B.++A+++_.< n ++o < 5.3+! A+n 3+! _.< j+c c c c c c n.G E.n F 8+! S.a+! i.#.8.f+-.9.9.1.q+_.k X - k C.s.F i ` M.Y.J _.3+! 3.- l+! n ! M.^.z z &.< S.E+Z i+( Z w+a+r+3+E.E.E.E.F s.e+e+C.w+7+e+l+'+:.;+'+y+N.!.9.9.C+<+[+E 9.9.7.m+s = 9.9.7.} : G.u 1.p.|.d .+9.{ C+l.Q #+1.!.p.0.0.0 1.!.Q.. . K.Z k+: . 0.U.b I.t+. . |+^+> . . . O _+S . . . & ^+g+0.. 0.& e.g.B+. |.B J.`.*.. g.u !.9.!+. . . . . . . . . 0.0.0.0.0.0.. . 0.0.Q d Q 0.Q q ] ] 7 <+o+!.!.x.E N x.-+*+;+p+x.{ k+0 y+d+$+d+v ).$+d+e+e+e+e+P 7+- ` o 4 R.k 9+Q.o.o.D.].].> <.T r 5 D { 9.4.p.$+v v d+d+F+d+d+e+[ [ [ [ [ d+j 7+,.g g Y.m 7+7+F+7+F+d+d+v $+$+v j.0 Q.t.Q.$.5+t.t.t.t.l+g * ` ` f.f.* * H [ 3 {.m+l.l.l.@ m+ .m+|+]. .K.x+o.Q.D.: ] m+K {.K $+d+w+,.J J - k - k k k _ k U '.j [ j.w.j.j.L x+L l ].m+", "`.&.&.&.z z `.-+) -+`.&.-+E `.`.-+&.-+) `.`.-+-+4.4.{ -.-.1.1.1.1.1.-.-.-.{ 1.-.u 1.1.-.1.-.-.1.1.1.1.-.-.1.1.-.{ -.q+4.q+4.) `.`.`.`.-+`.`.4.4.`.`.&.&.i+z z 9 9 f+&.i+o+c.o+f+f+c.f+o+k+B i *+f+D i..+i )+q.^..+'+4+7.++B.B.q.4+^.i )+2.^.B N.H.N.4+4+4+B )+B.)+X.C+C+k+i.++3+C+B.A+n ++#.A+n 3+o 3+n 3+o W 5.c c c i+Z.5.c ]+T 3.n /.! ! ! ! o ! 8.-.9.9.9.9.9.9.9.9.@.s.3.X k #.3+M.M.s.- 3.n R.3.s.J X < o M.s.< 9.++_ S : : K.w.(+D E+[ f o 3+E.E.n n _.a+9+#+N.N.N.p.,.l+7+e+[ '+N { :+C.y+J.9.9.u /+U.B.u 9.{ w+[.t.4.9.{ /+|.<+)+E { B 7 .u.!.z y+0.|.B.!.{ L . Q C+9.z [.. . D.k+1 0.. . O 2 |+. . . I.^+: . . . T r ~+. . t+a r |.. . 0.1+5+s &+. r.++o+`.g.. . . . . . . . . 0.. . . . . . . 0.0.7 7 0.0.0.Q Q q q l ^.{ 9.9.8 E u.{ 9.!.{ E ;+N.e+v $+d+$+v d+$+v d+d+F+e+d+[ F+J M.o _.! w t.w.D. .[.k.~+0+~+S S o.p.4 C+t.$+v v d+d+7+L.a+! G ; c+5 E+f R.R.8+8+` ` t ` * g g ,.m e+d+v v v j.t. +t. +$. + +1+ +t.l+L.A.* ` ` R./+K p K l F.F.m+l.l.l.m+L D.w.6+S K. .].L U.] [.m+{.K 3 d+U J - V J k J U j 0 [ j j '._ '.'.'.[ O O L l .l.} 7 ", "-+&.&.&.&.`.z &.`.) -+&.&.E -+) ) ) 4.) ) ) ) ) 4.q+q+{ -.-.1.1.1.1.1.-.-.-.-.-.-.-.-.4.-.-.-.1.1.1.1.1.-.-.-.q+q+-.-.-.4.q+4.) -+`.) 4.4.) 4.4.) `.&.`.z &.z z 9 f+i+o+G.G.D o+9 G.>+i+>+8..+C+o+9 u.f+f+o+D J.b '+4+7.8.H.N.'+H 2.++N.^.2.r+:.D i..+4+4+^.i.)+.+)+C+C+B.#.A+++#.++b+3+#._.5.< #._.5.n o G z u u u 1.-.) {+~ T $.- 8+M.M.M.3.s.3.! u 9.9.9 5 e.a j+u 9.4.0 f S.! _.n s.J X f o < 3+X ,+s.]+n ! U C.! &.G Q.: k.T.k.O G+++@.v L.3.o A+5.i+{+{+{+i+8.#.}+M.@.B N.L.l+[ 2.F R.C.e+y+w+4 b.7.y+t.4.9.9.z <+<+:+9.9.z <+l.^.1.9.E 0 r.N.-+u *+U.Q s { !.++l.0.r.9 9.G.7 0.B+G.9.D q . q n+D 1+. . 0.& T : . . 0.T T &+. . 0.2 r D+. . k.2 I.|.. . B+I. +s 0.. . . . . . . . . . . . . . . . . 0.} l.q 0.. . 0.0.0.7 ].9+:.x.9.9.9.!.= :+x.!.!.z [+e+7+d+d+d+e+d+d+d+v d+e+d+v v v [ 7+h+i .+#.o+b+H+D.K.~+k.0+T.T.k.[.].<+y+e+y+$+$+$+d+p.8+i B.W h Z.Z.c W _.o 8+f.8+8+` 8+8+` ` t * * g J P [ @.n (+3+++B.H+w z+n+ +'.C.* * ` ` ` s.y+3 l {.F.m+@ m+l.l.l 0 '.Q.w.O S K.K. .[.} @ m+K 3 3 P - V - J U j [ [ j.j.3 j.j.j.0 0 0 w.[ x+l : ] 7 q 0.. ", "`.-+`.&.-+`.`.`.) 4.) &.&.&.E 4.4.4.4.q+4.4.) 4.q+{ q+4.q+-.1.-.-.1.-.-.-.-.1.1.u u u -.1.-.1.1.-.-.-.-.-.-.-.-.{ -.-.-.-.q+4.4.) `.-+4.q+4.) ) ) -+-+&.&.&.&.9 i+f+o+o+>+o+*+o+z i+o+G.D b+D C+++++f+9 &.&.9 D A+J.;+D P.H '+'+N.^.o+++w '+^.2.C+++7.r+B.B.2.B.r+C+r+)+B.++++k+k+A+3+C+++n n _.o n n _.o < W D {+) -.9.9.) r C w.k s.j J C.9+- L.i.9.9.G+K.~+[.~+: 8.9.9.R k f f ]+5.! s.L.s.! #.3+n f X o 3+n 3.j J X _.-.`.D (+z u u D R w+g 3.3.]+Z.q+-.Z.=+; j+D >+#.,+s.#+H 9+#+3+4+7+e+[ e+d+e+e+e+d+l+..{ x.^.<+N.9.9.9.7.L o.E 9.9.G.r.<+9 9.9.G. .[.p.b+z H [.B+H.9.!.N.q 0.y+{ 9.B.q 0.].-+9..+. . B+*.8.S . . B+a & B+. . k.r +.0.. . [.^ <.0.. . k.T +.[.. . . . . . . . . . . . . . . . . . q 7 d Q . Q Q Q 0.Q [.x+Q.b C+u.{ 9.9.9.x.;+7.b.C+/+7+,.7+7+7+7+e+e+e+d+e+d+d+d+v d+v v M.J.E+u.9.u i+& w.w.w.> S S O D.<+U.<+e+7+v $+$+F+X #+l+<+g.6+^+c Z.=+_.o 8+8+` ` t * ` ` ` ` 8+` ` t Y./+n { u 9.u -.4.9 D k+B '.e+P h+` R.8+` h+<+K 3 {.F.F.F.m+F.0 _ e.& C w.O |+ .[.7 } m+3 L v j J - - - - [ j.v L 3 l l m+F.K l l L L ]. .7 d Q 0.0.. . ", "`.`.`.&.&.&.-+-+) -+-.4.-+&.`.-+4.4.-+4.4.4.q+4.4.q+{ q+-.-.1.-.1.-.-.-.-.-.-.1.-.-.1.-.u 1.-.u -.-.-.-.{ 4.-.-.-.-.1.1.-.-.q+) 4.) ) 4.4.4.`.`.`.4.-+`.`.&.&.9 f+i+i+D 8.G.o+c.b+i.)+;+o+b+G.o+G.C+*+f+z &.9 9 9 >+o+D 8.^.i J.H.4+G.D H.'+4+^.2.4+4+q.B.2.J.b+B.o ^.)+i C+B.B.J.A+++_.J.< i _.n n r+#.3+n 5 5 2 ^ ~ W 9 < w.C & '.3.X - L.C.C.C.w D 1.i+a O S O 2 4.9.-.k _ X E+< n ! 3.f M.f ]+G _.5.f z.#.3+n ! [ j U X #.n >+o+E.J.a+7+m Y.* X @.c =+& K.0+~+S *.>+i+G+n+H.H+G+_.n 3+C.[ 7+w+,.7+7+7+d+L.;+r+'+C.e+L.= 8 u.y.<+C+9.9.!.4+r.m.1.9.!.N.l.2+z 9.9.N.|.U.b+-.4.0 7 B+A+9.1.y.Q Q N.9.9.[+0.0.I.4.!.o.. . |.G+6 |.. . .2 w.. . . K.2 D.. . . ~+r C 0.. . . . . . . . . . . . . . . . . . 0.Q Q Q Q q q q q q ] x+Q. +y.H.^.*+1.9.9.9.E i N.,+l+w+p.p.4+q.2.q.L.C.w+7+[ e+e+d+d+v w+a+9+f+!.9.j+& w.w.w.C w.c+z z o+t.y+,+p.l+v p d+/+[+<+l.B+7 k.> ; ; 6 3.g * - ,.U ,.,.g u+* A.` ` t J j b S.A+o+`.{ u !.1.-.f+b y+$+U ` ` 8+8+M.j.3 3 K {.{.{.F.j.S.H+a $.& & +.O S : 7 ] 3 [ l+U J - M.M.3.- [ L 3 3 3 {.m+@ l.F.F.F. .l.l.l.7 d Q . . . . ", "`.`.&.z -+E 4.q+-+4.{ q+) `.&.E 4.4.q+4.4.q+-.{ { -.-.{ -.{ 1.u 1.-.-.-.-.-.-.-.1.-.-.1.1.-.1.1.1.-.-.q+q+q+q+-.1.-.-.-.{ q+{ 4.) 4.) 4.4.`.&.`.) ) 4.`.4.) &.9 i+f+f+c.++J.J.b+X.4+B.G.8.8.G.o+>+o+>+z &.&.f+9 9 f+>+D 8.i.G.W B q..+@.w s.'+4+)+}+'+4+R..+a+)+)+^.^.r+r+2.o 7.A+++B.A+n ++#.A+n A+o _.n #.z.z.2 ^+2 2 2 k C & 1 '.b S.3.s.s.- C.9+X E+< `.`.4.4.4.{ -+_.k J _ G n o a+R.a+f S.3.o o < 5.3.s.o _.n R.P l+7+7+l+7+7+l+w+7+7+P P P U J W _ : 0+[.k.k.> >+4.-.4.) &.i+D D D n C.l+g Y.Y.Y.w+7+r+4 R.L.l+y+! ;+q.Y.e+y+w+J.u.:+t.l+z 9.9.`.0 .@.!.9.{ o.|.m.9.!.1.y+B+}.A+{ E t.q : z 9.E U.0.7 ++9.1.U.. . M 1.4.|.. . r.6 e.t+. . x+2 > 0.. . S T > . . . . . . . . . . . . . . . . . . 0.d d ] ] ] } } } } ] ] L Q.'.Q.t.t.p.q.u.!.9.9.9.E r+q.2.u.x.!.9.!.9.`.(+)+L.w+,.w+e+d+v d+e+Q._ z+H+& O & C & & I.( u 9.u A+Q.,+4+p.e+3 p [ j _ w.|+: ~+].a n.E+'.U 7+P d+d+d+d+d+e+7+U l+J J j.j.o.w.I.o.Q.t.m.)+b+E E P.<+3 P 8+8+8+8+* j.3 3 3 K l l l 3.5._.H+X b y.y.M Q.g.l.[.$+P J J - g - - - U 0 j.v L L l m+] .[ 0 O O ]. .[.7 d d Q 0.. . ", "`.4.) `.`.-+4.4.4.4.{ -.4.) `.-+x.q+4.4.{ { -.1.q+-.-.-.q+4.-.-.-.{ -.-.-.-.-.-.1.1.1.1.u 1.1.-.1.{ -.{ q+{ q+-.1.-.1.1.-.q+q+4.q+{ 4.4.) `.&.&.&.`.) `.) `.&.f+9 &.>+8.C+C+G.(+i.4+C+J.J.G.f+>+f+f+D 8.b+f+D 8.f+&.9 o+b+A+o+G.B.C+H+H H H '+'+'+'+q.*+G+a+R.R.^.2.o o 2.)+r+7.i #.++J.A+B.A+n _.o _.< _.! z.5 6 ~ 2 a $.$.w.T 3+X 3.]+Z G+H+3.E+#+X X R _ R R f ! R.3.Y.J /+G+< o ! f M.}+M.f f 3.G+o < 5.G+X o A+n o J J ,.J C.,.,.m ,.,.m 7+P [ P '.z.z.<.|+|+w.a 9 -.1.9.9.9.9.9.u 4.( 5.s.,.'+H h+,+a+3+3.'+#+w+C.7.o s.w+e+e+v d+e+e+[ '+a.A !.J.s 0 1.9.9.:+g.r.G.9.9.z U.7 C+!.9.4.U.l.t.b+4.f+U.0.<+4.9.o+[.0.|.b+9.9 B+. Q X.u k+. . . Q.k+& . . . I.T S . . . . . . . . . . . . . . . . 0.Q d } ] l.K j.j.j.j.L K K [ R - m.#+R m.m.H :.x.8 8 1.;+3+z 9.9.9.-.`.>+8.j+c < w ,.7+e+e+e+F+e+o.O |+K.[.k.[.~+S |+> ]+{ 9.9.8.t./+i B [ 3 3 $+v v [ w.w.O Q._ k _ [ F+e+d+d+v v v v v $+v v j.j.L L K.K.|+<+x+D.<+L x+o.t.0 3 $+m 8+t 8+8+- v 3 p 3 K l p L R.u.u.f+A+#.! .+)+B.H.x+[.v P w+J k J U U j 0 [ j.j j.j.L .l.].k R $.w.O |+K.: d q 0.0.. . ", "-+4.q+4.`.`.-+4.4.4.-.-.-.-.4.) ) { 4.{ q+q+-.-.-.q+-.4.-.-.4.1.-.-.q+-.-.1.u 1.-.1.-.u 1.u -.1.-.-.-.-.-.-.{ -.-.u -.-.-.{ { q+4.) ) 4.) ) ) -+`.) ) ) `.) &.&.`.&.9 9 8.i.C+J.J.7.J.c.o+k+i.i.J.z 9 (+B.o+i+o+>+k+b+o+o+f+8.k+G.b+)+J.i.'+a+}+^.#.4+B.@.a+^.R.4+B.2.o ! r+7.i C+_.3+3+r+7.n 3+r+_.n 3+#.H+X ^ (.^ 5 T '.$.'._ k b ]+G G G _.6 #.]+S.w X k R k k k C.J J k z.< A+! s.9+9+C.#+X X X f ! ]+3+5.G+s.o o o i i 8+R.M.h+L.- L.g Y.,.Y.P [ [ [ j k 5 6 c+5 n.~ (.W j+9 `.1.9.9.{ A+5.S.C.'+'+s.A+3+- h+h+k ! 3+'+'+L.C./+7+l+e+7+l+4 Y b./.Y.[ /+u.!.{ .+].w u 9.9.C+r.l `.9.9.G.r.r.G.!.9.G. .|.t.b+f+)+7 0.Q.4.9.B 7 . K.-+9.i.0.. B+++1.k+0.. Q 5+k+X.0.. . . . . . . . . . . . . . . . q } l.{.L j.j.j '.'. +k X E+@.}+s.w #+w N.}+4+q.f.q.8+a+'+n u -.G 0 L . .L H+W k+.+L.Y.,.w+/+0 |+ .l.|.0.D+0.D+T.k.~+x+ +m.B.B 0 e+7.^.y+3 3 3 3 3 $+v v v j.[ [ [ 7+e+l+7+e+e+d+d+d+v v 3 3 l 3 l .l.l. .L 0 o.y+<+L .l j.v d+J 8+8+8+8+- v 3 3 K 3 K l 3 v C.^.*+u.z f+u.N { E 1 L L [ e+e+j 0 [ j.j.j.j.y+_ <+L ]. .l.F.w.e.a $.+.w.O K.k.d q 0.. . ", "-+4.4.q+4.4.4.{ q+q+-.-.-.{ -.4.4.q+q+q+{ q+{ q+{ -.-.{ q+-.4.{ -.1.-.-.-.-.1.-.4.{ -.1.1.1.-.1.1.-.-.-.-.-.-.-.-.1.1.-.-.q+{ q+q+4.) 4.) ) ) -+`.4.) ) ) `.) 9 f+&.f+) D ++i.C+*+9 o+o+o+b+C+^.7.++D b+)+;+f+f+i+b+H+++++o+f+D (+A+o+f+k+.+2.'+4+^.B.A+^.C+@.a+R.^.2.2.2.i r+o r+3+3+#._.n 3+i #.n < _.]+f 5 1 1 ^ 1 1 k w.L j.j.R ! #.#.G _._.W _.8.G #.@.G+G+G+S.f X X 3.< _.3.X J J C./+w+,+J U ,+X f o _.n ]+3.R.3.3.3.3.` R.i 4 /.R.` s.J J ,.U U P [ l+X G+c+1 (.; 6 ; ; ; W W c 9 n )+_.5.! k a+! r+n _._ s.! o n S.,+L.h+L.p.C.C.H 3.F E.Y i ,.P L.3+:.L.e+y+0 J.z -+#+l ++9.9.u m.r.t.4.9.!.b l.g.E 9.9.X.Q |.B q+&.}.0.0.z+{ -.5+0.. s 1.9.k+r.0.|.D u 1.|.. . . . . . . . . 0.0.. . . . . Q d d ] F.[ '.k X f X b E+f f S.)+#.o o S.a+H L.C.w+l+l+C.s._.z 8.D.|.B+D+|.w.P.< 5.3+o ` X k o.K.[.] B+. . . t+. t+D+].|+L y+v e+e+,.l+v $+$+$+$+3 3 3 $+v L v v v e+a+7.C+.+y.0 y+[ y+v 3 3 l l . .[.[. .j.'.'.'./+o. . .L v v u+8+8+8+8+J v 3 K p 3 p 3 3 l m+K $+e+h+q.J.N E E k+s L v j.j.v v v 3 j.j.o.0 '.x+ . .F. . .l x+O & $.<.|+: 7 d d q . . ", "4.4.4.4.) 4.4.q+-.{ 1.-.-.q+q+{ q+4.{ { -.-.-.-.q+-.-.-.-.-.-.4.q+-.-.-.u -.{ -.-.-.-.4.{ -.1.1.1.1.-.-.-.-.1.1.-.-.-.q+q+{ q+{ 4.) -.-.4.4.-+4.4.) 4.) ) `.&.9 i+>+>+D f+f+o+b+b+G.b+b+G.b+C+)+++4+C+k+N.q.++(+u.9 G.++f+o+(+f+o+D ( 9 D J.7.G.f+f+o+G.f+f+G+R.^.2.^.! 7.J.#.o J.3+r+r+n 5.7.#.3+n 7.#.! H+G+c+G+6 < ( G _ j.3 [ 9+S.]+6 _.c i+9 &.&.9 i+W _.@.3.G+]+G A+_.A+o M.C.C.C.C.L.w+l+Q.j U '.k X ! 3.R.! o 3+7.r+o ! R.M.s.s.3.R.o 4 i ` ,.l+U ,.l+_ b 1 (.(.(.; 6 ; W ; W 6 P.z.s.! i n o J R.! G n 3+k f ! _.n ! C.s.h+s.#+L.#+a+o F E.b./.J h+4 Y 8+w+e+v e+e+l+o.y+N.f+{ `.o.L f+9.9.-.o.[.m.u 9.{ +q g.1.9.-.s B+[.4+-+:+e 0.q ++!.u }.x+|.x+-.9.u }.0.. . . . . . . . q |.k.Q . Q d q d } ] ] K d+j /+k X E+! #.}+9+s.s.a+a+^.! 2.B.2.H l+7+e+P ,.X _.< G+e.X 5 c+W 5.5.A+/.r+f y.& |+: d 0.. . . . . . B+ .K. .].3 $+d+v v p p 3 $+p $+3 3 3 3 $+3 v v C.*+x.x.z i.*.$.t.Q.0 o.D.x+L ].l.[.l. .x+'.t.[+R o. .l L $+[ M.8+8+8+8+J v $+3 3 3 3 3 K l.@ ] @ @ m+K p v d+e+y+l 3 <+3 v j.j.j.y+X X R +$.s K.: : l l . . . .: [.k.B+d d q q Q . ", "{ { -.{ 4.4.{ -.-.-.1.-.-.{ q+q+{ q+-.-.-.-.-.-.-.-.-.-.q+{ -.-.q+{ -.q+-.q+4.4.q+-.-.-.-.-.1.1.1.u 1.1.-.-.-.-.-.-.-.-.q+q+4.q+4.) 4.q+4.4.4.4.4.4.4.) ) ) `.&.f+9 9 i+8.8.b+i.G.G.D o+f+c.J.A+4+B q.C+N.q.J..+J.8.J.o+D b+B.b+o+f+f+9 i+>+D o+o+8.k+k+G.>+i.C+B.2.B.r+G.n A+++G.3+#.3+n 3+_.3+n 3+_.]+1 G _.6 G (+4.u E.0 x+L e+X }+@.9 u 9.1.&.q+9.9.9.9.-.i+n < 7.o o ! 3.3.E+X k C./+R .+_.8.++f _ /+'._ - s.M.M.f f 3.o o _.3+_.o ! 3.3.M.3.3+4 U J h+k R b n.(.; ; ; W ; W ; ; n.e.1+k f ! o 5._.'.M.! ]+3+< k X ^.o n G /+s.'+s.'+M.s.a+o i n % 4 J - r+F i R.C.e+j.e+[ y+[ /+/+e+<+y+^.-+8 f+g.<+`.9.9.9 2+[.N.9.9.`.g.q t.4.u `.r.0.r.6 `.f+<+B+o.b+9.9.9.X.: Q 0.. . . . . . 7 |.&+k.0+k.|.] ] ] @ @ 3 v $+v j.l+- s.f _.]+,+/+C.9+L.L.H '+'+r+3.l+e+e+[ F+e+J f H+G G ]+5 f f M.s.i H+$.w.].[.d . . . . . . . B+ .K.l L y+e+e+d+v $+$+$+$+3 ' $+$+$+p $+3 $+j.4+E !.!.-.8.a T *.T $.$.$.Q.<.O ].K.].|+0 X .+w o.l m+l 3 v [ M.8+8+8+` j $+$+3 3 3 3 3 3 @ @ ] ] @ ] @ @ @ @ ] @ {.l 3 L L L 3 3 e+r+S.[+w.$.z+0 ].[.: F.l ].l F.m+[.} 7 d d q Q 0.. ", "q+q+q+q+-.-.-.1.1.1.-.{ q+4.q+{ ) { -.-.-.-.-.-.-.-.-.-.-.q+q+{ -.u -.{ -.-.-.-.{ -.-.1.-.1.-.1.1.1.-.-.-.-.1.-.{ q+4.q+{ 4.q+4.4.`.{ -.-.q+4.q+{ q+4.4.) ) `.`.) i+f+9 9 9 o+8.G.u.9 &.>+c.++b+G.G.C+J.k+m.B 2.++B.C+A+8.A+8.J.G.f+9 z i+i.B.++k+C+C+G.A+++B.*+D ++i r+7.#.A+3+3+++A+;+7._.7.n 3+A+_.]+#.z 5.]+D ) 9.9.-._ j.$+J 3.@.i+u 9.{+n.6+6+2 &.9.9.9.q+_.o ! 3.M.3.M.X s.s.- ,+y.8.1.!.9.9.{ f+#.k j U k X X X 3.3.3.3.M.s.M.3.o 3+_.X 3.o 3+3+k J s.f ^ c+; 6 W ; ; W ; ; c+2 & $.k k X 3.]+n < _ X R.]+< < k X R.o < _.k s.a+}+H+3.3.3.o o n E.F M.J a+R.R.o i 4 r+R.L.0 y+v y+e+v e+,+/+t.j.y+J.{ !.J.r.0 9 9.9.k+U.[.k+9.9.9 [.B+M D b+k+r.Q U.9 9.9.9.&.o.|.Q Q Q Q 0.Q d T.0+> r <.> S K. .{.{.K d+/+l+e+l+l+C.9+s.f G _.k l+w+w+7+w+,.h+}+o G k 0 [ [ j.v d+[ [ U j j U U U U l+'.D. .[.|.|.q . . . . . . q ].x+L '.p.q.p.v $+$+$+$+$+$+p p p ' $+' $+3 j.3+9.9.9.9.8.2 2 a a T T T T $.C & 5 G #.Z y.Q.O ].[.l.K j.j - ` 8+8+8+M.e+v 3 3 3 3 3 3 l m+@ ] ] ] } ] ] ] } ] @ F.3 l K l l l L 3 ,+y+x+].O y.E+& S : : l l l l m+l.} d q q 0.0.. . ", "{ -.{ q+{ q+-.-.-.-.-.-.-.4.4.4.4.4.1.1.1.1.1.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.4.q+4.-.q+q+4.) -.1.-.1.1.1.-.-.1.-.-.{ 4.4.4.{ q+4.q+4.{ -.4.4.-.1.-.q+4.4.4.`.`.`.9 9 z z 9 9 z i+D o+D z >+D ++)+A+i.N.;+f+.+p.r+4+C+7.*+b+G.b+J.D o+9 z D X.J.o+Z i J.k+@.2.2.J.A+i.n ++7.#.i i C+_.3+J._._.n 3+A+_.G ]+#._.@.G+G.{ u 9.9.3+[ j.J E+H+9 {+W > S 0+~+S <.) 9.9.5.3.X X X C.k C.k k C.U k < u u 9.9.9.9.9.= ^./+l+,.9+}+}+H+H+E+b s.f 3.M.f S.< < R 3.o 3+F X H+< i+i+c c.j+j+W W W 6 1 e.w.& R 9+s.3.S.]+< 5.z.X 3.! 5.G '.s.! ! n A+k X a+.+S.a+3.! 8+o n E.n R.J s.M.a+a+a+^.! 2.r+A+A+a+s./+j.<+3 j.d+v 0 /+/+t.y+4 !.9.9.P.r.Q.4.9.9.X.|.g+b+9.9.b+|.q N.4.!.9.9.9.>+U.] } } d q d } : S 0+0+t+D+T.~+: {.<+K $+e+7+7+7+l+C.9+C.#+}+o A+X 7+w+w+w+l+w+L.a+_.n G S.s.C.'.j j [ [ F+[ [ e+[ e+e+j L } d q Q Q . . . . . . |.O O D.'.)+Y r+e+p p p $+3 $+3 ' 3 ' $+p $+$+[ r+-+9.9.9.j+2 2 2 2 a a a z.T z.T A+z -+-+( P.x+ .7 l J M.` 3.8+8+8+8+M.P $+3 3 3 3 3 3 3 l.l.m+l.@ @ ] @ ] ] @ F.{.K K l 3 l {.l 3 y+L K. .].0 w R w.K.|.l. .l r.m+[.} } q Q 0.0.. . ", "q+-.-.-.-.-.{ -.-.1.-.-.4.4.4.4.4.q+-.-.-.-.-.-.-.q+{ -.1.-.-.-.q+-.q+q+-.-.-.-.-.-.4.4.4.-.-.1.-.1.1.1.-.-.-.-.4.) 4.4.4.4.4.4.4.4.q+q+q+-.1.1.-.{ 4.q+q+) ) `.&.`.9 i+>+o+c.z 9 9 9 &.z D 6 N.4+B.4+r+J.i.^.4+2.++C+o+b+o+++B.b+G.f+9 (+B.J.o+b+C+++B.a+^.7._..+2.^.2.B.A+i B.r+A+3+A+3+;+n 3+< < < 8.8.G R #+_.*+E.>.N F M.J J - f 6 i+6 <.S 0+S > ^+&.u 9 @.3.M.- L.- L.M.- J J C.3.E u.++b+z { 9.9.-+w /+J /+E+z { u u -.z B.#+#+w f ! ]+3+< X 3.o A+n 9 1.9.9.9.u -.q+) {+c ; a C O Q.o+9 _ /+s.E+]+i+< ,+k c+5.S.k - s.3.! A+< y.k s.3.S.3.S.3.R.o 3+E.n ! w+s.'+3.M.M.S.a+a+3.f 3.! ! o i r+B e+$+3 $+v v d+f.b.a.*+t.L X.!.9.!.n+[.[+1.9.9.!+|. .o+!.9.9.9.9.9.z l+[ 3 @ ] ] ] S <.0+t+t+t+0.0.B+{.[ L $+F+e+e+e+e+e+e+l+,.Y.f ! A+f e+7+w+,.w+w+C._.-.1.9.9.1.z b+a+w+w+l+e+F+[ F+d+F+e+j.] d d q . . . . . . d F.j.o.w.y.B.A u.e+p $+' $+' p ' $+$+' ' $+' v y+t.y.b k+8.2 T 2 2 2 2 2 2 2 z.2 5 `.u 9.!.4.8.& S ] U 4 ` ` 8+` 8+8+8+* e+y+$+$+3 3 <+v 3 U.F.F.F.F.l.] @ ] ] @ F.p 3 3 3 K 3 K K l L . . .l j.0 Q.& |+: k.l.: F.m+m+7 } d q Q 0.0.0.", "4.-.q+{ -.-.-.-.-.1.-.-.4.4.4.-.{ { -.-.-.q+{ 4.q+q+-.{ -.-.-.-.-.-.{ 4.{ -.-.-.-.{ 4.4.4.-.-.4.4.-.-.-.-.-.4.-.4.4.4.4.4.4.4.4.q+{ q+{ q+{ -.-.-.-.q+q+) 4.q+q+`.`.&.f+9 8.J.f+9 u.&.`.`.&.f+k+#+q.^.^.^.7.*+.+B '+B B.B C+b+C+G.o+o+>+++4+G.++i.a+^.4+a+4+q.2.R.q.^.J.A+b+B.#.7.3+7.A+n n < A+A+8.< < < 8.R _ }+n Y F F + F 8+X k - f 5 ]+W ; ~ j+) {+( 5.G+f f 3.M.a+3.s.L.X - k X n N z E.n 3+i.D 9.`.m.k k b >+9.9.9.9.9.9.-.++'+_ k E+S.]+< 3+k M.]+< i+`.q+-.u 9.9.9.9.9.9.c.C x+|+Q.z u i.,+- k w ( < X z.5.W M.- L.s.s.3.S._.n R /+L.#+s.M.3.'+R.o F E.5.o k s.}+}+a+a+a+S.S..+S.! .+}+E+f #.A+9+j.d+e+j.C.+ + 4 m d+[ p.*+f+^.s ].J.9.9.u s [.H.u 9.9.9.9.9.4.E a+g J P 3 ] ] l.l S 0+T.Q Q d l.3 l+j.v F+e+F+F+e+e+e+F+e+l+w+h+a+A+o '.e+7+w+,.l+*+9.9.9.9.u 9.9.9.E ! ,.w+7+7+7+d+d+d+[ l.] d d q Q 0.Q l.F.l v v d+U - m.E { t.$+$+$+' $+p p p p $+' p $+v [ y+O D.x g+~+~+S > 6+w.T T z.2 5 ]+u 9.9.9.9.i+P.D. .j.` ` 3.` 3.M.- J U [ v 3 v e+l+p.H+b #+[+o.<+F.m+@ @ @ ] @ <+,.7+e+y+<+3 3 3 <+j.].K.K.K.l L O w.w.].: k.|. .L <+l .l.} } 7 7 .", "-.q+{ q+-.-.1.1.1.-.-.4.4.4.-.-.-.q+-.1.1.{ q+q+{ -.-.-.-.-.-.-.-.-.q+q+q+4.{ -.q+4.4.q+-.1.-.-.-.-.-.-.-.q+-.4.4.4.4.4.q+4.q+{ q+4.{ 4.q+q+-.-.q+{ 4.-+`.-+4.) &.`.`.&.9 8.C+++k+C+D o+>+9 i+o+i.H 2.b+k+.+B ^.4+'+H H q.G.o+f+9 z -+i+6 7.A+b+B.B '+4+'+'+q.#.R.^.q.2.2.r+A+C+3+++++++D >+D D D < _.k+_._.#.H+@._.n E.E.a.E.n o - J J k k k k z.5 ]+5 E+X - X s.M.M.M.M.M.M.3.! i 3+n *+..E.E.:.C+i.++B.w 9+R 3+4.-+-+-.9.9.9.!.#.y./+s.f f f < < f R ! ]+5 ^ (.; j+c 9 -.9.9.9.5.O |+L I.n = f X - _ W ( G+k G n ! }+s.X L.X s.f 3.i+_./+Y.s.L.H - M.3.3.o o *+E.i k s.a+a+.+! .+! i.)+.+S.@.3.3.! #.n }+e+w+s.R.;++ 4 C.v 7+R.:.F L.[ y+#+u.f+)+D.K.b 1.9.9.9.9.u p.e+$+U * * J v @ @ @ m+F. .].L j.y+e+7+d+F+F+7+7+e+e+d+d+[ F+[ P l+X 3._._.k [ [ [ j n 9.9.D b I.[+J.-.9.u X.w+7+7+e+d+e+d+d+K @ ] ] } d d l.[ [ [ P P m * * C.* '+7+v v $+$+' $+' $+$+$+$+p $+v <+D.x+]. .k.&+D+D+&+T.0+0+~+S > 6+T 9 1.9.9.9.q+) k+w.3 m - V J U U F+d+d+v v $+[ b ]+#.W G 8.-+9 6 +<+r.l.@ @ @ ,.Y :+;+:.2.4+L.0 j.x+j.j.].K. .l O y.P.b & ].g+l.<+e+H ^..+H+H.b P.P.", "{ -.-.-.-.-.-.1.-.-.-.-.{ -.-.-.-.-.-.-.1.-.-.4.1.-.q+-.1.1.u 1.-.-.-.1.q+q+-.{ q+4.q+-.1.1.1.-.-.-.1.u -.-.q+4.4.4.4.q+-+{ q+{ q+q+{ { -.-.4.-.-.-.q+4.4.) -+&.&.`.&.9 &.>+X.i.)+)+J.i.i u.9 f+f+8.;+A+k+N.L.h+H '+H H b.G.G.D f+9 z 9 ++++B.B.H.'+q.R.'+4+4+4+R.4+r+2.2.2.r+7.7.++A+D ( i+9 &.-+4.{+c.W ]+_._._.3+< 5.u.>.N E.E.o X f E+E+z.z.- k k J k J - - w M.R.! o F F Y Y E.E.F F n ..b.o B.#.B.i.]+a+b o 5.n ++++D 4.9.9.B.y.k X X R 1 5.o X f _.5 & T a r 2 ^+^+^ j+&.) c+O |+x+0 f i.w f - E+5._.f X 5._.M.3.'+M.'+s.L.,+o ( ! X h+s.#+#+#+- s.M.3.! o n E.3+3.w X X E+Z 8.D 9 i+(+6 H.E+a+! 2.3+R.[ g R.i b.% 4 J d+s.2.i 7.J y+a+;+r+#+0 j.y+9+J.z 4.-+b+0 3 @ K J ` ! 3.'.m+l.@ F.{.{.K p v v d+d+e+7+7+d+v v 3 y+y+j.<+v j.e+,.M.! A+E+[ v e+a+1.-.6+~+[.|.l.s 4.9.-+[ 7+7+F+e+d+F+v K F.@ @ @ @ {.'.f X - - - M.M.h+/+7+e+d+d+d+).$+).' $+F+e+d+$+v $+y+j.x+|+K.: &+t+t+t+t+t+t+D+D+&+T.T.: |+Q.z+8.f+-+9.9.(+w.v F+d+d+v $+$+$+$+$+v 3 [+S.]+#._.W W &.) {+c.1 0 3 l {.K 4+a.= N = = A { z i.Q.w.Q.O ].K.].w.E+_.< D Z Q.s Q.B *+x.1.1.1.{ z >+", "q+-.-.-.1.1.1.-.1.1.1.-.-.-.1.{ q+4.-.-.-.4.-.{ q+-.-.-.-.-.1.-.-.-.-.-.-.-.4.4.4.{ 1.u -.1.-.-.1.-.-.9.1.-.4.4.-.{ q+q+q+4.{ q+4.q+q+q+q+1.-.q+q+4.q+4.) ) `.`.`.&.i+D o+`.9 o+b+X.J.o+b+b+f+f+f+9 f+k+w B L.Y.q.q.4+J.f+i.D G.8.D D D (+++++^.^.R.7.B '+'+R.R.a+q.2.2.^.2.i J.A+C+n >+5.*+< _.8.< 8.9 i+G S.8.< < 3+< E.E.>.a.E.E._.G+G G G ]+@.f X X s.M.3.8+i F F + % F % E.E.% E.Y F F 4 i r+B.#.#.#.r+]+E+G u.z = z f+A+8.z H+m.- k _ k < _.f X o _.'.O & C C C C T C <.T z.'.D.x+x+o.'.X #+X k < < 3.k _.< 3.M.L.s.s.s.M.X k 5.< E+M.w #+s.s.H s.#+#+M.3.! o 3+5.( 5.D >+u 9.9.9.9.9.9.9.-.( w 3.R.! 3+o J g R.o F b.F M.j #+! _.3+s.k 2.3+i 0 v e+l+/+w+[+e+y+{.{.F.@ K k n < 8.@.L {.F.F.K {.K K ' d+F+7+7+v L j.i.{ u u { o+b v $+v w+M.3.A+! [ d+w+4+x.&.z.S : [.D.E 9.`.y+m 7+7+F+e+d+d+$+p K K v 3.E.`.&.( 5.3+R.C.g h+,.7+7+F+d+d+d+d+$+$+$+f.:.'+Y./+e+d+<+x+]. .[.Q . . t+t+t+t+t+t+t+t+D+k.: .r.r.e 4+E !.-+a j.$+$+$+v $+$+v v $+j.d+'.]+]+]+G ; G c &.Z.{+{+X.0 <+3 <+:.s+A A ~.~.E u.C+z+& w.& w.w.> |+x+w.Q.e.M +Q.Q.B u.!.9.9.9.9.9.9.-.", "-+{ -.-.1.1.1.1.-.1.1.-.1.1.1.1.1.-.-.-.-.-.-.{ -.-.-.-.-.{ -.1.9.u -.4.-.-.q+4.q+{ -.1.-.1.1.-.-.-.-.-.-.4.4.4.q+-.{ 4.q+q+4.{ 4.4.4.{ q+-.{ { q+4.4.4.4.) ) `.4.{ ) 9 z 9 &.&.z i+G.c.A+b+8.8.*+>+D 9 o+k+H H :.:+o+f+9 D o+o+k+N.H 2.o+1 ^.2.B.C+++N.'+a+'+4+R.q.2.B.)+r+2.#.#.C+o+( < i.b z.e.a 2 (.i+D 1 #.A+8.3+< n 5.z z {+9 {+c (+(+c 8.G G _.F n b.n Y Y E.E.% E.% n % 3+F 4 4 o o o o B.B.B.]+#.#.G+G ( 9 z z u.3+o )+.+E+w 9+k '.]+3+3.z.3._.f w.|+O <.6+6+6+6+6+> D.Q.'.O |+_ w.t.w 3.X ]+( o f f n o s.h+L.L.L.Y.- J ]+5.! f f }+M.H s.H.s.s.s.s.M.f S.f s.S.#.n 4.9.9.9.&.8.1 c+9 u 9.`.$.M.M.R._.i J M.8+o F E.Y o J s.)+o 3+#.X ! r+7.X [ [ y+v y+p K K K p K j 5.{+{+{+Z.W $.v $+$+$+).v d+F+7+7+O.$+<+m.9.9.9.9.9.9.9.b+<+3 3 w+h+3._.3+X /+t.j .+D z `.-+4.E o+^.7+F+e+).F+d+).v $+$+$+$+4 ~.u x.( 5.9 { E o 7+Y.,.,.7+7+e+).d+$+).v e+= A f+++)+C+_ j.].]. .[.0.. . . . . . . . . . . B+[.: l.m+ .0 H 7.C+Q.<+$+$+$+v <+' <+v y+e+k E+< < G ]+G 6 W {+( i+&.`.>+@.l+l+b.A 8 !.!.8 8 { -+f+D (.5 2 a e.C O O D.x+x+K.K. .U.p.D 4.!.9.9.9.1.`.", "4.{ -.1.-.1.1.1.1.-.-.1.1.-.1.u -.4.4.{ 1.-.-.-.4.-.-.1.-.-.1.1.u 1.-.-.-.-.{ q+q+-.-.{ 1.u -.-.-.-.-.-.4.4.4.-.{ q+4.4.{ q+{ 4.4.4.4.q+{ 4.`.q+{ 4.q+4.4.q+4.-+q+q+) ) ) &.9 &.&.&.&.i.A+8.o+C+*+D X.G.f+f+o+B.*+c.++f+9 ++D >+D B '+q.u.i.2.J.o+G.i.'+'+'+'+a+R.q.R.2.2.o r+2.2._.G.u.D G+2 a a T 1 (+( < @.o _._.W < < < {+{+q+-.1.u 9.9.u u &.5.u.z a.E.E.E.E.Y Y n F _.F _._._.i o r+o o o B.G o G G j+i+1.u -.4.z 5.]+.+)+X.a+E+X k f < o X X o ! _ w.|+|+O 6+6+O 6+6+x+x+w.0 0 $.:+! y.E+w E+< n G+X < 3+3.M.#+h+s.- k k X n #.M.M.s.M.}+H.s.s.}+}+}+f }+f f f 3.3.H+z.(+9.9.(.S k.&+&+0+1 9.9.G [ h+X 8+n - M.R.R.! n E.5._._ w ! ! 3+8.X M.s.a+! r+r+4+e+y+d+$+p p [ 5.{+Z.h h Z.Z.Z.j+n+w+Y.,.,.,.,.7+* * j.x+I.{ 9.9.9.9.9.9.u e.L ].d+,.* f @.G A+< _.]+f _ _ k #+H Y.7+F+d+F+d+d+d+$+d+v $+d+P E.u.o x+ . . .w.b.x.G.L.,.7+7+7+7+F+e+F+v $+l+x.{ E >+++R o.|+].l .k.. . . . . . . . . . . 0.7 [.l.l. .l ,.` 4 2.0 j.v <+$+$+$+$+7+L.a+! 3.3.f z.5 n.c < < ) ) {+i+8.k+^.4+2.N 8 8 8 !.!.9.9.9.9.9.4.; 2 T & +.6+|+S g+: . .: l.: .L Q.z+6 k+1 e.", "q+{ -.-.-.1.-.-.-.1.-.-.1.1.1.-.-.4.-.-.1.-.-.-.-.4.{ -.1.1.1.-.1.1.-.4.4.q+-.{ q+q+q+4.-.-.{ -.-.-.{ q+4.4.4.q+4.q+-.q+4.q+-.4.4.4.4.q+4.4.4.q+{ q+q+4.4.) ) `.-+&.) -+4.`.&.9 &.&.`.i+o+G.k+.+;+D B 4+B.)+b+f+o+D ++u.9 o+D 8.D k+4+2.G.i.4+B.^.i.a+'+'+R.R.q.2.2.)+R.2.i r+#.! #.++n ( f+5.(+G 6 D 9 5.G ]+]+_.A+_._.< < ( {+{+c W c &.u 9.9.u {+z E.E.E.% 3+F F _.F _._.3+_.F _.o o o o i.o G 8.i+`.1.9.9.9.9.9.9.9.5.S.S.^.! G+a+E+X < _.f z.! o X '.O |+|+> 6+6+6+O 6+S |+w.w.0 w.'.m.k X k ]+5.o E+! n o 3.a+a+#+s.s.L._ G n 3.s.s.#+#+s.#+#+L.H s.#+E+}+}+3.f E+w X w P.b+u c > k.k.B+D+e.u u D v J k F o s.M.f 3.&.u u 9.u 1.8.P.]+! _.< R s.a+}+s.s.S.J.9+y+F+d+d+#+D c ^+> 0+0+> h.i+!.B ,.g h+V g g ,.g l+y+x+I.(+u 9.9.9.9.`. +x+L d+,.Y.s.a+S.E+E+}+G+_.< < _.! s.C.l+7+e+7+7+d+e+d+).v $+d+d+8+n 3.S k.[.[.7 j.E.`.E b.4 ` A.g ,.e+e+d+v 4+8 9.9.9 6 b 0 ]. .[.|.q . . . . . . . . . . . 0.B+|.[.l.l.F.v 7+7+e+y+3 $+3 $+3 $+e+'+3.s.L.C.,+U _ '.Q._ 5 W 5.n G z._ t./+,.H p+s+~.8 8 !.9.9.9.9.9.u 9 6 T +.w.6+w.O > K.: .r. .g+: : : g+r.g+g+0+", "4.q+{ -.u 1.1.-.1.-.1.1.1.1.1.u 1.1.-.1.1.1.-.-.-.-.q+-.-.1.-.1.1.1.-.-.q+{ q+-.-.{ -.-.-.-.q+4.{ q+-.-.-.4.4.{ -.{ -.{ 4.-.-.q+4.4.4.4.) ) 4.{ q+4.4.) 4.`.`.`.`.9 z 4.) &.&.9 9 9 &.&.9 D i.)+G.(+.+H B B C+f+b+o+o+o+D o+o+D G.b+A+B.G.D D k+N.'+'+'+'+'+a+4+)+2.2.2.++B.o r+r+2.#.C+C+3+J.< _.#.A+A+k+o o _.< _.< W G W 5.c ^ T C C r =+q+9.9.1.9 n 3+F F _.F _.i _._._._.#.G #._.A+A+8.3+< ( -.9.u 9.9.9.u 1.u u 9.) z.M.a+G+! G+X ]+3+! X M._.3.k U O x+w.C T C C <.O ].].j.j.].L L [ k J z.n _.3.3.3+3+o R.S..+a+@.f X z.n #.3.M.s.L.g h+L.Y.L.C.C.L.L.L.L.#+w s.#+#+X X b D 4.-.j+c+c.&.1.1.z w j [ 3.3+! L.X f -.9.9.9.9.9.9.9.q+k+P.3.o n S.9+s.N.s.a+! n B [ 7+U - 8.r 0+T.&+&+&+k.P.u 4.y+Y.h+g L.,.g Y.g Y.j j.L g.1+1 X.1 1+o.j.j.P ,.C.C.s.}+H+w E+E+E+H+E+a+S.! 2.r+q.q.L.7+7+e+e+d+F+d+v d+[ U f f $.w.O O X < ( E.b.:.+ /./././.4 4 *+8 9.9.u >+1 a w. .[.} 7 . . . . . . . . . . . . 0.|.7 7 [.m+m+3 3 p 3 3 $+3 p 3 $+3 j f /+e+j e+[ [ [ j U U U U '.'._ /+j 0 e+e+w+b.= s+~.A 8 8 9.9.9.9.1.i+k+z+<.w.O O O O O D.> x+|+x+r. .l.|.B+B+Q 0.", "4.q+4.4.-.1.u 1.u 1.1.-.1.-.-.1.1.1.1.u -.1.-.-.-.-.-.-.-.1.1.1.1.-.-.-.-.4.-.-.q+-.q+{ -.-.q+q+{ q+4.4.4.q+-.-.q+-.-.-.4.-.{ q+{ 4.) 4.4.4.-.q+4.4.4.) 4.) `.`.) `.`.) 4.) `.z f+f+9 o+9 >+D D G.f+9 b+B 4+H :+D o+i+o+c.f+f+i+>+o+f+f+z 9 9 D #.^.a+'+4+4+q.7.B.^.^.F b+i.o 2.o B.#.A+_.#.#.B.G B.#.#.#.k+_._.8.A+_.3+_.W < ; T C 6+6+<.^+Z.9.u {+G _.i _._._.i _.o i o _._.F 3+3+3+3+3+_._.G (+1.9.9.u {+_+C r r %+{+{+; _ a+! ! f @.3+_.X X o o f _ '.w.w._ 2 2 r r C > ].|+w.x+l F.l j.l+'.G < S.X o n o ! ! ^.! @..+H+b < < 3.3.f '+f s.s.X L.- #+9+L.L.L.Y.C.- L.- #+L.9+'._.( E.u.u.`.>.3+! #+J U U 3+_.X g ,+D 9.9.4.D G+1 W 4.9.9.8.k }+! n G+U 9+#+s.}+S.< ]+0 l+J b W r ~+0+0+S T 9 !.9 y+m ,.g g Y.g Y.Y.L.L.9+l+0 y+s o.o.I.0 j w+,.m ,.w+C.i.9 q+1.1.4.9 8.i.G+@.}+'+H h+'+q.q.q.* C.e+7+e+d+v [ [ 0 _ k E+f R.3.R.R.R.8+/.4 + + :.s+A f+1 X.c.&.i+a 5+w. .|.d q . . . . . . . . . . . . . d 7 } } l.l 3 y+v v $+v v $+3 v 3 ,.f j j.j.j.v j.v j.[ [ [ j j j j l+0 l+0 l+C.i >.~.8 8 { x.E E `.u.c.6 1 a s O I.Q.Q.I.s O O s x+x+U.K.r.~+B+D+0.0.", "-.{ q+{ -.-.-.1.1.1.-.1.-.1.u -.1.-.u u 1.1.1.-.-.1.1.-.1.-.1.1.u u 1.-.-.-.q+-.-.-.-.q+4.-.-.-.q+4.4.4.4.{ -.-.-.-.-.-.{ q+-.-.4.4.) 4.q+{ q+4.4.) ) 4.4.q+) 4.4.) `.`.) ) `.`.&.&.z 9 z &.z -+9 f+z D .+H 4+*+o+i.o+f+o+o+>+o+o+i+f+9 9 9 ( o+X.J.C+4+8+a+q.2.o ^.^.^.r+n B.2.r+2.B.C+#.C+_.i _._._._._._._._._._.G G G o 6 < 5.c c.j+c &.1.1.&.G o F _.i o _.o _._.3+3+3+3+3+3+3+_._.r+i G _.W i+u 9.{+C S 0+0+0+> _+{+< $.M.f f f _.3+3.X ! o 3.X k w.T 2 z.^+^+^+C <.> S ].0 j.].m+3 j.[ f < o X f 3+i R.a+! .+a+f f 5 G 5._.s.a+^.S.a+}+}+s.E+s.s.s.#+L.#+L.L.9+9+L.- k J X n E.n b.3+o #+- C.,.,.J 3.n ! C.9+k _.9.q+O 0+k.k.~+> &.9.u $.,.a+! 3+]+k C.L.s.f @.3+8._ U k _ @.G c+G -+{ z G.H 7+,.Y.,.Y.Y.Y.Y.Y.L.L.g L.L.- L.C.C.- Y.Y.Y.Y.Y.,.w+@.u 9.9.-.{+`.1.9.q+++n+'+s.N.H H L.Y.p.L.a+o k 7+,+J e+[ [ 0 [ e+j l+l+U Y.'+s.'+'+a+2.*+!.9.9 T s s | W.S g+: o.z.& K.Q . Q q q Q 0.. . . . . Q d 7 7 } l.l y+,.'+p.p.g p.y+y+$+v - f w.v L 3 L $+3 $+3 $+v v v d+[ e+e+e+e+e+/+C.H 4+C+J.:+f+o+G.G.++i.X.P.1+O x x+t.Q.& I.o.O O e O |+|+K.g+[.q Q . ", "-.-.-.-.-.1.1.-.-.u 1.u -.1.-.-.u -.1.1.1.u 1.-.-.-.1.-.1.-.1.u u 1.-.-.-.-.{ -.-.-.-.-.-.-.-.-.-.-.4.q+q+-.1.-.1.-.q+q+{ q+4.) `.4.) 4.) 4.4.-+4.) ) `.4.4.) 4.`.&.) `.`.`.&.`.&.`.&.&.`.`.9 9 f+i+9 6 '+H q.:+f+b+o+f+9 o+>+8.b+o+(+b+++k+X.C+C+r+C+B.f+)+4+4+^.^.R.^.r+2.)+o B.r+i i r+C+_.++_.7._._.7.A+3+A+_._._.o ]+]+]+6 < ( z E `.`.9 5.G G G _._.< 3+3+3+n F 3+3+3+_._.#._._._._._._._._.W 5.q+q+I r C C r h.c ( W z.3.H+b ]+< ! X f 8+3.X _ '._ 5 1 5 2 r T C <.<.O x+w.j .{.K v Q.G 3+f X o F 3.R.3.a+G+G+6 (+c 5.i+W k f ! a+S.S.@.a+H+H+}+}+}+}+f #+s.L.L.9+L.9+J o E.E.Y % F M.J J C.C.X M.o n n X R s.w D -.a 0+B+T.B+k.1 -.9.z+j ,.s.S.A+_.k w+L.s.f @._.< k j /+J /+'._ #+w m.p.,.,.,.,.,.m ,.Y.Y.Y.Y.Y.g Y.Y.Y.L.L.L.L.L.C.Y.g L.Y.C.J.9.u ^ | ~+W.6+8.9.9.8.'.C.Y.Y.C.Y.Y.L.* H.f A+! _ j '.,+J U 0 [ e+P e+[ [ d+7+l+C.}+! 9 9.9.>+!+e.1+5+I.O O g+@.E 4.k+|+|.g+K.K. .: [.|.B+q Q B+B+7 7 7 l.L e+q.p+N ;+..p+H y+$+y+M.M.0 v L 3 3 3 3 3 3 3 p 3 L 3 3 v v y+e+e+e+l+w+C.p.p.p.[+Q.N.b+++B.B.k+X.*.O |+t.R m.*.Q.Q.w.w.O O O |+g+k.|.7 0.", "-.-.-.-.-.-.-.-.1.-.u 1.1.-.-.1.1.u 1.1.1.-.-.-.-.-.-.1.-.1.1.1.1.u u 1.-.-.-.-.-.-.-.-.4.-.-.{ 4.4.4.4.{ q+-.-.q+-.{ -.q+4.) ) 4.4.) 4.4.4.q+4.4.) 4.4.4.`.) ) `.9 &.`.`.9 f+&.`.&.`.`.) `.`.9 9 9 k+X.2.7.)+f+f+f+9 o+>+>+>+8.C+J..+4+N.'+2.J.++)+2.r+A+G+R.R.q.2.q.2.^.)+2.2.r+i _.#._.i i 7.7.A+A+A+_._.A+_._.i _.3+_._.#.G G G _.G _.G G G _.< < n < 3+3+3+3+3+_.3+A+A+A+_.i _._._.#.G _._.G W G W (+c i+{+{+{+5.5.W S.3.@.f 3.3+_.f X o ! f - _ $.]+G 5 z.T T r T z.2 z.$.'._ x+F.K L X 3+! - f 3+o M.M.#+]+(+5.{+{+Z.{+Z.{+W k a+! R.a+a+a+a+a+}+a+3.a+E+a+}+}+E+'+w f f o E.E.E.E.F ` Y.Y.k w f @.]+G 3+n E+,+m.k b G G P.M 5 G ( 4.-+3.7+7+U - 3.i < R '.C.X H+3.]+A+R j /+U /+,+w+,.,.Y.,.,.,.,.Y.,.,.,.C.p.Y.Y.C.L.C.C.p.Y.C.,.,.C.w+,.,.C.C.N.!.1.+.T.T.B+B+T.c.9.1.t.w+,.,.,.l+w+,.l+g f o n (+j+6 z.M R k ,+w+l+w+,.7+P e+v /+s.[+ +i.o+i.e.*.y.y.*.y.[+ +o+!.!.8.s S <+y+y+I.o.O g.|+K.K.K.K.r.l.l. .U.C+= A 8 { x.p+B o.v [ 3.- 0 j.$+$+v v L 3 p 3 l 3 3 3 3 K 3 3 3 3 y+e+y+[ o.0 e+y+U.y+r+)+B.A+*+3+i.n+w.S y.;+B.)+H.e.$.5+I.s O |+].g+|.0.", "1.1.u u 1.1.1.1.u -.1.1.-.-.-.u 1.1.1.1.u -.-.{ -.-.-.1.1.1.1.1.1.1.-.-.-.-.-.-.-.-.-.1.-.-.-.q+4.4.-.q+{ -.-.-.4.q+4.4.4.4.4.) ) -+4.4.4.4.4.) 4.4.) 4.q+4.) ) ) -+) `.`.i+i+9 9 &.`.) ) `.&.&.9 i+X.H ^.)+J.9 i+D o+o+o+D b+)+)+H 4+^.'+q.G.8.2.)+^.B..+^.^.^.S.^.R.2.^.)+2.o B.r+#.r+r+#.r+_._._.7.3+A+A+3+3+3+3+_._._._._._.A+_._._._.< < 3+< n 3+3+< 3+< 3+3+< 3+< A+_.A+A+A+_._.++_._.#._._.#.o ]+]+]+]+]+o G ]+]+3.S.S.f 5 G n ! f o 4 3.f k a W ) &.; 2 r z.5 ; c 9 9 ]+X _ L l K [ o F X X i F 3.M.s.S.5.i+>+W ^ r h.~ c 9 ]+k 3.a+a+}+'+3.a+}+}+}+a+H+}+a+a+a+3.a+H+S.]+3+E.E.E.E.F M.- ! 9 -.-.`.( i+n 5.S.'.j j [ '.X r+E.u.u.u.E.3+s.U J C.s.a+#.n E+/+k #+f @.! A+@.'.U C.C.,.Y.C.Y.p.g Y.Y.g Y.g Y.Y.,.C.g Y.Y.Y.Y.,.,.C.,.w+,.,.7+7+7+7+,.B `.-.(.+.> S e.&.9.) [+,.Y.,.,.7+7+w+l+,+X 6 8.j+j+Z.{+{+i+j+6 E+X - L.w+e+e+0 m.E+Q.S r.r.W.r.: r.].e O Q.n+z !.!.c.I.D.0 t./+[+,+/+t.Q.Q.I.Q.I.o.s <+y+t.`.9.9.9.9.9.z B }.j.e+3.k [ j.v <+v v j.j.<+$+3 3 l 3 3 l l {.K {.{.3 3 3 l U.L F.l.l t.m.m.)+_.3+8.k+n+w.S <+n+H.4+.+H.P.P.n+M 1+Q.O |+: ", "1.1.1.1.1.1.u 1.1.u 1.1.u u u 1.1.1.u 1.1.1.-.-.-.1.u 1.1.1.-.1.1.1.1.1.-.-.-.-.-.{ 1.1.-.-.1.-.-.4.q+4.-.-.-.-.-.-.q+-.-.q+4.4.4.4.4.4.q+{ q+4.4.) -+) 4.4.4.) ) `.) 4.`.&.z z `.&.`.) 4.`.&.&.&.9 D )+4+C+:+9 k+.+B 4+++*+>+++)+B q.2.4+2.G.i.4+q.B.*+k+2.u.9 b+G+! 2.^.2.B.B.2.B.#.r+++_._.i 7.A+_._.A+_.8.3+_.A+3+< 3+3+3+3+_.3+_._.3+3+3+< 3+3+< < < 8.8.8.A+A+A+A+A+3+A+A+A+< 8.A+A+_._._.G G o ]+S.@.@.1 @.f f 3.G+]+G+f ]+n _.3.3.F i ! f z.6 u 9.9.-.( (+j+i+q+9.9.9.( H+0 l l v - F 3.- M.4 ! M.h+- o 5.6 e.> ~+~+S 0+^+i+9 +- '+M.M.'+E+}+3.a+3.a+3.a+}+}+S.H+@.3.3.! o n E.E.a.E.b.3.G+>.1.9.9.9.9.4.< n ! j e+[ [ U X ]+3+E.E.E.Y F M.l+C.- M.3.]+n ]+_ - X E+@.3._.#.k C.L.g C.Y.Y.Y.Y.p.Y.Y.Y.Y.Y.Y.Y.g Y.Y.Y.Y.g Y.Y.,.,.,.,.7+7+7+e+F+e+/+t.H.D { u 1.1.-.z )+C.Y.,.,.w+,.7+l+7+U _ o c.c Z.V.h.h.; c c &.( 3+8+! 2.3+n H+R y+K.S K.].].K.K.K.: : [.r. +G.z ++n+Q.t.p.L.H N.N.N.p.p.p.y.p.p.t.t.Q.y.G.9.9.9.9.9.E .+t.[ J 3.k 0 j.j.d+'._ 5 5 5 *.Q.y+y+3 3 3 l {.F.F.3 l l l K F.l : ] l.L y+0 Q.9+H+_.A+6 e.o.|+U.o.Q.t.m.n+H.X.B.B.)+.+n+& ", "1.1.1.1.1.1.u u 1.1.u 1.u u u u u 1.1.-.1.-.-.-.1.-.1.1.1.u u 1.1.1.1.1.-.-.-.-.-.q+-.1.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.{ q+q+q+-.4.4.4.) 4.4.4.) ) ) 4.4.4.4.`.`.`.) ) `.&.`.-+) ) -+4.) `.`.&.`.`.&.9 b+++b+o+++A+)+4+4+C+8.A+J.B.4+r+J.b+o+(+++4+)+A+8.A+u.9 f+k+a+q.2.2.C+#.B.B.#.C+7.A+A+_._.A+A+A+3+3+8.A+< _._._.8.A+A+3+3+3+< 3+3+3+< < < 5.( 9 ) -+-+) &.i+n 8.7.F 7.A+A+3+_.A+A+A+A+A+_._.G G o G ]+]+]+G+G+! ! ! @.G+3+3+]+! G F o 3.3.z.D 9.9.9.9.9.9.9.9.9.9.9.9.q+b j.3 l U f.8+f - f./.3.M.L.- 3.A+1 O 0+S 0+0+0+r {+`.z.J a+s.E+'+s.s.}+}+E+}+}+3.a+}+a+3.S.S.! ! ! o 3+E.E.a.E.5.G j+c i+{+q+1.1.D o 3+o '.l+l+C.k 3.]+3+E.E.E.E.F 3.J L.M.'+S.G+n _.R X w f 3.3.o A+X C.L.L.L.g Y.Y.,.,.Y.,.Y.Y.g ,.g ,.Y.Y.C.Y.Y.C.,.C.,.,.,.,.7+7+7+e+[ e+l+t.e+ +#+H.N.N.C.,.,.Y.,.w+m 7+7+l+w+U G+< ^ > 0+D+&+&+> j+) `.! - C.U w+#+Q.I.x+l. . . . . .K.K.K. . . .: g+U.t.H p.p.p.N.B B B 4+B B B N.N.N.#+H p.p.B o+4.u -.-.o+B *./+#+S._ e+v 0 a 5 n.~ ; W =+W ; z.t.y+v 3 K l l 4+;+7.4+p.o.<+l m+l.m+ .L j.w.Q.n+}+X.P.e.6+e o.Q.t.t. + +1+1+n+N.X.X.m.", "u 1.1.u 1.1.u 1.u u 1.u 1.u u 1.u u u u 1.1.-.u 1.1.1.1.1.1.1.u 1.1.1.1.1.1.-.-.-.{ -.-.-.-.-.-.-.{ 4.q+q+-.-.-.-.-.-.-.q+4.4.{ 4.q+4.4.4.4.) 4.q+4.4.4.4.4.-.4.`.) ) `.`.4.) &.&.`.`.4.q+q+`.&.&.9 i+i+o+k+4+G.k+C+A+2.J.C+H 2.C+++)+J.u.f+9 i+8.++G.8.)+2.i G.b+C+#.! )+B.C+B.r+r+r+++A+3+b+< D D n A+8._.3+3+8.< < A+< A+A+A+_.A+3+8.3+< < 5.( 4.-.1.-.1.1.-.q+1.-.) 8.r+A+7.A+7.7._.A+A+_._._._._._._.G #.G ]+o o ]+]+]+@._.< _.! o F i ! ! G+E+G &.-.u u 9.9.9.9.9.9.9.9.z $.L K j.3.F R.M.3.4 R.M.s.- C.R w S.b & 6+6+6+C 6 u.n X L.}+a+a+3.a+a+f }+}+}+}+}+a+3.H+3.3.3.3.3.R.! o F E.a.E.5.< j+=+j+c j+c j+]+S.! 3+7.R C.C.X s.3.G 5.E z u.E.F R.J J L.M.3.@.W < b #+'+3.3.f ]+< P.L.H * L.g g Y.Y.,.,.,.,.Y.,.p.,.Y.,.g Y.Y.Y.g C.,.,.,.,.,.,.,.7+7+/+e+7+e+e+e+e+e+e+e+e+7+7+7+w+7+7+7+e+e+j j @.^ 6+0+&+T.D+D+r z E.R l+e+y+[ e+[ .[.7 7 7 l.l.: l.: . . .K. . . .y+Y.N.H N.'+B 4+4+4+B 4+B 4+B B N.N.B B B B X.X.i.++C+P.#+m.H.a+X _ j _ 5 ^ ~ ^ ^ ~ ~ ; =+j+W z+0 y+U.{.3 ;+8 !.!.u { z D k+H.Q.Q.o.O j.t.[+G+G ]+P.[+Q.5+Q.t.[+y.p.[+p.[+ +t.[+m.", "u u 1.u u 1.u u u 9.u 9.u u u u u u u u 1.u u -.-.-.-.-.1.1.1.u 1.1.1.u 1.1.-.1.-.-.-.-.1.1.1.-.-.4.{ -.-.-.-.4.{ q+q+{ q+4.4.4.4.4.-.q+4.4.) 4.4.4.4.4.4.) 4.4.) ) 4.) ) ) `.9 -+4.4.q+{ q+-+-+`.&.f+D o+b+C+>.>+.+C+C+B.N.h+r+^.i f+f+9 f+o+o+D 8..+N.4+4+^.2.a+.+^.)+B.2.i.)+B.#._.++b+*+5.*+u.f+9 z f+D W A+A+A+< < < 8.8.3+A+A+3+_.A+3+< 5.&.-.{ -.4.9 (+W W {+-.1.4.G r+A+A+3+A+_.7.A+A+A+A+_._._._._._._.G G G G ]+]+G < F ]+o 3+F ! ! ! ]+G+G+G n 3+n 5.( ( i+f+z &.z X.j.3 v - i o 3.M.8+F 3.X s.#+L.C.J k k E+E+5 @.]+G G 3.- M.3.a+a+S.a+a+a+@.@.a+S.S.S.a+@.a+a+S.3.3.3.3.! ]+_.E.E.( c c c c c j+W (.H+3.a+! _.3+E+k L.s.3.n 1.9.9.9.{ z n 3.j ,.9+s.a+@.G (+5 k E+'+3.E+S.< ]+9+h+H H h+g g Y.Y.,.,.m m ,.,.Y.p.,.,.,.C.g Y.Y.Y.p.,.,.C.,.,.w+w+/+w+7+7+7+7+7+7+7+7+7+7+F+7+7+7+F+l+P e+l+j _ ^ T > > > & G+n o '.w+P [ [ v [ .7 q Q 0.0.Q Q q d |.l. . .: l. .L l+'+N.N.'+4+4+4+4+4+4+4+4+4+4+4+B B B X.X.B B X.B .+N.N.N.a+.+s.#+R R c+c+(.~ ^ ~ n.~ ; c ( c z.[ <+3 <+..8 !.9.9.9.9.9.u { >+k+b I.D.0 R a+B.G )+H+n+*.M [+p.p.p.N.p.N.N.z+N.m.", "-.1.u 1.u u u u u u u u u u 9.u u 1.!.u u u 1.1.1.1.1.1.1.1.u 1.u 1.1.1.1.-.-.-.q+4.-.-.-.-.-.1.-.q+1.1.-.-.4.-.q+4.{ q+4.4.4.4.4.) 4.q+) 4.q+) 4.4.4.) 4.) ) ) ) ) ) ) `.) 4.q+) q+4.{ 4.4.4.`.`.`.9 i+D o+o+z 9 (+o+D i.H * 4+H '+J.b+(+k+C+b+8.B.B.^.'+2.2.}+a+R.a+R.R.S.^.2.2.i #.3+*+G.o+o+o+f+u.9 9 z f+8._.< A+< < < 3+< 8.< A+< A+A+< < z 4.-.-+W 2 T T T n.&.{ -.(+]+_.A+_.A+A+_._._._._.A+++_._._._._._._._._.o ]+< n ]+o _.3+o o ! ! ]+]+6 G _.o ! R.E+t.o.}. +4+@._ j.$+w.8+F R.R.R.! i 4 a+X 3.f s.g k J _ k k k X X - C.Y.h+'+3.a+S.a+@.S.a+a+S.a+@.@.@.a+S.S.S.S.S.! 3.3.3.o W ( ) `.{+{+Z.c c W 2 w 3.R.S.! 7.n 3.X M.E+_.-+9.9.9.9.9.>.o l+w+L.X s.f 1 < D R L.H s.a+3.H+8.k+p.h+* '+H Y.g V ,.Y.,.Y.,.,.,.h+g Y.,.Y.Y.H L.,.g ,.,.C.,.,.,.,.,.,.,.w+,.7+,.m ,.7+7+7+7+7+7+F+e+[ [ [ 0 j '.0 $.z.f ]+G+3.E+- w+7+7+P e+e+v <+@ ] d q Q 0.. . 0.q 7 l. .m+[.l.U.l+q.q.B '+B 4+4+4+4+q.4+4+4+4+4+4+4+B B B X.4+X.B B B 4+}+B 4+H.w X X 5 (.6 ; ; 6 ; ; ; c {+`.( Z ,+y+e+..A 8 !.!.9.!.u ) D 6 b y.Q.O O t.y.H.P.E+#+b n+M p.y.y.p.n+n+N.z+N.N.b ", "u !.u u u u u u u u 9.u 9.u u u 9.1.u u u 1.1.1.-.-.-.-.1.1.u 1.1.1.1.-.1.1.-.-.-.4.q+-.-.-.-.-.1.-.-.-.-.-.q+{ -.q+-.{ 4.) 4.4.) ) 4.-+`.) 4.) ) 4.q+q+4.q+4.) ) `.`.) `.`.4.4.4.4.q+4.`.) 4.) `.`.9 9 9 9 >+k+*+f+o+D k+B '+h+L.H q.G.(+H.'+'+^.C+b+k+a+'+'+'+^.^.a+4+R.a+4+! ! )+C+A+G.G.J._.k+B._.n ( u.z z 8._.A+A+3+8.A+< A+3+8.3+8.A+3+< 5.&.4.-+W 5 T a 2 ~ {+{ 4.< o _.3+_.A+A+A+A+_.A+C+_.++_._.#._.r+_.G _.G ]+< n < ! G n F o o o W c.i+c c 5.( ( 3+s.L m+m+ .3 L j.d+[ 3.F o ! R.R.R.o _.F G S.3.@.}+3.'+E+X X - R k C.C.- X s.}+}+}+a+a+3.a+@.a+S.a+@.a+S..+S.S.@.3.! S.! 3.! o 9 u 9.9.9.9.9.&.~ *.k k 3.3.3.]+*+o - a+f c+8.i+`.q+-.z 3+3.C.L.L.#+#+- b j+5.z.- s.H s.a+f H+_._.n+H H * H H h+g g Y.,.V Y.Y.g * Y.,.,.Y.g Y.p.,.,.,.,.w+w+,.,.,.,.w+,.,.,.,.,.,.m ,.,.7+e+e+7+,+#+! o r+o ]+! f z._ _ _ J /+w+,.m w+7+7+e+e+d+3 j.t.0 K.[.] B+d q .3 L l l.l.3 e+B q.B 4+B 4+q.4+4+q.q.4+4+4+4+4+4+4+4+4+4+B B X.B B B 4+B B H.N.H.}+f P.c+6 ; 6 W W W c 5.9 5.D ++2.:.= A A 8 8 !.8 8 { 9 j+6 P.1+I.O w.I.$. +*. +*.y.y.p.p.p.p.N.n+p.!+p.n+p.", "u 1.9.u u u u u u u u 9.u u u u 1.u 1.u 1.u u 1.1.1.u 1.1.1.u 1.1.1.-.1.1.-.-.-.-.-.4.-.-.1.u u -.-.-.-.-.q+{ q+4.{ -.q+4.4.q+4.4.) ) ) 4.4.) 4.) 4.{ q+4.4.) 4.) ) `.`.`.-+4.4.4.`.`.`.&.`.) ) `.`.q+-.) D X.N.q.A+o+D i.H '+4+q.H *+i.J.B.H '+'+'+2.J.X.^.C+4+B.a+}+a+4+a+R.^.^.2.#.7.n G._.b z+z+b X.(+f+f+u.( < _._.8.A+3+A+A+A+3+A+3+A+_.A+< 5.9 z z ( 5.D 5.( z -+9 8._.A+A+8.A+A+_._.7._.7.++_.C+k+_._.k+#._._.G _.n < o G F n #.o _.i+-.9.u 1.q+u u 1.4._.o.l F.m+m+K $+d+- F 4 8+3.R.! ! o _.5.n < 8.B.! S.}+a+R.a+a+a+f M.'+s.s.s.M.}+}+E+'+}+}+a+}+a+S.a+S.a+a+S.S.S.3.@.S.@.3.@.3.]+< ( -+u 9.9.{ c+*.R ,+#+M.X i 3+S.M.f H+]+6 G G W G 1 z+C.- H s.s.X R z.5.j+X C.L.L.Y.L.'+f @.k+8.H.H '+* H * H Y.g Y.,.Y.Y.g * h+g ,.Y.,.,.p.,.,.,.,.7+m 7+7+7+7+,.,.,.Y.,.Y.g Y.,.w+/+s.! #.i r+o ! 3.E+E+E+f ! ]+o ! f X w+l+e+7+7+7+l+7+e+v s.N x.-+i+k+5 w.].[ J U 0 3 y+e+e+p.H B N.q.4+4+4+q.4+4+q.q.4+4+4+4+4+B B 4+X.B B B 4+.+B B B 4+B B B H+}+P.1 c+6 ; W W < < W G+H+B #+r+N s+A A x.{ !.9.9.{ f+8.1 a & I.<.I.o.I.I.Q.5+ + +y.p.n+p.p.N.N.p.z+n+z+", "1.-.1.1.u u u u u u u u 9.u u u u u u u u u u u u 1.u 1.1.1.1.1.1.u 1.-.-.-.-.-.-.-.-.4.-.-.-.-.-.-.-.1.1.-.q+-.-.u 1.-.4.4.4.4.4.q+-+`.`.) `.q+4.) 4.4.4.4.) ) q+) `.`.`.4.4.) `.) ) ) &.`.`.`.) -+4.`.i+8.X.N.'+7.o+D 1 L.L.* H L.'+B C+A+.+'+H * q.C+a+i J..+C+}+'+'+a+^.R.4+a+2.++B.i J.A+B.)+X.Z ++o+f+f+z ( < < A+A+A+8.A+_._._.8._.< _._._._.< < 5.5.>+( ( ( 5.5.< ++++A+3+A+A+A+A+_.++_._.++_.++_.B.#.#.#.#.#._.< n _.o _.3+_.o o n 1.9.9.9.u 1.u 9.9.9.4.1 j.K {.F.K v j ! F ! 3.R.R.! R.]+W ( {+{+{+9 D D 8.Z a+a+a+a+a+S.3.a+}+}+}+3.a+}+}+f '+f H+}+H+a+a+}+f }+a+3.3.3.3.3.f H+z.$.& & T 1 W D ++z.$.k R w s.E+3+i 3.3.G+G W 6 G 6 6 1 e.Q.C.H s.'+'+M.X 6 ( 6 X L.L.L.L.L.L.#+'+S.6 8.G+m.g h+* h+* H g g p.Y.g * H * g L.h+Y.Y.Y.,.,.,.,.,.,.7+,.7+7+7+,.,.,.,.Y.g p.w+'+4 r+! S.3.f f s.s.f E+E+E+E+E+f M.R.8+R.R.s.C.w+l+e+e+e+0 y.i.G.z { 8 x.#.f 3.M.U e+e+e+e+p.p.N.'+B q.4+X.q.)+X.4+X.4+X.4+B 4+B B B 4+B .+B B 4+B B B B B B B P.B P.@.1 1 1 c+c+(.c+@.P.H.w N.4+*+p+= x.x.A 9.9.9.u `.D 6 !+*.& I.O O s o.I.Q.t.[+[+p.p.p.p.p.N.p.!+H p.", "-.-.1.1.u u u 9.u u u u 9.u u 9.u u u u u u 1.1.1.1.1.u 1.1.!.1.u u 1.-.-.-.-.-.-.-.-.-.q+-.-.-.1.-.1.-.-.q+{ -.-.-.) 4.4.) 4.) ) 4.) ) ) `.4.) ) ) ) 4.q+4.q+4.) `.) ) ) -+4.4.) ) ) &.&.`.`.`.`.`.&.9 D 8.A+7.G.D o+>+H.h+L.g h+* 4+4+L.q.B.4+'+B ^.H '+'+E+'+s.'+'+'+'+a+a+a+^.a+q.2.B.r+r+i i ++A+b+n :+:+>+n A+_._._._.A+_.A+A+A+A+A+++A+A+i r+#._.#.++A+A+A+A+A+A+A+A+3+8.A+_.A+A+A+A+A+A+A+++++_.++#.#.#.G #.G _.< _.o o 3+F o o S.(+u 9.1.c _+^+~ c u 9.9.`.0 ' K K p [ X F _.8+3.3.3.3.3.G+< &.{+{+c ; ; 8.o+{+D H+* R.R.a+a+a+a+'+a+}+a+a+a+}+}+'+a+S.}+s.}+}+#+M.E+E+E+'+f f f f _ w.D.> |+W.|+O Q.P.n+_ s.s.E+o 3+! E+i.>+-+) &.i+c j+1 & I.,.L.s.}+E+w 5 j+5.P.X h+s.s.#+L.#+L.#+M.f Z (+6 p.p.Y.L.Y.p.Y.Y.g Y.Y.h+* h+* * h+L.Y.Y.L.Y.Y.,.,.,.,.7+,.,.7+7+,.,.,.,.,.,.J ! ! s.X s.s.M.}+Z G G G 1 X b X X w #+L.L.Y.s.* '+a+a+M.,.0 }.+.5+ +*.1 _.i o 4 f.C.e+e+l+7+p.p.N.B 4+4+4+4+4+4+q.q.4+4+4+B 4+X.B B B B B B B B B 4+4+B 4+B B N.N.B H.H.H.P.H+P.P.H+P.B B N.N.N.B C+J.*+:+u.E { !.9.8 z D k+P.e.I.}.w.o.O s }.0 t.t. +p.p.p.!+p.p.N.p.p.n+", "9.u 1.1.u u u 9.u 9.9.9.u u 1.u u u u u u u u u u u u u u 1.1.1.-.1.1.1.-.1.-.-.-.-.q+-.-.-.-.-.-.-.-.{ 4.q+-.-.-.-.4.) 4.4.) 4.) ) 4.-+`.&.`.`.) q+4.q+4.{ 4.4.4.`.) ) `.`.&.`.-+) ) &.&.&.&.&.&.&.&.>+(+b+b+o+o+(+G.>+)+'+Y.H g '+'+'+H '+r+J.G.)+a+2.)+'+'+'+H H '+a+4+'+R.a+^.a+a+R.4+^.B.++r+r+i 7.A+b+J.8.++C+_.i _._._._._._.i _.A+A+_._._.++_.++#.#.#.#._.#.r+_._._.A+A+3+_.A+A+A+A+_.++A+A+++++_.++_._.r+_._.n n G _.F < o o ! 3.W &.q+%+> S S > r {+9.9.1.X d+' p $+U o F o 3.R.! S.! M.E+_.i+=+;.C > > <.^ 9 q+c k s.R.R.a+a+a+a+a+a+3.a+a+a+3.S.S.a+S.E+E+'+s.}+'+s.w w w w #+R $.w.6+6+S K.S ].o.q.a+m.s.X H+< 3+3.s.]+( { 9.9.9.9.1.8.w.I.l+C.L.'+M.w ]+5.W f X L.H s.H h+H s.H #+}+f ]+(+W N.L.L.g Y.g ,.Y.,.p.Y.g p.h+Y.h+L.h+h+h+h+h+L.p.Y.,.,.,.,.m 7+,.,.,.,.p.,.X o 3._ J C.9+! ( q+u 9.9.u 4.W f s.#+X - C.,.,+Y.Y.Y.#+L.9+t.I.s I.Q.5+I.y.i F i 8+X 7+e+t.p.p.H B B B 4+4+4+X.4+4+X.q.4+4+4+4+B B 4+B B B 4+B .+B B 4+B B B B B N.B B B H.H.B H.N.H.N.H.H.N.N.N.B )+C+++J.J.G.o+u.`.E f+b+i.B y.& I.w.s w.s I.}.l+t.[+p.p.p.H p.p.n+n+n+p.", "1.u u 1.1.u 9.u 9.u u 1.u u u u u u u u u u u u u -.u u u 1.u 1.1.1.1.-.1.-.-.-.4.{ -.-.-.-.-.-.-.-.-.q+q+4.q+4.-.-.4.) 4.4.) ) ) `.`.) ) 4.`.-+4.{ 4.4.1.-.q+4.) ) `.) `.`.-+`.&.`.`.`.&.&.&.9 &.9 9 9 f+o+f+f+D 8.J.D X.4+'+4+q.;+D H.* '+7.C+i.J.^.J.b+H.* R.'+* '+2.G.B.4+R.R.R.4+a+^.R.^.2.)+)+)+)+B.o C+A+r+_.C+_.r+_.i i i _._._.r+_._.++_.++A+_.++_.++_.r+_._._.++A+_._._.A+A+_.A+++A+A+8.A+A+A+A+A+A+_.G _.< n 3+o _.3+3+o o ! 3.]+< z i+h.<.C r ; ) 9.9.E b P F+v [ f F F 3.` ! S.3.S.S.H+o 8.^+> 0+0+0+0+> ; &.z E+C.a+a+a+a+3.a+a+a+a+a+a+a+@.a+a+H+}+a+a+f }+a+H.s.#+#+#+R 9+'.0 $.a & <.|+|+].x+0 - X s.X ]+3+]+s.s.b P.++D &.4.!.8 D s /+,+C.s.s.s.X W (+]+#+h+s.s.H L.h+H L.#+'+w '+H+1 8.8.B p.H g p.Y.g ,.V ,.,.Y.p.g Y.h+h+h+H H h+H * L.H Y.Y.Y.p.,.,.,.,.,.,.U 3._.X '.e+j - n z ( W ^+^ ; -+u `.G+L.Y.L.9+,.,.l+7+l+l+R i.6 P.a 1+5+5+Q.Q.M.` * L.Y.w+e+,.,.p.H N.B 4+4+4+4+4+4+4+4+X.4+4+B 4+B B B B B B B B B B 4+B 4+4+B 4+B B N.N.P.N.H.N.N.N.b b b N.N.N.N.N.B B X.X.i.C+C+++++8.C+i..+P.*.Q.& I.I.I.I.}.0 5+t.t.[+p.p.p.p.N.p.n+p.n+", "u 1.1.u u u u 1.u u 9.u 9.9.9.u 9.u u u u u u u u 1.u u 1.1.1.1.1.1.u 1.1.-.-.-.q+-.-.-.-.-.-.1.-.-.-.-.-.{ -.4.-.4.) ) 4.) -+) ) ) 4.4.) 4.) 4.) q+4.4.4.-.4.) ) 4.`.4.) &.`.&.&.`.&.`.`.-+4.`.&.9 f+D o+z `.&.D X.J.D H+'+r+^.^.G.b+H+2.4+2.A+)+}+H :.D P.L.h+H '+'+J.b+}+a+4+a+R.4+^.a+R.a+^.r+C+)+^.)+o B.#.B.r+r+r+r+r+r+_.i r+r+r+r+r+r+r+_.C+A+A+_.A+_._.++C+_.i _.i C+_.C+_.8.8.3+++_._._._._._._.8._._._.< n n _.F 3+n F o o o ]+G+6 < < G 5 5 ; 5.4.1.) A+X - J '.- o F o 3.! ! ! ! S.3.E+3.i.1 r <.> > > r W {+D H+- M.a+'+a+a+S.a+a+a+a+a+a+a+a+3.a+3.a+a+3.}+a+}+'+s.E+s.#+R $.Q.z.5 z.C O O x+ . .o.9+R X ]+i f E+X +O O <.5+!+6 ++P.I.Q.,+L.s.#+w 5 n < 5 - L.L.L.L.H L.h+h+H #+#+s.}+i.W D D P.p.g g p.Y.,.Y.,.,.g Y.Y.Y.p.h+h+'+'+'+'+'+'+'+H h+L.g ,.p.,.L.Y.C.k o _.k 0 [ e+k A+W T S 0+T.0+> i+u z X w+Y.Y.C.Y.,.l+7+e+H+{ 9.u -.&.c.8.X.5+I.l+w+7+e+e+l+/+p.p.H N.B 4+4+4+4+q.4+4+4+B 4+B B B B B B B B B B B B B B B B B B 4+B B B N.B B N.N.H.N.N.N.N.N.b B N.N.N.N.N.B !+.+4+.+X.X.B B N.H.z+[+ +5+Q.I.I.o.}.0 t.t./+[+p.!+p.p.p.n+p.y.", "u u 1.1.1.u u 1.9.u u 9.u u 9.u u 9.u 9.u u u u u u u 1.-.-.-.1.1.1.1.-.-.1.-.-.-.4.-.-.-.4.-.-.u -.4.{ q+-.q+-.4.q+4.4.4.4.&.`.-+) -+) 4.4.4.4.4.-.{ q+4.) { 4.`.) 4.) `.) `.`.&.) ) 4.) &.`.&.9 i+c.8.o+`.&.&.&.9 9 ++4+H H 4+B 2.b+H.h+'+i G.++B h+2.G.@.'+L.q.2.B.b+]+'+'+^.^.)+2.C+)+.+R.2.B._.! ^.o 2.B.r+B.#.#.r+r+#.#.o #.#.o )+! ! ! )+o r+r+_.++#.r+r+r+_.r+_.++++_.++3+D :+f+( o+A+_.C+++++++_._._._._.n 5.< _._.3+n n A+G G o G ]+c+G+@.E+E+]+8.n n _.a+}+s.- X 3.i o ! ! 3.! ! ! ! @.3.H.f H+H+5 5 ^ 1 G W 8.G f s.a+a+a+a+a+a+a+a+}+a+a+a+a+a+a+S.a+a+a+S.S.3.a+}+}+'+w R n+_ b 1 1 2 b 2 e.o.l .y+U k f #.! X #+9+Q.D.S K.|+|+> }.$.9+/+C.H '+M.X 6 5.G E+s.L.L.L.L.Y.Y.Y.L.L.L.s.#+'+n E -.{ 9 J.4+'+Y.Y.,.g ,.g Y.g h+h+h+H h+H B 4+B B 4+B '+'+* p.g g L.h+L.k - _.o _ [ d+[ J R._.r S T.D+D+0+C u.u.}+l+7+w+,.,.,.C.,+t..+{ 9.9.9.9.9.9.u D y.d+d+d+e+e+7+p.p.H '+B 4+4+4+4+4+4+4+B 4+4+4+4+B B B B N.B B B B B B B .+4+B 4+B B N.B B H.B N.B B N.!+N.N.!+N.N.N.N.N.N.N.N.N.B N.N.B B B B B N.N.N.n+*. +Q.0 I.o.}.}.t.t.t. +p.[+p.p.n+p.y.m.", "u u 1.-.!.u u u 9.9.u 9.u u 9.u 1.1.1.u !.u u u 1.u u 1.q+1.u 1.1.1.1.1.1.-.1.u -.{ q+-.-.4.-.-.u -.4.-.-.{ 4.q+{ -.q+4.4.4.4.4.4.) ) ) ) ) 4.q+4.q+{ q+-.4.q+4.) &.`.`.&.&.`.-+&.&.&.4.) &.&.9 i+f+f+f+9 z 9 f+9 f+9 6 .+q.)+H L.'+J.8.4+4+7.o+8.w H ^.b+w L.* 4+'+r+)+}+'+'+R.4+^.R.2.J.i.a+R.q.q.^.^.)+2.o r+2.o B.o o o 2.)+! i.#._.k+k+B.i.)+]+)+o B.#.#.#.#.r+#.r+r+_.r+A+o+9 z z z z o+C+#.B.r+++_._._._.< n n 3+_._._.3+3+n < W G G G 6 ]+G+G+G+]+Z Z i.! ^.3.3.3.3._.4 ! R.! ! ! ^..+! G+S.}+E+E+5 w E+1 @.]+G ]+! S.a+R.! a+S.a+S.@.a+}+}+a+}+}+a+a+a+a+a+a+a+S.a+a+a+}+}+3.E+b G &.9 W c+8.z i+e.].D.j /+k ! o f k k w+I.D.|+|+x+L ].x+'.9+[+- s.s.E+5 (+5.c+s.M.H h+L.L.Y.Y.L.Y.L.C.L.9+9+^.:+E A 8 8 x.:+q.p.Y.Y.Y.Y.g p.h+h+H h+N.B.b+>+>+D ++)+B '+'+H L.Y.p.g L.9+f _.! _ e+7+e+J - _.< ~ C 6+> C ^ 3+A+X l+7+7+7+7+/+l+l+l+t.P.D ) 1.9.9.9.!.u.H.e+e+d+e+e+7+p.H H B B q.4+q.q.4+4+4+4+4+B 4+B B B B B B N.N.B B B B B B B B B B B B B B B B B B N.B N.N.N.N.N.N.N.N.N.N.N.N.!+N.N.N.N.N.B N.H.N.N.N.z+n+*. +Q.}.o.}.y+}.e+t.t.t.p.[+p.*.p.M p.", "u u 1.u 1.9.u u u u 9.u 9.u u 1.1.1.1.1.9.u u u u u u u u 1.1.u 1.1.-.-.-.1.-.1.-.-.-.1.-.-.-.1.1.-.-.4.q+4.q+{ q+q+{ q+4.) 4.q+4.4.4.4.4.4.q+4.4.4.-.4.q+q+q+-.) &.9 9 &.&.&.`.&.-+&.&.&.9 9 >+f+i+D k+++B.C+i.;+>+i+f+D >+f+D N.L.;+b+.+'+q.G.o+D G.G.b+.+h+h+2.4+B.a+'+'+a+'+R.R.q.2.7.! R.a+R.R.! ^.)+^.2.o 2.2.o 2.B.! .+^.B.3+b+G.G.*+D < ++! ^.S.R.2.2.2.B.o B.B.#.B.++n *+u.u.z z E f+++B.#._.++A+_._.< n n 3+3+F 3+3+W 5.5.( 9 {+) ) {+c.G Z ]+#.#.B.]+o ! S.3.3.o 4 o R.! R.! ! ! ! ! ! G+S.3.H+H+f f f @.3.@.S.S.S.! R.a+^.a+a+a+4+@.@.a+a+a+3.}+a+a+S.S.a+@.a+^.S.a+a+a+B f E+>+!.9.{ &.`.9.9.8.x+0 '.'.f f.! #+k ,+0 o.o.O D.D.x+x+L y+l+9+L.s.E+X ]+5.< S.s.s.'+L.* L.L.L.Y.p.L.Y.C.,.Q.& a P.i.8.*+p+;+4+Y.g ,.Y.Y.g g h+h+h+4+n -.u 9.9.9.9.q+f+)+H H L.L.Y.C.Y.- ! o E+U l+P l+j k 3.< 5.c j+W _.o ! '+C.7+e+7+7+7+7+l+e+[ I. +a !+n.k+j+D D i.z+l+e+e+e+,.,.Y.H '+B 4+4+q.X.4+q.4+q.4+4+B B q.B B N.B B N.N.N.B N.N.B B B .+B B .+B B B P.B B B B N.B N.N.N.H !+N.p.!+N.!+p.N.N.N.!+N.N.N.H.N.B N.N.N.n+p. +Q.o.y+s y+}.y+}.e+}.t.t.[+ +p.[+y.", "u u u 1.1.u u u u u u u u u u 1.1.1.1.1.u u u u u u u u u 1.1.1.-.u u 1.-.-.1.1.1.1.1.1.-.-.-.-.1.-.-.4.-.4.q+-.{ q+{ q+-.4.4.q+4.4.4.) { q+q+4.4.4.q+{ 4.4.q+-.) 9 9 9 z &.&.`.&.&.&.&.9 9 >+f+i+D o+D k+N.a+4+2.7.D D D D 8.i.H Y.q.J.G.b+B.J.D o+>+D 8.H.h+* H q.2.H a+'+4+'+'+a+a+q.q.)+R.a+a+R.R.R.^.^.)+^.^.^.)+)+2.2.S.S._.n J.G.n *+:+o+G._.a+H+a+^.o 2.2.o 2.2.B.B.++G.G.o+u.u.z z u.#.B.#.i ++A+_.A+< n n F 3+A+7.A+< i+) q+q+1.u 9.9.9.-.9 G ]+i.o i.i.o ! ! o o o 8+R.! R.! R.G+.+G+G+G+G+G+G+@.G+S.G+@.S.! ! ! S.S.R.a+a+a+! a+R.a+S.a+a+a+a+a+3.a+a+S.a+! a+^.S.S.}+}+}+H+1 < E { ~.8 !.9.9.9 Q.J k k ! i 3.X X ,+0 w.& & & +.I.w.j.x+y+w+L.H w b W < G f M.s.'+H h+H L.L.L.L.L.L.C.,+t.Q.5+5+5+5+5+*.p.p.,.Y.,.,.Y.Y.Y.Y.g p.r+= 1.) c ; ~ c ) u { ++H Y.L.L.9+9+M.o o - l+7+7+w+3._._.W n 5.5.< o 3.X ,+l+7+7+7+w+7+w+w+/+e+I.$.M a a !+a 5+5+Q.e+e+e+e+e+7+,.p.* '+q.q.4+q.q.q.q.q.4+4+q.4+4+B B B B B B B B N.X.N.B B B B B B B .+.+X.4+B B B B 4+N.B N.N.N.N.N.N.N.p.N.N.p.p.!+p.N.p.N.N.!+B N.N.N.N.z+p.p.5+}.y+g.g.g.<+g.y+y+}.e+}.t.t.t./+", "u u 1.u 1.1.u u u 9.u u u u u u u u 1.u u u 9.u 9.u u u 1.u 1.1.1.1.1.1.u 1.-.-.-.-.!.1.1.-.-.-.4.-.-.-.4.-.-.4.q+4.q+{ q+4.-.{ 4.4.) 4.4.4.-.{ 4.4.q+q+{ 4.{ 4.4.`.&.9 &.z &.&.`.&.z 9 z i+D >+D D f+>+6 o 4+^.)+B.*+D k+@.^.H H '+h+B 4+^.4+i f+D A+b+i.L.g '+2.^.'+'+'+q.'+'+* '+'+a+R.q.^.R.R.a+a+R.a+a+R.R.R.^.^.R.R.a+}+)+#.J.J.;+J.J.n ;+n ++a+s.a+R.^.2.o 2.2.B.2.r+r+i ++++G.f+f+u.( k+B.i _.7._.A+3+n 5.n _.A+7.7._.< &.1.u -.) q+9.9.9.9.9.`.Z ^.^.! 2.! 3.! o i R.3.3.R.^.a+G+#.8.D i+{+i+D W G G+G+S.! ! S.S.S.a+! a+S.a+a+a+a+@.S.a+a+a+R.R.a+a+S.S.a+! S..+S.! ^..+S.@.G+6 W (+n D f+E 1.{ b+$.k k f o o E+#+#+_ *.z.b z.z.b 5 n+I.L y+l+C.- k 1 < < ]+}+'+'+H '+H L.'+h+h+H L.L.L.,+[+y.*.e. +5+Q.o.}.e+7+,.,.,.,.,.p.g g Y.o E.( _+> 0+0+0+C ( 8 E .+p.Y.L.Y.k 3.F ! k 7+7+7+l+i = A 8 -+9 5.< o #+w+w+w+w+w+/+w+w+/+/+l+Q.t.*.n+n+!+H.P.N. +}.e+y+d+d+7+7+Y.H * B B 4+q.4+X.)+q.)+q.q.4+q.q.q.4+4+B B B B !+N.B .+!+B X.B .+4+B 4+4+4+.+.+.+B B B B N.N.N.N.N.N.N.N.N.p.N.N.p.N.p.N.z+N.N.B N.B B N.p.N.p.[+Q.I.e U.2+l U.2+K g.<+y+y+y+y+0 0 ", "1.1.1.u u u u 1.1.u u u u u u u u u u 9.u u 9.u 9.u u u -.-.-.1.1.-.u -.1.1.-.-.1.-.-.-.-.-.-.-.-.1.-.-.4.4.-.-.-.4.q+{ 4.4.q+q+4.4.4.q+{ q+q+q+4.{ -.q+q+4.) ) 4.`.`.9 &.9 `.&.`.9 9 D (+b+>+G.(+D f+f+8..+a+^.)+B.b+o+D 8.}+i w * 2.7.^.H '+i G.8.)+2.#+L.L.'+2.N.'+'+i C+'+'+L.H H '+R.R.R.R.^.'+a+a+a+a+a+R.R.R.R.^.R.a+}+^.B.i 7.J.A+7.J.J.:.#.4+s.}+R.! ^.2.2.! 2.2.2.B.2.)+)+C+G.:+f+G.B.B.i ++3+A+++A+3+n n 3+_._.4 _.(+&.-.q+Z.V.%+=+{+q+9.9.9.c f ^.! o ! ! o F o ! 3.a+R.R.^.! (+`.u 9.9.u ) {+9 5.; G+S.! ! ^.! a+a+a+S.a+a+a+a+a+R.a+R.a+a+S.a+R.a+^.a+R.! ^.! ]+#.o G W (+c 5.j+; 6 6 G i.P.y._ #+X ! i R.s.X X b A+< k+c+1 (+`.o+*.j.e+C.C.- X ]+< G f s.s.* h+h+H L.H L.L.H L.#+m.H.G+6 k+1 P.z+ +t.0 /+,.,.Y.,.,.,.,.,.C.Y.M.r+3+2 > 0+0+0+0+^ `.= _.C.g L.L.k ! i ! k w+P e+[ ,+#.o+u.u.u.E.E.4 s.l+7+,.7+,.,.C.C.C.C.C.Q.H.6 i.G+X.i.A+J.B.L.,+l+e+e+7+,.p.g '+q.B q.q.q.4+q.q.)+q.4+q.4+q.B 4+4+B B B 4+4+B B B B B B B B 4+B .+4+4+4+4+4+4+B B B B B B N.N.N.N.N.N.N.N.N.N.p.z+N.p.p.N.N.N.N.N.N.N.z+p.p.Q.s 2+K.r.g+l.g+r.r.r.| K g.<+<+y+", "1.1.1.1.u u -.1.1.u 1.1.u u u u u u u u u u u u u 9.u u -.4.-.-.-.-.-.1.-.1.1.1.-.-.-.-.-.-.-.-.-.-.-.4.4.q+4.4.q+{ q+q+q+-.4.q+4.4.q+{ q+4.4.4.4.-.1.4.{ 4.4.4.`.`.`.9 9 `.) `.&.&.i+(+b+G.8.++J.#.}+i o+(+B.J..+'+r+*+9 (+.+4+H Y.g H H H * H '+4+r+B.L.L.q.i N.h+L.2.o+8.w H '+'+h+}+a+R.'+a+R.a+'+'+a+'+a+a+a+a+R.a+a+R.a+}+4+o B.r+C+i C+r+#.^.}+a+a+4+q.2.)+^.2.)+2.r+C+i r+B.B.C+J.J.++B.i C+i i _.A+A+3+< n n 3+_.#._.< i+q+i+^+C <.<.T h u 9.9.&.5 R.o ! ]+o 4 F 8+` R.a+a+a+3.W i+1.u u -.`.c c {+) {+< ]+S.R.! a+R.R.! S.R.a+a+S.S.a+a+a+a+a+a+a+a+R.a+^.S.! o #.7._._.D 9 ) `.{+c.W W W ; 1 t.l+X X f f.o S.s.'+s.E+A+*+n i.B.-+9.9.6 Q.C.9+#+R E+W 8.! s.H s.H H H L.H L.L.L.L.H L.H+b+E 1.1.q+&.c.X. +t./+p.Y.p.Y.g p.Y.C.C.C.k X f E+2 r C C a ]+E.E.i.#+L.L.X - o #.3.g ,.7+7+e+o.0 _ b 2 z.H+.+a+H C.7+w+,.,.w+w+,.C.C.,+L.*+>.*+J.++J.f+E p+;+2.q.'+H Y.p.H * '+B q.4+X.q.q.q.q.X.q.q.4+4+4+q.4+4+4+4+4+4+B 4+B B 4+B B 4+4+4+4+4+B 4+4+B B B 4+B B B N.B B B B N.B B !+N.N.N.p.N.N.N.N.N.N.H.N.N.N.n+N.n+ +I.o.U.r.g+|.|.7 7 ] [.l.g+m+r.l U.", "u u u 1.-.1.u u u u u 1.1.u u u u 1.u u 1.-.u 9.9.u u u u -.{ -.-.-.-.-.-.u 1.1.1.1.1.-.-.-.1.-.4.-.q+4.{ -.q+{ q+-.{ 4.4.{ q+4.4.4.4.-.-.{ q+4.4.q+1.4.-.-.q+4.`.&.i+9 z &.`.`.9 z 9 D >+n ++++Z ^.++@.2.C+b+b+@.4+'+q.;+o+++w H L.h+'+L.L.g Y.* '+a+^.4+r+;+Z N.h+h+'+q.)+s.Y.s.s.H H '+a+R.'+'+'+a+'+'+` '+a+R.'+R.a+4+R.'+a+'+a+a+R.! ^.! ^.R.a+'+a+R.R.R.2.R.R.^.)+B.7.A+J.J.7.r+B.B.C+r+C+i C+++i i ++++A+3+< < n 3+#._.< (+9 9 j+_+2 r r =+-.9.9.9 1 R.! o o #.F _.R.3.R.3.a+3.a+_.{+-.{+=+~ r C 2 ; {+q+{+c ]+S.R.S.a+S.R.S.R.R.a+a+@.@.a+a+a+a+a+a+a+a+a+a+! #.7.3+7._.8.9 ) `.c W ^ ^ ; D &.i+E+U - f G i o 3.M.'+'+E+]+_.o i.B.E 9.!.D [+L.s.s.b ]+< _.@.M.'+'+L.h+L.L.L.h+H L.H #+#+b ++N 8 !.9.9.!.f+H.Q.p.Y.L.h+p.g Y.h+L.g L.C.J k k X w 3.H+! ! i o }+L.h+h+- E+o o f - C.,.l+l+t.Q.Q.I.I.s O s o.l+,.w+7+7+w+,.w+w+C.C.p.,+q.:.J.7.++*+s+8 A N Y :.:.4 f.q.q.q.q.B q.q.q.q.)+q.q.q.q.q.q.q.X.4+4+4+4+4+X.4+X.4+4+B B B B B B B 4+B B 4+4+4+4+B 4+B B B B B B B B B B B B N.B B N.N.N.N.N.z+N.N.N.!+N.N.n+p. +}.e K.: |.B+0.D+. 0.Q q q 7 |.[.l.", "u u u u 1.1.u u u u 1.u 1.u u u u u u u 1.u 9.u u 9.u u u u -.-.-.-.4.-.1.-.-.-.-.-.-.-.-.-.4.-.-.u 1.-.4.-.-.-.4.4.4.4.) ) { 4.q+q+4.4.q+q+-.4.4.4.q+-.-.q+4.4.`.9 >+>+&.i+( 9 9 9 (+k+C+b+8.k+)+)+G.i.B 2.i ++i.r+.+B C+( >+Z H L.q.4+'+N.Y.Y.Y.'+H 2.*+o+6 H L.Y.Y.h+7.C+#+L.L.h+h+'+a+'+'+'+'+'+'+* '+'+'+'+'+a+'+'+R.'+a+'+a+'+a+a+a+a+'+a+4+q.a+a+a+a+4+a+R.R.^.2.r+F J.J.;+J.i 2.B.B.C+++++A+++++++i 7.A+A+J.3+< < A+o G < 5.5.( ( D j+; c.{+1.) 8.]+! o ]+o _.4 3+o 3.a+a+a+f f W ( q+c r S S 0+S r c q+q+{+5.o ! R.R.R.a+R.a+a+a+^.a+a+a+S.S.S.a+'+a+* a+R.2.r+_.o ]+3._.( `.8.2 <.S > C j+) 4.8.R k 3._.F o 3.}+f H+G+G+G+o ! ]+D { x.8.#+#+w X f G 3+o 3.3.s.s.'+H h+Y.h+L.H s.#+#+C. +b k+c.f+&.{ x.:+X.l+p.p.* h+'+g h+H h+L.L.L.L.L.- X X X X E+M.E+s.L.g L.#+- R.o ! X L.C.C.C./+*.a a e.5+5+Q.Q.Q.0 w+,.,.p.w+w+,.C.C.L.Y.,+0 [+p.#+H ^.;+p+p+;+:.4 :.:.4 q.q.q.q.q.q.X.)+)+q.)+q.q.q.q.q.X.q.q.q.4+q.4+4+4+4+X.B 4+4+B B B 4+4+B 4+4+B B B B B B B B B B B B B B B B B B B B N.N.N.N.N.N.N.N.N.N.N.N.p.n+*.t.I.<+x g+k.0.0.. . . . . 0.0.0.0.q ", "u u 1.u 1.1.1.1.u u u 1.1.u u u u u u u u u u u u u u u u u 1.-.-.-.-.1.-.-.1.-.-.-.-.-.1.-.-.-.-.-.1.-.-.-.-.-.-.-.4.4.4.4.4.4.4.4.4.{ q+4.q+4.{ 4.-.-.{ -.q+) `.&.i+D f+>+>+D >+i+>+b+(+o+D X.H 4+7.^.2.4+4+)+4+^.^.^.^.J.f+8.s.'+H q.7.B L.g Y.H H ;+f+k+4+7.B Y.Y.q.a+L.L.L.L.h+L.L.* h+'+* '+q.H * H '+'+'+'+* '+'+'+'+'+'+a+'+'+'+'+a+'+a+a+'+R.'+` '+R.a+4+q.2.2.r+4 7.A+7.J.7.C+B.C+i 7.7.7.7.++++++i ++++3+3+3+< < A+G G < < D >+5.(+W 8.c i+(+G o o o ! o o i o o ! 3.3.a+a+E+]+< 5.j+n.r C C r h.=+{+{+{+5.G o R.! ! ! R.R.S.3.S.a+R.R.a+a+R.a+a+a+a+3.3.3.R.S.3.E+X ]+3+5.G+6+S 0+0+S ^ 9 x.< X R o _._.R.3.a+6 < D (+8.G G ]+G W C+.+s.H.M.w S._._.]+M.'+'+h+L.L.Y.C.L.h+H H H #+_ $.e.e.!+5 P.n.k+X.y./+p.Y.h+H h+h+h+H h+H h+h+h+#+#+#+X X X #+s.#+L.#+h+h+#+b ! o 3.X Y.9+,+m.S.k+k+6 1 5 5 z+*.[+/+w+,.,.,.p.,.,.C.Y.p.Y.L.,+/+w+p.w+t.y.H B '+H '+'+q.q.q.q.4+4+4+q.q.q.q.q.q.)+q.q.q.q.q.q.X.q.4+4+B 4+B 4+4+B B 4+4+B B B 4+B B 4+B 4+B B B B B B N.B B B B B B 4+B B B B B N.N.N.N.N.N.N.N.N.N.n+!+p. +Q.}.x+r.|.B+0.. . . . . . . . . . . ", "9.u u u 1.1.1.u u u u 1.u u u u u u u u u 9.u u u u 9.u 9.u u 1.1.1.1.-.1.-.-.-.1.1.1.1.-.1.-.-.-.1.-.1.1.-.-.-.-.-.-.q+4.4.) 4.4.4.4.q+-.{ -.4.q+4.4.4.4.-.4.&.&.`.`.D D A+o+f+o+b+++)+7.o+f+W )+B ^.)+@..+H '+'+H '+4+^.B.A+)+B H L.'+H L.Y.Y.g h+i D (+#+h+2.2.H L.L.L.Y.L.h+L.Y.L.L.g '+C+B h+h+H H * h+* h+h+'+'+* '+'+'+'+'+'+'+'+'+'+a+'+'+a+'+'+4+'+'+a+R.q.q.r+i ++:.J.J.J.J.B.r+7.++A+++7.++7.i i ++i ++++A+< 3+3+< A+_.G G 8.8.(+_.G G W _.G #.o )+! ! ! ! o o o o S.'+R.S.S.]+]+_.]+c+^ ^ 2 ^ (.W c 5.5.8.o ! R.! o o ! ! o ! ! ! S.a+S.a+@.a+S.a+a+a+3.f f E+f X f X ]+o 1 a T C C T c+5.( _.E+f _.3+o a+3.]+( ) `.>+8.G 6 G W _.G+N.s.M.E+E+o _.#.3.'+'+'+H L.Y.p.L.H H h+M.w #+R *.*.z.a !+a 5+}.}.0 w+g p.g h+h+h+h+H h+h+H H H s.s.s.s.s.s.s.#+H H L.s.#+X f o o a+#+9+C.9+#+A+>.{ -.q+&.c.k+1 p.C.p.Y.Y.Y.Y.Y.Y.g Y.L.L.Y.L.C.C.C.p.C.,+w+p.C.p.p.L.p.H B B q.4+q.4+X.B.)+q.)+q.q.X.q.q.4+q.q.4+q.4+4+4+4+B 4+4+4+4+B B B B B B B B B N.B B B B B B B B B B B B 4+B B B B N.N.B B N.N.N.N.N.N.p.N.z+p.*. +0 e U.g+|.&+t+. . . . . . . . . . . ", "9.u u u 1.1.u 1.u u 1.u u u u u u 9.u 9.u u 9.u u u 9.u u u u u 1.u u -.1.1.1.1.1.1.1.1.1.1.1.1.1.1.-.-.1.-.-.-.-.-.{ q+4.) ) 4.4.) ) `.`.-+4.4.4.4.) ) 4.4.`.&.&.`.-+9 G+^.7.D 6 J.b+8.++o+( 8.J.b+k+B '+s.H H '+L.h+h+2.2.)+a+a+a+H h+Y.Y.Y.p.H '+q.:.Z L.h+L.'+Y.Y.C.Y.h+'+h+L.g g Y.Y.'+2.^.H h+L.L.h+H h+h+H h+'+* h+* h+'+'+'+'+'+'+'+* '+'+'+'+'+'+` '+R.^.2.2.r+r+C+A+J.J.J.n ++r+i ++7._.i ++_.r+i i i i ++++A+3+8.3+_.A+A+_.8.G W k+k+#.#.#.#.i.o )+^.R.3.3.S.! o o S.3.f 3.3.S.3.G+! ]+@.G+G+G+]+G ; G G S.3.S.3.3.! o o ^.o o ! ! o 2.! R.! S.S.S.3.3.3.f E+f f E+f f b E+f b z.z.z.f G+G _.@.E+]+_._.]+M.a+A+>.4.9 G 2 a a n.D 9 D ]+w '+f G+_._.o M.M.'+'+H h+h+H L.'+'+H H s.#+z+E+5 P.5 P.1 b +o.y+,+Y.g p.h+h+H h+H L.h+L.h+h+h+h+h+H H h+h+s.H s.H H s.#+! _.o f X L.9+C.y.X.*+E A !.!.!.x.D 1 p.,.,.,.,.Y.Y.p.g Y.L.Y.L.g Y.Y.p.C.,.p.C.p.C.C.C.p.p.p.p.p.N.B 4+q.q.q.X.q.q.X.q.q.q.q.4+4+4+q.4+4+4+4+4+B 4+X.4+4+4+B B B B B B B B B B B B B B B B B 4+B B B B B B N.B N.N.N.N.N.N.N.z+N.N.n+N.p.p. +t.}.<+U.g+|.0.. . . . . . . . . . . . ", "u 9.u u u u u u 1.1.1.u u u u u u u 9.u 9.u u u 1.9.u 9.9.9.u u u 1.1.u 1.1.1.1.1.1.1.1.1.-.-.-.-.-.-.1.1.1.-.-.-.q+-.4.4.-+-+) ) `.-+&.&.&.`.4.4.) `.) -+) ) `.) `.&.(+P.N.B.u.(+G+)+7.++b+D H+J.o+++G+)+4+L.4+#+'+H h+q.A+C+C+B.C+)+N.H q.4+'+L.L.L.2.}+Y.Y.* H L.p.g Y.L.h+L.h+Y.Y.Y.L.L.L.h+H L.h+'+H h+h+H * H H h+h+H '+h+* h+* * * '+* '+'+'+'+'+'+'+'+'+2.2.2.^.2.B.++7.J.;+7.7.++i i 7.7.7.C+r+r+B.r+i i i ++i _.3+_.A+_.< 5.9 9 9 i+D 8._.#.o )+.+^.a+H+f E+s.E+f S.S.}+s.H E+3.f f 3.f f 3.@.G+1 c+G+1 @.@.3.3.3.a+3.S.S.! R.! o R.! ! R.! ! o ! ! ! ! S.S.3.H+3.3.3.f E+w b w f E+5 f @.3.f 5 3._.3+o R.M.f 3+>.z W C > S S T W 9 &.8.f s.3.o _._.! '+'+'+'+* '+'+H '+H s.'+'+s.w .+k+i.6 6 ++G.A+b 0 l+p.H h+H h+h+H L.L.h+L.h+L.L.H h+s.H H H H h+H H H M.s.f G _.Z }+s.L.L./+t.y.P.6 (+>+z N u.:.4+L.C.,.p.Y.Y.Y.Y.Y.C.g Y.Y.Y.Y.Y.g p.g Y.Y.p.Y.Y.C.C./+/+,.p.p.N.N.B 4+4+q.4+4+q.4+4+X.4+)+q.q.4+q.4+4+4+4+4+4+4+4+B B B B B '+B N.B B B B B B B B B B B B B B B B N.B B N.B B N.N.N.N.N.N.p.N.!+p.n+[+p.Q.o.g.r.g+B+&+. . . . . . . . . . . . ", "u 9.u u 1.1.u 1.1.1.1.u 9.u u u u u 9.u u u u u u u u u u 9.u u u 1.1.-.1.u 1.u u 1.1.-.u 1.u u 1.1.-.-.1.-.-.-.-.-.-.-.q+&.&.&.&.&.) 4.&.9 z -+) 4.`.) `.`.) `.&.&.&.9 D ]+2.u.9 D 8.B.7.++G.b+o+>+>+++G+w H '+4+}+H H q.G.X.2.G.D D k+^.4+L.L.Y.L.L.'+p.Y.Y.H '+L.Y.g Y.Y.g p.Y.g L.L.g H L.L.g 2.4+H L.g L.H h+h+h+h+L.L.h+L.h+h+h+H h+H * * * * '+* * '+'+'+4+2.2.)+^.2.^.B.i J.r+i B.B.o 2.o r+o B.r+B.r+r+r+i ++4 i _.++A+< i+4.1.u u u 1.q+9 D _.i.a+H+P.b b b b b b w E+w b X m.#+w w E+E+E+f f 3.f f 3.@.3.@.f H.}+! #.++A+_._.! ! 3.a+R.! R.! ! ! ! ! ]+]+o o ! ! S.@.@.f f E+E+f E+E+5 f 1 G+]+G _._.]+3.M.f #.n 5.n.6+0+0+0+6+~ 9 &.(+1 X G+A+3+#.3.3.'+'+'+'+'+'+* '+'+'+s.'+H s.^.r+C+++b+o+= = J.y.,+Y.H h+H H h+* L.H H h+h+h+H L.L.h+L.L.h+H h+L.'+H s.#+E+#._.]+f s.H #+/+Q. +y.a a !+!+1 1 4+#+p.C.C.,.,.,.,.,.,.p.C.,.Y.Y.Y.p.Y.p.Y.C.Y.Y.C.Y.C.w+w+e+t.l+/+p.p.p.B B 4+4+4+q.q.4+q.4+4+)+X.4+q.4+q.4+X.4+4+4+4+q.B B B N.B B N.B B '+B B B B B B B 4+N.B N.N.B N.N.N.N.N.N.N.N.N.N.N.N.!+p.p.p.y.[+t.Q.s U.r.|.B+0.. . . . . . . . . . . . ", "u u u u 1.1.u u 1.1.1.!.u 9.u u u u u 9.9.u 1.u u u u 9.9.9.u 1.1.u 1.u 1.1.1.1.1.u u u 1.1.1.1.1.1.-.-.-.1.4.-.-.-.q+q+-.) `.`.9 9 z 9 9 z `.4.4.`.) `.`.4.4.) &.&.9 9 9 D f+z &.9 D H+.+4+J.J.b+o+9 ( D i.a+'+q.r+.+'+i A+H+q.++G.o+b+i.H p.Y.p.g Y.'+g '+L.4+2.p.H Y.L.Y.Y.Y.Y.Y.Y.g Y.L.L.Y.* q.N.Y.g L.L.g L.L.L.L.h+h+L.h+* H L.* H * h+H h+H h+H '+a+^.R.q.)+^.^.)+^.2.^.2.B.2.^.R.R.^.)+^.2.B.r+r+r+2.r+C+i 7.C+C+i ++_.D ) 1.1.u u u u 9.u -+>+#.H+E+z+n+n+y.y.y.M z.R b R n+R m.R #+X #+X s.E+E+E+E+E+f E+f s.f X.< u.-+x.E E u.A+^.3.f 3.S.a+! ^.! ! o o ]+]+]+! ]+! ! ]+@.3.S.f S.]+]+]+o o o i _.r+R.a+}+S.G < _.6 ^ 2 r r r 6 c 9 < ]+s.G < 8.o R.'+a+'+'+'+'+'+'+'+'+'+'+}+}+}+a+.+Z A+;+b+p+a.;+N.p.H * H * H H h+* H H L.h+L.H h+h+L.L.L.L.L.L.L.L.L.h+X ! _._.! E+#+H X [+_ *.e.1+e.1+1+5+Q. +p.#+L.Y.p.p.,.,.,.,.7+w+,.p.,.,.,.,.C.,.Y.Y.,.Y.C.,./+e+e+y+y+}.e+/+p.p.p.N.B B 4+4+q.4+q.4+q.q.q.4+q.4+q.q.q.4+q.q.B q.B B '+H B B * B B B B N.B B B B N.B B B B N.N.N.N.H N.N.N.N.N.p.N.p.N.p.N.p.p. +t.}.y+U.g+g+&+Q . . . . . . . . . . . . ", "u u u u u 1.u u 1.u 1.1.u u u u 9.9.u 9.u u 9.u u 9.u u 9.9.u 1.u 1.1.1.1.1.1.1.1.1.u 1.1.1.u u 1.-.1.-.-.-.-.-.-.{ 4.4.4.&.i+D f+>+>+9 f+f+z -+4.4.) `.`.) -+) &.9 D o+9 (+D f+9 z &.D i.B ^.B.J.( >+9 9 (+^.C+@.a+B 4+4+4+H ^.^.^.A+)+4+^.H H H p.h+4+L.H h+h+Y.Y.Y.h+4+p.g p.Y.Y.Y.p.h+h+g p.g L.Y.Y.Y.g Y.L.* '+'+h+L.g L.L.g h+g L.L.L.h+L.h+h+h+h+4+R.^.^.R.2.2.2.)+2.2.)+^.2.2.4+a+a+R.R.^.o 2.o B.r+#.r+r+r+i i r+++r+++( 4.1.1.u u u 9.u 1.4.z 8.1 z+a a *.M *.*.1+*.*.R y.y.y.R [+y.9+R R X R X X X X #+#+s.w @.8.u.A 8 9.9.9.u x.3+}+H s.3.a+3.a+S..+G+! ! ! ! ! ! ! ! ! ! ! ! o ]+o #.G #._.G o o ! S.a+#.n >+( D G c+5 E+H+1 G 8.< W @.G+_.< _.! R.a+'+'+'+'+'+'+'+B }+a+'+a+4+@.a+H.Z _.C+X.)+i q.N.C.L.* H * H * H h+'+h+H H L.H L.h+H h+L.L.L.L.h+h+#+s.X o _.G S.s.#+#+9+M z.2 y._ *.y.*.$.Q.t.C.p.H h+L.Y.p.C.w+,.w+w+,./+w+w+,.,.w+,.,.w+,.7+w+,.e+0 y+g.g.2+g.y+y+t.p.p.p.p.B B 4+4+q.X.q.q.q.q.)+q.X.4+q.4+4+B q.B B B B B '+N.B B '+B B B B B '+B N.N.B N.N.N.N.N.N.N.H N.N.p.N.N.N.p.N.p.n+y.[+t.5+}.<+U.g+|.q 0.. . . . . . . . . . . . ", "u u u u 1.1.u 1.1.u -.1.1.u u u 9.u 9.9.9.9.u u 9.u u u 9.u u 1.u 1.-.1.-.u 1.u u u u u u 1.1.u 1.1.-.1.-.-.-.1.-.q+-.q+4.4.) &.D f+z -+&.9 &.4.4.4.) 4.4.) `.) `.( _.++b+D ( f+( ( 9 >+Z 4+A+X.2.J.i G.f+8.H+B.2.! )+a+a+^.a+4+S.N.h+'+q.q.B.q.H '+7.)+Y.L.Y.g h+L.Y.Y.h+H ,.Y.,.p.g Y.Y.p.g L.Y.L.g p.Y.Y.Y.h+'+'+'+'+'+L.g L.Y.g g h+* h+g g g g L.h+R.^.^.2.! R.'+a+a+'+a+^.q.^.^.R.` '+a+a+R.q.^.2.r+r+r+#.B.r+i _.i i ++A+( { { 1.1.u u -.-.4.-+f+b+1 z+n+*.*.1+1+$. +1+1+ + +_ y.y.R *.y.[+[+[+R R R R m.m.#+#+H.)+n >.E 8 !.9.9.9.9.z @.#+s.a+.+#._.A+b+< ++]+S.a+a+G+S.! 3.! ! ]+o #.#.o o o o ! ! S.S.a+]+n z { 4.( j+6 c+c+c+c+6 6 6 ]+1 ]+< < _.! a+'+'+` '+'+'+'+'+'+a+a+4+^.)+i.)+Z W _.G n+5+/+p.p.L.h+g H H * H * h+H H h+h+h+L.h+L.L.L.L.L.L.L.L.L.L.X E+G W 6 H+#+X R w ++G.#.z.& Q.y.B #+w n+X H H H '+H h+L.p.p.,.w+,.w+w+/+w+7+7+e+7+7+l+7+e+e+e+<+U.K r.{.r.| g.g.}.e+t.p.p.N.B B 4+4+4+X.q.X.q.4+q.q.4+q.q.q.B q.B '+B N.N.'+B B B N.B B B N.N.N.B N.N.N.N.N.N.H N.N.H N.N.N.N.N.p.N.p.!+p.p.p.t.Q.0 <+| g+g+|.Q . . . . . . . . . . . . ", "u u u u u u 1.1.1.u 1.1.1.1.1.1.9.u u 1.u u u u 9.u u u u u u 1.u 1.-.1.1.u 1.1.1.u u 1.u 1.1.1.1.1.-.1.-.4.-.-.-.4.{ 4.4.4.4.) c.D f+&.&.`.`.4.4.4.`.) q+) ) 4.`.c G #+f.f+D (+)+7.G.n Z ^.7.G+a+)+}+i J.n G.D G.8.@.7.++@.H q.3+H.H '+'+2.B.2.B.A+D X.H L.Y.p.Y.Y.Y.,.Y.h+H g Y.p.Y.Y.'+H L.p.g Y.Y.g p.Y.Y.g * '+4+'+L.p.g H L.H L.'+4+'+H Y.Y.g h+h+4+R.^.2.^.^.a+* '+'+'+a+R.R.4+'+'+'+` 4+4+R.R.2.o #.i i #.r+i i ++i r+A+( -+{ 1.{ `.i+c.c.D D c.6 P.a a *.*.$.$.$.$.$.$.$.$.$.$.$.[+ +y.y._ [+[+*.y.y._ [+9+R E+i.3+( f+f+&.1.9.9.9.x.)+n+w ^.++o+u.z E { { &.(+B.a+3.3.S.S.S.! ! ]+o o o ! R.R.3.R.a+a+a+++z 8 !.1.&.j+6 c+c+G+c+(.6 W G G W W _.]+a+a+'+'+'+` '+a+'+'+4+'+R.2.b+f+z 9 9 9 D 8.E+,+w+C.g L.H * h+H * h+H L.h+H L.L.H L.L.h+L.L.L.g L.L.L.H #+#+G+8._.G 5 E+S.G+o :.b.4 P.Q.Q.R i 2.4+s.s.}+3.}+S.}+}+}+#+m.m.p.C.C.C.w+w+w+w+7+7+l+e+7+e+e+y+3 r.r.] |.] l.F.r.2+g.y+y+e+/+p.p.p.N.B B B B q.4+4+q.4+4+4+q.B B B '+B B B B B B B B B B B B B N.H B N.H N.N.N.N.N.p.N.N.p.N.p.N.p.N.p.p.p.p.*.[+}.0 s U.r.l.k.B+Q . . . . . . . . . . . ", "u 1.u u u u u u u u u 1.1.-.1.1.-.1.-.-.u u -.u u u 9.u u 1.u 1.1.1.1.u 1.1.1.1.u u 1.u 1.1.-.1.1.1.1.-.-.-.-.-.-.-.) ) ) 4.q+-.) 9 `.-+i+( z &.`.4.4.) ) ) &.) 4.`.c+N.i >.D Z w H R.2.)+.+E+H H a+'+'+.+.+r+#.X.a+B R.a+H '+'+H '+'+L.4+^.4+C+b+G.o+b+.+H Y.Y.Y.g p.Y.Y.* H Y.Y.4+'+,.L.g L.g Y.Y.,.,.Y.Y.Y.p.,.p.g p.g g p.g L.L.'+q.4+'+H Y.g Y.Y.'+a+4+R.q.R.a+a+a+a+q.q.^.a+a+'+'+* '+a+'+R.a+R.^.2.o r+r+i #.#.r+i C+_.++D u.-+4.9 W ; (.(.(.6 c+P.!+a a e.e.1+e.5+$.& 5+5+5+& $.$.$.$.& $.1+$. +t.$. +[+_ *.n+b )+k+k+6 X.6 o+1.!.!.E X.9+w B.n >.E 8 9.9.9.9.-.D B.}+3.a+R.! a+3.! R.! R.R.R.a+a+a+a+'+@._.z A !.1.&.8.6 6 c+c+6 W D ( ( 5.< < _.! a+` '+'+'+'+'+4+` '+4+a+4+++:+x.8 9.9.u -.( C+'+L.h+L.h+h+h+h+* H h+'+H h+H L.L.L.h+L.Y.g L.L.Y.h+L.L.L.X X G < W ]+E+@.! o S.o 2.a+k *.y.}+2.a+a+N.s.f E+S.S.G+G+G+@.1 f w #+p.p.p.C.w+,+w+w+w+7+e+e+y+y+l r.[.|.q B+q 7 @ r.r.2+g.y+}.e+t.,.p.p.p.p.N.p.N.B N.B B N.B B q.B '+B B '+q.B B B q.B B N.H N.N.'+H N.N.N.N.H N.N.p.N.N.N.N.N.N.!+p.N.p.!+p.p.[+/+}.y+g.| g+g+|.B+q 0.0.. . . . . . . . ", "u u u 1.1.u u u 1.u u u u u u u u u u u u u 1.u 9.u u u 1.u 1.1.1.1.u u 1.u u u 1.u u 1.1.1.-.-.-.-.1.-.-.-.-.-.-.4.`.`.-+-+&.&.) 4.4.`.9 9 z -+`.4.4.) ) `.&.`.-+) 9 G 4+*+D E+L.L.H 2.^.a+}+'+4+N.a+^.4+^..+4+.+^.)+)+.+'+w H H H H h+q.C+B 4+7.D b+J.++B.^.N.p.g Y.p.Y.Y.p.Y.Y.,.Y.Y.p.Y.Y.p.Y.Y.Y.Y.Y.Y.g Y.Y.,.Y.,.L.h+L.h+H H '+4+'+B '+Y.p.g Y.H h+H h+'+'+h+h+'+R.^.)+2.^.a+h+'+'+'+'+'+` a+a+R.2.o r+r+i i r+r+i C+r+C+8.D >+>+8.6 6 X.1 P.P.P.z+z.M M e.e.1+e.5+1+1+e.& & & 5+& Q.$.& $.$.$.$.$.t.$. + +$. +M H.H+!+a M a 1 D E E o+H+m.H.B.J.:+E ~.9.9.9.9.9.1.*+! R.S.a+S.a+a+R.R.R.S.a+a+R.* a+'+a+}+B.n >.E 9 (+6 c+c+6 6 6 D &.{ -+z (+_.o a+'+'+'+'+'+'+'+'+'+4+'+'+@.++f+E 8 !.9.9.!.E b+.+* * * H '+* H * * H '+'+H '+'+H H h+H L.L.L.h+Y.L.L.L.L.- E+G _.G ]+5 o G o S.#+y.[+/+#+'+'+'+'+H m.#+#+w w E+f @.1 H+1 @.@.H+E+E+w #+m.p.,+p.C.C.w+l+e+<+U.m+|.q 0.. . 0.Q 7 ] l.r.{.2+g.y+}.e+e+7+/+p.,.p.p.p.p.p.H H H H * H '+'+B '+q.B B B B '+B B '+N.N.N.H H N.N.N.H N.N.N.p.N.N.p.N.p.p.N.p.p.p.p. +t.e+}.y+<+| l.g+7 |.7 q 0.0.0.. . . . . ", "1.u 1.u 1.u 1.u u u u u 1.u 1.1.u u u u 1.-.1.u 9.u u u u 1.1.1.1.-.1.u u 1.u u u 1.u 1.u 1.1.-.-.-.-.1.-.-.-.-.-.q+4.&.&.`.&.9 z -+4.4.4.`.&.) `.4.4.4.`.&.&.&.&.) 9 W b+o+D @.2.a+'+a+S.'+2.a+#+R.q.#.E+a+^.^.a+)+#..+2.i.)+4+w '+'+4+4+a+'+4+4+^.4+B q.A+C+q.4+H * p.g p.L.p.p.Y.Y.,.Y.Y.,.g Y.,.p.,.g ,.,.g ,.Y.p.Y.g p.* '+N.N.H..+w m.p.p.C.C.p.L.p.g Y.Y.Y.Y.Y.L.h+a+q.R.a+H '+'+'+R.` q.4+a+R.4+R.2.o r+i i _.r+r+i i ++_.A+8.8.k+c+1 1 5 5 b 2 z+a M M M e.1+1+e.$.e.$.5+5+& t.t.$.t.t.5+t.& 5+$.5+5+$.$. + +1+*.M *.M 1+e.M P.C+8.i.z+n+H+G+++b+D f+E 9.9.9.9.8 :+B.! ^.o ! ! ! ! S.R.R.R.'+a+'+'+'+s.L.b G+#.W 6 2 a 2 5 ^ n.W ( { 8 { z < #.G+a+'+'+'+'+'+'+'+'+a+'+a+a+^.i o+E { !.9.9.A >.;+^.* h+g * H h+'+'+'+'+4+a+^.]+i.]+G+.+}+N.h+H Y.Y.g Y.g - k f G G G 1 f G o ]+}+X 9+,+,+L.'+* L.[+9+m.9+#+X X X b z.E+5 H+5 1 5 H+H+E+H+H+H.H.#+z+p.,+/+0 y+l g+|.q . . . . . . 0.Q B+7 l.r.| 2+g.g.g.y+y+y+y+e+}.e+t./+7+p.p.p.p.H H N.'+N.'+q.B B '+B B N.N.'+N.N.N.N.H N.N.N.H N.H N.N.N.N.N.N.p.!+p.p.p.[+/+t.y+y+<+2+r.r.r.g+|.] |.B+q q Q 0.0.. ", "1.u u u u !.1.u u u !.u u u u 1.u u 1.1.u 1.u 9.9.u u u u u 1.1.u 1.u 1.u u u u u u u 1.1.1.1.1.-.-.-.-.-.-.4.-.-.-.4.&.&.&.&.`.9 `.4.4.) `.-+4.) q+4.4.&.z z &.&.) &.>+D D A+_.a+a+4+)+N.'+4+2.#.H.a+'+Y.h+s.4+a+2.B.B ^.B.C+B.)+B a+4+^.B.H R.)+^.}+H '+4+^.^.'+H H L.H Y.L.g H Y.Y.p.,.Y.p.,.Y.Y.Y.,.Y.Y.p.Y.Y.L.,.p.L.p.H N.b e.+.w.O O O o.I.$.I.O Q.C.p.Y.Y.Y.g Y.g L.Y.L.h+h+* '+a+4+q.q.q.R.R..+R.^.2.o r+i i _.r+r+i r+k+k+6 6 6 n.^ 1 5 !+b z+a M M *.*.*.e.e.e.e.e.a e.e.$.& & & $.$.$. +$.$. +$.1+1+1+$.1+$.e.$.1+1+5+1+1+*.M M M M n+b P.G+1 1 6 b+&.!.9.!.x.n o R.S.! ! ! ! ! ! ]+! o R.a+a+}+}+#+,+t.+.I.+.<.6+6+}.& T a n.D -+A E ( k+S.B '+'+'+'+'+'+* '+H '+'+N.a+i.++b+f+z -+{ 4.E o+++B * h+H g * H h+* '+'+4+++o+z `.`.E 9 5.G S.'+H L.L.Y.L.#+R G+_.G ]+5 @.G ]+G+E+L.L.L.L.L.H H H p.9+L.#+L.#+#+z.w b H+1 @.5 1 5 E+E+5 E+E+f E+H+H+S.H.#+[+I.<+ .B+0.. . . . . . . . 0.Q q 7 ] l.l.| {.| 2+2+2+g.g.y+g.}.e+e+e+/+/+p.p.p.p.p.p.H H '+'+H '+B '+B '+B N.H N.'+N.N.N.H p.N.p.N.p.N.N.N.p.N.p.p.p.t./+}.e+y+<+2+K | r.l.g+g+l.[.|.7 7 q q ", "u u u u u 1.u u u u u u u u u u 1.1.1.u 1.1.1.u u 9.u u u 1.u u u u 1.1.u u u u u u u u u 1.1.1.1.1.1.1.1.-.-.-.1.-.-.) `.&.9 z `.`.`.&.9 z -+4.-.4.q+&.9 D >+z -+&.-+9 k+! B.B..+R.;+_.w '+2.2.'+h+4+s.w H L.'+H a+^.! #+'+R.2.! ^.4+a+a+H '+q.4+B N.'+4+4+N.h+p.g h+'+'+'+H Y.p.g p.g Y.Y.p.g Y.Y.,.Y.p.L.,.p.Y.H 4+4+H H z.a C C +.6+> > <.6+> <.6+w.w. +C.,.,.,.Y.,.Y.Y.g L.h+h+'+* '+R.R.R.2.2.2.^.R.2.2.o r+i i 4 7.r+r+C+#.k+6 c+1 1 1 5 5 5 b a z+a a *.a *.*.y.a M a e.a e.e.$.& 5+& $.$.*.e.e.1+1+$.1+5+1+$.$.5+$. +5+1+5+1+ +*.1+*.*.[+1+n+M M M !+1 k+f+E E o+)+H+}+3.3.S.S.3.! S.S.! ! ! 2.#.B..+E+'.w.K.~+T.T.0+~+~+> e <.e.6 n ( :+8.G+N.s.'+'+H * H * H '+'+'+'+'+)+A+D f+9 9 9 9 9 D ++4+H H g Y.* Y.h+* h+h+3.7.E.x.~.{ { -+-+= z n i.'+h+h+L.- R X ]+G o 1 E+S.]+S.3.s.L.L.L.L.h+L.H #+#+L.#+- w E+1 G+c+]+]+G+1 f 5 E+E+b b b 5 5 H+E+5 5 E+b _ Q.e | |.0.. . . . . . . . . . . . 0.Q 7 7 7 ] l.l.@ r.r.r.2+g.| g.y+y+y+}.e+e+t.,.p.p.p.p.p.H H H N.H H H B N.N.N.H N.N.N.N.N.N.p.N.N.p.N.p.p.!+p.p.p./+/+}.e+y+y+3 2+g.U.U.r.r.r.m+g+[.} |.", "u u u u u u 1.1.u u u u u u u u u u u u u u u u u u u u u u 1.u u u u 1.u u u u u u u 1.-.1.1.-.-.1.1.1.1.-.-.-.1.1.-.4.) &.9 ( f+z `.`.&.&.-+`.4.{ 4.`.9 (+G.u.z &.) 9 8.#.a+4+}+s.4+r+E+h+}+#+4+'+s.L.'+}+'+H '+^.}+s.L.L.L.H s..+^.a+'+}+B '+'+4+4+4+4+'+h+L.Y.p.Y.Y.H H '+'+L.Y.p.Y.Y.Y.p.,.Y.Y.p.Y.,.Y.q.q.p.g * '+B 5 & C C C 6+> > 6+C C 6++.6+S <.O t.C.Y.Y.Y.,.Y.Y.g g L.h+'+h+'+'+a+a+R.! o 2.^.R.8+^.B.r+r+_.i _.i #.#.k+Z G+c+1 1 5 5 !+z+z+M a a *.*.a a a a n+z+a M M e.$.$.& $.$.1+*.*.y.*.e.e.e.$.$.1+$.1+5+1+5+1+5+5+5+5+5+ +1+1+1+1+ +1+*.M b !+1 k+6 X.N.z+#+w w w E+E+f H+H+3.3.! #.n E.A+P.t.|+|.B+t+t+t+t+D+&+T.~+> & P.i.)+P.#+L.h+* * L.H H * h+N.H H N.a+C+:+E x.1.-.q+&.>+8.X.N.p.Y.g H g * Y.H * H a+3+u.E -+( ( 5.5.9 z u.n ! H h+L.h+#+E+]+G ]+1 f ]+o S.E+- L.9+L.Y.L.L.L.L.#+w H+H+G+]+]+]+c+c+G+f 5 E+5 b z.R z.X 5 5 H+H+5 H+5 z._ Q.D.: [.0.. . . . . . . . . . . . . . . 0.0.0.0.B+q B+7 7 ] l.r.r.r.| 2+p g.}.y+}.e+e+7+p.7+p.p.p.p.p.p.p.H p.N.H H N.N.N.N.N.N.N.p.N.p.N.p.p.p.p.p.p. +p.t.e+}.e+}.y+y+g.y+2+3 | | {.| l.g+", "u u u u u u 1.1.u u u u u u u u u u u u u u 9.9.9.9.u u u 1.1.u u u u u -.u 1.1.1.u 1.-.1.1.1.u u -.1.1.1.u 1.-.-.-.-.4.&.9 ( i+( ( z 9 D z &.&.-+-+4.q+&.D ++G.z -+`.>+i.++#.H+s.H L.:.++.+a+h+2.w H C.Y.H L.'+s.L.L.9+Y.H L.H 2.3.'+'+H H s.B H H R.r+^.4+B H p.Y.p.g p.Y.'+B '+* H p.Y.Y.Y.Y.Y.p.Y.H p.Y.'+p.,.p.H #+b <.6+w.C 6+> > > C 6+<.6+T 6+> w.6+I.p.,.,.g ,.Y.C.Y.Y.h+'+H #+L.L.'+a+R.2.2.o )+a+R.8+2.o r+_.r+i r+#.B.Z c+6 n.n.1 5 b z+z+z+M y.a a a a z.z+n+z.z.n+a M e.$.5+5+1+$.$.a a *.a M *.*.e.5+$.5+5+e.5+e.1+e. +t. +5+$.5+5+5+ + + +1+e.M M M a n+y.M n+M R R R R R z+b E+E+E+1 A+*+*+D H+I.|+~+0.. . t+t+t+t+t+t+&+: D.I.Q. +[+9+L.L.L.'+h+H L.H h+s.s.h+}+#.n u.x.8 !.!.{ u.8..+m.L.H g g h+h+h+h+L.s.3._.n E.5.W ^ r 2 6 E.u.*+i '+L.s.s.X G+G o ]+f 5 o ! S.M.#+9+L.m.C.#+#+w H+@.G+]+G+! 1 @.@.@.@.E+E+X R R R X X k R X E+E+E+f E+E+z.$.w.2+g+&+0.. . . . . . . . . . . . . . . . 0.0.. 0.. . 0.0.. 0.q 7 |.] g+r.r.r.2+g.g.g.g.y+y+}.}.e+t.e+/+,.p.p.p.p.p.p.N.p.p.p.p.N.N.p.N.p.N.N.!+p.p.p.t.p./+p./+e+t.e+e+}.y+}.y+y+y+<+U.U.l ", "u u u u u u u u u u u u u u u u u 1.u u 1.1.u u u 9.9.u u u u u 1.u u u u u 1.1.u u 1.-.1.1.1.1.u 1.u 1.1.1.-.-.4.-.-.q+&.9 &.&.9 9 z i+]+r+2.^.! 3+N q+) &.W C+:+o+9 < ! J.f+8.G.D k+i n H.s.L.'+H '+H h+s.C.h+h+L.h+H h+s.H L.H 9+L.4+q..+a+2.#+'+H '+#+L.H L.g H p.L.Y.p.p.Y.Y.Y.'+* H ,.p.g Y.g H h+p.Y.,.H p.Y.L.m.e.S S > 6+> > > > > C C C <.<.> 6+> O C.Y.,.Y.Y.g Y.g Y.L.'+r+i.- 9+L.s.R.2.o 2.q.R.R.q.2.++r+r+#.#.#.G Z 6 G+(.c+n.1 5 5 z.z.z+z+a z+n+z+n+z+a 2 z+!+z.a M e.$.$.5+e.e.e.a a a a e.1+1+e.$.e.1+e.e.1+e.e.1+1+5+$.5+& $.t.5+5+$. + +5+ +1+1+*.1+ + +*.[+[+*.*.M y.R a n+#+z+w #.b+n 3+5 I.|+: B+0.. . . . . . . t+D+[.K.x+0 C.L.s.H L.H h+h+L.L.h+H H #+#+4+r+*+u.E ~.A E u.(+X.N.H h+* H h+* H * h+H 3.o 3+3+]+r 6+~+S <.~ Y 3+o a+L.L.s.E+]+#.]+]+f 3.]+]+3.w - 9+#+E+E+S.S.G+S.G+S.! @.@.1 H+E+b w X R R 9+R R R R k R R X w E+E+5 E+y.& O |+: B+. . . . . . . . . . . . . . . . . . . . . . . . . 0.. . . 0.Q Q 7 7 ] l.m+r.| | U.2+<+g.y+}.y+}.}.e+e+/+p./+p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.!+p.p.p.p.p.t.p.t.p.e+/+t.e+t.}.e+y+y+g.g.", "u u u 9.u u u u u 9.u u u u u u u u u u u u u u 9.u u u u u u 1.1.u u u u u u u 1.1.u u 1.1.1.1.1.u u 1.1.-.q+4.-.4.-.q+4.) &.D 8.++( z Z a+2.B.i B.:+`.4.`.>+D < < :+( 6 J.f+D b+b+++B.B.A+.+a+L.'+^.a+a+H ^.a+H L.q.s.H L.Y.'+#+L.h+'+^.r+R p.Y.C.H r+p.p.L.'+N.'+B '+'+H h+p.p.Y.p.p.,.Y.Y.p.,.p.g p.g p.Y.Y.,.Y.- _ <.S S |+6+> > <.6+6+C C C C 6+6+> 6+e +H L.,.,.Y.p.Y.L.Y.'+4+a+9+L.s.'+3.^.o o q.a+R.R.q.2.r+#.B.#.k+B.Z Z 6 c+c+1 5 5 b z+2 a z+a z+z.z+z.z+z+z+2 z+z+n+M M 1+5+$.$.e.M a n+a a M *.1+1+e.e.M *.*.*.e.1+e.1+1+1+$. +5+& & 5+5+ +$. +5+5+5+ +5+$.$.& $.$. +1+1+*.[+y.M n+n+z+1 #.++X.a w.x+S : k.&+0.t+. . . . . q |. .x+t.#+'+H H L.L.H L.H s.H L.L.9+9+y.b X.8.o+f+f+f+f+u.G.X.H H * * '+* * H h+M.s.3.! ]+G+5 r r C $.1 _.i 2.3.X s.X 3.o G ]+3.5 ! o ! 3.w #+f S.a+! S.S.! G+S.@.f H+f E+w X R 9+k 9+,.9+C.9+9+9+9+C.k R k R R k R _ w.D.r.|.&+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 0.0.0.0.Q B+7 ] l.l.m+r.{.| 2+2+2+y+g.g.y+y+y+}.e+}.t.}.t./+t.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.t.p.p.p.[+p./+t.t.t.0 o.o.", "u u 1.u u u u u u u 9.u u u u u u u u u u u u u 9.u u u u u u u u u 9.u u u u u 1.1.1.1.1.1.1.1.1.u u u 1.1.-.4.-.4.-.q+-.4.) `.4.&.i+D G a+R..+2.G.>+f+`.`.9 i+8.b+G.f+i+b+o+D G k+)+2.! a+q.'+'+2.J.)+f L.h+#+C.C.C.h+'+L.Y.Y.,.C.C.Y.H C.C.C.C.Y.h+'+C.,.p.Y.L.H '+B 4+'+'+'+H H p.L.p.Y.Y.p.,.p.,.,.,.,.p.,.p.L.[+D.> S S > > > > 6+<.6+C r C C <.<.> 6+> +.#+H Y.Y.Y.Y.Y.Y.p.h+L.H h+H s.'+a+B.2.! q.a+q.q.2.2.2.2.2.B.Z B.Z Z G+c+c+1 5 5 b b b z+z+!+z+b 2 z+z+b b b 2 z+z+M e.1+e.5+e.y.M a z.a a *.*.e.1+*.*.e.*.e.M e.e.e.*. +$.e.& $. +$.1+$.$. +5+1+5+5+Q.5+5+t.$.5+$.$.$.& $. +[+*.y.y.n+z+H.P.n+5+I.w.x+|+K. .[.k.T.q D+Q Q B+[.K.0 S.B.r+'+'+s.h+'+h+L.L.H L.#+9+/+Q.}.w.5+M 1 i.++b.b.b.:.2.H '+'+* '+* '+'+s.M.s.f f f X z.X z.X f G+! 3.H.#+L.E+G+o o ]+3.1 ! ! 3.f M.3.a+! S.S.! 3.S.3.f f w w X X R 9+9+9+C.9+C.C.C.C.C.p.,+C.C.9+C.- 9+[+_ t.o.|+: B+0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 0.0.. . 0.0.q B+B+7 g+@ l.r.r.| | 2+g.<+g.y+y+y+y+}.e+}.t.}.t.t.t.[+p. +p. +p.p.p.p.p.p.p.p.p.p.[+p.p.t.t.t.t.}.", "1.-.1.u u 9.9.9.9.u u 9.u u 9.u u u u u u u 9.u u u u u 9.u u u u u u u u u u u u 1.1.u -.1.u 1.1.1.1.1.u -.-.-.) -.4.-.-.4.4.`.`.`.&.9 (+Z J.n o+f+f+>+5.f+z z 9 D >+( 8.1 k+D b+k+2.b+G+R.a+^..+R.a+2.H.'+'+^.! m.Y.Y.Y.C.,.,.C.,.C.Y.Y.C.w+C.C.,.p.C.,.,.,.p.,.p.,.Y.H N.H '+'+q.'+H '+Y.H H g p.p.p.,.,.C.h+H #+$.].> S S > > > > <.C <.C r r C C <.6+<.C 6+}.p.p.,.,.p.C.L.L.Y.H h+s.L.h+'+a+a+^.q.a+R.a+R.q.^.^.)+)+)+i.Z X.Z 6 G+c+1 1 P.b b z+z+z.z+2 z+z+2 z+2 !+z+z+a a M a e.& e.*.a M M a a n+e.e.1+e.e.e.y.a a M M *.e.$.e.e.1+e.1+1+1+e.1+$.$.1+$.$.5+$.Q.5+& Q.& & Q.& 5+$.& $. +[+[+*.y.M M e.$.Q.I.o.D.D.|+|+K. .K.: : ~+ . .x+y.F Y ;+r+}+s.H H H H s.L.H L.,+'.w.x+x S W.e }.M )+7.:.7.q.q.4+'+* '+'+h+'+M.M.s.f E+E+f X E+E+E+f 3.}+H.s.s.s.f ]+G ]+]+3.3.! S.! f E+R.R.3.R.a+f }+}+w w #+#+#+#+m.L.L.L.9+p.C.C.,+C.,+C.,+C.,+9+C.C.,+9+C.'.0 D.r.g+B+0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 0.0.0.0.. 0.0.q q 7 7 ] l.@ r.{.r.| | U.2+g.g.y+g.y+}.}.}.}.}.}.t.t.5+t.t.p.p.p.p.p.p.p.p.p.p.p.p.p./+t.", "u u u 9.u 1.u u 9.9.u 9.u u u 9.u 9.u u 9.u 9.u 9.u u u u u u u u 1.u u u u u 1.1.u 1.u 1.1.1.1.1.1.1.-.1.-.4.&.`.4.q+4.-.4.-.4.) ) ) `.9 D o+b+G.D u.f+D #.b+G.u.9 9 9 9 z >+(+++8.n ++i.s.a+r+N.a+'+a+'+L.'+'+s.C.,.,.,.C.C.,.,.,.C.C.C.C.C.Y.,+,.p.,.w+,.,.,.,.p.p.,.,.p.,.p.,.p.h+H '+B H H H L.,.p.p.L.H 4+a+C.O K.S S ~+> <.> > C C <.C C C r r C > <.> > O +p.,.,.,.Y.H H L.L.L.'+H s.'+^.^..+R.a+R.4+R.^.2.2.)+^.)+)+X.X.G+]+G+1 1 P.P.b b b !+z+z+z+z+z+z+z+z+2 a z+n+z.M e.e.$.e.*.a n+M n+a *.e.$.e.M M *.M M M *.a *.e.1+$.1+e.*.1+e.1+e.e.1+1+1+$. +5+5+& & & 5+& 5+5+Q.& $.5+$.$. + +*.*.*.*.1+$.Q.I.I.o.s O O D.x+|+|+|+K.|+L w.w :.Y ..7.a+H '+M.'+h+s.H #+L.,+/+Q.o.x+S S K.S e +4+2.2.^.^.q.4+N.* '+'+* H * h+X X b X w X E+w E+s.M.'+#+s.#+3.o G o ]+f ]+o 3.S.f 3.! R.3.f E+#+#+#+L.H #+L.L.L.H 9+L.Y.L.L.9+C.C.C.C.C.C.C.,+,+p.9+,+,+/+e+y+L .|.Q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 0.Q q q 7 |.] l.l.g+r.m+r.| K | g.3 g.y+y+}.}.e+e+}.t.}./+t.p. +p.p.p.p.p.p.p.y.[+[+", "u 9.u u u -.u 9.u 9.9.9.u u 9.u 9.u 9.u u 9.9.u u 9.u u u u u 1.u u u u u u u 1.1.u 1.u 1.1.1.1.-.1.-.1.-.-.-.&.&.{ -.-.4.4.4.4.4.) `.) ) 9 D 8.b+n n 8.3+J.o+o+9 z z &.`.&.>+G ++J.8.#.G+^.R.r+a+'+a+'+L.H * '+'+* H s.9+9+C.C.L.Y.g Y.H p.C.'+H ,.B w+,.l+,.7+,.,.,.,.,.,.,.,.,.,.,.p.,.p.H '+'+'+'+H H Y.Y.L.C.0 K.S S S S > C <.C C r C r r C r r r C > > > > I.p.H N.H '+4+H H '+L.L.h+s.}+a+S.R.4+a+a+R.R.R.)+^.o )+)+i.i.X.X.X.c+1 1 P.P.5 z+z.b !+b z+z+2 z+z+a a z.a a a *.*.e.e.*.M n+a z.a a *.1+1+1+e.e.*.M z+a a e.e.e.1+1+e.1+*.*.e.M *.*.*.1+e.5+$.& 5+& 5+5+$.5+$.5+& Q.& Q.t.$.$.1+ +1+[+e. + +$.t.t.Q.Q.0 I.I.o.w.O O w.w.o.Q.H.:.:.;+7.a+#+'+L.h+L.L.H L.#+C.,+$.& w.O e O O D.o.t.#+N.G+i.)+^.4+N.H * h+'+H s.* s.s.s.X s.h+s.s.s.w s.'+M.f G+G o ]+G+@.! ! ! S.f S.! 3.3.s.#+L.#+H L.L.L.L.L.L.Y.L.Y.#+L.C.p.p.p.C.C.C.C.,+p.C.C.,+,+/+/+0 y+U.g+|.q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 0.Q Q 7 q 7 |.] g+l.l.r.{.| | p 2+g.g.g.y+y+}.}.}.}.t.t.t. +p.p.*.p.[+p./+", "9.9.1.1.u u u 9.u 9.u 9.u u 9.u 9.u 9.u u u 9.9.u u u 9.u u u u u u u u 1.1.1.-.1.u 1.1.1.1.-.1.-.1.-.-.-.4.) `.&.4.4.4.q+) ) 4.-+4.`.`.) ) &.D k+8.8.G+X.r+*+o+b+G.o+u.`.`.D k+D #.++C+.+a+^.2.S.R.'+X '+s.L.h+'+L.h+a+'+i #+H L.C.C.h+7.H C.C.p.'+2./+,.7+,.p.,.7+,.,.,.p.,.,./+p.,.Y.,.p.,.p.p.,.H H '+'+H L.9+D.S K.S S ~+> > C C C r r r C r r r r r h.=.=._+T *.B B N.'+a+a+'+4+'+H h+'+'+R.4+a+a+a+4+4+^.2.i ++++k+)+i.G+X.G+X.X.1 P.P.b H.b b z+z+5 z+z+z+a z+a a a M a a *.e.$.e.*.M M a n+z+*.e.1+5+ +*.e.*.*.a a a a e.e.$. +e.e.e.*.*.a e.e.e.1+1+5+$.5+5+& e.1+5+e.& $.& Q.5+& Q.5+ +1+ +e.$.$.$.$.5+Q.t.Q.5+t.Q.& I.Q.Q.I.I.I.Q./+#+B.F 7.^.B #+#+H L.H L.L.L.#+#+s.b n+*.e.$.1+ +Q.o.Q.C.#+3.r+#.o R.'+'+'+h+* L.H L.L.#+L.#+X #+#+s.H H s.s.E+f ]+_.G G ]+3.o ! ! 3.3.! ! 3.3.s.s.L.L.L.L.p.L.m.L.p.L.L.L.p.Y.L.Y.Y.C.p.C.p.C.C.,+,+C.C.,+[+/+[ <+r.l.q 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 0.0.Q Q B+7 7 ] g+l.r.{.| | 2+2+$+g.y+y+}.}.}.e+}.t. +t.t.t./+", "{ 1.1.9.u 9.9.9.9.9.u u u u u 9.u u u 9.u 9.u u 9.9.u u u u u u u u u u u -.1.u 1.1.u u u 1.-.-.-.-.1.1.-.-.-.&.&.{ -.4.&.&.( z ) ) `.&.&.&.) ) &.`.&.9 D k+n 8.B.J.*+f+z &.>+8.3+6 a+2.r+.+s.'+2.2.! '+^.s.L.Y.Y.L.L.L.Y.C.h+q.p.C.,.,.,.Y.L.C.C.Y.7+,.,.,.7+,.,.p.7+,.7+w+,.7+,.,.p.,.,.,.,.,.g p.C.Y.Y.L.h+#+_ S S S > S S > 6+C C r C C C r C r r r %+h h h V.2 1+P.4+'+4+'+a+a+'+a+H H H '+a+R.'+'+a+R.^.r+++J.;+G.J.++Z )+G+.+.+1 P.P.P.P.b b z+P.b z+b z+2 z+a a M a a *.e.e.*.e.e.e.M M n+a a *.e.1+$.1+e.e.a *.a a M M e.e.e.e.$.*.*.a *.M a *.1+e.$.$.5+& $.$.5+e.e.1+e.1+5+$.Q.5+5+t.5+$.5+5+1+1+t.5+$.$.& $.$.5+$.t.$.Q.& t.t.'.'.*.z+H .+.+H.b R #+m.L.9+p.9+9+#+H+! S.@.P.z+P.i.)+w [+/+,+R S.G #.o ! '+H '+'+H '+h+* H L.h+* H H h+L.'+H H s.s.3.G G G ]+1 ]+o ! ! @.S.! R.3.M.s.L.L.L.L.L.L.m.L.L.L.Y.p.Y.Y.L.C.p.C.Y.C.C.p.,+p.C.p.C.[+w+/+l+y+<+r.|.q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 0.0.0.Q q q 7 7 7 ] l.l.r.r.| | U.g.g.g.}.y+}.}.t.}.Q.0 ", "{ 9.u 9.9.u 9.9.u 9.9.u u u u 9.9.u u u u 9.9.9.u u u 9.u u 9.u 9.u u u u u 1.1.u 1.u 1.1.u -.-.4.-.1.1.-.-.-.-+`.`.4.4.&.`.&.9 9 `.4.) 9 z &.&.`.) &.&.&.9 >+(+6 k+n >+z z &.8.#.#.++B.R.)+s.'+a+'+a+.+q.}+L.L.h+L.Y.H Y.p.L.L.C.Y.Y.w+w+w+,.L.B H w+,.,.,.7+7+,.p.,.7+7+,.7+7+,.p.,.7+,.7+,.,.,.,.,.w+p.C.C.p.'.> S > > S S > 6+<.C <.r r C r r r r ;.h c h y %+5 b z+@.a+4+a+4+a+'+H h+h+h+h+H '+'+4+'+^.2.i J.G.*+( o+J.k+)+X.X.@..+P.P.P.P.b P.b b b b b z+!+n+z+a M M e.*.a e.$.e.1+e.*.*.M *.a e.1+1+5+e.*.e.*.M M a *.a e.e.e.e.e.*.a a a a *.e.e.e.$.$.$.5+5+e.e.e.e.1+1+1+1+1+$.t.& Q.5+& 5+5+5+$.5+Q.5+& 5+$.$.$.$. + + +$.$.$. + + +n+n+b #+n+m.m.9+y.9+9+9+9+m.a+^.B.#.#.]+X.++;+:.i 4+9+9+w o #.#.o ! a+'+'+'+h+H H * H L.h+h+H H H H s.'+H.}+E+G+_.G G ]+G+]+o ! 3.S.! ! R.3.f s.H L.H 9+L.L.Y.L.p.L.Y.L.Y.p.L.Y.p.C.p.C.C.C.C.w+p.,+C.,+,+/+e+y+L m+} q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 0.0.0.Q Q B+7 7 ] l.l.l.r.r.r.U.2+2+<+g.y+g.y+", "u 9.9.u 9.9.9.9.9.9.u 9.9.9.9.u 9.9.9.u u u u u u u u u 9.u u 9.u u u u u u u 1.u u 1.u 1.1.1.-.4.-.-.-.-.-.4.9 z -+`.) `.4.) &.`.`.-+-+&.&.z &.`.&.9 ( D ( 9 9 >+z 9 A+( `.&.9 G B.n ]+.+r+@.H L.h+'+2.B.s.L.L.Y.L.h+'+H Y.'+H H Y.L.C.,.,.L.2.p.7+,.,.,.7+,.,.,.7+,.,.p.7+,.,.7+,.,./+,.,.,.,./+w+w+/+y+l L v o.S S S S > S > > C C ;.%.;.r h.r v.y y h h h V.%+^ H.#+w }+^.4+'+4+}+'+L.Y.L.L.* H '+'+a+^.B.7.G.G.f+f+o+D ++i.X..+.+1 1 P.P.b P.P.b 5 b !+b z+z+a z+a a M M *.e.e.1+e.e.e.a *.a *.e.1+1+1+$.1+1+*.*.M M M a M y.e.1+e.e.*.e.a *.*.e.e.$.5+5+$.5+$.5+e.e.*.*.a *.y.1+e.5+& & $.5+5+$.& 5+5+$.1+$.$.t.5+5+5+ + + + + + + + + +*.1+*.*.*.1+1+1+*.*.[+,+[+m.#+@.B.i 7.7.C+++J.:+b.:.B.#+- E+]+G #.o S.'+'+N.* H h+H H * H H H s.'+H s.s.H M.s.f ]+G G ]+]+c+]+]+! ]+3.! ! ! a+M.#+H L.L.L.L.L.L.L.L.Y.L.Y.Y.Y.p.C.C.p.C.p.,+p.C.w+,+p.[+,+/+t.l+y+U.g+|.0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 0.0.0.0.0.0.0.0.0.q q q 7 |.] [.m+m+r.r.U.U.U.", "u 9.9.9.9.u 9.9.9.9.9.u 9.9.9.u u 9.9.u 9.u u u u u u u u 9.u 9.9.!.u u u u u 1.u 1.-.-.-.1.1.-.4.-.4.-.-.q+4.9 9 z ) 4.&.5.9 `.z `.&.(+D z &.&.9 9 &.9 f+*+f+f+9 &.`.i+>+&.&.&.i+8.++o #+'+r+s.H L.h+h+H ^.}+L.h+'+H '+C.Y.C.C.C.C.'+C.H ,.Y.,.L.w+,.H H H 7+,.p.p.'+p.,.,.7+,.,.7+w+7+,.7+7+7+e+y+$+: l.l.[.[.: .S > > > S > 6+C <.;.=.%.;.h.;.h h Z.h h h V.%+^ H H H H a+'+B a+'+'+H L.L.g h+'+* '+4+q.r+J.G.o+o+f+:+D 8.)+X.1 B H+P.P.P.H.P.P.b P.z+b b z+z.2 n+n+a M e.1+1+$.1+1+1+e.e.*.e.*.e.1+5+$.e.e.1+1+*.a n+M a M *.*.e.e.e.M *.a a a e.e.$.& Q.5+$.$.$.*.a a a a a *.e.1+$.$.5+Q.& Q.$.$.5+5+5+5+5+5+5+$.$.5+5+ + + + + +1+e.$.$.1+1+1+e. +1+$. +1+1+*.*.[+R H.)+B.++7.C+C+J.b.;+:.C+N.X 3.o G ]+o a+'+'+'+* H H h+H h+H h+H h+s.H H H s.w w @.G W G G ]+]+]+! S.@.S.]+! 3.3.M.#+h+L.L.L.L.L.L.p.L.L.L.p.Y.Y.Y.Y.p.9+C.C.w+w+C.,+w+/+/+,+t.t.o.<+l l.q 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 0.0.0.. 0.0.0.0.. 0.0.q q B+7 [.] l.l.g+", "u u 9.u 9.9.9.9.9.9.9.u u u 9.u u 9.u u u u u u u 9.u u u u u u u 9.9.u u u u u u u u 1.-.1.u 1.-.-.-.-.4.-.q+) 9 9 4.&.&.9 5.( &.`.`.9 D D u.`.&.) &.8.i..+:.( f+z z -+-+&.&.9 >+D #.B L.Y.* ^.s.L.L.L.'+2.4+H C.Y.L.L.L.C.Y.'+L.C.Y.C.H w+w+,.,.p.,.4+,.,.,.7+,.Y.Y.H p.w+/+7+,.p.7+,.7+7+7+U.m+: [.|.|.[.[.[.[.[.: ~+> <.> > C r > ;.=.=.=.=.I h h h h h y %+_+5 s.H C.Y.C.Y.Y.L.L.L.g L.g L.h+H H '+4+2.A+b+*+o+:+:+D ;+k+X..+.+.+P.1 H.P.P.P.H.P.b P.z+5 b z+z+2 z+a a *.*.e.e.e.e.e.e.a *.a e.e.1+e.5+$.$. + +e.*.M M M M e.e.e.e.a *.a a a *.e.e.1+$.$.& & $.e.*.*.*.a z.a e.e.e.5+& & 5+& 5+5+& & 5+e.$.$.5+1+$.1+$.1+e.$.e._ 1+1+1+e.e.5+& 5+$.$.$.$. + + + + +*.y.n+b .+.+X.X.X.B.++i C+.+w E+! ]+o o ^.a+}+'+'+H '+'+'+h+'+H L.'+H H s.H s.s.s.f S.G G ; ]+c+]+]+]+]+1 G+! S.S.f w h+H H H Y.L.L.L.L.p.p.L.Y.9+L.p.C.C.p.C.C.p.C.w+w+/+/+/+l+l+e+y+<+r.|.q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 0.0.0.q B+7 ", "u u 9.9.9.9.9.9.9.9.u u 9.u u 9.u u 9.u 9.u u u u u 9.u u u u 9.u u 9.u u u u u u u u u u 1.u 1.-.4.4.-.4.-.4.&.&.`.`.9 z `.&.9 9 `.) &.9 D b+:+-+) 9 6 H+R.++^.a+;+z `.z &.`.z D G b w 9+H '+L.'+#+L.* L.L.4+)+L.Y.Y.h+L.H C.,.,.C.Y.H L.w+Y.p.w+,.7+,.p.,.,.,.7+,.,.,.p.,.p.7+,.,.7+,.7+y+U.l.l.[.|.[.|.[.[.[.: : : [.: S C r r r r r %.%.h h h h h h h V.v.r ^+!+#+- C.C.C.C.C.C.C.C.Y.Y.L.L.'+'+* 4+R.2.J.J.G.o+o+G.b+8.k+X.X.1 H+P.P.P.H+P.P.H.P.b E+z+z+b 5 z+!+z.z+a M e.e.e.e.*.*.e.*.e.M *.e.1+e.e.1+e.*.*.e. +y.*.a *.a e.M e.e.e.*.a a *.e.e.5+5+Q.Q.5+1+e.a a a z.n+a e.e.1+$.5+& & Q.& Q.5+5+& $.e.e.5+5+$.e.$.5+1+1+1+$.$.e.1+5+1+$.5+$.5+5+5+5+$.$.t. + +$.*.*.*.n+n+z+b N.H.B 1 B H.w f ! ! ]+! R.M.'+'+'+'+h+'+h+H * '+L.h+H H s.H H s.#+E+]+W G G ]+]+]+]+3.3.@.S.]+3.3.f w L.L.L.L.Y.L.L.L.L.L.L.9+L.C.Y.9+9+C.C.C.C.p.C.C.C.,.l+/+/+l+e+y+].: B+0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 0.", "1.u u 9.u u u u 1.u u u u 9.u 9.9.9.9.u u u u u u u u 9.u 9.u 9.9.9.9.u u u u u u u u u 1.u u u u -.-.4.q+) q+4.4.4.&.9 &.&.( z ) ) `.&.( (+#.n z ) &.i+H+q.5.H+4+^.B.;+f+9 >+9 9 i+( ++#+C.4+)+^.a+H L.h+h+'+'+L.H L.Y.L.Y.C.p.g H '+q.H ,.H w+,.,.,.,.7+,.7+,.L.,.,.7+,.,.H p.7+e+$+U.F.l.[.l.[.g+l.g+: r.r.r.r.r.: : ~+~+S > r ;.;.r =.%.h h h h h h I I %._+%+E+H p.C.p.,.Y.Y.L.Y.g p.Y.Y.L.L.H '+'+4+2.r+7.;+b+J.b+8.C+i.X..+B 1 B 1 H+P.P.P.P.H.5 b !+P.b b b z+z+n+a M *.e.e.M a *.a e.a e.a *.*.*.1+$.1+e.e.*.*.*.*.*.*.e.*.1+e.*.*.a *.a e.1+$.$.$.$.$.$.e.e.*.a z+a a *.*.e.$.$.5+I.& & & $.& $.e.5+e.1+1+e.5+$.5+$.$.5+5+e.e.1+$.$.5+1+$.Q.Q.$.& t.5+5+5+$.1+$.1+1+*.*.*.*.y.M *.M n+n+n+b E+3.S.! ! a+a+'+'+'+'+'+'+'+'+H H H s.H L.L.H s.s.f f G G G W ]+]+G ]+]+3.c+G+G+S.3.H.#+L.H L.L.L.p.#+C.Y.L.Y.Y.p.Y.Y.Y.Y.p.C.C.C.C.C.C.,.w+,.7+7+e+e+3 U.[.q 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "u u 1.u 1.-.-.1.q+1.u 9.u 9.u 9.u u 9.9.u 9.u u 9.u u u u u 9.u 9.u 9.u u u u u u u u u u u u 1.u -.q+q+q+4.4.4.4.q+&.( 9 `.) 4.`.`.) `.D 8.< B.G.( D i+6 2.^.4+;+C+C+7.:+( 8.G.u.9 9 W a+7.;+G H 2.@.N.H h+L.C.L.h+R.'+p.Y.Y.C.Y.L.g N.C.C.C.w+w+7+7+,.,.Y.p.,.,.,.,.,.7+e+r.r.U.r.m+g+l.r.g+g+m+g+l.: l.: . .r.K.K. .: : : ~+> ;.=.C ;.=.h h h y y y y =.%.I V.P.N.s.#+9+C.C.Y.Y.Y.Y.H L.'+4+'+B a+4+a+q.B.++A+A+J.++++i.)+G+1 H+1 H.P.1 B P.P.5 b 5 H.z+b !+5 b !+z.n+a a *.M M *.M *.a e.M e.*.a *.*.e.1+ +1+1+e.e.e.e.a *.e.e.1+e.e.e.*.e.a e.e.1+5+$.Q.5+$.1+e.*.a a a a e.e.1+$.5+$.Q.5+& 5+5+& 5+1+5+5+$.$.1+5+$.5+5+$.$.5+$.5+e.5+$.$.5+$.$.5+Q.& & & Q.$.5+5+ + + +1+*.e.1+*.y.[+[+1+y.y.#+w }+a+}+a+a+}+'+'+'+'+'+'+'+'+H '+H s.H H L.H #+#+w @.G G G G ]+~ o ]+]+c+! S.]+@.3.w s.L.L.L.L.L.Y.L.L.p.L.Y.Y.C.Y.C.C.C.C.C.,.,.,.,.,.m 7+m 7+e+d+[ L m+} Q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "1.1.1.1.-.1.u 1.u u u 9.u u u -.u u u u u u u u u u u u u u u 9.u 9.u u u 1.1.u u u u u 1.1.1.1.1.1.1.{ -.-.-.-.4.4.q+`.`.4.4.) ) &.`.) 9 8.6 r+u.z (+_.B.)+S.^.@.a+a+R.;+z 9 ( 9 9 9 5.P.E+)+@.a+7.B.3.'+H L.L.L.Y.Y.h+L.Y.p.,.p.Y.Y.L.w+Y.,.p.,.p.,.,.7+,.,.,.,.7+7+7+<+<+<+F.r.r.[.[.l.g+m+r.: .g+: g+: [.: ].: [.[.: : ~+~+S > %.%.C ;.h h h =.h =.h I %.=.V.5 H '+B B '+H Y.L.N.'+B '+'+4+4+4+^.^.^.^.2.r+C+C+C+b+8.Z X.B H+B P.H+1 P.P.P.H.P.P.b 2 z.z+5 b b b b z+n+y.M M y.M a M y.M a a e.e.a *.*.1+1+ +$.1+e.a *.e.e.e.e.e.a *.*.e.*.1+e.$.5+ +5+$.$.5+ +1+e.a M M e.e.1+$.5+5+5+& Q.& 5+& 5+$.$.e.1+1+5+$.5+& 5+$.& 5+$.5+e.& e.1+5+& 5+5+& 5+& & & Q.5+5+$.5+ + + + + +1+e.1+1+1+[+*.*.M z+E+P.H+a+'+a+'+'+a+a+}+a+N.'+'+'+s.s.h+#+H L.h+s.X ]+G G G ]+G ]+]+]+]+G+G+]+@.S.f #+L.H h+L.L.Y.L.p.C.L.p.Y.p.Y.C.Y.,.Y.,.,.,.,.w+m 7+7+F+F+F+d+d+$+K r.] Q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "4.u u u u 1.1.q+-.u u 9.u u -.-.u 9.u u u u 9.u u u u u u u 9.9.9.9.u u 1.u u u u u u u u 1.u 1.-.1.-.-.q+-.4.q+q+-.4.) `.`.-+4.`.9 &.`.) &.(+k+b+_.A+k+#.A+( f+< i.)+^.:+z &.9 9 9 9 ( D o+o+]+H R.w 4+r+G @.'+Y.C.p.Y.C.Y.Y.Y.Y.4+B C+H.,.,.h+Y.C.,.,.p.7+7+,.,.7+7+e+<+g.l r.l.l.l.g+m+g+: m+: .r.: : [.[.[.: ~+: : |.: [.~+~+> <.%.=.=.y =.h h =.h =.=.%.h y _+H.N.H H '+B '+4+4+4+q.4+4+^.^..+^.B.)+B.B.C+C+k+C+k+i.X.G+1 P.H+P.P.H+1 H+P.P.P.H.P.b b !+b b b 2 z+!+a M *.M R y.R *.a *.*.a a *.a a *.e.e.1+1+1+1+e.M M M e.*.1+e.a e.e.e.1+1+1+5+5+$.& Q.$. +1+1+1+e.*.e.$.e.5+& & Q.& Q.Q.& 5+5+5+5+e.5+1+e.e.$.& 5+$.$.$.e.5+$.& & $.$.5+& 5+& 5+& 5+5+5+Q.5+5+5+5+$.5+ + + + +1+1+ + + +[+*.y.R #+w H.a+a+R.4+^.^.)+! ! a+}+'+s.H H L.#+#+X s.w ]+G G G n.]+G ]+! 3.c+! S.@.@.3.w L.L.L.L.H Y.L.L.L.g L.Y.Y.Y.C.Y.,.V ,.,.7+d.7+F+F+F+d+$+).$+3 K F.] 7 Q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "-.u 1.u u -.4.-+4.u 9.u 9.u u u u u u u u u u 9.u u u u u u 9.u 9.u 9.u u u u u u u u u u u u 1.1.-.q+-.-.-.-.-.4.) 4.) &.&.4.`.&.9 ( 9 -+) ( 8.8.++B.*+b+G.u.f+>+< .+^.;+9 9 9 >+9 9 &.i+(+}+s.'+h+R.R.2.;+A+B H R.'+Y.h+h+L.C.'+'+'+2.B ,.p.,.p.,.Y.H p.,.,.7+,.7+t.<+<+y+l | r.g+m+g+: [.g+: : : : U.: [.|.k.[. .|.: : : : [.: S S T %.I =.h =.h =.h =.%.%.=.=.%+b '+B '+B '+'+H H '+H 4+4+'+4+^.)+C+B.B.C+k+k+k+i.X.X..+H+H+B P.H+B P.P.P.P.P.P.P.b 2 b b 5 b !+b n+z.n+a a a M M *.M *.e.a M a a a *.a M $.5+1+*.*.M e.e.e.*.*.*.*.e.*.e.1+e.5+5+$.5+5+Q.5+5+$.$.1+e.e. +1+$.5+& Q.Q.5+5+Q.& $.& & & $.$.$.$.$.$.1+$.5+$.5+& & T 5+e.$.5+5+& & & Q.5+& & & $.5+& $.5+$.5+ +5+1+t. + + +$.$. +$.$.e.y.M m.w N.a+^.i 7.3+3+3+3+_.#.G+}+E+'+#+#+#+X X f o ]+; ]+]+]+]+]+G+]+G+G+G+S.S.E+H H L.L.Y.Y.L.L.g L.Y.g L.Y.g g g Y.,.m m 7+F+d+v $+$+p p 3 3 K {.l.] q 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "1.-.4.) ) -.1.-.u 1.u u u u u u 9.1.u u u u u u u u u u u u u u 9.u u u u u 1.u u u u u u 1.1.1.1.-.-.-.-.q+-.4.4.) ) ) ) &.4.) &.9 &.z &.&.) 9 >+k+G J.++++#.B.G+}+2.r+;+o+f+>+( z z -+i+1 #+2.H.L.h+* H 4+a+a+4+H #+L.L.Y.Y.Y.H h+L.Y.L.C.Y.w+,.p.q.'+w+w+7+,.,.t.g.U.U.r.r.r.F.r.r. .: .: r.: [.[.[.: |.[.|.g+].k.: ].: ~+: : : ~+> <.^+%.=.=.=.=.h =.=.=.=.h.!+z+L.L.L.H '+'+H Y.H p.L.L.L.H '+4+^.B.B.C+C+C+k+i.G+1 @.H+B H+P.P.P.H+P.H+P.P.P.P.P.5 H.b b b z+z+z+a a n+y.a R a a M *.1+e.M M M a M e.e.e.e.e.e.e.*.e.*.e.e.e.e.*.e.*.*.e.1+$.5+$.5+& & Q.& $.$.5+$.$.$.5+& Q.5+& & 5+$.Q.& 5+& $.5+5+$.$.1+5+$.e.$.& $.5+5+& $.& 5+e.$.$.5+& $.& & Q.5+5+5+5+& Q.Q.5+Q. +& 5+5+$. +5+ +$.Q.5+& & +*.k m.E+! r+4 F 7.3+3+n n n 8.G H+'+s.H s.#+w 3.o ]+]+G ~ ]+]+]+3.G+G+3.3.@.3.X #+L.h+H L.L.h+Y.g L.g g g g g g v+V V m d.F+d+$+$+p p K K F.F.m+@ ] d Q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "-.) ) ) 1.u u u u u u u u u u u u u u u 9.u u u u u u u u 1.u 9.u 9.9.u 1.1.u 1.u u u u 1.u 1.1.1.1.-.-.-.-.-.4.4.) 4.) 4.`.) q+4.&.z {+9 z ) ) i+( 9 W A+< B.J.#.H+'+'+r+o+>+f+>+D z `.&.8.@.2.#+p.C.C.H H L.h+R.++B H H L.Y.L.L.L.Y.p.C.C.,.,.* L.p.Y.p.l+y+<+U.l l r.r. .r.g+g+ .: r. .: K.o.[.~+[.|.|.[.[.: g+K.[. .K.: [.: : g+: K.S > ^+=.h =.=.=.=.%.=.=.5 N.L.p.#+H H H H L.#+Y.Y.L.L.'+'+a+'+4+^.)+#.k+6 B.Z i.X..+P.P.P.P.H.P.P.P.P.H+P.P.P.P.b H.2 !+z+2 z+z+z.M a M z.a R M a *.*.*.a n+a y.*.M M e.e.1+*.*.1+*.e.a *.*.a *.M e.*.1+$.5+Q.5+Q.Q.Q.5+5+5+& 5+5+1+& & Q.t.Q.& Q.Q.& $.5+& 5+& 5+$.t.$.5+e.5+5+e. +e.$.5+1+T 5+e.$.$.$.$.e.5+5+5+5+& & $.$.5+& 5+$.5+& Q.5+ +5+t. +Q.$.$.I.Q.Q.& Q.$.y.E+a+)+o r+o _._.< < < 5.8.G P.'+#+X s.f ]+o G ]+]+]+G ]+3.]+c+]+! G+3.E+s.L.H Y.Y.h+g L.L.g g g g g g g u+u+v+Y.m F+d+$+' {.{.F.F.l.m+l.l.] } q 0.0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "`.4.u u u -.1.u 1.u u u 9.u u 1.u u u u u u u u u u u u u u u u 9.u u u u 1.u 1.u u u u 1.u 1.1.1.-.1.-.-.-.-.) -.) 4.4.4.) ) 4.) `.&.&.9 &.`.-+&.9 z i+D (+G ^.;+8.@.'+q.:.C+*+z >+9 &.&.9 G '+#+C.L.q.a+C.R.H * 2.a+B.H L.L.h+Y.L.g w+,.C.w+p.* '+p.w+l+y+2+U.<+U.l r.r. . .: l.r.: s K.[.|.[.[.[.g+g+: g+: K.S S |.[.|.: K.: .x+|+S K.|+<.h.=.=.=.=.%.%.%+n.N.H.N.H H H N.'+B '+B '+H L.H h+H a+a+.+)+B.B.#.6 i.6 i.X.G+@.H+H.P.H.P.H.P.P.P.P.P.P.P.5 b H.z.z+z+a a n+a n+a a a a M *.e.*.M *.z.M a y.*.*.e.e.e._ *.e.*.e.e.e.e.*.*.a e.M e.$.$.Q.& & 5+Q.& Q.$.5+& & Q.& & +.Q.& Q.& Q.Q.Q.Q.5+& 5+& 5+$.t.t.$.$.$.5+$.e.e.e.$.e.e.5+e.5+$.5+& $.& & & 5+& Q.& 5+& Q.& 5+$.Q. +5+$.$.5+Q.Q.Q.I.<.I.I.I.I.1+b a+! ]+]+! ! ]+; W j+< W W G+E+s.w X 1 o ]+]+]+]+]+]+]+]+3.c+3.3.3.3.f s.L.L.H Y.L.L.g g p.h+L.g * * * u+u+g m m F+v 3 K F.m+@ @ ] l.] } d d 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "4.1.1.1.1.-.-.1.u u u u 9.u 1.1.-.1.u u u u u u u u 9.u u 1.u u u u u u 1.u u u u u u u u u -.1.-.1.-.-.-.-.4.4.4.q+4.4.) ) 4.) ) ) &.`.) -+`.4.) 9 9 9 D 8.b+k+_.#.4+a+'+4+B.*+9 9 9 z 9 8.H+}+L.Y.h+L.L.C.Y.a+'+B.E+H H L.h+L.Y.C.C.C.,.,.,.,.,.C.p.e+r.U.<+g.l r.F. . .: [.[.: [.[.[.[.|.: : ~+: K.|+K.O D.D.w.|+k.[.|.[.|.|.0+[.[.: ~+r.e r %.%.%.=.=.I h.P.B a+B '+H '+'+N.H H '+N.B '+H N.'+}+^.)+B.i.6 B.B.k+Z G+G+P.P.H.P.H.H.P.P.b H.P.P.P.b 5 b z.!+b z+a z+M a R a M M n+z.a a a *.y.y.M M y.y.M e.*.*.1+*.*.*.*.*.e.e.*.*.a *.*.e.*.1+5+5+Q.Q.Q.5+Q.& & Q.Q.Q.& Q.Q.& +.I.& Q.5+5+5+$.Q.& & 5+$.& 5+$.5+1+1+$.e.$.$.e.e.e.$.e.e.$.5+$.$.& $.Q.$.& & & & Q.& & Q.5+Q.$.$.Q.5+5+5+ +& Q.I.w.O 6+O w.t.z.w H+@.G+5 2 2 ^ ; =+=+W G (.S.#+X f f ]+G ]+]+]+]+]+]+3.]+]+]+G+3.f E+H L.L.L.L.Y.H g g g g * g * u+* * u+v+6.P d+$+K {.@ @ ] ] ] } 7 7 d Q 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "4.1.u u 1.-.1.-.1.u u u u u 1.-.-.-.1.1.1.1.1.u u 1.u 1.u u u u 9.9.u u u u u 1.u u 1.1.u u 1.-.-.1.-.1.q+q+-.-.1.q+4.4.4.4.4.4.4.) `.&.`.`.`.`.) `.{+9 9 >+D < b+k+@.a+4+i 4+*+9 f+( >+( 8.i.w L.R.H C.,.C.C.C.L.q.@.#+H #+L.L.N.N.h+p.,.p.H p./+H I.x+Q.<+ .l.g+[.g+m+g+ .: [.: [.[.|.[.[.l.r.K.S x & w.a +.K.D.S [.[.[.|.|.|.|.[.[.[.g+K.x I._+%.=.I V.%+!+H H '+H '+H H H '+B B }+'+a+a+a+a+4+a+^.)+#.B.k+6 6 B.6 X.G+P.P.H.P.H.H.P.H.5 N.H.b 5 b !+b b z+b z.a a M *.*.a M a M z.a a a y.*.a y.M *.*.*.*.e.*.1+e.e.e.e.*.e.e.e.*.a *.y.*.*.1+Q.5+& & & Q.Q.Q.Q.& & Q.& Q.I.& Q.+.Q.Q.& Q.Q.$.t.t.$.Q.t.$.$.$.1+$. +1+e.e. +e.1+e.$.$.e.5+& 5+5+& $.& & & +.Q.& I.& 5+& & Q.5+ +5+$.5+5+5+& I.I.O O O D.O Q.y.b E+5 1 5 2 r ^+~ =+W =+; c+1 X X f ! ]+]+]+]+]+]+]+]+3.c+]+3.G+3.3.E+#+L.L.Y.L.L.g g h+h+h+u+* h+* A.A.A.g m P d+3 l m+l.] ] 7 7 d d q 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "{ 1.u 1.u 1.u 1.1.1.u u u u 1.u -.u 1.1.1.1.1.-.1.1.1.1.1.1.1.u u u u u 1.1.u u 1.1.-.-.u u 1.1.-.-.{ -.-.1.-.-.-.-.4.4.4.q+q+q+4.4.4.4.`.) ) `.) `.`.9 ( &.i+(+8._.i.i X.)+J.9 o+k+J.C+++5.++R H L.s.L.C.C.C.Y.'+A+J.++)+N.'+4+2.B.Z ,+7+e+0 U.o.*.z+b U.g+l.[.|.|.[.[.: r.g+[.[.l.: : [.[.: K.S ].I.1 & e.I.K.K.: |.|.7 |.|.[.[.[.[.~+[. .| |+!+%+V.I %+2 [+9+H H '+H #+H '+H '+'+'+a+B 4+^.^.^..+)+)+B.k+C+#.G 6 i.G+P.H.b b H.b b b z+b b !+b b z+b z+z+z+a M n+*.e.a *.M M *.*.M M *.*.y.y.*.*.M *.e.e.1+*.$.*.*.*.M _ e.$.e.*.e.*.*.e.e.*. +$.Q.& & Q.& Q.Q.& Q.& & I.& 5+I.+.& & & 5+& 5+$.5+& Q.t.5+5+$.1+$.$.1+1+1+ + +[+1+e.e.5+5+$.$.& & & Q.& I.& Q.+.5+& I.Q.Q.Q.Q.Q.5+t.& $.5+& I.I.w.O O |+> w.Q.1+z.E+5 z.2 z.z.^ ^ ; ; 6 ]+c+@.E+M.f ]+]+o ]+]+]+]+]+]+]+]+]+]+S.3.f s.H L.L.L.L.g L.L.g h+* h+u+* * t * A.A.J j j.3 .l.] 7 d d Q q Q Q 0.. 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "1.u u u u 1.1.1.1.1.1.1.u u u u u 1.u 1.u 1.1.1.1.1.-.1.u u u u u 1.1.u u 1.1.1.1.u -.1.1.u u 1.1.1.-.q+-.1.-.-.-.-.q+4.4.4.4.4.4.4.4.4.q+-.-.) `.&.&.&.9 9 D D b+++B.G.G.o+A+b+.+^.B.++++(+#.n C+++@.#+C.C.Y.'+;+i.4+q.a+#+H .+@.6 s . .[.: 5+X.X.G+|+: [.[.[.l.|.[.|.|.l.r.l.g+[.l.g+: [.r.K.|+|+I.& O |+K.[.[.[.k.7 T.7 k.|.[.g+l.g+: r.K.|+r ^+%+=._+*.w+,+L.L.H C.C.,.9+C.p.L.H h+'+B 4+^.2.)+C+C+B.B.k+i.B.6 G+H+b b z+z+z+n+n+n+M y.R n+n+z+z+z+a M n+n+*.M *.1+*.*.*.a *.*.M a M *.*.*.*.*.*.*.e.e.1+_ e.*._ *.*.e.e.$.e.*.a *.*.a e.e. +& Q.& I.& & & Q.5+Q.Q.& & I.& Q.I.& I.& 5+$.5+$.& +& $.$.1+5+1+1+ + +1+1+1+ +1+1+e.e.e.e.& $.5+& & & 5+Q.& Q.Q.I.& +.+.Q.5+5+Q.& Q.5+Q.5+Q.+.I.w.O > |+|+O 0 $.R X E+5 5 5 5 ^ c+n.; (.]+c+3.w s.S.o ]+]+]+]+]+]+3.]+3.c+3.! 3.3.f s.L.L.L.L.L.h+h+g h+g * * * A.* ` * t u+V P [ l m+l.} d Q Q Q Q . 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "-.-.-.-.-.-.u u -.1.1.u 1.-.-.u u u 1.1.1.u 1.-.1.1.u u u u 1.1.1.u u 1.u 1.-.1.u -.1.1.1.1.1.1.-.-.-.-.-.-.-.-.q+-.4.4.4.4.-.4.4.4.4.4.4.4.4.4.`.) &.&.`.&.( b+8.8.++++k+A+^.}+2.:+>+b+D k+.+2.A+f+P.H L.C.p.Y.'+s.L.X w b 2 2 h.r ~+: [.|+P.k+6 *.r.: [.|.[.|.|.[.[.[.[.|.[.g+l.|.: [.: : r.x+S ].D.O ].~+: |.|.k.7 |.|.k.|.|.[.: : : .r.r.x 5+T a !+z+#+L.,+C.}+C.C.,.,.C.C.Y.}+B L.L.* '+a+4+^.! )+X.G+! ]+G+G+G+P.z+a n+M n+M M *.*.*.*.e.e.e.e.e.*.*.*.1+ + + +1+e.e.1+e.*.*.y.*._ *.a e.*.e.e.1+e.$.$.e.*.e.*.y.*.*.*.e.e.*.*.a *.*.*.e.1+Q.+.5+Q.+.I.I.& I.& Q.Q.Q.& I.+.& I.& & $.& $.5+$.$.$.5+5+$.$.$. + +$.$.1+ + + + +1+e.& 5+$.5+5+& & & I.Q.I.+.+.5+I.Q.Q.& Q.Q.Q.5+5+5+$.Q.Q.I.w.D.D.|+S |+O 0 _ _ E+f f f 5 1 f G+c+6 ]+c+G+H+f f ]+]+o ]+]+]+G ]+]+1 ]+]+! G+S.S.}+H H H H h+L.L.p.g L.* h+* * * ` * * t u+V U d+L .] d q Q 0.. . 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "-.4.-+-.-.-.u u -.1.-.1.u u u 1.1.1.1.1.1.1.1.1.1.u u 1.u u u u 1.1.u 1.1.1.1.1.u -.1.1.1.1.1.1.1.1.-.-.-.-.-.{ -.-.4.4.4.) 4.4.) 4.q+-.4.4.4.`.&.&.9 `.) &.9 >+D 8.b+*+9 8.@.4+H 8+C+^.:+( 8.H+2.*+< k+B ^.a+L.Y.L.s.b r ^+h.h.;.h.0+K.*.6 ++5 +.K.: l.[.[.[.[.|.|.[.[.[.[.|.[.l.|.[.: r.K.: x+: K.K. . .: |.k.k.|.7 |.|.|.|.[.g+l.r.: r. .l L p.p.R #+#+L.L.p.'+^.C.w+w+,.C.C.Y.2.4+L.H h+'+'+.+)+B.B.)+Z )+Z ]+G+P.b R *.[+e. +$.$.$.$.t.$.& Q.Q.$.Q.Q.Q.Q.$.Q.Q.& Q.$.$. +e.e.$.1+*.*.$.e.e._ 1+$.$.$.& $.$._ e.e.*.*.*.M *.*.e.*.e.e.*.e.e.5+5+Q.Q.& Q.& I.& I.& Q.Q.Q.& & Q.Q.+.5+5+$.5+& 5+5+5+$.$.5+$. +e.$. +$.1+$.1+1+$.1+1+e.$.5+& & & & & & +.& Q.Q.I.& I.5+I.Q.$.Q.t.Q.Q.Q.& & I.I.O 6+|+].].|+O 0 _ k R E+E+f 3.1 c+3.n.c+G+@.f f H+S.]+o G ]+o ]+]+]+]+3.]+]+! ! 3.@.f #+H L.L.L.L.h+L.h+g h+* * * * A.` * ` A.u+U [ 3 .] d q 0.. 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "4.4.4.-.-+1.u u u u u 1.1.-.-.1.1.u 1.1.1.1.1.-.1.1.u u u 1.u u u u 1.1.1.u u u 1.1.1.1.-.1.-.1.-.-.1.1.1.-.q+-.-.-.-.-.4.4.q+q+4.4.4.4.4.4.4.`.&.&.9 &.`.`.&.&.9 >+W ++i b+k+)+)+B.N.'+4 u.9 b+4+^.B 2.G.G R p.C.b ^+r h.h.;.;.;.h.> z+B.X.*.*.r.l.[.[.[.|.[.[.[.|.|.[.[.[.g+[.[.[.[.|.[.: K.S : : : [.|.|.|.|.|.|.B+|.|.|.|.[.: g+ .r. .r. .j.7+w+,.C.L.H L.C.w+,.w+w+,.w+,.,.p.L.L.h+h+'+'+4+R.^.^..+)+! G+]+G+G+H+z.e.$.$.Q.Q.Q.Q.Q.I.I.I.I.I.o.I.I.I.I.I.o.I.I.I.I.I.Q.Q.& t.$.$.& $.1+ +$.$.$.$.t.5+$.$.e.e.e.*.e.e.*.e.*.e.*.1+*.*.e.e.$.$.5+& & I.5+I.Q.+.Q.Q.Q.+.& I.I.& I.& & & 5+$.$.$.$.5+& $. +5+1+$.1+ +$.$.& $. +1+$.e.$.T & 5+5+Q.+.& I.& I.+.I.+.I.+.Q.Q.Q.Q.Q.& $.t.5+5+I.+.O O |+S S K.|+o.j ,+R X X E+5 f f 3.@.S.@.S.@.3.f f ! G G ]+o ; G ]+]+]+! ]+c+S.G+S.3.E+s.L.H p.L.h+p.g H Y.L.g * * * * * t ` * u+V U d+l l.} Q 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "4.4.1.-.4.1.{ u 1.1.1.-.) -+-.-.-.1.1.-.-.-.-.-.1.1.u u -.-.u u u u u 1.1.1.1.u 1.1.1.u 1.u 1.u -.-.1.1.1.1.-.-.-.-.-.q+-.4.4.4.4.q+-.-.q+4.4.4.4.4.`.&.9 9 &.`.z 9 D 8.i.J.< )+2.^.^.a+2.:+i+>+G+! .+^.:+D b L.w ^ ;.;.;.;.;.%.v.;.2 b P.e.Q.K.: |.|.|.|.|.|.|.|.g+|.g+|.g+l.[.[.[.|.[.[.g+K.|+k.~+[.|.|.|.k.7 |.|.B+|.|.|.g+~+g+g+o.Q.].F.U.l+7+7+7+w+7+w+Y.7+7+7+7+7+,.,.,.,.,.C.L.L.h+'+'+R.R.4+R.}+a+a+B }+P.E+b R $.Q.Q.Q.I.I.o.o.w.s o.O O O e O D.<+D.O s O s w.O o.w.w.I.0 Q.& Q.$.& & & & Q.Q.& & 5+$.$.e._ *.*.*.*.*.*.*.*.*.1+1+e.5+& Q.Q.& +.& +.Q.Q.I.I.& I.5+& +.Q.& 5+$.& 5+$.5+$.$.5+5+$.e.1+1+1+e.$. + +t.$. +$.$.1+5+5+& & & 5+Q.5+& & & Q.Q.I.Q.I.I.Q.Q.& Q.Q.& t.Q.Q.I.I.O O |+K.K.K.L w.j /+- #+s.M.s.f E+f E+f f f H+}+a+S.! o G G G G G ]+]+]+]+]+]+3.G+3.S.f s.H L.H Y.L.p.L.L.h+L.Y.h+* * * * * * ` * u+U P v F.] d Q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "4.-.) -.1.q+4.1.1.u -.`.`.-+1.1.1.1.1.u -.-.-.-.1.1.u u 1.u u u u u 1.u 1.1.-.-.-.1.1.1.1.u u -.1.1.1.1.u u -.-.1.1.q+-.4.4.-.q+4.-.q+-.4.4.4.4.4.4.) ) &.&.&.&.9 D 5.>+(+A+b+_.! ! 4+4+2.:+>+8.a+2.}+h+r+a+9+#+5 _+%.;.%.%.%.v.%+2 e.1 I.].r.l.[.[.|.|.|.|.|.|.B+|.|.g+] g+l.g+[.[.|.|.|.[.K.|+[.|.|.|.k.|.7 k.B+|.k.|.[.> C r C > 2+b |+ .e+7+w+w+7+7+d.7+7+,.,.Y.7+,.7+w+w+,.,.Y.Y.L.* * '+4+R.a+a+'+}+}+3.f E+b z.*.$.Q.Q.I.w.o.O D.D.x+x+2+|+|+|+|+|+].|+|+|+|+|+x+|+|+|+D.O O w.o.w.w.I.I.I.Q.Q.Q.I.Q.Q.& $.$.e.1+1+*.e.e.e.e.e.1+1+1+5+& & & +.Q.Q.Q.Q.Q.I.& & I.& Q.I.Q.& Q.& & 5+e.5+e.5+5+& 5+5+1+5+e.1+ +$.5+$.$. +$.1+5+5+& & & +.Q.+.& I.& I.+.I.+.Q.+.& Q.+.I.& & Q.Q.Q.Q.I.I.o.D.|+S S K.].x+o.0 C.9+s.s.s.f f s.E+3.E+a+}+a+}+f 3.]+]+]+]+G G ]+]+]+]+]+c+G+G+3.G+S.E+H H H L.H H Y.L.g p.g h+g g g * * * * * A.u+V U d+$+{.] q 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "4.-+4.4.4.-+-+-.1.1.`.`.-.-.1.1.-.-.1.u 1.1.1.-.-.1.u u u u 9.u u u 1.u u 1.-.-.q+-.-.u 1.1.u 1.1.1.1.1.1.u 1.1.-.u -.1.-.-.-.q+4.-.-.-.4.4.q+4.) ) 4.4.&.`.&.9 f+9 b+o+D b+8.#.i.^.a+a+4+*+( G+a+R.H L.L.'+#+#+1 ^+_+v.%.v.v._+^ }.P.O r.: [.[.|.[.|.|.|.|.|.|.|.|.|.|.|.7 |.|.|.[.|.|.|.[. .: ~+|.k.|.7 |.k.k.|.B+k.|.> +.h.h.;.h.> s D.<+7+7+7+7+7+7+7+7+7+7+7+,.7+,.7+,.,.,.,.Y.g g H * '+4+R.'+H H s.s.H.M.w R R _ t.0 w.w.o.O O D.|+|+].S K.K.K.K.K.K.K.K.K.K.K.S r.S x ].|+|+|+e x+D.O s O s o.o.w.I.I.Q.& & $.1+$.$.1+e.e.$.$.e.$.5+5+Q.Q.Q.& Q.Q.Q.+.Q.Q.I.Q.I.+.Q.Q.I.+.Q.$.5+& $.$.e.$.& e.& e.e.$.1+5+1+ +5+$.$.5+5+$.$.$.5+5+& & & & & I.& Q.& Q.I.Q.I.I.& Q.I.5+& Q.t.Q.Q.I.I.O D.|+S K.~+|+x+[ '.9+- H s.s.s.f M.'+f '+'+'+'+}+}+f S.]+]+G ]+G G ]+]+]+]+]+! G+3.@.3.f E+H H H L.L.L.Y.H Y.L.g L.L.g h+* * * * * * V J P d+v {.l.} q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "4.4.-+) ) 4.-.1.1.) &.4.1.1.-.-.1.u 1.-.1.1.1.1.1.1.1.u u u u u u 1.1.1.-.-.q+-.-.-.1.1.1.1.1.-.u 1.1.1.1.-.u 1.u 1.u -.1.-.-.{ -.4.4.4.q+q+-.-.q+4.q+`.&.&.9 >+(+( 5.D A+5.3+b+D i.i.H q.G.D Z H H h+'+s.r+f L.H+^ ^+h.v._+^+^ D.e.I.r.: : [.[.|.|.|.|.|.|.7 |.|.|.|.|.|.[.|.|.|.|.|.7 |.k.[.[.[.7 k.k.|.|.|.|.B+|.k.0+6+C r h.;.;.r > <+7+7+7+7+7+7+7+,.7+7+,.7+7+m 7+,.7+,.,.,.,.Y.Y.* * '+'+'+'+#+#+H w w #+R m._ _ Q.Q.I.o.o.O e D.|+|+S K.K.K.: : : : [.[.~+[.~+: : : K.: K.K.K.S S ].|+|+].|+x+D.D.O o.s I.I.Q.& Q.$.$.$.$.$.$.5+Q.& & & Q.Q.Q.Q.+.Q.Q.& Q.5++.Q.Q.+.Q.& Q.5+5+$.1+$.e.$.$.$.& $.$.$.1+1+$.$.$.$.5+5+$.$.5+$.5+$.5+& & I.& I.& I.& I.I.+.I.I.Q.+.I.& I.Q.Q.Q.5+Q.I.w.O |+S K.: : ].j.0 l+9+L.L.s.'+'+'+H }+'+H.H '+}+}+3.3.3.]+]+]+; ]+G ; (.]+c+3.c+]+1 1 H+}+f '+#+#+H h+p.g p.p.L.Y.L.g g g g h+u+* * * u+V J P [ v 3 F.l.} d 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "4.4.4.) ) 4.1.1.) `.4.-.1.1.1.1.1.1.1.-.1.-.1.1.1.1.u u u u u u u 1.-.u 1.1.-.-.-.-.1.1.u 1.4.-.1.-.u 1.u -.1.1.-.-.u 9.u -.) -.4.-.-.-.-.-.-.-.-.q+q+) 4.`.9 9 ( D 9 (+++A+J.*+G r+++6 J.( 8.@.M.H L.'+4+4+f H 3.^ ^+r r ^+2 & D.s K. .[.[.|.|.|.|.|.|.|.|.|.|.|.|.|.g+|.|.[.|.|.|.|.k.|.|.[.|.|.|.7 |.7 B+B+|.|.|.k.g+C r r ;.h.;.;.C e 7+7+m C.7+7+7+7+7+7+7+7+7+,.,.,.7+,.,.,.,.Y.Y.h+* '+'+'+H 9+9+#+9+R #+R R [+ +Q.0 w.o.o.O D.D.|+].].K.: : ~+~+|.|.k.k.k.k.T.|.|.k.|.|.|.0+: : g+: K.K.K.r.K.U.].|+D.D.O s w.w.I.I.Q.Q.Q.& & 5+Q.Q.I.5+Q.Q.I.Q.I.+.Q.I.Q.Q.I.Q.Q.I.I.5+I.& & 5+e.$.e.e.e.$.e.5+1+e.$.5+e.$. +5+$.5+$.e.$.$.$.$.& & 5+& Q.Q.+.I.+.Q.I.+.Q.I.Q.Q.I.& I.5+Q.Q.Q.I.I.}.D.|+S K. .: ].j.0 l+C.L.H s.s.H '+H '+}+}+N.'+'+'+}+3.f G+]+]+]+]+]+G G ]+c+3.n.! ]+f 1 H+E+E+H.#+H H L.H L.Y.Y.Y.Y.p.g Y.L.L.L.h+u+* * u+g V U P [ v 3 F.@ } q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "4.4.-+4.-.u -.q+) 4.1.4.{ 1.u 1.1.1.1.u -.-.-.1.1.1.1.1.u u 1.1.1.1.1.1.1.-.1.1.-.-.1.u u -.1.u 1.u 1.u u u u 1.1.u u 1.u 1.1.-.-.4.4.4.4.-.-.1.-.-.4.q+4.) &.&.&.9 9 8.#.^.B.b+D (+D f+>+G i.}+a+a+.+}+a+R.a+s.3.6 r r r ^+^ |+r. .r.r.l.[.[.|.|.7 |.|.|.|.|.|.|.|.B+|.|.g+|.[.|.|.k.|.|.|.[.|.|.7 |.|.k.|.k.B+|.k.T.> C r r h.;.;.;.r D.e+,.7+7+,.7+7+,.7+7+7+,.7+7+,.,.,.,.,.,.Y.Y.g L.L.* * L.L.9+9+9+9+9+[+[+_ +t.0 Q.I.w.o.O D.D.U.|+S S K.: : ~+|.k.k.B+B+D+B+D+D+Q &+&+&+7 T.|.k.[.[.: : : : g+K.K.x S |+|+g.D.O o.O }.I.I.I.I.I.I.Q.I.+.Q.Q.& Q.Q.I.Q.Q.+.& I.& & & & & & 5+5+5+$.$.1+1+1+$.$.1+$.1+$.5+5+5+$.5+$.5+$.$.5+5+$.5+& & I.+.I.Q.& I.+.Q.Q.+.I.I.I.5+I.& Q.Q.5+& Q.I.O O x+|+K.S K.|+o.e+,+Y.h+h+H s.H s.M.H.M.'+'+}+'+}+M.M.3.3.f ]+~ ]+]+~ ]+G ]+G+@.1 c+]+@.H+H+}+f H.N.#+L.Y.H p.p.g Y.Y.Y.L.g g h+g h+h+h+h+g g V J U [ d+3 K @ } d q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", ") 4.4.4.-+-.-+4.4.-.-.q+4.-.1.u 1.1.1.u 1.1.1.1.1.1.u u 1.1.u 1.1.1.1.1.1.-.1.1.1.1.1.1.1.1.1.u 1.1.1.1.u 1.u u 1.1.1.u 9.u u 1.-.-.4.4.4.-.-.-.-.-.4.4.q+q+`.&.&.&.&.D c+)+n >+8.C+G.f+i+++#.^.^.r+++E+s.}+'+s.s.G ^+r ^+6 a K. . .g.[.[.|.] |.|.|.|.|.|.|.|.|.|.|.|.g+|.|.|.|.|.|.|.|.|.[.: k.|.|.|.|.k.|.k.|.|.k.~+> h.;.;.;.;.;.;.h.}.l+7+7+7+7+7+7+7+,.,.w+,.7+,.7+7+,.,.,.,.,.,.Y.g p.H L.L.C.C.[+9+9+9+,+/+/+t.'.Q.I.o.o.o.O D.D.|+].K.K.K.: : [.k.|.k.B+B+D+Q Q D+0.0.0.0.0.D+D+D+&+B+k.|.|.[.[.[.: : : K.K.K.|+].|+x+|+D.O s o.s I.o.o.I.I.I.I.Q.Q.+.I.Q.I.I.I.I.I.I.+.& & & $.$.1+1+$.1+ + +$.1+5+$.1+$.$.$.& & $.$.$.1+$.e.& & I.& Q.+.I.I.+.Q.I.I.I.Q.I.Q.}.& I.+.I.Q.Q.Q.+.I.I.O O > D.x+O Q._ #+E+}+}+'+s.}+H H '+H.'+E+H H '+'+E+f f 3.f 3.c+]+]+]+~ G G (.]+@.@.c+1 @.1 E+f E+E+w H L.Y.L.Y.p.Y.Y.Y.Y.L.g L.g g h+g h+h+h+g g J m P d+3 {.@ } d d Q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "4.) ) ) 4.4.-.-.1.-.4.) 4.1.u u u u 1.1.1.1.-.-.-.-.1.1.1.1.1.u 1.1.u 1.1.u 1.1.1.-.1.1.1.u u 1.1.1.1.u -.u u 1.u -.1.1.1.u 1.-.-.4.4.-.q+4.4.-.-.-.) ) 4.4.4.`.&.`.`.&.i+( 9 >+D k+*+f+W 3+G+'+R.q.a+^.7.a+s.'+#+G+2 r ^ G O : l.U.y+g+[.[.|.|.|.|.|.|.|.|.|.|.|.|.|.[.[.|.|.|.|.|.|.[.[.: [.|.k.7 |.|.|.|.|.7 |.k.0+> ;.=.=.=.%.;.;.h.+.l+7+,.7+7+7+7+7+,.H ^.w+7+7+7+7+,.7+,.,.,.Y.Y.Y.Y.L.Y.p.C.,+,+,+/+'.[+'.t.Q.Q.0 Q.w.o.O O D.|+].|+K.S K.: : : [.k.B+B+D+B+D+Q 0.0.0.t+t+0.. . 0.0.0.Q 0.Q Q &+T.k.|.[.|.~+: : K.r.S ].S x ].|+D.D.O s o.s I.o.w.s I.I.I.+.Q.5+I.& Q.& I.& 5+5+5+5+$.1+1+1+ +5+5+$.e.$.$.& 5+$.5+5+1+5+$.5+& & & & I.I.& & I.Q.I.I.+.I.I.+.I.Q.I.Q.Q.Q.& Q.Q.Q.& I.& & $.1+1+R a+B.++J.J.A+++k+B.]+^.@.a+}+}+}+3.N.s.'+f f E+f 5 3.n.]+]+]+(.6 G (.G+c+G+G+c+@.1 E+H+E+H.#+#+#+L.p.L.Y.p.p.C.L.Y.Y.- h+h+g g g h+u+g g Y.U F+$+K F.@ ] d q q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "q+4.-+4.4.4.-.4.4.4.4.4.1.u 1.1.u u 1.1.u u 1.1.1.1.-.1.u 1.-.-.-.1.1.1.1.1.1.1.1.-.1.1.1.1.u u u 1.1.u u u u 1.1.1.-.1.1.1.1.-.q+-.4.-.4.4.4.4.4.) ) 4.) `.) ) ) ) `.z 9 9 D D b+D f+>+b+G H+w '+'+a+^.a+)+)+X L.G+r 2 k+2 : : l.g.o.[.|.|.|.|.|.|.|.|.|.|.|.g+B+|.|.|.[.|.|.|.[.[.[.|.[.[.|.|.k.|.[.[.|.7 |.|.|.k.g+> h.=.=.=.=.%.;.%.r H.p.7+7+7+7+7+7+7+,.p.7+,.,.,.7+,.7+,.,.,.,.Y.Y.C.p.C.,+,+w+/+/+/+t.t.t.'.Q.0 Q.0 w.o.s D.D.D.|+|+K.K.K.: ~+k.[.|.T.B+B+Q D+Q D+t+0.. 0.0.0.. . . . . t+0.0.0.Q D+D+&+B+|.|.|.[.: ~+: K.K.K.K.K.].|+|+x+|+g.D.O o.o.o.o.o.o.I.}.I.I.& I.& +.& $.5+5+$.$.$.$.$.$.5+5+& $.5+& 5+& & $.5+e.e.$.5++.& & I.I.& I.I.I.I.I.I.I.I.+.I.+.I.I.Q.I.Q.Q.Q.& +n+H H.@.G+B.i ;+:+>.E E = z 9 o+D 3+++B.! a+'+}+s.H s.f E+f f f 1 G+]+]+6 ; ]+G ]+c+G+G+c+G+G+1 @.H+E+w #+L.L.L.p.L.p.Y.9+p.Y.g Y.g - g - h+- h+g g g ,.F+$+' {.@ ] } d d q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "4.4.) ) 4.-.-.-.-.4.-.-.-.u 1.1.u u u 9.u u u 1.-.-.-.-.1.1.-.-.1.1.u 1.-.1.1.u -.1.1.1.1.1.1.-.-.-.-.1.1.u 1.-.-.-.-.-.-.1.-.-.-.4.4.q+q+4.4.4.q+4.-.-.-.4.) ) `.) `.&.9 9 z (+b+o+i+b+++A+8.i.}+}+a+4+a+4+o w #+1 2 2 W D.: |.l.<+g.g+|.[.|.|.&+|.&+|.|.|.|.|.g+|.[.[.|.g+[.[.g+: |.[.|.[.|.|.|.|.[.[.|.|.|.|.|.[.g+> r =.=.=.=.%.%.%.;.a l+7+7+7+7+,.7+7+7+7+7+7+7+7+7+,.,.,.,.,.Y.,.,.Y.C.C.w+/+/+l+l+/+/+'.t.0 '.Q.0 I.o.w.o.O D.|+|+].K.K.: : : : |.k.T.B+B+D+Q Q 0.0.0.t+. . . . . . . . . . . . . . 0.t+Q D+Q D+&+B+|.[.|.[.: : : K.r.K.K.].].].U.|+x+D.D.s D.s w.w.}.}.I.I.Q.& Q.& t.5+$.5+1+$.5+$.& 5+& & & & & & 5+$.5+$.$.$.5+& Q.& I.+.I.+.I.+.I.Q.Q.I.I.Q.I.I.I.I.Q.Q.Q.Q. +M 4+^.^.2.J.;+:+u.E A 8 !.!.8 !.8 { 4.z f+b+B..+H s.H s.s.s.s.f f f 1 n.]+]+G ; ]+; ]+]+c+G+G+c+G+G+@.}+H.N.#+#+m.C.p.Y.p.Y.9+Y.Y.Y.Y.g L.g g g - g Y.Y.U F+).K K @ @ ] ] d d q Q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "4.q+4.4.-.q+q+4.-.4.-.u 1.-.-.-.1.1.1.1.u u u 1.-.-.-.1.1.u 1.u u 1.u u 1.1.-.1.-.1.1.1.1.-.q+-.1.-.-.4.q+-.-.-.1.-.q+1.-.1.-.-.-.-.{ -.4.q+-.4.q+-.-.-.-.4.4.`.&.{+z &.z 9 9 z 9 z i+(+o+>+_.k+#.S.q.o s.w 2.++H+@.2 c+5 : : [.: y+x+: |.|.|.|.g+B+|.|.&+|.g+|.|.g+g+g+g+[.[.[.|.: [.[.[.[.[.~+[.|.|.[.|.|.|.[.|.[.g+> C ;.%.=.=.%.=.%.%.r t.7+7+,.7+7+7+7+7+,.7+,.,.,.,.7+,.,.,.,.,.Y.C.Y.,.C.w+/+w+/+/+l+'.t.'.j Q.Q.0 I.w.o.o.O D.x+|+].S K.K.: [.~+|.|.T.B+B+D+D+Q Q t+0.0.0.. . . . . . . . . . . . . . . . 0.t+0.t+0.Q &+&+B+k.|.k.[.[.: : .K.K.K.K.K.].].x+|+x+|+e O O w.}.w.I.Q.+.Q.Q.& & 5+$.Q.Q.& & I.Q.+.& Q.& & 5+e.e.5+$.& & & +.Q.I.I.I.I.I.I.I.I.I.I.Q.Q.Q.& I.5+I.Q.Q.*.P.^.2.2.7.b.p+>.= A 8 u 9.9.9.9.9.9.9.!.~.z G.B.a+'+H H s.s.X X f f f 1 ]+; G ]+(.]+; G ]+1 G+c+]+@.@.3.f E+#+#+#+L.p.9+9+L.9+C.9+C.C.g 9+g Y.L.Y.Y.Y.m 7+d+$+K {.@ @ ] ] d d q q 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "-.-.4.4.4.4.-.4.4.-+4.-.1.1.1.1.1.1.1.1.1.1.1.-.-.-.1.u u 1.-.-.1.1.q+-.1.-.-.-.1.1.1.-.-.-.1.u u u q+-.-.-.q+-.1.1.-.1.1.-.-.-.4.) 4.q+-.-.4.-.-.-.-.4.q+4.) `.`.&.&.{+D A+o+9 9 &.9 i+( ( i+++B._.i.B.i.1 C+5.G H+2 6 }.~+[.|.: <+g.g+g+|.|.|.7 g+B+g+|.|.] g+[.g+W.> W.g+s e.g+[.[.: [.[.[.[.[.[.[.[.[.l.|.[.m+L e+}.<.h.;.%.=.=.%.%.%._+1+7+7+7+7+7+7+7+7+7+,.,.p.,.,.m 7+,.,.,.,.Y.,.C.C.C.,+l+l+l+'./+l+t.t.t.0 Q.Q.0 w.o.O s D.|+|+S K.K.: : : [.|.k.k.&+&+Q 0.D+0.0.0.0.. 0.0.. . . . . . . . . . . . . . . . . . 0.. . 0.t+Q D+B+&+T.T.k.|.|.[.[.: : K.r.K.K.x ].|+|+x+D.e O O o.w.I.I.I.I.Q.Q.& Q.Q.I.Q.+.Q.& & & & & & $.$.5+& I.& Q.+.Q.+.I.I.+.I.I.I.Q.I.I.I.I.I.Q.I.Q.& 5+n+4+C+i 7.;+:+p+s+A 8 !.9.9.9.9.9.9.9.9.9.9.A >.b+^.s.L.L.H #+s.s.X f 5 f c+G W G 6 ]+G 6 ]+G+]+c+]+]+1 H+H+}+w #+L.L.L.L.p.9+p.L.Y.L.L.9+Y.L.C.Y.Y.Y.C.J P v p K {.@ @ ] } } d d q Q 0.0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "4.-.-.-.-.4.-.4.q+4.-.u 1.u u u q+4.1.1.q+-.1.-.-.-.-.-.-.1.u u u 1.1.4.1.q+1.-.1.1.1.-.-.-.1.1.1.u 1.1.u u 1.q+q+-.-.1.q+q+-.-.4.) -+-.4.-.-.-.-.-.-.-.4.4.4.) `.&.`.9 i+(+o+9 z &.&.i+D o+( 8.++b+b+8.b+b+o+b+H+H.G+(.].: [.[. .g.L r.g+g+|.|.|.|.] |.|.g+g+g+r.}.&.q+{+=+|+K.~+[.[.: [.[.[.[.l.[.[.l.l.[. .L e+w+l+0 <.r ;.%.=.=.=.=.%.%.r l+7+7+7+7+,.,.H 7+7+'+g 7+7+7+,.m ,.Y.,.Y.,.C.C.,.C./+w+/+l+/+'.t.j t.Q.0 Q.I.o.o.o.D.O x+U.|+S K.S : : [.|.k.7 B+B+&+Q Q 0.t+0.t+. . . . . . . . . . . . . . . . . . . . . . . . . . 0.t+0.t+0.D+D+q T.|.B+|.|.|.[.: : : : K.K.K.S ].|+|+D.O D.s o.O }.w.}.I.I.I.I.+.I.Q.& & & & 5+& 5+& & Q.+.Q.I.I.+.I.I.I.I.Q.I.I.I.Q.+.I.I.Q.I.I.Q.$.n+4+i :.:.*+p+>.s+8 !.9.9.9.9.9.9.9.9.9.9.9.!.E o+B.'+#+L.H #+s.E+#+s.f f c+G ; G 6 (.G 6 ]+G+G+]+]+]+@.H+f }+s.#+#+#+m.H #+L.L.9+9+9+Y.9+C.Y.Y.Y.k C.J w+F+$+p @ @ ] ] ] } d d d q Q . 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "-.-.-.-.-.-.q+q+{ u u -.1.1.-.4.4.-.1.1.4.-.-.-.1.u -.-.1.u u u -+{ -.1.-.-.-.u -.1.-.-.-.1.-.1.-.u u u u u u -.4.q+-.4.4.-.4.4.-.4.) 4.-+-.-.4.-.-.4.4.4.4.4.4.-+) `.9 f+9 9 >+9 -+>+b+D b+J.f+(+b+o+D A+J.D G+}+'+i.5 K.: [.[.: U.|+r.r.g+[.g+|.|.g+|.|.[.r.1 +. +z i+Z x+S K.K.: : |.: [.|.[.[.[.m+r.r.3 d+7+w+7+7+l+}.C ;.;.=.=.h =.=.%.^+t.7+7+7+7+7+7+,.7+7+,.7+,.m ,.,.,.,.,.,.,.Y.C.C.C.w+w+l+/+/+'.l+'.t.Q.'.0 0 Q.w.w.o.O D.|+|+].K.K. .~+: [.[.|.B+&+&+Q D+D+Q 0.0.0.0.t+. 0.. 0.. . . . . . . . . . . . . . . . . . . . . . . 0.. . . 0.0.0.D+0.B+&+B+k.|.[.[.[.: ~+K.g+K.K.W.].|+|+x+D.D.O D.O s w.s o.I.I.I.I.& & & & Q.& I.I.Q.+.+.I.I.I.+.I.I.I.I.& I.I.I.I.5+I.Q.Q.I. +z+^.C+J.;+:+p+= x.A !.9.9.9.9.9.9.9.9.9.9.9.9.~.f+++}+H L.L.#+#+s.s.w E+f ]+; G G G G G G ]+]+]+c+]+G+@.3.f }+H #+#+H #+L.#+m.#+#+#+#+m.#+L.L.C.C.Y.C.w+j [ 3 K @ @ ] ] } d d d q Q Q Q 0.0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "`.4.4.4.4.4.-.4.4.1.u -.4.-.u 9.1.1.-.1.-.q+-.-.-.-.1.-.1.1.-.-.) -.-.-.-.-.-.1.-.-.1.1.-.1.-.u 1.-.1.u u u 1.1.-.4.) 4.) 4.-.4.4.4.) ) ) -.-.4.-.-.) `.4.4.4.4.) ) `.&.9 z 9 >+9 z i+>+( W B.^.r+J.A+)+B.C+_.]+E+}+! $.K.: : l.r.U.x+x .g+g+l.|.|.|.g+[.g+U.C+|+U.2+x S x |+e S g+ .: K.[.|.[.l.m+y+e+7+e+7+7+w+7+w+7+Q.C r ;.%.=.h =.=.=.;.1+e+e+7+7+7+7+7+7+7+7+7+7+7+7+7+,.,.,.,.,.,.C.C.C.w+w+/+l+/+t.'.'.'.t.Q.Q.0 I.o.o.o.D.O D.|+|+K.S .: ~+~+|.|.k.B+B+Q Q D+0.0.0.. 0.0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 0.. t+. t+0.Q Q B+B+B+|.|.|.0+: : : g+K.K.K.K.].|+|+x+|+D.D.O s O I.}.I.I.I.+.Q.Q.Q.Q.Q.Q.Q.I.+.I.I.I.I.I.I.+.I.5+I.I.Q.I.I.Q.I. +z+4+i ;+*+:+N = x.8 !.9.9.9.9.9.9.9.9.9.9.9.9.{ u.A+B L.h+H H L.s.s.E+E+c+]+G G ; G G G ]+]+S.]+]+]+G+G+3.f }+s.H #+#+#+w H.E+P.w b w m.- 9+#+- 9+C.J l+0 j.3 {.@ @ d } d d d q q Q 0.0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "q+4.-.q+4.-.-.-.-+4.4.4.{ u u u u u 1.-.-.-.-.-.-.-.q+-.1.-.-.`.-.1.1.1.1.1.1.-.1.1.1.1.1.-.1.1.-.1.1.1.u 1.u 1.-.q+`.) &.4.4.q+-.q+) &.`.-+4.-.-.q+) `.`.) -.4.) &.`.&.&.&.&.9 f+9 z i+D 8.B.o J.D k+6 n 8.k+k+#.G+! I.S r.: : K.].|+r. .r.g+g+g+l.g+[.[.[. .r.S K.K.K.K.K.K.|+].K.K.: : : |.k.l.[ ,.'+w+l+7+w+C.7+7+l+t.+.r ;.%.%.h h =.%.%.r 7+7+7+7+7+7+7+7+,.7+7+,.7+,.,.7+,.,.,.C.C.C.C.C.w+w+l+/+l+/+t.j t.Q.'.0 Q.0 I.w.o.O D.|+|+].S S : : : [.|.k.k.B+&+D+D+Q 0.t+0.t+. . t+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . t+0.t+t+0.Q B+B+B+|.k.[.[.~+: .g+r.K.r.].S ].|+x+D.D.O s w.s I.I.I.I.I.w.I.I.I.I.I.I.+.I.I.Q.I.I.}.Q.I.I.I.I.I.}. +p.4+C+J.*+p+N x.~.A !.9.9.9.9.9.9.9.9.9.9.9.9.{ f+++}+s.L.#+#+s.H w f E+c+G G G ]+6 G W ]+G+]+]+]+]+S.3.a+3.s.H L.L.w P.P.1 1 G+c+1 1 P.P.w m.m.9+,+,+w+[ j.K F.@ } } d d d q Q 0.0.0.0.0.0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "4.-.-.-.4.-.4.-.4.4.q+-.-.u u 1.-.-.q+-.1.-.-.-.-.4.4.-.1.-.1.-.1.-.1.-.1.1.u -.1.1.1.1.1.1.-.1.1.1.-.-.1.1.1.1.-.-.) q+-.-.-.4.4.4.4.4.4.) 4.4.4.4.`.`.`.4.q+q+) `.&.&.9 &.9 i+z 9 9 9 >+8.8.]+4+B.;+8.o+b+b+b+k+B.G+w.|+K.r.: : K.].K.r. .l.g+g+l.g+[.[.[.: .g+K.K.K.K.K.K.].|+K.K.: [.: : |.: 3 e+w+7+7+7+7+7+7+7+w+l+Q.+.h.;.=.=.=.=.=.%.^+Q.7+7+7+7+7+7+7+7+7+7+7+7+7+,.7+,.,.,.,.C.,.C.C.,+w+l+w+/+l+'.t.l+j Q.Q.Q.0 w.o.o.O D.x+|+|+].K.K.: : ~+[.k.k.B+B+q D+Q Q 0.t+0.0.. 0.. 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . t+t+0.D+D+B+&+B+k.|.k.[.|.: : : .r. .r.K.S |+|+|+D.D.O O o.O }.w.I.I.I.I.I.I.I.I.I.I.I.Q.I.I.Q.Q.}.w.I.I.5+z+4+r+;+:+p+= x.A 8 !.9.9.9.9.9.9.9.9.9.9.9.9.{ f+C+N.H L.h+H #+s.s.'+E+c+G ; G G W G G G ]+G+]+]+]+! 3.3.a+s.s.s.w w 1 1 c+c+c+c+c+c+1 1 P.P.n+R 9+,+/+0 j.{.@ ] } d d d q q q Q 0.0.0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", ") 4.4.4.-.-.-.4.-.-.u u -.-.1.-.1.1.-.-.-.-.-.-.q+4.-.-.-.1.u u 1.1.-.1.1.1.1.u 1.1.1.1.1.1.-.-.-.-.1.-.1.1.-.-.-.q+-.-.-.-.-.-.-.q+4.) &.&.&.&.) 4.`.&.) 4.4.4.4.`.) `.&.&.i+9 9 9 9 9 9 ( (+++#.B.^.B.)+^.2.++! i.G+<.|+K.K.: K.K.K. .g+: g+m+g+l.g+[.|.|.|.[.x+S K.: .K.K.K.].].|+K.: [.[.g+[.: 3 7+7+,.7+7+w+7+w+7+w+/+C r ;.%.%.h =.=.%.h.t.7+7+7+7+7+7+7+7+7+7+7+,.7+,.,.,.,.,.C.,.C.C.C.C.,+,.l+t./+l+t.t.Q.'.Q.0 I.o.w.o.s O x+|+].K.S : K.: : |.|.k.B+&+q D+D+0.0.0.0.. 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . t+0.0.Q &+q B+B+k.k.k.[.[.: : g+r.K.S ].|+U.x+x+D.D.D.O y+O o.w.o.o.I.I.I.I.}.I.I.I.I.I.s O w.Q.n+B C+:.:+N s+A 8 !.!.9.9.9.9.9.9.9.9.9.9.9.9.x.o+B.'+L.H #+H s.s.w E+@.]+]+G G G ; G G ]+]+]+]+o G+S.@.}+f H.#+b w P.1 1 1 c+^ ^ ^ 1 ^ 1 1 P.5 #+,+,+j [ L .@ } d d d Q q Q Q Q 0.. . 0.0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "-+4.4.4.4.4.4.4.-.-.1.1.) -+-.-.-.4.q+-.-.-.-.-.4.-.1.u u u 1.1.1.1.1.-.1.u 1.1.1.1.1.1.-.1.-.1.-.-.1.1.u 1.-.4.4.1.1.-.-.-.-.-.-.-.4.&.`.&.9 &.`.`.`.`.`.4.) `.) `.&.`.) -+9 &.9 9 ( 9 9 9 i+8.G i.^.++A+_._..+#.B.G+w.|+K.K.K.K. .: K.K. .g+ .g+: l.|.[.k.|.[.Q.& S g+K.K.g+K.K.K.|+U.K.l.[.[.: |.l.v e+7+7+7+7+7+7+7+7+l+ ++.;.%.%.=.=.=.=.%.e.l+7+7+7+7+7+7+7+7+7+7+7+7+7+7+,.C.,.C.,.C.,.,.C.,+C.,.l+/+'.l+'.t.Q.0 Q.Q.w.o.o.D.D.D.|+|+].K.K.~+: [.k.|.k.B+&+q D+B+~+g+K.|+O O O e K.K.k.B+t+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . t+t+0.Q D+B+B+B+k.|.[.k.: : : : K.K.K.K.].|+].|+x+x+D.D.O s O o.o.o.I.o.I.}.w.w.O O O I.*.B C+;+:+= s+8 8 !.9.9.9.9.9.9.9.9.9.9.9.9.u E b+)+H H h+L.L.H '+s.f @.6 G ; G G G W G ]+c+]+]+o G+S.S.3.3.'+#+w P.P.5 ^ !+^ !+^+^+5 ^ ^ 5 5 P.b n+/+j [ 3 l @ ] d d d d d q q Q Q 0.. 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", ") ) ) 4.4.4.-.-.4.4.4.4.4.q+-+4.-.-.4.-.-.4.4.-.-.-.u u u u 1.1.1.u 1.1.1.-.u 1.1.1.1.-.u 1.u -.1.1.-.-.-.-.-.4.-.-.-.1.-.-.-.-.-.-.4.q+&.-+) &.9 `.&.&.&.-+4.) &.&.`.&.`.`.&.9 9 9 >+D ( 9 9 9 (+++++B.++J.++r+++G+G+<.|+K.K.K.: K.K. .: K.K.: : : g+[.[.|.|.[.r.z.+.S : K.K.S K.S K.K.: g+[.[.: g+l.r.l+'+/+7+7+7+7+7+7+w+ ++.r %.%.=.h h =.%.r 7+7+7+7+7+7+d.7+7+7+7+7+,.,.,.,.w+C.,.C.C.C.C.C.C.,+,+C.,+w+t.j '.'.'.0 0 I.w.O o.O D.|+|+S K.S .: : [.|.: & X.c.9 i+i+c.8.k+(.(.(.(.; 6 8.8.j+8.W 6 b I.: . . . . . . . . . &+q &+q &+q &+q &+q &+q &+q &+q D+B+q D+B+q D+B+q &+q D+B+B+&+B+&+B+B+T.q t+t+0.0.Q &+: g+: S K.K.K.].|+K. .K.r.].S U.].x+U.D.D.D.D.O s D.O e o.I.I.I.& z+X.C+*+p+= A 8 !.9.9.9.9.9.9.9.9.9.9.9.9.9.1.z b+.+'+H H H H #+#+f E+G+G W G W _.W W G ! ]+o ]+! ! S.a+3.'+E+s.w H.P.^ 5 ^ ^+^ ^+!+^+^+2 ^+5 5 b z.[+t.0 3 F.@ } } } d d d d q d q q Q 0.Q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "q+4.4.) ) ) 4.4.4.-.4.4.-.-.-.4.4.4.q+-.-.-.-.-.-.-+-.1.u 1.-.1.1.-.-.1.1.-.1.1.1.1.1.-.-.-.u -.-.1.1.1.-.-.-.-.-.1.4.&.-.-.-.-.4.q+4.q+`.`.4.) &.&.&.&.&.&.`.`.&.&.&.9 &.&.&.9 D ( i+i+( 9 9 D G B.B.E+'+4+C+D 5.G G++.|+K.: K. .: : .: : .: : g+[.[.~+[.[.[.[.L R +.S K.K.K.x |+S K.g+ .: |.[.g+: l.2+w+7+7+7+7+7+7+7+7+l+Q.T ;.%.%.h Z.=.=.^+t.7+7+7+7+7+7+7+7+,.,.7+7+7+,.,.,.w+,.,.Y.C.C.C.C.C.C.C.,+C./+/+'.t.'.Q.0 I.o.o.O D.D.|+|+].K.K.~+: K.z.i+`.j+!+}.2+2+e g.| | e e e 2+2+| 2+e e | 2+g.+.!+c+W 6 1 t+. . . . . 4.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.c.!+Q . t+. t+0.c D c.c.c.c.c.c.c.!+: l.: .g+K. .].S U.U.|+2+|+g.x+x+O ( 9 c.c.c.c.D c.k+*+s+A 8 !.q+c.c.D c.c.c.c.c.9 9.9.9.{ f+++4+H H h+H '+h+#+f @.z i+(+(+(+(+(+(+; f ]+! ]+3.G+3.3.3.}+E+#+w E+b 5 (.q+c.c.c.c.c.8.r !+^+2 b z+_ 0 j.L F.@ ] d ] } } ] ] 7 ] } 7 q Q q Q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "-.4.) ) 4.4.4.4.4.4.-.-.4.4.4.q+4.-.4.-.-.1.1.1.1.1.-.q+-.1.-.u 1.1.1.1.1.-.-.-.u -.u 1.1.1.1.1.1.-.-.-.-.-.-.-.4.-.-.) -.4.-.-.-.-.4.4.4.`.4.q+`.( 9 `.`.`.`.&.9 9 9 z 9 9 ( >+i+i+9 >+9 z 9 i+j+G+}+s.a+)+n G.k+b+G e.|+S K.: K.: : : : K.: : l.: : : [.~+|.|.|.[. .R & |+S K.].S K.K. .: [.[.: : r.[.l.U.d+7+7+O.7+7+P 7+7+0 <.h.%.%.=.h h =.;.[+l+7+7+e+7+7+7+7+7+7+7+7+,.7+,.w+,.C.C.C.C.Y.Y.C.C.k C.C.k k _ ,+/+'.'.Q.0 0 w.o.O D.x+x+S K.K.K.c+) c.e.e 2+2+2+| | 2+e 2+g.e e g.2+2+2+| g.e 2+2+e g.g.2+2+| 2+g+. . . . . i+2+2+2+| 2+e 2+2+g.e e 2+2+2+| 2+e 2+2+g.e e 2+2+2+| | g.2+2+g.e e 2+2+2+B+. . . . . c.e 2+2+2+| | g.2+2+[.k.|.|.[.: : : K.K.K.].K.].].].2+8.i+e g.2+2+g.e e 5+*+s+8 !.9.q+2+e e e 2+2+| | }.u 9.9.-+D C+B '+H s.H H s.s.f 1 q+e 2+|+| |+D.2+|+T G+]+]+S.! 3.S.}+3.'+s.b H.P.b c.X.| g.g.2+g.e r 2 2 5 2 z.y.'.y+3 {.@ ] ] } @ m+F.K.l . . .l.] 7 d Q 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "4.q+q+4.4.4.4.4.4.4.4.-.q+4.-.-.-.u 4.-.-.-.1.-.-.-.-.1.1.9.u 9.u u u -.1.-.-.-.-.-.u 1.-.-.1.1.-.-.-.1.-.-.4.-.-.1.-.-.-.q+-.-.-.-.4.4.4.q+4.4.`.9 &.) `.&.{+z &.i+D o+f+9 9 9 9 9 ( D >+( f+( i+8.]+)+J.(+8.G.G .+#.a O K.K.g+K.: .: : K.K.K.: : [.: : ~+[.|.|.[.[.: o.x+|+S K.].K.S K.g+g+: : l.| e : .3 e+7+e+7+F+7+7+e+l+I.T h.%.=.h Z.=.%.1+e+7+7+e+7+7+7+7+7+7+7+7+7+7+,.w+,.,.,.Y.C.C.Y.L.C.9+9+9+9+9+9+_ _ /+/+'.Q.0 o.o.o.D.x+|+|+K.*.) c.}.e 2+e e g.e e e e e e g.2+g.g.g.e e e e e e e 2+2+g.g.e e e W.. . . . . >+g.e e e e e e e g.2+e 2+e e e e e e g.g.2+e g.e e e e e e g.g.2+g.g.e e B+. . . . . c.e g.e e e e e e e D+D+B+B+B+k.|.|.|.: : : : K.: g+G+&.}.e g.e g.2+g.W.t+}.x.8 !.9.9.}.g.2+e g.s e e e (.9.u `.b+)+H '+H s.H s.H.w f G {+g.e s e e e e e x E+G+! 3.S.3.3.a+3.H '+w w 5 !+&.e.e e e e g.| t+2 2 b 5 z.[+j v l l @ ] ] l.l L L |+O x+O |+|+ .[.] d q 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", ") 4.{ 4.4.q+q+) -.-.q+{ -.1.u 1.1.-.4.q+-.-.4.-.4.4.1.-.-.u u 4.1.u 1.1.1.1.-.-.1.u 1.1.1.u 1.-.1.1.1.-.-.-.-.-.-.-.-.-.4.-.-.-.4.q+4.q+4.4.4.) ) 9 z ) 4.9 9 9 ( (+k+^.J.o+9 9 &.&.9 >+D D D >+9 D 6 ++b+A+J.b+n Z ]+z.C |+K. .: . .: : K.U.S K.: : : [.: : 0+|.|.[.[.: D.> ].S S K.K.K.r. .: : : K.L g+[.m+<+F+7+7+e+7+7+7+e+e++.h.%.=.=.Z.y %.r e+7+7+7+7+7+7+7+7+7+7+7+7+,.w+,.,.,.C.C.C.Y.Y.Y.L.L.L.L.L.- 9+- k _ U $.'.'.Q.0 w.o.D.x+x+6 ) !+g.e g.| 2+2+g.}.}.}.g.2+e g.| 2+2+2+}.}.}.g.2+e e | 2+2+2+}.}.}.W.. . . . . >+2+e }.}.e 2+g.g.2+2+2+2+e }.}.e 2+g.e 2+2+2+2+g.}.}.e g.2+e 2+2+2+2+g.}.k.. . . . . c.2+2+2+}.}.s g.2+e D+0.t+0.Q Q Q B+B+B+k.|.[.[.: e.q+T e g.2+e g.| | t+r.p+~.!.9.9.9.1 | 2+2+2+e }.}.g.+.9.1.u.b+.+'+H '+H s.H M.}+P.b+W 2+e }.}.e 2+e <+> $.G+S.3.S.a+@.a+a+a+H+s.w H.P.q+}.e g.2+e 2+W.|.2 2 2 z.z.*.Q.j.L F.@ @ @ {.3 O O j.w.w.w.6+O |+K.: ] d q Q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "`.`.4.4.4.4.4.4.-.1.-.-.u -.-.u u -.4.-.4.-.q+&.4.u u 9.u -.q+-.1.u u -.1.1.-.-.1.1.-.1.-.u u 1.-.-.-.-.-.-.-.q+-.1.-.-.4.4.-.-.-.-.4.4.4.q+4.q+`.&.`.`.4.&.i+9 (+k+k+C+++G.&.z &.9 9 ( (+A+*+9 >+i+D 8.4+i B.B.7.G.6 P.& > S .: : : : [.: : K.: : : : [.[.: : [.|.[.|.[.r.I.O S K.S K.: K.K.r.: : l.: .[.l.r.$+7+7+7+w+w+7+l+e+0 T h.=.=.h h =.^+0 7+7+e+7+F+7+7+7+7+7+,.7+,.7+,.,.,.,.Y.,.Y.C.Y.g Y.L.- L.#+L.L.L.R C.k _ _ '.0 0 w.j.O < {+}.g+| e g.2+2+| 2+}.e e x | e g.2+2+| | }.e e | | g.e 2+2+| | s e e g+. . . . . o+| s }.g.2+| g.g.2+2+2+| e e s 2+| g.e 2+2+2+| e }.e 2+| 2+e 2+2+2+| e s B+. . . . . c.2+| g.s e 2+| 2+g.D+. . . t+0.t+t+Q Q B+D+B+B+s q+e.}.e W.| e g.| &+k.A+z A !.9.9.9.c.g.2+2+2+s e e | g+1.4.f+C+4+H H s.H H #+#+}+@.&.a | e e s 2+r.g.e 2+w.G+3.3.S.a+R.! ^.R.^.S.H.E+k+i+e 2+| 2+e 2+k.2+5 2 2 z+z._ 0 L l F.m+] m+L L j.w.w.$.$.$.& w.O |+K.: } d q Q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "4.4.) 4.q+{ 1.q+-.4.) { 4.4.u 1.q+q+4.-.q+4.&.&.`.4.-.q+-.-.u u u u u u 1.q+-.u 1.-.1.-.-.1.1.1.1.1.1.1.-.-.-.1.-.-.4.-.4.-.4.-.-.4.4.-.4.4.q+q+`.&.) `.`.&.i+D k+#.)+i J.G.z &.&.9 i+D 8.++A+G.( 9 >+_.P.H..+@.^.7.< c+R w.O : [.~+: : : [.: : ~+: [.: : : [.: : ~+|.|.[.[.<+b O S K.K.K. .K.K.K.g+: : [.r.[.l.U.v 7+7+Y.w+7+7+7+e++.^+%.=.h h =.h.5+e+F+7+e+e+O.7+7+7+7+7+7+,.7+,.,.Y.C.,.Y.Y.Y.L.L.L.L.s.s.s.#+#+#+- R k k _ _ '.'.Q.0 b+9 g.| | 2+g.g.2+g.| g.g.| | | 2+e 2+| | g+W.2+W.| | 2+2+2+e g.2+2+e 2+2+g+. . . . . >+2+g.| | | | 2+g.2+e 2+2+s 2+| | | 2+g.2+e 2+| e 2+2+| | 2+2+g.e 2+| e 2+&+. . . . . c.2+| e 2+2+| | 2+2+D+. . . . . . 0.. 0.t+0.Q g+) !+g.| | | 2+e 2+&+0.X.f+E 8 9.9.9.9.q+e e | 2+e 2+2+| 2+(+-+G.C+B H '+#+H w s.'+E+X.) e 2+e 2+| x 2+2+2+2+|+S.H+f f S.^.R.2.B.2.r+B.)+9 !+| | | 2+e e t+& b 5 b b z.*.Q.o.l m+@ l.l.l O j.w.& $._ T _ C w.O ]. .[.} q Q Q 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "q+4.q+4.) 4.-.4.4.q+) -.-.-.-.u 1.-.4.4.4.`.`.`.-+) -.-.u u u u u 9.u 9.1.q+-.-.u 1.1.u u u 1.1.-.1.1.1.-.4.-.1.-.4.4.-.4.-.4.4.4.-.4.q+-.4.q+4.) ) `.) `.&.8.G @.B.)+B.b+D G.u.9 i+>+( i+D (+o+o+>+i+< ++3+D G+H+)+J.G P.I.O S [.~+: g+: [.: : ~+: : : ~+: : [.: : [.[.|.|.: Q.H+6+S K.K.: |+O S .: : : [.x : l.U.d+7+e+7+e+7+7+7+0 5+_+=.I h =.%.e.e+e+7+7+e+7+e+7+7+7+7+7+,.7+,.,.,.,.,.Y.Y.Y.g L.s.L.h+H * s.#+#+#+X 9+R k _ _ '.'._.&.e W.| | | | e e 2+2+}.g.x W.g+&+t+t+. . . . . . . t+&+k.g+2+e 2+}.e x x g+. . . . . e e e | x | | W.2+2+g.| g.}.2+x | | | g.e e 2+e e | g+| | | | 2+e 2+2+e 2+D+. . . . . c.g.2+}.2+x | | | 2+t+. . . . . . . . . . . &+9 ~ }.e x | | | | 0+t+N.G.z { 9.9.9.9.9.9.5+e 2+}.g.| x | | !+-+b+)+B H s.s.s.H s.E+H.G 9 | s s 2+x | | | 2+e W.E+}+}+a+3.! )+o 3+J.;+n J.{ }.W.| | | | 2+t+b z.P.b 5 R _ Q.o.].F.l.@ m+l L j.w.w.$.T _ z.& w.6+|+K.: ] d Q 0.Q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "4.4.4.{ -.4.4.4.-.-.4.{ 4.-.4.-.4.) ) 4.) &.`.`.`.4.4.1.u u u u u 1.u 1.-.1.-.-.1.u 1.1.1.1.u 1.u -.-.u 1.u u q+-.1.1.-.1.-.4.-.-.q+4.-.4.-.-.q+4.) ) &.&.i+(+(+++i.B.8.8..+.+;+>+( D ++J.A+8.G.G.( ( 8.++b+b+k+A+G a+S.G+$.w.S .: ~+ .: : [.[.[.[.[.[.[.[.: : [.~+: [.: [.[.: s G+<.S K.: K.s w.S r. .: : l.g+[.r.U.e+7+e+F+e+e+e+l++.!+%.=.h h %.!+e+7+7+e+7+7+d.7+7+7+7+7+7+,.w+,.,.C.Y.,.g Y.L.h+h+'+s.M.'+s.M.M.s.X X - R k _ _ 1 q+e.g.x 2+2+g+2+2+e 2+e }.| &+. . . 0.Q Q 0.0.0.0.D+&+k.k.&+t+. t+&+W.2+x | g+. . . . . . . t+. . . t+. t+t+. t+t+P.}.| 2+x x 2+2+2+g.e . t+0.. t+t+t+t+. t+. t+. . . . . . . c.2+}.}.g.x 2+2+g+| D+. . . . . . . . . . 0.c.8.e }.e | | | g+g+. +D z { 9.9.9.9.9.9.9.X.2+2+}.s x | 2+x s z b+)+'+}+H N.s.}+s.H..+D ; e }.}.| x 2+x x 2+g.W. +E+s.}+a+)+r+3+*+*+*+:+o+&.2+x 2+| W.2+g+: b H+E+H+f E+X $.o.<+l m+l.@ l L O w.w.C & $.$.w.6+O ].K. .] } d q Q Q 0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", ") 4.-.-.q+4.q+-.-.-.q+-.q+-.4.4.) 4.4.4.`.&.`.-+) 4.4.-.u u -.u -.-.1.-.-.u 1.-.u 1.1.u u 1.1.1.u u 1.u u 1.u 1.-.1.1.-.-.-.-.-.-.-.4.-.4.4.4.) ) q+4.`.9 &.i+W #.B.b+o+i+8.i.J.++J.++6 #.J.8.A+b+o+9 (+++B.b+k+2.@.a+R.G 2 & O : S K.~+~+: [.[.[.[.~+: : [.[.: : ~+: [.: [.[.[.: e+X.> K.: : x Q.+.S g+: : |.l.: l.g+$+F+7+7+F+7+e+7+e+T h.=.h h =.h.5+e+7+F+e+O.e+7+7+7+7+7+7+7+7+,.,.,.Y.,.Y.L.L.h+h+'+'+}+a+a+}+}+f s.#+R R k _ k 4.!+}.2+x | 2+| e 2+2+2+e g+t+. B+[.[.[.|.|.B+B+|.|.[.r.S e o.+.I.s x k.t+t+k.0+D+&+t+t+. t+. . . . . . . . . . . . X.}.| 2+| | g.2+| 2+2+. . . . . . . . . . . . . . . . . . . c.2+e }.| | | 2+2+g.D+. . . . . . . . . . 6 i+2+e }.g.| | 2+g+. e G.z { !.9.9.9.9.9.9.9.i+| e }.e x | 2+| W.D ++.+'+'+s.'+H s.'+E+G+&.e.g.e s x | 2+x 2+g.| 2+w.H.E+'+! #.J.*+*+:+:+..E W | | | | | e &+}.E+@.]+6 o ]+f X _ j.L {.m+@ F.K L x+j.w.w.w.C w.O O ]. .: ] d d q Q Q Q 0.0.0.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "4.q+u q+4.4.4.4.4.-.4.q+{ ) 4.4.4.4.4.4.) q+4.4.-.4.-.-.1.u u u u u 1.1.u u u u 1.u 1.-.1.-.u 1.1.1.u u -.) -.-.-.-.-.-.-.-.) -.4.4.-.4.4.4.4.) ) q+-.`.&.D D 8.k+++>+G.( 8.G+C+i.^.#.++++++A+++A+*+9 i+D k+++#+L.L.L.H a+5 C w.|+ .: : : [.: |.[.|.: ~+[.[.: [. .: [.: ~+: [.|.|.: /+5 S : . .D.y.& ].: g+[.|.[.g+l.x v e+e+e+e+7+e+e+Q.!+%.=.h =.;.5+e+e+e+7+7+7+7+7+7+7+,.7+,.,.,.,.,.C.Y.g L.L.H s.'+'+'+a+a+R.a+@.S.f s.X k 9+b+c.| e 2+2+2+e e 2+| 2+| &+. B+r.r. . .l.[.[.] |.: K.|+O w.$.a b P.1 H+E+a }.r.D+|.: 0+T.D+D+D+t+t+t+. . . . . . . . X.}.2+g.e e 2+| 2+| W.. . . . . . . . . . . . . . . . . . . c.| 2+g.2+2+2+e e 2+D+. . . . . . . . . e.&.e 2+| g.2+2+2+2+t+r.A+f+E !.9.9.9.9.9.9.9.9.q+2+| 2+2+2+2+e e g.P.C+B }+H H E+'+H.E+}+X.q+e | g.e 2+2+g.e e 2+2+2+W.3.}+H+)+7.n *+..:+:+p+4.!+2+2+e s e e t+R @.#.8.n b+3+++o E+k 0 L {.m+m+ .l |+L O O O w.O O |+]. .l.l.} d q q Q Q Q Q 0.Q Q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "4.4.-.) 4.4.4.4.4.-.4.q+-.-.4.4.4.-.q+4.-.-.-.4.4.) 4.-.1.u 1.1.1.1.1.q+q+4.-.u 1.u 1.-.u -.1.1.1.-.-.u u u u 1.1.-.-.q+4.4.4.-.-.4.-.-.q+4.) ) -+q+q+) &.>+(+D D >+(+>+&.D 6 ++i.S.B.B.H+^.C+B.X.J.( (+8._.G+R - 9+,+C.H E+r +.O : : : : : ~+[.[.: .|.[.[.l. .<+o.: : [.: : [.|.|.: t.& S ~+ .K.x+& w.S .: [.[.[.[.g+{.e+F+e+e+e+7+e+t.5+v.=.h h ^+e y+e+e+e+7+e+F+7+7+7+7+7+7+w+,.,.,.Y.,.g L.g h+H '+'+3.a+a+^.! ! .+S.f w R #+q+}.e g.2+2+e }.}.2+| 2+&+t+r.].3 l K. . .F. . . .].O w.1+a P.]+G _.8._._.6 1 z.T w.> S S 0+k.k.T.D+D+t+t+t+t+. . . . 1 +.g.}.}.g.2+2+e 2+| . . . . . . . . . . . . . . . . . . . c.2+2+g.2+2+s }.e 2+t+. . . . . . . . I.) }.2+2+2+e g.| 2+D+&+.+G.E { 9.9.9.9.9.9.9.9.9.9.5+g.g.2+2+2+}.}.2++.B.B '+'+'+w '+M.E+H+++i+g.2+2+g.2+2+}.}.e | 2+e W.f S.! B.i J.n *+:+:+p+q+e g.| e }.e W.B+.+#.3+o+:+u.u.:+*+A+2.s.'.j.l m+m+F.].l L L ].L ].L . .m+] ] } d d d d q q q Q Q q q Q . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", "4.-+4.4.4.4.q+-.4.4.-.{ -.4.q+4.4.4.4.4.-.4.4.4.4.4.`.) ) 4.-.-.q+) `.4.4.4.1.u u -.-.u 1.u 1.-.1.-.-.u u -.-.u u 1.-.-.-.-.-.-.-.-.-.-.-.q+4.4.4.4.4.`.9 (+b+D o+z &.&.&.D G+! S.B.C+k+H+^.r+)+B.7.G.b+_.k+G+#+C.C.C.- C.*.T +.<.|+~+: : [.: ~+|.K.: |.|.|.: .<+'.o.K.: ~+[.: : : [.: o.|+: : : K.|+I.I.S g+g+[.[.g+l.g+3 e+7+7+7+e+7+e+5+!+%+h.r *.}.y+e+7+O.7+7+7+7+7+7+7+7+,.7+w+,.,.,.Y.Y.L.L.h+M.M.'+'+a+a+S.^.! ! ^.a+}+#+b+j+e g.2+2+2+g.e 2+| 2+0+. .L L ].L L l ].l .].x+O & a 5 6 G < 5.>+( >+D < W c+b a <.6+> S S S ~+~+0+0+k.&+&+t+t+t+t+X.}.2+g.e 2+| 2+e e | . . . . . . . . . . . . . . . . . . . c.g.g.2+2+2+2+e 2+| D+. . . . . . . g+q++.| e e g.2+| 2+&+0. +C+f+x.9.9.9.9.9.9.9.9.9.9.9.X.g.2+2+2+2+g.e | | i.}+}+s.s.'+s.H.}+.+i+6 e e g.2+2+2+2+e 2+| 2+e W.R S.! B.C+J.n *+:+u.N i+2+| 2+e e 2+0+x+r+J.*+E.N N = N >.:+;+B.#._.< ( {+i+5.5.< c.< 1 w. . .l.[.] ] } } } d d d d l 3 ].l l . . . .[.. . . . . . . . . . . . . . . . . |.: [.: ~+: [.. . . . . . . . . . . . . B+& 6 D i+i+D 8.W 1 w.0.. . . . . . . . . . . . . . . . ", "4.) ) q+4.4.-.-.-.4.q+q+-.-.4.4.4.-.-.) 4.-.-.q+4.4.) ) `.`.) 4.1.1.-.1.1.1.1.1.u u 1.1.1.1.1.-.1.1.-.1.1.-.-.-.u u -.-.4.4.4.q+4.-.1.-.-.4.q+`.4.4.4.`.i+8.b+( f+9 ( o+(+i.C+B.o a+2.b+G+H+a+a+4+^.i J.b+*+W #+m.9+C.,+k *.C & w.|+: : : : [.: : I.~+k.|.|.[. .l y+l+o.K.: : [.[.: [.[.: o.C K.: : K.U.Q.I.S : g+[.[.l.g+l.<+d+7+7+e+7+e+0 I.e 2+}.1+5+}.y+e+e+7+7+e+7+7+7+,.w+,.7+,.,.,.,.,.g g L.L.h+s.s.'+a+a+S.S.^.! ! ! a+E+4.}.e g.2+2+| 2+g.2+2+W.. r.<+L L L l L l ].l ].x+w.'.z.f ]+< D 9 z `.E `.z ( 5.8.6 5 a C <.6+> > > > S S ~+~+0+~+0+T.&+6 }.| 2+g.2+2+2+e e W.. . . . . . . . . . . . . . . . . . . c.e 2+2+2+2+2+g.2+2+0.. . . . . . [.) !+2+2+e e g.2+2+&+t+2+m.C+u.A 9.9.9.9.9.9.9.9.9.9.9.i+e 2+2+2+| 2+e 2+W.H.B }+'+s.H.M.E+}+@.`.5+e g.2+2+2+| 2+g.2+2+2+e e I.S.! B.#.++n o+( u.4.X.g.2+| 2+e 2+D+p.7.;+*+:+>.= E s+~.~.1.&.j+1 5+e | W.e e | |+g.& ^ c+_ @ l.} } } } ] ] m+l L i+W W j+j+j+j+j+j+6 k.0.. . . . . . . . . . . . . . T.q+j+j+j+W j+(.&+. . . . . . . . . . |+c.`.W a e e e 2+2+2+| T X.a k.. . . . . . . . . . . . . . ", "4.q+) { -.-.-.-.-.q+4.{ -.4.-.) ) 4.4.) ) -+4.-.-.4.`.`.`.&.`.{ 1.1.1.-.-.4.q+1.u 1.-.1.u 1.u u 1.-.-.-.-.u u -.4.1.-.-.-.-.-.4.-.q+4.4.-.-.-.q+-.q+) ) {+( D D 9 i+8.Z #.#..+a+H+.+2.J._.i.w '+^.2.i.Z )+2.w #+X ,+9+,+/+e.T T e.6+S : : ~+: [.: o.: [.|.|.[.[. .r.e+U e+|+g+: : [.: [.[.: Q.& S : : K.|+$.& K.g+[.[.l.l.[.r.y+e+e+7+e+l+e+K.| > <.h.h.| | e+7+e+7+7+7+7+7+C.L.C.,.7+,.,.,.Y.C.Y.L.H s.'+'+}+}+3.a+! ! ! ! a+^.C+{+2+g.g.g.e e 2+e e e &+B+3 j.L L L l l L ].L L w.$.z.5 G < i+&.x.{ 8 { ~.4.`.9 >+8.6 5 a C C C 6+6+6+> > > > > S S ~+g+6 5+g.e e e e e 2+e | . . . . . . . . . . . . . . . . . . . c.2+g.g.g.g.g.e e g.D+. . . . . 0.9 (.e e e g.2+e e g+. [.e n+++:+{ !.9.9.9.9.9.9.9.9.9.9.q+e g.e e 2+e e e e I.'+H H.'+H.H.}+H+6 q+e 2+e 2+e e g.e e e e e 2+g.O ! ! o #.7.J.o+u.z 1.}.e e g.g.e g.t+i 7.J.*+E.N = s+u {+(.}.2+2+e g.e e e e e e e 2+2+g.g.+.a m+} } } ] @ {.j.0 _ 8.}.e e e 2+2+2+g.e 2+Q Q . . . . . . . . . . . . . a k+2+| g.2+e e T.. . . . . . . . B+8.`.!+e e e e 2+e g.e e e e e e 5+> . . . . . . . . . . . . . ", "4.q+q+4.4.4.q+4.-.-.-.4.4.4.-.q+4.) -+4.4.4.4.4.4.4.`.`.`.`.4.-.-.-.-.4.4.4.-.-.1.1.1.u u -.-.1.-.4.-.-.4.-.1.) &.-.4.-.-.-.-.1.1.1.1.-.1.-.1.-.-.4.4.) ( (+k+D D o+D 8.k+B.G+++i.}+}+r+a+B.Z R }+q.2.B.G+@.E+}+#+,+w+w+w+[+T e.$.w.> : : : K.: [.: |.|.|.[.[.[.l.m+y+C.,+k w.: : : [.[.~+: : I.z.> ~+K. .].o.x+: : [.[.g+[.: F.y+e+7+e+7+e+|+S 2 %.h =.;.}.l+7+e+7+F+7+7+7+,.w+w+7+w+7+,.,.Y.Y.Y.g L.s.s.'+M.a+a+S.! o o ]+^.a+f+1 | 2+2+2+}.}.}.2+2+2+t+L v L v L L L l L l L O j _ H+6 < ( `.q+u 9.9.9.9.8 { -+z 5.W (.5 a T T T C C <.C <.6+> > > > > W !+}.e 2+2+e 2+| e W.. t+. . . . . . . . . . . . . . . . . c.2+2+g.}.}.}.2+g.e t+. . . . 0.c.j+g.2+e g.| 2+2+g+t+0.: x+ +)+*+E !.9.9.9.9.9.9.9.9.9.9.9.5+2+s }.}.e 2+e e e a+}+E+'+s.}+H+@.8.i+2+| e 2+e }.}.e 2+2+e 2+| g.g+S..+]+#.A+*+f+N E ) 2+e }.}.e g.g+: i :.J.*+u.>.E ~.6 2+e g.| 2+2+g.}.}.s e 2+e e 2+2+2+2+s }.+.l.} } ] K j.U M.3.B.(.g.2+e e 2+2+2+2+e |.d d Q 0.0.. 0.. . . . . . . 9 +.2+2+g.2+e }.t+. . . . . . . S ) W }.e g.g.e 2+| g.2+e }.}.e e e e e W.. . . . . . . . . . . . ", "4.4.4.-.-.-.-.q+{ -.q+q+q+4.4.4.4.q+4.4.) 4.) ) 4.q+`.&.&.`.) 4.-.) ) q+4.4.-.1.-.1.1.1.-.1.1.1.-.q+-.q+-.) ) 4.4.q+4.4.4.-.-.1.-.-.1.u -.`.-.-.-.-.q+`.9 i+9 9 i+8._.#.n Z B.@.s.H.^.G+m.2._.w #+s.a+a+i.B.i.E+m.9+C.l+w+t.5+T & +.D.S S K.: ~+: [.~+[.[.|.[.|.l. .3 l+w+w+l+w. .: : [.[.|.[.: D.P.C g+~+ .K.K.K.g+g+[.|.[.g+: U.e+e+7+P l+o.s ^+=.h h =.a e+,.7+7+e+7+7+7+7+7+7+7+m ,.,.,.,.,.Y.Y.h+L.s.s.}+}+a+R.^.i.! 2.S.^.) }.| g.| 2+s }.e | 2+0+7 v j.v L 3 L 3 L l L j.w._ 5 6 < 5.&.4.9.9.9.9.9.9.9.u -.`.i+(+G ^ 2 z.T T T T T T C C C C <.6+> W 1+e 2+| e e 2+2+2+W.D+&+&+D+D+t+t+t+. . . . . . . . . . . c.g.| g.s s 2+| 2+e D+. . . . X.i+e | 2+e g.| 2+W.t+. 0.|.x 5+P.J.u.A 9.9.9.9.9.9.9.9.9.9.9.X.2+e }.s | | e e W.H.'+a+}+}+}+P..+i+(.2+2+2+| e T }.2+| e e 2+2+2+g+X ^.! B.8.*+u.N x.j+| e e }.2+| k.0 r+7.*+:+>.= E x.X.2+e g.2+2+W.2+s s e x 2+e 2+2+2+2+2+e }.e r.} @ F.v j - 3.)+X.c.| | e g.| 2+2+| s S .} d d q q 0.Q 0.0.. . . g+{+e 2+| 2+| e W.. . . . . . . x q+!+e }.2+| 2+e 2+2+2+| e e }.g.| 2+e 2+2+0+. . . . . . . . . . . ", "4.4.4.-.-.-.{ -.-.4.-+4.-.4.4.4.4.q+4.4.4.) ) &.`.) ) `.&.`.-+4.) 4.4.4.4.-.1.-.-.u u 1.-.-.q+-.4.-.-.-.4.&.&.`.) 4.) -.4.4.-.u u 1.-.-.-.q+-.1.-.-.q+&.9 9 9 o+z D 8.k+B.H+.+.+f s.4+s.H s.}+#+H s.#+R.)+#.i.S.R 9+,+/+U '.$.+.& C w.S K.: K.: : [.[.: : |.[.[.: .r.v 7+l+l+j 0 K.K.: : |.~+[.: x+E+a S ~+ .: : : ~+: g+: g+S e.a t.e+7+7+l+t.M ~ h h h ;.5+e+e+7+e+e+7+e+7+7+7+7+7+w+7+,.C.C.Y.L.L.L.H '+M.3.a+a+! R.S.^.! ^.) e e g.| g.2+| | | 2+D+U.j.v v $+$+L 3 3 3 L w.'.E+G+W D &.q+9.9.9.9.9.9.9.9.9.u 4.{+c W n.^+5 2 5 r z.r T r r T T C & C j+5+| | | 2+e g.g.2+g+&+~+0+0+0+k.T.k.T.&+D+D+D+t+. . . . . c.2+| g.g.2+| | 2+g.D+. . . a {+e | | | g.e e | t+. . 0.B+ .o.p.C+G.E !.9.9.9.9.9.9.9.9.9.9.i+g.e | 2+x | 2+g.| R }+'+H.H.a+H+i.) +.g.g.2+2+e e.!+x | 2+e e g.2+W.I.@.G+o A+*+u.p+{ !+| e 2+2+| | t+H 4 :.*+:+N = = ~.i.2+e g.e e | e g.| | x 2+g.2+e 2+| g.g.| | x K.] K j.k s.3.! i.(+}.2+2+e g.g.| 2+e W.O L m+|.] } d d Q Q 0.. 0.1 X.e g.e | 2+e &+. . . . . . : ) r e 2+| | | 2+e g.g.2+| e 2+| | | 2+e g.g.g.&+. . . . . . . . . . ", "-.4.4.4.-.-.q+q+4.4.) 4.4.4.) 4.-.4.4.q+&.&.`.4.) 4.) ) 4.4.4.4.`.4.4.) 4.-.-.-.-.q+q+1.-.4.) -.-.4.-.q+4.`.`.`.4.q+4.4.4.1.1.) -.u 1.-.u -.1.1.1.-.-.q+q+&.9 i+9 c._.i.]+k+G+}+b H s.s..+L.9+9+h+#+9+H '+4+R.S.n+k 9+C./+w+/+_ $.C <.D.: : K.: [.[.[.~+: [.|.[.[.: F.U.e+w+l+U e+j x+: : : [.: [.: ].E+5 > S g+: : : : e C <._+^+2 1+j e+7+l+l+ +h.h Z.h =.r e+7+e+7+7+7+7+7+7+7+7+,.,.,.,.,.C.C.C.L.h+h+s.s.'+3.R.a+a+! ^..+++c.g.e g.2+}.g.x | | W.0.[ [ j.j.j.L $+L L L j.[ z.f G < 9 ) u 9.9.9.9.9.9.9.9.9.u -.`.i+W (.^ ^+^ 2 5 2 2 2 z.2 r a r T T c.}.x 2+2+2+2+e e 2+|+k.> S > S S S S S > S K.S : [.T.0.0.. c.2+2+}.2+x | | | | D+. . }.q+}.x | | | | e 2+D+. . . . 0.[.2+ +B J.f+E 8 9.9.9.9.9.9.9.9.9.-.}.e | x | 2+2+g.e I.}+}+}+M.}+.+6 ) g.e e 2+e e ~+X.U.2+U.2+e e 2+e s 3.}+)+++G...:+-.e g.s 2+x | W.q R.r+;+:+N N = = -+X.| | g.e g.| W.g+0+T.T.~+W.e g.e 2+s e r.| 2+| m+p [ J X a+G+)+C+(.| 2+2+e e 2+s e | O 0 L ].m+l.@ ] } d q Q 0.&.e g.g.e 2+e e . . . . . . . 9 !+g.}.2+| | | | | e e g+[.W.| x | | | | e e 2+| t+. . . . . . . . . ", "q+-.-.4.-.-.-.-.-.-.4.4.4.4.4.) 4.4.4.-.`.4.q+4.4.4.`.`.4.4.q+4.4.) 4.) ) 4.-.4.4.q+q+-.-.q+4.1.-.&.-.-.q+) ) ) { q+4.4.-.-.-.4.4.1.1.-.-.-.u 1.-.1.-.q+q+4.&.9 9 i+6 )+b+++Z ! i.@.w '+s.#+9+m.C.C.L.L.L.9+N.i .+}+R C.,+,+l+,+y.T +.<.S : : : |+g+[.[.~+[.[.[.[.[. .l y+l+l+l+w+e+j D.K.: ~+[.[.[.: .}+(.6+S S K.S <.e.^ Z.c ^+2 a +e+e+7+e+t.!+h Z.h h ;.5+l+7+e+e+F+7+7+7+7+7+7+w+7+,.,.C.Y.Y.L.- L.s.s.s.a+a+! R.R.R.^.G.6 e 2+2+e }.g.| 2+| g+[.P P [ [ d+j.v v v j.w._ E+]+< 5.z -.9.9.9.9.9.9.9.9.9.9.9.-.`.i+j+; c+^ ^ ^ ^ 5 5 ^+5 2 2 2 2 r 2 c.+.| | r.r.2+2+g.2+e ~+6+6+6+6+6+<.C w.T $.& & +.o.|+K.k.D+c.2+e }.g.x 2+| x | D+. K.q+!+2+x 2+| x | 2+&+t+. . . . 0.|.x I.m.)+J.f+E { !.!.9.9.9.9.9.9.9.!+s | 2+| r.W.2+g.e }+}+}+}+H+.+b+c.2+g.2+g.}.}.t+j+| x r.2+g.e g.}.> H+E+a+B.A+;+*+9 g.}.}.2+| | g+r.'+/.b.a.a.N = N E X.x | 2+W.&+t+. . 0.0.0.0.. W.e 2+e }.s x | | g+g+3 [ U - f a+]+)+c.x | 2+g.2+e }.}.x > k j w.L L .F.@ @ ] d D.i+W.2+g.g.g.}.g+. . . . . . a i+e }.}.| | 2+| x | g+t+t+. . t+2+2+| x | g.g.g.e g+. . . . . . . . . ", "4.4.4.4.-.{ -.4.q+-.q+4.`.) q+4.4.4.4.4.) 4.4.4.q+) &.`.) 4.) 4.q+4.4.4.4.) ) 4.q+4.-.q+) 4.4.4.) `.4.4.`.-.-.) 4.-.4.`.4.-.q+-.-.-.-.-.4.-.-.-.-.-.-.-.-.q+) &.&.( W ++n _.B.i.)+G+H+w s.#+#+9+9+9+C.9+9+9+L.'+a+a+w 9+9+w+w+l+9+n+& & |+: : ~+ .: ~+|.: |.[.[.[.l.g+l <+e+l+l+l+7+w+j j.K. .: [.[.[.: K.,+G T S |+Q.2 ^ Z.Z.Z.h.^+2 e.t.l+e+e+ +!+=.h h h =.!+0 e+e+7+7+e+7+7+7+7+7+7+,.,.,.C.C.C.C.Y.L.L.s.'+M.a+a+a+! )+q.>+!+2+| 2+e }.2+x | | k.L ,.w+j j j j [ [ j.0 U R @._.n 9 4.u 9.9.9.9.9.9.9.9.9.9.9.1.) 9 W ; n.n.n.^ ^ ^ 5 ^ ^+5 ^ ^ 5 5 !+i+}.| 2+| | 2+| | g.> K.C <.C C T T 5 5 1 c+G+1 P.z.1+w.g.r.i+2+}.}.| | | | | 2+D+k.) !+}.g.x | | | e 0+. . . . . . t+B+K.<+t.B i.J.*+u.`.x.{ 8 !.9.9.9.!.W e x | 2+r.2+2+| W.}+}+a+}+H+i.f+X.2+| 2+2+}.2+k.i+g.x | 2+| | g.s 2+9+w H..+C+A+u.6 2+e }.| | | &+y+'+2.b.p+a.p+:+p+z B W.0+t+. D+ .<+<+3 F.@ @ ] 7 !+2+e }.g.r.2+2+| W.F.v l+,+L.w H+X.b++.2+2+| 2+e }.e x W._ _ j w.j.j.l l F.@ l.++!+| g.| | 2+}.D+. . . . . D+) }.g.e }.| | 2+| | W.t+. 0.. . . T.5+x x e | | 2+s e . . . . . . . . . ", "q+4.q+4.q+4.-.4.-.-.q+q+4.`.q+4.4.) 4.4.) `.4.4.) ) ) `.) 4.) ) q+q+q+q+4.) ) -+4.4.4.4.4.4.q+q+4.4.`.`.&.4.-.-.-.-.) `.4.-.4.-.-.-.-.q+4.-.-.4.q+-.-.-.-.4.) &.&.9 i+8.8.i.G+)+b+D G b L.L.'+9+L.9+C.C.9+C.C.C.9+L.H.#+m.,+w+l+,+/+'.& O S : [.: : [.[.~+[.: [.|.l.: .l y+e+l+l+l+7+e+j 0 x+S : ~+[.|.: .o.*.I.> & 2 Z.{+Z.c h.^+2 a 5+'.l+e+t.a %.h h h =.%.T e+e+e+7+e+7+7+7+7+w+7+w+,.,.C.C.L.L.L.h+L.s.H '+3.R.a+R.^.^.u.e.2+2+2+2+e 2+| 2+e [.I.H L.9+k U _ '.U j _ X H+G A+( E -.9.9.9.9.9.9.9.9.9.9.9.u -.{+i+W ; (.~ n.^ ~ n.^ ^ ^ ^ ^ ^ ^ ^ ^ i++.2+g.e e g.| 2+| W.S T T r 2 ^ n.; W 8.(+n < < G X.b $.O i+| | e 2+2+2+e e 2+k.9 n.| e 2+2+2+e e g+. . . . . . . 0.7 g+x+o.p.B i.A+G.o+f+9 z E E 4.4.-+i+g.| 2+e e e 2+| | ,+}+}+}+H+]+) 5+2+| 2+| g.g+e D a e e 2+| 2+| 2+e I.R #+H.^.B.) 5+2+2+e 2+2+2+t+l+L.q.:.......*+*+*+++&+. r.t.p.l+e+3 l {.@ @ @ ] )+2+2+e 2+| 2+e e e l.v [ l+,+9+#+}+X.k+e 2+2+2+| e 2+2+2+& X k j [ [ v v l l l ) }.e | 2+2+| W.. . . . . . a j+| 2+2+e 2+| 2+e e t+. 0.0.. 0.. . P.e e e 2+2+| 2+e D+. . . . . . . . ", "4.4.4.-.4.-.4.-.4.4.{ q+) 4.-.-.q+) ) ) `.`.`.) ) ) `.) ) `.) ) 4.4.-.q+4.4.) ) `.) -+4.4.q+-+-.q+) &.&.`.) 4.4.) `.`.4.4.4.q+4.4.q+) 4.-.-.-.-.-.-.4.-.4.q+) `.9 9 D (+++G B.2.r+C+@.#+9+L.X 9+9+C.9+9+Y.9+C.,+,+L.- C.C.w+l+/+C.,+,+X w.|+: : [.: : : : : [.[.[.[.[.: .<+e+7+l+l+e+l+j e+[ j.K.g+: [.|.~+: K.w.e r Z.Z.Z.Z.Z._+^ 2 r T 1+t.e+e+5+!+=.h h =.=._+5+7+e+w+w+e+7+7+7+w+7+w+,.C.C.H s.#+s.L.H s.M.a+'+a+R.a+.+q.z +.| 2+2+2+g.g.2+e }.0+9+3.}+M.#+X - k k k X f ]+_.n ( `.1.9.9.9.9.9.9.9.9.9.9.9.9.-.{+( W ; ~ ]+(.~ n.~ n.n.n.^ ^ ^ ^ ^ ^ i+5+2+s }.e | 2+2+2+S S z.2 5 n.G < (+i+9 9 9 z f+o+< B.H.*.i+2+g.g.2+2+e }.e g.c.8.2+2+g.g.2+e }.e t+. . . . . . . 0.7 .L o.t.p.B .+i.C+A+b+D o+f+f+f+u.`.e 2+2+s }.e | 2+2+I.a+a+3.X.6 ) e | 2+g.2+g.&+*.k+k+}.e 2+2+g.2+2+e D.n+y.z+H.i.) e 2+2+g.2+2+W.B+l+C.q.4 ;+b.;+;+;+;+;+o.4+4+H /+e+y+3 K F.@ @ @ @ .++.2+g.e 2+e }.}.2+|.3 v [ j U _ n+N.j+e | 2+2+2+2+e 2+g.O X - k U j [ [ v 3 N.c.}.e 2+| g.2+0+. . . . . . 9 }.2+2+2+g.2+2+}.}.g+. . Q Q 0.0.. t+a e.e 2+| 2+g.2+e ~+. . . . . . . . ", "4.4.4.4.4.q+4.4.-.4.4.4.-+) q+4.) 4.) ) `.-+`.&.`.&.`.) `.`.4.4.4.4.-.4.4.) 4.`.`.) `.`.4.-.4.4.-.-.) `.`.`.&.`.`.`.) ) &.-+q+4.`.-+4.) 4.4.&.-+4.4.4.4.q+4.`.) &.9 9 i+D G G+)+)+B.G+P.m.- '+}+#+9+9+9+C.9+9+9+9+,+[+/+/+,+w+l+,+w+,+/+'.O S : K.|+: l.: l.: [.|.[.[.r.r.U.v e+l+l+l+l+7+e+j j [ ].S : [.~+: ~+g+r Z.Z.Z.Z.Z.Z.=._+^+a T !+a 0 e+l+*._+h Z.h =.%.^+Q.l+l+7+7+7+7+7+w+w+w+,.C.C.Y.h+L.s.* s.'+'+'+'+a+a+q.R.^.z }.| e e 2+2+2+2+2+e k.B R.a+R.a+3.'+s.s.E+S.! #.< o+z x.u 9.9.9.9.9.9.9.9.9.9.9.u q+{+c W G ~ ~ ~ n.~ n.n.~ n.(.(.n.n.n.^ i++.2+g.s 2+| 2+e e 2+> 5 ^ ~ W c ( &.`.-+{ x.x.E z f+n C+@.9 e g.2+2+2+g.s g.| ; e e g.2+| 2+g.e e W.. . . . . . 0.q ] .<+[ t.p.H 4+4+X.)+i.C+k+J.b+b+G.f+M 2+2+e e | | e e 2+}+}+S.G+(+c.| | g.e g.2+t+i.i.c.s 2+x 2+e g.g.2+W.R ,+M z+++c.e e g.2+| 2+k.: o.e+w q.4 :.:.:.:.J.:.:.7.4+p.l+e+y+3 K {.F.@ @ @ 4+*.g.2+2+| 2+e e x q {.3 j.j.e+0 t.t.H+a | g.e e 2+2+| 2+e $.- k U U j [ [ v ( !+e | | g.e 2+t+0.. . . . [.&.g.e e g.2+| 2+g.e D+0.Q D+q Q 0.. . e P.2+| 2+e e g.2+W.. . . . . . . . ", "-.4.) 4.4.4.4.4.`.`.`.-+) 4.{ -.q+) 4.) ) ) ) ) &.`.`.`.`.`.4.) { -.4.4.) 4.) ) ) 4.) ) 4.) ) 4.4.q+q+`.4.&.&.`.) `.) 4.`.) -+4.`.&.9 9 z 9 z &.`.`.&.-+) `.) `.&.9 >+D >+k+@.@..+a+R.H+R 9+H s.9+9+s.R ,+H 9+L.L.w #+k ,+C.,+w+/+m.#+_ /+0 |+K.: : : : : g+l.: [.|.[.l.r.l <+7+l+l+l+l+l+l+l+e+P 0 x+K.: : ~+S r c Z.Z.Z.Z.h c c V.^+r T a ~ 5+/+e+t.!+%.h h =.%.%.a t.l+l+l+7+w+w+7+w+,.,.C.Y.C.Y.h+L.#+'+s.'+}+'+'+R.R.4+q.9 }.2+e e g.2+2+| | e k.^.2.2.! ^.^.^.S.S.S.! #.A+n z -+-.9.9.9.9.9.9.9.9.9.9.9.9.u q+i+< W ~ ; ]+~ n.n.~ ~ ^ ~ ~ (.(.(.(.(.9 }.| 2+g.2+2+e e e S > ^ ; j+5.{+`.4.1.1.9.u 1.8 x.E f+G.i.`.e 2+2+2+| | g.2+| 2+e g.g.2+2+| | e g.| g+. . . . 0.q |. .].j.0 l+9+H H B 4+4+4+X.)+)+i.i.C+C+; | | 2+g.2+2+g.e W.H.a+H+i.9 P.2+| g.e e W.[.G B.i+e 2+| e e e 2+2+g+[+[+m.!+i+1 e e 2+2+2+| D+].<+y+/+4+q.r+r+7.7.;+J.J.7.)+N.[+e+y+g.p {.F.{.@ @ 4+M g.2+2+2+| g.2+2+Q m+K 3 v j.d+y+0 }.6 2+e e g.2+2+2+W.2+w.k k U U j P j /+`.g.g.2+2+g.e W.. Q Q Q 0.0.5+; g.e e 2+2+2+| | 2+t+q B+B+B+D+q Q 0.g+; 2+| 2+e e 2+2+| . . . . . . . . ", "4.4.4.) q+-.4.4.4.) `.-+&.) ) 4.4.4.) ) 4.4.) 4.&.&.`.`.) ) 4.4.) ) ) ) ) ) `.4.) 4.`.`.) `.`.`.`.) ) ) q+) &.&.&.&.`.) `.) ) `.9 9 i+9 9 9 f+f+f+f+9 `.z &.9 9 >+D b+b+D k+)+#.H+H+@..+#+m.9+#+L.9+a+9+C.9+#+H.C.L.p.9+9+C./+C.,+X /+,+/+j o.D.: : : : : : : [.: [.[.[.: .U.y+7+l+e+l+7+l+l+l+l+l+j o.K.: S r =+c h c h c Z.h Z.%+^+r T T (.^ 5+l+t.t.!+%.h h h =.%.5+t.l+t.l+7+,.7+w+C.,.C.C.C.Y.L.h+s.s.s.'+a+'+a+R.R.R.^.z +.e 2+g.g.2+e e 2+e ~+^.B.o 2.o ! 2.! )+o B._.< u.(+G+1 c+c+X.c+c+X.c+c+1 c+c+c+n.n.^ W ; ]+~ ~ (.~ (.n.~ (.(.(.(.~ (.~ ~ 9 5+e g.e e g.e 2+e 2+O ~ W c {+`.-.u !.9.9.9.9.!.8 x.z f+A+`.2+g.g.g.g.g.e e e e 2+e 2+e e e g.e e e g.g+0.Q q B+|.l.].x+o.j /+m.s.B '+4+4+B 4+4+4+X.X.4+X.c.e g.g.e e e 2+e 2+*.S.@.6 q+}.e e g.2+g.0+O Z #.5.e.e 2+e 2+e 2+e 2+I.R H..+4.}.2+e 2+e e | . ].].L o.p.'+^.2.i 7.;+:.J.J.C+q.N.,+e+y+<+3 K {.{.F.4+M 2+2+e e 2+e e g.Q @ @ K 3 3 v j.j.j.X.e e 2+g.2+e e g.g.> /+J U U U j j i W e e e e g.2+T.q d q Q 0.0..+!+g.2+e 2+e e e e W.0.[.: [.|.B+q Q 0.k.8.e e e 2+e g.e e D+. . . . . . . ", "q+4.4.q+4.4.4.q+q+4.`.&.&.4.4.4.-.q+) 4.) q+4.4.) `.`.`.4.) `.`.4.) ) 4.) ) ) `.) ) ) `.`.) `.`.) z &.) 4.4.4.`.) ) `.4.) `.9 9 9 i+f+>+>+D >+D D o+o+o+f+D o+o+G.b+b+A+7.6 i.a+4+)+.+}+E+#+9+9+9+p.C.9+9+C.C.,+/+w+C.- m.,+}+z+C.,+w+C./+/+0 D.w.K.: ~+[.: : : |.|.[.: : .r.v e+l+7+l+l+e+l+e+l+l+l+e+0 w.r ~ %+I y y y =.I Z.h %+r r T 5+r ; !+t.e+e+5+!+h h =.h =.h.t.l+/+7+/+7+/+w+w+C.,.C.9+L.L.H L.'+'+* '+` a+R.R.q.q.f++.g.2+2+2+g.}.}.}.g.0+B.r+r+o B.B.o o #.B.#._.8.z !+g.2+}.}.}.e g.e e | 2+g.2+e }.}.<.n.~ ~ ]+~ (.(.(.(.~ n.~ (.(.(.6 (.~ i+!+}.e g.g.g.2+2+g.S 6+W c {+`.-.u 9.9.9.9.9.9.9.9.8 E u.D ) g.2+g.}.}.}.e e e &+e 2+g.2+}.}.}.g.g.e e | [.7 7 7 l.K.L O 0 t.m.X H.a+B 4+.+4+.+B 4+4+4+4+4+>+}.}.e g.e g.2+2+2+}.@.X.k+`.e e e 2+| g.D+R G #.A+c+e e 2+2+g.2+e }.O H.^.A+{+e | g.2+g.}.W.B+K.K.].y+Q.N..+i.C+J.J.J.:.i 2.q.4+)+C+J.G.o+f+o+o+o+&.e.g.e s }.}.e 2+e q @ @ @ {.l l 3 3 <+Q.P.2+2+2+g.e }.}.e 2+O j j j P U w+`.e.e 2+e g.2+| . l.@ d d q Q b+}.2+2+2+g.e }.}.e +.a z.z.z.M a *.1+1+n+c.g.e 2+| 2+2+e }.T.. . . . . . . ", "4.4.4.4.q+-.q+4.4.4.) `.`.-+4.4.-.4.4.) ) ) 4.) 4.4.`.) 4.4.4.) ) ) ) 4.) ) 4.) 4.) 4.) ) `.&.&.9 &.z `.) ) ) `.) `.`.) `.`.9 i+( D D o+9 f+i+>+D b+J.b+b+b+J.J.A+J.b+B.^.2.B.@.a+r+@.}+)+#+- L.9+9+9+9+9+C.C.9+,+,+/+C.C./+C.,+9+k ,+w+/+/+'.w.I.g+: : : [.: g+: : [.: : .r.U.e+l+l+l+l+l+l+e+e+e+l+l+j l+z.2 %+%+V.V.V.=.%._+h h r +.T 5++.^ %+e./+l+/+5+!+h h h h =.^+5+l+l+l+,.7+w+w+,+C.C.C.Y.- L.L.h+'+'+'+'+a+` R.q.q.:+1+2+| g.| 2+}.s e | [.^.r+i r+r+2.#.#.#._._.7.A+9 P.2+| s }.e | 2+e e 2+2+2+2+s }.s W.C c+(.(.(.(.n.(.n.(.(.~ (.~ (.(.~ (.9 e.e 2+| g.e 2+2+2+g+<.(+( {+-.u 9.9.9.9.9.9.9.9.9.!.{ z :+) 2+| 2+}.e g.| | e &+g+e | 2+e }.g.| | e 2+| e : : .].].j.w.'.$.k w s.a+a+@..+.+.+.+.+4+X.4+4+8.!+e 2+| g.e 2+2+2+S @.X.D j+| g.g.2+2+2+t+]+G o #.j+g.e 2+2+2+| e s 2+]+i u.8.2+| g.| g.}.T.r.].].].o.*.H.i.C+J.;+;+J.7.i J.N 4.i+6 !+!+e | 2+e 2+| 2+| 2+}.s e 2+2+g.Q @ @ @ @ F.F.{.l 3 l 6 2+2+2+| e s e 2+U.|+j.[ [ [ P X &.}.2+| g.g.2+g+0.F.l.] } q q D e 2+2+2+| g.s }.2+}.!+^ !+!+!+!+!+^ !+!+5+g.e 2+2+2+| 2+}.~+. . . . . . . ", ") 4.4.4.{ -.4.4.`.) ) 4.) ) ) ) 4.4.4.4.) 4.) 4.4.) ) `.) `.) ) ) ) ) 4.) 4.) ) 4.4.4.q+) `.4.&.&.&.`.) ) 4.) `.`.`.`.) `.&.&.9 9 >+(+o+o+o+o+D b+++b+A+J.8.8.8.++++B.)+i.i.)+H.a+a+s.s.w R 9+R 9+9+9+9+,+9+C.,+9+,+,+/+,+,+,+/+C.9+9+_ C.9+j 0 D.S : g+: : : x+|+[.[.r.[.: .r.v l+e+l+7+l+l+l+l+l+e+e+e+l+'.1+^ I h y I V.%+%+%+=.%.r +.T +.e.W ^+e+e+t.5+!+h h Z.Z.h =.r t.l+l+7+w+w+l+,.w+,.C.C.C.L.L.#+h+* '+'+` a+` q.f.G.!+g.e 2+| 2+2+2+2+| ~+2.i r+r+r+r+r+#.B.#._._.8.u.P.| 2+e 2+| | | g.2+2+e | 2+e 2+| : w.^ ^ ^ ^ n.^ n.^ n.^ (.(.(.(.(.(.(.9 +.2+x | 2+e 2+g.2+K.C i+{+q+u 9.9.9.9.9.9.9.9.9.9.9.8 E f+) 2+| g.g.2+| | 2+e &+~+W.2+g.g.2+| | 2+e e e g.> ].K.L O w.'._ k b w E+H+a+@..+@..+.+.+X.4+X..+X.k+2+r.2+2+g.2+e | g+G+i.9 !+| 2+g.e e g+: ]+G B.C+i+2+g.2+e 2+| e 2+W.X.J.-+!+g.e 2+| e 2+t+D.x+|+o.$.b )+++J.J.*+G.J.*+q+{+!+e | e g.2+| | 2+g.g.e e | 2+g.2+2+r.2+g.Q @ @ @ @ @ @ m+m+F.l H.}.e | 2+e 2+2+x | W.j.j.[ [ e+J.(.| | | 2+e e &+m+L K l.] } 7 9 e g.e 2+| e 2+2+| | 2+g.e e 2+| e e 2+| | 2+e e e 2+x e 2+~+. . . . . . . ", "4.4.) ) 4.4.4.4.) 4.`.) `.) ) 4.) ) 4.4.4.) ) ) ) ) ) 4.) `.`.4.) ) 4.4.q+4.4.4.) 4.4.q+q+4.q+) ) 4.) ) &.) ) ) ) 4.) ) &.&.&.9 &.i+(+b+(+A+++J.8.++C+++b+o+b+k+C+C+C+A+++X..+H.w H.}+H s.w a+)+H+w #+9+m.9+9+,+,+9+9+,+,+,+9+m.9+9+[+/+/+/+w+/+0 |+K.: ~+g+: : : [.: : [.r. .r.o.t.l+t.e+l+l+e+l+l+l+l+l+l+'.t.T ~ V.=.v.;._+;.v.=.=.;.C +.+.5+^ _+t.e+l+l+5+%+h h Z.h h =.r /+/+l+l+w+w+,.w+,.C.C.C.Y.g L.h+M.'+'+R.a+R.` q.7.X.g.e 2+2+}.2+x x | g+a+4 i i r+r+r+r+#.#.C+++++f+P.2+e e | | 2+| 2+e e g.| e e | x g+6+^ 5 ^ ^ 5 ^ ^ ^ ^ n.n.n.n.n.(.(.(.{+}.| | 2+| 2+e e 2+| C 9 `.1.9.9.9.9.9.9.9.9.9.9.9.9.u E 9 ) g.2+e g.x | | | 2+&+ .K.W.}.2+W.| | | | 2+e 2+| O |+O w.0 $._ R E+f H+1 .+S.G+G+G+.+.+.+)+)+^.X.c.| | 2+| e g.e 2+e *.Z 4.e | | 2+e e ~+w.G ]+#.#.( }.2+g.e 2+e s | g+N.J.q+2+e e 2+g.e W.B+5+s O Q.H.B.J.;+G.*+*+*+E ) e.e e e 2+e g.| | | | 2+g.g.g.2+s g.x x | 2+2+q l.@ @ @ l.@ @ m+l.m+3 1 e 2+s e | x 2+2+| ].3 v j.[ ) }.x | 2+| g.2+t+y+y+L l r.l.l.D 2+e e 2+e e 2+W.| 2+| 2+e e 2+g.e 2+| | | | 2+g.e 2+2+s 2+g+. . . . . . . ", "4.4.q+4.q+4.) ) ) 4.q+4.`.`.4.) ) ) 4.q+) ) ) 4.4.) `.) ) ) ) 4.) 4.4.) 4.4.4.q+) `.4.-.4.4.) 4.) ) ) &.) `.`.) 4.4.) ) `.&.`.&.9 &.f+j+8.C+C+)+C+)+C+J.J.z D k+k+i.B.G.k+B.)+^.)+H.#+H.B b #+p.'+H #+w #+#+9+9+C.,+,+,+,+C.L.m.C.a+_.'.l+,+/+_ k O S K. .: : : : : [.[.: : K.O 5+/+w+/+/+l+l+l+,+e+e+l+l+e+l+j '.a _+h.;.v.;.v.=.V.y =.r C +.+.e.!+Q.l+e+t.5+v.=.=.h h h h _+5+l+l+w+/+l+/+C.C.C.C.L.C.L.L.h+h+* * '+` R.q.f.q.j+g.e g.e }.g.x | | g+X 4 4 i i r+i r+o #.#.#.++>+P.e }.e x | | x | 2+g.g.e }.s | | g+6+2 2 2 2 5 5 ^ 5 ^ 5 ^ ^ ^ ^ ^ n.^ 9 }.| 2+r.x 2+2+e 2+O & {+q+u 9.9.9.9.9.9.9.9.9.9.9.9.u x.9 ) g.e }.2+| | | x | D+ .K.K.e e | | | x 2+e e g.e +.w.w.Q.$._ z.b E+H+@.@.G+]+S.G+G+! ]+! G+@.G+X.D e 2+r.x 2+e g.g.}.+.6 &.2+x | 2+g.g.D+z.o #.G B.A+!+2+2+e 2+}.}.2+x +G.i+| g.g.2+}.}.0+K.5+o.I.n+B.:.*+:+p+:+p+-.i+| | g.e 2+e }.g.| | 2+g+| 2+e 2+e }.g.x | 2+g+| B+3 l {.m+F.m+@ m+@ @ l.X.e 2+}.}.| | | r.W.r.3 3 v p.9 | | 2+g+W.| g+7 t.0 0 o.y+<+2+i+2+g.g.2+}.}.2+x 2+W.r.2+g.e 2+}.}.2+x 2+x x 2+2+e g.s }.g.|.. 0.. . . . . ", ") 4.4.4.q+q+{ 4.) ) `.`.`.`.) 4.) ) 4.q+4.4.`.) 4.4.4.) `.) 4.4.) 4.) 4.q+4.4.4.4.4.) 4.) ) ) 4.4.4.`.&.`.`.&.&.) &.) ) 4.`.&.&.&.&.9 f+c.6 .+B )+4+B B N.q.J.b+k+++++k+i.B.B.X.^.H+}+@.i.B.G P.#+9+9+L.w 9+C.m.9+#+m.,+,+C.C.,+C.9+y.y.k R ,+C.,+w.K.: S K.: : : : : [.[.K.I.& & t.l+l+l+l+l+e+l+l+e+l+l+e+'.l+t.a r h.;.v.%.%.=.V.I y ;.C +.+.T M e+l+e+l+t.~ =.r =.h =.h I r l+l+l+w+w+w+w+w+,.C.C.C.Y.Y.L.h+'+* '+'+` ` q.q.c.2+| 2+s }.2+x 2+| x 5+F i 4 4 r+r+r+o B.B.G k+++!+| e | g+g+g+e e 2+| 2+e }.s x | g+> T r r r 2 r 2 2 2 2 5 ^ 5 ^ ^ ^ ^ i+}.| | | | e | 2+2+> & {+q+9.9.9.9.9.9.9.9.9.9.9.9.9.u E f+) g.}.}.2+| | | | g.&+ . .K. .e | 2+| x 2+2+| 2+e }.e <.$._ z.X E+E+1 1 @.G+G+G+! G+G+G+]+]+G+]+G+8.!+| x 2+2+| 2+g.}.e (+W | x | g.| | D+]+6 ]+o o o j+e 2+2+2+s }.| x e 9 X.e | | 2+}.}.&+Q.t.o.5+N.i *+p+:+:+:+E i+2+| e | | g.e }.g.x | 2+x e 2+2+2+e }.e x | 2+r.2+|.0 0 o.y+<+3 l {.r.m+m+/++.e }.e x | 2+r.2+2+L 3 v G.!+| | 2+| | e D+o.N.b b b b n+M i+g.| 2+2+}.s | | | | | g.2+2+2+s }.| x | | x g.2+| 2+s }.2+g+0.0.. . . . . ", "4.4.q+q+4.4.q+`.`.) ) ) 4.) 4.) `.-+-+4.q+q+) ) ) ) ) ) ) ) ) 4.) ) ) 4.4.q+) ) ) q+4.q+`.) ) &.) ) `.&.&.&.&.`.) ) ) `.&.`.&.&.&.&.9 i+i+8.k+X.i.B.k+X..+4+X.X.)+C+++++8.k+k+)+X.w H *+++X..+'+w m.p.9+9+R 9+#+9+#+,+9+[+,+9+,+C.9+! @.R m.'.,+/+'.O S K.K.: : : : : : : 6+& & & & t.l+l+l+l+l+l+e+l+e+l+/+/+'._ r ^+h.;.v.=.=.I =.=.I %.r & +.5+t.l+t.l+e+5+_+;.5+=.=.v.h I h.t./+7+7+w+w+w+,.,+,+C.C.Y.Y.L.g h+* * ` * ` ` q.:+2+2+2+2+e g.| 2+e g.}.F F 3+4 4 r+r+#.B.i.Z )+k+++. . . . . t+k+}.2+2+2+2+g.g.| 2+S S T T T T r T r r r r 2 2 5 2 !+!+^ i++.| e e e 2+| 2+2+S T `.-.9.9.9.9.9.9.9.9.9.9.9.9.9.8 E f+) | 2+e 2+| g.e e 2+T.{.l l l r.e 2+e g.g.| 2+2+2+g.g.|+& z.z.z.5 1 @.G+c+c+G+]+G+]+]+]+G+]+]+]+i.i.k+g.e g.2+| 2+W.g.| >+!+e e e 2+| g+: ]+]+o ]+]+i.D 2+| 2+2+2+g.2+| x 4.+.g.| 2+| 2+e t+y.5+s 5+4+J...:+..:+p+-.}.e e e | 2+2+2+e 2+W.g+k.&+&+&+T 5+2+g.2+| 2+g.g.g.: 4+B N.m.p.t.0 y+y+<+3 U.X.2+2+g.| 2+2+e e 2+| v y+) }.| 2+g.e e W.t+^.C+A+b+b+b+A+8.&.2+| 2+2+2+e 2+| g.W.g+[.k.[.|.g+g+g+k.[.g+|.g+|.g+[.[.g+g+B+0.Q 0.. . . . ", ") 4.4.{ q+4.) ) ) ) `.`.4.) 4.4.`.) ) q+4.4.4.) 4.) ) 4.) 4.) q+) ) 4.4.-+) 4.q+4.4.4.) ) ) ) ) q+`.`.&.`.&.&.) ) 4.) ) ) ) ) `.&.&.9 i+(+k+8.k+6 B.4+X.)+C+B.J.i.4+C+++8.++i.)+H.H.H+)+}+'+R m.9+- #+#+H.R 9+9+9+9+,+9+R ,+,+,+C.9+L.m.k #+_ 9+R '.o.K.: : g+: g+: S S C e.T & & & j l+l+l+/+l+e+l+l+l+l+l+j +2 r h.;.%.=.V.=.h I I =.=.r C +.& l+e+l+l+l+ +_+!+5+h v.!+h =.=.5+/+7+l+7+7+w+,.w+C.C.C.C.g Y.g L.* * * '+` ` ` :.M 2+2+2+g.g.2+e }.e 2+4 F F 4 F i i r+r+#.G k+k+k+6 k+k+k+8.k+`.}.| 2+2+2+2+e 2+g.|+S C C C C T C T T T r T r 2 2 2 2 2 i+5+2+}.s e 2+2+2+2+| $.) 1.9.9.9.9.9.9.9.9.9.9.9.9.9.1.E o+) 2+2+e g.2+e }.s 2+&+F.F. .l .K.}.}.e 2+| 2+2+2+g.g.2+O a E+f 3.1 G+G+]+G+c+G+]+]+]+]+]+G+]+G+]+G+c.}.}.2+2+2+2+2+g.2+&.e e }.g.2+2+0+w.]+G+]+]+! ! o+s 2+2+2+2+e g.2+2+) e 2+2+e | 2+W.|.y.Q.o.& B 7.*+..*+*+E 6 e }.e g.| g.2+2+e 0+. . D+g+g+r.X.*.2+g.g.2+g.}.}.2+r.b+J.++++B.)+4+N.p.l+e+y+6 e g.g.2+e }.e e | W.v B D e 2+g.e }.e ~+g.*+:+N E E x.-+N q+e 2+2+2+2+g.g.2+s W.. 0.. . . . . . . . 0.. . . . . . . . . Q Q . . . . . ", "`.`.4.q+4.) ) `.) `.`.) `.4.) ) ) ) 4.4.4.&.) ) ) 4.) ) 4.4.4.) 4.4.4.4.) `.4.`.) 4.q+) ) ) ) ) ) ) `.&.) &.`.) ) ) ) `.&.) ) `.&.&.&.9 c.8.D 8.)+C+k+i.B..+.+B N.X.i o+8.++k+)+B.k+C+X.1 w E+H+E+R H s.'+w k m.k m.R [+H #+R [+m.C.9+#+s.9+#+m.k /+j D.S S S : S ~+C ; %+r & T T & Q.t.l+e+l+l+l+l+e+l+e+j t.2 r h.;.=.=.h y h =.I V.I =.;.C +.I.l+l+e+l+e+t.!+5+*.=.h.!+h %.%.a e+l+l+7+w+l+/+w+w+w+,.C.C.Y.Y.h+L.'+* * '+` q.q.k+e g.2+2+2+2+g.e e W.E+F F F F F 4 i #.#.B.k+k+k+8.8.8.(+b+j+`.e | 2+g.g.g.2+2+2+S S C C C C C C C T C T T T T r a r !+i+}.2+e s 2+x 2+e e S T ) -.9.9.9.9.9.9.9.9.9.9.9.9.9.~.z o+) g.g.2+2+2+e e 2+x &+F.l l l l l x }.e | 2+e g.e 2+2+2+2+w.z.5 1 1 1 G+G+G+]+6 ]+]+]+c+6 6 ]+6 Z Z >+}.e 2+| 2+e e 2+2+; g.e e | W.g.t+M @.G+S.! S.S.++!+2+e e e 2+2+2+e j+g.| 2+g.e g.T.].5+s D.Q.N.C+;+;+b.b.-.}.e e g.| | g.e e &+. r.t.p.m.#+N.o+M e 2+2+| g.e e | K.z z z u.f+o+G.A+B.4+N.p.B *.2+2+2+2+e s | | 2+y+o+!+| 2+2+s e | t+o E A 8 !.!.9.9.9.9.+.2+g.g.e 2+2+2+e e r.U.r.g+l.] |.] } } ] ] [.] |.} |.7 d q Q q 0.. . . . ", ") 4.4.-+&.-+) `.`.`.4.) `.) ) `.) ) ) q+) `.) ) 4.q+4.4.) ) ) `.`.) q+4.`.`.) ) ) ) 4.4.) 4.`.) ) &.&.) ) `.) ) ) q+) ) `.`.) `.) ) &.i+(+b+(+8.i.)+8.++i.i.k+i.X.)+J.G.b+8.8.++C+i.B.i.P.m.a+2.P.H.#+m.#+@.#+9+9+#+#+R m.- #+s.m._ #+H.m.C.X [+C._ /+0 |+|+> S 6+h.=+c y ^+T & & & & t.l+t.e+l+e+l+e+l+l+t.& r h.v.=.y =.h =.h =.h =.y %+h.+.'.t.e+l+e+l+/+/+ +t.!+~ 5+5+=.!+^ a l+7+t.l+w+w+l+/+w+w+,.C.C.C.L.L.g * * * '+` ` q.b+e e 2+2+2+| 2+g.2+2+}.F F F F 7.7.7.7._._._.8.8.8.(+b+(+D (+`.e g.g.e g.2+2+2+x g+~+6+6+<.<.6+<.6+<.<.<.C C C T C T T c.+.| 2+g.2+| 2+e e | $.`.-.9.9.9.9.9.9.9.9.9.9.9.9.u { u.G.`.e 2+2+| | 2+e 2+| &+F.F. .l l l l |+e | 2+g.g.2+2+| | | e }.5 G+S.G+G+]+c+]+c+]+6 ]+]+]+]+6 ]+6 ]+++P.g.| 2+e e g.2+2+e 2+g.e | | 2+D+P.3.@.S.@.S.}+S.6 g.e g.2+2+| | 2+}.2+| g.e e 2+t+s }.D.|+}.m.^.:.J.;+*+9 | | e 2+| 2+e e W.. }.H H N.#+w N.D M g.2+2+| | g.2+2+g.!.!.u u 8 { E u.o+J.C+4+N.; 2+2+| | 2+2+2+| e s ) e 2+| | g.e W.k.E 8 9.9.9.9.9.9.9.9.!+e e g.2+2+| | 2+g.K.x+r.m+[.[.} ] } } } } } ] } 7 7 7 d d Q Q . . . . . ", ") 4.4.) ) ) `.4.4.) ) 4.4.`.) 4.) -+) 4.4.4.4.4.4.4.) ) ) ) ) `.`.4.4.) ) `.) ) ) `.4.) q+) &.`.`.) `.) 4.4.) &.q+q+q+`.&.&.`.) ) ) &.9 f+D c.b+6 ++8.8.k+8.i.i.X.)+.+C+C+8.++++k+C+++)+E+#+H }+a+S.G+P.4+^.w b R m.a+E+R 9+9+w R 9+H .+R m.#+k ,+,+_ $.'.C C r ~ V.=+h =+;.T T T +.& t.l+w+/+l+l+l+l+0 j Q.C ^+;.=.=.y h h y y h =.I =.%+2 Q./+l+l+e+l+l+e+p./+5+!+_+ +*.%.!+[+t.l+l+7+l+7+l+l+w+w+w+w+C.C.Y.Y.g Y.g g * * * ` ` 4 !+e e 2+g.g.2+e e g.e H+F ;+F F F F 7.A+A+8.< n D D D o+D c.) }.g.g.2+g.g.2+e 2+S ~+6+6+6+> <.> 6+6+6+<.<.C <.C C C +.c.5+2+g.e g.g.e g.g.> & &.4.1.9.9.9.9.9.9.9.9.9.9.9.!.E u.D `.g.g.g.e 2+2+e e e &+l l l l l l l l e e e 2+2+g.e e e 2+e D.& @.1 S.G+G+]+]+]+]+]+]+6 ]+]+]+6 ]+6 Z j+e e e 2+2+e e e e 2+g.e e e g+: P.P.3.E+f E+H+B c.e 2+e g.e e 2+e e e g.e 2+e W.Q s |+K.K.g.Q.N.q.C+7.G.c.2+g.e e e e 2+g.k.U.L.L.H L.#+N.N.o+M g.g.e 2+2+e e e |+9.9.9.9.9.9.9.!.{ z o+J.q.(+e g.e 2+e s e e 2+!+j+2+e e 2+2+e k.m.8 9.9.9.9.9.9.9.9.9.c.g.2+e 2+g.e 2+g.e W.y+L r.l.] |.7 } 7 7 } } 7 } 7 } 7 d Q Q 0.. . . . . ", "4.4.) &.`.`.&.&.) ) ) 4.q+) `.4.4.q+4.4.) ) &.) ) ) ) 4.`.) ) ) 4.) `.`.`.) 4.) ) ) ) -+`.) ) `.) ) `.`.) `.) 4.{ ) `.&.&.9 &.`.) ) ) &.i+D c.8.8.b+>+8.++A+++++k+i.C+C+k+++8.k+)+)+)+i.)+E+'+s.H.B 2.i.w w s.H }+P.#+)+P.H+H.)+#+y.#+s.m.k m.[+R ,+9+R R T r _+~ V.=+=+=+I r r e.T & 1+/+'./+t.l+l+l+t.Q.& r h.%.=.V.=.h =.y h h I V.%+h.$.Q.e+e+l+e+e+7+t./+l+t.[+M t. +~ !+t.e+7+l+7+e+7+7+l+7+w+,.w+,.,.C.C.Y.Y.g g * * * '+` q.7.g.2+e s }.s e 2+e g.2+! F F F 3+3+3+n n n D o+( f+( f+f+>+) }.e 2+2+2+e e }.}.> ~+6+> <.6+6+<.> 6+> 6+> 6+6+6+<.C <.j+!+e s e e e 2+2+2+W.w.9 `.{ u 9.9.9.9.9.9.9.9.9.!.{ -+:+b+`.2+g.g.}.}.}.g.g.e k.3 3 l l l l l 3 ].O e 2+2+2+g.s }.s e 2+e T G+G+G+G+G+c+]+]+]+]+]+]+]+]+]+]+G+G+D g.e e 2+2+g.2+e }.}.e e e e k.o.5 E+E+E+E+E+w w D e | g.2+e }.}.e e e e 2+| e g+T.|+K.: : r.s +B 4+C+G.k+}.}.g.g.e g.| g.&+/+h+L.H L.#+s.N.o+*.2+g.}.}.}.g.2+s e 9.9.9.9.9.9.9.9.!.u x.9 J.J.!+e }.}.e 2+e e | g.5+g.e }.}.e 2+t+u.9.9.9.9.9.9.9.9.9.9.-.g.| e 2+e }.}.e e 2+}.x+r. .[.] } 7 7 7 7 7 d d d d q q Q Q 0.. . . . . ", "-.) ) &.&.`.&.) ) `.) 4.4.) 4.) -.{ ) q+`.&.`.) ) ) 4.4.) `.`.&.) ) ) ) ) 4.4.4.4.`.`.`.) ) ) ) ) ) `.`.) &.) ) ) `.{+&.&.`.) `.) ) ) &.9 i+c.>+D f+i+o+8.8.b+c.8.++8.b+b+k+b+++6 i.C+k+)+@.H.H.a+a+4+C+k+b #+a+C+3+H+i.H..+_.G+R m.9+9+R m.R b X b R R _ *.r ^+_+%+V.V.y =+_+r T & +. +t./+e+l+7+l+l+t.Q.C ^+;.%.=.y h h y y h V.=.V._+a Q.l+l+e+e+e+7+e+e+/+e+e+t.e+e+0 a +e+7+7+e+e+7+7+l+7+w+7+7+w+w+w+,.Y.,.,.Y.g g * * * * ` q.!+2+2+s }.e U.2+e 2+2+}._.F ;+n ;+n ;+5.*+( f+f+z z z z z q+}.g.| 2+2+| s }.s g+S <.<.<.<.> <.> 6+> 6+> 6+> 6+> <.> j+e.}.2+| g.g.2+U.2+W.C 5.9 -+{ !.9.9.9.9.9.9.9.!.8 x.z :+J.`.2+| g.s }.g.| 2+g.T.3 3 L 3 3 3 L 3 3 x+s | 2+2+2+s }.s | 2+e x+a ]+]+o G o ]+]+]+c+]+G+]+]+]+]+]+X.c.}.g.e | 2+2+| e e }.2+| e e t+ +b b w w w w b N.C+a 2+2+| e e }.g.| 2+e 2+2+2+&+~+K.: [.|.: U.}.t.N.B G.; e e | 2+e 2+2+2+0+L.H L.#+H L.N.4+9 *.| 2+e }.e | 2+e |+9.9.9.9.9.9.9.9.9.9.!.{ z b+8.s }.s 2+2+e e 2+| 2+| e }.}.2+g+K.!.9.9.9.9.9.9.9.9.9.9.9.!+2+2+| g.}.s e W.g.}.y+U.r.l.] 7 7 7 7 q q q d q q q Q Q 0.. . . . . . ", ") 4.4.`.`.4.`.) `.`.) ) 4.`.q+4.) q+4.4.4.) ) `.&.) 4.-.q+) 4.`.4.) `.`.`.`.4.4.) ) `.`.&.`.) 4.) ) ) `.) `.`.&.) -+`.&.) `.&.`.`.) ) &.&.9 D o+o+b+(+b+J.(+*+D 8.k+++8.++++++A+(+k+B.i.X.B.)+X..+H.s.^.^.z+#+B P.N.a+i B B.i.H+R R R m.#+E+E+G+5 2 2 ^+^ r T ^+~ %+V.V.V.=+V.h.T T +.& '.,+t.t.e+e+l+t.+.r h.v.%.V.h y h y h y y V.%+r Q.e+e+l+l+e+e+e+7+e+7+l+e+e+e+l+l+e+l+e+e+e+7+e+e+7+7+e+7+7+7+7+,.w+7+,.Y.Y.V Y.g g * * * ` q.2.2+e 2+2+2+r.2+e 2+2+g.2+6 Y n Y 5.*+( f+>.z `.E E -+E z -.}.e g.g.| 2+e 2+2+~+S C <.<.<.<.> <.> <.> <.> > 6+> 6+> j+}.g.x x g.g.g.e 2+W.O (+( z -+1.!.9.!.9.9.9.!.1.x.E f+*+J.`.2+| g.g.2+2+x 2+g.k.d+d+j.j.j.v v j.v y+o.6+2+| 2+e 2+2+W.| e 2+e 1 G _._.3+A+_.o ]+]+G+G+1 G+G+G+c+k+!+g.e g.g.| 2+}.2+2+x | g.2+D+z+z+b b n+n+n+n+#+H.; g.2+| e g.2+| | 2+e 2+2+2+t+|+S K.[.|.|.l.U.y+[+N.C+6 2+| | 2+e g.g.g.g+'+'+h+L.L.L.s.A+q+}.| g.e 2+2+r.| e O 9.9.9.9.9.9.9.9.9.9.9.!.{ f+9 }.2+2+x | 2+e e e | 2+e 2+2+x D+B !.9.9.9.9.9.9.9.9.9.9.9.9 g.2+| e 2+2+| x 2+s 5+<+r.l.l.] 7 7 7 7 q q q q Q q x+0.0.. . . . . . ", ") ) `.`.`.) `.`.`.) ) `.`.q+-.4.`.-+) ) q+q+) `.) `.) 4.q+) 4.`.) 4.) `.`.`.`.) `.`.&.`.`.) q+) ) ) `.`.) `.`.`.`.&.&.&.9 `.) ) `.) ) &.`.9 c.c.>+b+c.8.b+b+G.c.8.++++++C+k+++++A+B.k+k+C+i.)+)+)+i.X.P.G+}+w @..+Z G+H..+H.H.E+w P.E+E+P.^ 2 ^+^+h.;.v.%.v.h.^+_+%+%+V.V.V.=+%+r & & & [+9+t.l+l+l+j Q.T r ;.%.=.y y h h y y I V.%+^+$.j t.l+e+e+l+e+e+e+e+e+e+l+e+e+e+e+e+e+e+e+7+e+7+P e+e+7+7+7+7+7+7+,.,.m ,.p.,.Y.Y.g h+* * t '+` !+e g.x x | | 2+e e g.2+s a 5.E.E.( ( z `.E { 4.{ x.4.-+-.e 2+e e 2+e e W.W.0+> C C C C <.<.<.<.<.> 6+6+> <.> > > j+}.W.| | | 2+e g.2+W.O W (+>+z -+{ 8 8 !.!.8 { x.E u.:+G.C+`.2+2+s 2+r.x | 2+2+k.e+e+[ [ d+y+y+[ [ e+e+I.s 2+e g.x x | U.2+e 2+s G 3+n n n < 3+_.G o ]+]+]+]+! i.6 8.2+2+e e | g.e | x | 2+| g+: n+n+n+R z+#+n+#+m.p.c.e 2+2+}.| x | | 2+2+e e W.&+<.6+|+K.: [.l. .U.}.p.B 8.| | | | | g.e 2+2+N.'+'+s.H '+b+-.!+g.2+e g.| | | 2+2+s 9.9.9.9.9.9.9.9.9.9.9.9.!.x.z P.| x | 2+2+2+g.e 2+e e | x W.t+p+8 !.9.9.9.9.9.9.9.9.9.9.9.!+2+2+e 2+W.2+| 2+2+e !+y+r.l.] ] 7 7 7 d q d <+X.&.i+~+. . . . . . . ", "`.&.) ) `.4.4.&.`.4.q+) q+4.) ) ) ) 4.q+q+4.q+4.4.) 4.q+-.q+q+) 4.q+4.4.) `.`.`.&.`.&.) `.`.`.`.`.`.&.`.`.`.&.`.`.) &.9 9 ) `.) `.`.`.&.) &.9 9 c.f+i+b+c.c.o+o+c.++++8.++C+++k+k+C+++8.B.i.X.)+)+i.)+++)+@.)+X.^.)+H+H.w H+B.H..+i.1 ^ ^+h.h.;.v.v.%.=.=.=.=.;.;.%+V.V.V.V.V.V.h.T C & #+9+'.t.l+t.R & r h.v.V.y h y y h h =.y %+^ T '.j e+l+/+l+e+p.e+7+t.e+e+l+t.e+l+l+l+l+e+e+7+e+e+7+7+e+l+7+7+w+w+7+,.,.,.,.Y.,.g Y.h+h+* * '+` ` ` 5+g.| | 2+r.x g.e 2+e }.e | a c.&.x.4.{ { 8 { 1.8 u 1.u e e g.2+e }.}.| | W.> C C C C C C <.<.<.<.<.> <.> <.6+> j++.| 2+x r.2+2+e 2+e |+6 8.(+o+z `.4.x.{ { ~.E z u.*+G.;+C+`.2+e }.g.x 2+x r.| |.,.7+l+l+7+P P l+l+l+l+w+}.}.}.e x | | g+| e e 2+}.n G.*+*+5.n < _._.G G o ]+]+i.)+c.| 2+e e g.}.}.| x 2+W.W.&+s z+n+n+R y.n+R m.#+m.(+e g.}.}.| | 2+x x 2+e g.k.W.& +.w.D.].K.: .r.<+0 N.j+| 2+| x | g.e 2+s 1+k+A+i b+-+{+5+g.2+e }.e x 2+| r.x 6+9.9.9.9.9.9.9.9.9.9.9.9.9.u E i+x | 2+r.| 2+e g.2+}.}.| | g+r.= A 8 !.9.9.9.9.9.9.9.9.9.9.`.e }.}.2+x 2+x x 2+g.e !+X.X.p.t.y+t.p.B.o+&.c.X.+.g.g+. . . . . . . ", ") `.`.`.`.) &.`.) &.`.4.{ ) 4.`.) 4.&.-+4.4.q+q+4.) -+4.q+) 4.q+4.-.q+4.q+) &.`.`.) `.&.&.`.`.`.`.) `.`.&.&.9 `.&.`.`.`.&.&.) ) `.`.) `.`.&.`.&.9 i+D >+o+o+D c.c.k+k+k+k+C+G.c.6 C+k+C+k+k+i.)+i.i.X..+1 .+)+i..+X.1 H.}+}+E+H+1 ^ ^ _+v.v.%.%.%.=.V.=.I I h =.%.; V.V.=+=+=+I v.r T & l+,+/+l+l+'.'.T r ;.=.h =.y h h y y y V._+T t.l+t./+l+l+l+7+l+l+e+e+l+t.7+l+/+l+l+e+l+l+7+l+7+7+e+e+l+7+l+7+7+7+,.7+,.,.,.,.Y.p.V Y.* Y.* * * '+` p.W.x 2+| r.2+2+2+2+e }.e x | | | 5+P.c+W 8.(+8.(.1 !+}.2+g.| 2+e }.e | W.0+> r r r r C C C C C <.C <.<.<.<.6+6+j+}.x 2+W.| 2+2+2+2+e > 1 6 8.D >+u.z z E E z >.u.o+*+J.i 2.&.2+}.}.2+x | | x e |.C.C.C.J ,.w+w+w+,.,.C.C.C.}.+.e r.2+2+r.2+2+| 2+e a E.E.p+E.:+E.n 3+_._.k+_.r+C+i.>+}.g.| 2+g.}.s x x | x | 0.$.R M y.y.y.y.y.m.p.p.++5+2+s }.2+| | x | 2+2+2+t+I.T $.& s O U.l .U.<+y+p.b+2+| | x g.2+2+g.e }.e 5+(.1 }.g.2+2+2+s }.e x | | x 2+g.(.9 i+9.9.9.9.9.9.9.9.9.9.!.{ 4.e | | x 2+2+| 2+e }.e x x D+w p+= ~.8 !.9.9.9.9.9.9.9.9.9.9.c+}.}.| x | W.| g.| | 2+}.}.!+!+(.X.!+!+}.2+e e }.2+g+. . . . . . . ", "`.`.`.) `.) -+`.`.-+4.`.q+q+q+4.4.) ) -+) 4.4.q+-.4.) 4.q+q+4.4.4.4.q+4.q+q+`.`.) `.&.`.) ) ) `.`.`.`.&.&.&.&.&.&.`.&.&.&.&.`.`.`.) ) `.) ) ) `.&.9 i+o+8.++G.G.>+c.>+D c.k+++8.k+i.k+k+8.k+i.i.B.)+X.)+i.8.)+1 X.(+6 H+.+P.i.^ ^ h._+%.%.%.=.=.=.=.y =.y =.h y =.V.V.y h c h h V.r e.Q.l+,+,+/+'._ & T ;.=.y h h y y h y y V._+2 '.j e+e+l+l+l+/+e+l+7+/+/+/+7+e+7+p.l+t.l+l+l+l+e+l+l+/+e+l+7+7+l+7+w+7+,./+,.,.,.,.,.g Y.g g * * * '+q.` t.g+2+e e e | 2+2+2+e 2+| 2+e g.g.2+2+2+2+e g.| | e e e 2+| 2+2+e g.| g.W.6+r r r r r r C r C C C C C <.<.<.<.j+}.| 2+g.e 2+| 2+| W.S 2 1 6 8.(+>+f+u.u.u.9 E.*+n J.i C+^.`.| 2+e 2+2+2+g.2+g.0+L.L.- Y.Y.C.9+C.Y.Y.C.g L.L.}.g.| 2+e g.e 2+2+2+| e !+z E = z >.( *+< 3+++r+#.#.B.++(.2+| 2+| 2+g.| 2+2+g.W.&+y.m.R n+y._ [+y.y.9+p.H.X.2+2+e | | 2+g.e 2+| | t+a T e.e.$.0 o.D.<+<+v e+p.'+X.| e g.g.| | 2+2+e 2+| 2+e e e | 2+| 2+e 2+| 2+g.g.e | | 2+e 1.9.9.9.9.9.9.9.9.9.9.8 x.X.| g.2+e 2+| 2+2+e g.| W.0.7.*+p+= x.A 8 !.9.9.9.9.9.9.9.9.q+e e 2+| 2+g.g.g.| 2+| g.e 2+| e e g.| W.| 2+g.e 2+g+. . . . . . . ", "`.`.) 4.`.&.`.&.&.4.q+) `.`.-+q+4.q+`.&.) 4.q+4.) ) ) ) 4.-.4.4.q+4.4.4.) q+) ) &.`.&.`.) ) ) &.&.`.&.&.&.&.&.&.{+`.) &.&.{+`.`.`.) ) `.) ) ) `.&.&.i+c.i+D c.c.G.o+9 c.b+8.b+8.k+C+i.A+D 6 C+)+X.)+C+i.++++Z X.G.D X..+P.P.^ ~ _+%.%.%+=+y =.y y y y h =.y V.I V.V.V.=+h c h =+%+r & t.,+,+k ,+l+$.T ^+%+=.y h y y h y y V._+2 '.'.'.l+l+l+l+l+/+l+7+/+7+l+/+/+/+l+7+l+7+l+e+p.l+l+l+7+e+w+7+l+7+l+7+7+7+7+,.,.,.,.Y.,.Y.Y.Y.g h+* * * ` ` q.0 ~+}.s 2+2+2+2+2+e e 2+e s s g.| 2+2+2+2+g.2+e }.e g.| 2+2+2+g.g.e 2+S 6+^+2 r r r r r r r r C r C C C C C j+5+2+s }.e 2+2+2+2+W.S a 5 c+G 8.D 5.>+5.o+o+G.;+7.r+C+2.q.&.2+2+g.2+2+e s s 2+[.* s.h+L.h+h+h+h+L.L.L.L.s.'+m.}.2+g.s s g.| 2+2+2+e e k+{ ~.~.E >.f+*+G.3+C+B.)+)+^.j+| 2+2+2+g.e 2+2+s }.g+K.n+n+n+y.y.y.*.*.[+[+p.p.j+2+2+g.g.2+s }.e 2+2+g+~+a a a a *. +Q.0 v y+[ e+p.B C+}.}.e 2+| 2+2+2+e e 2+e }.e g.| | 5+2+g.g.2+g.}.e e | g.2+e T 9.9.9.9.9.9.9.9.9.9.!.{ i+g.}.}.g.| 2+2+2+2+g.2+k.r.7.;+*+:+>.E x.{ 8 !.9.9.9.9.9.9.9.9 W.2+2+s }.e 2+2+2+2+g.g.2+2+e }.e g.| g.2+2+e 2+g+. . . . . . . ", "&.`.`.`.`.&.`.`.`.-+4.`.`.) q+-.1.q+) ) 4.4.{ ) ) 4.4.4.-+) q+-.4.4.q+4.) ) q+`.`.&.) q+) ) `.`.`.&.&.&.`.&.&.&.&.`.`.&.&.&.`.&.&.) ) ) ) ) ) `.`.`.9 >+9 c.G.G.b+b+G.D D c.G.>+++8.k+k+C+6 i.X.B X.i.i.B.++++@.A+9 6 H+1 ~ _+_+%+%+V.I h =+I h h =.y y =.=.=.=.%+V.=+=+=+=+V.%+%+r 1+/+/+/+,+,+t.$.^+v.y y h h h h y y =._+2 $.j l+/+l+e+l+l+l+l+l+l+l+l+l+7+7+/+/+l+/+/+,+l+l+l+e+l+l+l+e+7+l+l+7+/+,.,.7+7+,.,.,.,.,.Y.g Y.Y.* * * * '+` q.q.l+k.| x 2+2+g.g.2+2+2+e e e | | 2+g.e g.2+| 2+s e 2+| 2+g.g.2+2+| e W.6+^ 2 ^+2 ^+2 r r r r r C r C r C T j+5+2+e s 2+x 2+e e | S r 5 n.6 _.8.D 5.*+n b+b+++r+B.2.^.4+&.e 2+2+2+2+e }.2+| k.'+'+'+h+'+s.H * * h+* * H s.'+y.e e s e | | e e g.2+2+2+>+8 A ~.E N f+*+< ++#.)+)+4+o+| g.e e 2+2+2+2+e e &+s y.n+m.y.[+[+[+[+[+[+m.m.c.e g.2+2+2+e s 2+| 2+T.s 2 z.z.a y._ +'.e+[ e+/+C.N.2.M e e | 2+e g.g.2+2+| e }.e | W.D+g+M 2+2+2+2+s e | | g.e e 5+9.9.9.9.9.9.9.9.9.9.!.A 4.5+e s 2+| 2+g.g.2+2+2+D+[+2.++J.G.*+f+u.z E x.{ 1.!.!.!.9.!.!.o+g+| e s 2+| 2+e g.g.2+2+| e }.2+| 2+g.g.2+2+2+g+. . . . . . . ", ") ) `.`.) ) ) ) `.`.`.&.) ) { -.-.q+-.-.) 4.q+4.`.q+-.) `.-+q+4.4.4.4.) ) q+) `.) `.) `.&.`.`.`.`.&.`.&.&.`.&.&.&.`.`.&.`.&.`.`.`.`.) `.`.) `.) &.&.9 i+c.b+8.b+c.c.c.>+i+c.D c.++8.D k+k+k+k+k+6 X.k+6 X.X.i.i.C+C+6 (._+_+=.%+=.y I h h h h h y V.h =.V.=.V.; %+%+V.=+V.; ~ ~ 2 a R 9+,+/+/+_ $.r ;.V.y y y h h y y V._+r '.'./+,+,+t.p.l+l+/+l+l+l+/+7+/+l+l+l+l+7+p.p.w+l+l+t.l+/+l+l+7+l+7+/+7+7+l+7+/+,.,.,.,.p.,.,.Y.g Y.g h+* * ` * ` ` q.H : T.W.e e 2+2+2+| | e 2+| 2+e e g.2+| 2+| g.g.| 2+e e e 2+| 2+| ~+6+^ 5 ^ 2 ^+2 2 2 2 r r r r T T T T c.}.| 2+g.| | g.e e W.S 2 ^ (.G W < b+n D b+< ++C+B.2.^.^.4+&.g.g.2+| | | e 2+| ~+'+}+'+'+'+'+'+h+'+'+'+'+'+'+}+4+*.e e 2+2+2+g.e 2+2+2+| e `.!.8 x.E u.:+;+++B.)+X..+c.}.g.e g.2+2+| | g.e t+*.n+n+y.y.,+[+[+[+m.9+y.p.J.+.2+2+2+| 2+g.2+| 2+D+a 5 2 z.R M R 9+,+t.l+l+,+L.'+2.J.e | | 2+e e g.2+2+| | g.2+g+0.D+C+6 2+2+| 2+e g.| | e e e I.9.9.9.9.9.9.9.9.9.!.8 x.z 6 g.2+| 2+g.e e 2+2+W.Q B ^.2.C+7.J.G.G.:+f+z N z E E { A { A x.o+g+g+e 2+| g.g.e 2+2+| | | e 2+| 2+e e 2+2+2+g+. . . . . . . ", "4.) ) ) q+) q+4.`.`.`.`.-+4.`.4.{ q+4.q+-.4.4.4.4.q+q+`.`.-+) q+-.4.4.4.) 4.q+) `.&.`.&.`.) `.{+&.`.`.&.`.&.&.&.&.&.&.`.`.`.&.`.`.&.&.&.) &.`.&.&.9 9 9 i+D c.c.J.G.c.G.G.c.o+c.c.b+b+C+k+8.8.++b+D ++8.k+6 k+k+k+; (.~ %+%+=.I V.c h h j+h =+c I =.V.V.=.%+v.~ %+~ ~ ~ ~ ^ 2 b z.n+#+[+9+,+,+R T h.%+V.=.y h y y y V._+z._ '.l+/+,+w+/+,+/+/+l+/+/+7+p.w+l+/+7+/+/+l+7+l+/+w+w+p.l+7+e+/+l+l+l+7+w+w+,.w+7+,.w+7+,.,.Y.p.Y.g p.g h+* * * '+q.` q.q.q.l+B+&+g+2+g.g.2+2+e e g.g.g.2+g.e 2+e 2+g.e e g.g.e | W.~+T.t+. C ^ ^ ^ ^ 5 ^ 2 2 2 5 2 2 r 2 r T r 5 }.| | g.2+2+U.2+2+W.> n.6 W 8.(+D D D G.b+J.7.i 2.^.a+a+'+)+e 2+2+| | x 2+2+2+[.'+a+'+'+'+'+'+'+'+'+'+'+'+'+a+'+a+}.| 2+2+2+2+2+2+x 2+| r.}.1.8 { E E f+G.++B..+4+.+)+e.2+| 2+| 2+2+x | x B+m.n+m.n+y.[+,+,+[+,+9+p.m.B 5+| 2+| x | 2+2+| W.T.5 P.!+z.z.z.R 9+9+C.,+w+C.h+a+o n D |+g+2+e 2+g.g.e 2+2+2+0+t+k.C+*+J.+.g+2+2+e e e g.e 2+2+O !.9.9.9.9.9.9.9.!.8 ~.x.p+c.2+2+2+2+2+| 2+| 2+&+| B 4+^.)+C+C+A+A+J.J.G.o+o+o+f+u.z N E >.p+*+5+D+k.W.2+g.g.g.e e 2+2+e e e g.2+2+W.&+t+. . . . . . . . ", ") ) &.-+4.) `.`.`.`.`.&.`.) `.4.4.4.-.{ q+4.q+4.4.q+&.`.`.`.) 4.q+) ) 4.4.4.q+) `.`.) `.) ) `.`.`.&.`.`.&.&.9 &.&.&.&.`.&.&.&.&.&.&.&.&.&.) ) ) &.9 i+i+9 i+D o+i+>+D b+8.b+b+b+8.b+8.k+D 9 c.k+8.++k+k+k+++8.8.j+~ %.%.V.V.y y Z.{+Z.c h c h V.V.V.V.%+_+_+_+~ ; ~ _+^ 5 2 b n+9+[+9+R [+y._ a ^+%+y y y y y y V.%+_+z._ k C.,+w+,+w+w+w+w+w+w+/+w+w+/+w+,./+w+w+/+w+/+l+w+/+/+p./+l+7+/+7+/+7+/+7+/+7+/+,./+,.,.,.,.,.,.Y.Y.Y.g h+H * * * * ` q.8+8+r+2.[+K.t+t+T.g+W.2+2+e e | 2+e 2+e }.e | W.g+0+&+t+t+. . k.> $.^ n.n.n.^ n.^ ^ ^ ^ 5 5 2 2 2 z.2 2 r C . . . . . . . . . O W 8.(+D D >+( ( o+*+;+J.C+o )+R.a+4+4+y+. . . . . . . . B+R.a+R.'+'+a+'+a+* '+'+'+'+'+a+R.a+R.K.. . . . . . . . . . . _.!.8 x.= u.o+J.i..+B B P.N.. . . . . . . . . K.n+m.n+y.y.[+[+[+[+[+,+[+p.#+m.0.. . . . . . . . |+1 5 5 b b z+#+m.L.p.C.9+C.X R.i n z `.z+t+&+g+g+W.W.g+&+t+. }.f+u.f+o+J.}.t+0+g+W.W.g+0+D+t+K.-+A !.!.9.9.!.!.8 A E >.p+*+s . . . . . . . . . /+'+B .+^.)+B.C+C+C+++++C+++++J.b+o+*+*+f+*+;+J.)+s &+t+&+k.g+W.W.| W.g+g+0+&+t+. . . . . . . . . . . . ", "`.) ) `.) ) ) `.`.&.&.`.4.) 4.) &.`.) -+4.4.4.4.-.q+`.`.) `.) 4.q+4.q+4.) ) 4.) ) 4.) ) 4.) ) ) ) `.`.`.`.) &.&.&.&.&.&.9 9 &.{+&.`.) `.&.&.`.&.&.`.&.9 9 &.9 i+>+c.i+>+D D c.b+(+c.b+8.o+9 D b+8.8.8.k+W 8.W n.; %+%+I h c Z.Z.h c h =+h =+y V.%+%+~ n.^ ~ ^ ^ ; 5 2 n.1 b w R #+P.R X m.R a 2 v.%+V.y y y =.y V.^+z._ _ k ,+w+w+C.,+/+/+w+/+p.w+w+/+w+w+/+/+w+w+/+C.w+/+w+w+l+w+/+/+/+l+/+/+w+w+w+,.,.w+,.,./+,.,.p.Y.Y.Y.Y.g Y.g h+* * '+'+` q.q.q.f.i 4 7.7.H.Q.S T.t+. . . t+t+t+t+t+. t+. . 0.k.2+I.e.^ 6 ; (.6 (.(.n.n.n.n.^ ^ 5 ^ ^ ^ 5 ^ 5 2 2 2 2 a C C C +.C T T 2 5 6 c >+( 9 9 z z u.( o+G.n A+i B.q.R.q.2.a+w }+}+4+.+4+}+w H q.a+'+R.'+'+'+R.'+R.'+a+` '+a+'+R.^.#.^.#.J.G.o+( ( i+9 ( i+9 !.8 { E >.o+J.k+@.P.H.H.H.*.t.Q.Q.I.I.I.Q.I.y.R n+m.m.y.[+,+[+,+[+p.9+m.m.#+t. + + +1+e.e.e.e.5 1 P.P.b w b w #+#+#+L.p.L.s.! 3+5.z 4.8 ) 1 2+&+t+t+&+W.n+f+E z >.u.:+G.J..+e k.t+. t+D+r.}.B.f+z E ~.8 8 8 A x.x.N p+*+;+2.p./+t.0 0 Q.0 t.l+'+'+'+4+X..+)+i.B.C+i.C+i.C+B.i.B.C+++J.J.J.7.C+C+4+4+ +g.g+0.t+t+t+. . . 0.D+q q q q Q 0.. . . . . . . ", ") ) `.`.`.`.`.`.`.&.`.`.) `.`.) ) `.&.) 4.) 4.4.1.4.) `.`.`.&.`.4.q+-.q+) ) ) 4.q+) ) ) ) 4.) ) ) ) ) &.) `.&.&.&.&.9 &.&.`.`.`.&.&.`.`.`.&.&.&.9 &.&.&.9 &.&.i+i+f+c.>+i+9 D b+b+b+c.D D D >+j+D j+k+c.j+~ _+j+c.=+h Z.Z.Z.c h h y =+=+V.V.V.~ ~ ~ ^ ^ ^ ^ 5 ^ G W k+X.G+P.H.H+1 G+E+9+X E+2 _+%+=.y y y y y %+_+z.z.E+R ,+,+[+,+C.p.,+w+w+Y.p.w+p.w+p.w+w+w+w+w+w+/+p.w+/+/+w+/+,./+w+w+/+,./+w+/+7+p.7+p.,.,.,.,.,.,.,.,.g p.Y.g h+'+* '+` '+` q.8+2.r+4 7.;+G.*+u.u.f+D 8.k+6 X.X.X.X.k+b+i+z ) ) {+i+c.W ; 6 ; (.; n.~ ~ n.n.n.~ n.^ ^ ^ ^ 5 ^ ^ ^ 5 ^ 2 2 5 2 5 ^ (.; W c i+9 9 &.E `.E E E E u.:+b.;+3+i r+2.r+i :.;+Y :+E.p+:+*+;+7.B.2.` '+'+` '+a+'+'+* a+'+'+a+a+a+! 7.*+>.x.{ !.9.9.9.9.9.9.9.9.!.~.E z :+b+i.H+H.H.H.H.N.b b n+n+n+n+a n+n+n+n+R m.[+[+/+[+[+,+9+[+m.#+#+w H.H.}+E+P.b P.5 1 1 P.E+P.b w w #+H L.#+L.L.s.o _.E.z 4.-.1.u 9.u -.4.-.1.-.4.-+`.z f+( *+b+C+C+2.q.^..+B.B.C+C+A+G.f+>.x.x.x.E = >.p+*+G.J.C+2.4+H L.p.L.h+H '+4+4+^.)+)+C+C+C+C+++++C+++C+C+C+i.i.i.i.C+B.C+)+4+4+N.N.p.p.p.t.e+}.y+s <+l r.: } 7 q Q 0.. . . . . . . ", "`.`.`.) &.&.&.`.&.) ) ) 4.) ) `.`.&.-+) 4.) -+) 4.) 4.) ) &.`.-+`.4.4.-.q+q+`.) 4.) ) ) ) `.) ) ) ) `.) `.) `.&.`.`.`.&.&.) ) `.`.`.`.&.&.&.&.9 &.{+9 &.9 &.&.9 9 i+>+f+i+i+c.b+c.o+c.D o+i+>+i+o+o+c.o+9 V.V.c c Z.c h j+y h j+=+=+=+; %+~ ~ ^ ^ (.^ (.5 n.6 W 6 k+6 6 6 H+@.@..+.+b w b 5 ^ v.v.V.y y y y V._+2 k k 3.C.9+L.9+,+C.C.,+p.p.C.C.,+w+w+p.p.p.w+w+p.,.w+p.C.C.w+p./+w+,./+/+w+w+w+,.,.,.,.p.p.7+p.,.,.,.,.Y.,.Y.g Y.g g * * '+'+4+` q.q.f.2.4 7.J.G.o+f+u.`.E -+-+4.{ -.1.1.1.1.1.-.4.`.9 c 8.W 6 6 ; ]+6 (.(.(.]+~ n.n.n.n.^ n.^ ^ ^ 5 ^ ^ ^ 5 ^ ^ ^ ^ (.W (+i+( &.`.-+4.{ { { x.x.E E u.( *+;+:.F 7.;+;+E.u.N = s+s+= = u.*+3+r+q.R.a+'+'+'+` '+'+R.'+'+R.a+R.r+;+:+= A 8 !.9.9.9.9.9.9.9.9.9.8 E z f+b+k+P.b b b n+b #+n+z+n+n+n+y.n+y.n+n+y.9+m.[+[+,+[+[+p.9+p.m.#+s.s.H+H+E+E+E+P.5 P.5 P.b w w w w #+s.H s.s.#+s.]+3+5.z -+{ -.1.1.u u u u u 1.-.4.E z u.( *+b+++B.)+^.4+B B 4+4+.+)+C+++G.:+p+u.p+p+:+*+;+J.7.2.q.B H #+p.m.#+N.a+.+)+B.C+++J.G.G.o+*+o+*+G.G.J.++++C+X.X.X.X.X.4+B N.N.p.p.[+[+t.t.e+0 y+<+l r.m+l.7 d Q Q . . . . . . . ", "`.) ) `.&.&.`.`.`.`.) `.`.`.`.`.&.&.&.-+) `.`.`.&.) ) ) `.`.`.`.`.`.) ) q+`.`.`.4.q+q+) ) ) &.&.) ) ) `.`.) ) `.) ) `.&.`.) ) ) ) ) `.`.&.&.`.&.`.&.&.9 &.9 9 9 9 9 i+i+i+c.j+b+D D D o+>+o+b+.+N.n+X.; j+=+h Z.Z.c h h h I =+V.=+~ ^ _+^ ^ ^ ^ ^ (.G G 6 k+(+6 k+6 6 k+i.X.)+G+@.@.H+E+b ^ %+_+V.y y y y y V.^ z.X k R m.9+9+p.9+#+9+C.C.9+p.p.p.C.p.C.L.p.p.C.C.p.p.C.p.p.,+p.,.p.,./+,.p.w+p.7+p.w+,.,.,.,.,.,.,.Y.,.Y.p.Y.Y.h+h+* * * * ` '+` ` q.2.r+r+7.J.;+*+:+u.z z `.x.4.4.{ { 1.1.1.-.4.`.9 i+(+W ; G ; (.~ G ~ ]+(.~ n.(.n.n.n.n.n.n.n.^ c+^ ^ ^ ^ 5 ^ ^ ~ W (+c 9 `.`.-.-.8 u !.8 1.8 { x.= N :+E.*+b.*+*+u.N E ~.A 8 8 8 ~.s+N *+:.4 q.R.a+a+'+'+4+* '+a+'+'+a+.+r+;+:+E A !.9.9.9.9.9.9.9.9.9.9.8 ~.E f+G.i.1 #+b n+#+n+n+n+n+y.M y.n+n+n+m.m.y.y.[+[+[+[+[+C.[+,+C.#+L.#+N.s.}+}+P.H.b z+z+b w H.E+H.w s.s.H H s.H s.M.o W E.E.`.-+4.-.1.u u 9.u 9.u -.4.-+z ( E.*+;+++)+4+B B N.N.N.N.B B 4+)+7.J.;+*+*+*+;+J.J.i 2.^.4+'+H 9+L.L.s.a+^.B.C+A+G.*+f+f+>.z N N z >.u.f+G.G.++C+q.4+B B N.N.p.p.p.,+[+/+l+t.t.o.y+<+L r.m+l.} d q Q Q . . . . . . ", "&.`.) `.&.&.&.`.&.&.&.`.`.9 &.`.`.&.&.`.`.`.`.`.`.) &.&.&.`.`.) 4.4.) ) 4.`.) ) ) 4.) ) ) &.`.) ) ) ) ) q+) ) ) ) &.) ) ) ) ) ) `.`.`.`.`.) `.&.&.9 9 &.&.9 &.&.i+i+c.i+9 i+c.c.9 k+n+)+J.8.1+*.+.5+^ n.j+Z.c c h j+h =+y =+V.~ ~ _+~ (.^ 5 c+6 G 8.G 6 6 8.8.8.(+k+i.C+Z X.i.H+@.X.}+1 ^ V._+_+y y y y y V.^ 5 X w S.w #+s.#+X w #+#+#+9+s.L.#+9+L.9+p.p.L.p.p.C.L.L.C.L.p.C.p.C.p.,.p.,./+p.,.,./+,.p.p.p.,.p.,.p.,.g Y.g g Y.h+H Y.* * '+* 4+4+` q.q.f.r+i A+J.G.*+f+u.N `.E x.4.{ { { 1.{ 4.`.&.i+c W G ; 6 ~ 6 ~ (.(.; (.(.(.]+~ ]+~ n.n.n.n.^ n.^ ^ ^ ^ ^ (.; ; c i+{+) q+1.u 9.9.9.9.9.!.!.8 A 4.E N u.:+E.p+N = ~.8 8 !.!.8 8 8 A s+>.*+7.2.R.` '+'+'+'+'+'+'+4+'+a+^.7.*+a.E A 8 !.9.9.9.9.9.9.9.9.9.!.{ E f+c.k+P.!+#+n+n+M n+y.n+m.n+y.y.n+n+M n+y.[+[+[+[+,+[+p.9+p.9+9+L.s.s.}+'+}+E+E+H.H.b b b w w w w H s.H s.h+H #+s.! _.5.( z `.-+q+q+1.-.u u u u 1.4.E z ( 5.n 3+7.B.B '+h+H L.H p.H N.B B 4+)+C+7.7.J.7.7.2.C+2.q.4+'+H #+L.H s.a+2.7.G.*+f+>.E x.~.{ 8 { { { x.E z u.o+J.++B.B B p.p.y.[+[+/+t.t.t.t.t.0 0 y+<+l m+@ } } q Q q 0.. . . . . ", ") `.`.&.9 &.`.`.&.9 &.`.`.`.`.&.&.&.`.) `.) `.&.&.&.`.&.`.`.4.4.4.4.`.) `.`.`.) `.) ) `.`.) ) q+) `.) ) q+) ) ) &.&.&.) `.) ) ) &.&.`.`.) ) &.&.&.&.&.&.&.&.9 &.9 {+9 i+&.9 9 f+j+^ !+e.z+i.(.e.y.(+6 !+c.c c c h =+=+j+=+%+~ ; ~ ^ n.W (.6 _.8.k+k+6 k+k+i.k+k+k+6 Z i.++G X..+@.@.@.]+=+%+_+I y I I =+V.%+n.f S..+H+#+E+w H.H H w @.w H H L.L.#+L.#+'+L.L.L.L.L.L.L.L.L.L.C.p.C.p.p.p.p.,.p.,.p.,.p.,.p.p.,.Y.,.Y.Y.,.Y.Y.p.g Y.Y.* h+'+* * '+` 4+R.q.2.2.i 7.J.n o+:+f+u.>.z `.x.4.4.{ 4.-+) &.i+i+8.W 6 (.~ ]+(.(.n.]+~ ]+~ n.(.n.n.n.n.(.n.(.n.(.n.n.n.(.(.(.; j+5.9 `.4.1.9.9.9.9.9.9.9.9.!.!.8 A ~.E = N = = s+8 8 !.9.9.9.9.9.!.!.8 x.u.;+r+q.a+R.R.'+4+'+` '+'+'+a+2.i *+:+= ~.8 !.9.9.9.9.9.9.9.9.9.!.~.E f+G.k+.+b n+M y.[+y.y.y.y.y.n+z+n+a n+y.n+m.y. +[+[+9+[+,+m.p.#+#+#+w '+E+s.E+E+E+w H w w H s.w N.s.H s.H s.#+s.3.3._.< E.( E.&.`.) q+q+u u u u -.-+z z E.5.n J.++B.4+H H L.H L.H L.p.H H B 4+q.q.C+2.C+2.q.q.4+4+B H H L.L.L.}+^.i b+o+u.= { { !.!.9.!.9.!.9.!.u { E z o+G.++X.B N.*. +t.t.l+/+t.l+t.0 0 y+y+<+l r.l.[.7 } d Q 0.. . . . . ", "`.`.`.) `.`.&.&.&.&.`.`.) `.&.9 &.&.`.`.`.`.`.&.`.`.`.`.) ) ) 4.q+4.) 4.) ) `.) `.) `.`.&.) ) ) ) q+4.) ) ) ) ) ) `.) ) ) ) ) q+`.) ) `.`.) &.9 9 &.&.&.`.&.`.`.&.&.&.9 9 &.i+9 i+c.W ; T X.D (.B z+5+2 j+j+c 9 j+V.%+; ~ ~ (.W W 6 G 8.6 k+(+D c.(+8.k+W W 8.8.k+6 6 i.i.k+6 @.)+H+1 =+=+_+=+c h =+V.=+V.^ f f ! @.}+a+B a+}+w H B J.k+#+w H h+H s.w L.H N.}+H H.#+L.L.L.H H Y.L.L.g p.Y.p.p.,.Y.p.Y.Y.g Y.p.Y.Y.Y.Y.Y.p.g Y.g h+H h+* * '+4+'+'+q.R.q.2.2.r+7.J.J.G.o+o+f+9 >.z z E E E -+&.9 9 c j+G ~ c+(.c+n.n.n.n.n.n.n.(.]+~ n.n.~ n.n.n.n.n.n.n.^ n.^ ~ ; W c {+`.q+1.9.9.9.9.9.9.9.9.9.9.9.!.8 A { s+E x.A 8 !.!.9.9.9.9.9.9.9.9.!.8 = E.J.r+R.'+` a+a+'+'+'+'+'+4+^.i ;+:+= s+A 8 !.9.9.9.9.9.9.9.!.8 x.z :+b+i..+b n+M y.[+[+[+[+R *.M n+n+n+n+y.y.[+y.[+[+[+m.m.9+9+9+9+L.H s.'+'+'+'+s.s.E+s.w w w s.s.#+s.H H H s.s.#+f 3.o < < 5.E.{+&.{+-+q+-.u u 1.4.`.z E.( n n 3+r+B.^.'+L.L.L.p.L.L.L.p.H H N.N.4+4+4+q.q.4+4+'+N.H L.#+p.m.H a+#.;+:+>.x.{ !.!.9.9.9.9.9.9.9.9.9.9.8 { E f+c.C+X.N.y.[+0 t.0 t.Q.l+t.Q.0 y+y+<+3 l r.@ ] 7 7 d q 0.. . . . ", "`.`.) ) ) ) &.&.`.&.`.&.`.`.9 &.9 &.&.`.`.`.&.`.&.`.) ) `.) 4.4.q+) ) q+q+) ) ) `.) ) `.`.`.) 4.) 4.) `.`.) ) ) `.`.&.`.`.&.&.) `.) ) ) ) ) `.{+&.`.&.`.&.&.`.&.&.&.9 9 9 9 f+i+i+i+c.c.y ^+k+b e.P.j+C+D 8.i+&.i+; j+W ; ; 8.8.j+k+W k+6 8.j+D (+(+(+c.D c.j+8.c.++8.Z X.i.)+P.P.E+; j+%+_+=+Z.c =+=+V.; 1 H+H+@..+G @.@.6 @.a+H+)+i k+H.H s.H.}+}+4+S.H '+H '+'+H H N.s.H H H H H H H L.L.H p.Y.Y.L.p.Y.p.Y.Y.p.Y.g Y.g Y.H H h+H * '+* '+'+` '+a+R.q.q.2.r+r+++J.J.G.*+*+f+f+u.z z z z 9 9 9 D (+W (.c+c+n.c+^ ^ n.^ ^ n.n.n.^ n.n.n.n.n.^ n.n.n.n.(.(.(.(.; W c 5.&.-+-.!.9.9.9.9.9.9.9.9.9.9.9.9.!.!.A A A { 8 !.9.9.9.9.9.9.9.9.9.9.!.!.A N *+4 8+q.R.` '+R.'+R.'+'+a+2.r+;+:+>.E ~.8 !.!.9.9.9.9.9.9.8 { E >.G.A+B..+b M *.[+*.*.y.R [+y.n+M m.n+n+n+[+p.y.y.m.n+m.m.m.#+p.L.L.L.H H '+'+}+}+s.H.H }+s.H w H s.'+H H s.H #+s.X 3.! o < 5.5.5.E.( z {+) q+-.-.-+{+( ( E.n 3+A+i o 4+B H L.p.L.L.L.L.Y.p.p.p.H N.H '+N.B '+'+H H s.H L.- #+w @.C+5.>.E A !.9.9.9.9.9.9.9.9.9.9.9.9.9.!.x.E f+b+i.B p. +t.0 t.Q.l+0 0 t.t.e+y+v <+l r.r.l.[.} d q q Q Q . . ", "&.&.`.`.) ) `.`.`.&.`.`.&.`.&.&.9 9 &.`.&.&.`.&.&.`.) 4.) ) 4.) q+4.) 4.q+) ) `.`.`.`.`.&.`.`.) ) ) `.`.&.) ) `.`.&.&.9 9 &.&.) q+) ) ) ) ) ) `.&.`.) ) `.&.&.&.&.&.&.9 &.&.9 9 9 i+i+c c V.!+n.n.++(.e.*.1 j+9 9 i+i+D D c.8._.8.8.(+k+6 ++8.(+(+(+8.(+(+D 8.8.(+(+8.6 Z X.Z @.1 ~ =+I %+V.c c h =+=+V.(.]+]+Z B.i.A+i.++o+H+S.)+.+^.^.G+}+a+4+a+a+4+4+B a+B B B a+'+B a+'+'+N.'+'+H H '+H h+L.H H * H h+'+h+H * Y.H * H * g * H H '+'+'+'+4+q.q.q.^.2.2.2.r+i ++A+J.b+D D o+>+( f+( 9 f+( >+c.8.k+(.c+1 5 5 5 ^ 5 ^ 5 ^ 5 ^ 5 n.^ ^ c+n.^ n.^ n.n.n.^ n.n.(.~ W c ( `.-.1.9.9.9.9.9.9.9.9.9.9.9.9.9.!.!.!.!.8 !.9.9.9.9.9.9.9.9.9.9.9.9.9.!.8 = :+;+r+8+R.8+R.` '+'+'+'+4+^.B.:.*+:+= E A 8 8 !.9.9.9.!.!.A E z :+G.++)+4+N.n+*.[+[+*.[+y.n+y.y.n+9+n+[+m.9+[+m.n+m.b H #+H w #+H L.L.h+s.s.s.}+}+}+E+H }+}+s.N.E+s.s.s.H H H s.s.s.3.3.o G < < 5.c 5.5.( {+`.-+`.z E.( 5.5.n 3+_.i 2.a+'+H L.L.p.p.p.p.Y.Y.Y.p.p.L.p.H H H p.'+L.L.#+L.L.p.#+s.! J.:+E A !.!.9.9.9.9.9.9.9.9.9.9.9.9.9.9.!.A N f+8.i.N.y.5+t.0 t.0 /+0 l+0 e+y+y+y+3 U.F.m+l.[.} 7 d q q Q 0.", "`.&.9 &.9 &.&.&.9 &.&.`.&.&.9 9 &.&.`.`.9 9 &.&.`.`.`.`.) 4.`.`.z -+q+q+{ q+q+q+q+) ) &.`.`.`.) 4.) &.&.&.`.) ) `.{+9 &.9 `.`.) q+) `.) `.`.`.`.`.) `.`.`.&.`.&.&.&.&.&.&.`.&.&.&.{+9 i+c j+; c.c.i+c.~ n.n.W j+c.i+i+c.i+i+c.8.(+D (+c.(+c.>+>+D D (+8.8.(+++8.++8.++8.k+k+6 6 ~ =+y =+=+=+h Z.h =+W V.~ Z )+)+6 k+k+k+k+k+Z )+! ^.)+)+)+^.! ^.^.#.)+S.4+a+.+a+4+.+.+4+4+4+4+4+4+'+4+'+'+'+'+'+'+'+H '+'+H '+'+'+'+'+'+'+'+'+* * * '+'+'+4+'+4+^.^.o 2.B.B.#.C+++++b+D 5.D n *+o+o+>+o+D c.(+8.; n.^ 5 ^+5 ^+2 5 5 5 5 5 5 5 5 5 5 5 5 ^ ^ ^ ^ n.^ ^ ^ n.n.(.; j+5.{+`.-.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.!.!.!.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.8 ~.N b.4 r+2.8+R.R.R.` a+'+a+^.2.++;+*+u.N s+~.A 8 !.!.!.!.~.E N f+*+J.C+i.B b n+n+[+y.[+y.y.m.y.m.n+M y.n+y.y.m.n+#+w w H }+N.'+'+s.H s.H h+H '+H '+'+'+}+H s.s.'+H H H H H L.s.H E+s.M.f ! o G _.< < < 5.5.5.5.( ( ( 5.5.5.3+3+7.7.o )+.+'+L.L.p.g Y.Y.p.#+p.L.L.p.g p.p.#+L.L.L.L.#+L.p.#+L.#+}+)+n u.x.8 !.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.!.u E u.o+C+X.p.t.t.Q.t.e+t.Q.t.0 0 0 y+v <+U.| F.r.l.l.] } } } d q ", "&.&.9 9 9 9 9 9 &.&.`.&.&.&.&.&.9 &.&.`.&.&.&.&.`.`.&.`.) ) &.&.9 `.4.) -+4.4.4.4.4.) &.&.&.&.&.&.`.&.&.&.`.`.`.4.`.`.&.&.) ) ) ) `.`.`.&.`.`.`.&.`.&.&.&.&.&.`.&.&.&.&.&.&.&.&.&.&.&.9 &.9 9 9 9 9 9 9 {+9 9 9 i+D i+i+i+i+9 9 9 i+i+D D >+D >+c.b+8.b+++8.8.8.8.k+k+k+W k+k+k+V.j+h c c Z.c Z.c h =+V.; 6 i.B.8.8.k+8.D b+C+i.i.)+#.#.k+)+)+)+)+#.^.)+)+)+C+)+B.B.)+)+)+)+^..+4+4+q.4+4+4+4+4+4+4+'+B B '+B B B B B B B q.B B 4+4+B 4+q.q.^.)+#.C+_.A+< b+D b+n b+o+5.o+b+b+b+b+G.b+G.b+8.8.6 ^ P.!+2 2 2 2 2 2 z.2 2 5 2 2 2 2 ^ 2 ^ 5 5 5 5 5 ^ n.^ n.^ ]+; c 5.{+{ 1.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.!.~.= E.F + f.f.8+8+R.R.'+'+'+^.2.r+7.;+:+u.N E x.~.A { ~.x.x.z p+o+G.J.C+X.B N.n+m.[+y.[+[+[+m.y.y.m.n+n+m.m.y.y.n+N.N.B a+a+a+a+a+'+'+'+H '+'+* L.H s.'+'+'+'+w H s.s.s.H h+h+H H #+s.s.M.3.! o o G _.W < W < < < c n n < 3+A+_.r+r+o 2.}+'+H L.L.L.p.L.Y.L.L.L.L.H L.H L.N.L.p.H L.#+#+L.m.L.#+a+r+*+N A !.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.{ E o+J.i.N.n+5+t.Q.e+t.t.l+t.e+0 y+y+y+<+3 U.l r.m+g+] |.] } 7 ", "&.&.9 i+z &.9 `.&.&.`.&.&.&.9 9 &.9 &.&.9 &.&.&.`.`.`.`.`.&.`.&.&.z ) 4.4.q+q+4.) q+`.`.&.9 &.&.`.&.`.`.&.9 9 &.9 &.&.`.) 4.4.) `.`.&.`.&.`.`.`.&.&.&.&.9 &.&.9 &.&.&.&.&.&.`.&.&.9 9 9 9 9 &.9 9 &.9 &.9 &.9 &.9 z {+9 9 9 9 9 &.&.9 9 9 i+>+c.(+c.(+c.(+c.c.(+c.j+k+8.W k+W ; =+c h Z.Z.Z.Z.c Z.Z.c c c ; ; k+8.(+c.8.W 8.W 8.G W k+8.W 6 G k+W 6 6 G k+W W G k+W 6 W 8.W W k+6 6 6 6 6 6 X.i.X.6 i.k+k+6 i.C+C+++++++8.8.b+J.J.;+G.D o+>+( f+( :+D n J.A+_.++++k+i.8.b+A+8.A+8.8.8.8.k+6 (.1 P.r a 2 T r T T r 2 T r 2 2 2 2 z.2 2 2 2 5 5 ^+5 5 5 ^ 1 ^ n.; c ( &.4.u 9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.8 A = E.b.F 4 4 f.8+8+q.` a+a+4+^.B.A+J.G.:+u.N E x.x.x.E E >.u.*+G.J.C+)+4+H.n+n+y.[+[+y.y.m.y.m.9+n+m.m.y.y.n+m.E+N.'+B '+4+4+4+q.q.^.R.R.4+'+}+'+}+s.s.s.w '+'+'+H H H h+H * h+'+h+s.g M.f f ! ]+o o o G _.W _._._.3+< 3+A+_.i r+o 2.a+a+#+#+L.9+L.L.p.L.H L.H H H '+N.N.N.N.'+w w #+#+L.#+#+w ! _.E.= A 8 !.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.!.8 x.z o+8.B N. +t.t.t.e+t.t.t.e+t.e+y+y+y+<+<+U.l r.m+r.l.l.l.[.", "&.&.&.&.&.&.&.&.&.&.&.`.&.&.&.&.&.&.z &.9 &.9 &.&.&.&.&.&.&.4.) &.&.&.) -+4.q+q+4.4.`.`.&.&.`.&.&.) `.`.9 &.&.&.&.9 &.`.) &.`.`.&.&.&.&.&.&.`.`.&.&.&.&.&.&.&.9 &.&.&.9 &.&.&.z 9 &.9 9 9 &.&.&.9 &.9 &.&.9 &.9 &.&.&.&.&.9 &.9 &.9 9 9 9 9 9 i+i+>+i+i+>+D i+i+i+c.c c.c i+c i+c i+i+Z.( ( {+{+9 {+( Z.9 {+9 {+&.&.9 {+&.&.&.`.&.`.&.`.`.&.`.`.`.`.`.`.`.) ) ) ) q+) ) 4.4.) 4.4.) -+) ) ) ) ) ) -+) -+4.4.4.) 4.4.4.x.-+E -+f+4+C+*+*+G.n :.3+A+7.A+J.J.A+J.< b+b+G k+++++++++++k+k+6 6 X.5 !+a r T T T T T T T T T T T T r T r 2 2 r r 2 2 2 2 2 2 5 5 ^ (.; (+( ) -.u 9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.!.A s+a.% F + 4 /.2.8+q.8+R.q.2.2.i J.;+G.o+f+f+u.>.z N u.u.f+o+G.J.J.C+^.4+N.m.n+y.*.y.y.y.R [+m.y.y.n+m.m.m.n+#+N.}+'+a+4+4+q.^.2.r+r+r+r+2.2.q.R.^.a+a+'+a+a+a+a+a+'+'+'+H H H h+L.M.X M.M.M.f ! ! ]+o o ]+o G o G o G o _.o #.o ! ^.3.'+#+L.L.L.p.L.L.L.H '+4+q.^.2.B.o o )+)+.+.+a+H.E+E+}+}+2.3+:+= ~.8 !.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.!.{ = f+b+i.N.p.t.5+/+t.e+l+t.t.e+e+}.y+y+y+<+<+<+l U.F.r.m+l.l.", "&.&.&.&.&.9 &.&.9 &.z &.z 9 9 9 &.9 9 &.&.9 9 9 &.&.&.9 9 u.z `.`.-.`.) ) 4.4.4.4.) `.`.9 &.&.&.) `.`.`.&.&.) ) ) &.&.) &.&.&.&.9 9 `.&.&.&.`.&.&.&.&.9 9 &.&.&.9 9 &.&.&.&.9 &.9 9 9 &.9 &.&.&.&.&.&.&.9 &.9 &.&.&.&.`.&.&.&.9 &.9 9 9 9 9 9 9 9 9 ( &.&.&.{+&.&.&.&.&.&.z &.&.&.&.z &.{+&.z z &.z z z &.&.&.&.&.`.-+-+`.`.`.`.) `.-+-+) ) ) `.) ) ) ) ) ) ) 4.-+-+) ) -+-+-+`.E -+E z E z z z z z z u.z z z u.u.f+u.f+:+f+*+)+#+C+3+B.R.^.)+)+^.)+)+G k+k+k+#.D D ++++8.++_.k+6 6 c+X.^ !+2 T T T T C T & C & C C $.C T & T T T T T r T T T 2 r 2 2 2 2 5 c+; c ( &.4.1.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.8 A s+a.Y % + F /.4 f.2.8+q.2.2.i 7.7.G.G.*+*+f+:+f+f+f+f+o+*+G.G.++C+)+.+H.#+n+[+/+[+ +[+[+y.n+[+m.m.9+n+y.n+n+#+N.H.N.'+B 4+^.2.i :.:.7.:.:.7.i r+B.r+2.B.2.2.2.2.q.R.a+'+'+'+H '+H L.h+X M.X M.f ! 3.! ! ! ! o o o o o o o o ! ! R.a+'+s.H #+L.9+L.p.H H a+^.2.B.i 7.7.J.3+3+A+3+i #.#.o )+@.! #.7.*+>.s+A 8 !.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.!.8 E >.G.++B N.p./+t./+/+/+/+t.t.t.e+e+e+y+y+y+<+3 U.U.l r.r. .", "9 9 z &.z 9 9 9 9 9 9 9 &.f+9 9 9 9 9 z &.&.`.&.&.&.&.&.9 9 f+f+z `.-+`.`.4.4.4.) `.&.&.9 &.&.`.) `.&.&.&.`.`.) ) `.) `.`.&.&.&.&.&.9 &.9 &.&.&.9 9 9 9 &.9 &.&.&.9 &.9 &.&.&.9 &.9 &.&.&.&.&.&.&.&.9 &.9 9 9 9 &.&.&.&.&.&.&.&.&.9 9 9 9 9 9 9 9 9 i+9 9 z z &.&.z 9 9 9 9 f+9 ( i+( ( 5.( ( ( ( ( ( ( 5.o+( E.( ( ( f+( 9 ( ( ( ( ( o+E.E.( f+( ( ( ( ( f+( 9 f+f+f+z z 9 ( ( E.5.*+*+G.G.n *+( o+o+o+*+o+*+b+G.b+;+G.G.;+J.B..+r+7.)+o A+3+++#.++b+*+n < b+n 5.D < ++++k+G k+i.X.c+1 5 a a T T +.& C C C C C w.C C w.C C C C C C & T T T C T T r T 2 r 2 ^ 6 < ( &.4.1.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.8 s+s+a.% % + + 4 /./.o 8+o i i 7.:.;+G.*+*+*+o+:+:+o+*+*+G.*+J.J.C+C+)+4+N.n+*. +t. +[+[+ +[+y.[+[+y.[+y.[+p.n+#+w H N.N.a+4+2.7.:.b...:+*+*+*+*+b.;+;+;+;+J.:.J.7.4 i 8+q.'+* '+h+h+h+H #+s.s.M.s.f 3.3.! 3.3.3.! ! ! ! ! )+! ^.a+a+}+H #+L.C.L.9+L.L.H.R.^.i 7.:.;+J.n ;+G.G.G.n G.n J._._.B.Z i J.*+p+N s+A 8 !.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.!.A x.N f+J.C+N.p.[+t./+t./+t.e+/+t.t.0 0 }.y+y+y+g.y+3 U.3 3 U.", "&.9 &.9 9 &.&.&.9 9 9 9 &.9 f+z 9 9 9 9 &.&.&.&.9 &.&.&.`.9 i+i+f+f+9 z z 4.`.`.`.&.&.&.&.z `.&.`.&.&.&.&.9 &.`.`.&.&.`.&.&.&.&.i+i+9 &.9 9 9 9 9 i+9 9 9 9 9 9 9 9 9 &.9 9 9 &.&.&.&.&.9 z &.&.&.&.9 9 9 9 9 &.&.`.&.&.&.&.&.9 &.&.9 9 9 9 9 f+i+9 9 9 9 9 &.9 9 9 f+>+D D o+b+< 3+< < 3+< _.< < < _.++#.B.i.X.B.8.b+b+D < D (+(+(+b+< 8.A+3+3+7.A+A+3+3+b+D n D n D n E.*+G.J.J.n 3+3+F 3+3+7.3+;+n J.J.J.A+J.J.J.A+A+7.J.J.7.A+7.7.3+7.:.3+;+;+n G.o+*+o+o+o+G.G.b+b+8.++k+6 c+G+1 5 2 2 T T C T C & C w.C C C <.<.<.<.w.<.w.C C C C C C C T C T T T T 2 5 ; W 5.9 -+{ u 9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.!.A A a.a.E.F % + + 4 o 4 i 4 4 :.7.J.;+*+*+*+f+*+o+*+G.G.G.G.J.J.++C+^.X.B #+n+ +t.Q.Q.Q.t.t./+/+[+[+[+y.m.[+[+y.m.w N.w B 4+2.7.J.G.:+p+>.N N N >.u.u.u.:+:+:+:+:+Y ;+:.7.2.2.R.'+H '+H '+h+s.h+X s.M.M.M.3.3.3.R.3.a+a+R.S.S.R.a+a+'+H s.L.#+L.C.L.p.#+a+)+i 7.;+;+G.*+;+*+*+E.E.E.*+*+5.G.J.A+++++7.*+*+>.= s+A 8 !.!.9.9.9.9.9.9.9.9.9.9.9.9.9.!.8 E >.:+G.C+4+!+p./+/+/+/+/+/+/+/+t.t.e+0 e+e+y+y+y+<+<+g.L L ", "&.9 &.f+9 z z &.&.9 9 9 9 9 i+f+9 9 9 9 &.z &.9 9 &.&.`.&.9 i+f+&.&.9 9 &.`.&.`.&.&.&.&.&.&.-+&.&.9 9 9 9 f+9 9 &.9 9 &.9 9 9 &.9 9 f+f+9 9 f+9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 i+9 z &.z &.&.9 &.&.&.&.9 9 9 9 9 &.&.&.&.9 9 9 9 i+9 9 9 i+f+9 i+9 i+>+9 9 &.9 9 9 9 ( i+>+D (+++++++G A+_._._.W #.G G G k+6 G 6 6 Z Z 6 Z G k+8.8.8.8.8._.W ++k+_.k+++++8.++8.8.8.< < 8.A+A+A+3+8.J.J.J.7.A+7.J.7.7.7.J.A+A+J.J.A+J.J.J.J.7.J.J.7.;+J.J.J.J.;+n G.G.*+*+( f+f+f+( o+o+D b+8.8.G 6 c+1 5 2 z.2 T T T T C C C C <.<.<.<.<.<.6+6+<.6+6+6+<.<.C C <.C C C C T T T 2 (.W 5.( &.-+1.!.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.!.A s+= % a.% % F + 4 /.4 4 7.;+n *+*+o+:+f+f+f+:+o+G.G.b+;+J.J.C+C+)+X.B N.n+y. +Q.I.0 Q.Q.Q.5+Q.t. +/+ +/+/+[+[+y.#+H w H..+C+J.*+p+>.= s+~.~.~.x.x.E E E s+= = N p+:+Y ;+7.2.q.R.'+H L.s.h+#+h+h+s.X s.M.M.M.f 3.3.a+}+a+a+a+H '+s.H L.L.L.L.L.p.L.L.'+R.r+F J.;+n G.*+5.*+o+E.f+p+E.:+E.*+n n 3+3+A+;+*+:+p+N s+~.A 8 !.!.9.9.9.9.9.9.9.9.9.!.!.A ~.= u.*+G.C+q.B p.[+/+p.t./+p.t./+t.t.t.t.}.e+}.y+y+}.y+g.<+<+", "9 9 f+9 f+9 &.`.z &.z 9 9 i+>+i+f+z z 9 9 9 f+f+z 9 &.&.9 9 f+i+f+9 9 9 z &.&.`.`.`.9 &.z z `.`.&.z 9 f+>+i+o+9 f+9 f+9 9 9 9 9 9 i+i+>+i+9 9 9 i+9 9 i+f+i+f+i+f+>+>+9 9 9 9 9 9 9 9 9 9 9 9 9 &.&.`.&.9 &.&.9 &.`.`.9 &.&.&.9 i+>+9 9 9 f+9 9 o+>+( ( o+G.5.D G.D 8.b+< 8.W k+k+k+k+]+]+S.^.S.a+a+H.B @.H+@.H+G+@.X.Z 6 G G G G G k+++++W ++k+++k+W ++8.b+8.b+8.8.J.b+b+J.b+J.J.J.J.J.7.J.7.J.J.J.J.G.b+b+b+b+b+J.b+;+;+J.;+G.;+;+;+G.*+*+*+o+:+f+f+f+u.u.u.f+u.>+5.D (+8.8.k+6 c+^ 5 2 z.r a T T T C C C C <.<.<.<.> 6+6+> 6+6+6+6+<.> 6+<.<.<.C C C <.T 2 ^ G j+5.u.E 4.{ 9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.!.8 s+s+s+% % % % + + 4 F 4 F ;+;+b.*+E.:+u.u.u.u.f+f+*+G.G.b+++C+B.)+4+B N.N.n+1+Q.I.o.}.o.o.I.I.Q.Q.Q.Q.5+t.t.t.[+[+m.m.H 4+2.A+*+p+= s+A A 8 8 8 8 8 8 8 8 8 A A s+= N :+*+;+:.f.R.'+H '+h+h+h+s.s.#+s.s.h+s.H h+h+'+H '+H '+s.H H H L.L.L.Y.L.9+L.9+H '+^.r+7.;+G.Y *+*+E.>+E.f+f+u.>.f+f+5.*+*+J.J.J.J.G.b.*+u.>.= x.~.A 8 !.!.9.9.9.9.9.9.9.!.8 A x.>.:+G.J.C+q.B p.p./+/+p./+7+p./+/+t.e+/+t.t.e+0 e+e+y+y+o.o.", "f+i+>+i+f+f+z &.9 9 9 u.i+f+f+i+o+f+f+f+i+i+i+f+9 9 &.9 9 9 i+i+f+9 9 f+z 9 u.&.z z 9 &.9 z `.`.z z 9 9 D o+>+i+9 9 >+f+9 9 f+f+9 f+D o+o+f+i+9 9 9 9 i+9 i+f+i+i+>+>+i+f+i+f+9 9 9 9 9 9 z 9 9 9 &.`.&.&.9 &.&.&.9 9 &.9 9 9 z f+o+o+G.b+J.++C+)+X..+H+1 P.H+P.P.w E+b H.P.H.b H.E+P.H.f P.E+H+P.@.@.@.G+X.G+X.X.Z Z B.Z i.i.#.k+_.k+_.k+k+++W 8.++8.8.8.b+8.b+b+b+J.A+J.J.J.J.J.J.J.;+J.;+J.G.G.G.G.*+G.o+G.o+G.G.G.G.*+G.G.G.G.o+*+*+o+o+:+f+f+9 9 9 z z &.z u.f+( o+D b+8.W G i.1 1 2 5 2 r T T T T T C C w.C <.<.<.6+6+6+> > 6+> 6+6+> 6+6+6+6+6+<.<.C T 2 6 W (+5.z `.{ 1.!.9.9.9.9.9.9.9.9.!.!.8 !.!.!.9.9.9.9.9.9.9.9.9.9.9.9.9.!.8 A s+a.a.% % % % + + F F F ;+n *+E.( u.u.= N E = >.u.f+*+G.J.++2.^.B B N.n+[+[+ +I.}.O D.s <+o.o.}.o.0 o.Q.I.Q.Q.t./+m.m.N.X.C+G.f+N x.A 8 8 !.!.!.9.9.9.9.9.9.9.!.8 A = N :+b.J.i 2.R.'+H H H L.H h+L.h+H L.s.H H L.h+H H L.H H H #+L.L.L.p.Y.L.p.C.p.s.R.2.4 J.;+;+n *+5.:+f+f+z z z >.u.u.( 5.5.n J.< J.J.;+G.*+:+u.N E E x.A { 8 !.!.!.!.!.8 8 ~.E z p+*+;+J.C+X.B N.p.p.p.t./+p./+/+/+p.t./+t.t.t.e+}.e+}.e+}.y+", ">+o+>+o+o+i+f+f+i+9 9 i+f+o+>+o+>+o+>+f+f+f+i+o+u.9 9 f+9 i+f+o+i+f+9 i+i+f+f+9 &.z 9 9 i+z z 9 9 9 `.i+(+D f+9 9 >+o+o+f+i+9 i+9 i+c.c.>+>+i+f+f+i+f+i+f+i+i+f+>+o+i+f+9 f+i+i+i+f+9 9 9 f+9 9 9 9 9 &.z &.9 9 9 9 f+o+o+b+++C+B.)+X.X.X.1 .+.+H+H+P.P.H.P.b z+z.b z+b P.P.P.E+P.P.P.@.H+@.@.S..+@.@.X.@.@.X.G+i.)+i.)+B.)+)+)+)+B.k+k+++++++++++8.8.8.8.A+b+8.A+A+b+b+b+J.b+b+J.G.;+b+G.J.b+;+G.G.G.o+o+o+*+o+o+*+o+*+o+*+*+*+:+*+:+f+f+f+f+u.9 z z z z &.E `.z z f+( 5.(+b+W G 6 n.1 ^ 2 2 2 2 r T T T T T C C C <.<.6+<.<.<.6+6+<.> > > 6+> > > 6+6+6+<.& 2 1 6 W D 5.z E { { 8 !.!.!.!.!.!.8 8 8 8 8 8 8 8 !.!.9.9.9.9.9.9.9.9.9.!.8 A s+a.s+a.% % % + % + F F F Y *+:+:+>.z E E 4.x.x.E N u.f+*+G.++C+.+B n+n+[+[+ +& o.o.D.g.|+g.<+<+s s s }.o.o.o.o.Q.t.[+#+B )+J.*+N s+A 8 !.!.9.9.9.9.9.9.9.9.9.9.!.8 8 A s+N :+b.:.r+q.'+H L.h+H H H H H L.h+h+H H H H L.h+h+#+L.L.L.L.L.Y.L.p.C.Y.L.L.L.a+2.4 7.J.n G.*+*+( ( >.`.E = `.z u.E.o+*+n b+A+++8.J.A+G.G.*+:+u.z N `.x.x.x.{ A 8 8 A ~.E N u.*+G.J.C+B.4+B !+p.p.p.p./+/+p./+p./+p./+/+t.t./+/+t.t.Q.0 Q.", "D D >+D o+o+i+o+o+f+f+9 i+o+c.(+G.o+>+i+i+o+o+c.o+o+f+i+>+>+>+o+9 f+9 >+>+o+f+f+i+9 f+f+f+9 z z 9 f+z o+++b+*+f+>+c.c.b+G.o+i+o+i+f+f+i+>+o+>+>+>+D >+>+o+>+i+f+i+>+i+>+i+f+i+>+i+o+>+f+9 i+i+9 9 u.9 f+f+f+f+o+D 8.k+k+B.k+i.X.i.X.X.@.X.P.P.P.b H.H.b b b w E+b b z.R w P.H+E+S.@.@..+.+^.X..+)+)+G+)+)+)+)+)+)+)+)+)+B.B.B.B.B.B.B.k+k+k+++++++A+A+A+8.A+b+A+b+A+J.J.b+J.;+G.b+b+;+b+G.;+G.b+G.G.G.*+o+o+o+:+o+*+o+*+o+*+o+:+f+:+f+:+u.f+9 z 9 z z &.`.`.`.-+z z 9 f+( D D 8.W G (.c+1 ^ 5 2 2 2 2 T T T T T C C C C <.<.<.<.<.> <.<.<.> 6+6+> 6+> > 6+<.C T 2 c+6 j+D >+z -+4.x.{ 8 8 8 8 { A ~.~.s+A A A 8 8 8 !.!.9.9.9.9.9.9.!.8 A s+s+a.% % % % % % + + F F n E.E.>.N = x.~.A { ~.{ x.E z u.o+G.++C+.+H.n+y.t.Q.Q.Q.o.D.U.].].].U.].L <+<+<+<+s o.o.}.e+[+#+.+C+G.p+E A 8 !.9.9.9.9.9.9.9.9.9.9.9.9.9.9.!.A ~.= u...;+i 2.R.* H * L.h+h+H H H L.h+h+h+L.H H H L.L.H L.L.L.H p.Y.Y.p.C.p.L.H 4+2.i 7.:.;+;+*+E.f+>.E E { x.E z ( E.*+n n J.J.++++++++J.J.G.G.*+*+f+:+f+u.z N N E = = = >.p+o+G.J.C+C+)+4+N.N.p.p.p.t.p.p./+p.p.t.p.t.p.t.p.t.t.7+l+t.e+t.", "o+o+o+>+D o+D D o+o+>+f+i+o+G.b+(+o+>+o+o+>+D D D o+f+>+b+G.o+o+D >+o+D o+D D o+o+o+o+o+o+f+9 9 o+f+f+D k+++8.J.;+b+G.(+c.D G.c.c.D D G.o+c.c.o+D D o+c.D G.c.o+D o+i+D o+>+o+>+o+>+o+D o+f+f+o+o+b+b+8.8.++C+k+C+C+C+i.i.i.)+.+1 G+P.P.P.H.z+n+n+M R z+R z+E+E+H.E+P.H+H+@.@.G+.+X.)+)+^.G+)+^.X.)+^.)+)+)+^.)+)+)+)+)+^.^.)+)+)+i.B.B.C+C+++++++++8.++++++++A+A+J.J.J.J.b+J.J.J.;+b+;+G.b+G.G.G.o+*+o+*+f+f+o+f+o+f+:+:+:+:+:+:+f+u.u.9 z z &.N z `.z `.E -+-+-+`.z z f+( D D W _.; 6 c+^ 5 ^ 5 2 2 2 2 r T r r C r C C C <.C <.C <.6+6+<.> 6+> 6+> 6+> <.<.T 2 P.6 k+(+D >+9 `.E E 4.E 4.{ x.E = = = s+s+s+A A 8 8 8 !.!.!.!.!.8 A A s+s+a.s+a.% % % % % + + + F Y E.p+N E ~.{ 8 8 8 8 A { 4.N z :+G.8.B.B b y. +Q.Q.I.s s |+K.K.: r.K.r.K.x ].g.<+<+y+y+y+Q. +N.^.A+o+N A 8 !.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.8 ~.N :+;+:.f.q.'+* H h+H h+L.h+h+h+H h+h+h+H L.L.L.L.L.L.g L.Y.L.Y.p.9+L.L.C.H 4+2.i 7.J.3+n ;+5.E.E.z E x.s+E N u.:+5.*+J.J.++++++C+C+C+++A+J.J.G.G.G.*+*+o+o+f+f+f+p+f+*+*+;+J.C+C+B.4+B N.!+p.p.p./+p.p.p./+p.p./+p.p.t.p.t.p./+/+/+/+t.", "o+D D D D D D D c.J.G.o+D D D G.D G.D D o+c.G.D D D b+8.k+++++8.G.D D 8.b+G.b+b+b+b+8.A+G.o+D b+A+b+8.8.8.++k+k+C+++A+J.8.J.++J.8.++8.++b+b+b+b+c.b+c.c.c.G.c.D o+D o+c.c.c.b+(+b+8.b+8.8.++++++8.++++C+C+k+B.k+i.i.B.6 )+i.X.i..+@.H+P.H+E+P.P.H+P.P.P.@.1 H+@.P.a+@.@..+.+! ^.G+.+)+i.)+)+)+)+)+i.)+)+i.)+)+B.)+B.)+)+)+B.)+2.2.i.C+B.B.#.C+++C+C+++++++A+++++++A+A+A+J.A+J.J.b+J.J.J.;+b+;+G.G.D *+o+o+*+f+o+:+*+o+f+o+( :+u.u.f+u.u.z z z &.-+`.-+E `.-+-+4.E -+&.z 9 9 >+D (+W 6 ; (.(.n.^ ^ 5 5 2 2 2 2 r r r T r r C C C C C <.<.<.<.<.<.<.6+<.6+<.<.+.+.a 2 c+6 8.b+D ( u.z z E = z N = N N a.a.a.s+= s+s+A A A A 8 8 8 A A A s+s+a.% % % % % % + % + + F Y Y u.N = ~.A 1.!.9.!.!.!.{ x.-+z f+*+8.B.@.#+*.$.I.o.o.D.D.U.K.: [.: : . .K.K.r.].U.<+s 0 t.p.B C+;+f+E A 8 !.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.!.8 x.>.:+;+i q.'+'+* H * * h+H h+h+g h+h+L.L.L.L.L.L.L.Y.Y.L.L.Y.L.Y.C.p.L.L.H a+q.r+i 7.7.;+;+*+E.f+>.E E E z u.( E.5.n < 7.++C+C+C+B.B.B.C+++C+++A+++++J.J.J.J.G.G.G.G.J.J.++7.C+q.X.B B N.N.p.p.p.p.p.p.p.p.p.p.p.p.t.p./+p./+p.t./+p./+", "b+G.G.o+D b+G.G.G.b+(+G.G.(+b+c.b+(+D G.b+b+b+A+b+A+b+A+A+8.++++b+A+b+++8.b+b+J.b+b+8.8.b+G.b+b+8.8.J.8.J.8.8.8.8.k+i.k+k+8.k+++C+6 i.k+k+k+k+k+C+b+G.c.o+c.o+D D c.c.D b+b+c.b+b+b+8.J.++8.8.++++++k+k+C+k+k+B.B.i.i.)+i.i.i.i.X.X.G+X.1 @.a+@.G+! S..+B @.H+P.H+P.P.H+@..+.+X.)+i.)+)+i.i.)+i.)+i.)+)+B.B.B.B.B.2.B.B.2.^.2.B.2.2.^.B.B.B.B.C+r+i C+7.7.C+7.++7.A+A+A+A+A+A+A+A+J.J.b+J.G.b+G.G.G.o+G.o+o+o+:+o+f+:+:+:+:+f+:+u.>.z N &.N `.`.`.-+-+4.-+-+4.4.4.-+-+`.z 9 i+5.c.< W ; G (.n.n.^ ^ ^ ^ 5 2 2 z.z.r r T r r r C r C C C C C <.<.<.<.<.<.C C C T a 5 1 X.6 8.b+D >+( f+f+f+u.u.f+E.E.a.% a.% a.a.s+s+s+A A A A A s+s+a.s+% s+% % % % % % % + % + F Y E.u.= x.8 8 !.!.9.9.9.!.!.{ E z u.o+J.k+1 n+$.Q.o.D.x+|+].r.[.[.|.k.[.|.[.[.: .r.U.<+y+y+t.p.4+C+G.>.~.8 9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.!.A = p+b.:.f.q.* * * '+H h+'+H h+h+H L.L.H L.H L.L.L.Y.H p.L.Y.p.Y.L.C.C.p.L.'+4+2.r+4 7.A+3+n n ( E.z z E N u.f+5.G.n A+A+i k+B.)+)+i.)+i.)+i.C+)+B.C+i.i.C+C+C+C+J.7.7.C+C+B.q.X.B B N.p.N.p.p.p.p.p./+p./+p.p.p.p.p.p.p./+p.p.p.t./+,+", "k+++++C+++++J.8.A+J.b+8.J.J.G.G.G.b+G.b+8.C+8.++k+k+C+k+++k+++k+k+++8.++++++8.++A+b+b+b+b+b+b+b+b+b+b+8.A+8.++b+(+c.b+b+c.8.c.c.c.c.b+b+c.8.c.c.>+D o+D >+D D D o+D D D c.G.b+b+8.++8.8.++++++++k+++++k+k+B.i.i.)+i.i.i.i.i.i.i.i.! )+)+@.H+B H.H.H.H.H+H+@..+.+i.i.)+)+)+)+)+)+i.)+i.)+)+B.B.B.2.B.B.B.B.B.B.B.B.B.2.2.2.)+^.)+)+2.^.)+^.B.2.B.B.C+C+C+C+C+7.C+C+C+7.++7.++7.7.++A+J.J.J.;+b+G.D G.G.G.G.G.o+o+o+o+:+( :+:+u.:+u.u.z N -+-+-+E -+-+-+4.4.4.{ 4.{ 4.-+-+z z 9 i+D j+W ; G ; ; (.~ n.^ ^ ^ ^ ^+5 2 2 2 2 2 r 2 r r C r r C C C C C C C C T T T a 2 5 1 6 6 8.8.b+D o+o+E.o+*+E.G...b.Y % % % a.% a.a.s+a.s+s+s+a.s+a.% a.% % % % % % % + + + + + Y E.E.= s+{ 8 !.9.9.9.9.9.9.!.{ { E u.o+b+C+.+n+$.}.O D.U.K.K.: k.B+B+B+B+|.7 |.|.l. . .U.<+y+5+p.^.i *+>.~.8 !.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.8 ~.N ..;+/.f.` ` '+* '+'+* '+H '+'+H H h+H H L.p.#+L.Y.p.L.L.Y.p.L.p.Y.9+L.H a+^.B.r+i ++7.J.n *+E.z u.>.( E.5.G.b+J.++++B.B.i.)+X.X..+X..+4+.+B B B B X.B X.X.)+)+C+2.q.q.X.4+B N.N.N.N.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.", "8.++++++k+k+C+C+++++C+++C+C+++8.++8.8.++8.8.8.8.8.8.8.c.8.b+8.8.b+8.8.b+b+b+8.8.b+D G.D (+D o+D o+D D (+b+b+(+b+b+c.c.D D >+D o+o+D i+D >+>+D o+D D D D D D D c.G.c.b+b+b+b+b+8.b+8.++++++8.k+++++k+k+C+i.i.i.i.i.)+i.X.i.i.i.G+@.X.G+.+@.H+P.E+H.P.H.P.H+@.@.G+.+G+X.X.X.i.i.i.i.i.Z B.B.i.i.)+)+B.)+)+B.)+)+2.B.2.)+B.B.2.B.2.2.)+2.2.B.2.B.B.B.i.B.B.C+C+C+++C+7.C+C+C+C+C+C+i ++7.A+b+J.G.b+G.b+G.G.G.o+G.o+*+*+*+o+:+f+:+f+u.u.>.`.E -+-+4.-+4.4.{ { { { { { -.{ -+) &.9 5.c < W W ; W ]+; ]+(.~ n.n.^ ^ ^ ^ ^ 2 2 2 z.2 2 r r r r r r C r C C T T T a 2 2 !+1 c+6 k+k+8.8.b+b+G.b+G.G.3+;+3+F F :.+ % % % % % a.a.% a.a.% % a.% % % % % % % + % % + + + F % E.a.= x.A 8 !.9.9.9.9.9.9.!.u x.E u.f+G.k+.+a $.I.O |+K. .: |.B+D+0.0.0.0.B+q B+|.l.r.l <+}.l+N.4+4 ;+>.s+8 9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.!.A = p+b.:.q.q.` ` ` ` ` * 4+* '+'+'+'+H H H H H L.L.L.L.L.Y.9+L.9+Y.L.p.L.H '+4+^.2.B.C+i A+3+n 5.E.E.u.f+5.*+n J.A+_.k+B.i.)+X..+H+B B B N.N.B P.N.!+N.N.N.N.N.B 4+4+X.4+B B B N.N.N.p.!+p.[+p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.", "8.8.8.8.++8.8.A+++8.8.8.8.8.b+b+b+b+b+b+8.b+b+b+b+b+(+D D b+b+b+c.D D D D D G.D (+(+D G.D D D D o+o+o+o+D D o+>+o+o+o+>+>+D D >+>+D o+D c.c.b+c.c.c.c.G.c.J.b+J.b+b+b+b+8.8.++8.++8.++C+i.C+i.i.k+k+i.i.i.i.)+i.i.i.i.i.G+G+X.G+X.@..+@..+@..+@.@.G+.+X.X.X.)+X..+.+.+i.)+i.X.)+i.B.i.i.B.B.B.B.)+B.B.)+B.C+i.C+B.C+C+2.B.B.C+B.C+2.C+2.B.)+B.)+B.2.2.2.)+B.B.B.2.C+2.B.C+B.C+B.C+C+++7.A+A+J.J.J.b+b+G.b+G.G.G.o+*+*+o+E.o+:+f+u.u.z E E 4.4.4.4.{ 4.4.-.-.-.-.-.-.{ -+) &.9 9 5.(+W W W W ; ; ; ; G ~ (.n.n.^ ^ ^ ^ ^ ^+2 2 2 2 2 r r r r r r r r 2 2 2 5 ^ 1 c+X.6 k+k+++8.8.++A+J.++A+7.++4 4 4 4 4 4 + + % % % % % a.% % % % % % % % % % % % % + + % + + + Y E.a.= s+A 8 !.9.9.9.9.9.9.!.8 4.-+u.o+G.k+.+n+5+o.|+U. .[.|.B+0.. . . 0.. 0.0.Q B+[. .l <+y+e+p.4+C+;+>.s+8 !.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.!.8 s+N Y :./.f.f.f.q.` f.` q.` q.4+4+a+a+H+H.N.N.H H H L.#+L.L.Y.L.9+L.C.Y.m.'+4+.+^.2.B.B.C+++A+< D 5.5.*+n J.b+A+++#.B.o ]+^.a+H+P.H.H.H.N.b N.n+N.N.n+p.N.!+N.!+N.N.B N.B N.p.p.p.!+p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.p.", "J.b+A+b+b+J.b+8.8.J.b+b+b+b+b+b+b+(+(+D G.D D D D D o+D D (+c.b+D G.D D D D D D G.o+D D o+o+>+o+o+>+f+>+>+o+>+D >+D D o+o+D D D D c.c.D G.b+G.b+b+J.J.++++++k+k+C+++++C+C+C+C+i.k+i.k+k+k+k+k+k+B.k+C+k+6 i.i.6 B.i.i.i.)+)+G+.+@..+H+H+H+H+.+.+.+.+a+@.@.@.@..+G+.+)+X.X.i.i.i.)+)+i.i.i.i.i.i.i.)+)+)+)+)+B.2.C+r+C+C+C+r+C+C+C+C+C+C+2.B.C+C+2.B.B.B.B.2.2.2.2.2.B.2.^.2.)+B.2.C+C+C+++7.8.J.J.J.b+b+J.G.;+G.G.G.G.*+o+:+:+:+f+u.>.E E 4.{ { { { { -.{ -.{ 1.1.-.-.4.) `.9 i+c j+j+W =+W W W G ; ; ]+; ]+~ n.n.n.n.n.^ ^ ^ 5 ^+2 2 2 2 2 2 r 2 2 2 ^ 1 c+6 6 k+k+k+++++++++++++8.++++B.B.r+2.r+r+/./././.+ % % % % % % % % % % % + % + % + % + % % + + + + + Y E.>.N x.~.8 !.!.9.9.9.9.9.!.8 ~.`.z o+b+++@.z+$.s |+K.~+k.0.0.. . . . . . . . 0.Q B+l. .<+y+/+Y.B C+;+:+= A !.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.8 A = ..% /./.f.f.f.f.8+8+8+q.R.! ^.G+.+.+@.@.S.H+N.H N.H #+L.L.p.L.9+p.p.#+#+H a+.+)+^.2.B.r+r+++3+J.b+b+J.J.7.i _.B.i.)+.+@.H+s.H.w H b n+N.#+b m.m.n+N.p.p.p.N.p.N.p.N.p.N.!+p.p.[+p.p.p.p.*.p.p.p.p.p.p.p.!+p.p.N.p.N.p.p.!+p.z+p.", "8.b+b+b+b+b+G.G.(+G.b+D b+G.D D D G.D D o+o+o+o+o+D o+D o+G.D D D D D o+o+D D o+D o+o+D o+o+o+>+o+o+o+o+D D o+D D c.b+b+b+8.b+G.J.J.b+J.8.C+C+k+i.k+++8.8.++++8.C+k+i.)+i.i.k+k+k+8.++++k+8.8.k+k+i.)+C+i.i.B.i.i.i.i.X.G+X.@..+1 .+1 H+B P.H.H.H.H.H.H+4+H+.+.+)+.+! )+X.)+)+)+i.)+i.i.)+)+)+)+)+i.)+B.)+)+i.B.B.C+r+C+i 7.7.:.7.7.7.++7.C+C+7.C+C+B.2.B.B.B.2.)+)+)+2.)+2.^.)+^.B.C+C+C+C+++++++J.++J.J.A+J.J.G.;+;+G.G.G.o+:+f+u.z E x.{ q+{ -.-.-.-.1.1.1.8 1.-.1.4.) `.{+( c < j+< W =+W W =+G ; ; ; ; ; ]+~ ~ ^ n.n.^ n.n.^ ^ 5 ^ 2 ^+2 ^+^ n.n.6 6 W 8.8.8.(+8.8.8.8.A+A+++k+C+k+2.^.2.q.8+2.f.i 4 :.+ % % % % % % % % + + + + + % % % % + % + + + /.+ % Y E.a.>.= x.A 8 !.!.9.9.9.!.!.{ x.N u.*+J.C+.+n+$.o.S r.k.q 0.. . . . . . . . . . 0.q |.r.l y+e+p.'+q.;+:+N ~.8 9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.!.A s+..% + /././.f.f./.f./.f.r+o o o o Z ]+G+G+G+.+}+}+P.N.w #+m.9+L.Y.9+m.H H '+a+4+^.! ^.2.B.B.k+C+C+++k+C+#.B.)+)+.+a+a+H.H.w #+n+#+#+m.m.m.#+#+#+m.m.n+p.p.p.p.p.p.p.p.p.p.y.p.y.y.[+*.p.p.p.p.p.p.p.p.N.p.N.p.!+p.N.p.p.p.N.p.N.", "b+(+G.D D G.(+D G.D D D o+D D o+o+o+o+o+>+>+>+o+o+f+o+o+o+o+o+D D o+o+o+o+o+o+D D D G.D G.D D D o+o+D o+o+o+b+8.C+i.i.i.C+i.X.X.X.k+k+k+6 k+k+k+k+k+k+i.X.6 i.k+k+k+X.k+C+8.8.8.++k+k+i.k+i.k+6 i.X.i.i.6 k+k+6 k+Z i.i.i.i.X.X..+H+H+H+H+@.@.H+P.H+H+P.P.B H+H+H+@..+@..+@.X..+.+X.)+i.)+i.)+)+)+^.)+)+B.B.B.C+C+C+C+7.++7.7.J.J.J.J.J.J.J.J.7.++C+C+C+B.2.^.)+B.2.^.^.^.^.^.q.^.q.^.2.C+C+C+C+++7.7.++A+A+J.A+J.J.J.J.J.G.G.o+:+u.>.`.E { { -.-.1.1.1.1.1.1.1.1.1.-.4.-+&.{+i+c < c W =+W W W =+W W W G ; ; ; ; ]+~ ]+~ n.n.n.n.^ ^ ^ ^ ^ ^ ^ (.~ G W 8.< (+D D G.D D G.b+b+A+8.++C+#.)+)+a+^.^.q.f./.+ :.Y % a.% a.% % % % % + % + + + % + % % + % + + /.+ F b...E.a.= = x.A 8 !.!.!.!.!.8 { E z f+G.8.i.H+n+Q.O U.[.&+0.. . . . . . . . . . . . 0.7 l.U.g.e+p.B q.7.b.a.s+A !.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.8 A s+a.% + + /./././.4 /.i 4 i i i G #._.Z Z i.G+G+S.@.S.}+H.H w #+Y.p.L.L.9+p.H '+a+4+4+)+)+^.)+)+i.B.B.B.B.)+)+)+.+S.B H.H w #+m.#+m.#+#+#+#+m.m.n+m.n+p.n+n+p.y.p.[+[+[+[+[+*.*.p.[+p.[+ +p. +p.p.!+p.p.p.N.p.p.N.p.N.p.N.N.p.N.p.", "o+D G.b+G.G.G.D G.D D G.D o+D D o+D o+o+o+f+>+f+f+>+f+o+o+o+o+o+G.D G.G.G.b+b+J.b+b+b+D G.o+D G.D D c.b+8.8.++8.++8.8.8.8.8.8.b+8.c.8.8.8.8.8.8.8.c.8.8.++++8.8.k+8.k+k+k+C+C+k+k+k+k+i.C+k+C+k+k+k+i.C+k+k+k+i.i.Z i.G+i.)+@.X.P.P.H.P.H.b b H.H.H.H.H.E+H.H+H+H+H+H+@.@.H+H+H+H+H+H+1 B X..+.+.+X..+.+)+)+B.2.r+i C+7.7.A+J.J.G.G.*+G.D G.G.G.;+J.A+++C+C+2.^.)+^.^.^.^.q.^.q.^.q.^.q.^.2.B.B.C+C+C+C+7.C+++++++++A+A+J.J.J.G.*+f+u.z x.{ { 1.1.1.8 1.u u u u u { -.q+-+&.9 ( c < =+< W =+W W W W =+W ; W ; G ; ; ; ~ ; ]+~ ~ (.n.n.n.^ n.n.]+; W W (+D D >+( ( f+:+o+o+G.G.b+A+C+B.i.^.a+a+'+q.2.r+4 b.....a.a.a.a.a.a.% % % % % % % % % % % % % + + + + + + b.% E.E.N = = x.A A 8 8 8 1.{ E N u.G.J.C+.+N.[+Q.D.r.[.D+. . . . . . . . . . . . . . q g+{.<+e+/+H 4+4 ;+:+= ~.8 !.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.8 A s+a...+ + + + + /./.+ 4 4 _.A+A+_._.G G G Z ]+G+@.H+H+}+H+H.H.w #+L.p.9+L.p.#+H H '+a+a+.+.+.+^..+^.)+)+)+i..+a+4+a+}+H.H #+#+m.R m.9+m.9+p.m.#+m.L.m.m.m.m.y.p.[+p./+p./+/+[+[+t.[+ +p.p.p.p.p.p.p.p.p.p.N.p.p.N.p.N.p.N.p.p.N.p.", "G.D b+D b+b+D D D o+D o+o+o+o+o+o+f+>+f+( >+:+( o+o+o+o+o+o+D G.(+G.b+b+b+b+b+b+G.b+G.G.G.b+b+b+8.b+J.b+b+b+b+b+c.c.b+b+b+8.b+8.b+8.b+8.b+8.c.b+b+b+b+8.8.8.8.8.8.8.8.k+k+k+k+k+k+k+k+k+k+k+k+k+k+k+C+6 k+B.i.i.i.)+)+i.X.G+.+1 .+H+H+H+P.P.w E+b b E+w H.E+N.P.P.P.H+P.H.H+H+P.H+P.P.H+H+H+H+H+H+.+4+.+X.)+)+B.B.C+7.7.A+J.;+G.*+o+:+f+:+f+:+:+*+*+;+J.7.i B.B.q.^.^.q.^.^.^.4+^.4+4+q.^.)+q.^.)+q.2.B.B.C+r+r+r+r+C+r+C+A+J.G.G.f+u.z E x.{ { { 1.1.1.1.1.u 1.1.1.q+4.`.{+i+c c < j+< =+< =+W W W W W W W W ; ; ; G G ; ; ; ~ ]+~ ~ n.n.~ ; W W j+D c i+9 9 u.z u.f+u.f+*+G.G.J.J.C+B..+@.a+a+R.q.4 ;+Y a.a.a.s+a.s+a.= a.a.% % % % % % % % % % % % + + + + F F ;+..E.:+>.N = x.~.~.A { x.x.E >.o+G.++B.B n+ +o.x+r.|.Q . . . . . . . . . . . . . 0.q [.l g.e+/+p.4+2.J.*+p+= A 8 !.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.!.8 A s+a.% % + + /.+ + + + + F 3+3+3+8.W 8.G 6 G c+c+1 G+H+P.E+}+H.w w #+L.L.p.- p.L.H H H }+'+a+a+B a+4+a+}+H+4+}+a+H.N.w #+#+m.p.9+9+9+m.9+m.X L.9+p.m.9+p.p.,+p.,+[+p./+[+/+[+/+/+/+[+5+p.5+p. +p.p.p.p.p.p.p.p.N.p.p.p.!+p.N.N.p.N.", "G.o+G.G.b+J.J.G.G.G.G.o+D o+o+D G.G.G.G.G.D n G.*+G.*+G.G.*+G.J.J.b+J.b+J.J.J.++A+A+A+++++A+A+J.8.8.8.b+b+b+b+b+++++++k+8.8.8.c.8.c.8.c.b+b+c.b+j+b+8.b+8.8.8.8.8.k+8.k+8.k+8.++k+k+k+k+k+k+k+k+6 i.B.i.X.i.i.i.X.X.G+i.G+@.G+P.1 1 P.P.H.P.b P.E+b H.b b b H.H.H.P.P.P.P.P.B P.B H+H.P.P.P.H.H+P.H+.+.+.+)+)+)+C+C+C+7.J.b+*+o+:+u.u.>.>.>.>.u.u.f+:+*+J.J.r+2.2.^.4+R.4+4+4+4+q.4+4+4+4+4+4+q.q.X.^.^.q.^.q.q.2.q.B.B.B.++++J.G.o+u.u.z E x.{ { { -.-.1.-.1.-.-.4.4.`.&.9 c (+j+=+< =+W < =+< =+W W =+W W W W W W V.G ; G ; ; ; ; ]+; ]+; ; W (+c >+9 z z `.E `.E z u.u.u.:+D G.3+i C+)+a+4+a+q.r+:.Y a.= s+s+s+s+s+s+s+s+s+s+s+a.s+s+s+s+a.a.a.% % % + + 4 F :.;+Y *+:+p+>.N E E x.~.x.E E u.:+o+J.C+X.N.[+Q.y+U.: |.Q . . . . . . . . . . . . . 0.B+[.| <+e+l+p.B q.C+;+:+>.s+A !.!.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.9.!.8 A s+a.% % + + + + + + + F Y n 3+n < _.W W 6 6 6 c+1 1 H+H+P.}+P.}+w w #+#+9+L.9+L.#+H H w H '+'+H.N.N.}+B H }+N.}+H.s.#+m.p.9+9+9+p.C.9+L.9+9+p.#+9+9+m.9+p.[+p.,+w+/+/+/+/+/+t.[+/+p.t.p.p. +p.p.p.p.p.p.p.p.N.p.N.p.N.N.p.p.N.N.p.", "J.A+++++A+8.A+A+b+G.D G.G.D G.o+D o+5.5.o+o+o+o+5.5.D < b+A+A+J.8.A+A+C+k+B.i.B.B.C+++++++8.A+8.b+b+8.b+b+8.8.8.8.j+8.8.c.8.8.b+8.b+8.b+8.c.8.b+8.c.8.8.b+8.8.8.8.8.8.k+k+k+k+k+k+k+k+k+k+k+k+6 B.6 i.i.Z X.i.X.G+X.X..+.+1 P..+P.P.P.P.P.P.P.b P.b P.b P.P.b H.P.P.H.H.P.P.P.H.P.H.H.H.H.H.P.H.B P.H+.+X.)+^.)+B.C+C+++b+G.*+:+u.z = E E E E E N N u.:+*+;+7.r+^.q.R.4+R.R.4+q.'+4+q.4+4+4+4+4+4+4+4+4+4+4+^.^..+^.^.^.2.B.++J.b+G.o+u.z `.-+E 4.4.{ { -.{ -.-.4.4.`.&.&.( c c < W W W =+W W =+< W W W W =+W V.W W W =+W ; ; G ; ; ; ; ; W W c.5.i+9 &.&.4.E 4.-+E E E z >.f+:+*+n 3+C+^.)+a+4+2.i b...= s+A A A A s+A A A A s+s+s+s+s+s+s+s+s+s+s+E.% % F + + :.:.;+Y ..*+u.u.N = = = E N >.f+G.J.C+)+B n+t.0 <+].g+|.Q . . . . . . . . . . . . . Q |.m+<+y+e+p.N.N.4+C+7.;+:+N x.A 8 !.9.9.9.9.9.9.9.9.9.9.9.9.9.9.!.A A s+= a.% + + + /.+ + + % F F n n < < < 8.W W G (.c+n.1 P.5 1 P.H+H.H.N.w #+#+9+L.p.Y.C.9+H H w w s.H.'+H s.N.H E+H H #+m.m.9+C.,+C.C.C.9+p.9+m.C.9+9+p.9+[+C.C.p.,+p./+p./+/+t.p.}.p.t.t.p.t.p.t.p.p.p.p.p.p.p.p.N.p.N.p.N.p.N.N.p.N.", "8.b+b+b+b+b+b+b+b+b+b+G.G.G.D 5.o+>+( ( ( 5.( o+5.*+5.G.n G.b+J.b+A+J.A+8.A+8.8.A+8.++A+A+A+b+++A+8.8.8.8.8.8.8.++8.8.8.8.8.8.8.8.8.8.8.8.++8.++8.++8.8.8.++8.++k+8.k+8.8.k+k+k+k+k+6 k+k+i.i.6 B.i.i.i.i.X.Z Z X.G+G+X.G+X.1 .+H+1 P.H+P.P.P.P.H.H.P.H.H.H.E+H.H.P.H.H.H.H.H.H.H.H.E+H.w H.b H.E+H.H+.+4+^.)+)+)+C+++J.G.*+f+u.E E x.A { ~.~.{ x.E = >.f+*+J.i 2.4+` '+'+'+4+'+4+'+'+'+4+4+'+4+4+'+4+4+4+4+'+4+4+4+^.X.2.B.C+A+b+G.o+f+u.u.z `.E -+-+) 4.4.4.4.-+) &.9 ( c < W W =+W W W W W =+W =+W W W W W W =+W W ; W W ; W ; ; ; W W W c c i+9 &.) 4.{ { { { { x.E E E u.E.*+G.J.++o ^.a+^.2.;+*+= s+A A A A A A A 8 A 8 8 8 A A s+s+s+s+s+a.a.a.E.Y F F F F :.;+b.....:+p+u.>.>.>.>.u.f+*+G.J.C+4+N.p.Q.o.<+r.l.} Q . . . . . . . . . . . . 0.B+l.r.<+y+t.p.p.4+q.C+7.J.*+:+N s+~.8 !.9.9.9.9.9.9.9.9.9.9.9.9.9.!.8 A s+a.a.% % + /.+ + + + + n % n n < < 8.W W G G 6 (.n.n.1 5 1 P.1 H+H+E+w w #+m.9+9+L.p.9+L.9+#+#+H #+H w H s.H #+m.p.L.p.9+[+p.C.,+p.,.C.9+9+9+9+p.C.9+p.9+[+,+/+,+w+/+/+t./+/+/+/+t.[+t.t.p.p.p.t.p.p.p.p.p.p.p.p.p.N.p.N.N.p.!+p.N.", ";+b+G.b+G.b+b+b+G.G.D D D D 5.5.E.( o+o+( E.o+E.*+5.*+5.G.n ;+b+J.J.A+A+A+A+++++++++++++8.++8.A+8.A+++k+8.++8.++8.8.8.++8.++8.++++++++k+++++k+8.C+8.k+++k+8.k+8.k+W k+k+k+k+k+6 k+6 i.i.i.i.i.i.i.X.X.X.X.X.G+X.G+X.1 1 H+1 P.P.P.P.H.P.P.P.P.H.H.b b b z+z+z+b z+b b b b b w b b b b b b z+H.w H.H.P.H..+X..+)+B.C+++J.G.f+u.N E ~.{ 8 8 8 8 8 A A E = p+:+;+7.2.q.4+4+` '+'+'+'+4+'+'+'+'+'+'+'+'+'+'+'+'+'+a+'+R.4+^.)+B.C+++J.b+D o+f+f+9 z z z &.`.) -+-+) `.&.9 9 i+(+j+W W W W W ; W W ; W W W =+W =+W W W W W =+W ; W ; W W ; W =+W (+c i+&.`.-+{ -.1.8 8 { { ~.E E z u.E.*+J.i B.^.^.)+C+G.a.s+A 8 8 8 8 !.8 !.!.u u u u 8 8 A s+s+s+s+s+a.a.E.E.b.F 4 4 :.:.;+b.Y ..:+p+p+u.u.>.f+:+G.J.C+^.4+#+[+t.o.L r.: B+0.. . . . . . . . . . . . Q |.l.U.<+y+t.p.N.4+4+C+C+7.;+*+:+>.E ~.A !.9.9.9.9.9.9.9.9.9.9.9.8 A A s+s+a.% % + + /.+ /.+ F + F 3+n n < < < < W W ; ; ~ n.n.^ n.1 1 P.1 P.B }+N.#+#+#+9+p.C.C.p.L.p.p.#+m.#+L.#+n+p.m.L.9+p.C.p.C.w+,+w+w+p.,+,+C.p.C.9+p.9+[+p.,+p.w+p./+/+/+/+/+/+t./+t.p.t.p.}.p.p.p.p.p.p.p.N.p.p.p.N.p.p.p.p.p.N.N.m."}; void make_splash_pixmaps(GtkWidget *window) { GtkStyle *style; style=gtk_widget_get_style(window); GLOBALS->wave_splash_pixmap=gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->wave_splash_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)wave_splash_xpm); } static gint expose_event(GtkWidget *widget, GdkEventExpose *event) { gdk_draw_pixmap(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE(widget)], GLOBALS->wave_splash_pixmap, event->area.x, event->area.y, event->area.x, event->area.y, event->area.width, event->area.height); return(FALSE); } gint splash_button_press_event(GtkWidget *widget, GdkEventExpose *event) { (void)widget; (void)event; if(GLOBALS->timeout_tag) { gtk_timeout_remove(GLOBALS->timeout_tag); GLOBALS->timeout_tag = 0; } if(GLOBALS->wave_splash_pixmap) { gdk_pixmap_unref(GLOBALS->wave_splash_pixmap); GLOBALS->wave_splash_pixmap = NULL; } if(GLOBALS->splash_splash_c_1) { gtk_widget_destroy(GTK_WIDGET(GLOBALS->splash_splash_c_1)); GLOBALS->splash_splash_c_1 = NULL; } if(GLOBALS->gt_splash_c_1) { g_timer_destroy(GLOBALS->gt_splash_c_1); GLOBALS->gt_splash_c_1 = NULL; } return(FALSE); } gint splash_kill(gpointer dummy) { (void)dummy; gulong usec; if(GLOBALS && GLOBALS->gt_splash_c_1) { gint sec = (gint) g_timer_elapsed(GLOBALS->gt_splash_c_1, &usec); int skill = (sec>=2); if(GLOBALS->cnt_splash_c_1) GLOBALS->cnt_splash_c_1 -= GLOBALS->load_complete_splash_c_1; if((!GLOBALS->cnt_splash_c_1)&&(skill)) { return(splash_button_press_event(NULL,NULL)); } else { if(!GLOBALS->load_complete_splash_c_1) gdk_window_raise(GTK_WIDGET(GLOBALS->splash_splash_c_1)->window); } } return(1); } void splash_create(void) { if((!GLOBALS->splash_disable)&&(!GLOBALS->splash_splash_c_1)) { GtkWidget *splash_table; gint dx, dy; GLOBALS->gt_splash_c_1 = g_timer_new(); GLOBALS->splash_splash_c_1 = gtk_window_new(GTK_WINDOW_POPUP); #if !defined _MSC_VER && !defined __MINGW32__ dx = 8; dy = 8; #else #if GTK_CHECK_VERSION(2,24,10) dx = 8; dy = 8; #else dx = 8; dy = 26; /* ...old value required for previous versions of GTK on mingw apparently no longer needed */ #endif #endif gtk_widget_set_usize(GTK_WIDGET(GLOBALS->splash_splash_c_1), WAVE_SPLASH_X + dx, WAVE_SPLASH_Y + dy); gtk_window_set_type_hint(GTK_WINDOW(GLOBALS->splash_splash_c_1), GDK_WINDOW_TYPE_HINT_SPLASHSCREEN); gtk_window_set_position(GTK_WINDOW(GLOBALS->splash_splash_c_1), GTK_WIN_POS_CENTER); gtk_widget_show(GLOBALS->splash_splash_c_1); make_splash_pixmaps(GLOBALS->splash_splash_c_1); splash_table = gtk_table_new(10, 10, FALSE); GLOBALS->darea_splash_c_1 = gtk_drawing_area_new(); gtk_widget_show(GLOBALS->darea_splash_c_1); gtk_widget_set_events(GLOBALS->darea_splash_c_1, GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK); gtk_table_attach (GTK_TABLE (splash_table), GLOBALS->darea_splash_c_1, 0, 9, 0, 9,GTK_FILL | GTK_EXPAND,GTK_FILL | GTK_EXPAND | GTK_SHRINK, 3, 3); gtk_widget_show(splash_table); gtk_container_add(GTK_CONTAINER(GLOBALS->splash_splash_c_1), splash_table); gtkwave_signal_connect(GTK_OBJECT(GLOBALS->darea_splash_c_1), "expose_event",GTK_SIGNAL_FUNC(expose_event), NULL); gtkwave_signal_connect(GTK_OBJECT(GLOBALS->darea_splash_c_1), "button_press_event",GTK_SIGNAL_FUNC(splash_button_press_event), NULL); gtk_events_pending_gtk_main_iteration(); gdk_draw_drawable(GLOBALS->darea_splash_c_1->window,GLOBALS->darea_splash_c_1->style->fg_gc[GTK_WIDGET_STATE (GLOBALS->darea_splash_c_1)],GLOBALS->wave_splash_pixmap,0,0,0,0,WAVE_SPLASH_X,WAVE_SPLASH_Y); gtk_events_pending_gtk_main_iteration(); GLOBALS->timeout_tag = gtk_timeout_add(100, splash_kill, GLOBALS->splash_splash_c_1); } else { /* was commented out for now because of DnD while loading crash */ #ifdef SPLASH_ADDED_LOADER_MESSAGES if(GLOBALS->mainwindow) { wave_gtk_window_set_title(GTK_WINDOW(GLOBALS->mainwindow), GLOBALS->winname, WAVE_SET_TITLE_LOADING, 0); } #endif } } void splash_sync(off_t current, off_t total) { struct Global *g_old = GLOBALS; int cur_bar_x; if(GLOBALS->splash_splash_c_1) { if((current)&&(total)) { cur_bar_x = WAVE_SPLASH_X * ((float)current / (float)total); if(cur_bar_x != GLOBALS->prev_bar_x_splash_c_1) { if((current==total)||(cur_bar_x>=WAVE_SPLASH_X-4)) GLOBALS->load_complete_splash_c_1=1; /* if(current>total) current = total; */ /* scan-build */ gdk_draw_rectangle(GLOBALS->darea_splash_c_1->window, GLOBALS->splash_splash_c_1->style->black_gc, TRUE,0,WAVE_SPLASH_Y-4, (GLOBALS->prev_bar_x_splash_c_1 = cur_bar_x), 4); } } gtk_events_pending_gtk_main_iteration(); } else { #ifdef SPLASH_ADDED_LOADER_MESSAGES if((GLOBALS->mainwindow)&&(!GLOBALS->tcl_running)) { if(!GLOBALS->splash_is_loading) { set_window_busy_no_refresh(GLOBALS->mainwindow); GLOBALS->splash_is_loading = 1; #ifdef MAC_INTEGRATION osx_menu_sensitivity(FALSE); #endif } if((current)&&(total)) { cur_bar_x = 100 * ((float)current / (float)total); if(cur_bar_x != GLOBALS->prev_bar_x_splash_c_1) { GLOBALS->prev_bar_x_splash_c_1 = cur_bar_x; wave_gtk_window_set_title(GTK_WINDOW(GLOBALS->mainwindow), GLOBALS->winname, WAVE_SET_TITLE_LOADING, cur_bar_x); if(0) { GdkDisplay *g = gdk_display_get_default(); if(g) gdk_display_flush(g); } else { gtk_events_pending_gtk_main_iteration(); set_GLOBALS(g_old); } } } } #endif } } void splash_finalize(void) { if(GLOBALS->splash_is_loading) { GLOBALS->splash_is_loading = 0; GLOBALS->splash_fix_win_title = 1; set_window_idle(GLOBALS->mainwindow); #ifdef MAC_INTEGRATION osx_menu_sensitivity(TRUE); #endif } } #else gint splash_button_press_event(GtkWidget *widget, GdkEventExpose *event) { (void)widget; (void)event; /* do nothing */ return(FALSE); } void splash_create(void) { /* do nothing */ } void splash_sync(off_t current, off_t total) { (void)current; (void)total; /* do nothing */ } void splash_finalize(void) { /* do nothing */ } #endif gtkwave-3.3.66/src/mouseover.c0000664000076400007640000002744212341266475015601 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2006-2014. * * 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. */ /* AIX may need this for alloca to work */ #if defined _AIX #pragma alloca #endif #include "globals.h" #include #include #include #include #include #include "main.h" #include "currenttime.h" #include "color.h" #include "bsearch.h" /************************************************************************************************/ static int determine_trace_flags(unsigned int flags, char *ch) { int pos = 0; /* [0] */ if((flags & TR_SIGNED) != 0) { ch[pos++] = '+'; } /* [1] */ if((flags & TR_HEX) != 0) { ch[pos++] = 'X'; } else if ((flags & TR_ASCII) != 0) { ch[pos++] = 'A'; } else if ((flags & TR_DEC) != 0) { ch[pos++] = 'D'; } else if ((flags & TR_BIN) != 0) { ch[pos++] = 'B'; } else if ((flags & TR_OCT) != 0) { ch[pos++] = 'O'; } /* [2] */ if((flags & TR_RJUSTIFY) != 0) { ch[pos++] = 'J'; } /* [3] */ if((flags & TR_INVERT) != 0) { ch[pos++] = '~'; } /* [4] */ if((flags & TR_REVERSE) != 0) { ch[pos++] = 'V'; } /* [5] */ if((flags & (TR_ANALOG_STEP|TR_ANALOG_INTERPOLATED)) == (TR_ANALOG_STEP|TR_ANALOG_INTERPOLATED)) { ch[pos++] = '*'; } else if((flags & TR_ANALOG_STEP) != 0) { ch[pos++] = 'S'; } else if((flags & TR_ANALOG_INTERPOLATED) != 0) { ch[pos++] = 'I'; } /* [6] */ if((flags & TR_REAL) != 0) { ch[pos++] = 'R'; } /* [7] */ if((flags & TR_REAL2BITS) != 0) { ch[pos++] = 'r'; } /* [8] */ if((flags & TR_ZEROFILL) != 0) { ch[pos++] = '0'; } else if((flags & TR_ONEFILL) != 0) { ch[pos++] = '1'; } /* [9] */ if((flags & TR_BINGRAY) != 0) { ch[pos++] = 'G'; } /* [10] */ if((flags & TR_GRAYBIN) != 0) { ch[pos++] = 'g'; } /* [11] */ if((flags & TR_FTRANSLATED) != 0) { ch[pos++] = 'F'; } /* [12] */ if((flags & TR_PTRANSLATED) != 0) { ch[pos++] = 'P'; } /* [13] */ if((flags & TR_TTRANSLATED) != 0) { ch[pos++] = 'T'; } /* [14] */ if((flags & TR_POPCNT) != 0) { ch[pos++] = 'p'; } /* [15] (at worst case this needs 16 characters) */ ch[pos] = 0; return(pos); } /************************************************************************************************/ static void local_trace_asciival(Trptr t, TimeType tim, int *nmaxlen, int *vmaxlen, char **asciivalue) { int len=0; int vlen=0; if(t->name) { len=font_engine_string_measure(GLOBALS->wavefont, t->name); if((tim!=-1)&&(!(t->flags&TR_EXCLUDE))) { GLOBALS->shift_timebase=t->shift; if(t->vector) { char *str; vptr v; v=bsearch_vector(t->n.vec,tim - t->shift); str=convert_ascii(t,v); if(str) { vlen=font_engine_string_measure(GLOBALS->wavefont,str); *asciivalue=str; } else { vlen=0; *asciivalue=NULL; } } else { char *str; hptr h_ptr; if((h_ptr=bsearch_node(t->n.nd,tim - t->shift))) { if(!t->n.nd->extvals) { unsigned char h_val = h_ptr->v.h_val; if(t->n.nd->vartype == ND_VCD_EVENT) { h_val = (h_ptr->time >= GLOBALS->tims.first) && ((GLOBALS->tims.marker-GLOBALS->shift_timebase) == h_ptr->time) ? AN_1 : AN_0; /* generate impulse */ } str=(char *)calloc_2(1,2*sizeof(char)); if(t->flags&TR_INVERT) { str[0]=AN_STR_INV[h_val]; } else { str[0]=AN_STR[h_val]; } *asciivalue=str; vlen=font_engine_string_measure(GLOBALS->wavefont,str); } else { if(h_ptr->flags&HIST_REAL) { if(!(h_ptr->flags&HIST_STRING)) { #ifdef WAVE_HAS_H_DOUBLE str=convert_ascii_real(t, &h_ptr->v.h_double); #else str=convert_ascii_real(t, (double *)h_ptr->v.h_vector); #endif } else { str=convert_ascii_string((char *)h_ptr->v.h_vector); } } else { str=convert_ascii_vec(t,h_ptr->v.h_vector); } if(str) { vlen=font_engine_string_measure(GLOBALS->wavefont,str); *asciivalue=str; } else { vlen=0; *asciivalue=NULL; } } } else { vlen=0; *asciivalue=NULL; } } } } *nmaxlen = len; *vmaxlen = vlen; } /************************************************************************************************/ static gint expose_event(GtkWidget *widget, GdkEventExpose *event) { gdk_draw_pixmap(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE(widget)], GLOBALS->mo_pixmap_mouseover_c_1, event->area.x, event->area.y, event->area.x, event->area.y, event->area.width, event->area.height); return(FALSE); } static void create_mouseover(gint x, gint y, gint width, gint height) { GLOBALS->mo_width_mouseover_c_1 = width; GLOBALS->mo_height_mouseover_c_1 = height; GLOBALS->mouseover_mouseover_c_1 = gtk_window_new(GTK_WINDOW_POPUP); gtk_window_set_default_size(GTK_WINDOW (GLOBALS->mouseover_mouseover_c_1), width, height); #ifdef WAVE_USE_GTK2 gtk_window_set_type_hint(GTK_WINDOW(GLOBALS->mouseover_mouseover_c_1), GDK_WINDOW_TYPE_HINT_SPLASHSCREEN); gtk_window_move(GTK_WINDOW(GLOBALS->mouseover_mouseover_c_1), x, y); #endif GLOBALS->mo_area_mouseover_c_1=gtk_drawing_area_new(); gtk_container_add(GTK_CONTAINER(GLOBALS->mouseover_mouseover_c_1), GLOBALS->mo_area_mouseover_c_1); gtk_widget_show(GLOBALS->mo_area_mouseover_c_1); gtk_widget_show(GLOBALS->mouseover_mouseover_c_1); #ifndef WAVE_USE_GTK2 gtk_window_reposition(GTK_WINDOW(GLOBALS->mouseover_mouseover_c_1), x, y); /* cuts down on GTK+-1.2 visual noise by moving it here */ #endif GLOBALS->mo_pixmap_mouseover_c_1 = gdk_pixmap_new(GLOBALS->mo_area_mouseover_c_1->window, GLOBALS->mouseover_mouseover_c_1->allocation.width, GLOBALS->mouseover_mouseover_c_1->allocation.height, -1); if(!GLOBALS->mo_dk_gray_mouseover_c_1) GLOBALS->mo_dk_gray_mouseover_c_1 = alloc_color(GLOBALS->mo_area_mouseover_c_1, 0x00cccccc, NULL); if(!GLOBALS->mo_black_mouseover_c_1) GLOBALS->mo_black_mouseover_c_1 = alloc_color(GLOBALS->mo_area_mouseover_c_1, 0x00000000, NULL); gdk_draw_rectangle(GLOBALS->mo_pixmap_mouseover_c_1, GLOBALS->mo_dk_gray_mouseover_c_1, TRUE, 0,0, GLOBALS->mo_width_mouseover_c_1, GLOBALS->mo_height_mouseover_c_1); gdk_draw_rectangle(GLOBALS->mo_pixmap_mouseover_c_1, GLOBALS->mo_black_mouseover_c_1, TRUE, 1,1, GLOBALS->mo_width_mouseover_c_1-2, GLOBALS->mo_height_mouseover_c_1-2); gtkwave_signal_connect(GTK_OBJECT(GLOBALS->mo_area_mouseover_c_1), "expose_event",GTK_SIGNAL_FUNC(expose_event), NULL); } #define MOUSEOVER_BREAKSIZE (32) #define MOUSEOVER_BREAKSIZE_ROWS (64) void move_mouseover(Trptr t, gint xin, gint yin, TimeType tim) { gint xd = 0, yd = 0; char *asciivalue = NULL; int nmaxlen = 0, vmaxlen = 0; int totalmax = 0; int name_charlen = 0, value_charlen = 0; int num_info_rows = 2; char *flagged_name = NULL; char *alternate_name = NULL; int fh; char flag_string[65]; if(GLOBALS->disable_mouseover) { if(GLOBALS->mouseover_mouseover_c_1) { gtk_widget_destroy(GLOBALS->mouseover_mouseover_c_1); GLOBALS->mouseover_mouseover_c_1 = NULL; gdk_pixmap_unref(GLOBALS->mo_pixmap_mouseover_c_1); GLOBALS->mo_pixmap_mouseover_c_1 = NULL; } goto bot; } fh = GLOBALS->wavefont->ascent+GLOBALS->wavefont->descent; if(t) { local_trace_asciival(t, tim, &nmaxlen, &vmaxlen, &asciivalue); value_charlen = asciivalue ? strlen(asciivalue) : 0; name_charlen = t->name ? strlen(t->name) : 0; if(name_charlen) { int len = determine_trace_flags(t->flags, flag_string); flagged_name = malloc_2(name_charlen + 1 + len + 1); memcpy(flagged_name, t->name, name_charlen); flagged_name[name_charlen] = ' '; strcpy(flagged_name+name_charlen+1, flag_string); name_charlen += (len + 1); } if(name_charlen > MOUSEOVER_BREAKSIZE) { alternate_name = malloc_2(MOUSEOVER_BREAKSIZE + 1); strcpy(alternate_name, "..."); strcpy(alternate_name + 3, flagged_name + name_charlen - (MOUSEOVER_BREAKSIZE - 3)); nmaxlen=font_engine_string_measure(GLOBALS->wavefont, alternate_name); } else { nmaxlen=font_engine_string_measure(GLOBALS->wavefont, flagged_name); } if(value_charlen > MOUSEOVER_BREAKSIZE) { char breakbuf[MOUSEOVER_BREAKSIZE+1]; int i, localmax; num_info_rows = (value_charlen + (MOUSEOVER_BREAKSIZE-1)) / MOUSEOVER_BREAKSIZE; vmaxlen = 0; for(i=0;iwavefont, breakbuf); vmaxlen = (localmax > vmaxlen) ? localmax : vmaxlen; } num_info_rows++; } if(num_info_rows > MOUSEOVER_BREAKSIZE_ROWS) num_info_rows = MOUSEOVER_BREAKSIZE_ROWS; /* prevent possible X11 overflow */ totalmax = (nmaxlen > vmaxlen) ? nmaxlen : vmaxlen; totalmax += 8; totalmax = (totalmax + 1) & ~1; /* round up to next even pixel count */ if((GLOBALS->mouseover_mouseover_c_1)&&((totalmax != GLOBALS->mo_width_mouseover_c_1)||((num_info_rows * fh + 7) != GLOBALS->mo_height_mouseover_c_1))) { gtk_widget_destroy(GLOBALS->mouseover_mouseover_c_1); GLOBALS->mouseover_mouseover_c_1 = NULL; gdk_pixmap_unref(GLOBALS->mo_pixmap_mouseover_c_1); GLOBALS->mo_pixmap_mouseover_c_1 = NULL; } } if((!t)||(yin<0)||(yin>GLOBALS->waveheight)) { if(GLOBALS->mouseover_mouseover_c_1) { gtk_widget_destroy(GLOBALS->mouseover_mouseover_c_1); GLOBALS->mouseover_mouseover_c_1 = NULL; gdk_pixmap_unref(GLOBALS->mo_pixmap_mouseover_c_1); GLOBALS->mo_pixmap_mouseover_c_1 = NULL; } goto bot; } if(!GLOBALS->mouseover_mouseover_c_1) { #ifdef WAVE_USE_GTK2 gdk_window_get_origin(GLOBALS->wavearea->window, &xd, &yd); #else gdk_window_get_deskrelative_origin(GLOBALS->wavearea->window, &xd, &yd); #endif create_mouseover(xin + xd + 8, yin + yd + 20, totalmax, num_info_rows * fh + 7); } else { #ifdef WAVE_USE_GTK2 gdk_window_get_origin(GLOBALS->wavearea->window, &xd, &yd); gtk_window_move(GTK_WINDOW(GLOBALS->mouseover_mouseover_c_1), xin + xd + 8, yin + yd + 20); #else gdk_window_get_deskrelative_origin(GLOBALS->wavearea->window, &xd, &yd); gtk_window_reposition(GTK_WINDOW(GLOBALS->mouseover_mouseover_c_1), xin + xd + 8, yin + yd + 20); #endif } gdk_draw_rectangle(GLOBALS->mo_pixmap_mouseover_c_1, GLOBALS->mo_dk_gray_mouseover_c_1, TRUE, 0,0, GLOBALS->mo_width_mouseover_c_1, GLOBALS->mo_height_mouseover_c_1); gdk_draw_rectangle(GLOBALS->mo_pixmap_mouseover_c_1, GLOBALS->mo_black_mouseover_c_1, TRUE, 1,1, GLOBALS->mo_width_mouseover_c_1-2, GLOBALS->mo_height_mouseover_c_1-2); font_engine_draw_string(GLOBALS->mo_pixmap_mouseover_c_1, GLOBALS->wavefont, GLOBALS->mo_dk_gray_mouseover_c_1, 4, fh + 2, alternate_name ? alternate_name : flagged_name); if(num_info_rows == 2) { if(asciivalue) font_engine_draw_string(GLOBALS->mo_pixmap_mouseover_c_1, GLOBALS->wavefont, GLOBALS->mo_dk_gray_mouseover_c_1, 4, 2*fh+2, asciivalue); } else { char breakbuf[MOUSEOVER_BREAKSIZE+1]; int i; num_info_rows--; for(i=0;imo_pixmap_mouseover_c_1, GLOBALS->wavefont, GLOBALS->mo_dk_gray_mouseover_c_1, 4, ((2+i)*fh)+2, breakbuf); } } gdk_window_raise(GLOBALS->mouseover_mouseover_c_1->window); gdk_draw_pixmap(GLOBALS->mo_area_mouseover_c_1->window, GLOBALS->mo_area_mouseover_c_1->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->mouseover_mouseover_c_1)],GLOBALS->mo_pixmap_mouseover_c_1,0,0,0,0,GLOBALS->mo_width_mouseover_c_1, GLOBALS->mo_height_mouseover_c_1); bot: if(asciivalue) { free_2(asciivalue); } if(alternate_name) { free_2(alternate_name); } if(flagged_name) { free_2(flagged_name); } } gtkwave-3.3.66/src/discardbuttons.c0000664000076400007640000000433512341266475016601 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999. * * 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. */ #include "globals.h" #include #include "currenttime.h" #include "pixmaps.h" #include "debug.h" /* Create actual buttons */ GtkWidget * create_discard_buttons (void) { GtkWidget *table; GtkWidget *table2; GtkWidget *frame; GtkWidget *main_vbox; GtkWidget *b1; GtkWidget *b2; GtkWidget *pixmapwid1, *pixmapwid2; GtkTooltips *tooltips; tooltips=gtk_tooltips_new_2(); gtk_tooltips_set_delay_2(tooltips,1500); pixmapwid1=gtk_pixmap_new(GLOBALS->larrow_pixmap, GLOBALS->larrow_mask); gtk_widget_show(pixmapwid1); pixmapwid2=gtk_pixmap_new(GLOBALS->rarrow_pixmap, GLOBALS->rarrow_mask); gtk_widget_show(pixmapwid2); /* Create a table to hold the text widget and scrollbars */ table = gtk_table_new (1, 1, FALSE); main_vbox = gtk_vbox_new (FALSE, 1); gtk_container_border_width (GTK_CONTAINER (main_vbox), 1); gtk_container_add (GTK_CONTAINER (table), main_vbox); frame = gtk_frame_new ("Disc "); gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0); gtk_widget_show (frame); gtk_widget_show (main_vbox); table2 = gtk_table_new (2, 1, FALSE); b1 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b1), pixmapwid1); gtk_table_attach (GTK_TABLE (table2), b1, 0, 1, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); gtk_signal_connect_object (GTK_OBJECT (b1), "clicked", GTK_SIGNAL_FUNC(discard_left), GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(tooltips, b1, "Increase 'From' Time", NULL); gtk_widget_show(b1); b2 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b2), pixmapwid2); gtk_table_attach (GTK_TABLE (table2), b2, 0, 1, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); gtk_signal_connect_object (GTK_OBJECT (b2), "clicked", GTK_SIGNAL_FUNC(discard_right), GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(tooltips, b2, "Decrease 'To' Time", NULL); gtk_widget_show(b2); gtk_container_add (GTK_CONTAINER (frame), table2); gtk_widget_show(table2); return(table); } gtkwave-3.3.66/src/ptranslate.c0000664000076400007640000003200012360623564015711 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2005-2009. * * 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. */ #include "globals.h" #include #include #include "gtk12compat.h" #include "symbol.h" #include "ptranslate.h" #include "pipeio.h" #include "debug.h" #ifdef _MSC_VER #define strcasecmp _stricmp #endif void init_proctrans_data(void) { int i; if(!GLOBALS->procsel_filter) { GLOBALS->procsel_filter = calloc_2(PROC_FILTER_MAX+1, sizeof(char *)); } if(!GLOBALS->proc_filter) { GLOBALS->proc_filter = calloc_2(PROC_FILTER_MAX+1, sizeof(struct pipe_ctx *)); } for(i=0;iprocsel_filter[i] = NULL; GLOBALS->proc_filter[i] = NULL; } } void remove_all_proc_filters(void) { struct Global *GLOBALS_cache = GLOBALS; unsigned int i, j; for(j=0;jnum_notebook_pages;j++) { GLOBALS = (*GLOBALS->contexts)[j]; if(GLOBALS) { for(i=1;iproc_filter[i]) { pipeio_destroy(GLOBALS->proc_filter[i]); GLOBALS->proc_filter[i] = NULL; } if(GLOBALS->procsel_filter[i]) { free_2(GLOBALS->procsel_filter[i]); GLOBALS->procsel_filter[i] = NULL; } } } GLOBALS = GLOBALS_cache; } } static void regen_display(void) { GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } /* * this is likely obsolete */ #if 0 static void remove_proc_filter(int which, int regen) { if(GLOBALS->proc_filter[which]) { pipeio_destroy(GLOBALS->proc_filter[which]); GLOBALS->proc_filter[which] = NULL; if(regen) { regen_display(); } } } #endif static void load_proc_filter(int which, char *name) { FILE *stream; char *cmd; char exec_name[1025]; char abs_path [1025]; char* arg, end; int result; exec_name[0] = 0; abs_path[0] = 0; /* if name has arguments grab only the first word (the name of the executable)*/ sscanf(name, "%s ", exec_name); arg = name + strlen(exec_name); /* remove leading spaces from argument */ while (isspace((int)(unsigned char)arg[0])) { arg++; } /* remove trailing spaces from argument */ if (strlen(arg) > 0) { end = strlen(arg) - 1; while (arg[(int)end] == ' ') { arg[(int)end] = 0; end--; } } /* turn the exec_name into an absolute path */ #if !defined __MINGW32__ && !defined _MSC_VER cmd = (char *)malloc_2(strlen(exec_name)+6+1); sprintf(cmd, "which %s", exec_name); stream = popen(cmd, "r"); result = fscanf(stream, "%s", abs_path); if((strlen(abs_path) == 0)||(!result)) { status_text("Could not find filter process!\n"); pclose(stream); /* cppcheck */ return; } pclose(stream); free_2(cmd); #else strcpy(abs_path, exec_name); #endif /* remove_proc_filter(which, 0); ... should never happen from GUI, but perhaps possible from save files or other weirdness */ if(!GLOBALS->ttrans_filter[which]) { GLOBALS->proc_filter[which] = pipeio_create(abs_path, arg); } } int install_proc_filter(int which) { int found = 0; if((which<0)||(which>=(PROC_FILTER_MAX+1))) { which = 0; } if(GLOBALS->traces.first) { Trptr t = GLOBALS->traces.first; while(t) { if(t->flags&TR_HIGHLIGHT) { if(!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH))) { t->f_filter = 0; t->p_filter = which; if(!which) { t->flags &= (~(TR_FTRANSLATED|TR_PTRANSLATED|TR_ANALOGMASK)); } else { t->flags &= (~(TR_ANALOGMASK)); t->flags |= TR_PTRANSLATED; } found++; } } t=t->t_next; } } if(found) { regen_display(); } return(found); } /************************************************************************/ static void destroy_callback(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; GLOBALS->is_active_ptranslate_c_2=0; gtk_widget_destroy(GLOBALS->window_ptranslate_c_5); GLOBALS->window_ptranslate_c_5 = NULL; } static void ok_callback(GtkWidget *widget, GtkWidget *nothing) { install_proc_filter(GLOBALS->current_filter_ptranslate_c_1); destroy_callback(widget, nothing); } static void select_row_callback(GtkWidget *widget, gint row, gint column, GdkEventButton *event, gpointer data) { (void)widget; (void)row; (void)column; (void)event; (void)data; GLOBALS->current_filter_ptranslate_c_1 = row + 1; } static void unselect_row_callback(GtkWidget *widget, gint row, gint column, GdkEventButton *event, gpointer data) { (void)widget; (void)row; (void)column; (void)event; (void)data; GLOBALS->current_filter_ptranslate_c_1 = 0; /* none */ } static void add_filter_callback_2(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; int i; GtkCList *cl; if(!GLOBALS->filesel_ok) { return; } if(*GLOBALS->fileselbox_text) { for(i=0;inum_proc_filters;i++) { if(GLOBALS->procsel_filter[i]) { if(!strcmp(GLOBALS->procsel_filter[i], *GLOBALS->fileselbox_text)) { status_text("Filter already imported.\n"); if(GLOBALS->is_active_ptranslate_c_2) gdk_window_raise(GLOBALS->window_ptranslate_c_5->window); return; } } } } GLOBALS->num_proc_filters++; load_proc_filter(GLOBALS->num_proc_filters, *GLOBALS->fileselbox_text); if(GLOBALS->proc_filter[GLOBALS->num_proc_filters]) { if(GLOBALS->procsel_filter[GLOBALS->num_proc_filters]) free_2(GLOBALS->procsel_filter[GLOBALS->num_proc_filters]); GLOBALS->procsel_filter[GLOBALS->num_proc_filters] = malloc_2(strlen(*GLOBALS->fileselbox_text) + 1); strcpy(GLOBALS->procsel_filter[GLOBALS->num_proc_filters], *GLOBALS->fileselbox_text); cl=GTK_CLIST(GLOBALS->clist_ptranslate_c_2); gtk_clist_freeze(cl); gtk_clist_append(cl,(gchar **)&(GLOBALS->procsel_filter[GLOBALS->num_proc_filters])); gtk_clist_set_column_width(cl,0,gtk_clist_optimal_column_width(cl,0)); gtk_clist_thaw(cl); } else { GLOBALS->num_proc_filters--; } if(GLOBALS->is_active_ptranslate_c_2) gdk_window_raise(GLOBALS->window_ptranslate_c_5->window); } static void add_filter_callback(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; if(GLOBALS->num_proc_filters == PROC_FILTER_MAX) { status_text("Max number of process filters installed already.\n"); return; } fileselbox("Select Filter Process",&GLOBALS->fcurr_ptranslate_c_1,GTK_SIGNAL_FUNC(add_filter_callback_2), GTK_SIGNAL_FUNC(NULL),"*", 0); } /* * mainline.. */ void ptrans_searchbox(char *title) { int i; GtkWidget *scrolled_win; GtkWidget *vbox1, *hbox, *hbox0; GtkWidget *button1, *button5, *button6; gchar *titles[]={"Process Filter Select"}; GtkWidget *frame2, *frameh, *frameh0; GtkWidget *table; GtkTooltips *tooltips; if(GLOBALS->is_active_ptranslate_c_2) { gdk_window_raise(GLOBALS->window_ptranslate_c_5->window); return; } GLOBALS->is_active_ptranslate_c_2=1; GLOBALS->current_filter_ptranslate_c_1 = 0; /* create a new modal window */ GLOBALS->window_ptranslate_c_5 = gtk_window_new(GLOBALS->disable_window_manager ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL); install_focus_cb(GLOBALS->window_ptranslate_c_5, ((char *)&GLOBALS->window_ptranslate_c_5) - ((char *)GLOBALS)); gtk_window_set_title(GTK_WINDOW (GLOBALS->window_ptranslate_c_5), title); gtkwave_signal_connect(GTK_OBJECT (GLOBALS->window_ptranslate_c_5), "delete_event",(GtkSignalFunc) destroy_callback, NULL); tooltips=gtk_tooltips_new_2(); table = gtk_table_new (256, 1, FALSE); gtk_widget_show (table); vbox1 = gtk_vbox_new (FALSE, 0); gtk_container_border_width (GTK_CONTAINER (vbox1), 3); gtk_widget_show (vbox1); frame2 = gtk_frame_new (NULL); gtk_container_border_width (GTK_CONTAINER (frame2), 3); gtk_widget_show(frame2); gtk_table_attach (GTK_TABLE (table), frame2, 0, 1, 0, 254, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); GLOBALS->clist_ptranslate_c_2=gtk_clist_new_with_titles(1,titles); gtk_clist_column_titles_passive(GTK_CLIST(GLOBALS->clist_ptranslate_c_2)); gtk_clist_set_selection_mode(GTK_CLIST(GLOBALS->clist_ptranslate_c_2), GTK_SELECTION_EXTENDED); gtkwave_signal_connect_object (GTK_OBJECT (GLOBALS->clist_ptranslate_c_2), "select_row",GTK_SIGNAL_FUNC(select_row_callback),NULL); gtkwave_signal_connect_object (GTK_OBJECT (GLOBALS->clist_ptranslate_c_2), "unselect_row",GTK_SIGNAL_FUNC(unselect_row_callback),NULL); for(i=0;inum_proc_filters;i++) { gtk_clist_append(GTK_CLIST(GLOBALS->clist_ptranslate_c_2),(gchar **)&(GLOBALS->procsel_filter[i+1])); } gtk_clist_set_column_width(GTK_CLIST(GLOBALS->clist_ptranslate_c_2),0,gtk_clist_optimal_column_width(GTK_CLIST(GLOBALS->clist_ptranslate_c_2),0)); gtk_widget_show (GLOBALS->clist_ptranslate_c_2); scrolled_win = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_widget_set_usize( GTK_WIDGET (scrolled_win), -1, 300); gtk_widget_show(scrolled_win); /* gtk_scrolled_window_add_with_viewport doesn't seen to work right here.. */ gtk_container_add (GTK_CONTAINER (scrolled_win), GLOBALS->clist_ptranslate_c_2); gtk_container_add (GTK_CONTAINER (frame2), scrolled_win); frameh0 = gtk_frame_new (NULL); gtk_container_border_width (GTK_CONTAINER (frameh0), 3); gtk_widget_show(frameh0); gtk_table_attach (GTK_TABLE (table), frameh0, 0, 1, 254, 255, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); hbox0 = gtk_hbox_new (FALSE, 1); gtk_widget_show (hbox0); button6 = gtk_button_new_with_label (" Add Proc Filter to List "); gtk_container_border_width (GTK_CONTAINER (button6), 3); gtkwave_signal_connect_object (GTK_OBJECT (button6), "clicked",GTK_SIGNAL_FUNC(add_filter_callback),GTK_OBJECT (GLOBALS->window_ptranslate_c_5)); gtk_widget_show (button6); gtk_tooltips_set_tip_2(tooltips, button6, "Bring up a file requester to add a process filter to the filter select window.",NULL); gtk_box_pack_start (GTK_BOX (hbox0), button6, TRUE, FALSE, 0); gtk_container_add (GTK_CONTAINER (frameh0), hbox0); frameh = gtk_frame_new (NULL); gtk_container_border_width (GTK_CONTAINER (frameh), 3); gtk_widget_show(frameh); gtk_table_attach (GTK_TABLE (table), frameh, 0, 1, 255, 256, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); hbox = gtk_hbox_new (FALSE, 1); gtk_widget_show (hbox); button1 = gtk_button_new_with_label (" OK "); gtk_container_border_width (GTK_CONTAINER (button1), 3); gtkwave_signal_connect_object (GTK_OBJECT (button1), "clicked",GTK_SIGNAL_FUNC(ok_callback),GTK_OBJECT (GLOBALS->window_ptranslate_c_5)); gtk_widget_show (button1); gtk_tooltips_set_tip_2(tooltips, button1, "Add selected signals to end of the display on the main window.",NULL); gtk_box_pack_start (GTK_BOX (hbox), button1, TRUE, FALSE, 0); button5 = gtk_button_new_with_label (" Cancel "); gtk_container_border_width (GTK_CONTAINER (button5), 3); gtkwave_signal_connect_object (GTK_OBJECT (button5), "clicked",GTK_SIGNAL_FUNC(destroy_callback),GTK_OBJECT (GLOBALS->window_ptranslate_c_5)); gtk_tooltips_set_tip_2(tooltips, button5, "Do nothing and return to the main window.",NULL); gtk_widget_show (button5); gtk_box_pack_start (GTK_BOX (hbox), button5, TRUE, FALSE, 0); gtk_container_add (GTK_CONTAINER (frameh), hbox); gtk_container_add (GTK_CONTAINER (GLOBALS->window_ptranslate_c_5), table); gtk_widget_set_usize(GTK_WIDGET(GLOBALS->window_ptranslate_c_5), 400, 400); gtk_widget_show(GLOBALS->window_ptranslate_c_5); } /* * currently only called by parsewavline */ void set_current_translate_proc(char *name) { int i; for(i=1;inum_proc_filters+1;i++) { if(!strcmp(GLOBALS->procsel_filter[i], name)) { GLOBALS->current_translate_proc = i; return; } } if(GLOBALS->num_proc_filters < PROC_FILTER_MAX) { GLOBALS->num_proc_filters++; load_proc_filter(GLOBALS->num_proc_filters, name); if(!GLOBALS->proc_filter[GLOBALS->num_proc_filters]) { GLOBALS->num_proc_filters--; GLOBALS->current_translate_proc = 0; } else { if(GLOBALS->procsel_filter[GLOBALS->num_proc_filters]) free_2(GLOBALS->procsel_filter[GLOBALS->num_proc_filters]); GLOBALS->procsel_filter[GLOBALS->num_proc_filters] = malloc_2(strlen(name) + 1); strcpy(GLOBALS->procsel_filter[GLOBALS->num_proc_filters], name); GLOBALS->current_translate_proc = GLOBALS->num_proc_filters; } } } gtkwave-3.3.66/src/ghw.h0000664000076400007640000000101012341266475014326 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2005. * * 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. */ #include "globals.h" #ifndef GHW_H #define GHW_H #include #include "tree.h" #include "vcd.h" #define WAVE_GHW_DUMMYFACNAME "!!__(dummy)__!!" TimeType ghw_main(char *fname); int strand_pnt(char *s); #endif gtkwave-3.3.66/src/fst.c0000664000076400007640000014565612513326514014351 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2009-2015. * * 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. */ #include #include "globals.h" #include #include "fstapi.h" #include "lx2.h" #ifndef _MSC_VER #include #endif #include #include #include #include "symbol.h" #include "vcd.h" #include "lxt.h" #include "lxt2_read.h" #include "vzt_read.h" #include "fstapi.h" #include "debug.h" #include "busy.h" #include "hierpack.h" #include "fst.h" #define FST_RDLOAD "FSTLOAD | " /******************************************************************/ /* * doubles going into histent structs are NEVER freed so this is OK.. * (we are allocating as many entries that fit in 4k minus the size of the two * bookkeeping void* pointers found in the malloc_2/free_2 routines in * debug.c) */ #ifdef _WAVE_HAVE_JUDY #define FST_DOUBLE_GRANULARITY ( (4*1024) / sizeof(double) ) #else #define FST_DOUBLE_GRANULARITY ( ( (4*1024)-(2*sizeof(void *)) ) / sizeof(double) ) #endif #ifndef WAVE_HAS_H_DOUBLE static void *double_slab_calloc(void) { if(GLOBALS->double_curr_fst==GLOBALS->double_fini_fst) { GLOBALS->double_curr_fst=(double *)calloc_2(FST_DOUBLE_GRANULARITY, sizeof(double)); GLOBALS->double_fini_fst=GLOBALS->double_curr_fst+FST_DOUBLE_GRANULARITY; } return((void *)(GLOBALS->double_curr_fst++)); } #endif /* * reverse equality mem compare */ static int memrevcmp(int i, const char *s1, const char *s2) { i--; for(;i>=0;i--) { if(s1[i] != s2[i]) break; } return(i+1); } /* * fast itoa for decimal numbers */ static char* itoa_2(int value, char* result) { char* ptr = result, *ptr1 = result, tmp_char; int tmp_value; do { tmp_value = value; value /= 10; *ptr++ = "9876543210123456789" [9 + (tmp_value - value * 10)]; } while ( value ); if (tmp_value < 0) *ptr++ = '-'; result = ptr; *ptr-- = '\0'; while(ptr1 < ptr) { tmp_char = *ptr; *ptr--= *ptr1; *ptr1++ = tmp_char; } return(result); } /* * preformatted sprintf statements which remove parsing latency */ static int sprintf_2_sd(char *s, char *c, int d) { char *s2 = s; while(*c) { *(s2++) = *(c++); } *(s2++) = '['; s2 = itoa_2(d, s2); *(s2++) = ']'; *s2 = 0; return(s2 - s); } static int sprintf_2_sdd(char *s, char *c, int d, int d2) { char *s2 = s; while(*c) { *(s2++) = *(c++); } *(s2++) = '['; s2 = itoa_2(d, s2); *(s2++) = ':'; s2 = itoa_2(d2, s2); *(s2++) = ']'; *s2 = 0; return(s2 - s); } /******************************************************************/ static struct fstHier *extractNextVar(void *xc, int *msb, int *lsb, char **nam, int *namlen, unsigned int *nnam_max) { struct fstHier *h; const char *pnts; char *pnt, *pntd, *lb_last = NULL, *col_last = NULL; /* *rb_last = NULL; */ /* scan-build : unused */ int acc; char *s; unsigned char ttype; int sdt = FST_SDT_NONE; int svt = FST_SVT_NONE; long sxt = 0; while((h = fstReaderIterateHier(xc))) { switch(h->htyp) { case FST_HT_SCOPE: GLOBALS->fst_scope_name = fstReaderPushScope(xc, h->u.scope.name, GLOBALS->mod_tree_parent); GLOBALS->fst_scope_name_len = fstReaderGetCurrentScopeLen(xc); switch(h->u.scope.typ) { case FST_ST_VCD_MODULE: ttype = TREE_VCD_ST_MODULE; break; case FST_ST_VCD_TASK: ttype = TREE_VCD_ST_TASK; break; case FST_ST_VCD_FUNCTION: ttype = TREE_VCD_ST_FUNCTION; break; case FST_ST_VCD_BEGIN: ttype = TREE_VCD_ST_BEGIN; break; case FST_ST_VCD_FORK: ttype = TREE_VCD_ST_FORK; break; case FST_ST_VCD_GENERATE: ttype = TREE_VCD_ST_GENERATE; break; case FST_ST_VCD_STRUCT: ttype = TREE_VCD_ST_STRUCT; break; case FST_ST_VCD_UNION: ttype = TREE_VCD_ST_UNION; break; case FST_ST_VCD_CLASS: ttype = TREE_VCD_ST_CLASS; break; case FST_ST_VCD_INTERFACE: ttype = TREE_VCD_ST_INTERFACE; break; case FST_ST_VCD_PACKAGE: ttype = TREE_VCD_ST_PACKAGE; break; case FST_ST_VCD_PROGRAM: ttype = TREE_VCD_ST_PROGRAM; break; case FST_ST_VHDL_ARCHITECTURE: ttype = TREE_VHDL_ST_ARCHITECTURE; break; case FST_ST_VHDL_PROCEDURE: ttype = TREE_VHDL_ST_PROCEDURE; break; case FST_ST_VHDL_FUNCTION: ttype = TREE_VHDL_ST_FUNCTION; break; case FST_ST_VHDL_RECORD: ttype = TREE_VHDL_ST_RECORD; break; case FST_ST_VHDL_PROCESS: ttype = TREE_VHDL_ST_PROCESS; break; case FST_ST_VHDL_BLOCK: ttype = TREE_VHDL_ST_BLOCK; break; case FST_ST_VHDL_FOR_GENERATE: ttype = TREE_VHDL_ST_GENFOR; break; case FST_ST_VHDL_IF_GENERATE: ttype = TREE_VHDL_ST_GENIF; break; case FST_ST_VHDL_GENERATE: ttype = TREE_VHDL_ST_GENERATE; break; case FST_ST_VHDL_PACKAGE: ttype = TREE_VHDL_ST_PACKAGE; break; default: ttype = TREE_UNKNOWN; break; } allocate_and_decorate_module_tree_node(ttype, h->u.scope.name, h->u.scope.component, h->u.scope.name_length, h->u.scope.component_length, GLOBALS->stem_valid ? GLOBALS->stem_struct_base_siz : 0, GLOBALS->istem_valid ? GLOBALS->istem_struct_base_siz : 0); GLOBALS->stem_valid = GLOBALS->istem_valid = 0; break; case FST_HT_UPSCOPE: GLOBALS->mod_tree_parent = fstReaderGetCurrentScopeUserInfo(xc); GLOBALS->fst_scope_name = fstReaderPopScope(xc); GLOBALS->fst_scope_name_len = fstReaderGetCurrentScopeLen(xc); break; case FST_HT_VAR: /* GLOBALS->fst_scope_name = fstReaderGetCurrentFlatScope(xc); */ /* GLOBALS->fst_scope_name_len = fstReaderGetCurrentScopeLen(xc); */ if(h->u.var.name_length > (*nnam_max)) { free_2(*nam); *nam = malloc_2(((*nnam_max) = h->u.var.name_length) + 1); } s = *nam; pnts = h->u.var.name; pntd = s; while(*pnts) { if(*pnts != ' ') { if(*pnts == '[') { lb_last = pntd; col_last = NULL; } else if(*pnts == ':') { col_last = pntd; } /* else if(*pnts == ']') { rb_last = pntd; } */ /* scan-build : unused */ *(pntd++) = *pnts; } pnts++; } *pntd = 0; *namlen = pntd - s; if(!lb_last) { *msb = *lsb = -1; } else if ((h->u.var.length > 1) && !col_last && lb_last) /* add for NC arrays that don't add final explicit bitrange like VCS does */ { lb_last = NULL; *msb = h->u.var.length -1; *lsb = 0; } else { int sgna = 1, sgnb = 1; pnt = lb_last + 1; acc = 0; while(isdigit((int)(unsigned char)*pnt) || (*pnt == '-')) { if(*pnt != '-') { acc *= 10; acc += (*pnt - '0'); } else { sgna = -1; } pnt++; } *msb = acc * sgna; if(!col_last) { *lsb = acc; } else { pnt = col_last + 1; acc = 0; while(isdigit((int)(unsigned char)*pnt) || (*pnt == '-')) { if(*pnt != '-') { acc *= 10; acc += (*pnt - '0'); } else { sgnb = -1; } pnt++; } *lsb = acc * sgnb; } } if(lb_last) { *lb_last = 0; if((lb_last - s) < (*namlen)) { *namlen = lb_last - s; } } *nam = s; h->u.var.svt_workspace = svt; h->u.var.sdt_workspace = sdt; h->u.var.sxt_workspace = sxt; return(h); break; case FST_HT_ATTRBEGIN: /* currently ignored for most cases except VHDL variable vartype/datatype creation */ if(h->u.attr.typ == FST_AT_MISC) { if(h->u.attr.subtype == FST_MT_SUPVAR) { if(h->u.attr.name) { JRB subvar_jrb_node; char *attr_pnt; if(GLOBALS->fst_filetype == FST_FT_VHDL) { char *lc_p = attr_pnt = strdup_2(h->u.attr.name); while(*lc_p) { *lc_p = tolower(*lc_p); /* convert attrib name to lowercase for VHDL */ lc_p++; } } else { attr_pnt = NULL; } /* sxt points to actual type name specified in FST file */ subvar_jrb_node = jrb_find_str(GLOBALS->subvar_jrb, attr_pnt ? attr_pnt : h->u.attr.name); if(subvar_jrb_node) { sxt = subvar_jrb_node->val.ui; } else { Jval jv; if(GLOBALS->subvar_jrb_count != WAVE_VARXT_MAX_ID) { sxt = jv.ui = ++GLOBALS->subvar_jrb_count; /* subvar_jrb_node = */ jrb_insert_str(GLOBALS->subvar_jrb, strdup_2(attr_pnt ? attr_pnt : h->u.attr.name), jv); } else { sxt = 0; if(!GLOBALS->subvar_jrb_count_locked) { fprintf(stderr, FST_RDLOAD"Max number (%d) of type attributes reached, please increase WAVE_VARXT_MAX_ID.\n", WAVE_VARXT_MAX_ID); GLOBALS->subvar_jrb_count_locked = 1; } } } if(attr_pnt) { free_2(attr_pnt); } } svt = h->u.attr.arg >> FST_SDT_SVT_SHIFT_COUNT; sdt = h->u.attr.arg & (FST_SDT_ABS_MAX-1); GLOBALS->supplemental_datatypes_encountered = 1; GLOBALS->supplemental_vartypes_encountered |= ((svt != FST_SVT_NONE) && (svt != FST_SVT_VHDL_SIGNAL)); } else if(h->u.attr.subtype == FST_MT_SOURCEISTEM) { uint32_t istem_path_number = (uint32_t)h->u.attr.arg_from_name; uint32_t istem_line_number = (uint32_t)h->u.attr.arg; if(istem_path_number <= GLOBALS->stem_path_string_table_siz) /* prevent overflows from malformed writers */ { GLOBALS->istem_valid = 1; if(!GLOBALS->istem_struct_base) { GLOBALS->istem_struct_base_siz_alloc = 1; GLOBALS->istem_struct_base_siz = 0; GLOBALS->istem_struct_base = malloc_2(GLOBALS->istem_struct_base_siz_alloc * sizeof(struct stem_struct_t)); } if(GLOBALS->istem_struct_base_siz == GLOBALS->istem_struct_base_siz_alloc) { GLOBALS->istem_struct_base_siz_alloc *= 2; GLOBALS->istem_struct_base = realloc_2(GLOBALS->istem_struct_base, GLOBALS->istem_struct_base_siz_alloc * sizeof(struct stem_struct_t)); } GLOBALS->istem_struct_base[GLOBALS->istem_struct_base_siz].stem_idx = istem_path_number - 1; GLOBALS->istem_struct_base[GLOBALS->istem_struct_base_siz].stem_line_number = istem_line_number; GLOBALS->istem_struct_base_siz++; } } else if(h->u.attr.subtype == FST_MT_SOURCESTEM) { uint32_t stem_path_number = (uint32_t)h->u.attr.arg_from_name; uint32_t stem_line_number = (uint32_t)h->u.attr.arg; if(stem_path_number <= GLOBALS->stem_path_string_table_siz) /* prevent overflows from malformed writers */ { GLOBALS->stem_valid = 1; if(!GLOBALS->stem_struct_base) { GLOBALS->stem_struct_base_siz_alloc = 1; GLOBALS->stem_struct_base_siz = 0; GLOBALS->stem_struct_base = malloc_2(GLOBALS->stem_struct_base_siz_alloc * sizeof(struct stem_struct_t)); } if(GLOBALS->stem_struct_base_siz == GLOBALS->stem_struct_base_siz_alloc) { GLOBALS->stem_struct_base_siz_alloc *= 2; GLOBALS->stem_struct_base = realloc_2(GLOBALS->stem_struct_base, GLOBALS->stem_struct_base_siz_alloc * sizeof(struct stem_struct_t)); } GLOBALS->stem_struct_base[GLOBALS->stem_struct_base_siz].stem_idx = stem_path_number - 1; GLOBALS->stem_struct_base[GLOBALS->stem_struct_base_siz].stem_line_number = stem_line_number; GLOBALS->stem_struct_base_siz++; } } else if(h->u.attr.subtype == FST_MT_PATHNAME) { if(h->u.attr.name && ((GLOBALS->stem_path_string_table_siz+1) == h->u.attr.arg)) { /* == check against h->u.attr.arg is a sanity check against the writer */ if(!GLOBALS->stem_path_string_table) { GLOBALS->stem_path_string_table_alloc = 1; GLOBALS->stem_path_string_table_siz = 0; GLOBALS->stem_path_string_table = malloc_2(GLOBALS->stem_path_string_table_alloc * sizeof(char *)); } if(GLOBALS->stem_path_string_table_siz == GLOBALS->stem_path_string_table_alloc) { GLOBALS->stem_path_string_table_alloc *= 2; GLOBALS->stem_path_string_table = realloc_2(GLOBALS->stem_path_string_table, GLOBALS->stem_path_string_table_alloc * sizeof(char *)); } GLOBALS->stem_path_string_table[GLOBALS->stem_path_string_table_siz] = strdup_2(h->u.attr.name); GLOBALS->stem_path_string_table_siz++; } } else if(h->u.attr.subtype == FST_MT_VALUELIST) { if(h->u.attr.name) { /* format is concatenations of [m b xs xe valstring] */ if(GLOBALS->fst_synclock_str) { free_2(GLOBALS->fst_synclock_str); } GLOBALS->fst_synclock_str = strdup_2(h->u.attr.name); } } } break; case FST_HT_ATTREND: break; default: break; } } *namlen = 0; *nam = NULL; return(NULL); } static void fst_append_graft_chain(int len, char *nam, int which, struct tree *par) { struct tree *t = talloc_2(sizeof(struct tree) + len + 1); memcpy(t->name, nam, len+1); t->t_which = which; t->child = par; t->next = GLOBALS->terminals_tchain_tree_c_1; GLOBALS->terminals_tchain_tree_c_1 = t; } /* * mainline */ TimeType fst_main(char *fname, char *skip_start, char *skip_end) { int i; struct Node *n; struct symbol *s, *prevsymroot=NULL, *prevsym=NULL; signed char scale; int numalias = 0; int numvars = 0; struct symbol *sym_block = NULL; struct Node *node_block = NULL; struct fstHier *h = NULL; int msb, lsb; char *nnam = NULL; uint32_t activity_idx, num_activity_changes; struct tree *npar = NULL; char **f_name = NULL; int *f_name_len = NULL, *f_name_max_len = NULL; int allowed_to_autocoalesce; unsigned int nnam_max = 0; int f_name_build_buf_len = 128; char *f_name_build_buf = malloc_2(f_name_build_buf_len + 1); GLOBALS->fst_fst_c_1 = fstReaderOpen(fname); if(!GLOBALS->fst_fst_c_1) { return(LLDescriptor(0)); /* look at GLOBALS->fst_fst_c_1 in caller for success status... */ } /* SPLASH */ splash_create(); allowed_to_autocoalesce = (strstr(fstReaderGetVersionString(GLOBALS->fst_fst_c_1), "Icarus") == NULL); if(!allowed_to_autocoalesce) { GLOBALS->autocoalesce = 0; } scale=(signed char)fstReaderGetTimescale(GLOBALS->fst_fst_c_1); exponent_to_time_scale(scale); f_name = calloc_2(F_NAME_MODULUS+1,sizeof(char *)); f_name_len = calloc_2(F_NAME_MODULUS+1,sizeof(int)); f_name_max_len = calloc_2(F_NAME_MODULUS+1,sizeof(int)); nnam_max = 16; nnam = malloc_2(nnam_max + 1); GLOBALS->fst_filetype = fstReaderGetFileType(GLOBALS->fst_fst_c_1); if(GLOBALS->fst_filetype == FST_FT_VHDL) { GLOBALS->is_vhdl_component_format = 1; } GLOBALS->subvar_jrb = make_jrb(); /* only used for attributes such as generated in VHDL, etc. */ GLOBALS->synclock_jrb = make_jrb(); /* only used for synthetic clocks */ GLOBALS->numfacs=fstReaderGetVarCount(GLOBALS->fst_fst_c_1); GLOBALS->mvlfacs_fst_c_3=(struct fac *)calloc_2(GLOBALS->numfacs,sizeof(struct fac)); GLOBALS->fst_table_fst_c_1=(struct lx2_entry *)calloc_2(GLOBALS->numfacs, sizeof(struct lx2_entry)); sym_block = (struct symbol *)calloc_2(GLOBALS->numfacs, sizeof(struct symbol)); node_block=(struct Node *)calloc_2(GLOBALS->numfacs,sizeof(struct Node)); GLOBALS->facs=(struct symbol **)malloc_2(GLOBALS->numfacs*sizeof(struct symbol *)); GLOBALS->mvlfacs_fst_alias = calloc_2(GLOBALS->numfacs,sizeof(fstHandle)); GLOBALS->mvlfacs_fst_rvs_alias = calloc_2(GLOBALS->numfacs,sizeof(fstHandle)); if(!GLOBALS->fast_tree_sort) { GLOBALS->do_hier_compress = 0; } init_facility_pack(); fprintf(stderr, FST_RDLOAD"Processing %d facs.\n", GLOBALS->numfacs); /* SPLASH */ splash_sync(1, 5); GLOBALS->first_cycle_fst_c_3 = (TimeType) fstReaderGetStartTime(GLOBALS->fst_fst_c_1) * GLOBALS->time_scale; GLOBALS->last_cycle_fst_c_3 = (TimeType) fstReaderGetEndTime(GLOBALS->fst_fst_c_1) * GLOBALS->time_scale; GLOBALS->total_cycles_fst_c_3 = GLOBALS->last_cycle_fst_c_3 - GLOBALS->first_cycle_fst_c_3 + 1; GLOBALS->global_time_offset = fstReaderGetTimezero(GLOBALS->fst_fst_c_1) * GLOBALS->time_scale; /* blackout region processing */ num_activity_changes = fstReaderGetNumberDumpActivityChanges(GLOBALS->fst_fst_c_1); for(activity_idx = 0; activity_idx < num_activity_changes; activity_idx++) { uint32_t activity_idx2; uint64_t ct = fstReaderGetDumpActivityChangeTime(GLOBALS->fst_fst_c_1, activity_idx); unsigned char ac = fstReaderGetDumpActivityChangeValue(GLOBALS->fst_fst_c_1, activity_idx); if(ac == 1) continue; if((activity_idx+1) == num_activity_changes) { struct blackout_region_t *bt = calloc_2(1, sizeof(struct blackout_region_t)); bt->bstart = (TimeType)(ct * GLOBALS->time_scale); bt->bend = (TimeType)(GLOBALS->last_cycle_fst_c_3 * GLOBALS->time_scale); bt->next = GLOBALS->blackout_regions; GLOBALS->blackout_regions = bt; /* activity_idx = activity_idx2; */ /* scan-build says is dead + assigned garbage value , which is true : code does not need to mirror for() loop below */ break; } for(activity_idx2 = activity_idx+1; activity_idx2 < num_activity_changes; activity_idx2++) { uint64_t ct2 = fstReaderGetDumpActivityChangeTime(GLOBALS->fst_fst_c_1, activity_idx2); ac = fstReaderGetDumpActivityChangeValue(GLOBALS->fst_fst_c_1, activity_idx2); if((ac == 0) && (activity_idx2 == (num_activity_changes-1))) { ac = 1; ct2 = GLOBALS->last_cycle_fst_c_3; } if(ac == 1) { struct blackout_region_t *bt = calloc_2(1, sizeof(struct blackout_region_t)); bt->bstart = (TimeType)(ct * GLOBALS->time_scale); bt->bend = (TimeType)(ct2 * GLOBALS->time_scale); bt->next = GLOBALS->blackout_regions; GLOBALS->blackout_regions = bt; activity_idx = activity_idx2; break; } } } /* do your stuff here..all useful info has been initialized by now */ if(!GLOBALS->hier_was_explicitly_set) /* set default hierarchy split char */ { GLOBALS->hier_delimeter='.'; } for(i=0;inumfacs;i++) { char buf[65537]; char *str; struct fac *f; int hier_len, name_len, tlen; unsigned char nvt, nvd, ndt; int longest_nam_candidate = 0; char *fnam; h = extractNextVar(GLOBALS->fst_fst_c_1, &msb, &lsb, &nnam, &name_len, &nnam_max); if(!h) { /* this should never happen */ fstReaderIterateHierRewind(GLOBALS->fst_fst_c_1); h = extractNextVar(GLOBALS->fst_fst_c_1, &msb, &lsb, &nnam, &name_len, &nnam_max); } npar = GLOBALS->mod_tree_parent; hier_len = GLOBALS->fst_scope_name ? GLOBALS->fst_scope_name_len : 0; if(hier_len) { tlen = hier_len + 1 + name_len; if(tlen > f_name_max_len[i&F_NAME_MODULUS]) { if(f_name[i&F_NAME_MODULUS]) free_2(f_name[i&F_NAME_MODULUS]); f_name_max_len[i&F_NAME_MODULUS] = tlen; fnam = malloc_2(tlen + 1); } else { fnam = f_name[i&F_NAME_MODULUS]; } memcpy(fnam, GLOBALS->fst_scope_name, hier_len); fnam[hier_len] = GLOBALS->hier_delimeter; memcpy(fnam + hier_len + 1, nnam, name_len + 1); } else { tlen = name_len; if(tlen > f_name_max_len[i&F_NAME_MODULUS]) { if(f_name[i&F_NAME_MODULUS]) free_2(f_name[i&F_NAME_MODULUS]); f_name_max_len[i&F_NAME_MODULUS] = tlen; fnam = malloc_2(tlen + 1); } else { fnam = f_name[i&F_NAME_MODULUS]; } memcpy(fnam, nnam, name_len + 1); } f_name[i&F_NAME_MODULUS] = fnam; f_name_len[i&F_NAME_MODULUS] = tlen; if((h->u.var.length > 1) && (msb == -1) && (lsb == -1)) { node_block[i].msi = h->u.var.length - 1; node_block[i].lsi = 0; } else { node_block[i].msi = msb; node_block[i].lsi = lsb; } GLOBALS->mvlfacs_fst_c_3[i].len = h->u.var.length; if(h->u.var.length) { switch(h->u.var.direction) { case FST_VD_INPUT: nvd = ND_DIR_IN; GLOBALS->nonimplicit_direction_encountered = 1; break; case FST_VD_OUTPUT: nvd = ND_DIR_OUT; GLOBALS->nonimplicit_direction_encountered = 1; break; case FST_VD_INOUT: nvd = ND_DIR_INOUT; GLOBALS->nonimplicit_direction_encountered = 1; break; case FST_VD_BUFFER: nvd = ND_DIR_BUFFER; GLOBALS->nonimplicit_direction_encountered = 1; break; case FST_VD_LINKAGE: nvd = ND_DIR_LINKAGE; GLOBALS->nonimplicit_direction_encountered = 1; break; case FST_VD_IMPLICIT: default: nvd = ND_DIR_IMPLICIT; break; } switch(h->u.var.typ) { case FST_VT_VCD_EVENT: nvt = ND_VCD_EVENT; break; case FST_VT_VCD_INTEGER: nvt = ND_VCD_INTEGER; break; case FST_VT_VCD_PARAMETER: nvt = ND_VCD_PARAMETER; break; case FST_VT_VCD_REAL: nvt = ND_VCD_REAL; break; case FST_VT_VCD_REAL_PARAMETER: nvt = ND_VCD_REAL_PARAMETER; break; case FST_VT_VCD_REALTIME: nvt = ND_VCD_REALTIME; break; case FST_VT_VCD_REG: nvt = ND_VCD_REG; break; case FST_VT_VCD_SUPPLY0: nvt = ND_VCD_SUPPLY0; break; case FST_VT_VCD_SUPPLY1: nvt = ND_VCD_SUPPLY1; break; case FST_VT_VCD_TIME: nvt = ND_VCD_TIME; break; case FST_VT_VCD_TRI: nvt = ND_VCD_TRI; break; case FST_VT_VCD_TRIAND: nvt = ND_VCD_TRIAND; break; case FST_VT_VCD_TRIOR: nvt = ND_VCD_TRIOR; break; case FST_VT_VCD_TRIREG: nvt = ND_VCD_TRIREG; break; case FST_VT_VCD_TRI0: nvt = ND_VCD_TRI0; break; case FST_VT_VCD_TRI1: nvt = ND_VCD_TRI1; break; case FST_VT_VCD_WAND: nvt = ND_VCD_WAND; break; case FST_VT_VCD_WIRE: nvt = ND_VCD_WIRE; break; case FST_VT_VCD_WOR: nvt = ND_VCD_WOR; break; case FST_VT_VCD_PORT: nvt = ND_VCD_PORT; break; case FST_VT_GEN_STRING: nvt = ND_GEN_STRING; break; case FST_VT_SV_BIT: nvt = ND_SV_BIT; break; case FST_VT_SV_LOGIC: nvt = ND_SV_LOGIC; break; case FST_VT_SV_INT: nvt = ND_SV_INT; break; case FST_VT_SV_SHORTINT: nvt = ND_SV_SHORTINT; break; case FST_VT_SV_LONGINT: nvt = ND_SV_LONGINT; break; case FST_VT_SV_BYTE: nvt = ND_SV_BYTE; break; case FST_VT_SV_ENUM: nvt = ND_SV_ENUM; break; case FST_VT_SV_SHORTREAL: nvt = ND_SV_SHORTREAL; break; default: nvt = ND_UNSPECIFIED_DEFAULT; break; } switch(h->u.var.typ) { case FST_VT_VCD_PARAMETER: case FST_VT_VCD_INTEGER: case FST_VT_SV_INT: case FST_VT_SV_SHORTINT: case FST_VT_SV_LONGINT: GLOBALS->mvlfacs_fst_c_3[i].flags = VZT_RD_SYM_F_INTEGER; break; case FST_VT_VCD_REAL: case FST_VT_VCD_REAL_PARAMETER: case FST_VT_VCD_REALTIME: case FST_VT_SV_SHORTREAL: GLOBALS->mvlfacs_fst_c_3[i].flags = VZT_RD_SYM_F_DOUBLE; break; case FST_VT_GEN_STRING: GLOBALS->mvlfacs_fst_c_3[i].flags = VZT_RD_SYM_F_STRING; GLOBALS->mvlfacs_fst_c_3[i].len = 2; break; default: GLOBALS->mvlfacs_fst_c_3[i].flags = VZT_RD_SYM_F_BITS; break; } } else /* convert any variable length records into strings */ { nvt = ND_GEN_STRING; nvd = ND_DIR_IMPLICIT; GLOBALS->mvlfacs_fst_c_3[i].flags = VZT_RD_SYM_F_STRING; GLOBALS->mvlfacs_fst_c_3[i].len = 2; } if(GLOBALS->fst_synclock_str) { if(GLOBALS->mvlfacs_fst_c_3[i].len == 1) /* currently only for single bit signals */ { Jval syn_jv; GLOBALS->mvlfacs_fst_c_3[i].flags |= VZT_RD_SYM_F_SYNVEC; /* special meaning for this in FST loader--means synthetic signal! */ syn_jv.s = GLOBALS->fst_synclock_str; jrb_insert_int(GLOBALS->synclock_jrb, i, syn_jv); } else { free_2(GLOBALS->fst_synclock_str); } GLOBALS->fst_synclock_str = NULL; /* under malloc_2() control for true if() branch, so not lost */ } if(h->u.var.is_alias) { GLOBALS->mvlfacs_fst_c_3[i].node_alias = h->u.var.handle - 1; /* subtract 1 to scale it with gtkwave-style numbering */ GLOBALS->mvlfacs_fst_c_3[i].flags |= VZT_RD_SYM_F_ALIAS; numalias++; } else { GLOBALS->mvlfacs_fst_rvs_alias[numvars] = i; GLOBALS->mvlfacs_fst_c_3[i].node_alias = numvars; numvars++; } f=GLOBALS->mvlfacs_fst_c_3+i; if((f->len>1)&& (!(f->flags&(VZT_RD_SYM_F_INTEGER|VZT_RD_SYM_F_DOUBLE|VZT_RD_SYM_F_STRING))) ) { int len=sprintf_2_sdd(buf, f_name[(i)&F_NAME_MODULUS],node_block[i].msi, node_block[i].lsi); longest_nam_candidate = len; if(!GLOBALS->do_hier_compress) { str=malloc_2(len+1); } else { if(len > f_name_build_buf_len) { free_2(f_name_build_buf); f_name_build_buf = malloc_2((f_name_build_buf_len=len)+1); } str = f_name_build_buf; } if(!GLOBALS->alt_hier_delimeter) { memcpy(str, buf, len+1); } else { strcpy_vcdalt(str, buf, GLOBALS->alt_hier_delimeter); } s=&sym_block[i]; symadd_name_exists_sym_exists(s,str,0); prevsymroot = prevsym = NULL; if(GLOBALS->fast_tree_sort) { len = sprintf_2_sdd(buf, nnam,node_block[i].msi, node_block[i].lsi); fst_append_graft_chain(len, buf, i, npar); } } else { int gatecmp = (f->len==1) && (!(f->flags&(VZT_RD_SYM_F_INTEGER|VZT_RD_SYM_F_DOUBLE|VZT_RD_SYM_F_STRING))) && (node_block[i].msi!=-1) && (node_block[i].lsi!=-1); int revcmp = gatecmp && (i) && (f_name_len[(i)&F_NAME_MODULUS] == f_name_len[(i-1)&F_NAME_MODULUS]) && (!memrevcmp(f_name_len[(i)&F_NAME_MODULUS], f_name[(i)&F_NAME_MODULUS], f_name[(i-1)&F_NAME_MODULUS])); if(gatecmp) { int len = sprintf_2_sd(buf, f_name[(i)&F_NAME_MODULUS],node_block[i].msi); longest_nam_candidate = len; if(!GLOBALS->do_hier_compress) { str=malloc_2(len+1); } else { if(len > f_name_build_buf_len) { free_2(f_name_build_buf); f_name_build_buf = malloc_2((f_name_build_buf_len=len)+1); } str = f_name_build_buf; } if(!GLOBALS->alt_hier_delimeter) { memcpy(str, buf, len+1); } else { strcpy_vcdalt(str, buf, GLOBALS->alt_hier_delimeter); } s=&sym_block[i]; symadd_name_exists_sym_exists(s,str,0); if((allowed_to_autocoalesce)&&(prevsym)&&(revcmp)&&(!strchr(f_name[(i)&F_NAME_MODULUS], '\\'))) /* allow chaining for search functions.. */ { prevsym->vec_root = prevsymroot; prevsym->vec_chain = s; s->vec_root = prevsymroot; prevsym = s; } else { prevsymroot = prevsym = s; } if(GLOBALS->fast_tree_sort) { len = sprintf_2_sd(buf, nnam,node_block[i].msi); fst_append_graft_chain(len, buf, i, npar); } } else { int len = f_name_len[(i)&F_NAME_MODULUS]; longest_nam_candidate = len; if(!GLOBALS->do_hier_compress) { str=malloc_2(len+1); } else { if(len > f_name_build_buf_len) { free_2(f_name_build_buf); f_name_build_buf = malloc_2((f_name_build_buf_len=len)+1); } str = f_name_build_buf; } if(!GLOBALS->alt_hier_delimeter) { memcpy(str, f_name[(i)&F_NAME_MODULUS], len+1); } else { strcpy_vcdalt(str, f_name[(i)&F_NAME_MODULUS], GLOBALS->alt_hier_delimeter); } s=&sym_block[i]; symadd_name_exists_sym_exists(s,str,0); prevsymroot = prevsym = NULL; if(f->flags&VZT_RD_SYM_F_INTEGER) { if(f->len != 0) { node_block[i].msi = f->len - 1; node_block[i].lsi = 0; GLOBALS->mvlfacs_fst_c_3[i].len = f->len; } else { node_block[i].msi = 31; node_block[i].lsi = 0; GLOBALS->mvlfacs_fst_c_3[i].len = 32; } } if(GLOBALS->fast_tree_sort) { fst_append_graft_chain(strlen(nnam), nnam, i, npar); } } } if(longest_nam_candidate > GLOBALS->longestname) GLOBALS->longestname = longest_nam_candidate; GLOBALS->facs[i]=&sym_block[i]; n=&node_block[i]; if(GLOBALS->do_hier_compress) { n->nname = compress_facility((unsigned char *)s->name, longest_nam_candidate); /* free_2(s->name); ...removed as f_name_build_buf is now used */ s->name = n->nname; } else { n->nname=s->name; } n->mv.mvlfac = GLOBALS->mvlfacs_fst_c_3+i; GLOBALS->mvlfacs_fst_c_3[i].working_node = n; n->vardir = nvd; n->varxt = h->u.var.sxt_workspace; if((h->u.var.svt_workspace == FST_SVT_NONE) && (h->u.var.sdt_workspace == FST_SDT_NONE)) { n->vartype = nvt; } else { switch(h->u.var.svt_workspace) { case FST_SVT_VHDL_SIGNAL: nvt = ND_VHDL_SIGNAL; break; case FST_SVT_VHDL_VARIABLE: nvt = ND_VHDL_VARIABLE; break; case FST_SVT_VHDL_CONSTANT: nvt = ND_VHDL_CONSTANT; break; case FST_SVT_VHDL_FILE: nvt = ND_VHDL_FILE; break; case FST_SVT_VHDL_MEMORY: nvt = ND_VHDL_MEMORY; break; default: break; /* keep what exists */ } n->vartype = nvt; switch(h->u.var.sdt_workspace) { case FST_SDT_VHDL_BOOLEAN: ndt = ND_VDT_VHDL_BOOLEAN; break; case FST_SDT_VHDL_BIT: ndt = ND_VDT_VHDL_BIT; break; case FST_SDT_VHDL_BIT_VECTOR: ndt = ND_VDT_VHDL_BIT_VECTOR; break; case FST_SDT_VHDL_STD_ULOGIC: ndt = ND_VDT_VHDL_STD_ULOGIC; break; case FST_SDT_VHDL_STD_ULOGIC_VECTOR: ndt = ND_VDT_VHDL_STD_ULOGIC_VECTOR; break; case FST_SDT_VHDL_STD_LOGIC: ndt = ND_VDT_VHDL_STD_LOGIC; break; case FST_SDT_VHDL_STD_LOGIC_VECTOR: ndt = ND_VDT_VHDL_STD_LOGIC_VECTOR; break; case FST_SDT_VHDL_UNSIGNED: ndt = ND_VDT_VHDL_UNSIGNED; break; case FST_SDT_VHDL_SIGNED: ndt = ND_VDT_VHDL_SIGNED; break; case FST_SDT_VHDL_INTEGER: ndt = ND_VDT_VHDL_INTEGER; break; case FST_SDT_VHDL_REAL: ndt = ND_VDT_VHDL_REAL; break; case FST_SDT_VHDL_NATURAL: ndt = ND_VDT_VHDL_NATURAL; break; case FST_SDT_VHDL_POSITIVE: ndt = ND_VDT_VHDL_POSITIVE; break; case FST_SDT_VHDL_TIME: ndt = ND_VDT_VHDL_TIME; break; case FST_SDT_VHDL_CHARACTER: ndt = ND_VDT_VHDL_CHARACTER; break; case FST_SDT_VHDL_STRING: ndt = ND_VDT_VHDL_STRING; break; default: ndt = ND_VDT_NONE; break; } n->vardt = ndt; } if((f->len>1)||(f->flags&(VZT_RD_SYM_F_DOUBLE|VZT_RD_SYM_F_STRING))) { n->extvals = 1; } n->head.time=-1; /* mark 1st node as negative time */ n->head.v.h_val=AN_X; s->n=n; } /* for(i) of facs parsing */ if(nnam) { free_2(nnam); nnam = NULL; } if(f_name_build_buf) { free_2(f_name_build_buf); f_name_build_buf = NULL; } for(i=0;i<=F_NAME_MODULUS;i++) { if(f_name[i]) { free_2(f_name[i]); f_name[i] = NULL; } } free_2(f_name); f_name = NULL; free_2(f_name_len); f_name_len = NULL; if(numvars != GLOBALS->numfacs) { GLOBALS->mvlfacs_fst_rvs_alias = realloc_2(GLOBALS->mvlfacs_fst_rvs_alias, numvars * sizeof(fstHandle)); } if(GLOBALS->subvar_jrb_count) /* generate lookup table for typenames explicitly given as attributes */ { JRB subvar_jrb_node = NULL; GLOBALS->subvar_pnt = calloc_2(GLOBALS->subvar_jrb_count + 1, sizeof(char *)); jrb_traverse(subvar_jrb_node, GLOBALS->subvar_jrb) { GLOBALS->subvar_pnt[subvar_jrb_node->val.ui] = subvar_jrb_node->key.s; } } if(GLOBALS->istem_struct_base) { if(GLOBALS->istem_struct_base_siz != GLOBALS->istem_struct_base_siz_alloc) { GLOBALS->istem_struct_base_siz_alloc = GLOBALS->istem_struct_base_siz; GLOBALS->istem_struct_base = realloc_2(GLOBALS->istem_struct_base, GLOBALS->istem_struct_base_siz_alloc * sizeof(struct stem_struct_t)); } } if(GLOBALS->stem_struct_base) { if(GLOBALS->stem_struct_base_siz != GLOBALS->stem_struct_base_siz_alloc) { GLOBALS->stem_struct_base_siz_alloc = GLOBALS->stem_struct_base_siz; GLOBALS->stem_struct_base = realloc_2(GLOBALS->stem_struct_base, GLOBALS->stem_struct_base_siz_alloc * sizeof(struct stem_struct_t)); } } if(GLOBALS->stem_path_string_table) { if(GLOBALS->stem_path_string_table_siz != GLOBALS->stem_path_string_table_alloc) { GLOBALS->stem_path_string_table_alloc = GLOBALS->stem_path_string_table_siz; GLOBALS->stem_path_string_table = realloc_2(GLOBALS->stem_path_string_table, GLOBALS->stem_path_string_table_alloc * sizeof(char *)); } } decorated_module_cleanup(); /* ...also now in gtk2_treesearch.c */ freeze_facility_pack(); iter_through_comp_name_table(); fprintf(stderr, FST_RDLOAD"Built %d signal%s and %d alias%s.\n", numvars, (numvars == 1) ? "" : "s", numalias, (numalias == 1) ? "" : "es"); GLOBALS->fst_maxhandle = numvars; if(GLOBALS->fast_tree_sort) { /* SPLASH */ splash_sync(2, 5); fprintf(stderr, FST_RDLOAD"Building facility hierarchy tree.\n"); init_tree(); treegraft(&GLOBALS->treeroot); /* SPLASH */ splash_sync(3, 5); fprintf(stderr, FST_RDLOAD"Sorting facility hierarchy tree.\n"); treesort(GLOBALS->treeroot, NULL); /* SPLASH */ splash_sync(4, 5); order_facs_from_treesort(GLOBALS->treeroot, &GLOBALS->facs); /* SPLASH */ splash_sync(5, 5); GLOBALS->facs_are_sorted=1; } else { /* SPLASH */ splash_sync(2, 5); for(i=0;inumfacs;i++) { char *subst, ch; int esc = 0; subst=GLOBALS->facs[i]->name; while((ch=(*subst))) { #ifdef WAVE_HIERFIX if(ch==GLOBALS->hier_delimeter) { *subst=(!esc) ? VCDNAM_HIERSORT : VCDNAM_ESCAPE; } /* forces sort at hier boundaries */ #else if((ch==GLOBALS->hier_delimeter)&&(esc)) { *subst = VCDNAM_ESCAPE; } /* forces sort at hier boundaries */ #endif else if(ch=='\\') { esc = 1; GLOBALS->escaped_names_found_vcd_c_1 = 1; } subst++; } } /* SPLASH */ splash_sync(3, 5); fprintf(stderr, FST_RDLOAD"Sorting facilities at hierarchy boundaries.\n"); wave_heapsort(GLOBALS->facs,GLOBALS->numfacs); #ifdef WAVE_HIERFIX for(i=0;inumfacs;i++) { char *subst, ch; subst=GLOBALS->facs[i]->name; while((ch=(*subst))) { if(ch==VCDNAM_HIERSORT) { *subst=GLOBALS->hier_delimeter; } /* restore back to normal */ subst++; } } #endif GLOBALS->facs_are_sorted=1; /* SPLASH */ splash_sync(4, 5); fprintf(stderr, FST_RDLOAD"Building facility hierarchy tree.\n"); init_tree(); for(i=0;inumfacs;i++) { char *nf = GLOBALS->facs[i]->name; build_tree_from_name(nf, i); } /* SPLASH */ splash_sync(5, 5); if(GLOBALS->escaped_names_found_vcd_c_1) { for(i=0;inumfacs;i++) { char *subst, ch; subst=GLOBALS->facs[i]->name; while((ch=(*subst))) { if(ch==VCDNAM_ESCAPE) { *subst=GLOBALS->hier_delimeter; } /* restore back to normal */ subst++; } } } treegraft(&GLOBALS->treeroot); treesort(GLOBALS->treeroot, NULL); if(GLOBALS->escaped_names_found_vcd_c_1) { treenamefix(GLOBALS->treeroot); } } #if 0 { int num_dups = 0; for(i=0;inumfacs-1;i++) { if(!strcmp(GLOBALS->facs[i]->name, GLOBALS->facs[i+1]->name)) { fprintf(stderr, FST_RDLOAD"DUPLICATE FAC: '%s'\n", GLOBALS->facs[i]->name); num_dups++; } } if(num_dups) { fprintf(stderr, FST_RDLOAD"Exiting, %d duplicate signals are present.\n", num_dups); exit(255); } } #endif GLOBALS->min_time = GLOBALS->first_cycle_fst_c_3; GLOBALS->max_time=GLOBALS->last_cycle_fst_c_3; GLOBALS->is_lx2 = LXT2_IS_FST; if(skip_start || skip_end) { TimeType b_start, b_end; if(!skip_start) b_start = GLOBALS->min_time; else b_start = unformat_time(skip_start, GLOBALS->time_dimension); if(!skip_end) b_end = GLOBALS->max_time; else b_end = unformat_time(skip_end, GLOBALS->time_dimension); if(b_startmin_time) b_start = GLOBALS->min_time; else if(b_start>GLOBALS->max_time) b_start = GLOBALS->max_time; if(b_endmin_time) b_end = GLOBALS->min_time; else if(b_end>GLOBALS->max_time) b_end = GLOBALS->max_time; if(b_start > b_end) { TimeType tmp_time = b_start; b_start = b_end; b_end = tmp_time; } fstReaderSetLimitTimeRange(GLOBALS->fst_fst_c_1, b_start, b_end); GLOBALS->min_time = b_start; GLOBALS->max_time = b_end; } fstReaderIterBlocksSetNativeDoublesOnCallback(GLOBALS->fst_fst_c_1, 1); /* to avoid bin -> ascii -> bin double swap */ /* SPLASH */ splash_finalize(); return(GLOBALS->max_time); } /* * conversion from evcd -> vcd format */ static void evcd_memcpy(char *dst, const char *src, int len) { static const char *evcd="DUNZduLHXTlh01?FAaBbCcf"; static const char *vcd="01xz0101xz0101xzxxxxxxz"; char ch; int i, j; for(j=0;jmvlfacs_fst_rvs_alias[--txidx]; struct HistEnt *htemp; struct lx2_entry *l2e = GLOBALS->fst_table_fst_c_1+facidx; struct fac *f = GLOBALS->mvlfacs_fst_c_3+facidx; GLOBALS->busycnt_fst_c_2++; if(GLOBALS->busycnt_fst_c_2==WAVE_BUSY_ITER) { busy_window_refresh(); GLOBALS->busycnt_fst_c_2 = 0; } /* fprintf(stderr, "%lld %d '%s'\n", tim, facidx, value); */ if(!(f->flags&(VZT_RD_SYM_F_DOUBLE|VZT_RD_SYM_F_STRING))) { unsigned char vt = ND_UNSPECIFIED_DEFAULT; if(f->working_node) { vt = f->working_node->vartype; } if(f->len>1) { char *h_vector = (char *)malloc_2(f->len); if(vt != ND_VCD_PORT) { memcpy(h_vector, value, f->len); } else { evcd_memcpy(h_vector, (const char *)value, f->len); } if((l2e->histent_curr)&&(l2e->histent_curr->v.h_vector)) /* remove duplicate values */ { if((!memcmp(l2e->histent_curr->v.h_vector, h_vector, f->len))&&(!GLOBALS->vcd_preserve_glitches)) { free_2(h_vector); return; } } htemp = histent_calloc(); htemp->v.h_vector = h_vector; } else { unsigned char h_val; if(vt != ND_VCD_PORT) { switch(*value) { case '0': h_val = AN_0; break; case '1': h_val = AN_1; break; case 'X': case 'x': h_val = AN_X; break; case 'Z': case 'z': h_val = AN_Z; break; case 'H': case 'h': h_val = AN_H; break; case 'U': case 'u': h_val = AN_U; break; case 'W': case 'w': h_val = AN_W; break; case 'L': case 'l': h_val = AN_L; break; case '-': h_val = AN_DASH; break; default: h_val = AN_X; break; } } else { char membuf[1]; evcd_memcpy(membuf, (const char *)value, 1); switch(*membuf) { case '0': h_val = AN_0; break; case '1': h_val = AN_1; break; case 'Z': case 'z': h_val = AN_Z; break; default: h_val = AN_X; break; } } if((vt != ND_VCD_EVENT) && (l2e->histent_curr)) /* remove duplicate values */ { if((l2e->histent_curr->v.h_val == h_val) && (!GLOBALS->vcd_preserve_glitches)) { return; } } htemp = histent_calloc(); htemp->v.h_val = h_val; } } else if(f->flags&VZT_RD_SYM_F_DOUBLE) { if((l2e->histent_curr)&&(l2e->histent_curr->v.h_vector)) /* remove duplicate values */ { #ifdef WAVE_HAS_H_DOUBLE if(!memcmp(&l2e->histent_curr->v.h_double, value, sizeof(double))) #else if(!memcmp(l2e->histent_curr->v.h_vector, value, sizeof(double))) #endif { if((!GLOBALS->vcd_preserve_glitches)&&(!GLOBALS->vcd_preserve_glitches_real)) { return; } } } /* if(fstReaderIterBlocksSetNativeDoublesOnCallback is disabled...) double *d = double_slab_calloc(); sscanf(value, "%lg", d); htemp = histent_calloc(); htemp->v.h_vector = (char *)d; otherwise... */ htemp = histent_calloc(); #ifdef WAVE_HAS_H_DOUBLE memcpy(&htemp->v.h_double, value, sizeof(double)); #else htemp->v.h_vector = double_slab_calloc(); memcpy(htemp->v.h_vector, value, sizeof(double)); #endif htemp->flags = HIST_REAL; } else /* string */ { unsigned char *s = malloc_2(plen + 1); uint32_t pidx; for(pidx=0;pidx '~')) { ch = '.'; } #endif s[pidx] = ch; } s[pidx] = 0; if((l2e->histent_curr)&&(l2e->histent_curr->v.h_vector)) /* remove duplicate values */ { if((!strcmp(l2e->histent_curr->v.h_vector, (const char *)value)) && (!GLOBALS->vcd_preserve_glitches)) { free(s); return; } } htemp = histent_calloc(); htemp->v.h_vector = (char *)s; htemp->flags = HIST_REAL|HIST_STRING; } htemp->time = (tim) * (GLOBALS->time_scale); if(l2e->histent_curr) /* scan-build : was l2e->histent_head */ { l2e->histent_curr->next = htemp; /* scan-build : this is ok given how it's used */ l2e->histent_curr = htemp; } else { l2e->histent_head = l2e->histent_curr = htemp; } l2e->numtrans++; } static void fst_callback(void *user_callback_data_pointer, uint64_t tim, fstHandle txidx, const unsigned char *value) { fst_callback2(user_callback_data_pointer, tim, txidx, value, 0); } /* * this is the black magic that handles aliased signals... */ static void fst_resolver(nptr np, nptr resolve) { np->extvals = resolve->extvals; np->msi = resolve->msi; np->lsi = resolve->lsi; memcpy(&np->head, &resolve->head, sizeof(struct HistEnt)); np->curr = resolve->curr; np->harray = resolve->harray; np->numhist = resolve->numhist; np->mv.mvlfac=NULL; } /* * actually import a fst trace but don't do it if it's already been imported */ void import_fst_trace(nptr np) { hptr htemp, htempx=NULL, histent_tail; int len, i; struct fac *f; int txidx; nptr nold = np; if(!(f=np->mv.mvlfac)) return; /* already imported */ txidx = f - GLOBALS->mvlfacs_fst_c_3; if(np->mv.mvlfac->flags&VZT_RD_SYM_F_ALIAS) { txidx = GLOBALS->mvlfacs_fst_c_3[txidx].node_alias; /* this is to map to fstHandles, so even non-aliased are remapped */ txidx = GLOBALS->mvlfacs_fst_rvs_alias[txidx]; np = GLOBALS->mvlfacs_fst_c_3[txidx].working_node; if(!(f=np->mv.mvlfac)) { fst_resolver(nold, np); return; /* already imported */ } } if(!(f->flags&VZT_RD_SYM_F_SYNVEC)) /* block debug message for synclk */ { int flagged = HIER_DEPACK_STATIC; char *str = hier_decompress_flagged(np->nname, &flagged); fprintf(stderr, "Import: %s\n", str); /* normally this never happens */ } /* new stuff */ len = np->mv.mvlfac->len; /* check here for array height in future */ if(!(f->flags&VZT_RD_SYM_F_SYNVEC)) { fstReaderSetFacProcessMask(GLOBALS->fst_fst_c_1, GLOBALS->mvlfacs_fst_c_3[txidx].node_alias+1); fstReaderIterBlocks2(GLOBALS->fst_fst_c_1, fst_callback, fst_callback2, NULL, NULL); fstReaderClrFacProcessMask(GLOBALS->fst_fst_c_1, GLOBALS->mvlfacs_fst_c_3[txidx].node_alias+1); } histent_tail = htemp = histent_calloc(); if(len>1) { htemp->v.h_vector = (char *)malloc_2(len); for(i=0;iv.h_vector[i] = AN_Z; } else { htemp->v.h_val = AN_Z; /* z */ } htemp->time = MAX_HISTENT_TIME; htemp = histent_calloc(); if(len>1) { if(!(f->flags&VZT_RD_SYM_F_DOUBLE)) { if(!(f->flags&VZT_RD_SYM_F_STRING)) { htemp->v.h_vector = (char *)malloc_2(len); for(i=0;iv.h_vector[i] = AN_X; } else { htemp->v.h_vector = strdup_2("UNDEF"); htemp->flags = HIST_REAL|HIST_STRING; } } else { #ifdef WAVE_HAS_H_DOUBLE htemp->v.h_double = strtod("NaN", NULL); #else double *d = malloc_2(sizeof(double)); *d = strtod("NaN", NULL); htemp->v.h_vector = (char *)d; #endif htemp->flags = HIST_REAL; } htempx = htemp; } else { htemp->v.h_val = AN_X; /* x */ } htemp->time = MAX_HISTENT_TIME-1; htemp->next = histent_tail; if(GLOBALS->fst_table_fst_c_1[txidx].histent_curr) { GLOBALS->fst_table_fst_c_1[txidx].histent_curr->next = htemp; htemp = GLOBALS->fst_table_fst_c_1[txidx].histent_head; } if(!(f->flags&(VZT_RD_SYM_F_DOUBLE|VZT_RD_SYM_F_STRING))) { if(len>1) { np->head.v.h_vector = (char *)malloc_2(len); for(i=0;ihead.v.h_vector[i] = AN_X; } else { np->head.v.h_val = AN_X; /* x */ } } else { np->head.flags = HIST_REAL; if(f->flags&VZT_RD_SYM_F_STRING) { np->head.flags |= HIST_STRING; } } { struct HistEnt *htemp2 = histent_calloc(); htemp2->time = -1; if(len>1) { htemp2->v.h_vector = htempx->v.h_vector; htemp2->flags = htempx->flags; } else { htemp2->v.h_val = htemp->v.h_val; } htemp2->next = htemp; htemp = htemp2; GLOBALS->fst_table_fst_c_1[txidx].numtrans++; } np->head.time = -2; np->head.next = htemp; np->numhist=GLOBALS->fst_table_fst_c_1[txidx].numtrans +2 /*endcap*/ +1 /*frontcap*/; memset(GLOBALS->fst_table_fst_c_1+txidx, 0, sizeof(struct lx2_entry)); /* zero it out */ np->curr = histent_tail; np->mv.mvlfac = NULL; /* it's imported and cached so we can forget it's an mvlfac now */ if(nold!=np) { fst_resolver(nold, np); } } /* * decompress [m b xs xe valstring]... format string into trace */ static void expand_synvec(int txidx, const char *s) { char *scopy = NULL; char *pnt, *pnt2; double m, b; uint64_t xs, xe, xi; char *vs; uint64_t tim; uint64_t tim_max; int vslen; int vspnt; unsigned char value[2] = {0, 0}; unsigned char pval = 0; scopy = strdup_2(s); vs = calloc_2(1, strlen(s) + 1); /* will never be as big as original string */ pnt = scopy; while(*pnt) { if(*pnt != '[') { pnt++; continue; } pnt++; pnt2 = strchr(pnt, ']'); if(!pnt2) break; *pnt2 = 0; /* printf("PNT: %s\n", pnt); */ int rc = sscanf(pnt, "%lg %lg %"SCNu64" %"SCNu64" %s", &m, &b, &xs, &xe, vs); if(rc == 5) { vslen = strlen(vs); vspnt = 0; tim_max = 0; for(xi = xs; xi <= xe; xi++) { tim = (xi * m) + b; /* fprintf(stderr, "#%"PRIu64" '%c'\n", tim, vs[vspnt]); */ value[0] = vs[vspnt]; if(value[0] != pval) /* collapse new == old value transitions so new is ignored */ { if((tim >= tim_max) || (xi == xs)) { fst_callback2(NULL, tim, txidx, value, 0); tim_max = tim; } pval = value[0]; } vspnt++; vspnt = (vspnt == vslen) ? 0 : vspnt; /* modulus on repeating clock */ } } else { break; } pnt = pnt2 + 1; } free_2(vs); free_2(scopy); } /* * pre-import many traces at once so function above doesn't have to iterate... */ void fst_set_fac_process_mask(nptr np) { struct fac *f; int txidx; if(!(f=np->mv.mvlfac)) return; /* already imported */ txidx = f-GLOBALS->mvlfacs_fst_c_3; if(np->mv.mvlfac->flags&VZT_RD_SYM_F_ALIAS) { txidx = GLOBALS->mvlfacs_fst_c_3[txidx].node_alias; txidx = GLOBALS->mvlfacs_fst_rvs_alias[txidx]; np = GLOBALS->mvlfacs_fst_c_3[txidx].working_node; if(!(np->mv.mvlfac)) return; /* already imported */ } if(np->mv.mvlfac->flags&VZT_RD_SYM_F_SYNVEC) { JRB fi = jrb_find_int(GLOBALS->synclock_jrb, txidx); if(fi) { expand_synvec(GLOBALS->mvlfacs_fst_c_3[txidx].node_alias+1, fi->val.s); import_fst_trace(np); return; /* import_fst_trace() will construct the trailer */ } } /* check here for array height in future */ { fstReaderSetFacProcessMask(GLOBALS->fst_fst_c_1, GLOBALS->mvlfacs_fst_c_3[txidx].node_alias+1); GLOBALS->fst_table_fst_c_1[txidx].np = np; } } void fst_import_masked(void) { unsigned int txidxi; int i, cnt; hptr htempx = NULL; cnt = 0; for(txidxi=0;txidxifst_maxhandle;txidxi++) { if(fstReaderGetFacProcessMask(GLOBALS->fst_fst_c_1, txidxi+1)) { cnt++; } } if(!cnt) { return; } if(cnt>100) { fprintf(stderr, FST_RDLOAD"Extracting %d traces\n", cnt); } set_window_busy(NULL); fstReaderIterBlocks2(GLOBALS->fst_fst_c_1, fst_callback, fst_callback2, NULL, NULL); set_window_idle(NULL); for(txidxi=0;txidxifst_maxhandle;txidxi++) { if(fstReaderGetFacProcessMask(GLOBALS->fst_fst_c_1, txidxi+1)) { int txidx = GLOBALS->mvlfacs_fst_rvs_alias[txidxi]; struct HistEnt *htemp, *histent_tail; struct fac *f = GLOBALS->mvlfacs_fst_c_3+txidx; int len = f->len; nptr np = GLOBALS->fst_table_fst_c_1[txidx].np; histent_tail = htemp = histent_calloc(); if(len>1) { htemp->v.h_vector = (char *)malloc_2(len); for(i=0;iv.h_vector[i] = AN_Z; } else { htemp->v.h_val = AN_Z; /* z */ } htemp->time = MAX_HISTENT_TIME; htemp = histent_calloc(); if(len>1) { if(!(f->flags&VZT_RD_SYM_F_DOUBLE)) { if(!(f->flags&VZT_RD_SYM_F_STRING)) { htemp->v.h_vector = (char *)malloc_2(len); for(i=0;iv.h_vector[i] = AN_X; } else { htemp->v.h_vector = strdup_2("UNDEF"); htemp->flags = HIST_REAL|HIST_STRING; } htempx = htemp; } else { #ifdef WAVE_HAS_H_DOUBLE htemp->v.h_double = strtod("NaN", NULL); #else double *d = malloc_2(sizeof(double)); *d = strtod("NaN", NULL); htemp->v.h_vector = (char *)d; #endif htemp->flags = HIST_REAL; htempx = htemp; } } else { htemp->v.h_val = AN_X; /* x */ } htemp->time = MAX_HISTENT_TIME-1; htemp->next = histent_tail; if(GLOBALS->fst_table_fst_c_1[txidx].histent_curr) { GLOBALS->fst_table_fst_c_1[txidx].histent_curr->next = htemp; htemp = GLOBALS->fst_table_fst_c_1[txidx].histent_head; } if(!(f->flags&(VZT_RD_SYM_F_DOUBLE|VZT_RD_SYM_F_STRING))) { if(len>1) { np->head.v.h_vector = (char *)malloc_2(len); for(i=0;ihead.v.h_vector[i] = AN_X; } else { np->head.v.h_val = AN_X; /* x */ } } else { np->head.flags = HIST_REAL; if(f->flags&VZT_RD_SYM_F_STRING) { np->head.flags |= HIST_STRING; } } { struct HistEnt *htemp2 = histent_calloc(); htemp2->time = -1; if(len>1) { htemp2->v.h_vector = htempx->v.h_vector; htemp2->flags = htempx->flags; } else { htemp2->v.h_val = htemp->v.h_val; } htemp2->next = htemp; htemp = htemp2; GLOBALS->fst_table_fst_c_1[txidx].numtrans++; } np->head.time = -2; np->head.next = htemp; np->numhist=GLOBALS->fst_table_fst_c_1[txidx].numtrans +2 /*endcap*/ +1 /*frontcap*/; memset(GLOBALS->fst_table_fst_c_1+txidx, 0, sizeof(struct lx2_entry)); /* zero it out */ np->curr = histent_tail; np->mv.mvlfac = NULL; /* it's imported and cached so we can forget it's an mvlfac now */ fstReaderClrFacProcessMask(GLOBALS->fst_fst_c_1, txidxi+1); } } } gtkwave-3.3.66/src/fst.h0000664000076400007640000000122212341266475014342 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2009. * * 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. */ #include "globals.h" #ifndef WAVE_FSTRDR_H #define WAVE_FSTRDR_H #ifdef HAVE_INTTYPES_H #include #endif #include "vcd.h" #include "ae2.h" #include "tree_component.h" TimeType fst_main(char *fname, char *skip_start, char *skip_end); void import_fst_trace(nptr np); void fst_set_fac_process_mask(nptr np); void fst_import_masked(void); #endif gtkwave-3.3.66/src/interp.h0000664000076400007640000000072711523063250015043 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2010 * * 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. */ #ifndef WAVE_FT_INTERP_H #define WAVE_FT_INTERP_H int ft_interpolate (double *data, double *ndata, double *oscale, int olen, double *nscale, int nlen, int degree); #endif gtkwave-3.3.66/src/debug.c0000664000076400007640000003251012360623564014630 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2014. * * 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. */ /* * debug.c 01feb99ajb * malloc debugs added on 13jul99ajb * malloc tracking added on 05aug07ajb for 3.1 series */ #include #include #include #include #include "globals.h" #include "debug.h" #ifdef _WAVE_HAVE_JUDY #include #endif #ifdef HAVE_SYS_STAT_H #include #include "fstapi.h" #include "lxt2_read.h" #include "lxt.h" #include "vzt_read.h" #endif #undef free_2 #undef malloc_2 #undef realloc_2 #undef calloc_2 #ifdef _WAVE_HAVE_JUDY void free_outstanding(void) { Pvoid_t PJArray = (Pvoid_t)GLOBALS->alloc2_chain; int rcValue; Word_t Index; #ifdef DEBUG_PRINTF int ctr = 0; printf("\n*** cleanup ***\n"); printf("Freeing %d chunks\n", GLOBALS->outstanding); system("date"); #endif if(GLOBALS->s_selected) { destroy_s_selected(); } Index = 0; for (rcValue = Judy1First(PJArray, &Index, PJE0); rcValue != 0; rcValue = Judy1Next(PJArray, &Index, PJE0)) { free((void *)Index); #ifdef DEBUG_PRINTF ctr++; #endif } Judy1FreeArray(&PJArray, PJE0); GLOBALS->alloc2_chain = NULL; GLOBALS->outstanding = 0; #ifdef DEBUG_PRINTF printf("Freed %d chunks\n", ctr); system("date"); #endif } #else void free_outstanding(void) { void **t = (void **)GLOBALS->alloc2_chain; void **t2; int ctr = 0; #ifdef DEBUG_PRINTF printf("\n*** cleanup ***\n"); printf("Freeing %d chunks\n", GLOBALS->outstanding); system("date"); #endif while(t) { t2 = (void **) *(t+1); free(t); t = t2; ctr++; } GLOBALS->alloc2_chain = NULL; GLOBALS->outstanding = 0; #ifdef DEBUG_PRINTF printf("Freed %d chunks\n", ctr); system("date"); #endif } #endif /* * wrapped malloc family... */ #ifdef _WAVE_HAVE_JUDY void *malloc_2(size_t size #ifdef DEBUG_MALLOC_LINES , char *filename, int lineno #endif ) { void *ret; ret=malloc(size); if(ret) { Judy1Set ((Pvoid_t)&GLOBALS->alloc2_chain, (Word_t)ret, PJE0); GLOBALS->outstanding++; return(ret); } else { #ifdef DEBUG_MALLOC_LINES fprintf(stderr, "FATAL ERROR: malloc_2() Out of memory, sorry. ['%s', %d]\n", filename, lineno); #else fprintf(stderr, "FATAL ERROR: malloc_2() Out of memory, sorry.\n"); #endif exit(1); } } #else void *malloc_2(size_t size #ifdef DEBUG_MALLOC_LINES , char *filename, int lineno #endif ) { void *ret; ret=malloc(size + 2*sizeof(void *)); if(ret) { void **ret2 = (void **)ret; *(ret2+0) = NULL; *(ret2+1) = GLOBALS->alloc2_chain; if(GLOBALS->alloc2_chain) { *(GLOBALS->alloc2_chain+0) = ret2; } GLOBALS->alloc2_chain = ret2; GLOBALS->outstanding++; return((char *)ret + 2*sizeof(void *)); } else { #ifdef DEBUG_MALLOC_LINES fprintf(stderr, "FATAL ERROR: malloc_2() Out of memory, sorry. ['%s', %d]\n", filename, lineno); #else fprintf(stderr, "FATAL ERROR: malloc_2() Out of memory, sorry.\n"); #endif exit(1); } } #endif #ifdef _WAVE_HAVE_JUDY void *realloc_2(void *ptr, size_t size #ifdef DEBUG_MALLOC_LINES , char *filename, int lineno #endif ) { void *ret=realloc(ptr, size); if(ret) { if(ptr != ret) { Judy1Unset ((Pvoid_t)&GLOBALS->alloc2_chain, (Word_t)ptr, PJE0); Judy1Set ((Pvoid_t)&GLOBALS->alloc2_chain, (Word_t)ret, PJE0); } return(ret); } else { #ifdef DEBUG_MALLOC_LINES fprintf(stderr, "FATAL ERROR: realloc_2() Out of memory, sorry. ['%s', %d]\n", filename, lineno); #else fprintf(stderr, "FATAL ERROR: realloc_2() Out of memory, sorry.\n"); #endif exit(1); } } #else void *realloc_2(void *ptr, size_t size #ifdef DEBUG_MALLOC_LINES , char *filename, int lineno #endif ) { void *ret; void **ret2 = ((void **)ptr) - 2; void **prv = (void **)*(ret2+0); void **nxt = (void **)*(ret2+1); if(prv) { *(prv+1) = nxt; } else { GLOBALS->alloc2_chain = nxt; } if(nxt) { *(nxt+0) = prv; } ret=realloc((char *)ptr - 2*sizeof(void *), size + 2*sizeof(void *)); ret2 = (void **)ret; *(ret2+0) = NULL; *(ret2+1) = GLOBALS->alloc2_chain; if(GLOBALS->alloc2_chain) { *(GLOBALS->alloc2_chain+0) = ret2; } GLOBALS->alloc2_chain = ret2; if(ret) { return((char *)ret + 2*sizeof(void *)); } else { #ifdef DEBUG_MALLOC_LINES fprintf(stderr, "FATAL ERROR: realloc_2() Out of memory, sorry. ['%s', %d]\n", filename, lineno); #else fprintf(stderr, "FATAL ERROR: realloc_2() Out of memory, sorry.\n"); #endif exit(1); } } #endif #ifdef _WAVE_HAVE_JUDY void *calloc_2_into_context(struct Global *g, size_t nmemb, size_t size #ifdef DEBUG_MALLOC_LINES , char *filename, int lineno #endif ) { void *ret; ret=calloc(nmemb, size); if(ret) { Judy1Set ((Pvoid_t)&g->alloc2_chain, (Word_t)ret, PJE0); g->outstanding++; return(ret); } else { #ifdef DEBUG_MALLOC_LINES fprintf(stderr, "FATAL ERROR: calloc_2() Out of memory, sorry. ['%s', %d]\n", filename, lineno); #else fprintf(stderr, "FATAL ERROR: calloc_2() Out of memory, sorry.\n"); #endif exit(1); } } #else void *calloc_2_into_context(struct Global *g, size_t nmemb, size_t size #ifdef DEBUG_MALLOC_LINES , char *filename, int lineno #endif ) { void *ret; ret=calloc(1, (nmemb * size) + 2*sizeof(void *)); if(ret) { void **ret2 = (void **)ret; *(ret2+0) = NULL; *(ret2+1) = g->alloc2_chain; if(g->alloc2_chain) { *(g->alloc2_chain+0) = ret2; } g->alloc2_chain = ret2; g->outstanding++; return((char *)ret + 2*sizeof(void *)); } else { #ifdef DEBUG_MALLOC_LINES fprintf(stderr, "FATAL ERROR: calloc_2() Out of memory, sorry. ['%s', %d]\n", filename, lineno); #else fprintf(stderr, "FATAL ERROR: calloc_2() Out of memory, sorry.\n"); #endif exit(1); } } #endif void *calloc_2(size_t nmemb, size_t size #ifdef DEBUG_MALLOC_LINES , char *filename, int lineno #endif ) { return(calloc_2_into_context(GLOBALS, nmemb, size #ifdef DEBUG_MALLOC_LINES , filename, lineno #endif )); } #ifdef _WAVE_HAVE_JUDY void free_2(void *ptr #ifdef DEBUG_MALLOC_LINES , char *filename, int lineno #endif ) { if(ptr) { int delstat = Judy1Unset ((Pvoid_t)&GLOBALS->alloc2_chain, (Word_t)ptr, PJE0); if(delstat) { GLOBALS->outstanding--; free(ptr); } else { #ifdef DEBUG_MALLOC_LINES printf("JUDYMEM | free to non-malloc'd address %p blocked ['%s', %d]\n", ptr, filename, lineno); #else printf("JUDYMEM | free to non-malloc'd address %p blocked\n", ptr); #endif } } else { #ifdef DEBUG_MALLOC_LINES fprintf(stderr, "WARNING: Attempt to free NULL pointer caught. ['%s', %d]\n", filename, lineno); #else fprintf(stderr, "WARNING: Attempt to free NULL pointer caught.\n"); #endif } } #else void free_2(void *ptr #ifdef DEBUG_MALLOC_LINES , char *filename, int lineno #endif ) { if(ptr) { void **ret2 = ((void **)ptr) - 2; void **prv = (void **)*(ret2+0); void **nxt = (void **)*(ret2+1); if(prv) { *(prv+1) = nxt; } else { GLOBALS->alloc2_chain = nxt; } if(nxt) { *(nxt+0) = prv; } GLOBALS->outstanding--; free((char *)ptr - 2*sizeof(void *)); } else { #ifdef DEBUG_MALLOC_LINES fprintf(stderr, "WARNING: Attempt to free NULL pointer caught. ['%s', %d]\n", filename, lineno); #else fprintf(stderr, "WARNING: Attempt to free NULL pointer caught.\n"); #endif } } #endif #ifdef DEBUG_MALLOC_LINES #define malloc_2(x) malloc_2((x),__FILE__,__LINE__) #endif char *strdup_2(const char *s) { char *s2 = NULL; if(s) { int nbytes = strlen(s) + 1; s2 = malloc_2(nbytes); memcpy(s2, s, nbytes); } return(s2); } char *strdup_2s(const char *s) { char *s2 = NULL; if(s) { int len = strlen(s); s2 = malloc(len+2); memcpy(s2, s, len); s2[len++] = ' '; s2[len] = 0; } return(s2); } /* * atoi 64-bit version.. * y/on default to '1' * n/nonnum default to '0' */ TimeType atoi_64(const char *str) { TimeType val=0; unsigned char ch, nflag=0; int consumed = 0; GLOBALS->atoi_cont_ptr=NULL; switch(*str) { case 'y': case 'Y': return(LLDescriptor(1)); case 'o': case 'O': str++; ch=*str; if((ch=='n')||(ch=='N')) return(LLDescriptor(1)); else return(LLDescriptor(0)); case 'n': case 'N': return(LLDescriptor(0)); break; default: break; } while((ch=*(str++))) { if((ch>='0')&&(ch<='9')) { val=(val*10+(ch&15)); consumed = 1; } else if((ch=='-')&&(val==0)&&(!nflag)) { nflag=1; consumed = 1; } else if(consumed) { GLOBALS->atoi_cont_ptr=str-1; break; } } return(nflag?(-val):val); } /* * wrapped tooltips */ void gtk_tooltips_set_tip_2(GtkTooltips *tooltips, GtkWidget *widget, const gchar *tip_text, const gchar *tip_private) { if(!GLOBALS->disable_tooltips) { gtk_tooltips_set_tip(tooltips, widget, tip_text, tip_private); } } void gtk_tooltips_set_delay_2(GtkTooltips *tooltips, guint delay) { if(!GLOBALS->disable_tooltips) { gtk_tooltips_set_delay(tooltips, delay); } } GtkTooltips* gtk_tooltips_new_2(void) { if(!GLOBALS->disable_tooltips) { return(gtk_tooltips_new()); } else { return(NULL); } } char *tmpnam_2(char *s, int *fd) { (void)s; #if defined _MSC_VER || defined __MINGW32__ char *fname = NULL; TCHAR szTempFileName[MAX_PATH]; TCHAR lpTempPathBuffer[MAX_PATH]; DWORD dwRetVal = 0; UINT uRetVal = 0; *fd = -1; dwRetVal = GetTempPath(MAX_PATH, lpTempPathBuffer); if((dwRetVal > MAX_PATH) || (dwRetVal == 0)) { fprintf(stderr, "GetTempPath() failed\n"); } else { uRetVal = GetTempFileName(lpTempPathBuffer, TEXT("GTKW"), 0, szTempFileName); if (uRetVal == 0) { fprintf(stderr, "GetTempFileName() failed\n"); } else { fname = strdup_2(szTempFileName); } } return(fname); #else char *backpath = "gtkwaveXXXXXX"; char *tmpspace; int len = strlen(P_tmpdir); int i; unsigned char slash = '/'; for(i=0;iloaded_file_name, "."EXTLOAD_SUFFIX)) { return(rc); } #endif #ifdef AET2_IS_PRESENT if(suffix_check(GLOBALS->loaded_file_name, ".aet") || suffix_check(GLOBALS->loaded_file_name, ".ae2")) { return(rc); } #endif memset(&buf, 0, sizeof(struct stat)); if(stat(path, &buf) == 0) { if(S_ISREG(buf.st_mode)) { FILE *f = fopen(path, "rb"); if(f) { int hdr[2] = { 0, 0 }; unsigned int magic_word; hdr[0] = fgetc(f); hdr[1] = fgetc(f); if((hdr[0] != EOF) && (hdr[1] != EOF)) { magic_word = (hdr[0] * 256) + hdr[1]; switch(magic_word) { case LT_HDRID: rc = G_FT_LXT; break; case LXT2_RD_HDRID: rc = G_FT_LXT2; break; case VZT_RD_HDRID: rc = G_FT_VZT; break; default: break; } if(rc == G_FT_UNKNOWN) { if(hdr[0] == FST_BL_ZWRAPPER) { rc = G_FT_FST; } else if(hdr[0] == FST_BL_HDR) { unsigned char e_ch[8]; int i, c; double fst_real_test = (2.7182818284590452354); int nfa, nfb; for(i=0;i<23;i++) { if(fgetc(f) == EOF) goto chk_ex; } for(i=0;i<8;i++) { e_ch[i] = c = fgetc(f); if(c == EOF) goto chk_ex; } nfa = nfb = 0; for(i=0;i<8;i++) { if(e_ch[i] == ((unsigned char *)&fst_real_test)[i]) { nfa++; } if(e_ch[7-i] == ((unsigned char *)&fst_real_test)[i]) { nfb++; } } if((nfa == 8) || (nfb == 8)) { rc = G_FT_FST; } } } } chk_ex: fclose(f); } } } errno = 0; return(rc); } #else int determine_gtkwave_filetype(const char *path) { return(G_FT_UNKNOWN); } #endif /******************************************************/ gtkwave-3.3.66/src/rgb.c0000664000076400007640000010326611570577234014327 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2009. * * 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. */ #include #include #include #include #include #include "rc.h" #include "color.h" #include "currenttime.h" #include "globals.h" #ifdef _MSC_VER #define strcasecmp _stricmp #endif struct wave_rgb_color { const char *name; int rgb; GdkGC *context; }; #define WAVE_RGB_COLOR(_name, r, g, b) { _name, (r << 16) | (g << 8) | b, NULL } /* * the strings *must* be in this order for the * case insensitive string bsearch */ static struct wave_rgb_color colors[] = { WAVE_RGB_COLOR("alice blue", 240, 248, 255), WAVE_RGB_COLOR("AliceBlue", 240, 248, 255), WAVE_RGB_COLOR("antique white", 250, 235, 215), WAVE_RGB_COLOR("AntiqueWhite", 250, 235, 215), WAVE_RGB_COLOR("AntiqueWhite1", 255, 239, 219), WAVE_RGB_COLOR("AntiqueWhite2", 238, 223, 204), WAVE_RGB_COLOR("AntiqueWhite3", 205, 192, 176), WAVE_RGB_COLOR("AntiqueWhite4", 139, 131, 120), WAVE_RGB_COLOR("aquamarine", 127, 255, 212), WAVE_RGB_COLOR("aquamarine1", 127, 255, 212), WAVE_RGB_COLOR("aquamarine2", 118, 238, 198), WAVE_RGB_COLOR("aquamarine3", 102, 205, 170), WAVE_RGB_COLOR("aquamarine4", 69, 139, 116), WAVE_RGB_COLOR("azure", 240, 255, 255), WAVE_RGB_COLOR("azure1", 240, 255, 255), WAVE_RGB_COLOR("azure2", 224, 238, 238), WAVE_RGB_COLOR("azure3", 193, 205, 205), WAVE_RGB_COLOR("azure4", 131, 139, 139), WAVE_RGB_COLOR("beige", 245, 245, 220), WAVE_RGB_COLOR("bisque", 255, 228, 196), WAVE_RGB_COLOR("bisque1", 255, 228, 196), WAVE_RGB_COLOR("bisque2", 238, 213, 183), WAVE_RGB_COLOR("bisque3", 205, 183, 158), WAVE_RGB_COLOR("bisque4", 139, 125, 107), WAVE_RGB_COLOR("black", 0, 0, 0), WAVE_RGB_COLOR("blanched almond", 255, 235, 205), WAVE_RGB_COLOR("BlanchedAlmond", 255, 235, 205), WAVE_RGB_COLOR("blue", 0, 0, 255), WAVE_RGB_COLOR("blue violet", 138, 43, 226), WAVE_RGB_COLOR("blue1", 0, 0, 255), WAVE_RGB_COLOR("blue2", 0, 0, 238), WAVE_RGB_COLOR("blue3", 0, 0, 205), WAVE_RGB_COLOR("blue4", 0, 0, 139), WAVE_RGB_COLOR("BlueViolet", 138, 43, 226), WAVE_RGB_COLOR("brown", 165, 42, 42), WAVE_RGB_COLOR("brown1", 255, 64, 64), WAVE_RGB_COLOR("brown2", 238, 59, 59), WAVE_RGB_COLOR("brown3", 205, 51, 51), WAVE_RGB_COLOR("brown4", 139, 35, 35), WAVE_RGB_COLOR("burlywood", 222, 184, 135), WAVE_RGB_COLOR("burlywood1", 255, 211, 155), WAVE_RGB_COLOR("burlywood2", 238, 197, 145), WAVE_RGB_COLOR("burlywood3", 205, 170, 125), WAVE_RGB_COLOR("burlywood4", 139, 115, 85), WAVE_RGB_COLOR("cadet blue", 95, 158, 160), WAVE_RGB_COLOR("CadetBlue", 95, 158, 160), WAVE_RGB_COLOR("CadetBlue1", 152, 245, 255), WAVE_RGB_COLOR("CadetBlue2", 142, 229, 238), WAVE_RGB_COLOR("CadetBlue3", 122, 197, 205), WAVE_RGB_COLOR("CadetBlue4", 83, 134, 139), WAVE_RGB_COLOR("chartreuse", 127, 255, 0), WAVE_RGB_COLOR("chartreuse1", 127, 255, 0), WAVE_RGB_COLOR("chartreuse2", 118, 238, 0), WAVE_RGB_COLOR("chartreuse3", 102, 205, 0), WAVE_RGB_COLOR("chartreuse4", 69, 139, 0), WAVE_RGB_COLOR("chocolate", 210, 105, 30), WAVE_RGB_COLOR("chocolate1", 255, 127, 36), WAVE_RGB_COLOR("chocolate2", 238, 118, 33), WAVE_RGB_COLOR("chocolate3", 205, 102, 29), WAVE_RGB_COLOR("chocolate4", 139, 69, 19), WAVE_RGB_COLOR("coral", 255, 127, 80), WAVE_RGB_COLOR("coral1", 255, 114, 86), WAVE_RGB_COLOR("coral2", 238, 106, 80), WAVE_RGB_COLOR("coral3", 205, 91, 69), WAVE_RGB_COLOR("coral4", 139, 62, 47), WAVE_RGB_COLOR("cornflower blue", 100, 149, 237), WAVE_RGB_COLOR("CornflowerBlue", 100, 149, 237), WAVE_RGB_COLOR("cornsilk", 255, 248, 220), WAVE_RGB_COLOR("cornsilk1", 255, 248, 220), WAVE_RGB_COLOR("cornsilk2", 238, 232, 205), WAVE_RGB_COLOR("cornsilk3", 205, 200, 177), WAVE_RGB_COLOR("cornsilk4", 139, 136, 120), WAVE_RGB_COLOR("cyan", 0, 255, 255), WAVE_RGB_COLOR("cyan1", 0, 255, 255), WAVE_RGB_COLOR("cyan2", 0, 238, 238), WAVE_RGB_COLOR("cyan3", 0, 205, 205), WAVE_RGB_COLOR("cyan4", 0, 139, 139), WAVE_RGB_COLOR("dark blue", 0, 0, 139), WAVE_RGB_COLOR("dark cyan", 0, 139, 139), WAVE_RGB_COLOR("dark goldenrod", 184, 134, 11), WAVE_RGB_COLOR("dark gray", 169, 169, 169), WAVE_RGB_COLOR("dark green", 0, 100, 0), WAVE_RGB_COLOR("dark grey", 169, 169, 169), WAVE_RGB_COLOR("dark khaki", 189, 183, 107), WAVE_RGB_COLOR("dark magenta", 139, 0, 139), WAVE_RGB_COLOR("dark olive green", 85, 107, 47), WAVE_RGB_COLOR("dark orange", 255, 140, 0), WAVE_RGB_COLOR("dark orchid", 153, 50, 204), WAVE_RGB_COLOR("dark red", 139, 0, 0), WAVE_RGB_COLOR("dark salmon", 233, 150, 122), WAVE_RGB_COLOR("dark sea green", 143, 188, 143), WAVE_RGB_COLOR("dark slate blue", 72, 61, 139), WAVE_RGB_COLOR("dark slate gray", 47, 79, 79), WAVE_RGB_COLOR("dark slate grey", 47, 79, 79), WAVE_RGB_COLOR("dark turquoise", 0, 206, 209), WAVE_RGB_COLOR("dark violet", 148, 0, 211), WAVE_RGB_COLOR("DarkBlue", 0, 0, 139), WAVE_RGB_COLOR("DarkCyan", 0, 139, 139), WAVE_RGB_COLOR("DarkGoldenrod", 184, 134, 11), WAVE_RGB_COLOR("DarkGoldenrod1", 255, 185, 15), WAVE_RGB_COLOR("DarkGoldenrod2", 238, 173, 14), WAVE_RGB_COLOR("DarkGoldenrod3", 205, 149, 12), WAVE_RGB_COLOR("DarkGoldenrod4", 139, 101, 8), WAVE_RGB_COLOR("DarkGray", 169, 169, 169), WAVE_RGB_COLOR("DarkGreen", 0, 100, 0), WAVE_RGB_COLOR("DarkGrey", 169, 169, 169), WAVE_RGB_COLOR("DarkKhaki", 189, 183, 107), WAVE_RGB_COLOR("DarkMagenta", 139, 0, 139), WAVE_RGB_COLOR("DarkOliveGreen", 85, 107, 47), WAVE_RGB_COLOR("DarkOliveGreen1", 202, 255, 112), WAVE_RGB_COLOR("DarkOliveGreen2", 188, 238, 104), WAVE_RGB_COLOR("DarkOliveGreen3", 162, 205, 90), WAVE_RGB_COLOR("DarkOliveGreen4", 110, 139, 61), WAVE_RGB_COLOR("DarkOrange", 255, 140, 0), WAVE_RGB_COLOR("DarkOrange1", 255, 127, 0), WAVE_RGB_COLOR("DarkOrange2", 238, 118, 0), WAVE_RGB_COLOR("DarkOrange3", 205, 102, 0), WAVE_RGB_COLOR("DarkOrange4", 139, 69, 0), WAVE_RGB_COLOR("DarkOrchid", 153, 50, 204), WAVE_RGB_COLOR("DarkOrchid1", 191, 62, 255), WAVE_RGB_COLOR("DarkOrchid2", 178, 58, 238), WAVE_RGB_COLOR("DarkOrchid3", 154, 50, 205), WAVE_RGB_COLOR("DarkOrchid4", 104, 34, 139), WAVE_RGB_COLOR("DarkRed", 139, 0, 0), WAVE_RGB_COLOR("DarkSalmon", 233, 150, 122), WAVE_RGB_COLOR("DarkSeaGreen", 143, 188, 143), WAVE_RGB_COLOR("DarkSeaGreen1", 193, 255, 193), WAVE_RGB_COLOR("DarkSeaGreen2", 180, 238, 180), WAVE_RGB_COLOR("DarkSeaGreen3", 155, 205, 155), WAVE_RGB_COLOR("DarkSeaGreen4", 105, 139, 105), WAVE_RGB_COLOR("DarkSlateBlue", 72, 61, 139), WAVE_RGB_COLOR("DarkSlateGray", 47, 79, 79), WAVE_RGB_COLOR("DarkSlateGray1", 151, 255, 255), WAVE_RGB_COLOR("DarkSlateGray2", 141, 238, 238), WAVE_RGB_COLOR("DarkSlateGray3", 121, 205, 205), WAVE_RGB_COLOR("DarkSlateGray4", 82, 139, 139), WAVE_RGB_COLOR("DarkSlateGrey", 47, 79, 79), WAVE_RGB_COLOR("DarkTurquoise", 0, 206, 209), WAVE_RGB_COLOR("DarkViolet", 148, 0, 211), WAVE_RGB_COLOR("deep pink", 255, 20, 147), WAVE_RGB_COLOR("deep sky blue", 0, 191, 255), WAVE_RGB_COLOR("DeepPink", 255, 20, 147), WAVE_RGB_COLOR("DeepPink1", 255, 20, 147), WAVE_RGB_COLOR("DeepPink2", 238, 18, 137), WAVE_RGB_COLOR("DeepPink3", 205, 16, 118), WAVE_RGB_COLOR("DeepPink4", 139, 10, 80), WAVE_RGB_COLOR("DeepSkyBlue", 0, 191, 255), WAVE_RGB_COLOR("DeepSkyBlue1", 0, 191, 255), WAVE_RGB_COLOR("DeepSkyBlue2", 0, 178, 238), WAVE_RGB_COLOR("DeepSkyBlue3", 0, 154, 205), WAVE_RGB_COLOR("DeepSkyBlue4", 0, 104, 139), WAVE_RGB_COLOR("dim gray", 105, 105, 105), WAVE_RGB_COLOR("dim grey", 105, 105, 105), WAVE_RGB_COLOR("DimGray", 105, 105, 105), WAVE_RGB_COLOR("DimGrey", 105, 105, 105), WAVE_RGB_COLOR("dodger blue", 30, 144, 255), WAVE_RGB_COLOR("DodgerBlue", 30, 144, 255), WAVE_RGB_COLOR("DodgerBlue1", 30, 144, 255), WAVE_RGB_COLOR("DodgerBlue2", 28, 134, 238), WAVE_RGB_COLOR("DodgerBlue3", 24, 116, 205), WAVE_RGB_COLOR("DodgerBlue4", 16, 78, 139), WAVE_RGB_COLOR("firebrick", 178, 34, 34), WAVE_RGB_COLOR("firebrick1", 255, 48, 48), WAVE_RGB_COLOR("firebrick2", 238, 44, 44), WAVE_RGB_COLOR("firebrick3", 205, 38, 38), WAVE_RGB_COLOR("firebrick4", 139, 26, 26), WAVE_RGB_COLOR("floral white", 255, 250, 240), WAVE_RGB_COLOR("FloralWhite", 255, 250, 240), WAVE_RGB_COLOR("forest green", 34, 139, 34), WAVE_RGB_COLOR("ForestGreen", 34, 139, 34), WAVE_RGB_COLOR("gainsboro", 220, 220, 220), WAVE_RGB_COLOR("ghost white", 248, 248, 255), WAVE_RGB_COLOR("GhostWhite", 248, 248, 255), WAVE_RGB_COLOR("gold", 255, 215, 0), WAVE_RGB_COLOR("gold1", 255, 215, 0), WAVE_RGB_COLOR("gold2", 238, 201, 0), WAVE_RGB_COLOR("gold3", 205, 173, 0), WAVE_RGB_COLOR("gold4", 139, 117, 0), WAVE_RGB_COLOR("goldenrod", 218, 165, 32), WAVE_RGB_COLOR("goldenrod1", 255, 193, 37), WAVE_RGB_COLOR("goldenrod2", 238, 180, 34), WAVE_RGB_COLOR("goldenrod3", 205, 155, 29), WAVE_RGB_COLOR("goldenrod4", 139, 105, 20), WAVE_RGB_COLOR("gray", 190, 190, 190), WAVE_RGB_COLOR("gray0", 0, 0, 0), WAVE_RGB_COLOR("gray1", 3, 3, 3), WAVE_RGB_COLOR("gray10", 26, 26, 26), WAVE_RGB_COLOR("gray100", 255, 255, 255), WAVE_RGB_COLOR("gray11", 28, 28, 28), WAVE_RGB_COLOR("gray12", 31, 31, 31), WAVE_RGB_COLOR("gray13", 33, 33, 33), WAVE_RGB_COLOR("gray14", 36, 36, 36), WAVE_RGB_COLOR("gray15", 38, 38, 38), WAVE_RGB_COLOR("gray16", 41, 41, 41), WAVE_RGB_COLOR("gray17", 43, 43, 43), WAVE_RGB_COLOR("gray18", 46, 46, 46), WAVE_RGB_COLOR("gray19", 48, 48, 48), WAVE_RGB_COLOR("gray2", 5, 5, 5), WAVE_RGB_COLOR("gray20", 51, 51, 51), WAVE_RGB_COLOR("gray21", 54, 54, 54), WAVE_RGB_COLOR("gray22", 56, 56, 56), WAVE_RGB_COLOR("gray23", 59, 59, 59), WAVE_RGB_COLOR("gray24", 61, 61, 61), WAVE_RGB_COLOR("gray25", 64, 64, 64), WAVE_RGB_COLOR("gray26", 66, 66, 66), WAVE_RGB_COLOR("gray27", 69, 69, 69), WAVE_RGB_COLOR("gray28", 71, 71, 71), WAVE_RGB_COLOR("gray29", 74, 74, 74), WAVE_RGB_COLOR("gray3", 8, 8, 8), WAVE_RGB_COLOR("gray30", 77, 77, 77), WAVE_RGB_COLOR("gray31", 79, 79, 79), WAVE_RGB_COLOR("gray32", 82, 82, 82), WAVE_RGB_COLOR("gray33", 84, 84, 84), WAVE_RGB_COLOR("gray34", 87, 87, 87), WAVE_RGB_COLOR("gray35", 89, 89, 89), WAVE_RGB_COLOR("gray36", 92, 92, 92), WAVE_RGB_COLOR("gray37", 94, 94, 94), WAVE_RGB_COLOR("gray38", 97, 97, 97), WAVE_RGB_COLOR("gray39", 99, 99, 99), WAVE_RGB_COLOR("gray4", 10, 10, 10), WAVE_RGB_COLOR("gray40", 102, 102, 102), WAVE_RGB_COLOR("gray41", 105, 105, 105), WAVE_RGB_COLOR("gray42", 107, 107, 107), WAVE_RGB_COLOR("gray43", 110, 110, 110), WAVE_RGB_COLOR("gray44", 112, 112, 112), WAVE_RGB_COLOR("gray45", 115, 115, 115), WAVE_RGB_COLOR("gray46", 117, 117, 117), WAVE_RGB_COLOR("gray47", 120, 120, 120), WAVE_RGB_COLOR("gray48", 122, 122, 122), WAVE_RGB_COLOR("gray49", 125, 125, 125), WAVE_RGB_COLOR("gray5", 13, 13, 13), WAVE_RGB_COLOR("gray50", 127, 127, 127), WAVE_RGB_COLOR("gray51", 130, 130, 130), WAVE_RGB_COLOR("gray52", 133, 133, 133), WAVE_RGB_COLOR("gray53", 135, 135, 135), WAVE_RGB_COLOR("gray54", 138, 138, 138), WAVE_RGB_COLOR("gray55", 140, 140, 140), WAVE_RGB_COLOR("gray56", 143, 143, 143), WAVE_RGB_COLOR("gray57", 145, 145, 145), WAVE_RGB_COLOR("gray58", 148, 148, 148), WAVE_RGB_COLOR("gray59", 150, 150, 150), WAVE_RGB_COLOR("gray6", 15, 15, 15), WAVE_RGB_COLOR("gray60", 153, 153, 153), WAVE_RGB_COLOR("gray61", 156, 156, 156), WAVE_RGB_COLOR("gray62", 158, 158, 158), WAVE_RGB_COLOR("gray63", 161, 161, 161), WAVE_RGB_COLOR("gray64", 163, 163, 163), WAVE_RGB_COLOR("gray65", 166, 166, 166), WAVE_RGB_COLOR("gray66", 168, 168, 168), WAVE_RGB_COLOR("gray67", 171, 171, 171), WAVE_RGB_COLOR("gray68", 173, 173, 173), WAVE_RGB_COLOR("gray69", 176, 176, 176), WAVE_RGB_COLOR("gray7", 18, 18, 18), WAVE_RGB_COLOR("gray70", 179, 179, 179), WAVE_RGB_COLOR("gray71", 181, 181, 181), WAVE_RGB_COLOR("gray72", 184, 184, 184), WAVE_RGB_COLOR("gray73", 186, 186, 186), WAVE_RGB_COLOR("gray74", 189, 189, 189), WAVE_RGB_COLOR("gray75", 191, 191, 191), WAVE_RGB_COLOR("gray76", 194, 194, 194), WAVE_RGB_COLOR("gray77", 196, 196, 196), WAVE_RGB_COLOR("gray78", 199, 199, 199), WAVE_RGB_COLOR("gray79", 201, 201, 201), WAVE_RGB_COLOR("gray8", 20, 20, 20), WAVE_RGB_COLOR("gray80", 204, 204, 204), WAVE_RGB_COLOR("gray81", 207, 207, 207), WAVE_RGB_COLOR("gray82", 209, 209, 209), WAVE_RGB_COLOR("gray83", 212, 212, 212), WAVE_RGB_COLOR("gray84", 214, 214, 214), WAVE_RGB_COLOR("gray85", 217, 217, 217), WAVE_RGB_COLOR("gray86", 219, 219, 219), WAVE_RGB_COLOR("gray87", 222, 222, 222), WAVE_RGB_COLOR("gray88", 224, 224, 224), WAVE_RGB_COLOR("gray89", 227, 227, 227), WAVE_RGB_COLOR("gray9", 23, 23, 23), WAVE_RGB_COLOR("gray90", 229, 229, 229), WAVE_RGB_COLOR("gray91", 232, 232, 232), WAVE_RGB_COLOR("gray92", 235, 235, 235), WAVE_RGB_COLOR("gray93", 237, 237, 237), WAVE_RGB_COLOR("gray94", 240, 240, 240), WAVE_RGB_COLOR("gray95", 242, 242, 242), WAVE_RGB_COLOR("gray96", 245, 245, 245), WAVE_RGB_COLOR("gray97", 247, 247, 247), WAVE_RGB_COLOR("gray98", 250, 250, 250), WAVE_RGB_COLOR("gray99", 252, 252, 252), WAVE_RGB_COLOR("green", 0, 255, 0), WAVE_RGB_COLOR("green yellow", 173, 255, 47), WAVE_RGB_COLOR("green1", 0, 255, 0), WAVE_RGB_COLOR("green2", 0, 238, 0), WAVE_RGB_COLOR("green3", 0, 205, 0), WAVE_RGB_COLOR("green4", 0, 139, 0), WAVE_RGB_COLOR("GreenYellow", 173, 255, 47), WAVE_RGB_COLOR("grey", 190, 190, 190), WAVE_RGB_COLOR("grey0", 0, 0, 0), WAVE_RGB_COLOR("grey1", 3, 3, 3), WAVE_RGB_COLOR("grey10", 26, 26, 26), WAVE_RGB_COLOR("grey100", 255, 255, 255), WAVE_RGB_COLOR("grey11", 28, 28, 28), WAVE_RGB_COLOR("grey12", 31, 31, 31), WAVE_RGB_COLOR("grey13", 33, 33, 33), WAVE_RGB_COLOR("grey14", 36, 36, 36), WAVE_RGB_COLOR("grey15", 38, 38, 38), WAVE_RGB_COLOR("grey16", 41, 41, 41), WAVE_RGB_COLOR("grey17", 43, 43, 43), WAVE_RGB_COLOR("grey18", 46, 46, 46), WAVE_RGB_COLOR("grey19", 48, 48, 48), WAVE_RGB_COLOR("grey2", 5, 5, 5), WAVE_RGB_COLOR("grey20", 51, 51, 51), WAVE_RGB_COLOR("grey21", 54, 54, 54), WAVE_RGB_COLOR("grey22", 56, 56, 56), WAVE_RGB_COLOR("grey23", 59, 59, 59), WAVE_RGB_COLOR("grey24", 61, 61, 61), WAVE_RGB_COLOR("grey25", 64, 64, 64), WAVE_RGB_COLOR("grey26", 66, 66, 66), WAVE_RGB_COLOR("grey27", 69, 69, 69), WAVE_RGB_COLOR("grey28", 71, 71, 71), WAVE_RGB_COLOR("grey29", 74, 74, 74), WAVE_RGB_COLOR("grey3", 8, 8, 8), WAVE_RGB_COLOR("grey30", 77, 77, 77), WAVE_RGB_COLOR("grey31", 79, 79, 79), WAVE_RGB_COLOR("grey32", 82, 82, 82), WAVE_RGB_COLOR("grey33", 84, 84, 84), WAVE_RGB_COLOR("grey34", 87, 87, 87), WAVE_RGB_COLOR("grey35", 89, 89, 89), WAVE_RGB_COLOR("grey36", 92, 92, 92), WAVE_RGB_COLOR("grey37", 94, 94, 94), WAVE_RGB_COLOR("grey38", 97, 97, 97), WAVE_RGB_COLOR("grey39", 99, 99, 99), WAVE_RGB_COLOR("grey4", 10, 10, 10), WAVE_RGB_COLOR("grey40", 102, 102, 102), WAVE_RGB_COLOR("grey41", 105, 105, 105), WAVE_RGB_COLOR("grey42", 107, 107, 107), WAVE_RGB_COLOR("grey43", 110, 110, 110), WAVE_RGB_COLOR("grey44", 112, 112, 112), WAVE_RGB_COLOR("grey45", 115, 115, 115), WAVE_RGB_COLOR("grey46", 117, 117, 117), WAVE_RGB_COLOR("grey47", 120, 120, 120), WAVE_RGB_COLOR("grey48", 122, 122, 122), WAVE_RGB_COLOR("grey49", 125, 125, 125), WAVE_RGB_COLOR("grey5", 13, 13, 13), WAVE_RGB_COLOR("grey50", 127, 127, 127), WAVE_RGB_COLOR("grey51", 130, 130, 130), WAVE_RGB_COLOR("grey52", 133, 133, 133), WAVE_RGB_COLOR("grey53", 135, 135, 135), WAVE_RGB_COLOR("grey54", 138, 138, 138), WAVE_RGB_COLOR("grey55", 140, 140, 140), WAVE_RGB_COLOR("grey56", 143, 143, 143), WAVE_RGB_COLOR("grey57", 145, 145, 145), WAVE_RGB_COLOR("grey58", 148, 148, 148), WAVE_RGB_COLOR("grey59", 150, 150, 150), WAVE_RGB_COLOR("grey6", 15, 15, 15), WAVE_RGB_COLOR("grey60", 153, 153, 153), WAVE_RGB_COLOR("grey61", 156, 156, 156), WAVE_RGB_COLOR("grey62", 158, 158, 158), WAVE_RGB_COLOR("grey63", 161, 161, 161), WAVE_RGB_COLOR("grey64", 163, 163, 163), WAVE_RGB_COLOR("grey65", 166, 166, 166), WAVE_RGB_COLOR("grey66", 168, 168, 168), WAVE_RGB_COLOR("grey67", 171, 171, 171), WAVE_RGB_COLOR("grey68", 173, 173, 173), WAVE_RGB_COLOR("grey69", 176, 176, 176), WAVE_RGB_COLOR("grey7", 18, 18, 18), WAVE_RGB_COLOR("grey70", 179, 179, 179), WAVE_RGB_COLOR("grey71", 181, 181, 181), WAVE_RGB_COLOR("grey72", 184, 184, 184), WAVE_RGB_COLOR("grey73", 186, 186, 186), WAVE_RGB_COLOR("grey74", 189, 189, 189), WAVE_RGB_COLOR("grey75", 191, 191, 191), WAVE_RGB_COLOR("grey76", 194, 194, 194), WAVE_RGB_COLOR("grey77", 196, 196, 196), WAVE_RGB_COLOR("grey78", 199, 199, 199), WAVE_RGB_COLOR("grey79", 201, 201, 201), WAVE_RGB_COLOR("grey8", 20, 20, 20), WAVE_RGB_COLOR("grey80", 204, 204, 204), WAVE_RGB_COLOR("grey81", 207, 207, 207), WAVE_RGB_COLOR("grey82", 209, 209, 209), WAVE_RGB_COLOR("grey83", 212, 212, 212), WAVE_RGB_COLOR("grey84", 214, 214, 214), WAVE_RGB_COLOR("grey85", 217, 217, 217), WAVE_RGB_COLOR("grey86", 219, 219, 219), WAVE_RGB_COLOR("grey87", 222, 222, 222), WAVE_RGB_COLOR("grey88", 224, 224, 224), WAVE_RGB_COLOR("grey89", 227, 227, 227), WAVE_RGB_COLOR("grey9", 23, 23, 23), WAVE_RGB_COLOR("grey90", 229, 229, 229), WAVE_RGB_COLOR("grey91", 232, 232, 232), WAVE_RGB_COLOR("grey92", 235, 235, 235), WAVE_RGB_COLOR("grey93", 237, 237, 237), WAVE_RGB_COLOR("grey94", 240, 240, 240), WAVE_RGB_COLOR("grey95", 242, 242, 242), WAVE_RGB_COLOR("grey96", 245, 245, 245), WAVE_RGB_COLOR("grey97", 247, 247, 247), WAVE_RGB_COLOR("grey98", 250, 250, 250), WAVE_RGB_COLOR("grey99", 252, 252, 252), WAVE_RGB_COLOR("honeydew", 240, 255, 240), WAVE_RGB_COLOR("honeydew1", 240, 255, 240), WAVE_RGB_COLOR("honeydew2", 224, 238, 224), WAVE_RGB_COLOR("honeydew3", 193, 205, 193), WAVE_RGB_COLOR("honeydew4", 131, 139, 131), WAVE_RGB_COLOR("hot pink", 255, 105, 180), WAVE_RGB_COLOR("HotPink", 255, 105, 180), WAVE_RGB_COLOR("HotPink1", 255, 110, 180), WAVE_RGB_COLOR("HotPink2", 238, 106, 167), WAVE_RGB_COLOR("HotPink3", 205, 96, 144), WAVE_RGB_COLOR("HotPink4", 139, 58, 98), WAVE_RGB_COLOR("indian red", 205, 92, 92), WAVE_RGB_COLOR("IndianRed", 205, 92, 92), WAVE_RGB_COLOR("IndianRed1", 255, 106, 106), WAVE_RGB_COLOR("IndianRed2", 238, 99, 99), WAVE_RGB_COLOR("IndianRed3", 205, 85, 85), WAVE_RGB_COLOR("IndianRed4", 139, 58, 58), WAVE_RGB_COLOR("ivory", 255, 255, 240), WAVE_RGB_COLOR("ivory1", 255, 255, 240), WAVE_RGB_COLOR("ivory2", 238, 238, 224), WAVE_RGB_COLOR("ivory3", 205, 205, 193), WAVE_RGB_COLOR("ivory4", 139, 139, 131), WAVE_RGB_COLOR("khaki", 240, 230, 140), WAVE_RGB_COLOR("khaki1", 255, 246, 143), WAVE_RGB_COLOR("khaki2", 238, 230, 133), WAVE_RGB_COLOR("khaki3", 205, 198, 115), WAVE_RGB_COLOR("khaki4", 139, 134, 78), WAVE_RGB_COLOR("lavender", 230, 230, 250), WAVE_RGB_COLOR("lavender blush", 255, 240, 245), WAVE_RGB_COLOR("LavenderBlush", 255, 240, 245), WAVE_RGB_COLOR("LavenderBlush1", 255, 240, 245), WAVE_RGB_COLOR("LavenderBlush2", 238, 224, 229), WAVE_RGB_COLOR("LavenderBlush3", 205, 193, 197), WAVE_RGB_COLOR("LavenderBlush4", 139, 131, 134), WAVE_RGB_COLOR("lawn green", 124, 252, 0), WAVE_RGB_COLOR("LawnGreen", 124, 252, 0), WAVE_RGB_COLOR("lemon chiffon", 255, 250, 205), WAVE_RGB_COLOR("LemonChiffon", 255, 250, 205), WAVE_RGB_COLOR("LemonChiffon1", 255, 250, 205), WAVE_RGB_COLOR("LemonChiffon2", 238, 233, 191), WAVE_RGB_COLOR("LemonChiffon3", 205, 201, 165), WAVE_RGB_COLOR("LemonChiffon4", 139, 137, 112), WAVE_RGB_COLOR("light blue", 173, 216, 230), WAVE_RGB_COLOR("light coral", 240, 128, 128), WAVE_RGB_COLOR("light cyan", 224, 255, 255), WAVE_RGB_COLOR("light goldenrod", 238, 221, 130), WAVE_RGB_COLOR("light goldenrod yellow", 250, 250, 210), WAVE_RGB_COLOR("light gray", 211, 211, 211), WAVE_RGB_COLOR("light green", 144, 238, 144), WAVE_RGB_COLOR("light grey", 211, 211, 211), WAVE_RGB_COLOR("light pink", 255, 182, 193), WAVE_RGB_COLOR("light salmon", 255, 160, 122), WAVE_RGB_COLOR("light sea green", 32, 178, 170), WAVE_RGB_COLOR("light sky blue", 135, 206, 250), WAVE_RGB_COLOR("light slate blue", 132, 112, 255), WAVE_RGB_COLOR("light slate gray", 119, 136, 153), WAVE_RGB_COLOR("light slate grey", 119, 136, 153), WAVE_RGB_COLOR("light steel blue", 176, 196, 222), WAVE_RGB_COLOR("light yellow", 255, 255, 224), WAVE_RGB_COLOR("LightBlue", 173, 216, 230), WAVE_RGB_COLOR("LightBlue1", 191, 239, 255), WAVE_RGB_COLOR("LightBlue2", 178, 223, 238), WAVE_RGB_COLOR("LightBlue3", 154, 192, 205), WAVE_RGB_COLOR("LightBlue4", 104, 131, 139), WAVE_RGB_COLOR("LightCoral", 240, 128, 128), WAVE_RGB_COLOR("LightCyan", 224, 255, 255), WAVE_RGB_COLOR("LightCyan1", 224, 255, 255), WAVE_RGB_COLOR("LightCyan2", 209, 238, 238), WAVE_RGB_COLOR("LightCyan3", 180, 205, 205), WAVE_RGB_COLOR("LightCyan4", 122, 139, 139), WAVE_RGB_COLOR("LightGoldenrod", 238, 221, 130), WAVE_RGB_COLOR("LightGoldenrod1", 255, 236, 139), WAVE_RGB_COLOR("LightGoldenrod2", 238, 220, 130), WAVE_RGB_COLOR("LightGoldenrod3", 205, 190, 112), WAVE_RGB_COLOR("LightGoldenrod4", 139, 129, 76), WAVE_RGB_COLOR("LightGoldenrodYellow", 250, 250, 210), WAVE_RGB_COLOR("LightGray", 211, 211, 211), WAVE_RGB_COLOR("LightGreen", 144, 238, 144), WAVE_RGB_COLOR("LightGrey", 211, 211, 211), WAVE_RGB_COLOR("LightPink", 255, 182, 193), WAVE_RGB_COLOR("LightPink1", 255, 174, 185), WAVE_RGB_COLOR("LightPink2", 238, 162, 173), WAVE_RGB_COLOR("LightPink3", 205, 140, 149), WAVE_RGB_COLOR("LightPink4", 139, 95, 101), WAVE_RGB_COLOR("LightSalmon", 255, 160, 122), WAVE_RGB_COLOR("LightSalmon1", 255, 160, 122), WAVE_RGB_COLOR("LightSalmon2", 238, 149, 114), WAVE_RGB_COLOR("LightSalmon3", 205, 129, 98), WAVE_RGB_COLOR("LightSalmon4", 139, 87, 66), WAVE_RGB_COLOR("LightSeaGreen", 32, 178, 170), WAVE_RGB_COLOR("LightSkyBlue", 135, 206, 250), WAVE_RGB_COLOR("LightSkyBlue1", 176, 226, 255), WAVE_RGB_COLOR("LightSkyBlue2", 164, 211, 238), WAVE_RGB_COLOR("LightSkyBlue3", 141, 182, 205), WAVE_RGB_COLOR("LightSkyBlue4", 96, 123, 139), WAVE_RGB_COLOR("LightSlateBlue", 132, 112, 255), WAVE_RGB_COLOR("LightSlateGray", 119, 136, 153), WAVE_RGB_COLOR("LightSlateGrey", 119, 136, 153), WAVE_RGB_COLOR("LightSteelBlue", 176, 196, 222), WAVE_RGB_COLOR("LightSteelBlue1", 202, 225, 255), WAVE_RGB_COLOR("LightSteelBlue2", 188, 210, 238), WAVE_RGB_COLOR("LightSteelBlue3", 162, 181, 205), WAVE_RGB_COLOR("LightSteelBlue4", 110, 123, 139), WAVE_RGB_COLOR("LightYellow", 255, 255, 224), WAVE_RGB_COLOR("LightYellow1", 255, 255, 224), WAVE_RGB_COLOR("LightYellow2", 238, 238, 209), WAVE_RGB_COLOR("LightYellow3", 205, 205, 180), WAVE_RGB_COLOR("LightYellow4", 139, 139, 122), WAVE_RGB_COLOR("lime green", 50, 205, 50), WAVE_RGB_COLOR("LimeGreen", 50, 205, 50), WAVE_RGB_COLOR("linen", 250, 240, 230), WAVE_RGB_COLOR("magenta", 255, 0, 255), WAVE_RGB_COLOR("magenta1", 255, 0, 255), WAVE_RGB_COLOR("magenta2", 238, 0, 238), WAVE_RGB_COLOR("magenta3", 205, 0, 205), WAVE_RGB_COLOR("magenta4", 139, 0, 139), WAVE_RGB_COLOR("maroon", 176, 48, 96), WAVE_RGB_COLOR("maroon1", 255, 52, 179), WAVE_RGB_COLOR("maroon2", 238, 48, 167), WAVE_RGB_COLOR("maroon3", 205, 41, 144), WAVE_RGB_COLOR("maroon4", 139, 28, 98), WAVE_RGB_COLOR("medium aquamarine", 102, 205, 170), WAVE_RGB_COLOR("medium blue", 0, 0, 205), WAVE_RGB_COLOR("medium orchid", 186, 85, 211), WAVE_RGB_COLOR("medium purple", 147, 112, 219), WAVE_RGB_COLOR("medium sea green", 60, 179, 113), WAVE_RGB_COLOR("medium slate blue", 123, 104, 238), WAVE_RGB_COLOR("medium spring green", 0, 250, 154), WAVE_RGB_COLOR("medium turquoise", 72, 209, 204), WAVE_RGB_COLOR("medium violet red", 199, 21, 133), WAVE_RGB_COLOR("MediumAquamarine", 102, 205, 170), WAVE_RGB_COLOR("MediumBlue", 0, 0, 205), WAVE_RGB_COLOR("MediumOrchid", 186, 85, 211), WAVE_RGB_COLOR("MediumOrchid1", 224, 102, 255), WAVE_RGB_COLOR("MediumOrchid2", 209, 95, 238), WAVE_RGB_COLOR("MediumOrchid3", 180, 82, 205), WAVE_RGB_COLOR("MediumOrchid4", 122, 55, 139), WAVE_RGB_COLOR("MediumPurple", 147, 112, 219), WAVE_RGB_COLOR("MediumPurple1", 171, 130, 255), WAVE_RGB_COLOR("MediumPurple2", 159, 121, 238), WAVE_RGB_COLOR("MediumPurple3", 137, 104, 205), WAVE_RGB_COLOR("MediumPurple4", 93, 71, 139), WAVE_RGB_COLOR("MediumSeaGreen", 60, 179, 113), WAVE_RGB_COLOR("MediumSlateBlue", 123, 104, 238), WAVE_RGB_COLOR("MediumSpringGreen", 0, 250, 154), WAVE_RGB_COLOR("MediumTurquoise", 72, 209, 204), WAVE_RGB_COLOR("MediumVioletRed", 199, 21, 133), WAVE_RGB_COLOR("midnight blue", 25, 25, 112), WAVE_RGB_COLOR("MidnightBlue", 25, 25, 112), WAVE_RGB_COLOR("mint cream", 245, 255, 250), WAVE_RGB_COLOR("MintCream", 245, 255, 250), WAVE_RGB_COLOR("misty rose", 255, 228, 225), WAVE_RGB_COLOR("MistyRose", 255, 228, 225), WAVE_RGB_COLOR("MistyRose1", 255, 228, 225), WAVE_RGB_COLOR("MistyRose2", 238, 213, 210), WAVE_RGB_COLOR("MistyRose3", 205, 183, 181), WAVE_RGB_COLOR("MistyRose4", 139, 125, 123), WAVE_RGB_COLOR("moccasin", 255, 228, 181), WAVE_RGB_COLOR("navajo white", 255, 222, 173), WAVE_RGB_COLOR("NavajoWhite", 255, 222, 173), WAVE_RGB_COLOR("NavajoWhite1", 255, 222, 173), WAVE_RGB_COLOR("NavajoWhite2", 238, 207, 161), WAVE_RGB_COLOR("NavajoWhite3", 205, 179, 139), WAVE_RGB_COLOR("NavajoWhite4", 139, 121, 94), WAVE_RGB_COLOR("navy", 0, 0, 128), WAVE_RGB_COLOR("navy blue", 0, 0, 128), WAVE_RGB_COLOR("NavyBlue", 0, 0, 128), WAVE_RGB_COLOR("old lace", 253, 245, 230), WAVE_RGB_COLOR("OldLace", 253, 245, 230), WAVE_RGB_COLOR("olive drab", 107, 142, 35), WAVE_RGB_COLOR("OliveDrab", 107, 142, 35), WAVE_RGB_COLOR("OliveDrab1", 192, 255, 62), WAVE_RGB_COLOR("OliveDrab2", 179, 238, 58), WAVE_RGB_COLOR("OliveDrab3", 154, 205, 50), WAVE_RGB_COLOR("OliveDrab4", 105, 139, 34), WAVE_RGB_COLOR("orange", 255, 165, 0), WAVE_RGB_COLOR("orange red", 255, 69, 0), WAVE_RGB_COLOR("orange1", 255, 165, 0), WAVE_RGB_COLOR("orange2", 238, 154, 0), WAVE_RGB_COLOR("orange3", 205, 133, 0), WAVE_RGB_COLOR("orange4", 139, 90, 0), WAVE_RGB_COLOR("OrangeRed", 255, 69, 0), WAVE_RGB_COLOR("OrangeRed1", 255, 69, 0), WAVE_RGB_COLOR("OrangeRed2", 238, 64, 0), WAVE_RGB_COLOR("OrangeRed3", 205, 55, 0), WAVE_RGB_COLOR("OrangeRed4", 139, 37, 0), WAVE_RGB_COLOR("orchid", 218, 112, 214), WAVE_RGB_COLOR("orchid1", 255, 131, 250), WAVE_RGB_COLOR("orchid2", 238, 122, 233), WAVE_RGB_COLOR("orchid3", 205, 105, 201), WAVE_RGB_COLOR("orchid4", 139, 71, 137), WAVE_RGB_COLOR("pale goldenrod", 238, 232, 170), WAVE_RGB_COLOR("pale green", 152, 251, 152), WAVE_RGB_COLOR("pale turquoise", 175, 238, 238), WAVE_RGB_COLOR("pale violet red", 219, 112, 147), WAVE_RGB_COLOR("PaleGoldenrod", 238, 232, 170), WAVE_RGB_COLOR("PaleGreen", 152, 251, 152), WAVE_RGB_COLOR("PaleGreen1", 154, 255, 154), WAVE_RGB_COLOR("PaleGreen2", 144, 238, 144), WAVE_RGB_COLOR("PaleGreen3", 124, 205, 124), WAVE_RGB_COLOR("PaleGreen4", 84, 139, 84), WAVE_RGB_COLOR("PaleTurquoise", 175, 238, 238), WAVE_RGB_COLOR("PaleTurquoise1", 187, 255, 255), WAVE_RGB_COLOR("PaleTurquoise2", 174, 238, 238), WAVE_RGB_COLOR("PaleTurquoise3", 150, 205, 205), WAVE_RGB_COLOR("PaleTurquoise4", 102, 139, 139), WAVE_RGB_COLOR("PaleVioletRed", 219, 112, 147), WAVE_RGB_COLOR("PaleVioletRed1", 255, 130, 171), WAVE_RGB_COLOR("PaleVioletRed2", 238, 121, 159), WAVE_RGB_COLOR("PaleVioletRed3", 205, 104, 137), WAVE_RGB_COLOR("PaleVioletRed4", 139, 71, 93), WAVE_RGB_COLOR("papaya whip", 255, 239, 213), WAVE_RGB_COLOR("PapayaWhip", 255, 239, 213), WAVE_RGB_COLOR("peach puff", 255, 218, 185), WAVE_RGB_COLOR("PeachPuff", 255, 218, 185), WAVE_RGB_COLOR("PeachPuff1", 255, 218, 185), WAVE_RGB_COLOR("PeachPuff2", 238, 203, 173), WAVE_RGB_COLOR("PeachPuff3", 205, 175, 149), WAVE_RGB_COLOR("PeachPuff4", 139, 119, 101), WAVE_RGB_COLOR("peru", 205, 133, 63), WAVE_RGB_COLOR("pink", 255, 192, 203), WAVE_RGB_COLOR("pink1", 255, 181, 197), WAVE_RGB_COLOR("pink2", 238, 169, 184), WAVE_RGB_COLOR("pink3", 205, 145, 158), WAVE_RGB_COLOR("pink4", 139, 99, 108), WAVE_RGB_COLOR("plum", 221, 160, 221), WAVE_RGB_COLOR("plum1", 255, 187, 255), WAVE_RGB_COLOR("plum2", 238, 174, 238), WAVE_RGB_COLOR("plum3", 205, 150, 205), WAVE_RGB_COLOR("plum4", 139, 102, 139), WAVE_RGB_COLOR("powder blue", 176, 224, 230), WAVE_RGB_COLOR("PowderBlue", 176, 224, 230), WAVE_RGB_COLOR("purple", 160, 32, 240), WAVE_RGB_COLOR("purple1", 155, 48, 255), WAVE_RGB_COLOR("purple2", 145, 44, 238), WAVE_RGB_COLOR("purple3", 125, 38, 205), WAVE_RGB_COLOR("purple4", 85, 26, 139), WAVE_RGB_COLOR("red", 255, 0, 0), WAVE_RGB_COLOR("red1", 255, 0, 0), WAVE_RGB_COLOR("red2", 238, 0, 0), WAVE_RGB_COLOR("red3", 205, 0, 0), WAVE_RGB_COLOR("red4", 139, 0, 0), WAVE_RGB_COLOR("rosy brown", 188, 143, 143), WAVE_RGB_COLOR("RosyBrown", 188, 143, 143), WAVE_RGB_COLOR("RosyBrown1", 255, 193, 193), WAVE_RGB_COLOR("RosyBrown2", 238, 180, 180), WAVE_RGB_COLOR("RosyBrown3", 205, 155, 155), WAVE_RGB_COLOR("RosyBrown4", 139, 105, 105), WAVE_RGB_COLOR("royal blue", 65, 105, 225), WAVE_RGB_COLOR("RoyalBlue", 65, 105, 225), WAVE_RGB_COLOR("RoyalBlue1", 72, 118, 255), WAVE_RGB_COLOR("RoyalBlue2", 67, 110, 238), WAVE_RGB_COLOR("RoyalBlue3", 58, 95, 205), WAVE_RGB_COLOR("RoyalBlue4", 39, 64, 139), WAVE_RGB_COLOR("saddle brown", 139, 69, 19), WAVE_RGB_COLOR("SaddleBrown", 139, 69, 19), WAVE_RGB_COLOR("salmon", 250, 128, 114), WAVE_RGB_COLOR("salmon1", 255, 140, 105), WAVE_RGB_COLOR("salmon2", 238, 130, 98), WAVE_RGB_COLOR("salmon3", 205, 112, 84), WAVE_RGB_COLOR("salmon4", 139, 76, 57), WAVE_RGB_COLOR("sandy brown", 244, 164, 96), WAVE_RGB_COLOR("SandyBrown", 244, 164, 96), WAVE_RGB_COLOR("sea green", 46, 139, 87), WAVE_RGB_COLOR("SeaGreen", 46, 139, 87), WAVE_RGB_COLOR("SeaGreen1", 84, 255, 159), WAVE_RGB_COLOR("SeaGreen2", 78, 238, 148), WAVE_RGB_COLOR("SeaGreen3", 67, 205, 128), WAVE_RGB_COLOR("SeaGreen4", 46, 139, 87), WAVE_RGB_COLOR("seashell", 255, 245, 238), WAVE_RGB_COLOR("seashell1", 255, 245, 238), WAVE_RGB_COLOR("seashell2", 238, 229, 222), WAVE_RGB_COLOR("seashell3", 205, 197, 191), WAVE_RGB_COLOR("seashell4", 139, 134, 130), WAVE_RGB_COLOR("sienna", 160, 82, 45), WAVE_RGB_COLOR("sienna1", 255, 130, 71), WAVE_RGB_COLOR("sienna2", 238, 121, 66), WAVE_RGB_COLOR("sienna3", 205, 104, 57), WAVE_RGB_COLOR("sienna4", 139, 71, 38), WAVE_RGB_COLOR("sky blue", 135, 206, 235), WAVE_RGB_COLOR("SkyBlue", 135, 206, 235), WAVE_RGB_COLOR("SkyBlue1", 135, 206, 255), WAVE_RGB_COLOR("SkyBlue2", 126, 192, 238), WAVE_RGB_COLOR("SkyBlue3", 108, 166, 205), WAVE_RGB_COLOR("SkyBlue4", 74, 112, 139), WAVE_RGB_COLOR("slate blue", 106, 90, 205), WAVE_RGB_COLOR("slate gray", 112, 128, 144), WAVE_RGB_COLOR("slate grey", 112, 128, 144), WAVE_RGB_COLOR("SlateBlue", 106, 90, 205), WAVE_RGB_COLOR("SlateBlue1", 131, 111, 255), WAVE_RGB_COLOR("SlateBlue2", 122, 103, 238), WAVE_RGB_COLOR("SlateBlue3", 105, 89, 205), WAVE_RGB_COLOR("SlateBlue4", 71, 60, 139), WAVE_RGB_COLOR("SlateGray", 112, 128, 144), WAVE_RGB_COLOR("SlateGray1", 198, 226, 255), WAVE_RGB_COLOR("SlateGray2", 185, 211, 238), WAVE_RGB_COLOR("SlateGray3", 159, 182, 205), WAVE_RGB_COLOR("SlateGray4", 108, 123, 139), WAVE_RGB_COLOR("SlateGrey", 112, 128, 144), WAVE_RGB_COLOR("snow", 255, 250, 250), WAVE_RGB_COLOR("snow1", 255, 250, 250), WAVE_RGB_COLOR("snow2", 238, 233, 233), WAVE_RGB_COLOR("snow3", 205, 201, 201), WAVE_RGB_COLOR("snow4", 139, 137, 137), WAVE_RGB_COLOR("spring green", 0, 255, 127), WAVE_RGB_COLOR("SpringGreen", 0, 255, 127), WAVE_RGB_COLOR("SpringGreen1", 0, 255, 127), WAVE_RGB_COLOR("SpringGreen2", 0, 238, 118), WAVE_RGB_COLOR("SpringGreen3", 0, 205, 102), WAVE_RGB_COLOR("SpringGreen4", 0, 139, 69), WAVE_RGB_COLOR("steel blue", 70, 130, 180), WAVE_RGB_COLOR("SteelBlue", 70, 130, 180), WAVE_RGB_COLOR("SteelBlue1", 99, 184, 255), WAVE_RGB_COLOR("SteelBlue2", 92, 172, 238), WAVE_RGB_COLOR("SteelBlue3", 79, 148, 205), WAVE_RGB_COLOR("SteelBlue4", 54, 100, 139), WAVE_RGB_COLOR("tan", 210, 180, 140), WAVE_RGB_COLOR("tan1", 255, 165, 79), WAVE_RGB_COLOR("tan2", 238, 154, 73), WAVE_RGB_COLOR("tan3", 205, 133, 63), WAVE_RGB_COLOR("tan4", 139, 90, 43), WAVE_RGB_COLOR("thistle", 216, 191, 216), WAVE_RGB_COLOR("thistle1", 255, 225, 255), WAVE_RGB_COLOR("thistle2", 238, 210, 238), WAVE_RGB_COLOR("thistle3", 205, 181, 205), WAVE_RGB_COLOR("thistle4", 139, 123, 139), WAVE_RGB_COLOR("tomato", 255, 99, 71), WAVE_RGB_COLOR("tomato1", 255, 99, 71), WAVE_RGB_COLOR("tomato2", 238, 92, 66), WAVE_RGB_COLOR("tomato3", 205, 79, 57), WAVE_RGB_COLOR("tomato4", 139, 54, 38), WAVE_RGB_COLOR("turquoise", 64, 224, 208), WAVE_RGB_COLOR("turquoise1", 0, 245, 255), WAVE_RGB_COLOR("turquoise2", 0, 229, 238), WAVE_RGB_COLOR("turquoise3", 0, 197, 205), WAVE_RGB_COLOR("turquoise4", 0, 134, 139), WAVE_RGB_COLOR("violet", 238, 130, 238), WAVE_RGB_COLOR("violet red", 208, 32, 144), WAVE_RGB_COLOR("VioletRed", 208, 32, 144), WAVE_RGB_COLOR("VioletRed1", 255, 62, 150), WAVE_RGB_COLOR("VioletRed2", 238, 58, 140), WAVE_RGB_COLOR("VioletRed3", 205, 50, 120), WAVE_RGB_COLOR("VioletRed4", 139, 34, 82), WAVE_RGB_COLOR("wheat", 245, 222, 179), WAVE_RGB_COLOR("wheat1", 255, 231, 186), WAVE_RGB_COLOR("wheat2", 238, 216, 174), WAVE_RGB_COLOR("wheat3", 205, 186, 150), WAVE_RGB_COLOR("wheat4", 139, 126, 102), WAVE_RGB_COLOR("white", 255, 255, 255), WAVE_RGB_COLOR("white smoke", 245, 245, 245), WAVE_RGB_COLOR("WhiteSmoke", 245, 245, 245), WAVE_RGB_COLOR("yellow", 255, 255, 0), WAVE_RGB_COLOR("yellow green", 154, 205, 50), WAVE_RGB_COLOR("yellow1", 255, 255, 0), WAVE_RGB_COLOR("yellow2", 238, 238, 0), WAVE_RGB_COLOR("yellow3", 205, 205, 0), WAVE_RGB_COLOR("yellow4", 139, 139, 0), WAVE_RGB_COLOR("YellowGreen", 154, 205, 50), }; #define C_ARRAY_SIZE (sizeof(colors)/sizeof(struct wave_rgb_color)) static int compar(const void *v1, const void *v2) { const char *key = (const char *)v1; const struct wave_rgb_color *color = (const struct wave_rgb_color *)v2; return((int)strcasecmp(key, color->name)); } GdkGC *get_gc_from_name(char *str) { struct wave_rgb_color *match; if((match=(struct wave_rgb_color *)bsearch((void *)str, (void *)colors, C_ARRAY_SIZE, sizeof(struct wave_rgb_color), compar))) { if(!match->context) match->context = alloc_color(GLOBALS->wavearea, match->rgb, GLOBALS->wavearea->style->white_gc); return(match->context); } return(NULL); } int get_rgb_from_name(char *str) { struct wave_rgb_color *match; if((match=(struct wave_rgb_color *)bsearch((void *)str, (void *)colors, C_ARRAY_SIZE, sizeof(struct wave_rgb_color), compar))) { return(match->rgb); } else { unsigned char *pnt=(unsigned char *)str; int l=strlen(str); unsigned char ch; int i; unsigned int rc; for(i=0;i='0')&&(ch<='9')) || ((ch>='a')&&(ch<='f')) || ((ch>='A')&&(ch<='F'))) continue; else { #if defined _MSC_VER || defined __MINGW32__ fprintf(stderr, "** gtkwave.ini (line %d): '%s' is an unknown color value; ignoring.\n", GLOBALS->rc_line_no, str); #else fprintf(stderr, "** .gtkwaverc (line %d): '%s' is an unknown color value; ignoring.\n", GLOBALS->rc_line_no, str); #endif return(~0); } } sscanf(str,"%x",&rc); return(rc&0x00ffffff); } } gtkwave-3.3.66/src/vzt.c0000664000076400007640000005332612360623564014375 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2003-2012. * * 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. */ #include #include "globals.h" #include #include "vzt.h" #include "lx2.h" #ifndef _MSC_VER #include #endif #include #include #include #include "symbol.h" #include "vcd.h" #include "lxt.h" #include "lxt2_read.h" #include "vzt_read.h" #include "debug.h" #include "busy.h" #include "hierpack.h" /* * mainline */ TimeType vzt_main(char *fname, char *skip_start, char *skip_end) { int i; struct Node *n; struct symbol *s, *prevsymroot=NULL, *prevsym=NULL; signed char scale; unsigned int numalias = 0; struct symbol *sym_block = NULL; struct Node *node_block = NULL; char **f_name = NULL; GLOBALS->vzt_vzt_c_1 = vzt_rd_init_smp(fname, GLOBALS->num_cpus); if(!GLOBALS->vzt_vzt_c_1) { return(LLDescriptor(0)); /* look at GLOBALS->vzt_vzt_c_1 in caller for success status... */ } /* SPLASH */ splash_create(); vzt_rd_process_blocks_linearly(GLOBALS->vzt_vzt_c_1, 1); /* vzt_rd_set_max_block_mem_usage(vzt, 0); */ scale=(signed char)vzt_rd_get_timescale(GLOBALS->vzt_vzt_c_1); exponent_to_time_scale(scale); GLOBALS->global_time_offset = vzt_rd_get_timezero(GLOBALS->vzt_vzt_c_1); GLOBALS->numfacs=vzt_rd_get_num_facs(GLOBALS->vzt_vzt_c_1); GLOBALS->mvlfacs_vzt_c_3=(struct fac *)calloc_2(GLOBALS->numfacs,sizeof(struct fac)); f_name = calloc_2(F_NAME_MODULUS+1,sizeof(char *)); GLOBALS->vzt_table_vzt_c_1=(struct lx2_entry *)calloc_2(GLOBALS->numfacs, sizeof(struct lx2_entry)); sym_block = (struct symbol *)calloc_2(GLOBALS->numfacs, sizeof(struct symbol)); node_block=(struct Node *)calloc_2(GLOBALS->numfacs,sizeof(struct Node)); for(i=0;inumfacs;i++) { GLOBALS->mvlfacs_vzt_c_3[i].node_alias=vzt_rd_get_fac_rows(GLOBALS->vzt_vzt_c_1, i); node_block[i].msi=vzt_rd_get_fac_msb(GLOBALS->vzt_vzt_c_1, i); node_block[i].lsi=vzt_rd_get_fac_lsb(GLOBALS->vzt_vzt_c_1, i); GLOBALS->mvlfacs_vzt_c_3[i].flags=vzt_rd_get_fac_flags(GLOBALS->vzt_vzt_c_1, i); GLOBALS->mvlfacs_vzt_c_3[i].len=vzt_rd_get_fac_len(GLOBALS->vzt_vzt_c_1, i); } fprintf(stderr, VZT_RDLOAD"Finished building %d facs.\n", GLOBALS->numfacs); /* SPLASH */ splash_sync(1, 5); GLOBALS->first_cycle_vzt_c_3 = (TimeType) vzt_rd_get_start_time(GLOBALS->vzt_vzt_c_1) * GLOBALS->time_scale; GLOBALS->last_cycle_vzt_c_3 = (TimeType) vzt_rd_get_end_time(GLOBALS->vzt_vzt_c_1) * GLOBALS->time_scale; GLOBALS->total_cycles_vzt_c_3 = GLOBALS->last_cycle_vzt_c_3 - GLOBALS->first_cycle_vzt_c_3 + 1; /* do your stuff here..all useful info has been initialized by now */ if(!GLOBALS->hier_was_explicitly_set) /* set default hierarchy split char */ { GLOBALS->hier_delimeter='.'; } if(GLOBALS->numfacs) { char *fnam = vzt_rd_get_facname(GLOBALS->vzt_vzt_c_1, 0); int flen = strlen(fnam); f_name[0]=malloc_2(flen+1); strcpy(f_name[0], fnam); } for(i=0;inumfacs;i++) { char buf[65537]; char *str; struct fac *f; if(i!=(GLOBALS->numfacs-1)) { char *fnam = vzt_rd_get_facname(GLOBALS->vzt_vzt_c_1, i+1); int flen = strlen(fnam); f_name[(i+1)&F_NAME_MODULUS]=malloc_2(flen+1); strcpy(f_name[(i+1)&F_NAME_MODULUS], fnam); } if(i>1) { free_2(f_name[(i-2)&F_NAME_MODULUS]); f_name[(i-2)&F_NAME_MODULUS] = NULL; } if(GLOBALS->mvlfacs_vzt_c_3[i].flags&VZT_RD_SYM_F_ALIAS) { int alias = GLOBALS->mvlfacs_vzt_c_3[i].node_alias; f=GLOBALS->mvlfacs_vzt_c_3+alias; while(f->flags&VZT_RD_SYM_F_ALIAS) { f=GLOBALS->mvlfacs_vzt_c_3+f->node_alias; } numalias++; } else { f=GLOBALS->mvlfacs_vzt_c_3+i; } if((f->len>1)&& (!(f->flags&(VZT_RD_SYM_F_INTEGER|VZT_RD_SYM_F_DOUBLE|VZT_RD_SYM_F_STRING))) ) { int len=sprintf(buf, "%s[%d:%d]", f_name[(i)&F_NAME_MODULUS],node_block[i].msi, node_block[i].lsi); str=malloc_2(len+1); if(!GLOBALS->alt_hier_delimeter) { strcpy(str, buf); } else { strcpy_vcdalt(str, buf, GLOBALS->alt_hier_delimeter); } s=&sym_block[i]; symadd_name_exists_sym_exists(s,str,0); prevsymroot = prevsym = NULL; } else { int gatecmp = (f->len==1) && (!(f->flags&(VZT_RD_SYM_F_INTEGER|VZT_RD_SYM_F_DOUBLE|VZT_RD_SYM_F_STRING))) && (node_block[i].msi!=-1) && (node_block[i].lsi!=-1); int revcmp = gatecmp && (i) && (!strcmp(f_name[(i)&F_NAME_MODULUS], f_name[(i-1)&F_NAME_MODULUS])); if(gatecmp) { int len = sprintf(buf, "%s[%d]", f_name[(i)&F_NAME_MODULUS],node_block[i].msi); str=malloc_2(len+1); if(!GLOBALS->alt_hier_delimeter) { strcpy(str, buf); } else { strcpy_vcdalt(str, buf, GLOBALS->alt_hier_delimeter); } s=&sym_block[i]; symadd_name_exists_sym_exists(s,str,0); if((prevsym)&&(revcmp)&&(!strchr(f_name[(i)&F_NAME_MODULUS], '\\'))) /* allow chaining for search functions.. */ { prevsym->vec_root = prevsymroot; prevsym->vec_chain = s; s->vec_root = prevsymroot; prevsym = s; } else { prevsymroot = prevsym = s; } } else { str=malloc_2(strlen(f_name[(i)&F_NAME_MODULUS])+1); if(!GLOBALS->alt_hier_delimeter) { strcpy(str, f_name[(i)&F_NAME_MODULUS]); } else { strcpy_vcdalt(str, f_name[(i)&F_NAME_MODULUS], GLOBALS->alt_hier_delimeter); } s=&sym_block[i]; symadd_name_exists_sym_exists(s,str,0); prevsymroot = prevsym = NULL; if(f->flags&VZT_RD_SYM_F_INTEGER) { node_block[i].msi=31; node_block[i].lsi=0; GLOBALS->mvlfacs_vzt_c_3[i].len=32; } } } n=&node_block[i]; n->nname=s->name; n->mv.mvlfac = GLOBALS->mvlfacs_vzt_c_3+i; GLOBALS->mvlfacs_vzt_c_3[i].working_node = n; if((f->len>1)||(f->flags&(VZT_RD_SYM_F_DOUBLE|VZT_RD_SYM_F_STRING))) { n->extvals = 1; } n->head.time=-1; /* mark 1st node as negative time */ n->head.v.h_val=AN_X; s->n=n; } for(i=0;i<=F_NAME_MODULUS;i++) { if(f_name[(i)&F_NAME_MODULUS]) { free_2(f_name[(i)&F_NAME_MODULUS]); f_name[(i)&F_NAME_MODULUS] = NULL; } } free_2(f_name); f_name = NULL; /* SPLASH */ splash_sync(2, 5); GLOBALS->facs=(struct symbol **)malloc_2(GLOBALS->numfacs*sizeof(struct symbol *)); if(GLOBALS->fast_tree_sort) { for(i=0;inumfacs;i++) { int len; GLOBALS->facs[i]=&sym_block[i]; if((len=strlen(GLOBALS->facs[i]->name))>GLOBALS->longestname) GLOBALS->longestname=len; } if(numalias) { int idx_lft = 0; int idx_lftmax = GLOBALS->numfacs - numalias; int idx_rgh = GLOBALS->numfacs - numalias; struct symbol **facs_merge=(struct symbol **)malloc_2(GLOBALS->numfacs*sizeof(struct symbol *)); fprintf(stderr, VZT_RDLOAD"Merging in %d aliases.\n", numalias); for(i=0;inumfacs;i++) /* fix possible tail appended aliases by remerging in partial one pass merge sort */ { if(strcmp(GLOBALS->facs[idx_lft]->name, GLOBALS->facs[idx_rgh]->name) <= 0) { facs_merge[i] = GLOBALS->facs[idx_lft++]; if(idx_lft == idx_lftmax) { for(i++;inumfacs;i++) { facs_merge[i] = GLOBALS->facs[idx_rgh++]; } } } else { facs_merge[i] = GLOBALS->facs[idx_rgh++]; if(idx_rgh == GLOBALS->numfacs) { for(i++;inumfacs;i++) { facs_merge[i] = GLOBALS->facs[idx_lft++]; } } } } free_2(GLOBALS->facs); GLOBALS->facs = facs_merge; } /* SPLASH */ splash_sync(3, 5); fprintf(stderr, VZT_RDLOAD"Building facility hierarchy tree.\n"); init_tree(); for(i=0;inumfacs;i++) { int esc = 0; char *subst = GLOBALS->facs[i]->name; char ch; while((ch=(*subst))) { if(ch==GLOBALS->hier_delimeter) { if(esc) *subst = VCDNAM_ESCAPE; } else if(ch=='\\') { esc = 1; GLOBALS->escaped_names_found_vcd_c_1 = 1; } subst++; } build_tree_from_name(GLOBALS->facs[i]->name, i); } /* SPLASH */ splash_sync(4, 5); if(GLOBALS->escaped_names_found_vcd_c_1) { for(i=0;inumfacs;i++) { char *subst, ch; subst=GLOBALS->facs[i]->name; while((ch=(*subst))) { if(ch==VCDNAM_ESCAPE) { *subst=GLOBALS->hier_delimeter; } /* restore back to normal */ subst++; } } } treegraft(&GLOBALS->treeroot); fprintf(stderr, VZT_RDLOAD"Sorting facility hierarchy tree.\n"); treesort(GLOBALS->treeroot, NULL); /* SPLASH */ splash_sync(5, 5); order_facs_from_treesort(GLOBALS->treeroot, &GLOBALS->facs); if(GLOBALS->escaped_names_found_vcd_c_1) { treenamefix(GLOBALS->treeroot); } GLOBALS->facs_are_sorted=1; } else { for(i=0;inumfacs;i++) { char *subst, ch; int len; int esc = 0; GLOBALS->facs[i]=&sym_block[i]; if((len=strlen(subst=GLOBALS->facs[i]->name))>GLOBALS->longestname) GLOBALS->longestname=len; while((ch=(*subst))) { #ifdef WAVE_HIERFIX if(ch==GLOBALS->hier_delimeter) { *subst=(!esc) ? VCDNAM_HIERSORT : VCDNAM_ESCAPE; } /* forces sort at hier boundaries */ #else if((ch==GLOBALS->hier_delimeter)&&(esc)) { *subst = VCDNAM_ESCAPE; } /* forces sort at hier boundaries */ #endif else if(ch=='\\') { esc = 1; GLOBALS->escaped_names_found_vcd_c_1 = 1; } subst++; } } /* SPLASH */ splash_sync(3, 5); fprintf(stderr, VZT_RDLOAD"Sorting facilities at hierarchy boundaries.\n"); wave_heapsort(GLOBALS->facs,GLOBALS->numfacs); #ifdef WAVE_HIERFIX for(i=0;inumfacs;i++) { char *subst, ch; subst=GLOBALS->facs[i]->name; while((ch=(*subst))) { if(ch==VCDNAM_HIERSORT) { *subst=GLOBALS->hier_delimeter; } /* restore back to normal */ subst++; } } #endif GLOBALS->facs_are_sorted=1; /* SPLASH */ splash_sync(4, 5); fprintf(stderr, VZT_RDLOAD"Building facility hierarchy tree.\n"); init_tree(); for(i=0;inumfacs;i++) { char *nf = GLOBALS->facs[i]->name; build_tree_from_name(nf, i); } /* SPLASH */ splash_sync(5, 5); if(GLOBALS->escaped_names_found_vcd_c_1) { for(i=0;inumfacs;i++) { char *subst, ch; subst=GLOBALS->facs[i]->name; while((ch=(*subst))) { if(ch==VCDNAM_ESCAPE) { *subst=GLOBALS->hier_delimeter; } /* restore back to normal */ subst++; } } } treegraft(&GLOBALS->treeroot); treesort(GLOBALS->treeroot, NULL); if(GLOBALS->escaped_names_found_vcd_c_1) { treenamefix(GLOBALS->treeroot); } } GLOBALS->min_time = GLOBALS->first_cycle_vzt_c_3; GLOBALS->max_time=GLOBALS->last_cycle_vzt_c_3; GLOBALS->is_lx2 = LXT2_IS_VZT; if(skip_start || skip_end) { TimeType b_start, b_end; if(!skip_start) b_start = GLOBALS->min_time; else b_start = unformat_time(skip_start, GLOBALS->time_dimension); if(!skip_end) b_end = GLOBALS->max_time; else b_end = unformat_time(skip_end, GLOBALS->time_dimension); if(b_startmin_time) b_start = GLOBALS->min_time; else if(b_start>GLOBALS->max_time) b_start = GLOBALS->max_time; if(b_endmin_time) b_end = GLOBALS->min_time; else if(b_end>GLOBALS->max_time) b_end = GLOBALS->max_time; if(b_start > b_end) { TimeType tmp_time = b_start; b_start = b_end; b_end = tmp_time; } if(!vzt_rd_limit_time_range(GLOBALS->vzt_vzt_c_1, b_start, b_end)) { fprintf(stderr, VZT_RDLOAD"--begin/--end options yield zero blocks, ignoring.\n"); vzt_rd_unlimit_time_range(GLOBALS->vzt_vzt_c_1); } else { GLOBALS->min_time = b_start; GLOBALS->max_time = b_end; } } /* SPLASH */ splash_finalize(); return(GLOBALS->max_time); } /* * vzt callback (only does bits for now) */ static void vzt_callback(struct vzt_rd_trace **lt, lxtint64_t *tim, lxtint32_t *facidx, char **value) { (void)lt; struct HistEnt *htemp = histent_calloc(); struct lx2_entry *l2e = GLOBALS->vzt_table_vzt_c_1+(*facidx); struct fac *f = GLOBALS->mvlfacs_vzt_c_3+(*facidx); GLOBALS->busycnt_vzt_c_2++; if(GLOBALS->busycnt_vzt_c_2==WAVE_BUSY_ITER) { busy_window_refresh(); GLOBALS->busycnt_vzt_c_2 = 0; } /* fprintf(stderr, "%lld %d %s\n", *tim, *facidx, *value); */ if(!(f->flags&(VZT_RD_SYM_F_DOUBLE|VZT_RD_SYM_F_STRING))) { if(f->len>1) { htemp->v.h_vector = (char *)malloc_2(f->len); memcpy(htemp->v.h_vector, *value, f->len); } else { switch(**value) { case '0': htemp->v.h_val = AN_0; break; case '1': htemp->v.h_val = AN_1; break; case 'Z': case 'z': htemp->v.h_val = AN_Z; break; default: htemp->v.h_val = AN_X; break; } } } else if(f->flags&VZT_RD_SYM_F_DOUBLE) { #ifdef WAVE_HAS_H_DOUBLE sscanf(*value, "%lg", &htemp->v.h_double); #else double *d = malloc_2(sizeof(double)); sscanf(*value, "%lg", d); htemp->v.h_vector = (char *)d; #endif htemp->flags = HIST_REAL; } else /* string */ { char *s = malloc_2(strlen(*value)+1); strcpy(s, *value); htemp->v.h_vector = s; htemp->flags = HIST_REAL|HIST_STRING; } htemp->time = (*tim) * (GLOBALS->time_scale); if(l2e->histent_head) { l2e->histent_curr->next = htemp; l2e->histent_curr = htemp; } else { l2e->histent_head = l2e->histent_curr = htemp; } l2e->numtrans++; } /* * this is the black magic that handles aliased signals... */ static void vzt_resolver(nptr np, nptr resolve) { np->extvals = resolve->extvals; np->msi = resolve->msi; np->lsi = resolve->lsi; memcpy(&np->head, &resolve->head, sizeof(struct HistEnt)); np->curr = resolve->curr; np->harray = resolve->harray; np->numhist = resolve->numhist; np->mv.mvlfac=NULL; } /* * actually import a vzt trace but don't do it if it's already been imported */ void import_vzt_trace(nptr np) { struct HistEnt *htemp, *histent_tail; int len, i; struct fac *f; int txidx; nptr nold = np; if(!(f=np->mv.mvlfac)) return; /* already imported */ txidx = f - GLOBALS->mvlfacs_vzt_c_3; if(np->mv.mvlfac->flags&VZT_RD_SYM_F_ALIAS) { txidx = vzt_rd_get_alias_root(GLOBALS->vzt_vzt_c_1, txidx); np = GLOBALS->mvlfacs_vzt_c_3[txidx].working_node; if(!(f=np->mv.mvlfac)) { vzt_resolver(nold, np); return; /* already imported */ } } fprintf(stderr, "Import: %s\n", np->nname); /* new stuff */ len = np->mv.mvlfac->len; if(f->node_alias <= 1) /* sorry, arrays not supported, but vzt doesn't support them yet either */ { vzt_rd_set_fac_process_mask(GLOBALS->vzt_vzt_c_1, txidx); vzt_rd_iter_blocks(GLOBALS->vzt_vzt_c_1, vzt_callback, NULL); vzt_rd_clr_fac_process_mask(GLOBALS->vzt_vzt_c_1, txidx); } histent_tail = htemp = histent_calloc(); if(len>1) { htemp->v.h_vector = (char *)malloc_2(len); for(i=0;iv.h_vector[i] = AN_Z; } else { htemp->v.h_val = AN_Z; /* z */ } htemp->time = MAX_HISTENT_TIME; htemp = histent_calloc(); if(len>1) { htemp->v.h_vector = (char *)malloc_2(len); for(i=0;iv.h_vector[i] = AN_X; } else { htemp->v.h_val = AN_X; /* x */ } htemp->time = MAX_HISTENT_TIME-1; htemp->next = histent_tail; if(GLOBALS->vzt_table_vzt_c_1[txidx].histent_curr) { GLOBALS->vzt_table_vzt_c_1[txidx].histent_curr->next = htemp; htemp = GLOBALS->vzt_table_vzt_c_1[txidx].histent_head; } if(!(f->flags&(VZT_RD_SYM_F_DOUBLE|VZT_RD_SYM_F_STRING))) { if(len>1) { np->head.v.h_vector = (char *)malloc_2(len); for(i=0;ihead.v.h_vector[i] = AN_X; } else { np->head.v.h_val = AN_X; /* x */ } } else { np->head.flags = HIST_REAL; if(f->flags&VZT_RD_SYM_F_STRING) np->head.flags |= HIST_STRING; } { struct HistEnt *htemp2 = histent_calloc(); htemp2->time = -1; if(len>1) { htemp2->v.h_vector = htemp->v.h_vector; } else { htemp2->v.h_val = htemp->v.h_val; } htemp2->next = htemp; htemp = htemp2; GLOBALS->vzt_table_vzt_c_1[txidx].numtrans++; } np->head.time = -2; np->head.next = htemp; np->numhist=GLOBALS->vzt_table_vzt_c_1[txidx].numtrans +2 /*endcap*/ +1 /*frontcap*/; memset(GLOBALS->vzt_table_vzt_c_1+txidx, 0, sizeof(struct lx2_entry)); /* zero it out */ np->curr = histent_tail; np->mv.mvlfac = NULL; /* it's imported and cached so we can forget it's an mvlfac now */ if(nold!=np) { vzt_resolver(nold, np); } } /* * pre-import many traces at once so function above doesn't have to iterate... */ void vzt_set_fac_process_mask(nptr np) { struct fac *f; int txidx; if(!(f=np->mv.mvlfac)) return; /* already imported */ txidx = f-GLOBALS->mvlfacs_vzt_c_3; if(np->mv.mvlfac->flags&VZT_RD_SYM_F_ALIAS) { txidx = vzt_rd_get_alias_root(GLOBALS->vzt_vzt_c_1, txidx); np = GLOBALS->mvlfacs_vzt_c_3[txidx].working_node; if(!(np->mv.mvlfac)) return; /* already imported */ } if(np->mv.mvlfac->node_alias <= 1) /* sorry, arrays not supported, but vzt doesn't support them yet either */ { vzt_rd_set_fac_process_mask(GLOBALS->vzt_vzt_c_1, txidx); GLOBALS->vzt_table_vzt_c_1[txidx].np = np; } } void vzt_import_masked(void) { int txidx, i, cnt; cnt = 0; for(txidx=0;txidxnumfacs;txidx++) { if(vzt_rd_get_fac_process_mask(GLOBALS->vzt_vzt_c_1, txidx)) { cnt++; } } if(!cnt) return; if(cnt>100) { fprintf(stderr, VZT_RDLOAD"Extracting %d traces\n", cnt); } set_window_busy(NULL); vzt_rd_iter_blocks(GLOBALS->vzt_vzt_c_1, vzt_callback, NULL); set_window_idle(NULL); for(txidx=0;txidxnumfacs;txidx++) { if(vzt_rd_get_fac_process_mask(GLOBALS->vzt_vzt_c_1, txidx)) { struct HistEnt *htemp, *histent_tail; struct fac *f = GLOBALS->mvlfacs_vzt_c_3+txidx; int len = f->len; nptr np = GLOBALS->vzt_table_vzt_c_1[txidx].np; histent_tail = htemp = histent_calloc(); if(len>1) { htemp->v.h_vector = (char *)malloc_2(len); for(i=0;iv.h_vector[i] = AN_Z; } else { htemp->v.h_val = AN_Z; /* z */ } htemp->time = MAX_HISTENT_TIME; htemp = histent_calloc(); if(len>1) { htemp->v.h_vector = (char *)malloc_2(len); for(i=0;iv.h_vector[i] = AN_X; } else { htemp->v.h_val = AN_X; /* x */ } htemp->time = MAX_HISTENT_TIME-1; htemp->next = histent_tail; if(GLOBALS->vzt_table_vzt_c_1[txidx].histent_curr) { GLOBALS->vzt_table_vzt_c_1[txidx].histent_curr->next = htemp; htemp = GLOBALS->vzt_table_vzt_c_1[txidx].histent_head; } if(!(f->flags&(VZT_RD_SYM_F_DOUBLE|VZT_RD_SYM_F_STRING))) { if(len>1) { np->head.v.h_vector = (char *)malloc_2(len); for(i=0;ihead.v.h_vector[i] = AN_X; } else { np->head.v.h_val = AN_X; /* x */ } } else { np->head.flags = HIST_REAL; if(f->flags&VZT_RD_SYM_F_STRING) np->head.flags |= HIST_STRING; } { struct HistEnt *htemp2 = histent_calloc(); htemp2->time = -1; if(len>1) { htemp2->v.h_vector = htemp->v.h_vector; } else { htemp2->v.h_val = htemp->v.h_val; } htemp2->next = htemp; htemp = htemp2; GLOBALS->vzt_table_vzt_c_1[txidx].numtrans++; } np->head.time = -2; np->head.next = htemp; np->numhist=GLOBALS->vzt_table_vzt_c_1[txidx].numtrans +2 /*endcap*/ +1 /*frontcap*/; memset(GLOBALS->vzt_table_vzt_c_1+txidx, 0, sizeof(struct lx2_entry)); /* zero it out */ np->curr = histent_tail; np->mv.mvlfac = NULL; /* it's imported and cached so we can forget it's an mvlfac now */ vzt_rd_clr_fac_process_mask(GLOBALS->vzt_vzt_c_1, txidx); } } } gtkwave-3.3.66/src/tcl_np.c0000664000076400007640000004762512360623564015036 0ustar bybellbybell/* * Copyright (c) 2003-2005 Active State Corporation. * See the file LICENSE.TXT for information on usage and redistribution * and for a DISCLAIMER OF ALL WARRANTIES. */ #include #include "globals.h" #include #include #include #include #include "debug.h" #include "tcl_np.h" #include "tcl_helper.h" #if !defined __MINGW32__ && !defined _MSC_VER #include #include #endif #ifdef HAVE_LIBTCL /* ======== Np... Begin */ #ifndef LIB_RUNTIME_DIR # define LIB_RUNTIME_DIR "" #endif # define XP_UNIX 1 /* * Default directory in which to look for Tcl libraries. The * symbol is defined by Makefile. */ static char defaultLibraryDir[sizeof(LIB_RUNTIME_DIR)+200] = LIB_RUNTIME_DIR; #ifdef WIN32 /* #include "shlwapi.h" */ # ifndef TCL_LIB_FILE # define TCL_LIB_FILE "tcl85.dll" # endif /* * Reference to ourselves */ static HINSTANCE nptclInst = NULL; /* *---------------------------------------------------------------------- * * NpLoadLibrary -- * * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ /* me :: path to the current executable */ extern int NpLoadLibrary(HMODULE *tclHandle, char *dllName, int dllNameSize, char *me) { char *envdll, libname[MAX_PATH]; HMODULE handle = (HMODULE) NULL; char path[MAX_PATH], *p ; /* #include */ /* #include */ if( !GetModuleFileName(NULL, path, MAX_PATH) ) { printf("GetModuleFileName() failed\n") ; } else { if((p = strrchr(path,'\\'))) { *(++p) = '\0' ; sprintf(libname, "%s\\tcl%d%d.dll", path, TCL_MAJOR_VERSION, TCL_MINOR_VERSION) ; NpLog("Attempt to load from executable directory '%s'\n", libname) ; if(!(handle = LoadLibrary(libname))) { sprintf(libname, "%s..\\lib\\tcl%d%d.dll", path, TCL_MAJOR_VERSION, TCL_MINOR_VERSION) ; NpLog("Attempt to load from relative lib directory '%s'\n", libname) ; handle = LoadLibrary(libname) ; } } } /* * Try a user-supplied Tcl dll to start with. */ if(!handle) { envdll = getenv("TCL_PLUGIN_DLL"); if (envdll != NULL) { NpLog("Attempt to load Tcl dll (TCL_PLUGIN_DLL) '%s'\n", envdll); handle = LoadLibrary(envdll); if (handle) { memcpy(libname, envdll, MAX_PATH); } } } if (!handle) { /* * Try based on full path. */ snprintf(libname, MAX_PATH, "%stcl%d%d.dll", defaultLibraryDir, TCL_MAJOR_VERSION, TCL_MINOR_VERSION); NpLog("Attempt to load Tcl dll (default) '%s'\n", libname); handle = LoadLibrary(libname); } if (!handle) { /* * Try based on anywhere in the path. */ snprintf(libname, MAX_PATH, "tcl%d%d.dll", TCL_MAJOR_VERSION, TCL_MINOR_VERSION); NpLog("Attempt to load Tcl dll (libpath) '%s'\n", libname); handle = LoadLibrary(libname); } if (!handle) { /* * Try based on ActiveTcl registry entry */ char path[MAX_PATH], vers[MAX_PATH]; DWORD result, size = MAX_PATH; HKEY regKey; # define TCL_REG_DIR_KEY "Software\\ActiveState\\ActiveTcl" result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TCL_REG_DIR_KEY, 0, KEY_READ, ®Key); if (result != ERROR_SUCCESS) { NpLog("Could not access registry \"HKLM\\%s\"\n", TCL_REG_DIR_KEY); result = RegOpenKeyEx(HKEY_CURRENT_USER, TCL_REG_DIR_KEY, 0, KEY_READ, ®Key); if (result != ERROR_SUCCESS) { NpLog("Could not access registry \"HKCU\\%s\"\n", TCL_REG_DIR_KEY); return TCL_ERROR; } } result = RegQueryValueEx(regKey, "CurrentVersion", NULL, NULL, vers, &size); RegCloseKey(regKey); if (result != ERROR_SUCCESS) { NpLog("Could not access registry \"%s\" CurrentVersion\n", TCL_REG_DIR_KEY); return TCL_ERROR; } snprintf(path, MAX_PATH, "%s\\%s", TCL_REG_DIR_KEY, vers); result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, path, 0, KEY_READ, ®Key); if (result != ERROR_SUCCESS) { NpLog("Could not access registry \"%s\"\n", path); return TCL_ERROR; } size = MAX_PATH; result = RegQueryValueEx(regKey, NULL, NULL, NULL, path, &size); RegCloseKey(regKey); if (result != ERROR_SUCCESS) { NpLog("Could not access registry \"%s\" Default\n", TCL_REG_DIR_KEY); return TCL_ERROR; } NpLog("Found current Tcl installation at \"%s\"\n", path); snprintf(libname, MAX_PATH, "%s\\bin\\tcl%d%d.dll", path, TCL_MAJOR_VERSION, TCL_MINOR_VERSION); NpLog("Attempt to load Tcl dll (registry) '%s'\n", libname); handle = LoadLibrary(libname); } if (!handle) { NpLog("NpLoadLibrary: could not find dll '%s'\n", libname); return TCL_ERROR; } *tclHandle = handle; if (dllNameSize > 0) { /* * Use GetModuleFileName to ensure that we have a fully-qualified * path, no matter which route above succeeded. */ if (!GetModuleFileNameA(handle, dllName, dllNameSize)) { int length; char *msgPtr; DWORD code = GetLastError(); length = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char *) &msgPtr, 0, NULL); NpLog3("GetModuleFileNameA ERROR: %d (%s)\n", code, ((length == 0) ? "unknown error" : msgPtr)); if (length > 0) { LocalFree(msgPtr); } } } return TCL_OK; } /* * DLL entry point */ BOOL WINAPI DllMain(HINSTANCE hDLL, DWORD dwReason, LPVOID lpReserved) { switch (dwReason) { case DLL_PROCESS_ATTACH: nptclInst = hDLL; break; case DLL_PROCESS_DETACH: nptclInst = NULL; break; } return TRUE; } #else /* !WIN32 */ # include # ifndef TCL_LIB_FILE # define TCL_LIB_FILE "libtcl" TCL_VERSION SHLIB_SUFFIX # endif # ifndef TCL_KIT_DLL # define TCL_KIT_DLL "tclplugin" SHLIB_SUFFIX # endif /* * In some systems, like SunOS 4.1.3, the RTLD_NOW flag isn't defined * and this argument to dlopen must always be 1. The RTLD_GLOBAL * flag is needed on some systems (e.g. SCO and UnixWare) but doesn't * exist on others; if it doesn't exist, set it to 0 so it has no effect. */ /* *---------------------------------------------------------------------- * NpMyDirectoryPath -- * * Results: * Full directory path to the current executable or NULL *---------------------------------------------------------------------- */ char *NpMyDirectoryPath(char *path, int path_max_len) { int length; char *p ; length = readlink("/proc/self/exe", path, path_max_len); if ((length < 0) || (length >= path_max_len)) { fprintf(stderr, "Error while looking for executable path.\n"); path = NULL ; } else { path[length] = '\0'; /* Strip '@' off the end. */ } if(path) { if((p = strrchr(path, '/'))) *p = '\0' ; else path = NULL ; } return path ; } # ifndef RTLD_NOW # define RTLD_NOW 1 # endif # ifndef RTLD_GLOBAL # define RTLD_GLOBAL 0 # endif /* *---------------------------------------------------------------------- * * NpLoadLibrary -- * * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ EXTERN int NpLoadLibrary(HMODULE *tclHandle, char *dllName, int dllNameSize, char *me) { char *envdll, libname[MAX_PATH]; HMODULE handle = (HMODULE) NULL; char path[MAX_PATH], *p ; *tclHandle = NULL; if(me) strcpy(path, me) ; if(me && (p = strrchr(path,'/'))) { *(++p) = '\0' ; sprintf(libname, "%s%s", path, TCL_LIB_FILE) ; NpLog("Attempt to load from executable directory '%s'\n", libname) ; if(!(handle = dlopen(libname, RTLD_NOW | RTLD_GLOBAL))) { sprintf(libname, "%s../lib/%s", path, TCL_LIB_FILE) ; NpLog("Attempt to load from relative lib directory '%s'\n", libname) ; handle = dlopen(libname, RTLD_NOW | RTLD_GLOBAL) ; } } else { handle = NULL ; } /* * Try a user-supplied Tcl dll to start with. */ if(!handle) { envdll = getenv("TCL_PLUGIN_DLL"); if (envdll != NULL) { NpLog("Attempt to load Tcl dll (TCL_PLUGIN_DLL) '%s'\n", envdll); handle = dlopen(envdll, RTLD_NOW | RTLD_GLOBAL); if (handle) { memcpy(libname, envdll, MAX_PATH); } } } if (!handle) { /* * Try based on full path. */ snprintf(libname, MAX_PATH, "%s%s", defaultLibraryDir, TCL_LIB_FILE); NpLog("Attempt to load Tcl dll (default) '%s'\n", libname); handle = dlopen(libname, RTLD_NOW | RTLD_GLOBAL); } if (!handle) { /* * Try based on anywhere in the path. */ strncpy(libname, TCL_LIB_FILE, MAX_PATH); NpLog("Attempt to load Tcl dll (libpath) '%s'\n", libname); handle = dlopen(libname, RTLD_NOW | RTLD_GLOBAL); } if (!handle) { /* * Try different versions anywhere in the path. */ char *pos; pos = strstr(libname, "tcl")+4; if (*pos == '.') { pos++; } *pos = '9'; /* count down from '8' to '4'*/ while (!handle && (--*pos > '3')) { NpLog("Attempt to load Tcl dll (default_ver) '%s'\n", libname); handle = dlopen(libname, RTLD_NOW | RTLD_GLOBAL); } } if (!handle) { NpPlatformMsg("Failed to load Tcl dll!", "NpCreateMainInterp"); return TCL_ERROR; } *tclHandle = handle; if (dllNameSize > 0) { # ifdef HAVE_DLADDR /* * Use dladdr if possible to get the real libname we are loading. * Grab any symbol - we just need one for reverse mapping */ int (* tcl_Init)(Tcl_Interp *) = (int (*)(Tcl_Interp *)) dlsym(handle, "Tcl_Init"); Dl_info info; if (tcl_Init && dladdr(tcl_Init, &info)) { NpLog3("using dladdr '%s' => '%s'\n", libname, info.dli_fname); snprintf(dllName, dllNameSize, "%s", info.dli_fname); /* format arg was missing */ } else # endif snprintf(dllName, dllNameSize, "%s", libname); /* format arg was missing */ } return TCL_OK; } #endif /* !WIN32 */ /* **** Cinterp */ /* * Static variables in this file: */ static char dllName[MAX_PATH] = ""; #if defined(WIN32) || defined(USE_TCL_STUBS) static HMODULE tclHandle = NULL; /* should be the same in any thread */ static int tclHandleCnt = 0; /* only close on last count */ static int (* tcl_createThread)(Tcl_ThreadId *, Tcl_ThreadCreateProc, ClientData, int, int) = NULL; #endif static Tcl_Interp * (* tcl_createInterp)(void) = NULL; static void (* tcl_findExecutable)(const char *) = NULL; /* * We want the Tcl_InitStubs func static to ourselves - before Tcl * is loaded dynamically and possibly changes it. */ #ifdef USE_TCL_STUBS static CONST char *(* tcl_initStubs)(Tcl_Interp *, CONST char *, int) = Tcl_InitStubs; #endif /* * We possibly have per-thread interpreters, as well as one constant, global * main intepreter. The main interpreter runs from NP_Initialize to * NP_Shutdown. tsd interps are used for each instance, but the main * interpreter will be used if it is in the same thread. * * XXX [hobbs]: While we have made some efforts to allow for multi-thread * safety, this is not currently in use. Firefox (up to 1.5) runs all plugin * instances in one thread, and we have requested the same from the * accompanying pluginhostctrl ActiveX control. The threading bits here are * mostly functional, but require marshalling via a master thread to guarantee * fully thread-safe operation. */ typedef struct ThreadSpecificData { Tcl_Interp *interp; } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; static Tcl_Interp *mainInterp = NULL; /* *---------------------------------------------------------------------- * * NpInitInterp -- * * Initializes a main or instance interpreter. * * Results: * A standard Tcl error code. * * Side effects: * Initializes the interp. * *---------------------------------------------------------------------- */ int NpInitInterp(Tcl_Interp *interp, int install_tk) { Tcl_Preserve((ClientData) interp); /* * Set sharedlib in interp while we are here. This will be used to * base the location of the default pluginX.Y package in the stardll * usage scenario. */ if (Tcl_SetVar2(interp, "plugin", "sharedlib", dllName, TCL_GLOBAL_ONLY) == NULL) { NpPlatformMsg("Failed to set plugin(sharedlib)!", "NpInitInterp"); return TCL_ERROR; } /* * The plugin doesn't directly call Tk C APIs - it's all managed at * the Tcl level, so we can just pkg req Tk here instead of calling * Tk_InitStubs. */ if (TCL_OK != Tcl_Init(interp)) { CONST char *msg = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY); fprintf(stderr, "GTKWAVE | Tcl_Init error: %s\n", msg) ; exit(EXIT_FAILURE); } if (install_tk) { NpLog("Tcl_PkgRequire(\"Tk\", \"%s\", 0)\n", TK_VERSION); if (1 && Tcl_PkgRequire(interp, "Tk", TK_VERSION, 0) == NULL) { CONST char *msg = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY); NpPlatformMsg(msg, "NpInitInterp Tcl_PkgRequire(Tk)"); NpPlatformMsg("Failed to create initialize Tk", "NpInitInterp"); return TCL_ERROR; } } return TCL_OK; } /* *---------------------------------------------------------------------- * * NpCreateMainInterp -- * * Create the main interpreter. * * Results: * The pointer to the main interpreter. * * Side effects: * Will panic if called twice. (Must call DestroyMainInterp in between) * *---------------------------------------------------------------------- */ Tcl_Interp *NpCreateMainInterp(char *me, int install_tk) { (void)me; ThreadSpecificData *tsdPtr; Tcl_Interp *interp; #ifdef USE_TCL_STUBS /* * Determine the libname and version number dynamically */ if (tclHandle == NULL) { /* * First see if some other part didn't already load Tcl. */ /* DLSYM(tclHandle, "Tcl_CreateInterp", Tcl_Interp * (*)(), tcl_createInterp); */ if ((tcl_createInterp == NULL) && (NpLoadLibrary(&tclHandle, dllName, MAX_PATH, me) != TCL_OK)) { NpPlatformMsg("Failed to load Tcl dll!", "NpCreateMainInterp"); return NULL; } NpLog("NpCreateMainInterp: Using dll '%s'\n", dllName); tclHandleCnt++; DLSYM(tclHandle, "Tcl_CreateInterp", Tcl_Interp * (*)(), tcl_createInterp); if (tcl_createInterp == NULL) { #ifndef WIN32 char *error = dlerror(); if (error != NULL) { NpPlatformMsg(error, "NpCreateMainInterp"); } #endif return NULL; } DLSYM(tclHandle, "Tcl_CreateThread", int (*)(Tcl_ThreadId *, Tcl_ThreadCreateProc, ClientData, int, int), tcl_createThread); DLSYM(tclHandle, "Tcl_FindExecutable", void (*)(const char *), tcl_findExecutable); } else { tclHandleCnt++; } #else tcl_createInterp = Tcl_CreateInterp; tcl_findExecutable = Tcl_FindExecutable; #endif if (dllName[0] == '\0') { #ifdef WIN32 GetModuleFileNameA((HINSTANCE) tclHandle, dllName, MAX_PATH); #elif defined(HAVE_DLADDR) Dl_info info; if (dladdr(tcl_createInterp, &info)) { NpLog3("NpCreateMainInterp: using dladdr '%s' => '%s'\n", dllName, info.dli_fname); snprintf(dllName, MAX_PATH, info.dli_fname); } #endif } NpLog("Tcl_FindExecutable(%s)\n", dllName); tcl_findExecutable((dllName[0] == '\0') ? NULL : dllName); /* * We do not operate in a fully threaded environment. The ActiveX * control is set for pure single-apartment threading and Firefox runs * that way by default. Otherwise we would have to create a thread for * the main/master and marshall calls through it. * Tcl_CreateThread(&tid, ThreadCreateProc, clientData, * TCL_THREAD_STACK_DEFAULT, TCL_THREAD_JOINABLE); */ interp = tcl_createInterp(); if (interp == (Tcl_Interp *) NULL) { NpPlatformMsg("Failed to create main interpreter!", "NpCreateMainInterp"); return NULL; } /* * Until Tcl_InitStubs is called, we cannot make any Tcl API * calls without grabbing them by symbol out of the dll. * This will be Tcl_PkgRequire for non-stubs builds. */ #ifdef USE_TCL_STUBS NpLog("Tcl_InitStubs(%p)\n", (void *)interp); if (tcl_initStubs(interp, TCL_VERSION, 0) == NULL) { NpPlatformMsg("Failed to create initialize Tcl stubs!", "NpCreateMainInterp"); return NULL; } #endif /* * From now until shutdown we need this interp alive, hence we * preserve it here and release it at NpDestroyInterp time. */ tsdPtr = TCL_TSD_INIT(&dataKey); tsdPtr->interp = interp; mainInterp = interp; if (NpInitInterp(interp, install_tk) != TCL_OK) { return NULL; } return interp; } /* *---------------------------------------------------------------------- * * NpGetMainInterp -- * * Gets the main interpreter. It must exist or we panic. * * Results: * The main interpreter. * * Side effects: * None. * *---------------------------------------------------------------------- */ Tcl_Interp *NpGetMainInterp() { if (mainInterp == NULL) { NpPanic("BUG: Main interpreter does not exist"); } return mainInterp; } /* *---------------------------------------------------------------------- * * NpDestroyMainInterp -- * * Destroys the main interpreter and performs cleanup actions. * * Results: * None. * * Side effects: * Destroys the main interpreter and unloads Tcl. * *---------------------------------------------------------------------- */ void NpDestroyMainInterp() { /* * We are not going to use the main interpreter after this point * because this may be the last call from the browser. * Could possibly do this as a ThreadExitHandler, but that seems to * have race/order issues for reload in Firefox. */ if (mainInterp) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); NpLog("Tcl_DeleteInterp(%p) MAIN\n", (void *)mainInterp); Tcl_DeleteInterp(mainInterp); Tcl_Release((ClientData) mainInterp); tsdPtr->interp = mainInterp = (Tcl_Interp *) NULL; } /* * We are done using Tcl, so call Tcl_Finalize to get it to unload * cleanly. With stubs, we need to handle dll finalization. */ #ifdef USE_TCL_STUBS tclHandleCnt--; if (tclHandle && tclHandleCnt <= 0) { Tcl_Finalize(); dlclose(tclHandle); tclHandle = NULL; } else { Tcl_ExitThread(0); } #else Tcl_Finalize(); #endif } /* *---------------------------------------------------------------------- * * NpGetInstanceInterp -- * * Gets an instance interpreter. If one doesn't exist, make a new one. * * Results: * The main interpreter. * * Side effects: * None. * *---------------------------------------------------------------------- */ Tcl_Interp *NpGetInstanceInterp(int install_tk) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); Tcl_Interp *interp; if (tsdPtr->interp != NULL) { NpLog("NpGetInstanceInterp - use main interp %p\n", (void *)tsdPtr->interp); return tsdPtr->interp; } interp = Tcl_CreateInterp(); NpLog("NpGetInstanceInterp - create interp %p\n", (void *)interp); if (NpInitInterp(interp, install_tk) != TCL_OK) { NpLog("NpGetInstanceInterp: NpInitInterp(%p) != TCL_OK\n", (void *)interp); return NULL; } /* * We rely on NpInit to inform the user if initialization failed. */ #ifdef nodef if (NpInit(interp) != TCL_OK) { NpLog("NpGetInstanceInterp: NpInit(%p) != TCL_OK\n", (void *)interp); return NULL; } #endif return interp; } /* *---------------------------------------------------------------------- * * NpDestroyInstanceInterp -- * * Destroys an instance interpreter and performs cleanup actions. * * Results: * None. * * Side effects: * Destroys the main interpreter and unloads Tcl. * *---------------------------------------------------------------------- */ void NpDestroyInstanceInterp(Tcl_Interp *interp) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); if (tsdPtr->interp == interp) { NpLog("NpDestroyInstanceInterp(%p) - using main interp\n", (void *)interp); return; } NpLog("Tcl_DeleteInterp(%p) INSTANCE\n", (void *)interp); Tcl_DeleteInterp(interp); Tcl_Release((ClientData) interp); } /* ======== Np... End */ #else static void dummy_compilation_unit(void) { } #endif gtkwave-3.3.66/src/bitvec.c0000664000076400007640000013016612361631225015016 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2012. * * 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. */ /* AIX may need this for alloca to work */ #if defined _AIX #pragma alloca #endif #include "globals.h" #include #include "analyzer.h" #include "symbol.h" #include "lxt.h" #include "lx2.h" #include "lxt2_read.h" #include "vcd.h" #include "extload.h" #include "debug.h" #include "bsearch.h" #include "strace.h" #include "translate.h" #include "ptranslate.h" #include "ttranslate.h" #include "main.h" #include "menu.h" #include "busy.h" #include "hierpack.h" #include /* * attempt to match top vs bottom rather than emit */ char *attempt_vecmatch_2(char *s1, char *s2) { char *s; char *p1, *p2; char *n1=NULL, *n2=NULL; int n1len = 0, n2len = 0; char *pfx = NULL; int pfxlen = 0; int pfxstate = 0; char *sfx = NULL; int sfxlen = 0; int totlen; int idx; if(!strcmp(s1, s2)) { s = malloc_2(strlen(s1)+1); strcpy(s, s1); return(s); } p1 = s1; p2 = s2; while(*p1 && *p2) { if(pfxstate==0) { if(*p1 == *p2) { pfx = p1; pfxlen = p1 - s1 + 1; p1++; p2++; continue; } if(!pfx) return(NULL); if(isdigit((int)(unsigned char)*p1)&&isdigit((int)(unsigned char)*p2)) { n1 = p1; n2 = p2; while(*p1) { if(isdigit((int)(unsigned char)*p1)) { n1len++; } else { break; } p1++; } while(*p2) { if(isdigit((int)(unsigned char)*p2)) { n2len++; } else { break; } p2++; } if(*p1 && *p2) { pfxstate = 1; sfx = p1; continue; } else { break; } } } if(pfxstate==1) { if(*p1 == *p2) { sfxlen++; p1++; p2++; continue; } else { return(NULL); } } return(NULL); } if((*p1)||(*p2)) return(NULL); if((!n1)||(!n2)) return(NULL); /* scan-build : null pointer on strcpy below */ while(pfxlen>1) /* backup if matching a sequence like 20..24 where the 2 matches outside of the left bracket */ { if(isdigit((int)(unsigned char)s1[pfxlen-1])) { pfxlen--; n1--; n1len++; n2--; n2len++; } else { break; } } totlen = pfxlen + 1 + n1len + 1 + n2len + 1 + sfxlen + 1; s = malloc_2(totlen); memcpy(s, s1, pfxlen); idx = pfxlen; if(!(pfxlen && (s1[pfxlen-1]=='['))) { s[idx] = '['; idx++; } memcpy(s+idx, n1, n1len); idx += n1len; s[idx] = ':'; idx++; memcpy(s+idx, n2, n2len); idx += n2len; if((!sfx) || (*sfx != ']')) { s[idx] = ']'; idx++; } if(sfxlen) { memcpy(s+idx, sfx, sfxlen); idx+=sfxlen; } s[idx] = 0; return(s); } char *attempt_vecmatch(char *s1, char *s2) { char *pnt = NULL; if(!s1 || !s2) { return(pnt); } else { int ns1_was_decompressed = HIER_DEPACK_ALLOC; char *ns1 = hier_decompress_flagged(s1, &ns1_was_decompressed); int ns2_was_decompressed = HIER_DEPACK_ALLOC; char *ns2 = hier_decompress_flagged(s2, &ns2_was_decompressed); if(*ns1 && *ns2) { pnt = attempt_vecmatch_2(ns1, ns2); } if(ns1_was_decompressed) free_2(ns1); if(ns2_was_decompressed) free_2(ns2); return(pnt); } } /* * mvlfac resolution */ void import_trace(nptr np) { set_window_busy(NULL); if(GLOBALS->is_lxt) { import_lxt_trace(np); } else if(GLOBALS->extload) /*needs to be ahead of is_lx2 as now can be is_lx2 with FsdbReader */ { import_extload_trace(np); } else if(GLOBALS->is_lx2) { import_lx2_trace(np); } else { fprintf(stderr, "Internal error with mvlfac trace handling, exiting.\n"); exit(255); } set_window_idle(NULL); } /* * turn a Bits structure into a vector with deltas for faster displaying */ bvptr bits2vector(struct Bits *b) { int i; int regions=0; struct Node *n; hptr *h; vptr vhead=NULL, vcurr=NULL, vadd; int numextrabytes; TimeType mintime, lasttime=-1; bvptr bitvec=NULL; TimeType tshift, tmod; if(!b) return(NULL); h=(hptr *)calloc_2(b->nnbits, sizeof(hptr)); numextrabytes=b->nnbits; for(i=0;innbits;i++) { n=b->nodes[i]; h[i]=&(n->head); } while(h[0]) /* should never exit through this point the way we set up histents with trailers now */ { mintime=MAX_HISTENT_TIME; vadd=(vptr)calloc_2(1,sizeof(struct VectorEnt)+numextrabytes); for(i=0;innbits;i++) /* was 1...big mistake */ { tshift = (b->attribs) ? b->attribs[i].shift : 0; if(h[i]->next) { if((h[i]->next->time >= 0) && (h[i]->next->time < MAX_HISTENT_TIME-2)) { tmod = h[i]->next->time+tshift; if(tmod < 0) tmod = 0; if(tmod > MAX_HISTENT_TIME-2) tmod = MAX_HISTENT_TIME-2; } else { tmod = h[i]->next->time; /* don't timeshift endcaps */ } if(tmod < mintime) { mintime = tmod; } } } vadd->time=lasttime; lasttime=mintime; regions++; for(i=0;innbits;i++) { unsigned char enc; tshift = (b->attribs) ? b->attribs[i].shift : 0; if((b->attribs)&&(b->attribs[i].flags & TR_INVERT)) { enc = ((unsigned char)(h[i]->v.h_val)); switch(enc) /* don't remember if it's preconverted in all cases; being conservative is OK */ { case AN_0: case '0': enc = AN_1; break; case AN_1: case '1': enc = AN_0; break; case AN_H: case 'h': case 'H': enc = AN_L; break; case AN_L: case 'l': case 'L': enc = AN_H; break; case 'x': case 'X': enc = AN_X; break; case 'z': case 'Z': enc = AN_Z; break; case 'u': case 'U': enc = AN_U; break; case 'w': case 'W': enc = AN_W; break; default: enc = enc & AN_MSK; break; } } else { enc = ((unsigned char)(h[i]->v.h_val)) & AN_MSK; } vadd->v[i] = enc; if(h[i]->next) { if((h[i]->next->time >= 0) && (h[i]->next->time < MAX_HISTENT_TIME-2)) { tmod = h[i]->next->time+tshift; if(tmod < 0) tmod = 0; if(tmod > MAX_HISTENT_TIME-2) tmod = MAX_HISTENT_TIME-2; } else { tmod = h[i]->next->time; /* don't timeshift endcaps */ } if(tmod < mintime) { mintime = tmod; } if(tmod == mintime) { h[i]=h[i]->next; } } } if(vhead) { vcurr->next=vadd; vcurr=vadd; } else { vhead=vcurr=vadd; } if(mintime==MAX_HISTENT_TIME) break; /* normal bail part */ } vadd=(vptr)calloc_2(1,sizeof(struct VectorEnt)+numextrabytes); vadd->time=MAX_HISTENT_TIME; for(i=0;iv[i]=AN_U; /* formerly 0x55 */ if(vcurr) { vcurr->next=vadd; } /* scan-build */ regions++; bitvec=(bvptr)calloc_2(1,sizeof(struct BitVector)+((regions)*sizeof(vptr))); /* ajb : found "regions" by manual inspection, changed to "regions-1" as array is already [1] */ /* C99, back to regions with [] */ strcpy(bitvec->bvname=(char *)malloc_2(strlen(b->name)+1),b->name); bitvec->nbits=b->nnbits; bitvec->numregions=regions; vcurr=vhead; for(i=0;ivectors[i]=vcurr; if(vcurr) { vcurr=vcurr->next; } /* scan-build */ } return(bitvec); } /* * Make solitary traces from wildcarded signals... */ int maketraces(char *str, char *alias, int quick_return) { char *pnt, *wild; char ch, wild_active=0; int len; int i; int made=0; unsigned int rows = 0; pnt=str; while((ch=*pnt)) { if(ch=='*') { wild_active=1; break; } pnt++; } if(!wild_active) /* short circuit wildcard evaluation with bsearch */ { struct symbol *s; nptr nexp; if(str[0]=='(') { for(i=1;;i++) { if(str[i]==0) return(0); if((str[i]==')')&&(str[i+1])) {i++; break; } } s=symfind(str+i, &rows); if(s) { nexp = ExtractNodeSingleBit(&s->n[rows], atoi(str+1)); if(nexp) { AddNode(nexp, alias); return(~0); } } return(0); } else { if((s=symfind(str, &rows))) { AddNode(&s->n[rows],alias); return(~0); } else { /* in case its a 1-bit bit-blasted signal */ char *str2; int l = strlen(str); str2 = calloc_2(1,l+4); strcpy(str2, str); str2[l] = '['; str2[l+1] = '0'; str2[l+2] = ']'; str2[l+3] = 0; if((s=symfind(str2, &rows))) { AddNode(&s->n[rows],alias); return(~0); } else return(0); } } } while(1) { pnt=str; len=0; while(1) { ch=*pnt++; if(isspace((int)(unsigned char)ch)||(!ch)) break; len++; } if(len) { wild=(char *)calloc_2(1,len+1); memcpy(wild,str,len); wave_regex_compile(wild, WAVE_REGEX_WILD); for(i=0;inumfacs;i++) { if(wave_regex_match(GLOBALS->facs[i]->name, WAVE_REGEX_WILD)) { AddNode(GLOBALS->facs[i]->n,NULL); made=~0; if(quick_return) break; } } free_2(wild); } if(!ch) break; str=pnt; } return(made); } /* * Create a vector from wildcarded signals... */ struct Bits *makevec(char *vec, char *str) { char *pnt, *pnt2, *wild=NULL; char ch, ch2, wild_active; int len, nodepnt=0; int i; struct Node *n[BITATTRIBUTES_MAX]; struct Bits *b=NULL; unsigned int rows = 0; while(1) { pnt=str; len=0; while(1) { ch=*pnt++; if(isspace((int)(unsigned char)ch)||(!ch)) break; len++; } if(len) { wild=(char *)calloc_2(1,len+1); memcpy(wild,str,len); DEBUG(printf("WILD: %s\n",wild)); wild_active=0; pnt2=wild; while((ch2=*pnt2)) { if(ch2=='*') { wild_active=1; break; } pnt2++; } if(!wild_active) /* short circuit wildcard evaluation with bsearch */ { struct symbol *s; if(wild[0]=='(') { nptr nexp; for(i=1;;i++) { if(wild[i]==0) break; if((wild[i]==')')&&(wild[i+1])) { i++; s=symfind(wild+i, &rows); if(s) { nexp = ExtractNodeSingleBit(&s->n[rows], atoi(wild+1)); if(nexp) { n[nodepnt++]=nexp; if(nodepnt==BITATTRIBUTES_MAX) { free_2(wild); goto ifnode; } } } else { char *lp = strrchr(wild+i, '['); if(lp) { char *ns = malloc_2(strlen(wild+i) + 32); char *colon = strchr(lp+1, ':'); int msi, lsi, bval, actual; *lp = 0; bval = atoi(wild+1); if(colon) { msi = atoi(lp+1); lsi = atoi(colon+1); if(lsi > msi) { actual = msi + bval; } else { actual = msi - bval; } } else { actual = bval; /* punt */ } sprintf(ns, "%s[%d]", wild+i, actual); *lp = '['; s=symfind(ns, &rows); if(s) { nexp =&s->n[rows]; if(nexp) { n[nodepnt++]=nexp; if(nodepnt==BITATTRIBUTES_MAX) { free_2(wild); goto ifnode; } } } free_2(ns); } } break; } } } else { if((s=symfind(wild, &rows))) { n[nodepnt++]=&s->n[rows]; if(nodepnt==BITATTRIBUTES_MAX) { free_2(wild); goto ifnode; } } } } else { wave_regex_compile(wild, WAVE_REGEX_WILD); for(i=GLOBALS->numfacs-1;i>=0;i--) /* to keep vectors in little endian hi..lo order */ { if(wave_regex_match(GLOBALS->facs[i]->name, WAVE_REGEX_WILD)) { n[nodepnt++]=GLOBALS->facs[i]->n; if(nodepnt==BITATTRIBUTES_MAX) { free_2(wild); goto ifnode; } } } } free_2(wild); } if(!ch) break; str=pnt; } ifnode: if(nodepnt) { b=(struct Bits *)calloc_2(1,sizeof(struct Bits)+(nodepnt)*sizeof(struct Node *)); for(i=0;inodes[i]=n[i]; if(n[i]->mv.mvlfac) import_trace(n[i]); } b->nnbits=nodepnt; strcpy(b->name=(char *)malloc_2(strlen(vec)+1),vec); } return(b); } /* * Create an annotated (b->attribs) vector from stranded signals... */ struct Bits *makevec_annotated(char *vec, char *str) { char *pnt, *wild=NULL; char ch; int len, nodepnt=0; int i; struct Node *n[BITATTRIBUTES_MAX]; struct BitAttributes ba[BITATTRIBUTES_MAX]; struct Bits *b=NULL; int state = 0; unsigned int rows = 0; memset(ba, 0, sizeof(ba)); /* scan-build */ while(1) { pnt=str; len=0; while(1) { ch=*pnt++; if(isspace((int)(unsigned char)ch)||(!ch)) break; len++; } if(len) { wild=(char *)calloc_2(1,len+1); memcpy(wild,str,len); DEBUG(printf("WILD: %s\n",wild)); if(state==1) { ba[nodepnt-1].shift = atoi_64(wild); state++; goto fw; } else if(state==2) { sscanf(wild, "%x", &ba[nodepnt-1].flags); state = 0; goto fw; } state++; /* no wildcards for annotated! */ { struct symbol *s; if(nodepnt==BITATTRIBUTES_MAX) { free_2(wild); goto ifnode; } if(wild[0]=='(') { nptr nexp; for(i=1;;i++) { if(wild[i]==0) break; if((wild[i]==')')&&(wild[i+1])) { i++; s=symfind(wild+i, &rows); if(s) { nexp = ExtractNodeSingleBit(&s->n[rows], atoi(wild+1)); if(nexp) { n[nodepnt++]=nexp; if(nodepnt==BITATTRIBUTES_MAX) { free_2(wild); goto ifnode; } } } else { char *lp = strrchr(wild+i, '['); if(lp) { char *ns = malloc_2(strlen(wild+i) + 32); char *colon = strchr(lp+1, ':'); int msi, lsi, bval, actual; *lp = 0; bval = atoi(wild+1); if(colon) { msi = atoi(lp+1); lsi = atoi(colon+1); if(lsi > msi) { actual = msi + bval; } else { actual = msi - bval; } } else { actual = bval; /* punt */ } sprintf(ns, "%s[%d]", wild+i, actual); *lp = '['; s=symfind(ns, &rows); if(s) { nexp =&s->n[rows]; if(nexp) { n[nodepnt++]=nexp; if(nodepnt==BITATTRIBUTES_MAX) { free_2(wild); goto ifnode; } } } free_2(ns); } } break; } } } else { if((s=symfind(wild, &rows))) { n[nodepnt++]=&s->n[rows]; } } } fw: free_2(wild); } if(!ch) break; str=pnt; } ifnode: if(nodepnt) { b=(struct Bits *)calloc_2(1,sizeof(struct Bits)+(nodepnt)*sizeof(struct Node *)); b->attribs = calloc_2(nodepnt, sizeof(struct BitAttributes)); for(i=0;inodes[i]=n[i]; if(n[i]->mv.mvlfac) import_trace(n[i]); b->attribs[i].shift = ba[i].shift; b->attribs[i].flags = ba[i].flags; } b->nnbits=nodepnt; strcpy(b->name=(char *)malloc_2(strlen(vec)+1),vec); } return(b); } /* * Create a vector from selected_status signals... */ struct Bits *makevec_selected(char *vec, int numrows, char direction) { int nodepnt=0; int i; struct Node *n[BITATTRIBUTES_MAX]; struct Bits *b=NULL; if(!direction) for(i=GLOBALS->numfacs-1;i>=0;i--) /* to keep vectors in hi..lo order */ { if(get_s_selected(GLOBALS->facs[i])) { n[nodepnt++]=GLOBALS->facs[i]->n; if((nodepnt==BITATTRIBUTES_MAX)||(numrows==nodepnt)) break; } } else for(i=0;inumfacs;i++) /* to keep vectors in lo..hi order */ { if(get_s_selected(GLOBALS->facs[i])) { n[nodepnt++]=GLOBALS->facs[i]->n; if((nodepnt==BITATTRIBUTES_MAX)||(numrows==nodepnt)) break; } } if(nodepnt) { b=(struct Bits *)calloc_2(1,sizeof(struct Bits)+(nodepnt)*sizeof(struct Node *)); for(i=0;inodes[i]=n[i]; if(n[i]->mv.mvlfac) import_trace(n[i]); } b->nnbits=nodepnt; strcpy(b->name=(char *)malloc_2(strlen(vec)+1),vec); } return(b); } /* * add vector made in previous function */ int add_vector_selected(char *alias, int numrows, char direction) { bvptr v=NULL; bptr b=NULL; if((b=makevec_selected(alias, numrows, direction))) { if((v=bits2vector(b))) { v->bits=b; /* only needed for savefile function */ AddVector(v, NULL); free_2(b->name); b->name=NULL; return(v!=NULL); } else { free_2(b->name); if(b->attribs) free_2(b->attribs); free_2(b); } } return(v!=NULL); } /***********************************************************************************/ /* * Create a vector from a range of signals...currently the single * bit facility_name[x] case never gets hit, but may be used in the * future... */ struct Bits *makevec_chain(char *vec, struct symbol *sym, int len) { int nodepnt=0, nodepnt_rev; int i; struct Node **n; struct Bits *b=NULL; struct symbol *symhi = NULL, *symlo = NULL; char hier_delimeter2; if(!GLOBALS->vcd_explicit_zero_subscripts) /* 0==yes, -1==no */ { hier_delimeter2=GLOBALS->hier_delimeter; } else { hier_delimeter2='['; } n=(struct Node **)wave_alloca(len*sizeof(struct Node *)); memset(n, 0, len*sizeof(struct Node *)); /* scan-build */ if(!GLOBALS->autocoalesce_reversal) /* normal case for MTI */ { symhi=sym; while(sym) { symlo=sym; n[nodepnt++]=sym->n; sym=sym->vec_chain; } } else /* for verilog XL */ { nodepnt_rev=len; symlo=sym; while(sym) { nodepnt++; symhi=sym; n[--nodepnt_rev]=sym->n; sym=sym->vec_chain; } } if(nodepnt) { b=(struct Bits *)calloc_2(1,sizeof(struct Bits)+(nodepnt)*sizeof(struct Node *)); for(i=0;inodes[i]=n[i]; if(n[i]->mv.mvlfac) import_trace(n[i]); } b->nnbits=nodepnt; if(vec) { strcpy(b->name=(char *)malloc_2(strlen(vec)+1),vec); } else { char *s1, *s2; int s1_was_packed = HIER_DEPACK_ALLOC, s2_was_packed = HIER_DEPACK_ALLOC; int root1len=0, root2len=0; int l1, l2; s1=symhi->n->nname; s2=symlo->n->nname; if(GLOBALS->do_hier_compress) { s1 = hier_decompress_flagged(s1, &s1_was_packed); s2 = hier_decompress_flagged(s2, &s2_was_packed); } l1=strlen(s1); for(i=l1-1;i>=0;i--) { if(s1[i]==hier_delimeter2) { root1len=i+1; break; } } l2=strlen(s2); for(i=l2-1;i>=0;i--) { if(s2[i]==hier_delimeter2) { root2len=i+1; break; } } if((root1len!=root2len)||(!root1len)||(!root2len)|| (strncasecmp(s1,s2,root1len))) { if(symlo!=symhi) { if(!b->attribs) { char *aname = attempt_vecmatch(s1, s2); if(aname) b->name = aname; else { strcpy(b->name=(char *)malloc_2(8+1),""); } } else { char *aname = attempt_vecmatch(s1, s2); if(aname) b->name = aname; else { strcpy(b->name=(char *)malloc_2(15+1),""); } } } else { strcpy(b->name=(char *)malloc_2(l1+1),s1); } } else { int add1, add2, totallen; add1=l1-root1len; add2=l2-root2len; if(GLOBALS->vcd_explicit_zero_subscripts==-1) { add1--; add2--; } if(symlo!=symhi) { unsigned char fixup1 = 0, fixup2 = 0; totallen= root1len -1 /* zap HIER_DELIMETER */ +1 /* add [ */ +add1 /* left value */ +1 /* add : */ +add2 /* right value */ +1 /* add ] */ +1 /* add 0x00 */ ; if(GLOBALS->vcd_explicit_zero_subscripts==-1) { fixup1=*(s1+l1-1); *(s1+l1-1)=0; fixup2=*(s2+l2-1); *(s2+l2-1)=0; } b->name=(char *)malloc_2(totallen); strncpy(b->name,s1,root1len-1); sprintf(b->name+root1len-1,"[%s:%s]",s1+root1len, s2+root2len); if(GLOBALS->vcd_explicit_zero_subscripts==-1) { *(s1+l1-1)=fixup1; *(s2+l2-1)=fixup2; } } else { unsigned char fixup1 = 0; totallen= root1len -1 /* zap HIER_DELIMETER */ +1 /* add [ */ +add1 /* left value */ +1 /* add ] */ +1 /* add 0x00 */ ; if(GLOBALS->vcd_explicit_zero_subscripts==-1) { fixup1=*(s1+l1-1); *(s1+l1-1)=0; } b->name=(char *)malloc_2(totallen); strncpy(b->name,s1,root1len-1); sprintf(b->name+root1len-1,"[%s]",s1+root1len); if(GLOBALS->vcd_explicit_zero_subscripts==-1) { *(s1+l1-1)=fixup1; } } } if(GLOBALS->do_hier_compress) { if(s2_was_packed) free_2(s2); if(s1_was_packed) free_2(s1); } } } return(b); } /* * add vector made in previous function */ int add_vector_chain(struct symbol *s, int len) { bvptr v=NULL; bptr b=NULL; if(len>1) { if((b=makevec_chain(NULL, s, len))) { if((v=bits2vector(b))) { v->bits=b; /* only needed for savefile function */ AddVector(v, NULL); free_2(b->name); b->name=NULL; return(v!=NULL); } else { free_2(b->name); if(b->attribs) free_2(b->attribs); free_2(b); } } return(v!=NULL); } else { return(AddNode(s->n,NULL)); } } /***********************************************************************************/ /* * Create a vector from a range of signals...currently the single * bit facility_name[x] case never gets hit, but may be used in the * future... */ struct Bits *makevec_range(char *vec, int lo, int hi, char direction) { int nodepnt=0; int i; struct Node *n[BITATTRIBUTES_MAX]; struct Bits *b=NULL; if(!direction) for(i=hi;i>=lo;i--) /* to keep vectors in hi..lo order */ { n[nodepnt++]=GLOBALS->facs[i]->n; if(nodepnt==BITATTRIBUTES_MAX) break; } else for(i=lo;i<=hi;i++) /* to keep vectors in lo..hi order */ { n[nodepnt++]=GLOBALS->facs[i]->n; if(nodepnt==BITATTRIBUTES_MAX) break; } if(nodepnt) { b=(struct Bits *)calloc_2(1,sizeof(struct Bits)+(nodepnt)*sizeof(struct Node *)); for(i=0;inodes[i]=n[i]; if(n[i]->mv.mvlfac) import_trace(n[i]); } b->nnbits=nodepnt; if(vec) { strcpy(b->name=(char *)malloc_2(strlen(vec)+1),vec); } else { char *s1, *s2; int s1_was_packed = HIER_DEPACK_ALLOC, s2_was_packed = HIER_DEPACK_ALLOC; int root1len=0, root2len=0; int l1, l2; if(!direction) { s1=GLOBALS->facs[hi]->n->nname; s2=GLOBALS->facs[lo]->n->nname; } else { s1=GLOBALS->facs[lo]->n->nname; s2=GLOBALS->facs[hi]->n->nname; } if(GLOBALS->do_hier_compress) { s1 = hier_decompress_flagged(s1, &s1_was_packed); s2 = hier_decompress_flagged(s2, &s2_was_packed); } l1=strlen(s1); for(i=l1-1;i>=0;i--) { if(s1[i]==GLOBALS->hier_delimeter) { root1len=i+1; break; } } l2=strlen(s2); for(i=l2-1;i>=0;i--) { if(s2[i]==GLOBALS->hier_delimeter) { root2len=i+1; break; } } if((root1len!=root2len)||(!root1len)||(!root2len)|| (strncasecmp(s1,s2,root1len))) { if(lo!=hi) { if(!b->attribs) { char *aname = attempt_vecmatch(s1, s2); if(aname) b->name = aname; else { strcpy(b->name=(char *)malloc_2(8+1),""); } } else { char *aname = attempt_vecmatch(s1, s2); if(aname) b->name = aname; else { strcpy(b->name=(char *)malloc_2(15+1),""); } } } else { strcpy(b->name=(char *)malloc_2(l1+1),s1); } } else { int add1, add2, totallen; add1=l1-root1len; add2=l2-root2len; if(lo!=hi) { totallen= root1len -1 /* zap HIER_DELIMETER */ +1 /* add [ */ +add1 /* left value */ +1 /* add : */ +add2 /* right value */ +1 /* add ] */ +1 /* add 0x00 */ ; b->name=(char *)malloc_2(totallen); strncpy(b->name,s1,root1len-1); sprintf(b->name+root1len-1,"[%s:%s]",s1+root1len, s2+root2len); } else { totallen= root1len -1 /* zap HIER_DELIMETER */ +1 /* add [ */ +add1 /* left value */ +1 /* add ] */ +1 /* add 0x00 */ ; b->name=(char *)malloc_2(totallen); strncpy(b->name,s1,root1len-1); sprintf(b->name+root1len-1,"[%s]",s1+root1len); } } if(GLOBALS->do_hier_compress) { if(s2_was_packed) free_2(s2); if(s1_was_packed) free_2(s1); } } } return(b); } /* * add vector made in previous function */ int add_vector_range(char *alias, int lo, int hi, char direction) { bvptr v=NULL; bptr b=NULL; if(lo!=hi) { if((b=makevec_range(alias, lo, hi, direction))) { if((v=bits2vector(b))) { v->bits=b; /* only needed for savefile function */ AddVector(v, NULL); free_2(b->name); b->name=NULL; return(v!=NULL); } else { free_2(b->name); if(b->attribs) free_2(b->attribs); free_2(b); } } return(v!=NULL); } else { return(AddNode(GLOBALS->facs[lo]->n,NULL)); } } /* * splits facility name into signal and bitnumber */ void facsplit(char *str, int *len, int *number) { char *ptr; char *numptr=NULL; char ch; ptr=str; while((ch=*ptr)) { if((ch>='0')&&(ch<='9')) { if(!numptr) numptr=ptr; } else numptr=NULL; ptr++; } if(numptr) { *number=atoi(numptr); *len=numptr-str; } else { *number=0; *len=ptr-str; } } /* * compares two facilities a la strcmp but preserves * numbers for comparisons * * there are two flavors..the slow and accurate to any * arbitrary number of digits version (first) and the * fast one good to 2**31-1. we default to the faster * version since there's probably no real need to * process ints larger than two billion anyway... */ #ifdef WAVE_USE_SIGCMP_INFINITE_PRECISION #if __STDC_VERSION__ < 199901L inline #endif int sigcmp_2(char *s1, char *s2) { char *n1, *n2; unsigned char c1, c2; int len1, len2; for(;;) { c1=(unsigned char)*s1; c2=(unsigned char)*s2; if((c1==0)&&(c2==0)) return(0); if((c1>='0')&&(c1<='9')&&(c2>='0')&&(c2<='9')) { n1=s1; n2=s2; len1=len2=0; do { len1++; c1=(unsigned char)*(n1++); } while((c1>='0')&&(c1<='9')); if(!c1) n1--; do { len2++; c2=(unsigned char)*(n2++); } while((c2>='0')&&(c2<='9')); if(!c2) n2--; do { if(len1==len2) { c1=(unsigned char)*(s1++); len1--; c2=(unsigned char)*(s2++); len2--; } else if(len1='0')&&(c1>='0')) { u1=(int)(c1&15); u2=(int)(c2&15); while(((c2=(unsigned char)*s2)>='0')&&(c2<='9')) { u2*=10; u2+=(unsigned int)(c2&15); s2++; } while(((c2=(unsigned char)*s1)>='0')&&(c2<='9')) { u1*=10; u1+=(unsigned int)(c2&15); s1++; } if(u1==u2) continue; else return((int)u1-(int)u2); } else { if(c1!=c2) return((int)c1-(int)c2); } } } #endif int sigcmp(char *s1, char *s2) { int rc = sigcmp_2(s1, s2); if(!rc) { rc = strcmp(s1, s2); /* to handle leading zero "0" vs "00" cases ... we provide a definite order so bsearch doesn't fail */ } return(rc); } #ifndef __linux__ /* * heapsort algorithm. this typically outperforms quicksort. note * that glibc will use a modified mergesort if memory is available, so * under linux use the stock qsort instead. */ static struct symbol **hp; static void heapify(int i, int heap_size) { int l, r; int largest; struct symbol *t; int maxele=heap_size/2-1; /* points to where heapswaps don't matter anymore */ for(;;) { l=2*i+1; r=l+1; if((lname,hp[i]->name)>0)) { largest=l; } else { largest=i; } if((rname,hp[largest]->name)>0)) { largest=r; } if(i!=largest) { t=hp[i]; hp[i]=hp[largest]; hp[largest]=t; if(largest<=maxele) { i=largest; } else { break; } } else { break; } } } void wave_heapsort(struct symbol **a, int num) { int i; int indx=num-1; struct symbol *t; hp=a; for(i=(num/2-1);i>0;i--) /* build facs into having heap property */ { heapify(i,num); } for(;;) { if(indx) heapify(0,indx+1); DEBUG(printf("%s\n", a[0]->name)); if(indx!=0) { t=a[0]; /* sort in place by doing a REVERSE sort and */ a[0]=a[indx]; /* swapping the front and back of the tree.. */ a[indx--]=t; } else { break; } } } #else static int qssigcomp(const void *v1, const void *v2) { struct symbol *a1 = *((struct symbol **)v1); struct symbol *a2 = *((struct symbol **)v2); return(sigcmp(a1->name, a2->name)); } void wave_heapsort(struct symbol **a, int num) { qsort(a, num, sizeof(struct symbol *), qssigcomp); } #endif /* * Malloc/Create a name from a range of signals starting from vec_root...currently the single * bit facility_name[x] case never gets hit, but may be used in the * future... */ char *makename_chain(struct symbol *sym) { int i; struct symbol *symhi = NULL, *symlo = NULL; char hier_delimeter2; char *name=NULL; char *s1, *s2; int s1_was_packed = HIER_DEPACK_ALLOC, s2_was_packed = HIER_DEPACK_ALLOC; int root1len=0, root2len=0; int l1, l2; if(!sym) { fprintf(stderr, "Internal error '%s' line %d, exiting.\n", __FILE__, __LINE__); exit(255); } if(!GLOBALS->vcd_explicit_zero_subscripts) /* 0==yes, -1==no */ { hier_delimeter2=GLOBALS->hier_delimeter; } else { hier_delimeter2='['; } if(!GLOBALS->autocoalesce_reversal) /* normal case for MTI */ { symhi=sym; symlo=sym; /* scan-build */ while(sym) { symlo=sym; sym=sym->vec_chain; } } else /* for verilog XL */ { symlo=sym; symhi=sym; /* scan-build */ while(sym) { symhi=sym; sym=sym->vec_chain; } } s1=hier_decompress_flagged(symhi->n->nname, &s1_was_packed); s2=hier_decompress_flagged(symlo->n->nname, &s2_was_packed); l1=strlen(s1); for(i=l1-1;i>=0;i--) { if(s1[i]==hier_delimeter2) { root1len=i+1; break; } } l2=strlen(s2); for(i=l2-1;i>=0;i--) { if(s2[i]==hier_delimeter2) { root2len=i+1; break; } } if((root1len!=root2len)||(!root1len)||(!root2len)|| (strncasecmp(s1,s2,root1len))) { if(symlo!=symhi) { char *aname = attempt_vecmatch(s1, s2); if(aname) name = aname; else { strcpy(name=(char *)malloc_2(8+1),""); } } else { strcpy(name=(char *)malloc_2(l1+1),s1); } } else { int add1, add2, totallen; add1=l1-root1len; add2=l2-root2len; if(GLOBALS->vcd_explicit_zero_subscripts==-1) { add1--; add2--; } if(symlo!=symhi) { unsigned char fixup1 = 0, fixup2 = 0; totallen= root1len -1 /* zap HIER_DELIMETER */ +1 /* add [ */ +add1 /* left value */ +1 /* add : */ +add2 /* right value */ +1 /* add ] */ +1 /* add 0x00 */ ; if(GLOBALS->vcd_explicit_zero_subscripts==-1) { fixup1=*(s1+l1-1); *(s1+l1-1)=0; fixup2=*(s2+l2-1); *(s2+l2-1)=0; } name=(char *)malloc_2(totallen); strncpy(name,s1,root1len-1); sprintf(name+root1len-1,"[%s:%s]",s1+root1len, s2+root2len); if(GLOBALS->vcd_explicit_zero_subscripts==-1) { *(s1+l1-1)=fixup1; *(s2+l2-1)=fixup2; } } else { unsigned char fixup1 = 0; totallen= root1len -1 /* zap HIER_DELIMETER */ +1 /* add [ */ +add1 /* left value */ +1 /* add ] */ +1 /* add 0x00 */ ; if(GLOBALS->vcd_explicit_zero_subscripts==-1) { fixup1=*(s1+l1-1); *(s1+l1-1)=0; } name=(char *)malloc_2(totallen); strncpy(name,s1,root1len-1); sprintf(name+root1len-1,"[%s]",s1+root1len); if(GLOBALS->vcd_explicit_zero_subscripts==-1) { *(s1+l1-1)=fixup1; } } } if(s1_was_packed) { free_2(s1); } if(s2_was_packed) { free_2(s2); } return(name); } /******************************************************************/ eptr ExpandNode(nptr n) { int width; int msb, lsb, delta; int actual; hptr h, htemp; int i, j; nptr *narray; char *nam; int offset, len; eptr rc=NULL; exptr exp1; if(n->mv.mvlfac) import_trace(n); if(!n->extvals) { DEBUG(fprintf(stderr, "Nothing to expand\n")); } else { char *namex; int was_packed = HIER_DEPACK_ALLOC; msb = n->msi; lsb = n->lsi; if(msb>lsb) { width = msb - lsb + 1; delta = -1; } else { width = lsb - msb + 1; delta = 1; } actual = msb; narray=(nptr *)malloc_2(width*sizeof(nptr)); rc = malloc_2(sizeof(ExpandInfo)); rc->narray = narray; rc->msb = msb; rc->lsb = lsb; rc->width = width; if(GLOBALS->do_hier_compress) { namex = hier_decompress_flagged(n->nname, &was_packed); } else { namex = n->nname; } offset = strlen(namex); for(i=offset-1;i>=0;i--) { if(namex[i]=='[') break; } if(i>-1) offset=i; nam=(char *)wave_alloca(offset+20+30); memcpy(nam, namex, offset); if(was_packed) { free_2(namex); } if(!n->harray) /* make quick array lookup for aet display--normally this is done in addnode */ { hptr histpnt; int histcount; hptr *harray; histpnt=&(n->head); histcount=0; while(histpnt) { histcount++; histpnt=histpnt->next; } n->numhist=histcount; if(!(n->harray=harray=(hptr *)malloc_2(histcount*sizeof(hptr)))) { fprintf( stderr, "Out of memory, can't add to analyzer\n"); return(NULL); } histpnt=&(n->head); for(i=0;inext; } } h=&(n->head); while(h) { if(h->flags & (HIST_REAL|HIST_STRING)) return(NULL); h=h->next; } DEBUG(fprintf(stderr, "Expanding: (%d to %d) for %d bits over %d entries.\n", msb, lsb, width, n->numhist)); for(i=0;iarray_height) { len = offset + strlen(nam+offset); sprintf(nam+len, "{%d}", n->this_row); } #endif len = offset + strlen(nam+offset); narray[i]->nname = (char *)malloc_2(len+1); strcpy(narray[i]->nname, nam); exp1 = (exptr) calloc_2(1, sizeof(struct ExpandReferences)); exp1->parent=n; /* point to parent */ exp1->parentbit=i; exp1->actual = actual; actual += delta; narray[i]->expansion = exp1; /* can be safely deleted if expansion set like here */ } for(i=0;inumhist;i++) { h=n->harray[i]; if((h->timemin_time)||(h->time>GLOBALS->max_time)) { for(j=0;jcurr) { htemp = (hptr) calloc_2(1, sizeof(struct HistEnt)); htemp->v.h_val = AN_X; /* 'x' */ htemp->time = h->time; narray[j]->curr->next = htemp; narray[j]->curr = htemp; } else { narray[j]->head.v.h_val = AN_X; /* 'x' */ narray[j]->head.time = h->time; narray[j]->curr = &(narray[j]->head); } narray[j]->numhist++; } } else { for(j=0;jv.h_vector[j]; switch(val) { case '0': val = AN_0; break; case '1': val = AN_1; break; case 'x': case 'X': val = AN_X; break; case 'z': case 'Z': val = AN_Z; break; case 'h': case 'H': val = AN_H; break; case 'l': case 'L': val = AN_L; break; case 'u': case 'U': val = AN_U; break; case 'w': case 'W': val = AN_W; break; case '-': val = AN_DASH; break; default: break; /* leave val alone as it's been converted already.. */ } if(narray[j]->curr->v.h_val != val) /* curr will have been established already by 'x' at time: -1 */ { htemp = (hptr) calloc_2(1, sizeof(struct HistEnt)); htemp->v.h_val = val; htemp->time = h->time; narray[j]->curr->next = htemp; narray[j]->curr = htemp; narray[j]->numhist++; } } } } for(i=0;iharray = (hptr *)calloc_2(narray[i]->numhist, sizeof(hptr)); htemp = &(narray[i]->head); for(j=0;jnumhist;j++) { narray[i]->harray[j] = htemp; htemp = htemp->next; } } } return(rc); } /******************************************************************/ nptr ExtractNodeSingleBit(nptr n, int bit) { int lft, rgh; hptr h, htemp; int i, j; int actual; nptr np; char *nam; int offset, len; exptr exp1; if(n->mv.mvlfac) import_trace(n); if(!n->extvals) { DEBUG(fprintf(stderr, "Nothing to expand\n")); return(NULL); } else { char *namex; int was_packed = HIER_DEPACK_ALLOC; if(n->lsi > n->msi) { rgh = n->lsi; lft = n->msi; actual = n->msi + bit; } else { rgh = n->msi; lft = n->lsi; actual = n->msi - bit; } if((actual>rgh)||(actualdo_hier_compress) { namex = hier_decompress_flagged(n->nname, &was_packed); } else { namex = n->nname; } offset = strlen(namex); for(i=offset-1;i>=0;i--) { if(namex[i]=='[') break; } if(i>-1) offset=i; nam=(char *)wave_alloca(offset+20); memcpy(nam, namex, offset); if(was_packed) { free_2(namex); } if(!n->harray) /* make quick array lookup for aet display--normally this is done in addnode */ { hptr histpnt; int histcount; hptr *harray; histpnt=&(n->head); histcount=0; while(histpnt) { histcount++; histpnt=histpnt->next; } n->numhist=histcount; if(!(n->harray=harray=(hptr *)malloc_2(histcount*sizeof(hptr)))) { DEBUG(fprintf( stderr, "Out of memory, can't add to analyzer\n")); return(NULL); } histpnt=&(n->head); for(i=0;inext; } } h=&(n->head); while(h) { if(h->flags & (HIST_REAL|HIST_STRING)) return(NULL); h=h->next; } DEBUG(fprintf(stderr, "Extracting: (%d to %d) for offset #%d over %d entries.\n", n->msi, n->lsi, bit, n->numhist)); np = (nptr)calloc_2(1, sizeof(struct Node)); sprintf(nam+offset, "[%d]", actual); #ifdef WAVE_ARRAY_SUPPORT if(n->array_height) { len = offset + strlen(nam+offset); sprintf(nam+len, "{%d}", n->this_row); } #endif len = offset + strlen(nam+offset); np->nname = (char *)malloc_2(len+1); strcpy(np->nname, nam); exp1 = (exptr) calloc_2(1, sizeof(struct ExpandReferences)); exp1->parent=n; /* point to parent */ exp1->parentbit=bit; exp1->actual=actual; /* actual bitnum in [] */ np->expansion = exp1; /* can be safely deleted if expansion set like here */ for(i=0;inumhist;i++) { h=n->harray[i]; if((h->timemin_time)||(h->time>GLOBALS->max_time)) { if(np->curr) { htemp = (hptr) calloc_2(1, sizeof(struct HistEnt)); htemp->v.h_val = AN_X; /* 'x' */ htemp->time = h->time; np->curr->next = htemp; np->curr = htemp; } else { np->head.v.h_val = AN_X; /* 'x' */ np->head.time = h->time; np->curr = &(np->head); } np->numhist++; } else { unsigned char val = h->v.h_vector[bit]; switch(val) { case '0': val = AN_0; break; case '1': val = AN_1; break; case 'x': case 'X': val = AN_X; break; case 'z': case 'Z': val = AN_Z; break; case 'h': case 'H': val = AN_H; break; case 'l': case 'L': val = AN_L; break; case 'u': case 'U': val = AN_U; break; case 'w': case 'W': val = AN_W; break; case '-': val = AN_DASH; break; default: break; /* leave val alone as it's been converted already.. */ } if(np->curr->v.h_val != val) /* curr will have been established already by 'x' at time: -1 */ { htemp = (hptr) calloc_2(1, sizeof(struct HistEnt)); htemp->v.h_val = val; htemp->time = h->time; np->curr->next = htemp; np->curr = htemp; np->numhist++; } } } np->harray = (hptr *)calloc_2(np->numhist, sizeof(hptr)); htemp = &(np->head); for(j=0;jnumhist;j++) { np->harray[j] = htemp; htemp = htemp->next; } return(np); } } /******************************************************************/ /* * this only frees nodes created via expansion in ExpandNode() functions above! */ void DeleteNode(nptr n) { int i; if(n->expansion) { if(n->expansion->refcnt==0) { for(i=1;inumhist;i++) /* 1st is actually part of the Node! */ { free_2(n->harray[i]); } free_2(n->harray); free_2(n->expansion); free_2(n->nname); free_2(n); } else { n->expansion->refcnt--; } } } gtkwave-3.3.66/src/currenttime.h0000664000076400007640000000354512341266475016121 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2010 * * 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. */ #include "globals.h" #ifndef CURRENTTIME_H #define CURRENTTIME_H #include #include #include #include #include "analyzer.h" #include "regex_wave.h" #include "translate.h" #define WAVE_INF_SCALING (0.5) #define WAVE_SI_UNITS " munpfaz" struct blackout_region_t { struct blackout_region_t *next; TimeType bstart, bend; }; /* currenttime.c protos */ void fractional_timescale_fix(char *); void update_markertime(TimeType val); void update_maxtime(TimeType val); void update_basetime(TimeType val); void update_currenttime(TimeType val); void update_maxmarker_labels(void); void reformat_time(char *buf, TimeType val, char dim); void reformat_time_simple(char *buf, TimeType val, char dim); TimeType unformat_time(const char *buf, char dim); void time_trunc_set(void); TimeType time_trunc(TimeType t); void exponent_to_time_scale(signed char scale); /* other protos / definitions */ #include "baseconvert.h" #include "edgebuttons.h" #include "entry.h" #include "fetchbuttons.h" #include "file.h" #include "fonts.h" #include "help.h" #include "interp.h" #include "logfile.h" #include "markerbox.h" #include "menu.h" #include "mouseover.h" #include "mouseover_sigs.h" #include "pagebuttons.h" #include "renderopt.h" #include "search.h" #include "shiftbuttons.h" #include "showchange.h" #include "signalwindow.h" #include "simplereq.h" #include "status.h" #include "strace.h" #include "timeentry.h" #include "tree.h" #include "treesearch.h" #include "vcd_partial.h" #include "wavewindow.h" #include "zoombuttons.h" #include "hiersearch.h" #endif gtkwave-3.3.66/src/color.c0000664000076400007640000000424512341266475014667 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2011. * * 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. */ #include "globals.h" #include #include "color.h" #include "debug.h" /* * return graphics context with tuple's color or * a fallback context. Note that if tuple<0, * the fallback will be used! */ GdkGC *alloc_color(GtkWidget *widget, int tuple, GdkGC *fallback) { GdkColor color; GdkGC *gc; int red, green, blue; red= (tuple>>16)&0x000000ff; green=(tuple>>8) &0x000000ff; blue= (tuple) &0x000000ff; if(tuple>=0) if((gc=gdk_gc_new(widget->window))) { struct wave_gcchain_t *wg = calloc_2(1, sizeof(struct wave_gcchain_t)); color.red=red*(65535/255); color.blue=blue*(65535/255); color.green=green*(65535/255); color.pixel=(gulong)(tuple&0x00ffffff); gdk_color_alloc(gtk_widget_get_colormap(widget),&color); gdk_gc_set_foreground(gc,&color); wg->next = GLOBALS->wave_gcchain; /* remember allocated ones only, not fallbacks */ wg->gc = gc; GLOBALS->wave_gcchain = wg; return(gc); } return(fallback); } void dealloc_all_gcs(void) { struct wave_gcchain_t *wg = GLOBALS->wave_gcchain; while(wg) { if(wg->gc) { gdk_gc_destroy(wg->gc); wg->gc = NULL; } wg = wg->next; } } void set_alternate_gcs(GdkGC *ctx, GdkGC *ctx_fill) { GLOBALS->gc.gc_low_wavewindow_c_1 = ctx; GLOBALS->gc.gc_high_wavewindow_c_1 = ctx; GLOBALS->gc.gc_trans_wavewindow_c_1 = ctx; GLOBALS->gc.gc_0_wavewindow_c_1 = ctx; GLOBALS->gc.gc_1_wavewindow_c_1 = ctx; GLOBALS->gc.gc_vbox_wavewindow_c_1 = ctx; GLOBALS->gc.gc_vtrans_wavewindow_c_1 = ctx; if(!GLOBALS->keep_xz_colors) { GLOBALS->gc.gc_mid_wavewindow_c_1 = ctx; GLOBALS->gc.gc_xfill_wavewindow_c_1 = ctx_fill; GLOBALS->gc.gc_x_wavewindow_c_1 = ctx; GLOBALS->gc.gc_ufill_wavewindow_c_1 = ctx_fill; GLOBALS->gc.gc_u_wavewindow_c_1 = ctx; GLOBALS->gc.gc_wfill_wavewindow_c_1 = ctx_fill; GLOBALS->gc.gc_w_wavewindow_c_1 = ctx; GLOBALS->gc.gc_dashfill_wavewindow_c_1 = ctx_fill; GLOBALS->gc.gc_dash_wavewindow_c_1 = ctx; } } gtkwave-3.3.66/src/showchange.h0000664000076400007640000000064211523063250015664 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2010 * * 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. */ #ifndef WAVE_SHOWCHANGE_H #define WAVE_SHOWCHANGE_H void showchange(char *title, Trptr t, GtkSignalFunc func); #endif gtkwave-3.3.66/src/pipeio.c0000664000076400007640000001110712341266475015031 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2005-2010 * * 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. */ #include "globals.h" #include #include "pipeio.h" #if defined _MSC_VER || defined __MINGW32__ static void cleanup_p(struct pipe_ctx *p) { if(p->g_hChildStd_IN_Rd) CloseHandle(p->g_hChildStd_IN_Rd); if(p->g_hChildStd_IN_Wr) CloseHandle(p->g_hChildStd_IN_Wr); if(p->g_hChildStd_OUT_Rd) CloseHandle(p->g_hChildStd_OUT_Rd); if(p->g_hChildStd_OUT_Wr) CloseHandle(p->g_hChildStd_OUT_Wr); free_2(p); } struct pipe_ctx *pipeio_create(char *execappname, char *args) { SECURITY_ATTRIBUTES saAttr; STARTUPINFO siStartInfo; BOOL bSuccess = FALSE; TCHAR *szCmdline; struct pipe_ctx *p = calloc_2(1, sizeof(struct pipe_ctx)); saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); /* Set the bInheritHandle flag so pipe handles are inherited */ saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; if (!CreatePipe(&p->g_hChildStd_OUT_Rd, &p->g_hChildStd_OUT_Wr, &saAttr, 0)) { cleanup_p(p); return(NULL); } if (!SetHandleInformation(p->g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0)) { cleanup_p(p); return(NULL); } if (!CreatePipe(&p->g_hChildStd_IN_Rd, &p->g_hChildStd_IN_Wr, &saAttr, 0)) { cleanup_p(p); return(NULL); } if (!SetHandleInformation(p->g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0)) { cleanup_p(p); return(NULL); } memset(&siStartInfo, 0, sizeof(STARTUPINFO)); siStartInfo.cb = sizeof(STARTUPINFO); /* siStartInfo.hStdError = p->g_hChildStd_OUT_Wr; (not sure how to redirect, for example GetStdHandle(STD_ERROR_HANDLE) */ siStartInfo.hStdOutput = p->g_hChildStd_OUT_Wr; siStartInfo.hStdInput = p->g_hChildStd_IN_Rd; siStartInfo.dwFlags |= STARTF_USESTDHANDLES; if (strlen(args) == 0) { szCmdline = strdup_2(execappname); } else { szCmdline = malloc_2(strlen(execappname) + 1 + strlen(args) + 1); sprintf(szCmdline, "%s %s", execappname, args); } bSuccess = CreateProcess(NULL, szCmdline, /* command line */ NULL, /* process security attributes */ NULL, /* primary thread security attributes */ TRUE, /* handles are inherited */ 0, /* creation flags */ NULL, /* use parent's environment */ NULL, /* use parent's current directory */ &siStartInfo, /* STARTUPINFO pointer */ &p->piProcInfo); /* receives PROCESS_INFORMATION */ free_2(szCmdline); if(!bSuccess) { cleanup_p(p); return(NULL); } else { /* CloseHandle(p->piProcInfo.hProcess); */ /* CloseHandle(p->piProcInfo.hThread); */ } return(p); } void pipeio_destroy(struct pipe_ctx *p) { CloseHandle(p->g_hChildStd_IN_Rd); CloseHandle(p->g_hChildStd_IN_Wr); CloseHandle(p->g_hChildStd_OUT_Rd); CloseHandle(p->g_hChildStd_OUT_Wr); TerminateProcess(p->piProcInfo.hProcess, 0); free_2(p); } #else #include struct pipe_ctx *pipeio_create(char *execappname, char *arg) { int rc1, rc2; pid_t pid, wave_pid; int filedes_w[2]; int filedes_r[2]; struct pipe_ctx *p; int mystat; FILE *fsin=NULL, *fsout = NULL; rc1 = pipe(filedes_r); if(rc1) return(NULL); rc2 = pipe(filedes_w); if(rc2) { close(filedes_r[0]); close(filedes_r[1]); return(NULL); } wave_pid = getpid(); if((pid=fork())) { fsout = fdopen(filedes_w[1], "wb"); fsin = fdopen(filedes_r[0], "rb"); close(filedes_w[0]); close(filedes_r[1]); } else { dup2(filedes_w[0], 0); dup2(filedes_r[1], 1); close(filedes_w[1]); close(filedes_r[0]); #ifdef _AIX /* NOTE: doesn't handle ctrl-c or killing, but I don't want to mess with this right now for AIX */ if ((!arg)||(strlen(arg) == 0)) { execl(execappname, execappname, NULL); } else { execl(execappname, execappname, arg, NULL); } exit(0); #else if((pid=fork())) /* monitor process */ { do { sleep(1); } while(wave_pid == getppid()); /* inherited by init yet? */ kill(pid, SIGKILL); waitpid(pid, &mystat, 0); exit(0); } else /* actual helper */ { if (strlen(arg) == 0) { execl(execappname, execappname, NULL); } else { execl(execappname, execappname, arg, NULL); } exit(0); } #endif } p = malloc_2(sizeof(struct pipe_ctx)); p->pid = pid; p->sin = fsin; p->sout = fsout; p->fd0 = filedes_r[0]; /* for potential select() ops */ p->fd1 = filedes_w[1]; /* ditto */ return(p); } void pipeio_destroy(struct pipe_ctx *p) { /* #ifdef _AIX */ int mystat; kill(p->pid, SIGKILL); waitpid(p->pid, &mystat, 0); /* #endif */ fclose(p->sout); fclose(p->sin); free_2(p); } #endif gtkwave-3.3.66/src/regex_wave.h0000664000076400007640000000131511570577234015706 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2004. * * 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. */ #include "globals.h" #ifndef REGEX_WAVE_H #define REGEX_WAVE_H enum WaveRegexTypes { WAVE_REGEX_SEARCH, WAVE_REGEX_TREE, WAVE_REGEX_WILD, WAVE_REGEX_DND, WAVE_REGEX_TOTAL }; int wave_regex_compile(char *regex, int which); int wave_regex_match(char *str, int which); void *wave_regex_alloc_compile(char *regex); int wave_regex_alloc_match(void *mreg, char *str); void wave_regex_alloc_free(void *pnt); #endif gtkwave-3.3.66/src/fetchbuttons.c0000664000076400007640000001224712360623564016257 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999. * * 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. */ #include "globals.h" #include #include "currenttime.h" #include "pixmaps.h" #include "debug.h" void fetch_left(GtkWidget *text, gpointer data) { (void)text; (void)data; TimeType newlo; char fromstr[32]; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nFetch Left"); help_text( " decreases the \"From\" time, which allows more of the trace" " to be displayed if the \"From\" and \"To\" times do not match" " the actual bounds of the trace." ); return; } DEBUG(printf("Fetch Left\n")); newlo=(GLOBALS->tims.first)-GLOBALS->fetchwindow; if(newlo<=GLOBALS->min_time) newlo=GLOBALS->min_time; reformat_time(fromstr, newlo, GLOBALS->time_dimension); gtk_entry_set_text(GTK_ENTRY(GLOBALS->from_entry),fromstr); if(newlo<(GLOBALS->tims.last)) { GLOBALS->tims.first=newlo; if(GLOBALS->tims.starttims.first) GLOBALS->tims.start=GLOBALS->tims.first; time_update(); } } void fetch_right(GtkWidget *text, gpointer data) { (void)text; (void)data; TimeType newhi; char tostr[32]; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nFetch Right"); help_text( " increases the \"To\" time, which allows more of the trace" " to be displayed if the \"From\" and \"To\" times do not match" " the actual bounds of the trace." ); return; } DEBUG(printf("Fetch Right\n")); newhi=(GLOBALS->tims.last)+GLOBALS->fetchwindow; if(newhi>=GLOBALS->max_time) newhi=GLOBALS->max_time; reformat_time(tostr, newhi, GLOBALS->time_dimension); gtk_entry_set_text(GTK_ENTRY(GLOBALS->to_entry),tostr); if(newhi>(GLOBALS->tims.first)) { GLOBALS->tims.last=newhi; time_update(); } } void discard_left(GtkWidget *text, gpointer data) { (void)text; (void)data; TimeType newlo; char tostr[32]; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nDiscard Left"); help_text( " increases the \"From\" time, which allows less of the trace" " to be displayed." ); return; } DEBUG(printf("Discard Left\n")); newlo=(GLOBALS->tims.first)+GLOBALS->fetchwindow; if(newlo<(GLOBALS->tims.last)) { reformat_time(tostr, newlo, GLOBALS->time_dimension); gtk_entry_set_text(GTK_ENTRY(GLOBALS->from_entry),tostr); GLOBALS->tims.first=newlo; time_update(); } } void discard_right(GtkWidget *text, gpointer data) { (void)text; (void)data; TimeType newhi; char tostr[32]; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nDiscard Right"); help_text( " decreases the \"To\" time, which allows less of the trace" " to be displayed." ); return; } DEBUG(printf("Discard Right\n")); newhi=(GLOBALS->tims.last)-GLOBALS->fetchwindow; if(newhi>(GLOBALS->tims.first)) { reformat_time(tostr, newhi, GLOBALS->time_dimension); gtk_entry_set_text(GTK_ENTRY(GLOBALS->to_entry),tostr); GLOBALS->tims.last=newhi; time_update(); } } /* Create actual buttons */ GtkWidget * create_fetch_buttons (void) { GtkWidget *table; GtkWidget *table2; GtkWidget *frame; GtkWidget *main_vbox; GtkWidget *b1; GtkWidget *b2; GtkWidget *pixmapwid1, *pixmapwid2; GtkTooltips *tooltips; tooltips=gtk_tooltips_new_2(); gtk_tooltips_set_delay_2(tooltips,1500); pixmapwid1=gtk_pixmap_new(GLOBALS->larrow_pixmap, GLOBALS->larrow_mask); gtk_widget_show(pixmapwid1); pixmapwid2=gtk_pixmap_new(GLOBALS->rarrow_pixmap, GLOBALS->rarrow_mask); gtk_widget_show(pixmapwid2); /* Create a table to hold the text widget and scrollbars */ table = gtk_table_new (1, 1, FALSE); main_vbox = gtk_vbox_new (FALSE, 1); gtk_container_border_width (GTK_CONTAINER (main_vbox), 1); gtk_container_add (GTK_CONTAINER (table), main_vbox); frame = gtk_frame_new ("Fetch "); gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0); gtk_widget_show (frame); gtk_widget_show (main_vbox); table2 = gtk_table_new (2, 1, FALSE); b1 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b1), pixmapwid1); gtk_table_attach (GTK_TABLE (table2), b1, 0, 1, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); gtk_signal_connect_object (GTK_OBJECT (b1), "clicked", GTK_SIGNAL_FUNC(fetch_left), GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(tooltips, b1, "Decrease 'From' Time", NULL); gtk_widget_show(b1); b2 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b2), pixmapwid2); gtk_table_attach (GTK_TABLE (table2), b2, 0, 1, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); gtk_signal_connect_object (GTK_OBJECT (b2), "clicked", GTK_SIGNAL_FUNC(fetch_right), GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(tooltips, b2, "Increase 'To' Time", NULL); gtk_widget_show(b2); gtk_container_add (GTK_CONTAINER (frame), table2); gtk_widget_show(table2); return(table); } gtkwave-3.3.66/src/shiftbuttons.h0000664000076400007640000000073611523063250016276 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2010 * * 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. */ #ifndef WAVE_SHIFTBUTTONS_H #define WAVE_SHIFTBUTTONS_H void service_left_shift(GtkWidget *text, gpointer data); void service_right_shift(GtkWidget *text, gpointer data); #endif gtkwave-3.3.66/src/ae2.h0000664000076400007640000000220112341266475014213 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2004-2011. * * 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. */ #ifndef WAVE_AE2RDR_H #define WAVE_AE2RDR_H #ifdef HAVE_INTTYPES_H #include #endif #include "vcd.h" #include "lx2.h" #ifdef AET2_IS_PRESENT #include #endif #ifdef AET2_ALIASDB_IS_PRESENT #include #endif #define AET2_RDLOAD "AE2LOAD | " #define AE2_MAX_NAME_LENGTH 2048 #define AE2_MAXFACLEN 65536 #define AE2_MAX_ROWS 16384 #define WAVE_ADB_ALLOC_POOL_SIZE (1024 * 1024) #define WAVE_ADB_ALLOC_ALTREQ_SIZE (4 * 1024) #ifdef WAVE_USE_STRUCT_PACKING #pragma pack(push) #pragma pack(1) #endif struct ae2_ncycle_autosort { struct ae2_ncycle_autosort *next; }; #ifdef WAVE_USE_STRUCT_PACKING #pragma pack(pop) #endif TimeType ae2_main(char *fname, char *skip_start, char *skip_end); void import_ae2_trace(nptr np); void ae2_set_fac_process_mask(nptr np); void ae2_import_masked(void); #endif gtkwave-3.3.66/src/vcd_saver.h0000664000076400007640000000160111570577234015524 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2005. * * 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. */ #include "globals.h" #ifndef VCD_SAVER_H #define VCD_SAVER_H #include "vcd.h" #include "strace.h" enum vcd_export_typ { WAVE_EXPORT_VCD, WAVE_EXPORT_LXT, WAVE_EXPORT_TIM, WAVE_EXPORT_TRANS }; enum vcd_saver_rc { VCDSAV_OK, VCDSAV_EMPTY, VCDSAV_FILE_ERROR }; enum vcd_saver_tr_datatype { VCDSAV_IS_BIN, VCDSAV_IS_HEX, VCDSAV_IS_TEXT }; int save_nodes_to_export(const char *fname, int export_typ); int do_timfile_save(const char *fname); int save_nodes_to_trans(FILE *trans, Trptr t); /* from helpers/scopenav.c */ extern void free_hier(void); extern char *output_hier(char *name); #endif gtkwave-3.3.66/src/tree_component.h0000664000076400007640000000104011570577234016566 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2011. * * 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. */ #include "debug.h" #ifdef _WAVE_HAVE_JUDY #include #else #include "jrb.h" #endif #ifndef WAVE_TREE_COMP_H #define WAVE_TREE_COMP_H void iter_through_comp_name_table(void); int add_to_comp_name_table(const char *s, int slen); #endif gtkwave-3.3.66/src/vcd_saver.c0000664000076400007640000007762012523241774015531 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2005-2014. * * 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. */ #include #include "globals.h" #include "vcd_saver.h" #include "helpers/lxt_write.h" #include "ghw.h" #include "hierpack.h" #include static void w32redirect_fprintf(FILE *sfd, const char *format, ...) { va_list ap; va_start(ap, format); vfprintf(sfd, format, ap); va_end(ap); } /* * unconvert trace data back to VCD representation...use strict mode for LXT */ static unsigned char analyzer_demang(int strict, unsigned char ch) { if(!strict) { if(ch < AN_COUNT) { return(AN_STR[ch]); } else { return(ch); } } else { if(ch < AN_COUNT) { return(AN_STR4ST[ch]); } else { return(ch); } } } /* * generate a vcd identifier for a given facindx */ static char *vcdid(unsigned int value, int export_typ) { char *pnt = GLOBALS->buf_vcd_saver_c_3; unsigned int vmod; if(export_typ != WAVE_EXPORT_TRANS) { value++; for(;;) { if((vmod = (value % 94))) { *(pnt++) = (char)(vmod + 32); } else { *(pnt++) = '~'; value -= 94; } value = value / 94; if(!value) { break; } } *pnt = 0; } else { sprintf(pnt, "%d", value); } return(GLOBALS->buf_vcd_saver_c_3); } static char *vcd_truncate_bitvec(char *s) { char l, r; r=*s; if(r=='1') { return s; } else { s++; } for(;;s++) { l=r; r=*s; if(!r) return (s-1); if(l!=r) { return(((l=='0')&&(r=='1'))?s:s-1); } } } /************************ splay ************************/ /* * integer splay */ typedef struct vcdsav_tree_node vcdsav_Tree; struct vcdsav_tree_node { vcdsav_Tree * left, * right; nptr item; int val; hptr hist; int len; union { void *p; long l; int i; } handle; /* future expansion for adding other writers that need pnt/handle info */ unsigned char flags; }; static long vcdsav_cmp_l(void *i, void *j) { intptr_t il = (intptr_t)i, jl = (intptr_t)j; return(il - jl); } static vcdsav_Tree * vcdsav_splay (void *i, vcdsav_Tree * t) { /* Simple top down splay, not requiring i to be in the tree t. */ /* What it does is described above. */ vcdsav_Tree N, *l, *r, *y; int dir; if (t == NULL) return t; N.left = N.right = NULL; l = r = &N; for (;;) { dir = vcdsav_cmp_l(i, t->item); if (dir < 0) { if (t->left == NULL) break; if (vcdsav_cmp_l(i, t->left->item)<0) { y = t->left; /* rotate right */ t->left = y->right; y->right = t; t = y; if (t->left == NULL) break; } r->left = t; /* link right */ r = t; t = t->left; } else if (dir > 0) { if (t->right == NULL) break; if (vcdsav_cmp_l(i, t->right->item)>0) { y = t->right; /* rotate left */ t->right = y->left; y->left = t; t = y; if (t->right == NULL) break; } l->right = t; /* link left */ l = t; t = t->right; } else { break; } } l->right = t->left; /* assemble */ r->left = t->right; t->left = N.right; t->right = N.left; return t; } static vcdsav_Tree * vcdsav_insert(void *i, vcdsav_Tree * t, int val, unsigned char flags, hptr h) { /* Insert i into the tree t, unless it's already there. */ /* Return a pointer to the resulting tree. */ vcdsav_Tree * n; int dir; n = (vcdsav_Tree *) calloc_2(1, sizeof (vcdsav_Tree)); if (n == NULL) { fprintf(stderr, "vcdsav_insert: ran out of memory, exiting.\n"); exit(255); } n->item = i; n->val = val; n->flags = flags; n->hist = h; if (t == NULL) { n->left = n->right = NULL; return n; } t = vcdsav_splay(i,t); dir = vcdsav_cmp_l(i,t->item); if (dir<0) { n->left = t->left; n->right = t; t->left = NULL; return n; } else if (dir>0) { n->right = t->right; n->left = t; t->right = NULL; return n; } else { /* We get here if it's already in the tree */ /* Don't add it again */ free_2(n); return t; } } /************************ heap ************************/ static int hpcmp(vcdsav_Tree *hp1, vcdsav_Tree *hp2) { hptr n1 = hp1->hist; hptr n2 = hp2->hist; TimeType t1, t2; if(n1) t1 = n1->time; else t1 = MAX_HISTENT_TIME; if(n2) t2 = n2->time; else t2 = MAX_HISTENT_TIME; if(t1 == t2) { return(0); } else if(t1 > t2) { return(-1); } else { return(1); } } static void recurse_build(vcdsav_Tree *vt, vcdsav_Tree ***hp) { if(vt->left) recurse_build(vt->left, hp); **hp = vt; *hp = (*hp) + 1; if(vt->right) recurse_build(vt->right, hp); } /* * heapify algorithm...used to grab the next value change */ static void heapify(int i, int heap_size) { int l, r; int largest; vcdsav_Tree *t; int maxele=heap_size/2-1; /* points to where heapswaps don't matter anymore */ for(;;) { l=2*i+1; r=l+1; if((lhp_vcd_saver_c_1[l],GLOBALS->hp_vcd_saver_c_1[i])>0)) { largest=l; } else { largest=i; } if((rhp_vcd_saver_c_1[r],GLOBALS->hp_vcd_saver_c_1[largest])>0)) { largest=r; } if(i!=largest) { t=GLOBALS->hp_vcd_saver_c_1[i]; GLOBALS->hp_vcd_saver_c_1[i]=GLOBALS->hp_vcd_saver_c_1[largest]; GLOBALS->hp_vcd_saver_c_1[largest]=t; if(largest<=maxele) { i=largest; } else { break; } } else { break; } } } /* * mainline */ int save_nodes_to_export_generic(FILE *trans_file, Trptr trans_head, const char *fname, int export_typ) { Trptr t = trans_head ? trans_head : GLOBALS->traces.first; int nodecnt = 0; vcdsav_Tree *vt = NULL; vcdsav_Tree **hp_clone = GLOBALS->hp_vcd_saver_c_1; nptr n; /* ExtNode *e; */ /* int msi, lsi; */ int i; TimeType prevtime = LLDescriptor(-1); time_t walltime; struct strace *st = NULL; int strace_append = 0; int max_len = 1; char *row_data = NULL; struct lt_trace *lt = NULL; int lxt = (export_typ == WAVE_EXPORT_LXT); if(export_typ == WAVE_EXPORT_TIM) { return(do_timfile_save(fname)); } errno = 0; if(lxt) { lt = lt_init(fname); if(!lt) { return(VCDSAV_FILE_ERROR); } } else { if(export_typ != WAVE_EXPORT_TRANS) { GLOBALS->f_vcd_saver_c_1 = fopen(fname, "wb"); } else { if(!trans_head) /* scan-build : is programming error to get here */ { return(VCDSAV_FILE_ERROR); } GLOBALS->f_vcd_saver_c_1 = trans_file; } if(!GLOBALS->f_vcd_saver_c_1) { return(VCDSAV_FILE_ERROR); } } while(t) { if(!t->vector) { if(t->n.nd) { n = t->n.nd; if(n->expansion) n = n->expansion->parent; vt = vcdsav_splay(n, vt); if(!vt || vt->item != n) { unsigned char flags = 0; if(n->head.next) if(n->head.next->next) { flags = n->head.next->next->flags; } vt = vcdsav_insert(n, vt, ++nodecnt, flags, &n->head); } } } else { bvptr b = t->n.vec; if(b) { bptr bt = b->bits; if(bt) { for(i=0;innbits;i++) { if(bt->nodes[i]) { n = bt->nodes[i]; if(n->expansion) n = n->expansion->parent; vt = vcdsav_splay(n, vt); if(!vt || vt->item != n) { unsigned char flags = 0; if(n->head.next) if(n->head.next->next) { flags = n->head.next->next->flags; } vt = vcdsav_insert(n, vt, ++nodecnt, flags, &n->head); } } } } } } if(export_typ == WAVE_EXPORT_TRANS) { break; } if(!strace_append) { t=t->t_next; if(t) continue; } else { st = st->next; t = st ? st->trace : NULL; if(t) { continue; } else { swap_strace_contexts(); } } strace_concat: GLOBALS->strace_ctx = &GLOBALS->strace_windows[GLOBALS->strace_current_window = strace_append]; strace_append++; if(strace_append == WAVE_NUM_STRACE_WINDOWS) break; if(!GLOBALS->strace_ctx->shadow_straces) { goto strace_concat; } swap_strace_contexts(); st = GLOBALS->strace_ctx->straces; t = st ? st->trace : NULL; if(!t) {swap_strace_contexts(); goto strace_concat; } } if(!nodecnt) return(VCDSAV_EMPTY); /* header */ if(lxt) { int dim; lt_set_chg_compress(lt); lt_set_clock_compress(lt); lt_set_initial_value(lt, 'x'); lt_set_time64(lt, 0); lt_symbol_bracket_stripping(lt, 1); switch(GLOBALS->time_dimension) { case 'm': dim = -3; break; case 'u': dim = -6; break; case 'n': dim = -9; break; case 'p': dim = -12; break; case 'f': dim = -15; break; default: dim = 0; break; } lt_set_timescale(lt, dim); } else { if(export_typ != WAVE_EXPORT_TRANS) { time(&walltime); w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "$date\n"); w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "\t%s",asctime(localtime(&walltime))); w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "$end\n"); w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "$version\n\t"WAVE_VERSION_INFO"\n$end\n"); w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "$timescale\n\t%d%c%s\n$end\n", (int)GLOBALS->time_scale, GLOBALS->time_dimension, (GLOBALS->time_dimension=='s') ? "" : "s"); if(GLOBALS->global_time_offset) { w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "$timezero\n\t"TTFormat"\n$end\n",GLOBALS->global_time_offset); } } else { w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "$comment data_start %p $end\n", (void *)trans_head); /* arbitrary hex identifier */ w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "$comment name %s $end\n", trans_head->name ? trans_head->name : "UNKNOWN"); w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "$timescale %d%c%s $end\n", (int)GLOBALS->time_scale, GLOBALS->time_dimension, (GLOBALS->time_dimension=='s') ? "" : "s"); if(GLOBALS->global_time_offset) { w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "$timezero "TTFormat" $end\n",GLOBALS->global_time_offset); } w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "$comment min_time "TTFormat" $end\n", GLOBALS->min_time / GLOBALS->time_scale); w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "$comment max_time "TTFormat" $end\n", GLOBALS->max_time / GLOBALS->time_scale); } } if(export_typ == WAVE_EXPORT_TRANS) { w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "$comment max_seqn %d $end\n", nodecnt); if(t && t->transaction_args) { w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "$comment args \"%s\" $end\n", t->transaction_args); } } /* write out netnames here ... */ hp_clone = GLOBALS->hp_vcd_saver_c_1 = calloc_2(nodecnt, sizeof(vcdsav_Tree *)); recurse_build(vt, &hp_clone); for(i=0;ihp_vcd_saver_c_1[i]->item->nname, &was_packed); char *netname = lxt ? hname : output_hier(hname); if(export_typ == WAVE_EXPORT_TRANS) { w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "$comment seqn %d %s $end\n", GLOBALS->hp_vcd_saver_c_1[i]->val, hname); } if(GLOBALS->hp_vcd_saver_c_1[i]->flags & (HIST_REAL|HIST_STRING)) { if(lxt) { GLOBALS->hp_vcd_saver_c_1[i]->handle.p = lt_symbol_add(lt, netname, 0, 0, 0, GLOBALS->hp_vcd_saver_c_1[i]->flags & HIST_STRING ? LT_SYM_F_STRING : LT_SYM_F_DOUBLE); } else { const char *typ = (GLOBALS->hp_vcd_saver_c_1[i]->flags & HIST_STRING) ? "string" : "real"; int tlen = (GLOBALS->hp_vcd_saver_c_1[i]->flags & HIST_STRING) ? 0 : 1; w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "$var %s %d %s %s $end\n", typ, tlen, vcdid(GLOBALS->hp_vcd_saver_c_1[i]->val, export_typ), netname); } } else { int msi = -1, lsi = -1; if(GLOBALS->hp_vcd_saver_c_1[i]->item->extvals) { msi = GLOBALS->hp_vcd_saver_c_1[i]->item->msi; lsi = GLOBALS->hp_vcd_saver_c_1[i]->item->lsi; } if(msi==lsi) { if(lxt) { int strand_idx = strand_pnt(netname); if(strand_idx >= 0) { msi = lsi = atoi(netname + strand_idx + 1); } GLOBALS->hp_vcd_saver_c_1[i]->handle.p = lt_symbol_add(lt, netname, 0, msi, lsi, LT_SYM_F_BITS); } else { w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "$var wire 1 %s %s $end\n", vcdid(GLOBALS->hp_vcd_saver_c_1[i]->val, export_typ), netname); } } else { int len = (msi < lsi) ? (lsi - msi + 1) : (msi - lsi + 1); if(lxt) { GLOBALS->hp_vcd_saver_c_1[i]->handle.p = lt_symbol_add(lt, netname, 0, msi, lsi, LT_SYM_F_BITS); } else { w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "$var wire %d %s %s $end\n", len, vcdid(GLOBALS->hp_vcd_saver_c_1[i]->val, export_typ), netname); } GLOBALS->hp_vcd_saver_c_1[i]->len = len; if(len > max_len) max_len = len; } } /* if(was_packed) { free_2(hname); } ...not needed for HIER_DEPACK_STATIC */ } row_data = malloc_2(max_len + 1); if(!lxt) { output_hier(""); free_hier(); w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "$enddefinitions $end\n"); w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "$dumpvars\n"); } /* value changes */ for(i=(nodecnt/2-1);i>0;i--) /* build nodes into having heap property */ { heapify(i,nodecnt); } for(;;) { heapify(0, nodecnt); if(!GLOBALS->hp_vcd_saver_c_1[0]->hist) break; if(GLOBALS->hp_vcd_saver_c_1[0]->hist->time > GLOBALS->max_time) break; if((GLOBALS->hp_vcd_saver_c_1[0]->hist->time != prevtime) && (GLOBALS->hp_vcd_saver_c_1[0]->hist->time >= LLDescriptor(0))) { TimeType tnorm = GLOBALS->hp_vcd_saver_c_1[0]->hist->time; if(GLOBALS->time_scale != 1) { tnorm /= GLOBALS->time_scale; } if(lxt) { lt_set_time64(lt, tnorm); } else { w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "#"TTFormat"\n", tnorm); } prevtime = GLOBALS->hp_vcd_saver_c_1[0]->hist->time; } if(GLOBALS->hp_vcd_saver_c_1[0]->hist->time >= LLDescriptor(0)) { if(GLOBALS->hp_vcd_saver_c_1[0]->flags & (HIST_REAL|HIST_STRING)) { if(GLOBALS->hp_vcd_saver_c_1[0]->flags & HIST_STRING) { char *vec = GLOBALS->hp_vcd_saver_c_1[0]->hist->v.h_vector ? GLOBALS->hp_vcd_saver_c_1[0]->hist->v.h_vector : "UNDEF"; if(lxt) { lt_emit_value_string(lt, GLOBALS->hp_vcd_saver_c_1[0]->handle.p, 0, vec); } else { int vec_slen = strlen(vec); char *vec_escaped = malloc_2(vec_slen*4 + 1); /* worst case */ int vlen = fstUtilityBinToEsc((unsigned char *)vec_escaped, (unsigned char *)vec, vec_slen); vec_escaped[vlen] = 0; if(vlen) { w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "s%s %s\n", vec_escaped, vcdid(GLOBALS->hp_vcd_saver_c_1[0]->val, export_typ)); } else { w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "s\\000 %s\n", vcdid(GLOBALS->hp_vcd_saver_c_1[0]->val, export_typ)); } free_2(vec_escaped); } } else { #ifdef WAVE_HAS_H_DOUBLE double *d = &GLOBALS->hp_vcd_saver_c_1[0]->hist->v.h_double; #else double *d = (double *)GLOBALS->hp_vcd_saver_c_1[0]->hist->v.h_vector; #endif double value; if(!d) { sscanf("NaN", "%lg", &value); } else { value = *d; } if(lxt) { lt_emit_value_double(lt, GLOBALS->hp_vcd_saver_c_1[0]->handle.p, 0, value); } else { w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "r%.16g %s\n", value, vcdid(GLOBALS->hp_vcd_saver_c_1[0]->val, export_typ)); } } } else if(GLOBALS->hp_vcd_saver_c_1[0]->len) { if(GLOBALS->hp_vcd_saver_c_1[0]->hist->v.h_vector) { for(i=0;ihp_vcd_saver_c_1[0]->len;i++) { row_data[i] = analyzer_demang(lxt, GLOBALS->hp_vcd_saver_c_1[0]->hist->v.h_vector[i]); } } else { for(i=0;ihp_vcd_saver_c_1[0]->len;i++) { row_data[i] = 'x'; } } row_data[i] = 0; if(lxt) { lt_emit_value_bit_string(lt, GLOBALS->hp_vcd_saver_c_1[0]->handle.p, 0, row_data); } else { w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "b%s %s\n", vcd_truncate_bitvec(row_data), vcdid(GLOBALS->hp_vcd_saver_c_1[0]->val, export_typ)); } } else { if(lxt) { row_data[0] = analyzer_demang(lxt, GLOBALS->hp_vcd_saver_c_1[0]->hist->v.h_val); row_data[1] = 0; lt_emit_value_bit_string(lt, GLOBALS->hp_vcd_saver_c_1[0]->handle.p, 0, row_data); } else { w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "%c%s\n", analyzer_demang(lxt, GLOBALS->hp_vcd_saver_c_1[0]->hist->v.h_val), vcdid(GLOBALS->hp_vcd_saver_c_1[0]->val, export_typ)); } } } GLOBALS->hp_vcd_saver_c_1[0]->hist = GLOBALS->hp_vcd_saver_c_1[0]->hist->next; } if(prevtime < GLOBALS->max_time) { if(lxt) { lt_set_time64(lt, GLOBALS->max_time / GLOBALS->time_scale); } else { w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "#"TTFormat"\n", GLOBALS->max_time / GLOBALS->time_scale); } } for(i=0;ihp_vcd_saver_c_1[i]); } free_2(GLOBALS->hp_vcd_saver_c_1); GLOBALS->hp_vcd_saver_c_1 = NULL; free_2(row_data); row_data = NULL; if(lxt) { lt_close(lt); lt = NULL; } else { if(export_typ != WAVE_EXPORT_TRANS) { fclose(GLOBALS->f_vcd_saver_c_1); } else { w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "$comment data_end %p $end\n", (void *)trans_head); /* arbitrary hex identifier */ #if !defined _MSC_VER && !defined __MINGW32__ fflush(GLOBALS->f_vcd_saver_c_1); #endif } GLOBALS->f_vcd_saver_c_1 = NULL; } return(VCDSAV_OK); } int save_nodes_to_export(const char *fname, int export_typ) { return(save_nodes_to_export_generic(NULL, NULL, fname, export_typ)); } int save_nodes_to_trans(FILE *trans, Trptr t) { return(save_nodes_to_export_generic(trans, t, NULL, WAVE_EXPORT_TRANS)); } /************************ scopenav ************************/ struct namehier { struct namehier *next; char *name; char not_final; }; void free_hier(void) { struct namehier *nhtemp; while(GLOBALS->nhold_vcd_saver_c_1) { nhtemp=GLOBALS->nhold_vcd_saver_c_1->next; free_2(GLOBALS->nhold_vcd_saver_c_1->name); free_2(GLOBALS->nhold_vcd_saver_c_1); GLOBALS->nhold_vcd_saver_c_1=nhtemp; } } /* * navigate up and down the scope hierarchy and * emit the appropriate vcd scope primitives */ static void diff_hier(struct namehier *nh1, struct namehier *nh2) { /* struct namehier *nhtemp; */ /* scan-build */ if(!nh2) { while((nh1)&&(nh1->not_final)) { w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "$scope module %s $end\n", nh1->name); nh1=nh1->next; } return; } for(;;) { if((nh1->not_final==0)&&(nh2->not_final==0)) /* both are equal */ { break; } if(nh2->not_final==0) /* old hier is shorter */ { /* nhtemp=nh1; */ /* scan-build */ while((nh1)&&(nh1->not_final)) { w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "$scope module %s $end\n", nh1->name); nh1=nh1->next; } break; } if(nh1->not_final==0) /* new hier is shorter */ { /* nhtemp=nh2; */ /* scan-build */ while((nh2)&&(nh2->not_final)) { w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "$upscope $end\n"); nh2=nh2->next; } break; } if(strcmp(nh1->name, nh2->name)) { /* nhtemp=nh2; */ /* prune old hier */ /* scan-build */ while((nh2)&&(nh2->not_final)) { w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "$upscope $end\n"); nh2=nh2->next; } /* nhtemp=nh1; */ /* add new hier */ /* scan-build */ while((nh1)&&(nh1->not_final)) { w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "$scope module %s $end\n", nh1->name); nh1=nh1->next; } break; } nh1=nh1->next; nh2=nh2->next; } } /* * output scopedata for a given name if needed, return pointer to name string */ char *output_hier(char *name) { char *pnt, *pnt2; char *s; int len; struct namehier *nh_head=NULL, *nh_curr=NULL, *nhtemp; pnt=pnt2=name; for(;;) { if(*pnt2 == '\\') { while(*pnt2) pnt2++; } else { /* while((*pnt2!='.')&&(*pnt2)) pnt2++; ... does not handle dot at end of name */ while(*pnt2) { if(*pnt2!='.') { pnt2++; continue; } else { if(!*(pnt2+1)) /* if dot is at end of name */ { pnt2++; continue; } else { break; } } } } s=(char *)calloc_2(1,(len=pnt2-pnt)+1); memcpy(s, pnt, len); nhtemp=(struct namehier *)calloc_2(1,sizeof(struct namehier)); nhtemp->name=s; if(!nh_curr) { nh_head=nh_curr=nhtemp; } else { nh_curr->next=nhtemp; nh_curr->not_final=1; nh_curr=nhtemp; } if(!*pnt2) break; pnt=(++pnt2); } diff_hier(nh_head, GLOBALS->nhold_vcd_saver_c_1); free_hier(); GLOBALS->nhold_vcd_saver_c_1=nh_head; { char *mti_sv_patch = strstr(nh_curr->name, "]["); /* case is: #implicit-var###VarElem:ram_di[0.0] [63:0] */ if(mti_sv_patch) { char *t = calloc_2(1, strlen(nh_curr->name) + 1 + 1); *mti_sv_patch = 0; sprintf(t, "%s] %s", nh_curr->name, mti_sv_patch+1); free_2(nh_curr->name); nh_curr->name = t; } if((nh_curr->name[0] == '\\') && (nh_curr->name[1] == '#')) { return(nh_curr->name+1); } } return(nh_curr->name); } /****************************************/ /*** ***/ /*** output in timing analyzer format ***/ /*** ***/ /****************************************/ static void write_hptr_trace(Trptr t, int *whichptr, TimeType tmin, TimeType tmax) { nptr n = t->n.nd; hptr *ha = n->harray; int numhist = n->numhist; int i; unsigned char h_val = AN_X; gboolean first; gboolean invert = ((t->flags&TR_INVERT) != 0); int edges = 0; first = TRUE; for(i=0;itime < tmin) { } else if(ha[i]->time > tmax) { break; } else { if((ha[i]->time != tmin) || (!first)) { edges++; } first = FALSE; } } first = TRUE; for(i=0;itime < tmin) { h_val = invert ? AN_USTR_INV[ha[i]->v.h_val] : AN_USTR[ha[i]->v.h_val]; } else if(ha[i]->time > tmax) { break; } else { if(first) { gboolean skip_this = (ha[i]->time == tmin); if(skip_this) { h_val = invert ? AN_USTR_INV[ha[i]->v.h_val] : AN_USTR[ha[i]->v.h_val]; } w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "Digital_Signal\n" " Position: %d\n" " Height: 24\n" " Space_Above: 24\n" " Name: %s\n" " Start_State: %c\n" " Number_Edges: %d\n" " Rise_Time: 0.2\n" " Fall_Time: 0.2\n", *whichptr, t->name, h_val, edges); first = FALSE; if(skip_this) { continue; } } h_val = invert ? AN_USTR_INV[ha[i]->v.h_val] : AN_USTR[ha[i]->v.h_val]; w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, " Edge: "TTFormat".0 %c\n", ha[i]->time, h_val); } } if(first) { /* need to emit blank trace */ w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "Digital_Signal\n" " Position: %d\n" " Height: 24\n" " Space_Above: 24\n" " Name: %s\n" " Start_State: %c\n" " Number_Edges: %d\n" " Rise_Time: 10.0\n" " Fall_Time: 10.0\n", *whichptr, t->name, h_val, edges); } (*whichptr)++; } /***/ static void format_value_string(char *s) { char *s_orig = s; if((s)&&(*s)) { gboolean is_all_z = TRUE; gboolean is_all_x = TRUE; while(*s) { if((*s != 'z') && (*s != 'Z')) { is_all_z = FALSE; } if((*s != 'x') && (*s != 'X')) { is_all_x = FALSE; } /* if(isspace(*s)) *s='_'; ...not needed */ s++; } if(is_all_z) { *(s_orig++) = 'Z'; *(s_orig) = 0; } else if(is_all_x) { *(s_orig++) = 'X'; *(s_orig) = 0; } } } static char *get_hptr_vector_val(Trptr t, hptr h) { char *ascii = NULL; if(h->time < LLDescriptor(0)) { ascii=strdup_2("X"); } else if(h->flags&HIST_REAL) { if(!(h->flags&HIST_STRING)) { #ifdef WAVE_HAS_H_DOUBLE ascii=convert_ascii_real(t, &h->v.h_double); #else ascii=convert_ascii_real(t, (double *)h->v.h_vector); #endif } else { ascii=convert_ascii_string((char *)h->v.h_vector); } } else { ascii=convert_ascii_vec(t,h->v.h_vector); } format_value_string(ascii); return(ascii); } static const char *vcdsav_dtypes[] = { "Bin", "Hex", "Text" }; static int determine_trace_data_type(char *s, int curtype) { int i; if((s) && (curtype != VCDSAV_IS_TEXT)) { int len = strlen(s); for(i=0;in.nd; hptr *ha = n->harray; int numhist = n->numhist; int i; char *h_val = NULL; gboolean first; int edges = 0; int curtype = VCDSAV_IS_BIN; first = TRUE; for(i=0;itime < tmin) { } else if(ha[i]->time > tmax) { break; } else { char *s = get_hptr_vector_val(t, ha[i]); if(s) { curtype = determine_trace_data_type(s, curtype); free_2(s); } if((ha[i]->time != tmin) || (!first)) { edges++; } first = FALSE; } } first = TRUE; for(i=0;itime < tmin) { if(h_val) free_2(h_val); h_val = get_hptr_vector_val(t, ha[i]); } else if(ha[i]->time > tmax) { break; } else { if(first) { gboolean skip_this = (ha[i]->time == tmin); if(skip_this) { if(h_val) free_2(h_val); h_val = get_hptr_vector_val(t, ha[i]); } w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "Digital_Bus\n" " Position: %d\n" " Height: 24\n" " Space_Above: 24\n" " Name: %s\n" " Start_State: %s\n" " State_Format: %s\n" " Number_Edges: %d\n" " Rise_Time: 0.2\n" " Fall_Time: 0.2\n", *whichptr, t->name, h_val, vcdsav_dtypes[curtype], edges); first = FALSE; if(skip_this) { continue; } } if(h_val) free_2(h_val); h_val = get_hptr_vector_val(t, ha[i]); w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, " Edge: "TTFormat".0 %s\n", ha[i]->time, h_val); } } if(first) { /* need to emit blank trace */ w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "Digital_Bus\n" " Position: %d\n" " Height: 24\n" " Space_Above: 24\n" " Name: %s\n" " Start_State: %s\n" " State_Format: %s\n" " Number_Edges: %d\n" " Rise_Time: 10.0\n" " Fall_Time: 10.0\n", *whichptr, t->name, h_val, vcdsav_dtypes[curtype], edges); } if(h_val) free_2(h_val); (*whichptr)++; } /***/ static char *get_vptr_vector_val(Trptr t, vptr v) { char *ascii = NULL; if(v->time < LLDescriptor(0)) { ascii=strdup_2("X"); } else { ascii=convert_ascii(t,v); } if(!ascii) { ascii=strdup_2("X"); } format_value_string(ascii); return(ascii); } static void write_vptr_trace(Trptr t, int *whichptr, TimeType tmin, TimeType tmax) { vptr *ha = t->n.vec->vectors; int numhist = t->n.vec->numregions; int i; char *h_val = NULL; gboolean first; int edges = 0; int curtype = VCDSAV_IS_BIN; first = TRUE; for(i=0;itime < tmin) { } else if(ha[i]->time > tmax) { break; } else { char *s = get_vptr_vector_val(t, ha[i]); if(s) { curtype = determine_trace_data_type(s, curtype); free_2(s); } if((ha[i]->time != tmin) || (!first)) { edges++; } first = FALSE; } } first = TRUE; for(i=0;itime < tmin) { if(h_val) free_2(h_val); h_val = get_vptr_vector_val(t, ha[i]); } else if(ha[i]->time > tmax) { break; } else { if(first) { gboolean skip_this = (ha[i]->time == tmin); if(skip_this) { if(h_val) free_2(h_val); h_val = get_vptr_vector_val(t, ha[i]); } w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "Digital_Bus\n" " Position: %d\n" " Height: 24\n" " Space_Above: 24\n" " Name: %s\n" " Start_State: %s\n" " State_Format: %s\n" " Number_Edges: %d\n" " Rise_Time: 0.2\n" " Fall_Time: 0.2\n", *whichptr, t->name, h_val, vcdsav_dtypes[curtype], edges); first = FALSE; if(skip_this) { continue; } } if(h_val) free_2(h_val); h_val = get_vptr_vector_val(t, ha[i]); w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, " Edge: "TTFormat".0 %s\n", ha[i]->time, h_val); } } if(first) { /* need to emit blank trace */ w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "Digital_Bus\n" " Position: %d\n" " Height: 24\n" " Space_Above: 24\n" " Name: %s\n" " Start_State: %s\n" " State_Format: %s\n" " Number_Edges: %d\n" " Rise_Time: 10.0\n" " Fall_Time: 10.0\n", *whichptr, t->name, h_val, vcdsav_dtypes[curtype], edges); } if(h_val) free_2(h_val); (*whichptr)++; } static void write_tim_tracedata(Trptr t, int *whichptr, TimeType tmin, TimeType tmax) { if(!(t->flags&(TR_EXCLUDE|TR_BLANK|TR_ANALOG_BLANK_STRETCH))) { GLOBALS->shift_timebase=t->shift; if(!t->vector) { if(!t->n.nd->extvals) { write_hptr_trace(t, whichptr, tmin, tmax); /* single-bit */ } else { write_hptr_trace_vector(t, whichptr, tmin, tmax); /* multi-bit */ } } else { write_vptr_trace(t, whichptr, tmin, tmax); /* synthesized/concatenated vector */ } } } int do_timfile_save(const char *fname) { const char *time_prefix=WAVE_SI_UNITS; const double negpow[] = { 1.0, 1.0e-3, 1.0e-6, 1.0e-9, 1.0e-12, 1.0e-15, 1.0e-18, 1.0e-21 }; char *pnt; int offset; Trptr t = GLOBALS->traces.first; int i = 1; /* trace index in the .tim file */ TimeType tmin, tmax; errno = 0; if((GLOBALS->tims.marker > LLDescriptor(0)) && (GLOBALS->tims.baseline > LLDescriptor(0))) { if(GLOBALS->tims.marker < GLOBALS->tims.baseline) { tmin = GLOBALS->tims.marker; tmax = GLOBALS->tims.baseline; } else { tmax = GLOBALS->tims.marker; tmin = GLOBALS->tims.baseline; } } else { tmin = GLOBALS->min_time; tmax = GLOBALS->max_time; } GLOBALS->f_vcd_saver_c_1 = fopen(fname, "wb"); if(!GLOBALS->f_vcd_saver_c_1) { return(VCDSAV_FILE_ERROR); } pnt=strchr(time_prefix, (int)GLOBALS->time_dimension); if(pnt) { offset=pnt-time_prefix; } else offset=0; w32redirect_fprintf(GLOBALS->f_vcd_saver_c_1, "Timing Analyzer Settings\n" " Time_Scale: %E\n" " Time_Per_Division: %E\n" " NumberDivisions: 10\n" " Start_Time: "TTFormat".0\n" " End_Time: "TTFormat".0\n", negpow[offset], (tmax-tmin) / 10.0, tmin, tmax ); while(t) { write_tim_tracedata(t, &i, tmin, tmax); t = GiveNextTrace(t); } fclose(GLOBALS->f_vcd_saver_c_1); GLOBALS->f_vcd_saver_c_1 = NULL; return(errno ? VCDSAV_FILE_ERROR : VCDSAV_OK); } gtkwave-3.3.66/src/busy.c0000664000076400007640000000731712360623564014533 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2006-2009. * * 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. */ #include "globals.h" #include #include "busy.h" static int inside_iteration = 0; void gtk_events_pending_gtk_main_iteration(void) { inside_iteration++; while (gtk_events_pending()) gtk_main_iteration(); inside_iteration--; } gboolean in_main_iteration(void) { return(inside_iteration != 0); } gboolean ignore_context_swap(void) { return(GLOBALS->splash_is_loading != 0); } static void GuiDoEvent(GdkEvent *event, gpointer data) { (void)data; if(!GLOBALS->busy_busy_c_1) { gtk_main_do_event(event); } else { /* filter out user input when we're "busy" */ /* originally we allowed these two sets only... */ /* usual expose events */ /* case GDK_CONFIGURE: */ /* case GDK_EXPOSE: */ /* needed to keep dnd from hanging */ /* case GDK_ENTER_NOTIFY: */ /* case GDK_LEAVE_NOTIFY: */ /* case GDK_FOCUS_CHANGE: */ /* case GDK_MAP: */ /* now it has been updated to remove keyboard/mouse input */ switch (event->type) { /* more may be needed to be added in the future */ case GDK_MOTION_NOTIFY: case GDK_BUTTON_PRESS: case GDK_2BUTTON_PRESS: case GDK_3BUTTON_PRESS: case GDK_BUTTON_RELEASE: case GDK_KEY_PRESS: case GDK_KEY_RELEASE: #if GTK_CHECK_VERSION(2,6,0) case GDK_SCROLL: #endif /* printf("event->type: %d\n", event->type); */ break; default: gtk_main_do_event(event); /* printf("event->type: %d\n", event->type); */ break; } } } void gtkwave_main_iteration(void) { if(GLOBALS->partial_vcd) { gtk_events_pending_gtk_main_iteration(); } else { struct Global *g_old = GLOBALS; struct Global *gcache = NULL; set_window_busy(NULL); while (gtk_events_pending()) { gtk_main_iteration(); if(GLOBALS != g_old) { /* this should never happen! */ /* if it does, the program state is probably screwed */ fprintf(stderr, "GTKWAVE | WARNING: globals changed during gtkwave_main_iteration()!\n"); gcache = GLOBALS; } } set_GLOBALS(g_old); set_window_idle(NULL); if(gcache) { set_GLOBALS(gcache); } } } void init_busy(void) { GLOBALS->busycursor_busy_c_1 = gdk_cursor_new(GDK_WATCH); gdk_event_handler_set((GdkEventFunc)GuiDoEvent, NULL, NULL); } void set_window_busy_no_refresh(GtkWidget *w) { unsigned int i; /* if(GLOBALS->tree_dnd_begin) return; */ if(!GLOBALS->busy_busy_c_1) { if(w) gdk_window_set_cursor (w->window, GLOBALS->busycursor_busy_c_1); else if(GLOBALS->mainwindow) gdk_window_set_cursor (GLOBALS->mainwindow->window, GLOBALS->busycursor_busy_c_1); } GLOBALS->busy_busy_c_1++; for(i=0;inum_notebook_pages;i++) { (*GLOBALS->contexts)[i]->busy_busy_c_1 = GLOBALS->busy_busy_c_1; } } void set_window_busy(GtkWidget *w) { set_window_busy_no_refresh(w); busy_window_refresh(); } void set_window_idle(GtkWidget *w) { unsigned int i; /* if(GLOBALS->tree_dnd_begin) return; */ if(GLOBALS->busy_busy_c_1) { if(GLOBALS->busy_busy_c_1 <= 1) /* defensively, in case something causes the value to go below zero */ { if(w) gdk_window_set_cursor (w->window, NULL); else if(GLOBALS->mainwindow) gdk_window_set_cursor (GLOBALS->mainwindow->window, NULL); } GLOBALS->busy_busy_c_1--; for(i=0;inum_notebook_pages;i++) { (*GLOBALS->contexts)[i]->busy_busy_c_1 = GLOBALS->busy_busy_c_1; } } } void busy_window_refresh(void) { if(GLOBALS->busy_busy_c_1) { gtk_events_pending_gtk_main_iteration(); } } gtkwave-3.3.66/src/zoombuttons.c0000664000076400007640000003512512360623564016152 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2005. * * 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. */ #include #include "globals.h" #include "pixmaps.h" #include "currenttime.h" #include "debug.h" void fix_wavehadj(void) { GtkAdjustment *hadj; gfloat pageinc; hadj=GTK_ADJUSTMENT(GLOBALS->wave_hslider); hadj->lower=GLOBALS->tims.first; hadj->upper=GLOBALS->tims.last+2.0; pageinc=(gfloat)(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx); hadj->page_size=hadj->page_increment=(pageinc>=1.0)?pageinc:1.0; /* hadj->step_increment=(GLOBALS->nspx>=1.0)?GLOBALS->nspx:1.0; */ hadj->step_increment = pageinc / 10.0; if(hadj->step_increment < 1.0) hadj->step_increment = 1.0; if(hadj->page_size >= (hadj->upper-hadj->lower)) hadj->value=hadj->lower; if(hadj->value+hadj->page_size>hadj->upper) { hadj->value=hadj->upper-hadj->page_size; if(hadj->valuelower) hadj->value=hadj->lower; } } void service_zoom_left(GtkWidget *text, gpointer data) { (void)text; (void)data; GtkAdjustment *hadj; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nZoom To Start"); help_text( " is used to jump scroll to the trace's beginning." ); return; } hadj=GTK_ADJUSTMENT(GLOBALS->wave_hslider); hadj->value=GLOBALS->tims.timecache=GLOBALS->tims.first; time_update(); } void service_zoom_right(GtkWidget *text, gpointer data) { (void)text; (void)data; GtkAdjustment *hadj; TimeType ntinc; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nZoom To End"); help_text( " is used to jump scroll to the trace's end." ); return; } ntinc=(TimeType)(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx); GLOBALS->tims.timecache=GLOBALS->tims.last-ntinc+1; if(GLOBALS->tims.timecachetims.first) GLOBALS->tims.timecache=GLOBALS->tims.first; hadj=GTK_ADJUSTMENT(GLOBALS->wave_hslider); hadj->value=GLOBALS->tims.timecache; time_update(); } void service_zoom_out(GtkWidget *text, gpointer data) { (void)text; (void)data; TimeType middle=0, width; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nZoom Out"); help_text( " is used to decrease the zoom factor around the marker." #ifdef WAVE_USE_GTK2 " Alt + Scrollwheel Up also hits this button in non-alternative wheel mode." #endif ); return; } if(GLOBALS->do_zoom_center) { if((GLOBALS->tims.marker<0)||(GLOBALS->tims.markertims.first)||(GLOBALS->tims.marker>GLOBALS->tims.last)) { if(GLOBALS->tims.end>GLOBALS->tims.last) GLOBALS->tims.end=GLOBALS->tims.last; middle=(GLOBALS->tims.start/2)+(GLOBALS->tims.end/2); if((GLOBALS->tims.start&1)&&(GLOBALS->tims.end&1)) middle++; } else { middle=GLOBALS->tims.marker; } } GLOBALS->tims.prevzoom=GLOBALS->tims.zoom; GLOBALS->tims.zoom--; calczoom(GLOBALS->tims.zoom); if(GLOBALS->do_zoom_center) { width=(TimeType)(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx); GLOBALS->tims.start=time_trunc(middle-(width/2)); if(GLOBALS->tims.start+width>GLOBALS->tims.last) GLOBALS->tims.start=time_trunc(GLOBALS->tims.last-width); if(GLOBALS->tims.starttims.first) GLOBALS->tims.start=GLOBALS->tims.first; GTK_ADJUSTMENT(GLOBALS->wave_hslider)->value=GLOBALS->tims.timecache=GLOBALS->tims.start; } else { GLOBALS->tims.timecache=0; } fix_wavehadj(); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */ gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed"); /* force zoom update */ DEBUG(printf("Zoombuttons out\n")); } void service_zoom_in(GtkWidget *text, gpointer data) { (void)text; (void)data; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nZoom In"); help_text( " is used to increase the zoom factor around the marker." #ifdef WAVE_USE_GTK2 " Alt + Scrollwheel Down also hits this button in non-alternative wheel mode." #endif ); return; } if(GLOBALS->tims.zoom<0) /* otherwise it's ridiculous and can cause */ { /* overflow problems in the scope */ TimeType middle=0, width; if(GLOBALS->do_zoom_center) { if((GLOBALS->tims.marker<0)||(GLOBALS->tims.markertims.first)||(GLOBALS->tims.marker>GLOBALS->tims.last)) { if(GLOBALS->tims.end>GLOBALS->tims.last) GLOBALS->tims.end=GLOBALS->tims.last; middle=(GLOBALS->tims.start/2)+(GLOBALS->tims.end/2); if((GLOBALS->tims.start&1)&&(GLOBALS->tims.end&1)) middle++; } else { middle=GLOBALS->tims.marker; } } GLOBALS->tims.prevzoom=GLOBALS->tims.zoom; GLOBALS->tims.zoom++; calczoom(GLOBALS->tims.zoom); if(GLOBALS->do_zoom_center) { width=(TimeType)(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx); GLOBALS->tims.start=time_trunc(middle-(width/2)); if(GLOBALS->tims.start+width>GLOBALS->tims.last) GLOBALS->tims.start=time_trunc(GLOBALS->tims.last-width); if(GLOBALS->tims.starttims.first) GLOBALS->tims.start=GLOBALS->tims.first; GTK_ADJUSTMENT(GLOBALS->wave_hslider)->value=GLOBALS->tims.timecache=GLOBALS->tims.start; } else { GLOBALS->tims.timecache=0; } fix_wavehadj(); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */ gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed"); /* force zoom update */ DEBUG(printf("Zoombuttons in\n")); } } void service_zoom_undo(GtkWidget *text, gpointer data) { (void)text; (void)data; gdouble temp; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nZoom Undo"); help_text( " is used to revert to the previous zoom value used. Undo" " only works one level deep." ); return; } temp=GLOBALS->tims.zoom; GLOBALS->tims.zoom=GLOBALS->tims.prevzoom; GLOBALS->tims.prevzoom=temp; GLOBALS->tims.timecache=0; calczoom(GLOBALS->tims.zoom); fix_wavehadj(); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */ gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed"); /* force zoom update */ DEBUG(printf("Zoombuttons Undo\n")); } void service_zoom_fit(GtkWidget *text, gpointer data) { (void)text; (void)data; gdouble estimated; int fixedwidth; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nZoom Best Fit"); help_text( " attempts a \"best fit\" to get the whole trace onscreen." " Note that the trace may be more or less than a whole screen since" " this isn't a \"perfect fit.\" Also, if the middle button baseline" " marker is nailed down, the zoom instead of getting the whole trace" " onscreen will use the part of the trace between the primary" " marker and the baseline marker." ); return; } if((GLOBALS->tims.baseline>=0)&&(GLOBALS->tims.marker>=0)) { service_dragzoom(GLOBALS->tims.baseline, GLOBALS->tims.marker); /* new semantics added to zoom between the two */ } else { if(GLOBALS->wavewidth>4) { fixedwidth=GLOBALS->wavewidth-4; } else { fixedwidth=GLOBALS->wavewidth; } estimated=-log(((gdouble)(GLOBALS->tims.last-GLOBALS->tims.first+1))/((gdouble)fixedwidth)*((gdouble)200.0))/log(GLOBALS->zoombase); if(estimated>((gdouble)(0.0))) estimated=((gdouble)(0.0)); GLOBALS->tims.prevzoom=GLOBALS->tims.zoom; GLOBALS->tims.timecache=0; calczoom(estimated); GLOBALS->tims.zoom=estimated; fix_wavehadj(); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */ gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed"); /* force zoom update */ } DEBUG(printf("Zoombuttons Fit\n")); } void service_zoom_full(GtkWidget *text, gpointer data) { (void)text; (void)data; gdouble estimated; int fixedwidth; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nZoom Full"); help_text( " attempts a \"best fit\" to get the whole trace onscreen." " Note that the trace may be more or less than a whole screen since" " this isn't a \"perfect fit.\"" ); return; } if(GLOBALS->wavewidth>4) { fixedwidth=GLOBALS->wavewidth-4; } else { fixedwidth=GLOBALS->wavewidth; } estimated=-log(((gdouble)(GLOBALS->tims.last-GLOBALS->tims.first+1))/((gdouble)fixedwidth)*((gdouble)200.0))/log(GLOBALS->zoombase); if(estimated>((gdouble)(0.0))) estimated=((gdouble)(0.0)); GLOBALS->tims.prevzoom=GLOBALS->tims.zoom; GLOBALS->tims.timecache=0; calczoom(estimated); GLOBALS->tims.zoom=estimated; fix_wavehadj(); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */ gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed"); /* force zoom update */ DEBUG(printf("Zoombuttons Full\n")); } void service_dragzoom(TimeType time1, TimeType time2) /* the function you've been waiting for... */ { gdouble estimated; int fixedwidth; TimeType temp; GtkAdjustment *hadj; Trptr t; if(time2time1) /* ensure at least 1 tick */ { if(GLOBALS->wavewidth>4) { fixedwidth=GLOBALS->wavewidth-4; } else { fixedwidth=GLOBALS->wavewidth; } estimated=-log(((gdouble)(time2-time1+1))/((gdouble)fixedwidth)*((gdouble)200.0))/log(GLOBALS->zoombase); if(estimated>((gdouble)(0.0))) estimated=((gdouble)(0.0)); GLOBALS->tims.prevzoom=GLOBALS->tims.zoom; GLOBALS->tims.timecache=GLOBALS->tims.laststart=GLOBALS->tims.start=time_trunc(time1); for(t=GLOBALS->traces.first;t;t=t->t_next) /* have to nuke string refs so printout is ok! */ { if(t->asciivalue) { free_2(t->asciivalue); t->asciivalue=NULL; } } for(t=GLOBALS->traces.buffer;t;t=t->t_next) { if(t->asciivalue) { free_2(t->asciivalue); t->asciivalue=NULL; } } if(!((GLOBALS->tims.baseline>=0)&&(GLOBALS->tims.marker>=0))) { update_markertime(GLOBALS->tims.marker=-1); } GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); hadj=GTK_ADJUSTMENT(GLOBALS->wave_hslider); hadj->value=time1; calczoom(estimated); GLOBALS->tims.zoom=estimated; fix_wavehadj(); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */ gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed"); /* force zoom update */ DEBUG(printf("Drag Zoom\n")); } } /* Create actual buttons */ GtkWidget * create_zoom_buttons (void) { GtkWidget *table; GtkWidget *table2; GtkWidget *frame; GtkWidget *main_vbox; GtkWidget *b1; GtkWidget *b2; GtkWidget *b3; GtkWidget *b4; GtkWidget *b5; GtkWidget *b6; GtkWidget *pixmapzout, *pixmapzin, *pixmapzfit, *pixmapzundo; GtkWidget *pixmapzleft, *pixmapzright; GtkTooltips *tooltips; tooltips=gtk_tooltips_new_2(); gtk_tooltips_set_delay_2(tooltips,1500); pixmapzin=gtk_pixmap_new(GLOBALS->zoomin_pixmap, GLOBALS->zoomin_mask); gtk_widget_show(pixmapzin); pixmapzout=gtk_pixmap_new(GLOBALS->zoomout_pixmap, GLOBALS->zoomout_mask); gtk_widget_show(pixmapzout); pixmapzfit=gtk_pixmap_new(GLOBALS->zoomfit_pixmap, GLOBALS->zoomfit_mask); gtk_widget_show(pixmapzfit); pixmapzundo=gtk_pixmap_new(GLOBALS->zoomundo_pixmap, GLOBALS->zoomundo_mask); gtk_widget_show(pixmapzundo); pixmapzleft=gtk_pixmap_new(GLOBALS->zoom_larrow_pixmap, GLOBALS->zoom_larrow_mask); gtk_widget_show(pixmapzleft); pixmapzright=gtk_pixmap_new(GLOBALS->zoom_rarrow_pixmap, GLOBALS->zoom_rarrow_mask); gtk_widget_show(pixmapzright); /* Create a table to hold the text widget and scrollbars */ table = gtk_table_new (1, 1, FALSE); main_vbox = gtk_vbox_new (FALSE, 1); gtk_container_border_width (GTK_CONTAINER (main_vbox), 1); gtk_container_add (GTK_CONTAINER (table), main_vbox); frame = gtk_frame_new ("Zoom "); gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0); gtk_widget_show (frame); gtk_widget_show (main_vbox); table2 = gtk_table_new (2, 3, FALSE); b1 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b1), pixmapzin); gtk_table_attach (GTK_TABLE (table2), b1, 0, 1, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); gtk_signal_connect_object (GTK_OBJECT (b1), "clicked", GTK_SIGNAL_FUNC(service_zoom_out), GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(tooltips, b1, "Zoom Out", NULL); gtk_widget_show(b1); b2 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b2), pixmapzout); gtk_table_attach (GTK_TABLE (table2), b2, 0, 1, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); gtk_signal_connect_object (GTK_OBJECT (b2), "clicked", GTK_SIGNAL_FUNC(service_zoom_in), GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(tooltips, b2, "Zoom In", NULL); gtk_widget_show(b2); b3 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b3), pixmapzfit); gtk_table_attach (GTK_TABLE (table2), b3, 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); gtk_signal_connect_object (GTK_OBJECT (b3), "clicked", GTK_SIGNAL_FUNC(service_zoom_fit), GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(tooltips, b3, "Zoom Best Fit", NULL); gtk_widget_show(b3); b4 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b4), pixmapzundo); gtk_table_attach (GTK_TABLE (table2), b4, 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); gtk_signal_connect_object (GTK_OBJECT (b4), "clicked", GTK_SIGNAL_FUNC(service_zoom_undo), GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(tooltips, b4, "Undo Last Zoom", NULL); gtk_widget_show(b4); b5 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b5), pixmapzleft); gtk_table_attach (GTK_TABLE (table2), b5, 2, 3, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); gtk_signal_connect_object (GTK_OBJECT (b5), "clicked", GTK_SIGNAL_FUNC(service_zoom_left), GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(tooltips, b5, "Zoom To Start", NULL); gtk_widget_show(b5); b6 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b6), pixmapzright); gtk_table_attach (GTK_TABLE (table2), b6, 2, 3, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); gtk_signal_connect_object (GTK_OBJECT (b6), "clicked", GTK_SIGNAL_FUNC(service_zoom_right), GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(tooltips, b6, "Zoom To End", NULL); gtk_widget_show(b6); gtk_container_add (GTK_CONTAINER (frame), table2); gtk_widget_show(table2); return table; } gtkwave-3.3.66/src/print.h0000664000076400007640000000715312341266475014713 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999. * * 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. */ #include "globals.h" /* * This module has been re-implemented by Udi Finkelstein. * Since it is no longer a PostScript-only module, it had been * renamed "print.c". * * Much of the code has been "C++"-ized in style, yet written in C. * We use classes, virtual functions, class members, and "this" pointers * written in C. */ #ifndef WAVE_PRINT_H #define WAVE_PRINT_H /************************************************************************* * Print Context * * * * This structure contains everything needed for the generic print code * *************************************************************************/ struct _gtk_print_device; struct _pr_context { struct _gtk_print_device *gpd; /* Pointer to print device class */ FILE *handle; /* Pointer to output file */ gdouble PageX; /* Legal page width */ gdouble PageY; /* Legal page height */ gdouble LM; /* Left Margin (inch) */ gdouble RM; /* Right Margin (inch) */ gdouble BM; /* Bottom Margin (inch) */ gdouble TM; /* Top Margin (inch) */ gdouble xscale, yscale, xtotal; gdouble tr_x, tr_y; gdouble gray; int MinX, MinY, MaxX, MaxY; /* These will be initialized by a routine */ char fullpage; }; typedef struct _pr_context pr_context; /************************************************************************* * GTKWave Print Device * * * * This structure contains pointers to device specific operations * *************************************************************************/ struct _gtk_print_device { void (*gpd_header)(pr_context *prc); void (*gpd_trailer)(pr_context *prc); void (*gpd_signal_init)(pr_context *prc); void (*gpd_setgray)(pr_context *prc, gdouble gray); void (*gpd_draw_line)(pr_context *prc, gdouble x1, gdouble y1, gdouble x2, gdouble y2); void (*gpd_draw_box)(pr_context *prc, gdouble x1, gdouble y1, gdouble x2, gdouble y2); void (*gpd_draw_string)(pr_context *prc, int x, int y, char *str, int xsize, int ysize); }; typedef struct _gtk_print_device gtk_print_device; void print_image(pr_context *prc); void print_mif_image(FILE *wave, gdouble px, gdouble py); void print_ps_image(FILE *wave, gdouble px, gdouble py); void ps_header(pr_context * prc); void ps_trailer(pr_context * prc); void ps_signal_init(pr_context * prc); void ps_setgray(pr_context * prc, gdouble gray); void ps_draw_line(pr_context * prc, gdouble x1, gdouble y1, gdouble x2, gdouble y2); void ps_draw_box(pr_context * prc, gdouble x1, gdouble y1, gdouble x2, gdouble y2); void ps_draw_string(pr_context * prc, int x, int y, char *str, int xsize, int ysize); void mif_header(pr_context * prc); void mif_trailer(pr_context * prc); void mif_signal_init(pr_context * prc); void mif_setgray(pr_context * prc, gdouble gray); void mif_translate(pr_context * prc, gdouble x, gdouble y); void mif_draw_line(pr_context * prc, gdouble x1, gdouble y1, gdouble x2, gdouble y2); void mif_draw_box(pr_context * prc, gdouble x1, gdouble y1, gdouble x2, gdouble y2); void mif_draw_string(pr_context * prc, int x, int y, char *str, int xsize, int ysize); #endif gtkwave-3.3.66/src/mouseover.h0000664000076400007640000000064511523063250015565 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2010 * * 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. */ #ifndef WAVE_MOUSEOVER_H #define WAVE_MOUSEOVER_H void move_mouseover(Trptr t, gint xin, gint yin, TimeType tim); #endif gtkwave-3.3.66/src/cocoa/0000775000076400007640000000000012546303363014457 5ustar bybellbybellgtkwave-3.3.66/src/cocoa/Makefile.in0000664000076400007640000004522012261434733016527 0ustar bybellbybell# Makefile.in generated by automake 1.13.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 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__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } 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 = : subdir = src/cocoa DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru AM_V_AR = $(am__v_AR_@AM_V@) am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) am__v_AR_0 = @echo " AR " $@; am__v_AR_1 = libgtkwmacintegration_a_AR = $(AR) $(ARFLAGS) libgtkwmacintegration_a_LIBADD = am_libgtkwmacintegration_a_OBJECTS = \ libgtkwmacintegration_a-cocoa_misc.$(OBJEXT) libgtkwmacintegration_a_OBJECTS = \ $(am_libgtkwmacintegration_a_OBJECTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f 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 = 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 = $(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 = SOURCES = $(libgtkwmacintegration_a_SOURCES) DIST_SOURCES = $(libgtkwmacintegration_a_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)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AET2_CFLAGS = @AET2_CFLAGS@ AET2_LDADD = @AET2_LDADD@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COCOA_GTK_CFLAGS = @COCOA_GTK_CFLAGS@ COCOA_GTK_LDADD = @COCOA_GTK_LDADD@ COCOA_GTK_LDFLAGS = @COCOA_GTK_LDFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTDEBUG = @EXTDEBUG@ EXTDEBUG2 = @EXTDEBUG2@ EXTDEBUG3 = @EXTDEBUG3@ EXTDEBUG4 = @EXTDEBUG4@ EXTLOAD_CFLAGS = @EXTLOAD_CFLAGS@ FASTTREE_CFLAGS = @FASTTREE_CFLAGS@ FSDB_CFLAGS = @FSDB_CFLAGS@ FSDB_LDADD = @FSDB_LDADD@ GCONF_CFLAGS = @GCONF_CFLAGS@ GCONF_LIBS = @GCONF_LIBS@ GEDITTEST = @GEDITTEST@ GEDIT_CFLAGS = @GEDIT_CFLAGS@ GPERF = @GPERF@ GREP = @GREP@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_CONFIG = @GTK_CONFIG@ GTK_LIBS = @GTK_LIBS@ GTK_MAC_CFLAGS = @GTK_MAC_CFLAGS@ GTK_MAC_LIBS = @GTK_MAC_LIBS@ GTK_UNIX_PRINT_CFLAGS = @GTK_UNIX_PRINT_CFLAGS@ GTK_UNIX_PRINT_LIBS = @GTK_UNIX_PRINT_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBBZ2_CFLAGS = @LIBBZ2_CFLAGS@ LIBBZ2_DIR = @LIBBZ2_DIR@ LIBBZ2_LDADD = @LIBBZ2_LDADD@ LIBJUDY_CFLAGS = @LIBJUDY_CFLAGS@ LIBJUDY_LDADD = @LIBJUDY_LDADD@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBXZ_CFLAGS = @LIBXZ_CFLAGS@ LIBXZ_LDADD = @LIBXZ_LDADD@ LIBZ_CFLAGS = @LIBZ_CFLAGS@ LIBZ_DIR = @LIBZ_DIR@ LIBZ_LDADD = @LIBZ_LDADD@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MINGW_LDADD = @MINGW_LDADD@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ 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@ POW_LIB = @POW_LIB@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ STRUCT_PACK = @STRUCT_PACK@ TCL_DEFADD = @TCL_DEFADD@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LDADD = @TCL_LDADD@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_MAJOR_VERSION = @TCL_MAJOR_VERSION@ TCL_MINOR_VERSION = @TCL_MINOR_VERSION@ TK_INCLUDE_SPEC = @TK_INCLUDE_SPEC@ TK_LDADD = @TK_LDADD@ TK_LIB_SPEC = @TK_LIB_SPEC@ UPDATE_DESKTOP_DATABASE = @UPDATE_DESKTOP_DATABASE@ UPDATE_MIME_DATABASE = @UPDATE_MIME_DATABASE@ VERSION = @VERSION@ XDGDATADIR = @XDGDATADIR@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ 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_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ 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@ 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@ noinst_LIBRARIES = libgtkwmacintegration.a libgtkwmacintegration_a_CFLAGS = $(COCOA_GTK_CFLAGS) $(GTK_CFLAGS) $(GTK_MAC_CFLAGS) libgtkwmacintegration_a_OBJCFLAGS = libgtkwmacintegration_a_SOURCES = cocoa_misc.c cocoa_misc.h # I'm listing these here instead of in SOURCES because we don't directly # compile them. Rather it is #include'd by cocoa_misc.c EXTRA_DIST = alert_sheet.m alert_sheet.h all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(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) --foreign src/cocoa/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/cocoa/Makefile .PRECIOUS: 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__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libgtkwmacintegration.a: $(libgtkwmacintegration_a_OBJECTS) $(libgtkwmacintegration_a_DEPENDENCIES) $(EXTRA_libgtkwmacintegration_a_DEPENDENCIES) $(AM_V_at)-rm -f libgtkwmacintegration.a $(AM_V_AR)$(libgtkwmacintegration_a_AR) libgtkwmacintegration.a $(libgtkwmacintegration_a_OBJECTS) $(libgtkwmacintegration_a_LIBADD) $(AM_V_at)$(RANLIB) libgtkwmacintegration.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgtkwmacintegration_a-cocoa_misc.Po@am__quote@ .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 $< .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 `$(CYGPATH_W) '$<'` libgtkwmacintegration_a-cocoa_misc.o: cocoa_misc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgtkwmacintegration_a_CFLAGS) $(CFLAGS) -MT libgtkwmacintegration_a-cocoa_misc.o -MD -MP -MF $(DEPDIR)/libgtkwmacintegration_a-cocoa_misc.Tpo -c -o libgtkwmacintegration_a-cocoa_misc.o `test -f 'cocoa_misc.c' || echo '$(srcdir)/'`cocoa_misc.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgtkwmacintegration_a-cocoa_misc.Tpo $(DEPDIR)/libgtkwmacintegration_a-cocoa_misc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cocoa_misc.c' object='libgtkwmacintegration_a-cocoa_misc.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgtkwmacintegration_a_CFLAGS) $(CFLAGS) -c -o libgtkwmacintegration_a-cocoa_misc.o `test -f 'cocoa_misc.c' || echo '$(srcdir)/'`cocoa_misc.c libgtkwmacintegration_a-cocoa_misc.obj: cocoa_misc.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgtkwmacintegration_a_CFLAGS) $(CFLAGS) -MT libgtkwmacintegration_a-cocoa_misc.obj -MD -MP -MF $(DEPDIR)/libgtkwmacintegration_a-cocoa_misc.Tpo -c -o libgtkwmacintegration_a-cocoa_misc.obj `if test -f 'cocoa_misc.c'; then $(CYGPATH_W) 'cocoa_misc.c'; else $(CYGPATH_W) '$(srcdir)/cocoa_misc.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgtkwmacintegration_a-cocoa_misc.Tpo $(DEPDIR)/libgtkwmacintegration_a-cocoa_misc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cocoa_misc.c' object='libgtkwmacintegration_a-cocoa_misc.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgtkwmacintegration_a_CFLAGS) $(CFLAGS) -c -o libgtkwmacintegration_a-cocoa_misc.obj `if test -f 'cocoa_misc.c'; then $(CYGPATH_W) 'cocoa_misc.c'; else $(CYGPATH_W) '$(srcdir)/cocoa_misc.c'; fi` 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: $(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 $(LIBRARIES) installdirs: 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-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -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-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 -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic 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 maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am # 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: gtkwave-3.3.66/src/cocoa/alert_sheet.m0000664000076400007640000000501111710320605017117 0ustar bybellbybell// // NSAlert+SynchronousSheet.h // // Created by Philipp Mayerhofer on 6/10/11. // Copyright 2011 Incredible Bee Ltd. Released under the New BSD License. // #import "alert_sheet.h" // Private methods -- use prefixes to avoid collisions with Apple's methods @interface NSAlert () -(IBAction) BE_stopSynchronousSheet:(id)sender; // hide sheet & stop modal -(void) BE_beginSheetModalForWindow:(NSWindow *)aWindow; @end @implementation NSAlert (SynchronousSheet) -(NSInteger) runModalSheetForWindow:(NSWindow *)aWindow { // Set ourselves as the target for button clicks for (NSButton *button in [self buttons]) { [button setTarget:self]; [button setAction:@selector(BE_stopSynchronousSheet:)]; } // Bring up the sheet and wait until stopSynchronousSheet is triggered by a button click [self performSelectorOnMainThread:@selector(BE_beginSheetModalForWindow:) withObject:aWindow waitUntilDone:YES]; NSInteger modalCode = [NSApp runModalForWindow:[self window]]; // This is called only after stopSynchronousSheet is called (that is, // one of the buttons is clicked) [NSApp performSelectorOnMainThread:@selector(endSheet:) withObject:[self window] waitUntilDone:YES]; // Remove the sheet from the screen [[self window] performSelectorOnMainThread:@selector(orderOut:) withObject:self waitUntilDone:YES]; return modalCode; } -(NSInteger) runModalSheet { return [self runModalSheetForWindow:[NSApp mainWindow]]; } #pragma mark Private methods -(IBAction) BE_stopSynchronousSheet:(id)sender { // See which of the buttons was clicked NSUInteger clickedButtonIndex = [[self buttons] indexOfObject:sender]; // Be consistent with Apple's documentation (see NSAlert's addButtonWithTitle) so that // the fourth button is numbered NSAlertThirdButtonReturn + 1, and so on // // TODO: handle case when alert created with alertWithMessageText:... where the buttons // have values NSAlertDefaultReturn, NSAlertAlternateReturn, ... instead (see also // the documentation for the runModal method) NSInteger modalCode = 0; if (clickedButtonIndex == NSAlertFirstButtonReturn) modalCode = NSAlertFirstButtonReturn; else if (clickedButtonIndex == NSAlertSecondButtonReturn) modalCode = NSAlertSecondButtonReturn; else if (clickedButtonIndex == NSAlertThirdButtonReturn) modalCode = NSAlertThirdButtonReturn; else modalCode = NSAlertThirdButtonReturn + (clickedButtonIndex - 2); [NSApp stopModalWithCode:modalCode]; } -(void) BE_beginSheetModalForWindow:(NSWindow *)aWindow { [self beginSheetModalForWindow:aWindow modalDelegate:nil didEndSelector:nil contextInfo:nil]; } @end gtkwave-3.3.66/src/cocoa/cocoa_misc.c0000664000076400007640000001617312006052613016720 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2012. * * 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. */ #include "cocoa_misc.h" #ifdef WAVE_COCOA_GTK #include "alert_sheet.m" #include /*************************/ /* menu.c */ /*************************/ void gtk_open_external_file(const char *fpath) { NSString *nspath = [NSString stringWithUTF8String:fpath]; [[NSWorkspace sharedWorkspace] openFile:nspath]; } /*************************/ /* file.c */ /*************************/ static char *gtk_open_file_req_bridge(const char *title, const char *fpath, const char *pattn) { NSOpenPanel * zOpenPanel = [NSOpenPanel openPanel]; [zOpenPanel setCanChooseDirectories:NO]; [zOpenPanel setCanChooseFiles:YES]; [zOpenPanel setAllowsMultipleSelection:NO]; [zOpenPanel setTreatsFilePackagesAsDirectories:YES]; NSString *nstitle = [NSString stringWithUTF8String:title]; [zOpenPanel setTitle:nstitle]; NSArray * zAryOfExtensions = nil; if(pattn) { const char *d = strchr(pattn, '.'); if(d) { const char *pattn2 = d+1; if(!strcasecmp(pattn2, "sav") || !strcasecmp(pattn2, "gtkw")) { zAryOfExtensions = [NSArray arrayWithObjects:@"gtkw", @"sav", nil]; } else { NSString *s = [NSString stringWithUTF8String:pattn2]; zAryOfExtensions = [NSArray arrayWithObjects:s,nil]; } } } NSString *p_path = nil; NSString *p_file = nil; if(fpath) { char *s_temp = realpath(fpath,NULL); if(s_temp) { struct stat sbuf; if(!stat(s_temp,&sbuf)) { if(S_ISDIR(sbuf.st_mode)) { p_path = [NSString stringWithUTF8String:s_temp]; NSURL *URL = [NSURL URLWithString:p_path]; [zOpenPanel setDirectoryURL:URL]; } else { p_path = [[NSString stringWithUTF8String:s_temp] stringByDeletingLastPathComponent]; p_file = [[NSString stringWithUTF8String:s_temp] lastPathComponent]; NSURL *URL = [NSURL URLWithString:p_path]; [zOpenPanel setDirectoryURL:URL]; } } free(s_temp); } } NSInteger zIntResult = [zOpenPanel runModalForDirectory:p_path file:p_file types:zAryOfExtensions]; if (zIntResult == NSFileHandlingPanelCancelButton) { return(NULL); } NSURL *zUrl = [zOpenPanel URL]; NSString *us = [zUrl absoluteString]; const char *cst = [us UTF8String]; return(g_filename_from_uri(cst, NULL, NULL)); } static char *gtk_save_file_req_bridge(const char *title, const char *fpath, const char *pattn) { NSSavePanel * zSavePanel = [NSSavePanel savePanel]; [zSavePanel setAllowsOtherFileTypes:YES]; [zSavePanel setTreatsFilePackagesAsDirectories:YES]; [zSavePanel setExtensionHidden:NO]; NSString *nstitle = [NSString stringWithUTF8String:title]; [zSavePanel setTitle:nstitle]; NSArray * zAryOfExtensions = nil; if(pattn) { const char *d = strchr(pattn, '.'); if(d) { const char *pattn2 = d+1; if(!strcasecmp(pattn2, "sav") || !strcasecmp(pattn2, "gtkw")) { zAryOfExtensions = [NSArray arrayWithObjects:@"gtkw", @"sav", nil]; } else { NSString *s = [NSString stringWithUTF8String:pattn2]; zAryOfExtensions = [NSArray arrayWithObjects:s,nil]; } } } [zSavePanel setAllowedFileTypes:zAryOfExtensions]; NSString *p_path = nil; NSString *p_file = nil; if(fpath) { char *s_temp = realpath(fpath,NULL); if(s_temp) { struct stat sbuf; if(!stat(s_temp,&sbuf)) { if(S_ISDIR(sbuf.st_mode)) { p_path = [NSString stringWithUTF8String:s_temp]; NSURL *URL = [NSURL URLWithString:p_path]; [zSavePanel setDirectoryURL:URL]; } else { p_path = [[NSString stringWithUTF8String:s_temp] stringByDeletingLastPathComponent]; p_file = [[NSString stringWithUTF8String:s_temp] lastPathComponent]; NSURL *URL = [NSURL URLWithString:p_path]; [zSavePanel setDirectoryURL:URL]; [zSavePanel setNameFieldStringValue:p_file]; } } free(s_temp); } } NSInteger zIntResult = [zSavePanel runModal]; if (zIntResult == NSFileHandlingPanelCancelButton) { return(NULL); } NSURL *zUrl = [zSavePanel URL]; NSString *us = [zUrl absoluteString]; const char *cst = [us UTF8String]; return(g_filename_from_uri(cst, NULL, NULL)); } char *gtk_file_req_bridge(const char *title, const char *fpath, const char *pattn, int is_writemode) { char *rc; if(is_writemode) { rc = gtk_save_file_req_bridge(title, fpath, pattn); } else { rc = gtk_open_file_req_bridge(title, fpath, pattn); } return(rc); } /*************************/ /* simplereq.c / entry.c */ /*************************/ static int gtk_simplereqbox_req_bridge_2(char *title, char *default_text, char *oktext, char *canceltext, int is_alert, int is_entry, char *default_in_text_entry, char **out_text_entry, int width) { NSAlert *alert = [[[NSAlert alloc] init] autorelease]; int rc = 0; if(oktext) { [alert addButtonWithTitle: [NSString stringWithUTF8String:oktext]]; if(canceltext) { [alert addButtonWithTitle: [NSString stringWithUTF8String:canceltext]]; } } if(title) { [alert setMessageText: [NSString stringWithUTF8String:title]]; } if(default_text) { [alert setInformativeText: [NSString stringWithUTF8String:default_text]]; } if(is_alert) { [alert setAlertStyle:NSCriticalAlertStyle]; } else { [alert setAlertStyle:NSInformationalAlertStyle]; } NSTextField *input = nil; if(is_entry && default_in_text_entry && out_text_entry) { input = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, width, 24)]; [input setSelectable:YES]; [input setEditable:YES]; [input setImportsGraphics:NO]; [[alert window] makeFirstResponder:input]; [input setStringValue:[NSString stringWithUTF8String:default_in_text_entry]]; [input selectText:input]; [alert setAccessoryView:input]; } NSInteger zIntResult = [alert runModalSheet]; if(zIntResult == NSAlertFirstButtonReturn) { rc = 1; if(is_entry && default_in_text_entry && out_text_entry) { [input validateEditing]; *out_text_entry = strdup([[input stringValue] UTF8String]); } } else if(zIntResult == NSAlertSecondButtonReturn) { rc = 2; } return(rc); } int gtk_simplereqbox_req_bridge(char *title, char *default_text, char *oktext, char *canceltext, int is_alert) { return(gtk_simplereqbox_req_bridge_2(title, default_text, oktext, canceltext, is_alert, 0, NULL, 0, 0)); } int entrybox_req_bridge(char *title, int width, char *dflt_text, char *comment, int maxch, char **out_text_entry) { int rc = gtk_simplereqbox_req_bridge_2(title, comment, "OK", "Cancel", 0, 1, dflt_text, out_text_entry, width); if((rc == 1)&&(*out_text_entry)) { int len = strlen(*out_text_entry); if(len > maxch) { char *s2 = calloc(1, maxch+1); memcpy(s2, *out_text_entry, maxch); free(*out_text_entry); *out_text_entry = s2; } } return(rc); } #else char *cocoa_misc_dummy_compilation_unit(void) { return(NULL); /* dummy compilation unit */ } #endif gtkwave-3.3.66/src/cocoa/alert_sheet.h0000664000076400007640000000152611710320605017121 0ustar bybellbybell// // NSAlert+SynchronousSheet.h // // Created by Philipp Mayerhofer on 6/10/11. // Copyright 2011 Incredible Bee Ltd. Released under the New BSD License. // #import /** * Category to allow NSAlert instances to be run synchronously as sheets. */ @interface NSAlert (SynchronousSheet) /** * Runs the receiver modally as an alert sheet attached to a specified window * and returns the constant positionally identifying the button clicked. * * \param aWindow The parent window for the sheet * * \return Response to the alert. See "Button Return Values" in Apple's NSAlert * documentation. */ -(NSInteger) runModalSheetForWindow:(NSWindow *)aWindow; /** * Runs the receiver modally as an alert sheet attached to the main window * and returns the constant positionally identifying the button clicked. */ -(NSInteger) runModalSheet; @end gtkwave-3.3.66/src/cocoa/Makefile.am0000664000076400007640000000065511710320605016507 0ustar bybellbybell## -*- makefile -*- ## noinst_LIBRARIES= libgtkwmacintegration.a libgtkwmacintegration_a_CFLAGS = $(COCOA_GTK_CFLAGS) $(GTK_CFLAGS) $(GTK_MAC_CFLAGS) libgtkwmacintegration_a_OBJCFLAGS = libgtkwmacintegration_a_SOURCES = cocoa_misc.c cocoa_misc.h # I'm listing these here instead of in SOURCES because we don't directly # compile them. Rather it is #include'd by cocoa_misc.c EXTRA_DIST= alert_sheet.m alert_sheet.h gtkwave-3.3.66/src/cocoa/cocoa_misc.h0000664000076400007640000000145112006052613016716 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2012. * * 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. */ #ifndef __COCOA_MISC_H__ #define __COCOA_MISC_H__ #ifdef WAVE_COCOA_GTK #import #endif #include void gtk_open_external_file(const char *fpath); char *gtk_file_req_bridge(const char *title, const char *fpath, const char *pattn, int is_writemode); int gtk_simplereqbox_req_bridge(char *title, char *default_text, char *oktext, char *canceltext, int is_alert); int entrybox_req_bridge(char *title, int width, char *dflt_text, char *comment, int maxch, char **out_text_entry); #endif gtkwave-3.3.66/src/renderopt.c0000664000076400007640000003716612523241774015560 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2012 * * 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. */ #include "globals.h" #include #include "currenttime.h" #include "print.h" #include "menu.h" #include #ifdef WAVE_GTK_UNIX_PRINT /* #include */ #include #endif static char *render_targets[]= {"PDF", "PS", "MIF", "UNIX"}; static char *page_size[]= {"Letter (8.5\" x 11\")", "A4 (11.68\" x 8.26\")", "Legal (14\" x 8.5\")", "Letter Prop (6.57\" x 8.5\")", "A4 Prop (8.26\" x 5.84\")"}; static char *render_type[]= {"Full", "Minimal"}; static gdouble px[]={11.00, 11.68, 14.00, 8.50, 8.26}; static gdouble py[]={ 8.50, 8.26, 8.50, 6.57, 5.84}; /* * button/menu/entry activations.. */ static void render_clicked(GtkWidget *widget, gpointer which) { (void)widget; int i; for(i=0;i<4;i++) GLOBALS->target_mutex_renderopt_c_1[i]=0; i = (int)((intptr_t)which); GLOBALS->target_mutex_renderopt_c_1[i] = 1; /* mark our choice */ DEBUG(printf("picked: %s\n", render_targets[i])); } static void pagesize_clicked(GtkWidget *widget, gpointer which) { (void)widget; int i; for(i=0;i<5;i++) GLOBALS->page_mutex_renderopt_c_1[i]=0; GLOBALS->page_size_type_renderopt_c_1 = (int)((intptr_t)which); GLOBALS->page_mutex_renderopt_c_1[GLOBALS->page_size_type_renderopt_c_1] = 1; /* mark our choice */ DEBUG(printf("picked: %s\n", page_size[GLOBALS->page_size_type_renderopt_c_1])); } static void rendertype_clicked(GtkWidget *widget, gpointer which) { (void)widget; int i; for(i=0;i<3;i++) GLOBALS->render_mutex_renderopt_c_1[i]=0; i = (int)((intptr_t)which); GLOBALS->render_mutex_renderopt_c_1[i] = 1; /* mark our choice */ DEBUG(printf("picked: %s\n", render_type[i])); } static void ps_print_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; FILE *wave; if(GLOBALS->filesel_ok) { DEBUG(printf("PS Print Fini: %s\n", *GLOBALS->fileselbox_text)); if(!(wave=fopen(*GLOBALS->fileselbox_text,"wb"))) { fprintf(stderr, "Error opening PS output file '%s' for writing.\n",*GLOBALS->fileselbox_text); perror("Why"); errno=0; } else { print_ps_image(wave,px[GLOBALS->page_size_type_renderopt_c_1],py[GLOBALS->page_size_type_renderopt_c_1]); fclose(wave); } } } static void pdf_print_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; FILE *wave; FILE *wave2; if(GLOBALS->filesel_ok) { DEBUG(printf("PDF Print Fini: %s\n", *GLOBALS->fileselbox_text)); if(!(wave=fopen(*GLOBALS->fileselbox_text,"wb"))) { fprintf(stderr, "Error opening PDF output file '%s' for writing.\n",*GLOBALS->fileselbox_text); perror("Why"); errno=0; } else { int len = strlen(*GLOBALS->fileselbox_text) ; char *zname = malloc_2(len + 4); strcpy(zname, *GLOBALS->fileselbox_text); #ifdef MAC_INTEGRATION if((len > 4)&&(!strcmp(".pdf", zname+len-4))) { zname[len-4] = 0; len-=4; } #endif strcpy(zname+len, ".ps"); if(!(wave2=fopen(zname,"wb"))) { fprintf(stderr, "Error opening PS output tempfile '%s' for writing.\n",zname); perror("Why"); fclose(wave); unlink(*GLOBALS->fileselbox_text); errno=0; } else { char *sysname = malloc_2(7 + 1 + len + 3 + 1 + len + 1); int rc; #ifdef MAC_INTEGRATION sprintf(sysname, "pstopdf" /* 7 */ #else sprintf(sysname, "ps2pdf" /* 6 */ #endif " " /* 1 */ "%s" /* len + 3 */ " " /* 1 */ "%s" /* len */ , zname, *GLOBALS->fileselbox_text); print_ps_image(wave2,px[GLOBALS->page_size_type_renderopt_c_1],py[GLOBALS->page_size_type_renderopt_c_1]); fclose(wave2); fclose(wave); rc = system(sysname); if(rc) { printf("GTKWAVE | ERROR: rc for '%s' = %d\n", sysname, rc); unlink(*GLOBALS->fileselbox_text); } free_2(sysname); unlink(zname); } free_2(zname); } } } static void mif_print_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; FILE *wave; if(GLOBALS->filesel_ok) { DEBUG(printf("MIF Print Fini: %s\n", *GLOBALS->fileselbox_text)); if(!(wave=fopen(*GLOBALS->fileselbox_text,"wb"))) { fprintf(stderr, "Error opening MIF output file '%s' for writing.\n",*GLOBALS->fileselbox_text); perror("Why"); errno=0; } else { print_mif_image(wave,px[GLOBALS->page_size_type_renderopt_c_1],py[GLOBALS->page_size_type_renderopt_c_1]); fclose(wave); } } } #ifdef WAVE_GTK_UNIX_PRINT static void wave_GtkPrintJobCompleteFunc(GtkPrintJob *print_job, gpointer user_data, GError *error) { (void)print_job; (void)error; if(user_data) { const char *ban = "Sent print job"; char *buf = wave_alloca(strlen(ban) + strlen(user_data) + 32); sprintf(buf, "%s '%s'", ban, (char *)user_data); status_text(buf); unlink(user_data); } } #endif static void unix_print_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; #ifdef WAVE_GTK_UNIX_PRINT GtkWidget *ropt = gtk_print_unix_dialog_new("GTK Print UNIX Options", GTK_WINDOW(GLOBALS->mainwindow)); gint gd_rc; if(GLOBALS->gprs) { gtk_print_unix_dialog_set_settings(GTK_PRINT_UNIX_DIALOG(ropt), GLOBALS->gprs); } if(GLOBALS->gps) { gtk_print_unix_dialog_set_page_setup(GTK_PRINT_UNIX_DIALOG(ropt), GLOBALS->gps); } gtk_print_unix_dialog_set_manual_capabilities(GTK_PRINT_UNIX_DIALOG(ropt), GTK_PRINT_CAPABILITY_GENERATE_PS | GTK_PRINT_CAPABILITY_COPIES ); #ifdef MAC_INTEGRATION osx_menu_sensitivity(FALSE); #endif gd_rc = gtk_dialog_run(GTK_DIALOG (ropt)); if(gd_rc == GTK_RESPONSE_OK) { GtkPrinter *gp = gtk_print_unix_dialog_get_selected_printer(GTK_PRINT_UNIX_DIALOG(ropt)); GtkPrintSettings *gprs = gtk_print_unix_dialog_get_settings(GTK_PRINT_UNIX_DIALOG(ropt)); GtkPageSetup *gps = gtk_print_unix_dialog_get_page_setup(GTK_PRINT_UNIX_DIALOG(ropt)); GtkPrintJob *gpj = gtk_print_job_new(GLOBALS->loaded_file_name, gp, gprs, gps); gboolean job_stat; GError *job_error = NULL; FILE *wave; char *save_tmpfilename; int fd_dummy = -1; if(gtk_printer_accepts_ps(gp)) { save_tmpfilename = tmpnam_2(NULL, &fd_dummy); if(!(wave=fopen(save_tmpfilename, "r+b"))) { fprintf(stderr, "Error opening PS output file '%s' for writing.\n", save_tmpfilename); perror("Why"); errno=0; } else { if(GLOBALS->gp_tfn) free_2(GLOBALS->gp_tfn); GLOBALS->gp_tfn = strdup_2(save_tmpfilename); print_ps_image(wave,px[GLOBALS->page_size_type_renderopt_c_1],py[GLOBALS->page_size_type_renderopt_c_1]); fflush(wave); fclose(wave); job_stat = gtk_print_job_set_source_file(gpj, GLOBALS->gp_tfn, &job_error); if(job_stat) { gtk_print_job_send(gpj, wave_GtkPrintJobCompleteFunc, GLOBALS->gp_tfn, NULL); GLOBALS->gprs = gtk_print_settings_copy(gprs); GLOBALS->gps = gtk_page_setup_copy(gps); } else { unlink(GLOBALS->gp_tfn); } } #if !defined _MSC_VER && !defined __MINGW32__ free_2(save_tmpfilename); #endif if(fd_dummy >=0) close(fd_dummy); } else { status_text("gtk_printer_accepts_ps() == FALSE, cannot print."); } } else if(gd_rc == GTK_RESPONSE_APPLY) { status_text("Preview not available."); } gtk_widget_destroy(ropt); #ifdef MAC_INTEGRATION osx_menu_sensitivity(TRUE); #endif #endif } static void ok_callback(void) { GLOBALS->ps_fullpage=GLOBALS->render_mutex_renderopt_c_1[0]; if(GLOBALS->target_mutex_renderopt_c_1[0]) { fileselbox("Print To PDF File",&GLOBALS->filesel_print_pdf_renderopt_c_1,GTK_SIGNAL_FUNC(pdf_print_cleanup), GTK_SIGNAL_FUNC(NULL), "*.pdf", 1); } else if(GLOBALS->target_mutex_renderopt_c_1[1]) { fileselbox("Print To PS File",&GLOBALS->filesel_print_ps_renderopt_c_1,GTK_SIGNAL_FUNC(ps_print_cleanup), GTK_SIGNAL_FUNC(NULL), "*.ps", 1); } else if(GLOBALS->target_mutex_renderopt_c_1[2]) { fileselbox("Print To MIF File",&GLOBALS->filesel_print_mif_renderopt_c_1,GTK_SIGNAL_FUNC(mif_print_cleanup), GTK_SIGNAL_FUNC(NULL), "*.fm", 1); } else { unix_print_cleanup(NULL,NULL); } } static void destroy_callback(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; GLOBALS->is_active_renderopt_c_3=0; gtk_widget_destroy(GLOBALS->window_renderopt_c_6); GLOBALS->window_renderopt_c_6 = NULL; } void renderbox(char *title) { GtkWidget *menu, *menuitem, *optionmenu; GSList *group; GtkWidget *vbox, *hbox, *small_hbox; GtkWidget *button1, *button2; int i; /* fix problem where ungrab doesn't occur if button pressed + simultaneous accelerator key occurs */ if(GLOBALS->in_button_press_wavewindow_c_1) { gdk_pointer_ungrab(GDK_CURRENT_TIME); } if(GLOBALS->wave_script_args) { char *s1 = NULL; char *s2 = NULL; char *s3 = NULL; while((!s1)&&(GLOBALS->wave_script_args->curr)) s1 = wave_script_args_fgetmalloc_stripspaces(GLOBALS->wave_script_args); while((!s2)&&(GLOBALS->wave_script_args->curr)) s2 = wave_script_args_fgetmalloc_stripspaces(GLOBALS->wave_script_args); while((!s3)&&(GLOBALS->wave_script_args->curr)) s3 = wave_script_args_fgetmalloc_stripspaces(GLOBALS->wave_script_args); if(s1 && s2 && s3) { memset(GLOBALS->target_mutex_renderopt_c_1, 0, 2); GLOBALS->target_mutex_renderopt_c_1[0] = 1; /* PS */ #ifdef WAVE_GTK_UNIX_PRINT for(i=0;i<4;i++) #else for(i=0;i<3;i++) #endif { if(!strcmp(s1, render_targets[i])) { fprintf(stderr, "GTKWAVE | Print using '%s'\n", render_targets[i]); memset(GLOBALS->target_mutex_renderopt_c_1, 0, 4); GLOBALS->target_mutex_renderopt_c_1[i] = 1; break; } } memset(GLOBALS->page_mutex_renderopt_c_1, 0, 5); GLOBALS->page_mutex_renderopt_c_1[0] = 1; /* 8.5 x 11 */ GLOBALS->page_size_type_renderopt_c_1 = 0; for(i=0;i<5;i++) { if(!strcmp(s2, page_size[i])) { fprintf(stderr, "GTKWAVE | Print using '%s'\n", page_size[i]); memset(GLOBALS->page_mutex_renderopt_c_1, 0, 5); GLOBALS->page_mutex_renderopt_c_1[i] = 1; GLOBALS->page_size_type_renderopt_c_1 = i; break; } } memset(GLOBALS->render_mutex_renderopt_c_1, 0, 3); GLOBALS->render_mutex_renderopt_c_1[0] = 1; /* Full */ for(i=0;i<2;i++) { if(!strcmp(s3, render_type[i])) { fprintf(stderr, "GTKWAVE | Print using '%s'\n", render_type[i]); memset(GLOBALS->render_mutex_renderopt_c_1, 0, 3); GLOBALS->render_mutex_renderopt_c_1[i] = 1; break; } } free_2(s1); free_2(s2); free_2(s3); ok_callback(); } else { fprintf(stderr, "Missing script entries for renderbox, exiting.\n"); exit(255); } return; } if(GLOBALS->is_active_renderopt_c_3) { if(GLOBALS->window_renderopt_c_6) { gdk_window_raise(GLOBALS->window_renderopt_c_6->window); } return; } GLOBALS->is_active_renderopt_c_3=1; /* create a new window */ GLOBALS->window_renderopt_c_6 = gtk_window_new(GLOBALS->disable_window_manager ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL); install_focus_cb(GLOBALS->window_renderopt_c_6, ((char *)&GLOBALS->window_renderopt_c_6) - ((char *)GLOBALS)); gtk_window_set_title(GTK_WINDOW (GLOBALS->window_renderopt_c_6), title); gtk_widget_set_usize( GTK_WIDGET (GLOBALS->window_renderopt_c_6), 420, -1); gtkwave_signal_connect(GTK_OBJECT (GLOBALS->window_renderopt_c_6), "delete_event",(GtkSignalFunc) destroy_callback, NULL); gtk_window_set_policy(GTK_WINDOW(GLOBALS->window_renderopt_c_6), FALSE, FALSE, FALSE); vbox = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (GLOBALS->window_renderopt_c_6), vbox); gtk_widget_show (vbox); small_hbox = gtk_hbox_new (TRUE, 0); gtk_widget_show (small_hbox); menu = gtk_menu_new (); group=NULL; for(i=0;i<4;i++) { GLOBALS->target_mutex_renderopt_c_1[i]=0; #ifndef WAVE_GTK_UNIX_PRINT if(i==3) { break; } #endif menuitem = gtk_radio_menu_item_new_with_label (group, render_targets[i]); group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem)); gtk_menu_append (GTK_MENU (menu), menuitem); gtk_widget_show (menuitem); gtkwave_signal_connect(GTK_OBJECT (menuitem), "activate", GTK_SIGNAL_FUNC(render_clicked), (void *)((intptr_t)i)); } GLOBALS->target_mutex_renderopt_c_1[0]=1; /* "ps" */ optionmenu = gtk_option_menu_new (); gtk_option_menu_set_menu (GTK_OPTION_MENU (optionmenu), menu); gtk_box_pack_start (GTK_BOX (small_hbox), optionmenu, TRUE, FALSE, 0); gtk_widget_show (optionmenu); menu = gtk_menu_new (); group=NULL; for(i=0;i<5;i++) { menuitem = gtk_radio_menu_item_new_with_label (group, page_size[i]); group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem)); gtk_menu_append (GTK_MENU (menu), menuitem); gtk_widget_show (menuitem); gtkwave_signal_connect(GTK_OBJECT (menuitem), "activate", GTK_SIGNAL_FUNC(pagesize_clicked), (void *)((intptr_t)i)); GLOBALS->page_mutex_renderopt_c_1[i]=0; } GLOBALS->page_mutex_renderopt_c_1[0]=1; /* "letter" */ optionmenu = gtk_option_menu_new (); gtk_option_menu_set_menu (GTK_OPTION_MENU (optionmenu), menu); gtk_box_pack_start (GTK_BOX (small_hbox), optionmenu, TRUE, FALSE, 0); gtk_widget_show (optionmenu); gtk_box_pack_start (GTK_BOX (vbox), small_hbox, FALSE, FALSE, 0); menu = gtk_menu_new (); group=NULL; for(i=0;i<2;i++) { menuitem = gtk_radio_menu_item_new_with_label (group, render_type[i]); group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem)); gtk_menu_append (GTK_MENU (menu), menuitem); gtk_widget_show (menuitem); gtkwave_signal_connect(GTK_OBJECT (menuitem), "activate", GTK_SIGNAL_FUNC(rendertype_clicked), (void *)((intptr_t)i)); GLOBALS->render_mutex_renderopt_c_1[i]=0; } GLOBALS->render_mutex_renderopt_c_1[0]=1; /* "full" */ optionmenu = gtk_option_menu_new (); gtk_option_menu_set_menu (GTK_OPTION_MENU (optionmenu), menu); gtk_box_pack_start (GTK_BOX (small_hbox), optionmenu, TRUE, FALSE, 0); gtk_widget_show (optionmenu); hbox = gtk_hbox_new (TRUE, 0); gtk_widget_show (hbox); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); button1 = gtk_button_new_with_label ("Select Output File"); gtk_widget_set_usize(button1, 100, -1); gtkwave_signal_connect(GTK_OBJECT (button1), "clicked", GTK_SIGNAL_FUNC(ok_callback), NULL); gtk_widget_show (button1); gtk_container_add (GTK_CONTAINER (hbox), button1); GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT); gtkwave_signal_connect_object (GTK_OBJECT (button1), "realize", (GtkSignalFunc) gtk_widget_grab_default, GTK_OBJECT (button1)); button2 = gtk_button_new_with_label ("Exit"); gtk_widget_set_usize(button2, 100, -1); gtkwave_signal_connect(GTK_OBJECT (button2), "clicked", GTK_SIGNAL_FUNC(destroy_callback), NULL); GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT); gtk_widget_show (button2); gtk_container_add (GTK_CONTAINER (hbox), button2); gtk_widget_show(GLOBALS->window_renderopt_c_6); } gtkwave-3.3.66/src/version.h0000664000076400007640000000067112477637005015243 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2010-2015. * * 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. */ #ifndef WAVE_VERSION_H #define WAVE_VERSION_H #define WAVE_VERSION_INFO "GTKWave Analyzer v" PACKAGE_VERSION " (w)1999-2015 BSI" #endif gtkwave-3.3.66/src/renderopt.h0000664000076400007640000000060211523063250015534 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2010 * * 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. */ #ifndef WAVE_RENDEROPT_H #define WAVE_RENDEROPT_H void renderbox(char *title); #endif gtkwave-3.3.66/src/lx2.c0000664000076400007640000005265712360623564014265 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2003-2012. * * 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. */ #include "globals.h" #include #include #include "lx2.h" #ifndef _MSC_VER #include #endif #include #include #include #include "symbol.h" #include "vcd.h" #include "lxt.h" #include "vzt.h" #include "lxt2_read.h" #include "debug.h" #include "busy.h" #include "hierpack.h" #include "fst.h" /* * mainline */ TimeType lx2_main(char *fname, char *skip_start, char *skip_end) { int i; struct Node *n; struct symbol *s, *prevsymroot=NULL, *prevsym=NULL; signed char scale; unsigned int numalias = 0; struct symbol *sym_block = NULL; struct Node *node_block = NULL; char **f_name = NULL; GLOBALS->lx2_lx2_c_1 = lxt2_rd_init(fname); if(!GLOBALS->lx2_lx2_c_1) { return(LLDescriptor(0)); /* look at GLOBALS->lx2_lx2_c_1 in caller for success status... */ } /* SPLASH */ splash_create(); /* lxt2_rd_set_max_block_mem_usage(lx2, 0); */ scale=(signed char)lxt2_rd_get_timescale(GLOBALS->lx2_lx2_c_1); exponent_to_time_scale(scale); GLOBALS->global_time_offset = lxt2_rd_get_timezero(GLOBALS->lx2_lx2_c_1); GLOBALS->numfacs=lxt2_rd_get_num_facs(GLOBALS->lx2_lx2_c_1); GLOBALS->mvlfacs_lx2_c_1=(struct fac *)calloc_2(GLOBALS->numfacs,sizeof(struct fac)); f_name = calloc_2(F_NAME_MODULUS+1,sizeof(char *)); GLOBALS->lx2_table_lx2_c_1=(struct lx2_entry *)calloc_2(GLOBALS->numfacs, sizeof(struct lx2_entry)); sym_block = (struct symbol *)calloc_2(GLOBALS->numfacs, sizeof(struct symbol)); node_block=(struct Node *)calloc_2(GLOBALS->numfacs,sizeof(struct Node)); for(i=0;inumfacs;i++) { GLOBALS->mvlfacs_lx2_c_1[i].node_alias=lxt2_rd_get_fac_rows(GLOBALS->lx2_lx2_c_1, i); node_block[i].msi=lxt2_rd_get_fac_msb(GLOBALS->lx2_lx2_c_1, i); node_block[i].lsi=lxt2_rd_get_fac_lsb(GLOBALS->lx2_lx2_c_1, i); GLOBALS->mvlfacs_lx2_c_1[i].flags=lxt2_rd_get_fac_flags(GLOBALS->lx2_lx2_c_1, i); GLOBALS->mvlfacs_lx2_c_1[i].len=lxt2_rd_get_fac_len(GLOBALS->lx2_lx2_c_1, i); } fprintf(stderr, LXT2_RDLOAD"Finished building %d facs.\n", GLOBALS->numfacs); /* SPLASH */ splash_sync(1, 5); GLOBALS->first_cycle_lx2_c_1 = (TimeType) lxt2_rd_get_start_time(GLOBALS->lx2_lx2_c_1) * GLOBALS->time_scale; GLOBALS->last_cycle_lx2_c_1 = (TimeType) lxt2_rd_get_end_time(GLOBALS->lx2_lx2_c_1) * GLOBALS->time_scale; GLOBALS->total_cycles_lx2_c_1 = GLOBALS->last_cycle_lx2_c_1 - GLOBALS->first_cycle_lx2_c_1 + 1; /* do your stuff here..all useful info has been initialized by now */ if(!GLOBALS->hier_was_explicitly_set) /* set default hierarchy split char */ { GLOBALS->hier_delimeter='.'; } if(GLOBALS->numfacs) { char *fnam = lxt2_rd_get_facname(GLOBALS->lx2_lx2_c_1, 0); int flen = strlen(fnam); f_name[0]=malloc_2(flen+1); strcpy(f_name[0], fnam); } for(i=0;inumfacs;i++) { char buf[65537]; char *str; struct fac *f; if(i!=(GLOBALS->numfacs-1)) { char *fnam = lxt2_rd_get_facname(GLOBALS->lx2_lx2_c_1, i+1); int flen = strlen(fnam); f_name[(i+1)&F_NAME_MODULUS]=malloc_2(flen+1); strcpy(f_name[(i+1)&F_NAME_MODULUS], fnam); } if(i>1) { free_2(f_name[(i-2)&F_NAME_MODULUS]); f_name[(i-2)&F_NAME_MODULUS] = NULL; } if(GLOBALS->mvlfacs_lx2_c_1[i].flags&LXT2_RD_SYM_F_ALIAS) { int alias = GLOBALS->mvlfacs_lx2_c_1[i].node_alias; f=GLOBALS->mvlfacs_lx2_c_1+alias; while(f->flags&LXT2_RD_SYM_F_ALIAS) { f=GLOBALS->mvlfacs_lx2_c_1+f->node_alias; } numalias++; } else { f=GLOBALS->mvlfacs_lx2_c_1+i; } if((f->len>1)&& (!(f->flags&(LXT2_RD_SYM_F_INTEGER|LXT2_RD_SYM_F_DOUBLE|LXT2_RD_SYM_F_STRING))) ) { int len = sprintf(buf, "%s[%d:%d]", f_name[(i)&F_NAME_MODULUS],node_block[i].msi, node_block[i].lsi); str=malloc_2(len+1); if(!GLOBALS->alt_hier_delimeter) { strcpy(str, buf); } else { strcpy_vcdalt(str, buf, GLOBALS->alt_hier_delimeter); } s=&sym_block[i]; symadd_name_exists_sym_exists(s,str,0); prevsymroot = prevsym = NULL; } else { int gatecmp = (f->len==1) && (!(f->flags&(LXT2_RD_SYM_F_INTEGER|LXT2_RD_SYM_F_DOUBLE|LXT2_RD_SYM_F_STRING))) && (node_block[i].msi!=-1) && (node_block[i].lsi!=-1); int revcmp = gatecmp && (i) && (!strcmp(f_name[(i)&F_NAME_MODULUS], f_name[(i-1)&F_NAME_MODULUS])); if(gatecmp) { int len = sprintf(buf, "%s[%d]", f_name[(i)&F_NAME_MODULUS],node_block[i].msi); str=malloc_2(len+1); if(!GLOBALS->alt_hier_delimeter) { strcpy(str, buf); } else { strcpy_vcdalt(str, buf, GLOBALS->alt_hier_delimeter); } s=&sym_block[i]; symadd_name_exists_sym_exists(s,str,0); if((prevsym)&&(revcmp)&&(!strchr(f_name[(i)&F_NAME_MODULUS], '\\'))) /* allow chaining for search functions.. */ { prevsym->vec_root = prevsymroot; prevsym->vec_chain = s; s->vec_root = prevsymroot; prevsym = s; } else { prevsymroot = prevsym = s; } } else { str=malloc_2(strlen(f_name[(i)&F_NAME_MODULUS])+1); if(!GLOBALS->alt_hier_delimeter) { strcpy(str, f_name[(i)&F_NAME_MODULUS]); } else { strcpy_vcdalt(str, f_name[(i)&F_NAME_MODULUS], GLOBALS->alt_hier_delimeter); } s=&sym_block[i]; symadd_name_exists_sym_exists(s,str,0); prevsymroot = prevsym = NULL; if(f->flags&LXT2_RD_SYM_F_INTEGER) { node_block[i].msi=31; node_block[i].lsi=0; GLOBALS->mvlfacs_lx2_c_1[i].len=32; } } } n=&node_block[i]; n->nname=s->name; n->mv.mvlfac = GLOBALS->mvlfacs_lx2_c_1+i; GLOBALS->mvlfacs_lx2_c_1[i].working_node = n; if((f->len>1)||(f->flags&(LXT2_RD_SYM_F_DOUBLE|LXT2_RD_SYM_F_STRING))) { n->extvals = 1; } n->head.time=-1; /* mark 1st node as negative time */ n->head.v.h_val=AN_X; s->n=n; } for(i=0;i<=F_NAME_MODULUS;i++) { if(f_name[(i)&F_NAME_MODULUS]) { free_2(f_name[(i)&F_NAME_MODULUS]); f_name[(i)&F_NAME_MODULUS] = NULL; } } free_2(f_name); f_name = NULL; /* SPLASH */ splash_sync(2, 5); GLOBALS->facs=(struct symbol **)malloc_2(GLOBALS->numfacs*sizeof(struct symbol *)); if(GLOBALS->fast_tree_sort) { for(i=0;inumfacs;i++) { int len; GLOBALS->facs[i]=&sym_block[i]; if((len=strlen(GLOBALS->facs[i]->name))>GLOBALS->longestname) GLOBALS->longestname=len; } if(numalias) { int idx_lft = 0; int idx_lftmax = GLOBALS->numfacs - numalias; int idx_rgh = GLOBALS->numfacs - numalias; struct symbol **facs_merge=(struct symbol **)malloc_2(GLOBALS->numfacs*sizeof(struct symbol *)); fprintf(stderr, LXT2_RDLOAD"Merging in %d aliases.\n", numalias); for(i=0;inumfacs;i++) /* fix possible tail appended aliases by remerging in partial one pass merge sort */ { if(strcmp(GLOBALS->facs[idx_lft]->name, GLOBALS->facs[idx_rgh]->name) <= 0) { facs_merge[i] = GLOBALS->facs[idx_lft++]; if(idx_lft == idx_lftmax) { for(i++;inumfacs;i++) { facs_merge[i] = GLOBALS->facs[idx_rgh++]; } } } else { facs_merge[i] = GLOBALS->facs[idx_rgh++]; if(idx_rgh == GLOBALS->numfacs) { for(i++;inumfacs;i++) { facs_merge[i] = GLOBALS->facs[idx_lft++]; } } } } free_2(GLOBALS->facs); GLOBALS->facs = facs_merge; } /* SPLASH */ splash_sync(3, 5); fprintf(stderr, LXT2_RDLOAD"Building facility hierarchy tree.\n"); init_tree(); for(i=0;inumfacs;i++) { int esc = 0; char *subst = GLOBALS->facs[i]->name; char ch; while((ch=(*subst))) { if(ch==GLOBALS->hier_delimeter) { if(esc) *subst = VCDNAM_ESCAPE; } else if(ch=='\\') { esc = 1; GLOBALS->escaped_names_found_vcd_c_1 = 1; } subst++; } build_tree_from_name(GLOBALS->facs[i]->name, i); } /* SPLASH */ splash_sync(4, 5); if(GLOBALS->escaped_names_found_vcd_c_1) { for(i=0;inumfacs;i++) { char *subst, ch; subst=GLOBALS->facs[i]->name; while((ch=(*subst))) { if(ch==VCDNAM_ESCAPE) { *subst=GLOBALS->hier_delimeter; } /* restore back to normal */ subst++; } } } treegraft(&GLOBALS->treeroot); fprintf(stderr, LXT2_RDLOAD"Sorting facility hierarchy tree.\n"); treesort(GLOBALS->treeroot, NULL); /* SPLASH */ splash_sync(5, 5); order_facs_from_treesort(GLOBALS->treeroot, &GLOBALS->facs); if(GLOBALS->escaped_names_found_vcd_c_1) { treenamefix(GLOBALS->treeroot); } GLOBALS->facs_are_sorted=1; } else { for(i=0;inumfacs;i++) { char *subst, ch; int len; int esc = 0; GLOBALS->facs[i]=&sym_block[i]; if((len=strlen(subst=GLOBALS->facs[i]->name))>GLOBALS->longestname) GLOBALS->longestname=len; while((ch=(*subst))) { #ifdef WAVE_HIERFIX if(ch==GLOBALS->hier_delimeter) { *subst=(!esc) ? VCDNAM_HIERSORT : VCDNAM_ESCAPE; } /* forces sort at hier boundaries */ #else if((ch==GLOBALS->hier_delimeter)&&(esc)) { *subst = VCDNAM_ESCAPE; } /* forces sort at hier boundaries */ #endif else if(ch=='\\') { esc = 1; GLOBALS->escaped_names_found_vcd_c_1 = 1; } subst++; } } /* SPLASH */ splash_sync(3, 5); fprintf(stderr, LXT2_RDLOAD"Sorting facilities at hierarchy boundaries.\n"); wave_heapsort(GLOBALS->facs,GLOBALS->numfacs); #ifdef WAVE_HIERFIX for(i=0;inumfacs;i++) { char *subst, ch; subst=GLOBALS->facs[i]->name; while((ch=(*subst))) { if(ch==VCDNAM_HIERSORT) { *subst=GLOBALS->hier_delimeter; } /* restore back to normal */ subst++; } } #endif GLOBALS->facs_are_sorted=1; /* SPLASH */ splash_sync(4, 5); fprintf(stderr, LXT2_RDLOAD"Building facility hierarchy tree.\n"); init_tree(); for(i=0;inumfacs;i++) { char *nf = GLOBALS->facs[i]->name; build_tree_from_name(nf, i); } /* SPLASH */ splash_sync(5, 5); if(GLOBALS->escaped_names_found_vcd_c_1) { for(i=0;inumfacs;i++) { char *subst, ch; subst=GLOBALS->facs[i]->name; while((ch=(*subst))) { if(ch==VCDNAM_ESCAPE) { *subst=GLOBALS->hier_delimeter; } /* restore back to normal */ subst++; } } } treegraft(&GLOBALS->treeroot); treesort(GLOBALS->treeroot, NULL); if(GLOBALS->escaped_names_found_vcd_c_1) { treenamefix(GLOBALS->treeroot); } } GLOBALS->min_time = GLOBALS->first_cycle_lx2_c_1; GLOBALS->max_time=GLOBALS->last_cycle_lx2_c_1; GLOBALS->is_lx2 = LXT2_IS_LXT2; if(skip_start || skip_end) { TimeType b_start, b_end; if(!skip_start) b_start = GLOBALS->min_time; else b_start = unformat_time(skip_start, GLOBALS->time_dimension); if(!skip_end) b_end = GLOBALS->max_time; else b_end = unformat_time(skip_end, GLOBALS->time_dimension); if(b_startmin_time) b_start = GLOBALS->min_time; else if(b_start>GLOBALS->max_time) b_start = GLOBALS->max_time; if(b_endmin_time) b_end = GLOBALS->min_time; else if(b_end>GLOBALS->max_time) b_end = GLOBALS->max_time; if(b_start > b_end) { TimeType tmp_time = b_start; b_start = b_end; b_end = tmp_time; } if(!lxt2_rd_limit_time_range(GLOBALS->lx2_lx2_c_1, b_start, b_end)) { fprintf(stderr, LXT2_RDLOAD"--begin/--end options yield zero blocks, ignoring.\n"); lxt2_rd_unlimit_time_range(GLOBALS->lx2_lx2_c_1); } else { GLOBALS->min_time = b_start; GLOBALS->max_time = b_end; } } /* SPLASH */ splash_finalize(); return(GLOBALS->max_time); } /* * lx2 callback (only does bits for now) */ static void lx2_callback(struct lxt2_rd_trace **lt, lxtint64_t *tim, lxtint32_t *facidx, char **value) { (void)lt; struct HistEnt *htemp = histent_calloc(); struct lx2_entry *l2e = GLOBALS->lx2_table_lx2_c_1+(*facidx); struct fac *f = GLOBALS->mvlfacs_lx2_c_1+(*facidx); GLOBALS->busycnt_lx2_c_1++; if(GLOBALS->busycnt_lx2_c_1==WAVE_BUSY_ITER) { busy_window_refresh(); GLOBALS->busycnt_lx2_c_1 = 0; } /* fprintf(stderr, "%lld %d %s\n", *tim, *facidx, *value); */ if(!(f->flags&(LXT2_RD_SYM_F_DOUBLE|LXT2_RD_SYM_F_STRING))) { if(f->len>1) { htemp->v.h_vector = (char *)malloc_2(f->len); memcpy(htemp->v.h_vector, *value, f->len); } else { switch(**value) { case '0': htemp->v.h_val = AN_0; break; case '1': htemp->v.h_val = AN_1; break; case 'Z': case 'z': htemp->v.h_val = AN_Z; break; default: htemp->v.h_val = AN_X; break; } } } else if(f->flags&LXT2_RD_SYM_F_DOUBLE) { #ifdef WAVE_HAS_H_DOUBLE sscanf(*value, "%lg", &htemp->v.h_double); #else double *d = malloc_2(sizeof(double)); sscanf(*value, "%lg", d); htemp->v.h_vector = (char *)d; #endif htemp->flags = HIST_REAL; } else /* string */ { char *s = malloc_2(strlen(*value)+1); strcpy(s, *value); htemp->v.h_vector = s; htemp->flags = HIST_REAL|HIST_STRING; } htemp->time = (*tim) * (GLOBALS->time_scale); if(l2e->histent_head) { l2e->histent_curr->next = htemp; l2e->histent_curr = htemp; } else { l2e->histent_head = l2e->histent_curr = htemp; } l2e->numtrans++; } /* * this is the black magic that handles aliased signals... */ static void lx2_resolver(nptr np, nptr resolve) { np->extvals = resolve->extvals; np->msi = resolve->msi; np->lsi = resolve->lsi; memcpy(&np->head, &resolve->head, sizeof(struct HistEnt)); np->curr = resolve->curr; np->harray = resolve->harray; np->numhist = resolve->numhist; np->mv.mvlfac=NULL; } /* * actually import an lx2 trace but don't do it if it's already been imported */ void import_lx2_trace(nptr np) { struct HistEnt *htemp, *histent_tail; int len, i; struct fac *f; int txidx; nptr nold = np; switch(GLOBALS->is_lx2) { #ifdef AET2_IS_PRESENT case LXT2_IS_AET2: import_ae2_trace(np); return; #endif case LXT2_IS_VZT: import_vzt_trace(np); return; case LXT2_IS_VLIST: import_vcd_trace(np); return; case LXT2_IS_FST: import_fst_trace(np); return; case LXT2_IS_FSDB: import_extload_trace(np); return; default: break; /* fallthrough */ } if(!(f=np->mv.mvlfac)) return; /* already imported */ txidx = f - GLOBALS->mvlfacs_lx2_c_1; if(np->mv.mvlfac->flags&LXT2_RD_SYM_F_ALIAS) { txidx = lxt2_rd_get_alias_root(GLOBALS->lx2_lx2_c_1, txidx); np = GLOBALS->mvlfacs_lx2_c_1[txidx].working_node; if(!(f=np->mv.mvlfac)) { lx2_resolver(nold, np); return; /* already imported */ } } fprintf(stderr, "Import: %s\n", np->nname); /* new stuff */ len = np->mv.mvlfac->len; if(f->node_alias <= 1) /* sorry, arrays not supported, but lx2 doesn't support them yet either */ { lxt2_rd_set_fac_process_mask(GLOBALS->lx2_lx2_c_1, txidx); lxt2_rd_iter_blocks(GLOBALS->lx2_lx2_c_1, lx2_callback, NULL); lxt2_rd_clr_fac_process_mask(GLOBALS->lx2_lx2_c_1, txidx); } histent_tail = htemp = histent_calloc(); if(len>1) { htemp->v.h_vector = (char *)malloc_2(len); for(i=0;iv.h_vector[i] = AN_Z; } else { htemp->v.h_val = AN_Z; /* z */ } htemp->time = MAX_HISTENT_TIME; htemp = histent_calloc(); if(len>1) { htemp->v.h_vector = (char *)malloc_2(len); for(i=0;iv.h_vector[i] = AN_X; } else { htemp->v.h_val = AN_X; /* x */ } htemp->time = MAX_HISTENT_TIME-1; htemp->next = histent_tail; if(GLOBALS->lx2_table_lx2_c_1[txidx].histent_curr) { GLOBALS->lx2_table_lx2_c_1[txidx].histent_curr->next = htemp; htemp = GLOBALS->lx2_table_lx2_c_1[txidx].histent_head; } if(!(f->flags&(LXT2_RD_SYM_F_DOUBLE|LXT2_RD_SYM_F_STRING))) { if(len>1) { np->head.v.h_vector = (char *)malloc_2(len); for(i=0;ihead.v.h_vector[i] = AN_X; } else { np->head.v.h_val = AN_X; /* x */ } } else { np->head.flags = HIST_REAL; if(f->flags&LXT2_RD_SYM_F_STRING) np->head.flags |= HIST_STRING; } { struct HistEnt *htemp2 = histent_calloc(); htemp2->time = -1; if(len>1) { htemp2->v.h_vector = htemp->v.h_vector; } else { htemp2->v.h_val = htemp->v.h_val; } htemp2->next = htemp; htemp = htemp2; GLOBALS->lx2_table_lx2_c_1[txidx].numtrans++; } np->head.time = -2; np->head.next = htemp; np->numhist=GLOBALS->lx2_table_lx2_c_1[txidx].numtrans +2 /*endcap*/ +1 /*frontcap*/; memset(GLOBALS->lx2_table_lx2_c_1+txidx, 0, sizeof(struct lx2_entry)); /* zero it out */ np->curr = histent_tail; np->mv.mvlfac = NULL; /* it's imported and cached so we can forget it's an mvlfac now */ if(nold!=np) { lx2_resolver(nold, np); } } /* * pre-import many traces at once so function above doesn't have to iterate... */ void lx2_set_fac_process_mask(nptr np) { struct fac *f; int txidx; switch(GLOBALS->is_lx2) { #ifdef AET2_IS_PRESENT case LXT2_IS_AET2: ae2_set_fac_process_mask(np); return; #endif case LXT2_IS_VZT: vzt_set_fac_process_mask(np); return; case LXT2_IS_VLIST: vcd_set_fac_process_mask(np); return; case LXT2_IS_FST: fst_set_fac_process_mask(np); return; case LXT2_IS_FSDB: fsdb_set_fac_process_mask(np); return; default: break; /* fallthrough */ } if(!(f=np->mv.mvlfac)) return; /* already imported */ txidx = f-GLOBALS->mvlfacs_lx2_c_1; if(np->mv.mvlfac->flags&LXT2_RD_SYM_F_ALIAS) { txidx = lxt2_rd_get_alias_root(GLOBALS->lx2_lx2_c_1, txidx); np = GLOBALS->mvlfacs_lx2_c_1[txidx].working_node; if(!(np->mv.mvlfac)) return; /* already imported */ } if(np->mv.mvlfac->node_alias <= 1) /* sorry, arrays not supported, but lx2 doesn't support them yet either */ { lxt2_rd_set_fac_process_mask(GLOBALS->lx2_lx2_c_1, txidx); GLOBALS->lx2_table_lx2_c_1[txidx].np = np; } } void lx2_import_masked(void) { int txidx, i, cnt; switch(GLOBALS->is_lx2) { #ifdef AET2_IS_PRESENT case LXT2_IS_AET2: ae2_import_masked(); return; #endif case LXT2_IS_VZT: vzt_import_masked(); return; case LXT2_IS_VLIST: vcd_import_masked(); return; case LXT2_IS_FST: fst_import_masked(); return; case LXT2_IS_FSDB: fsdb_import_masked(); return; default: break; /* fallthrough */ } cnt = 0; for(txidx=0;txidxnumfacs;txidx++) { if(lxt2_rd_get_fac_process_mask(GLOBALS->lx2_lx2_c_1, txidx)) { cnt++; } } if(!cnt) return; if(cnt>100) { fprintf(stderr, LXT2_RDLOAD"Extracting %d traces\n", cnt); } set_window_busy(NULL); lxt2_rd_iter_blocks(GLOBALS->lx2_lx2_c_1, lx2_callback, NULL); set_window_idle(NULL); for(txidx=0;txidxnumfacs;txidx++) { if(lxt2_rd_get_fac_process_mask(GLOBALS->lx2_lx2_c_1, txidx)) { struct HistEnt *htemp, *histent_tail; struct fac *f = GLOBALS->mvlfacs_lx2_c_1+txidx; int len = f->len; nptr np = GLOBALS->lx2_table_lx2_c_1[txidx].np; histent_tail = htemp = histent_calloc(); if(len>1) { htemp->v.h_vector = (char *)malloc_2(len); for(i=0;iv.h_vector[i] = AN_Z; } else { htemp->v.h_val = AN_Z; /* z */ } htemp->time = MAX_HISTENT_TIME; htemp = histent_calloc(); if(len>1) { htemp->v.h_vector = (char *)malloc_2(len); for(i=0;iv.h_vector[i] = AN_X; } else { htemp->v.h_val = AN_X; /* x */ } htemp->time = MAX_HISTENT_TIME-1; htemp->next = histent_tail; if(GLOBALS->lx2_table_lx2_c_1[txidx].histent_curr) { GLOBALS->lx2_table_lx2_c_1[txidx].histent_curr->next = htemp; htemp = GLOBALS->lx2_table_lx2_c_1[txidx].histent_head; } if(!(f->flags&(LXT2_RD_SYM_F_DOUBLE|LXT2_RD_SYM_F_STRING))) { if(len>1) { np->head.v.h_vector = (char *)malloc_2(len); for(i=0;ihead.v.h_vector[i] = AN_X; } else { np->head.v.h_val = AN_X; /* x */ } } else { np->head.flags = HIST_REAL; if(f->flags&LXT2_RD_SYM_F_STRING) np->head.flags |= HIST_STRING; } { struct HistEnt *htemp2 = histent_calloc(); htemp2->time = -1; if(len>1) { htemp2->v.h_vector = htemp->v.h_vector; } else { htemp2->v.h_val = htemp->v.h_val; } htemp2->next = htemp; htemp = htemp2; GLOBALS->lx2_table_lx2_c_1[txidx].numtrans++; } np->head.time = -2; np->head.next = htemp; np->numhist=GLOBALS->lx2_table_lx2_c_1[txidx].numtrans +2 /*endcap*/ +1 /*frontcap*/; memset(GLOBALS->lx2_table_lx2_c_1+txidx, 0, sizeof(struct lx2_entry)); /* zero it out */ np->curr = histent_tail; np->mv.mvlfac = NULL; /* it's imported and cached so we can forget it's an mvlfac now */ lxt2_rd_clr_fac_process_mask(GLOBALS->lx2_lx2_c_1, txidx); } } } gtkwave-3.3.66/src/libz/0000775000076400007640000000000012546303363014333 5ustar bybellbybellgtkwave-3.3.66/src/libz/Makefile.in0000664000076400007640000004257012261434733016410 0ustar bybellbybell# Makefile.in generated by automake 1.13.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 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__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } 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 = : subdir = src/libz DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp README ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru AM_V_AR = $(am__v_AR_@AM_V@) am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) am__v_AR_0 = @echo " AR " $@; am__v_AR_1 = libz_a_AR = $(AR) $(ARFLAGS) libz_a_LIBADD = am_libz_a_OBJECTS = adler32.$(OBJEXT) gzread.$(OBJEXT) trees.$(OBJEXT) \ zutil.$(OBJEXT) compress.$(OBJEXT) example.$(OBJEXT) \ gzwrite.$(OBJEXT) inflate.$(OBJEXT) crc32.$(OBJEXT) \ gzclose.$(OBJEXT) infback.$(OBJEXT) uncompr.$(OBJEXT) \ inffast.$(OBJEXT) inftrees.$(OBJEXT) deflate.$(OBJEXT) \ gzlib.$(OBJEXT) libz_a_OBJECTS = $(am_libz_a_OBJECTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f 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 = $(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 = SOURCES = $(libz_a_SOURCES) DIST_SOURCES = $(libz_a_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)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AET2_CFLAGS = @AET2_CFLAGS@ AET2_LDADD = @AET2_LDADD@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COCOA_GTK_CFLAGS = @COCOA_GTK_CFLAGS@ COCOA_GTK_LDADD = @COCOA_GTK_LDADD@ COCOA_GTK_LDFLAGS = @COCOA_GTK_LDFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTDEBUG = @EXTDEBUG@ EXTDEBUG2 = @EXTDEBUG2@ EXTDEBUG3 = @EXTDEBUG3@ EXTDEBUG4 = @EXTDEBUG4@ EXTLOAD_CFLAGS = @EXTLOAD_CFLAGS@ FASTTREE_CFLAGS = @FASTTREE_CFLAGS@ FSDB_CFLAGS = @FSDB_CFLAGS@ FSDB_LDADD = @FSDB_LDADD@ GCONF_CFLAGS = @GCONF_CFLAGS@ GCONF_LIBS = @GCONF_LIBS@ GEDITTEST = @GEDITTEST@ GEDIT_CFLAGS = @GEDIT_CFLAGS@ GPERF = @GPERF@ GREP = @GREP@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_CONFIG = @GTK_CONFIG@ GTK_LIBS = @GTK_LIBS@ GTK_MAC_CFLAGS = @GTK_MAC_CFLAGS@ GTK_MAC_LIBS = @GTK_MAC_LIBS@ GTK_UNIX_PRINT_CFLAGS = @GTK_UNIX_PRINT_CFLAGS@ GTK_UNIX_PRINT_LIBS = @GTK_UNIX_PRINT_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBBZ2_CFLAGS = @LIBBZ2_CFLAGS@ LIBBZ2_DIR = @LIBBZ2_DIR@ LIBBZ2_LDADD = @LIBBZ2_LDADD@ LIBJUDY_CFLAGS = @LIBJUDY_CFLAGS@ LIBJUDY_LDADD = @LIBJUDY_LDADD@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBXZ_CFLAGS = @LIBXZ_CFLAGS@ LIBXZ_LDADD = @LIBXZ_LDADD@ LIBZ_CFLAGS = @LIBZ_CFLAGS@ LIBZ_DIR = @LIBZ_DIR@ LIBZ_LDADD = @LIBZ_LDADD@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MINGW_LDADD = @MINGW_LDADD@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ 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@ POW_LIB = @POW_LIB@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ STRUCT_PACK = @STRUCT_PACK@ TCL_DEFADD = @TCL_DEFADD@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LDADD = @TCL_LDADD@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_MAJOR_VERSION = @TCL_MAJOR_VERSION@ TCL_MINOR_VERSION = @TCL_MINOR_VERSION@ TK_INCLUDE_SPEC = @TK_INCLUDE_SPEC@ TK_LDADD = @TK_LDADD@ TK_LIB_SPEC = @TK_LIB_SPEC@ UPDATE_DESKTOP_DATABASE = @UPDATE_DESKTOP_DATABASE@ UPDATE_MIME_DATABASE = @UPDATE_MIME_DATABASE@ VERSION = @VERSION@ XDGDATADIR = @XDGDATADIR@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ 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_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ 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@ 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@ noinst_LIBRARIES = libz.a AM_CFLAGS = -DNO_VIZ libz_a_SOURCES = adler32.c deflate.h gzread.c inffixed.h trees.c zutil.c \ compress.c example.c gzwrite.c inflate.c trees.h zutil.h \ crc32.c gzclose.c infback.c inflate.h uncompr.c \ crc32.h gzguts.h inffast.c inftrees.c zconf.h \ deflate.c gzlib.c inffast.h inftrees.h zlib.h EXTRA_DIST = README all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(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) --foreign src/libz/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/libz/Makefile .PRECIOUS: 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__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libz.a: $(libz_a_OBJECTS) $(libz_a_DEPENDENCIES) $(EXTRA_libz_a_DEPENDENCIES) $(AM_V_at)-rm -f libz.a $(AM_V_AR)$(libz_a_AR) libz.a $(libz_a_OBJECTS) $(libz_a_LIBADD) $(AM_V_at)$(RANLIB) libz.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/adler32.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compress.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crc32.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/deflate.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/example.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gzclose.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gzlib.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gzread.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gzwrite.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/infback.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inffast.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inflate.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inftrees.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trees.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uncompr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zutil.Po@am__quote@ .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 $< .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 `$(CYGPATH_W) '$<'` 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: $(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 $(LIBRARIES) installdirs: 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-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -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-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 -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic 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 maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am # 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: gtkwave-3.3.66/src/libz/zconf.h0000664000076400007640000003622412235606635015635 0ustar bybellbybell/* zconf.h -- configuration of the zlib compression library * Copyright (C) 1995-2013 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* @(#) $Id$ */ #ifndef ZCONF_H #define ZCONF_H /* * If you *really* need a unique prefix for all types and library functions, * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. * Even better than compiling with -DZ_PREFIX would be to use configure to set * this permanently in zconf.h using "./configure --zprefix". */ #ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ # define Z_PREFIX_SET /* all linked symbols */ # define _dist_code z__dist_code # define _length_code z__length_code # define _tr_align z__tr_align # define _tr_flush_bits z__tr_flush_bits # define _tr_flush_block z__tr_flush_block # define _tr_init z__tr_init # define _tr_stored_block z__tr_stored_block # define _tr_tally z__tr_tally # define adler32 z_adler32 # define adler32_combine z_adler32_combine # define adler32_combine64 z_adler32_combine64 # ifndef Z_SOLO # define compress z_compress # define compress2 z_compress2 # define compressBound z_compressBound # endif # define crc32 z_crc32 # define crc32_combine z_crc32_combine # define crc32_combine64 z_crc32_combine64 # define deflate z_deflate # define deflateBound z_deflateBound # define deflateCopy z_deflateCopy # define deflateEnd z_deflateEnd # define deflateInit2_ z_deflateInit2_ # define deflateInit_ z_deflateInit_ # define deflateParams z_deflateParams # define deflatePending z_deflatePending # define deflatePrime z_deflatePrime # define deflateReset z_deflateReset # define deflateResetKeep z_deflateResetKeep # define deflateSetDictionary z_deflateSetDictionary # define deflateSetHeader z_deflateSetHeader # define deflateTune z_deflateTune # define deflate_copyright z_deflate_copyright # define get_crc_table z_get_crc_table # ifndef Z_SOLO # define gz_error z_gz_error # define gz_intmax z_gz_intmax # define gz_strwinerror z_gz_strwinerror # define gzbuffer z_gzbuffer # define gzclearerr z_gzclearerr # define gzclose z_gzclose # define gzclose_r z_gzclose_r # define gzclose_w z_gzclose_w # define gzdirect z_gzdirect # define gzdopen z_gzdopen # define gzeof z_gzeof # define gzerror z_gzerror # define gzflush z_gzflush # define gzgetc z_gzgetc # define gzgetc_ z_gzgetc_ # define gzgets z_gzgets # define gzoffset z_gzoffset # define gzoffset64 z_gzoffset64 # define gzopen z_gzopen # define gzopen64 z_gzopen64 # ifdef _WIN32 # define gzopen_w z_gzopen_w # endif # define gzprintf z_gzprintf # define gzvprintf z_gzvprintf # define gzputc z_gzputc # define gzputs z_gzputs # define gzread z_gzread # define gzrewind z_gzrewind # define gzseek z_gzseek # define gzseek64 z_gzseek64 # define gzsetparams z_gzsetparams # define gztell z_gztell # define gztell64 z_gztell64 # define gzungetc z_gzungetc # define gzwrite z_gzwrite # endif # define inflate z_inflate # define inflateBack z_inflateBack # define inflateBackEnd z_inflateBackEnd # define inflateBackInit_ z_inflateBackInit_ # define inflateCopy z_inflateCopy # define inflateEnd z_inflateEnd # define inflateGetHeader z_inflateGetHeader # define inflateInit2_ z_inflateInit2_ # define inflateInit_ z_inflateInit_ # define inflateMark z_inflateMark # define inflatePrime z_inflatePrime # define inflateReset z_inflateReset # define inflateReset2 z_inflateReset2 # define inflateSetDictionary z_inflateSetDictionary # define inflateGetDictionary z_inflateGetDictionary # define inflateSync z_inflateSync # define inflateSyncPoint z_inflateSyncPoint # define inflateUndermine z_inflateUndermine # define inflateResetKeep z_inflateResetKeep # define inflate_copyright z_inflate_copyright # define inflate_fast z_inflate_fast # define inflate_table z_inflate_table # ifndef Z_SOLO # define uncompress z_uncompress # endif # define zError z_zError # ifndef Z_SOLO # define zcalloc z_zcalloc # define zcfree z_zcfree # endif # define zlibCompileFlags z_zlibCompileFlags # define zlibVersion z_zlibVersion /* all zlib typedefs in zlib.h and zconf.h */ # define Byte z_Byte # define Bytef z_Bytef # define alloc_func z_alloc_func # define charf z_charf # define free_func z_free_func # ifndef Z_SOLO # define gzFile z_gzFile # endif # define gz_header z_gz_header # define gz_headerp z_gz_headerp # define in_func z_in_func # define intf z_intf # define out_func z_out_func # define uInt z_uInt # define uIntf z_uIntf # define uLong z_uLong # define uLongf z_uLongf # define voidp z_voidp # define voidpc z_voidpc # define voidpf z_voidpf /* all zlib structs in zlib.h and zconf.h */ # define gz_header_s z_gz_header_s # define internal_state z_internal_state #endif #if defined(__MSDOS__) && !defined(MSDOS) # define MSDOS #endif #if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) # define OS2 #endif #if defined(_WINDOWS) && !defined(WINDOWS) # define WINDOWS #endif #if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) # ifndef WIN32 # define WIN32 # endif #endif #if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) # if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) # ifndef SYS16BIT # define SYS16BIT # endif # endif #endif /* * Compile with -DMAXSEG_64K if the alloc function cannot allocate more * than 64k bytes at a time (needed on systems with 16-bit int). */ #ifdef SYS16BIT # define MAXSEG_64K #endif #ifdef MSDOS # define UNALIGNED_OK #endif #ifdef __STDC_VERSION__ # ifndef STDC # define STDC # endif # if __STDC_VERSION__ >= 199901L # ifndef STDC99 # define STDC99 # endif # endif #endif #if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) # define STDC #endif #if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) # define STDC #endif #if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) # define STDC #endif #if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) # define STDC #endif #if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ # define STDC #endif #ifndef STDC # ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ # define const /* note: need a more gentle solution here */ # endif #endif #if defined(ZLIB_CONST) && !defined(z_const) # define z_const const #else # define z_const #endif /* Some Mac compilers merge all .h files incorrectly: */ #if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) # define NO_DUMMY_DECL #endif /* Maximum value for memLevel in deflateInit2 */ #ifndef MAX_MEM_LEVEL # ifdef MAXSEG_64K # define MAX_MEM_LEVEL 8 # else # define MAX_MEM_LEVEL 9 # endif #endif /* Maximum value for windowBits in deflateInit2 and inflateInit2. * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files * created by gzip. (Files created by minigzip can still be extracted by * gzip.) */ #ifndef MAX_WBITS # define MAX_WBITS 15 /* 32K LZ77 window */ #endif /* The memory requirements for deflate are (in bytes): (1 << (windowBits+2)) + (1 << (memLevel+9)) that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) plus a few kilobytes for small objects. For example, if you want to reduce the default memory requirements from 256K to 128K, compile with make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" Of course this will generally degrade compression (there's no free lunch). The memory requirements for inflate are (in bytes) 1 << windowBits that is, 32K for windowBits=15 (default value) plus a few kilobytes for small objects. */ /* Type declarations */ #ifndef OF /* function prototypes */ # ifdef STDC # define OF(args) args # else # define OF(args) () # endif #endif #ifndef Z_ARG /* function prototypes for stdarg */ # if defined(STDC) || defined(Z_HAVE_STDARG_H) # define Z_ARG(args) args # else # define Z_ARG(args) () # endif #endif /* The following definitions for FAR are needed only for MSDOS mixed * model programming (small or medium model with some far allocations). * This was tested only with MSC; for other MSDOS compilers you may have * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, * just define FAR to be empty. */ #ifdef SYS16BIT # if defined(M_I86SM) || defined(M_I86MM) /* MSC small or medium model */ # define SMALL_MEDIUM # ifdef _MSC_VER # define FAR _far # else # define FAR far # endif # endif # if (defined(__SMALL__) || defined(__MEDIUM__)) /* Turbo C small or medium model */ # define SMALL_MEDIUM # ifdef __BORLANDC__ # define FAR _far # else # define FAR far # endif # endif #endif #if defined(WINDOWS) || defined(WIN32) /* If building or using zlib as a DLL, define ZLIB_DLL. * This is not mandatory, but it offers a little performance increase. */ # ifdef ZLIB_DLL # if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) # ifdef ZLIB_INTERNAL # define ZEXTERN extern __declspec(dllexport) # else # define ZEXTERN extern __declspec(dllimport) # endif # endif # endif /* ZLIB_DLL */ /* If building or using zlib with the WINAPI/WINAPIV calling convention, * define ZLIB_WINAPI. * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. */ # ifdef ZLIB_WINAPI # ifdef FAR # undef FAR # endif # include /* No need for _export, use ZLIB.DEF instead. */ /* For complete Windows compatibility, use WINAPI, not __stdcall. */ # define ZEXPORT WINAPI # ifdef WIN32 # define ZEXPORTVA WINAPIV # else # define ZEXPORTVA FAR CDECL # endif # endif #endif #if defined (__BEOS__) # ifdef ZLIB_DLL # ifdef ZLIB_INTERNAL # define ZEXPORT __declspec(dllexport) # define ZEXPORTVA __declspec(dllexport) # else # define ZEXPORT __declspec(dllimport) # define ZEXPORTVA __declspec(dllimport) # endif # endif #endif #ifndef ZEXTERN # define ZEXTERN extern #endif #ifndef ZEXPORT # define ZEXPORT #endif #ifndef ZEXPORTVA # define ZEXPORTVA #endif #ifndef FAR # define FAR #endif #if !defined(__MACTYPES__) typedef unsigned char Byte; /* 8 bits */ #endif typedef unsigned int uInt; /* 16 bits or more */ typedef unsigned long uLong; /* 32 bits or more */ #ifdef SMALL_MEDIUM /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ # define Bytef Byte FAR #else typedef Byte FAR Bytef; #endif typedef char FAR charf; typedef int FAR intf; typedef uInt FAR uIntf; typedef uLong FAR uLongf; #ifdef STDC typedef void const *voidpc; typedef void FAR *voidpf; typedef void *voidp; #else typedef Byte const *voidpc; typedef Byte FAR *voidpf; typedef Byte *voidp; #endif #if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) # include # if (UINT_MAX == 0xffffffffUL) # define Z_U4 unsigned # elif (ULONG_MAX == 0xffffffffUL) # define Z_U4 unsigned long # elif (USHRT_MAX == 0xffffffffUL) # define Z_U4 unsigned short # endif #endif #ifdef Z_U4 typedef Z_U4 z_crc_t; #else typedef unsigned long z_crc_t; #endif #ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ # define Z_HAVE_UNISTD_H #endif #ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ # define Z_HAVE_STDARG_H #endif #ifdef STDC # ifndef Z_SOLO # include /* for off_t */ # endif #endif #if defined(STDC) || defined(Z_HAVE_STDARG_H) # ifndef Z_SOLO # include /* for va_list */ # endif #endif #ifdef _WIN32 # ifndef Z_SOLO # include /* for wchar_t */ # endif #endif /* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even * though the former does not conform to the LFS document), but considering * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as * equivalently requesting no 64-bit operations */ #if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 # undef _LARGEFILE64_SOURCE #endif #if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H) # define Z_HAVE_UNISTD_H #endif #ifndef Z_SOLO # if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) # include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ # ifdef VMS # include /* for off_t */ # endif # ifndef z_off_t # define z_off_t off_t # endif # endif #endif #if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 # define Z_LFS64 #endif #if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) # define Z_LARGE64 #endif #if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) # define Z_WANT64 #endif #if !defined(SEEK_SET) && !defined(Z_SOLO) # define SEEK_SET 0 /* Seek from beginning of file. */ # define SEEK_CUR 1 /* Seek from current position. */ # define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ #endif #ifndef z_off_t # define z_off_t long #endif #if !defined(_WIN32) && defined(Z_LARGE64) # define z_off64_t off64_t #else # if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) # define z_off64_t __int64 # else # define z_off64_t z_off_t # endif #endif /* MVS linker does not support external names larger than 8 bytes */ #if defined(__MVS__) #pragma map(deflateInit_,"DEIN") #pragma map(deflateInit2_,"DEIN2") #pragma map(deflateEnd,"DEEND") #pragma map(deflateBound,"DEBND") #pragma map(inflateInit_,"ININ") #pragma map(inflateInit2_,"ININ2") #pragma map(inflateEnd,"INEND") #pragma map(inflateSync,"INSY") #pragma map(inflateSetDictionary,"INSEDI") #pragma map(compressBound,"CMBND") #pragma map(inflate_table,"INTABL") #pragma map(inflate_fast,"INFA") #pragma map(inflate_copyright,"INCOPY") #endif #endif /* ZCONF_H */ gtkwave-3.3.66/src/libz/adler32.c0000664000076400007640000001155012235606635015740 0ustar bybellbybell/* adler32.c -- compute the Adler-32 checksum of a data stream * Copyright (C) 1995-2011 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* @(#) $Id$ */ #include "zutil.h" #define local static local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); #define BASE 65521 /* largest prime smaller than 65536 */ #define NMAX 5552 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ #define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} #define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); #define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); #define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); #define DO16(buf) DO8(buf,0); DO8(buf,8); /* use NO_DIVIDE if your processor does not do division in hardware -- try it both ways to see which is faster */ #ifdef NO_DIVIDE /* note that this assumes BASE is 65521, where 65536 % 65521 == 15 (thank you to John Reiser for pointing this out) */ # define CHOP(a) \ do { \ unsigned long tmp = a >> 16; \ a &= 0xffffUL; \ a += (tmp << 4) - tmp; \ } while (0) # define MOD28(a) \ do { \ CHOP(a); \ if (a >= BASE) a -= BASE; \ } while (0) # define MOD(a) \ do { \ CHOP(a); \ MOD28(a); \ } while (0) # define MOD63(a) \ do { /* this assumes a is not negative */ \ z_off64_t tmp = a >> 32; \ a &= 0xffffffffL; \ a += (tmp << 8) - (tmp << 5) + tmp; \ tmp = a >> 16; \ a &= 0xffffL; \ a += (tmp << 4) - tmp; \ tmp = a >> 16; \ a &= 0xffffL; \ a += (tmp << 4) - tmp; \ if (a >= BASE) a -= BASE; \ } while (0) #else # define MOD(a) a %= BASE # define MOD28(a) a %= BASE # define MOD63(a) a %= BASE #endif /* ========================================================================= */ uLong ZEXPORT adler32(adler, buf, len) uLong adler; const Bytef *buf; uInt len; { unsigned long sum2; unsigned n; /* split Adler-32 into component sums */ sum2 = (adler >> 16) & 0xffff; adler &= 0xffff; /* in case user likes doing a byte at a time, keep it fast */ if (len == 1) { adler += buf[0]; if (adler >= BASE) adler -= BASE; sum2 += adler; if (sum2 >= BASE) sum2 -= BASE; return adler | (sum2 << 16); } /* initial Adler-32 value (deferred check for len == 1 speed) */ if (buf == Z_NULL) return 1L; /* in case short lengths are provided, keep it somewhat fast */ if (len < 16) { while (len--) { adler += *buf++; sum2 += adler; } if (adler >= BASE) adler -= BASE; MOD28(sum2); /* only added so many BASE's */ return adler | (sum2 << 16); } /* do length NMAX blocks -- requires just one modulo operation */ while (len >= NMAX) { len -= NMAX; n = NMAX / 16; /* NMAX is divisible by 16 */ do { DO16(buf); /* 16 sums unrolled */ buf += 16; } while (--n); MOD(adler); MOD(sum2); } /* do remaining bytes (less than NMAX, still just one modulo) */ if (len) { /* avoid modulos if none remaining */ while (len >= 16) { len -= 16; DO16(buf); buf += 16; } while (len--) { adler += *buf++; sum2 += adler; } MOD(adler); MOD(sum2); } /* return recombined sums */ return adler | (sum2 << 16); } /* ========================================================================= */ local uLong adler32_combine_(adler1, adler2, len2) uLong adler1; uLong adler2; z_off64_t len2; { unsigned long sum1; unsigned long sum2; unsigned rem; /* for negative len, return invalid adler32 as a clue for debugging */ if (len2 < 0) return 0xffffffffUL; /* the derivation of this formula is left as an exercise for the reader */ MOD63(len2); /* assumes len2 >= 0 */ rem = (unsigned)len2; sum1 = adler1 & 0xffff; sum2 = rem * sum1; MOD(sum2); sum1 += (adler2 & 0xffff) + BASE - 1; sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; if (sum1 >= BASE) sum1 -= BASE; if (sum1 >= BASE) sum1 -= BASE; if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1); if (sum2 >= BASE) sum2 -= BASE; return sum1 | (sum2 << 16); } /* ========================================================================= */ uLong ZEXPORT adler32_combine(adler1, adler2, len2) uLong adler1; uLong adler2; z_off_t len2; { return adler32_combine_(adler1, adler2, len2); } uLong ZEXPORT adler32_combine64(adler1, adler2, len2) uLong adler1; uLong adler2; z_off64_t len2; { return adler32_combine_(adler1, adler2, len2); } gtkwave-3.3.66/src/libz/infback.c0000664000076400007640000005426512235606635016113 0ustar bybellbybell/* infback.c -- inflate using a call-back interface * Copyright (C) 1995-2011 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* This code is largely copied from inflate.c. Normally either infback.o or inflate.o would be linked into an application--not both. The interface with inffast.c is retained so that optimized assembler-coded versions of inflate_fast() can be used with either inflate.c or infback.c. */ #include "zutil.h" #include "inftrees.h" #include "inflate.h" #include "inffast.h" /* function prototypes */ local void fixedtables OF((struct inflate_state FAR *state)); /* strm provides memory allocation functions in zalloc and zfree, or Z_NULL to use the library memory allocation functions. windowBits is in the range 8..15, and window is a user-supplied window and output buffer that is 2**windowBits bytes. */ int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) z_streamp strm; int windowBits; unsigned char FAR *window; const char *version; int stream_size; { struct inflate_state FAR *state; if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || stream_size != (int)(sizeof(z_stream))) return Z_VERSION_ERROR; if (strm == Z_NULL || window == Z_NULL || windowBits < 8 || windowBits > 15) return Z_STREAM_ERROR; strm->msg = Z_NULL; /* in case we return an error */ if (strm->zalloc == (alloc_func)0) { #ifdef Z_SOLO return Z_STREAM_ERROR; #else strm->zalloc = zcalloc; strm->opaque = (voidpf)0; #endif } if (strm->zfree == (free_func)0) #ifdef Z_SOLO return Z_STREAM_ERROR; #else strm->zfree = zcfree; #endif state = (struct inflate_state FAR *)ZALLOC(strm, 1, sizeof(struct inflate_state)); if (state == Z_NULL) return Z_MEM_ERROR; Tracev((stderr, "inflate: allocated\n")); strm->state = (struct internal_state FAR *)state; state->dmax = 32768U; state->wbits = windowBits; state->wsize = 1U << windowBits; state->window = window; state->wnext = 0; state->whave = 0; return Z_OK; } /* Return state with length and distance decoding tables and index sizes set to fixed code decoding. Normally this returns fixed tables from inffixed.h. If BUILDFIXED is defined, then instead this routine builds the tables the first time it's called, and returns those tables the first time and thereafter. This reduces the size of the code by about 2K bytes, in exchange for a little execution time. However, BUILDFIXED should not be used for threaded applications, since the rewriting of the tables and virgin may not be thread-safe. */ local void fixedtables(state) struct inflate_state FAR *state; { #ifdef BUILDFIXED static int virgin = 1; static code *lenfix, *distfix; static code fixed[544]; /* build fixed huffman tables if first call (may not be thread safe) */ if (virgin) { unsigned sym, bits; static code *next; /* literal/length table */ sym = 0; while (sym < 144) state->lens[sym++] = 8; while (sym < 256) state->lens[sym++] = 9; while (sym < 280) state->lens[sym++] = 7; while (sym < 288) state->lens[sym++] = 8; next = fixed; lenfix = next; bits = 9; inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); /* distance table */ sym = 0; while (sym < 32) state->lens[sym++] = 5; distfix = next; bits = 5; inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); /* do this just once */ virgin = 0; } #else /* !BUILDFIXED */ # include "inffixed.h" #endif /* BUILDFIXED */ state->lencode = lenfix; state->lenbits = 9; state->distcode = distfix; state->distbits = 5; } /* Macros for inflateBack(): */ /* Load returned state from inflate_fast() */ #define LOAD() \ do { \ put = strm->next_out; \ left = strm->avail_out; \ next = strm->next_in; \ have = strm->avail_in; \ hold = state->hold; \ bits = state->bits; \ } while (0) /* Set state from registers for inflate_fast() */ #define RESTORE() \ do { \ strm->next_out = put; \ strm->avail_out = left; \ strm->next_in = next; \ strm->avail_in = have; \ state->hold = hold; \ state->bits = bits; \ } while (0) /* Clear the input bit accumulator */ #define INITBITS() \ do { \ hold = 0; \ bits = 0; \ } while (0) /* Assure that some input is available. If input is requested, but denied, then return a Z_BUF_ERROR from inflateBack(). */ #define PULL() \ do { \ if (have == 0) { \ have = in(in_desc, &next); \ if (have == 0) { \ next = Z_NULL; \ ret = Z_BUF_ERROR; \ goto inf_leave; \ } \ } \ } while (0) /* Get a byte of input into the bit accumulator, or return from inflateBack() with an error if there is no input available. */ #define PULLBYTE() \ do { \ PULL(); \ have--; \ hold += (unsigned long)(*next++) << bits; \ bits += 8; \ } while (0) /* Assure that there are at least n bits in the bit accumulator. If there is not enough available input to do that, then return from inflateBack() with an error. */ #define NEEDBITS(n) \ do { \ while (bits < (unsigned)(n)) \ PULLBYTE(); \ } while (0) /* Return the low n bits of the bit accumulator (n < 16) */ #define BITS(n) \ ((unsigned)hold & ((1U << (n)) - 1)) /* Remove n bits from the bit accumulator */ #define DROPBITS(n) \ do { \ hold >>= (n); \ bits -= (unsigned)(n); \ } while (0) /* Remove zero to seven bits as needed to go to a byte boundary */ #define BYTEBITS() \ do { \ hold >>= bits & 7; \ bits -= bits & 7; \ } while (0) /* Assure that some output space is available, by writing out the window if it's full. If the write fails, return from inflateBack() with a Z_BUF_ERROR. */ #define ROOM() \ do { \ if (left == 0) { \ put = state->window; \ left = state->wsize; \ state->whave = left; \ if (out(out_desc, put, left)) { \ ret = Z_BUF_ERROR; \ goto inf_leave; \ } \ } \ } while (0) /* strm provides the memory allocation functions and window buffer on input, and provides information on the unused input on return. For Z_DATA_ERROR returns, strm will also provide an error message. in() and out() are the call-back input and output functions. When inflateBack() needs more input, it calls in(). When inflateBack() has filled the window with output, or when it completes with data in the window, it calls out() to write out the data. The application must not change the provided input until in() is called again or inflateBack() returns. The application must not change the window/output buffer until inflateBack() returns. in() and out() are called with a descriptor parameter provided in the inflateBack() call. This parameter can be a structure that provides the information required to do the read or write, as well as accumulated information on the input and output such as totals and check values. in() should return zero on failure. out() should return non-zero on failure. If either in() or out() fails, than inflateBack() returns a Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it was in() or out() that caused in the error. Otherwise, inflateBack() returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format error, or Z_MEM_ERROR if it could not allocate memory for the state. inflateBack() can also return Z_STREAM_ERROR if the input parameters are not correct, i.e. strm is Z_NULL or the state was not initialized. */ int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) z_streamp strm; in_func in; void FAR *in_desc; out_func out; void FAR *out_desc; { struct inflate_state FAR *state; z_const unsigned char FAR *next; /* next input */ unsigned char FAR *put; /* next output */ unsigned have, left; /* available input and output */ unsigned long hold; /* bit buffer */ unsigned bits; /* bits in bit buffer */ unsigned copy; /* number of stored or match bytes to copy */ unsigned char FAR *from; /* where to copy match bytes from */ code here; /* current decoding table entry */ code last; /* parent table entry */ unsigned len; /* length to copy for repeats, bits to drop */ int ret; /* return code */ static const unsigned short order[19] = /* permutation of code lengths */ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; /* Check that the strm exists and that the state was initialized */ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; /* Reset the state */ strm->msg = Z_NULL; state->mode = TYPE; state->last = 0; state->whave = 0; next = strm->next_in; have = next != Z_NULL ? strm->avail_in : 0; hold = 0; bits = 0; put = state->window; left = state->wsize; /* Inflate until end of block marked as last */ for (;;) switch (state->mode) { case TYPE: /* determine and dispatch block type */ if (state->last) { BYTEBITS(); state->mode = DONE; break; } NEEDBITS(3); state->last = BITS(1); DROPBITS(1); switch (BITS(2)) { case 0: /* stored block */ Tracev((stderr, "inflate: stored block%s\n", state->last ? " (last)" : "")); state->mode = STORED; break; case 1: /* fixed block */ fixedtables(state); Tracev((stderr, "inflate: fixed codes block%s\n", state->last ? " (last)" : "")); state->mode = LEN; /* decode codes */ break; case 2: /* dynamic block */ Tracev((stderr, "inflate: dynamic codes block%s\n", state->last ? " (last)" : "")); state->mode = TABLE; break; case 3: strm->msg = (char *)"invalid block type"; state->mode = BAD; } DROPBITS(2); break; case STORED: /* get and verify stored block length */ BYTEBITS(); /* go to byte boundary */ NEEDBITS(32); if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { strm->msg = (char *)"invalid stored block lengths"; state->mode = BAD; break; } state->length = (unsigned)hold & 0xffff; Tracev((stderr, "inflate: stored length %u\n", state->length)); INITBITS(); /* copy stored block from input to output */ while (state->length != 0) { copy = state->length; PULL(); ROOM(); if (copy > have) copy = have; if (copy > left) copy = left; zmemcpy(put, next, copy); have -= copy; next += copy; left -= copy; put += copy; state->length -= copy; } Tracev((stderr, "inflate: stored end\n")); state->mode = TYPE; break; case TABLE: /* get dynamic table entries descriptor */ NEEDBITS(14); state->nlen = BITS(5) + 257; DROPBITS(5); state->ndist = BITS(5) + 1; DROPBITS(5); state->ncode = BITS(4) + 4; DROPBITS(4); #ifndef PKZIP_BUG_WORKAROUND if (state->nlen > 286 || state->ndist > 30) { strm->msg = (char *)"too many length or distance symbols"; state->mode = BAD; break; } #endif Tracev((stderr, "inflate: table sizes ok\n")); /* get code length code lengths (not a typo) */ state->have = 0; while (state->have < state->ncode) { NEEDBITS(3); state->lens[order[state->have++]] = (unsigned short)BITS(3); DROPBITS(3); } while (state->have < 19) state->lens[order[state->have++]] = 0; state->next = state->codes; state->lencode = (code const FAR *)(state->next); state->lenbits = 7; ret = inflate_table(CODES, state->lens, 19, &(state->next), &(state->lenbits), state->work); if (ret) { strm->msg = (char *)"invalid code lengths set"; state->mode = BAD; break; } Tracev((stderr, "inflate: code lengths ok\n")); /* get length and distance code code lengths */ state->have = 0; while (state->have < state->nlen + state->ndist) { for (;;) { here = state->lencode[BITS(state->lenbits)]; if ((unsigned)(here.bits) <= bits) break; PULLBYTE(); } if (here.val < 16) { DROPBITS(here.bits); state->lens[state->have++] = here.val; } else { if (here.val == 16) { NEEDBITS(here.bits + 2); DROPBITS(here.bits); if (state->have == 0) { strm->msg = (char *)"invalid bit length repeat"; state->mode = BAD; break; } len = (unsigned)(state->lens[state->have - 1]); copy = 3 + BITS(2); DROPBITS(2); } else if (here.val == 17) { NEEDBITS(here.bits + 3); DROPBITS(here.bits); len = 0; copy = 3 + BITS(3); DROPBITS(3); } else { NEEDBITS(here.bits + 7); DROPBITS(here.bits); len = 0; copy = 11 + BITS(7); DROPBITS(7); } if (state->have + copy > state->nlen + state->ndist) { strm->msg = (char *)"invalid bit length repeat"; state->mode = BAD; break; } while (copy--) state->lens[state->have++] = (unsigned short)len; } } /* handle error breaks in while */ if (state->mode == BAD) break; /* check for end-of-block code (better have one) */ if (state->lens[256] == 0) { strm->msg = (char *)"invalid code -- missing end-of-block"; state->mode = BAD; break; } /* build code tables -- note: do not change the lenbits or distbits values here (9 and 6) without reading the comments in inftrees.h concerning the ENOUGH constants, which depend on those values */ state->next = state->codes; state->lencode = (code const FAR *)(state->next); state->lenbits = 9; ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), &(state->lenbits), state->work); if (ret) { strm->msg = (char *)"invalid literal/lengths set"; state->mode = BAD; break; } state->distcode = (code const FAR *)(state->next); state->distbits = 6; ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, &(state->next), &(state->distbits), state->work); if (ret) { strm->msg = (char *)"invalid distances set"; state->mode = BAD; break; } Tracev((stderr, "inflate: codes ok\n")); state->mode = LEN; case LEN: /* use inflate_fast() if we have enough input and output */ if (have >= 6 && left >= 258) { RESTORE(); if (state->whave < state->wsize) state->whave = state->wsize - left; inflate_fast(strm, state->wsize); LOAD(); break; } /* get a literal, length, or end-of-block code */ for (;;) { here = state->lencode[BITS(state->lenbits)]; if ((unsigned)(here.bits) <= bits) break; PULLBYTE(); } if (here.op && (here.op & 0xf0) == 0) { last = here; for (;;) { here = state->lencode[last.val + (BITS(last.bits + last.op) >> last.bits)]; if ((unsigned)(last.bits + here.bits) <= bits) break; PULLBYTE(); } DROPBITS(last.bits); } DROPBITS(here.bits); state->length = (unsigned)here.val; /* process literal */ if (here.op == 0) { Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? "inflate: literal '%c'\n" : "inflate: literal 0x%02x\n", here.val)); ROOM(); *put++ = (unsigned char)(state->length); left--; state->mode = LEN; break; } /* process end of block */ if (here.op & 32) { Tracevv((stderr, "inflate: end of block\n")); state->mode = TYPE; break; } /* invalid code */ if (here.op & 64) { strm->msg = (char *)"invalid literal/length code"; state->mode = BAD; break; } /* length code -- get extra bits, if any */ state->extra = (unsigned)(here.op) & 15; if (state->extra != 0) { NEEDBITS(state->extra); state->length += BITS(state->extra); DROPBITS(state->extra); } Tracevv((stderr, "inflate: length %u\n", state->length)); /* get distance code */ for (;;) { here = state->distcode[BITS(state->distbits)]; if ((unsigned)(here.bits) <= bits) break; PULLBYTE(); } if ((here.op & 0xf0) == 0) { last = here; for (;;) { here = state->distcode[last.val + (BITS(last.bits + last.op) >> last.bits)]; if ((unsigned)(last.bits + here.bits) <= bits) break; PULLBYTE(); } DROPBITS(last.bits); } DROPBITS(here.bits); if (here.op & 64) { strm->msg = (char *)"invalid distance code"; state->mode = BAD; break; } state->offset = (unsigned)here.val; /* get distance extra bits, if any */ state->extra = (unsigned)(here.op) & 15; if (state->extra != 0) { NEEDBITS(state->extra); state->offset += BITS(state->extra); DROPBITS(state->extra); } if (state->offset > state->wsize - (state->whave < state->wsize ? left : 0)) { strm->msg = (char *)"invalid distance too far back"; state->mode = BAD; break; } Tracevv((stderr, "inflate: distance %u\n", state->offset)); /* copy match from window to output */ do { ROOM(); copy = state->wsize - state->offset; if (copy < left) { from = put + copy; copy = left - copy; } else { from = put - state->offset; copy = left; } if (copy > state->length) copy = state->length; state->length -= copy; left -= copy; do { *put++ = *from++; } while (--copy); } while (state->length != 0); break; case DONE: /* inflate stream terminated properly -- write leftover output */ ret = Z_STREAM_END; if (left < state->wsize) { if (out(out_desc, state->window, state->wsize - left)) ret = Z_BUF_ERROR; } goto inf_leave; case BAD: ret = Z_DATA_ERROR; goto inf_leave; default: /* can't happen, but makes compilers happy */ ret = Z_STREAM_ERROR; goto inf_leave; } /* Return unused input */ inf_leave: strm->next_in = next; strm->avail_in = have; return ret; } int ZEXPORT inflateBackEnd(strm) z_streamp strm; { if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) return Z_STREAM_ERROR; ZFREE(strm, strm->state); strm->state = Z_NULL; Tracev((stderr, "inflate: end\n")); return Z_OK; } gtkwave-3.3.66/src/libz/uncompr.c0000664000076400007640000000372312235606635016172 0ustar bybellbybell/* uncompr.c -- decompress a memory buffer * Copyright (C) 1995-2003, 2010 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* @(#) $Id$ */ #define ZLIB_INTERNAL #include "zlib.h" /* =========================================================================== Decompresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be large enough to hold the entire uncompressed data. (The size of the uncompressed data must have been saved previously by the compressor and transmitted to the decompressor by some mechanism outside the scope of this compression library.) Upon exit, destLen is the actual size of the compressed buffer. uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, or Z_DATA_ERROR if the input data was corrupted. */ int ZEXPORT uncompress (dest, destLen, source, sourceLen) Bytef *dest; uLongf *destLen; const Bytef *source; uLong sourceLen; { z_stream stream; int err; stream.next_in = (z_const Bytef *)source; stream.avail_in = (uInt)sourceLen; /* Check for source > 64K on 16-bit machine: */ if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; stream.next_out = dest; stream.avail_out = (uInt)*destLen; if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; stream.zalloc = (alloc_func)0; stream.zfree = (free_func)0; err = inflateInit(&stream); if (err != Z_OK) return err; err = inflate(&stream, Z_FINISH); if (err != Z_STREAM_END) { inflateEnd(&stream); if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) return Z_DATA_ERROR; return err; } *destLen = stream.total_out; err = inflateEnd(&stream); return err; } gtkwave-3.3.66/src/libz/zlib.h0000664000076400007640000025351312235606635015460 0ustar bybellbybell/* zlib.h -- interface of the 'zlib' general purpose compression library version 1.2.8, April 28th, 2013 Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler 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. Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). */ #ifndef ZLIB_H #define ZLIB_H #include "zconf.h" #ifdef __cplusplus extern "C" { #endif #define ZLIB_VERSION "1.2.8" #define ZLIB_VERNUM 0x1280 #define ZLIB_VER_MAJOR 1 #define ZLIB_VER_MINOR 2 #define ZLIB_VER_REVISION 8 #define ZLIB_VER_SUBREVISION 0 /* The 'zlib' compression library provides in-memory compression and decompression functions, including integrity checks of the uncompressed data. This version of the library supports only one compression method (deflation) but other algorithms will be added later and will have the same stream interface. Compression can be done in a single step if the buffers are large enough, or can be done by repeated calls of the compression function. In the latter case, the application must provide more input and/or consume the output (providing more output space) before each call. The compressed data format used by default by the in-memory functions is the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped around a deflate stream, which is itself documented in RFC 1951. The library also supports reading and writing files in gzip (.gz) format with an interface similar to that of stdio using the functions that start with "gz". The gzip format is different from the zlib format. gzip is a gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. This library can optionally read and write gzip streams in memory as well. The zlib format was designed to be compact and fast for use in memory and on communications channels. The gzip format was designed for single- file compression on file systems, has a larger header than zlib to maintain directory information, and uses a different, slower check method than zlib. The library does not install any signal handler. The decoder checks the consistency of the compressed data, so the library should never crash even in case of corrupted input. */ typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); typedef void (*free_func) OF((voidpf opaque, voidpf address)); struct internal_state; typedef struct z_stream_s { z_const Bytef *next_in; /* next input byte */ uInt avail_in; /* number of bytes available at next_in */ uLong total_in; /* total number of input bytes read so far */ Bytef *next_out; /* next output byte should be put there */ uInt avail_out; /* remaining free space at next_out */ uLong total_out; /* total number of bytes output so far */ z_const char *msg; /* last error message, NULL if no error */ struct internal_state FAR *state; /* not visible by applications */ alloc_func zalloc; /* used to allocate the internal state */ free_func zfree; /* used to free the internal state */ voidpf opaque; /* private data object passed to zalloc and zfree */ int data_type; /* best guess about the data type: binary or text */ uLong adler; /* adler32 value of the uncompressed data */ uLong reserved; /* reserved for future use */ } z_stream; typedef z_stream FAR *z_streamp; /* gzip header information passed to and from zlib routines. See RFC 1952 for more details on the meanings of these fields. */ typedef struct gz_header_s { int text; /* true if compressed data believed to be text */ uLong time; /* modification time */ int xflags; /* extra flags (not used when writing a gzip file) */ int os; /* operating system */ Bytef *extra; /* pointer to extra field or Z_NULL if none */ uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ uInt extra_max; /* space at extra (only when reading header) */ Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ uInt name_max; /* space at name (only when reading header) */ Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ uInt comm_max; /* space at comment (only when reading header) */ int hcrc; /* true if there was or will be a header crc */ int done; /* true when done reading gzip header (not used when writing a gzip file) */ } gz_header; typedef gz_header FAR *gz_headerp; /* The application must update next_in and avail_in when avail_in has dropped to zero. It must update next_out and avail_out when avail_out has dropped to zero. The application must initialize zalloc, zfree and opaque before calling the init function. All other fields are set by the compression library and must not be updated by the application. The opaque value provided by the application will be passed as the first parameter for calls of zalloc and zfree. This can be useful for custom memory management. The compression library attaches no meaning to the opaque value. zalloc must return Z_NULL if there is not enough memory for the object. If zlib is used in a multi-threaded application, zalloc and zfree must be thread safe. On 16-bit systems, the functions zalloc and zfree must be able to allocate exactly 65536 bytes, but will not be required to allocate more than this if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers returned by zalloc for objects of exactly 65536 bytes *must* have their offset normalized to zero. The default allocation function provided by this library ensures this (see zutil.c). To reduce memory requirements and avoid any allocation of 64K objects, at the expense of compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). The fields total_in and total_out can be used for statistics or progress reports. After compression, total_in holds the total size of the uncompressed data and may be saved for use in the decompressor (particularly if the decompressor wants to decompress everything in a single step). */ /* constants */ #define Z_NO_FLUSH 0 #define Z_PARTIAL_FLUSH 1 #define Z_SYNC_FLUSH 2 #define Z_FULL_FLUSH 3 #define Z_FINISH 4 #define Z_BLOCK 5 #define Z_TREES 6 /* Allowed flush values; see deflate() and inflate() below for details */ #define Z_OK 0 #define Z_STREAM_END 1 #define Z_NEED_DICT 2 #define Z_ERRNO (-1) #define Z_STREAM_ERROR (-2) #define Z_DATA_ERROR (-3) #define Z_MEM_ERROR (-4) #define Z_BUF_ERROR (-5) #define Z_VERSION_ERROR (-6) /* Return codes for the compression/decompression functions. Negative values * are errors, positive values are used for special but normal events. */ #define Z_NO_COMPRESSION 0 #define Z_BEST_SPEED 1 #define Z_BEST_COMPRESSION 9 #define Z_DEFAULT_COMPRESSION (-1) /* compression levels */ #define Z_FILTERED 1 #define Z_HUFFMAN_ONLY 2 #define Z_RLE 3 #define Z_FIXED 4 #define Z_DEFAULT_STRATEGY 0 /* compression strategy; see deflateInit2() below for details */ #define Z_BINARY 0 #define Z_TEXT 1 #define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ #define Z_UNKNOWN 2 /* Possible values of the data_type field (though see inflate()) */ #define Z_DEFLATED 8 /* The deflate compression method (the only one supported in this version) */ #define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ #define zlib_version zlibVersion() /* for compatibility with versions < 1.0.2 */ /* basic functions */ ZEXTERN const char * ZEXPORT zlibVersion OF((void)); /* The application can compare zlibVersion and ZLIB_VERSION for consistency. If the first character differs, the library code actually used is not compatible with the zlib.h header file used by the application. This check is automatically made by deflateInit and inflateInit. */ /* ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); Initializes the internal stream state for compression. The fields zalloc, zfree and opaque must be initialized before by the caller. If zalloc and zfree are set to Z_NULL, deflateInit updates them to use default allocation functions. The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: 1 gives best speed, 9 gives best compression, 0 gives no compression at all (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION requests a default compromise between speed and compression (currently equivalent to level 6). deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if level is not a valid compression level, or Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible with the version assumed by the caller (ZLIB_VERSION). msg is set to null if there is no error message. deflateInit does not perform any compression: this will be done by deflate(). */ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); /* deflate compresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full. It may introduce some output latency (reading input without producing any output) except when forced to flush. The detailed semantics are as follows. deflate performs one or both of the following actions: - Compress more input starting at next_in and update next_in and avail_in accordingly. If not all input can be processed (because there is not enough room in the output buffer), next_in and avail_in are updated and processing will resume at this point for the next call of deflate(). - Provide more output starting at next_out and update next_out and avail_out accordingly. This action is forced if the parameter flush is non zero. Forcing flush frequently degrades the compression ratio, so this parameter should be set only when necessary (in interactive applications). Some output may be provided even if flush is not set. Before the call of deflate(), the application should ensure that at least one of the actions is possible, by providing more input and/or consuming more output, and updating avail_in or avail_out accordingly; avail_out should never be zero before the call. The application can consume the compressed output when it wants, for example when the output buffer is full (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK and with zero avail_out, it must be called again after making room in the output buffer because there might be more output pending. Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to decide how much data to accumulate before producing output, in order to maximize compression. If the parameter flush is set to Z_SYNC_FLUSH, all pending output is flushed to the output buffer and the output is aligned on a byte boundary, so that the decompressor can get all input data available so far. (In particular avail_in is zero after the call if enough output space has been provided before the call.) Flushing may degrade compression for some compression algorithms and so it should be used only when necessary. This completes the current deflate block and follows it with an empty stored block that is three bits plus filler bits to the next byte, followed by four bytes (00 00 ff ff). If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the output buffer, but the output is not aligned to a byte boundary. All of the input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. This completes the current deflate block and follows it with an empty fixed codes block that is 10 bits long. This assures that enough bytes are output in order for the decompressor to finish the block before the empty fixed code block. If flush is set to Z_BLOCK, a deflate block is completed and emitted, as for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to seven bits of the current block are held to be written as the next byte after the next deflate block is completed. In this case, the decompressor may not be provided enough bits at this point in order to complete decompression of the data provided so far to the compressor. It may need to wait for the next block to be emitted. This is for advanced applications that need to control the emission of deflate blocks. If flush is set to Z_FULL_FLUSH, all output is flushed as with Z_SYNC_FLUSH, and the compression state is reset so that decompression can restart from this point if previous compressed data has been damaged or if random access is desired. Using Z_FULL_FLUSH too often can seriously degrade compression. If deflate returns with avail_out == 0, this function must be called again with the same value of the flush parameter and more output space (updated avail_out), until the flush is complete (deflate returns with non-zero avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that avail_out is greater than six to avoid repeated flush markers due to avail_out == 0 on return. If the parameter flush is set to Z_FINISH, pending input is processed, pending output is flushed and deflate returns with Z_STREAM_END if there was enough output space; if deflate returns with Z_OK, this function must be called again with Z_FINISH and more output space (updated avail_out) but no more input data, until it returns with Z_STREAM_END or an error. After deflate has returned Z_STREAM_END, the only possible operations on the stream are deflateReset or deflateEnd. Z_FINISH can be used immediately after deflateInit if all the compression is to be done in a single step. In this case, avail_out must be at least the value returned by deflateBound (see below). Then deflate is guaranteed to return Z_STREAM_END. If not enough output space is provided, deflate will not return Z_STREAM_END, and it must be called again as described above. deflate() sets strm->adler to the adler32 checksum of all input read so far (that is, total_in bytes). deflate() may update strm->data_type if it can make a good guess about the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered binary. This field is only for information purposes and does not affect the compression algorithm in any manner. deflate() returns Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if all input has been consumed and all output has been produced (only when flush is set to Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and deflate() can be called again with more input and more output space to continue compressing. */ ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending output. deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state was inconsistent, Z_DATA_ERROR if the stream was freed prematurely (some input or output was discarded). In the error case, msg may be set but then points to a static string (which must not be deallocated). */ /* ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); Initializes the internal stream state for decompression. The fields next_in, avail_in, zalloc, zfree and opaque must be initialized before by the caller. If next_in is not Z_NULL and avail_in is large enough (the exact value depends on the compression method), inflateInit determines the compression method from the zlib header and allocates all data structures accordingly; otherwise the allocation will be deferred to the first call of inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to use default allocation functions. inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_VERSION_ERROR if the zlib library version is incompatible with the version assumed by the caller, or Z_STREAM_ERROR if the parameters are invalid, such as a null pointer to the structure. msg is set to null if there is no error message. inflateInit does not perform any decompression apart from possibly reading the zlib header if present: actual decompression will be done by inflate(). (So next_in and avail_in may be modified, but next_out and avail_out are unused and unchanged.) The current implementation of inflateInit() does not process any header information -- that is deferred until inflate() is called. */ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); /* inflate decompresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full. It may introduce some output latency (reading input without producing any output) except when forced to flush. The detailed semantics are as follows. inflate performs one or both of the following actions: - Decompress more input starting at next_in and update next_in and avail_in accordingly. If not all input can be processed (because there is not enough room in the output buffer), next_in is updated and processing will resume at this point for the next call of inflate(). - Provide more output starting at next_out and update next_out and avail_out accordingly. inflate() provides as much output as possible, until there is no more input data or no more space in the output buffer (see below about the flush parameter). Before the call of inflate(), the application should ensure that at least one of the actions is possible, by providing more input and/or consuming more output, and updating the next_* and avail_* values accordingly. The application can consume the uncompressed output when it wants, for example when the output buffer is full (avail_out == 0), or after each call of inflate(). If inflate returns Z_OK and with zero avail_out, it must be called again after making room in the output buffer because there might be more output pending. The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much output as possible to the output buffer. Z_BLOCK requests that inflate() stop if and when it gets to the next deflate block boundary. When decoding the zlib or gzip format, this will cause inflate() to return immediately after the header and before the first block. When doing a raw inflate, inflate() will go ahead and process the first block, and will return when it gets to the end of that block, or when it runs out of data. The Z_BLOCK option assists in appending to or combining deflate streams. Also to assist in this, on return inflate() will set strm->data_type to the number of unused bits in the last byte taken from strm->next_in, plus 64 if inflate() is currently decoding the last block in the deflate stream, plus 128 if inflate() returned immediately after decoding an end-of-block code or decoding the complete header up to just before the first byte of the deflate stream. The end-of-block will not be indicated until all of the uncompressed data from that block has been written to strm->next_out. The number of unused bits may in general be greater than seven, except when bit 7 of data_type is set, in which case the number of unused bits will be less than eight. data_type is set as noted here every time inflate() returns for all flush options, and so can be used to determine the amount of currently consumed input in bits. The Z_TREES option behaves as Z_BLOCK does, but it also returns when the end of each deflate block header is reached, before any actual data in that block is decoded. This allows the caller to determine the length of the deflate block header for later use in random access within a deflate block. 256 is added to the value of strm->data_type when inflate() returns immediately after reaching the end of the deflate block header. inflate() should normally be called until it returns Z_STREAM_END or an error. However if all decompression is to be performed in a single step (a single call of inflate), the parameter flush should be set to Z_FINISH. In this case all pending input is processed and all pending output is flushed; avail_out must be large enough to hold all of the uncompressed data for the operation to complete. (The size of the uncompressed data may have been saved by the compressor for this purpose.) The use of Z_FINISH is not required to perform an inflation in one step. However it may be used to inform inflate that a faster approach can be used for the single inflate() call. Z_FINISH also informs inflate to not maintain a sliding window if the stream completes, which reduces inflate's memory footprint. If the stream does not complete, either because not all of the stream is provided or not enough output space is provided, then a sliding window will be allocated and inflate() can be called again to continue the operation as if Z_NO_FLUSH had been used. In this implementation, inflate() always flushes as much output as possible to the output buffer, and always uses the faster approach on the first call. So the effects of the flush parameter in this implementation are on the return value of inflate() as noted below, when inflate() returns early when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of memory for a sliding window when Z_FINISH is used. If a preset dictionary is needed after this call (see inflateSetDictionary below), inflate sets strm->adler to the Adler-32 checksum of the dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise it sets strm->adler to the Adler-32 checksum of all output produced so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described below. At the end of the stream, inflate() checks that its computed adler32 checksum is equal to that saved by the compressor and returns Z_STREAM_END only if the checksum is correct. inflate() can decompress and check either zlib-wrapped or gzip-wrapped deflate data. The header type is detected automatically, if requested when initializing with inflateInit2(). Any information contained in the gzip header is not retained, so applications that need that information should instead use raw inflate, see inflateInit2() below, or inflateBack() and perform their own processing of the gzip header and trailer. When processing gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output producted so far. The CRC-32 is checked against the gzip trailer. inflate() returns Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if the end of the compressed data has been reached and all uncompressed output has been produced, Z_NEED_DICT if a preset dictionary is needed at this point, Z_DATA_ERROR if the input data was corrupted (input stream not conforming to the zlib format or incorrect check value), Z_STREAM_ERROR if the stream structure was inconsistent (for example next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no progress is possible or if there was not enough room in the output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and inflate() can be called again with more input and more output space to continue decompressing. If Z_DATA_ERROR is returned, the application may then call inflateSync() to look for a good compression block if a partial recovery of the data is desired. */ ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending output. inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state was inconsistent. In the error case, msg may be set but then points to a static string (which must not be deallocated). */ /* Advanced functions */ /* The following functions are needed only in some special applications. */ /* ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy)); This is another version of deflateInit with more compression options. The fields next_in, zalloc, zfree and opaque must be initialized before by the caller. The method parameter is the compression method. It must be Z_DEFLATED in this version of the library. The windowBits parameter is the base two logarithm of the window size (the size of the history buffer). It should be in the range 8..15 for this version of the library. Larger values of this parameter result in better compression at the expense of memory usage. The default value is 15 if deflateInit is used instead. windowBits can also be -8..-15 for raw deflate. In this case, -windowBits determines the window size. deflate() will then generate raw deflate data with no zlib header or trailer, and will not compute an adler32 check value. windowBits can also be greater than 15 for optional gzip encoding. Add 16 to windowBits to write a simple gzip header and trailer around the compressed data instead of a zlib wrapper. The gzip header will have no file name, no extra data, no comment, no modification time (set to zero), no header crc, and the operating system will be set to 255 (unknown). If a gzip stream is being written, strm->adler is a crc32 instead of an adler32. The memLevel parameter specifies how much memory should be allocated for the internal compression state. memLevel=1 uses minimum memory but is slow and reduces compression ratio; memLevel=9 uses maximum memory for optimal speed. The default value is 8. See zconf.h for total memory usage as a function of windowBits and memLevel. The strategy parameter is used to tune the compression algorithm. Use the value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no string match), or Z_RLE to limit match distances to one (run-length encoding). Filtered data consists mostly of small values with a somewhat random distribution. In this case, the compression algorithm is tuned to compress them better. The effect of Z_FILTERED is to force more Huffman coding and less string matching; it is somewhat intermediate between Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy parameter only affects the compression ratio but not the correctness of the compressed output even if it is not set appropriately. Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler decoder for special applications. deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible with the version assumed by the caller (ZLIB_VERSION). msg is set to null if there is no error message. deflateInit2 does not perform any compression: this will be done by deflate(). */ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, const Bytef *dictionary, uInt dictLength)); /* Initializes the compression dictionary from the given byte sequence without producing any compressed output. When using the zlib format, this function must be called immediately after deflateInit, deflateInit2 or deflateReset, and before any call of deflate. When doing raw deflate, this function must be called either before any call of deflate, or immediately after the completion of a deflate block, i.e. after all input has been consumed and all output has been delivered when using any of the flush options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The compressor and decompressor must use exactly the same dictionary (see inflateSetDictionary). The dictionary should consist of strings (byte sequences) that are likely to be encountered later in the data to be compressed, with the most commonly used strings preferably put towards the end of the dictionary. Using a dictionary is most useful when the data to be compressed is short and can be predicted with good accuracy; the data can then be compressed better than with the default empty dictionary. Depending on the size of the compression data structures selected by deflateInit or deflateInit2, a part of the dictionary may in effect be discarded, for example if the dictionary is larger than the window size provided in deflateInit or deflateInit2. Thus the strings most likely to be useful should be put at the end of the dictionary, not at the front. In addition, the current implementation of deflate will use at most the window size minus 262 bytes of the provided dictionary. Upon return of this function, strm->adler is set to the adler32 value of the dictionary; the decompressor may later use this value to determine which dictionary has been used by the compressor. (The adler32 value applies to the whole dictionary even if only a subset of the dictionary is actually used by the compressor.) If a raw deflate was requested, then the adler32 value is not computed and strm->adler is not set. deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is inconsistent (for example if deflate has already been called for this stream or if not at a block boundary for raw deflate). deflateSetDictionary does not perform any compression: this will be done by deflate(). */ ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, z_streamp source)); /* Sets the destination stream as a complete copy of the source stream. This function can be useful when several compression strategies will be tried, for example when there are several ways of pre-processing the input data with a filter. The streams that will be discarded should then be freed by calling deflateEnd. Note that deflateCopy duplicates the internal compression state which can be quite large, so this strategy is slow and can consume lots of memory. deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc being Z_NULL). msg is left unchanged in both source and destination. */ ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); /* This function is equivalent to deflateEnd followed by deflateInit, but does not free and reallocate all the internal compression state. The stream will keep the same compression level and any other attributes that may have been set by deflateInit2. deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being Z_NULL). */ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, int level, int strategy)); /* Dynamically update the compression level and compression strategy. The interpretation of level and strategy is as in deflateInit2. This can be used to switch between compression and straight copy of the input data, or to switch to a different kind of input data requiring a different strategy. If the compression level is changed, the input available so far is compressed with the old level (and may be flushed); the new level will take effect only at the next call of deflate(). Before the call of deflateParams, the stream state must be set as for a call of deflate(), since the currently available input may have to be compressed and flushed. In particular, strm->avail_out must be non-zero. deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if strm->avail_out was zero. */ ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, int good_length, int max_lazy, int nice_length, int max_chain)); /* Fine tune deflate's internal compression parameters. This should only be used by someone who understands the algorithm used by zlib's deflate for searching for the best matching string, and even then only by the most fanatic optimizer trying to squeeze out the last compressed bit for their specific input data. Read the deflate.c source code for the meaning of the max_lazy, good_length, nice_length, and max_chain parameters. deflateTune() can be called after deflateInit() or deflateInit2(), and returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. */ ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, uLong sourceLen)); /* deflateBound() returns an upper bound on the compressed size after deflation of sourceLen bytes. It must be called after deflateInit() or deflateInit2(), and after deflateSetHeader(), if used. This would be used to allocate an output buffer for deflation in a single pass, and so would be called before deflate(). If that first deflate() call is provided the sourceLen input bytes, an output buffer allocated to the size returned by deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed to return Z_STREAM_END. Note that it is possible for the compressed size to be larger than the value returned by deflateBound() if flush options other than Z_FINISH or Z_NO_FLUSH are used. */ ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, unsigned *pending, int *bits)); /* deflatePending() returns the number of bytes and bits of output that have been generated, but not yet provided in the available output. The bytes not provided would be due to the available output space having being consumed. The number of bits of output not provided are between 0 and 7, where they await more bits to join them in order to fill out a full byte. If pending or bits are Z_NULL, then those values are not set. deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent. */ ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, int bits, int value)); /* deflatePrime() inserts bits in the deflate output stream. The intent is that this function is used to start off the deflate output with the bits leftover from a previous deflate stream when appending to it. As such, this function can only be used for raw deflate, and must be used before the first deflate() call after a deflateInit2() or deflateReset(). bits must be less than or equal to 16, and that many of the least significant bits of value will be inserted in the output. deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the source stream state was inconsistent. */ ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, gz_headerp head)); /* deflateSetHeader() provides gzip header information for when a gzip stream is requested by deflateInit2(). deflateSetHeader() may be called after deflateInit2() or deflateReset() and before the first call of deflate(). The text, time, os, extra field, name, and comment information in the provided gz_header structure are written to the gzip header (xflag is ignored -- the extra flags are set according to the compression level). The caller must assure that, if not Z_NULL, name and comment are terminated with a zero byte, and that if extra is not Z_NULL, that extra_len bytes are available there. If hcrc is true, a gzip header crc is included. Note that the current versions of the command-line version of gzip (up through version 1.3.x) do not support header crc's, and will report that it is a "multi-part gzip file" and give up. If deflateSetHeader is not used, the default gzip header has text false, the time set to zero, and os set to 255, with no extra, name, or comment fields. The gzip header is returned to the default state by deflateReset(). deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent. */ /* ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, int windowBits)); This is another version of inflateInit with an extra parameter. The fields next_in, avail_in, zalloc, zfree and opaque must be initialized before by the caller. The windowBits parameter is the base two logarithm of the maximum window size (the size of the history buffer). It should be in the range 8..15 for this version of the library. The default value is 15 if inflateInit is used instead. windowBits must be greater than or equal to the windowBits value provided to deflateInit2() while compressing, or it must be equal to 15 if deflateInit2() was not used. If a compressed stream with a larger window size is given as input, inflate() will return with the error code Z_DATA_ERROR instead of trying to allocate a larger window. windowBits can also be zero to request that inflate use the window size in the zlib header of the compressed stream. windowBits can also be -8..-15 for raw inflate. In this case, -windowBits determines the window size. inflate() will then process raw deflate data, not looking for a zlib or gzip header, not generating a check value, and not looking for any check values for comparison at the end of the stream. This is for use with other formats that use the deflate compressed data format such as zip. Those formats provide their own check values. If a custom format is developed using the raw deflate format for compressed data, it is recommended that a check value such as an adler32 or a crc32 be applied to the uncompressed data as is done in the zlib, gzip, and zip formats. For most applications, the zlib format should be used as is. Note that comments above on the use in deflateInit2() applies to the magnitude of windowBits. windowBits can also be greater than 15 for optional gzip decoding. Add 32 to windowBits to enable zlib and gzip decoding with automatic header detection, or add 16 to decode only the gzip format (the zlib format will return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a crc32 instead of an adler32. inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_VERSION_ERROR if the zlib library version is incompatible with the version assumed by the caller, or Z_STREAM_ERROR if the parameters are invalid, such as a null pointer to the structure. msg is set to null if there is no error message. inflateInit2 does not perform any decompression apart from possibly reading the zlib header if present: actual decompression will be done by inflate(). (So next_in and avail_in may be modified, but next_out and avail_out are unused and unchanged.) The current implementation of inflateInit2() does not process any header information -- that is deferred until inflate() is called. */ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, const Bytef *dictionary, uInt dictLength)); /* Initializes the decompression dictionary from the given uncompressed byte sequence. This function must be called immediately after a call of inflate, if that call returned Z_NEED_DICT. The dictionary chosen by the compressor can be determined from the adler32 value returned by that call of inflate. The compressor and decompressor must use exactly the same dictionary (see deflateSetDictionary). For raw inflate, this function can be called at any time to set the dictionary. If the provided dictionary is smaller than the window and there is already data in the window, then the provided dictionary will amend what's there. The application must insure that the dictionary that was used for compression is provided. inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the expected one (incorrect adler32 value). inflateSetDictionary does not perform any decompression: this will be done by subsequent calls of inflate(). */ ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm, Bytef *dictionary, uInt *dictLength)); /* Returns the sliding dictionary being maintained by inflate. dictLength is set to the number of bytes in the dictionary, and that many bytes are copied to dictionary. dictionary must have enough space, where 32768 bytes is always enough. If inflateGetDictionary() is called with dictionary equal to Z_NULL, then only the dictionary length is returned, and nothing is copied. Similary, if dictLength is Z_NULL, then it is not set. inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the stream state is inconsistent. */ ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); /* Skips invalid compressed data until a possible full flush point (see above for the description of deflate with Z_FULL_FLUSH) can be found, or until all available input is skipped. No output is provided. inflateSync searches for a 00 00 FF FF pattern in the compressed data. All full flush points have this pattern, but not all occurrences of this pattern are full flush points. inflateSync returns Z_OK if a possible full flush point has been found, Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the success case, the application may save the current current value of total_in which indicates where valid compressed data was found. In the error case, the application may repeatedly call inflateSync, providing more input each time, until success or end of the input data. */ ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, z_streamp source)); /* Sets the destination stream as a complete copy of the source stream. This function can be useful when randomly accessing a large stream. The first pass through the stream can periodically record the inflate state, allowing restarting inflate at those points when randomly accessing the stream. inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc being Z_NULL). msg is left unchanged in both source and destination. */ ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); /* This function is equivalent to inflateEnd followed by inflateInit, but does not free and reallocate all the internal decompression state. The stream will keep attributes that may have been set by inflateInit2. inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being Z_NULL). */ ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, int windowBits)); /* This function is the same as inflateReset, but it also permits changing the wrap and window size requests. The windowBits parameter is interpreted the same as it is for inflateInit2. inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent (such as zalloc or state being Z_NULL), or if the windowBits parameter is invalid. */ ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, int bits, int value)); /* This function inserts bits in the inflate input stream. The intent is that this function is used to start inflating at a bit position in the middle of a byte. The provided bits will be used before any bytes are used from next_in. This function should only be used with raw inflate, and should be used before the first inflate() call after inflateInit2() or inflateReset(). bits must be less than or equal to 16, and that many of the least significant bits of value will be inserted in the input. If bits is negative, then the input stream bit buffer is emptied. Then inflatePrime() can be called again to put bits in the buffer. This is used to clear out bits leftover after feeding inflate a block description prior to feeding inflate codes. inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent. */ ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); /* This function returns two values, one in the lower 16 bits of the return value, and the other in the remaining upper bits, obtained by shifting the return value down 16 bits. If the upper value is -1 and the lower value is zero, then inflate() is currently decoding information outside of a block. If the upper value is -1 and the lower value is non-zero, then inflate is in the middle of a stored block, with the lower value equaling the number of bytes from the input remaining to copy. If the upper value is not -1, then it is the number of bits back from the current bit position in the input of the code (literal or length/distance pair) currently being processed. In that case the lower value is the number of bytes already emitted for that code. A code is being processed if inflate is waiting for more input to complete decoding of the code, or if it has completed decoding but is waiting for more output space to write the literal or match data. inflateMark() is used to mark locations in the input data for random access, which may be at bit positions, and to note those cases where the output of a code may span boundaries of random access blocks. The current location in the input stream can be determined from avail_in and data_type as noted in the description for the Z_BLOCK flush parameter for inflate. inflateMark returns the value noted above or -1 << 16 if the provided source stream state was inconsistent. */ ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, gz_headerp head)); /* inflateGetHeader() requests that gzip header information be stored in the provided gz_header structure. inflateGetHeader() may be called after inflateInit2() or inflateReset(), and before the first call of inflate(). As inflate() processes the gzip stream, head->done is zero until the header is completed, at which time head->done is set to one. If a zlib stream is being decoded, then head->done is set to -1 to indicate that there will be no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be used to force inflate() to return immediately after header processing is complete and before any actual data is decompressed. The text, time, xflags, and os fields are filled in with the gzip header contents. hcrc is set to true if there is a header CRC. (The header CRC was valid if done is set to one.) If extra is not Z_NULL, then extra_max contains the maximum number of bytes to write to extra. Once done is true, extra_len contains the actual extra field length, and extra contains the extra field, or that field truncated if extra_max is less than extra_len. If name is not Z_NULL, then up to name_max characters are written there, terminated with a zero unless the length is greater than name_max. If comment is not Z_NULL, then up to comm_max characters are written there, terminated with a zero unless the length is greater than comm_max. When any of extra, name, or comment are not Z_NULL and the respective field is not present in the header, then that field is set to Z_NULL to signal its absence. This allows the use of deflateSetHeader() with the returned structure to duplicate the header. However if those fields are set to allocated memory, then the application will need to save those pointers elsewhere so that they can be eventually freed. If inflateGetHeader is not used, then the header information is simply discarded. The header is always checked for validity, including the header CRC if present. inflateReset() will reset the process to discard the header information. The application would need to call inflateGetHeader() again to retrieve the header from the next gzip stream. inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source stream state was inconsistent. */ /* ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, unsigned char FAR *window)); Initialize the internal stream state for decompression using inflateBack() calls. The fields zalloc, zfree and opaque in strm must be initialized before the call. If zalloc and zfree are Z_NULL, then the default library- derived memory allocation routines are used. windowBits is the base two logarithm of the window size, in the range 8..15. window is a caller supplied buffer of that size. Except for special applications where it is assured that deflate was used with small window sizes, windowBits must be 15 and a 32K byte window must be supplied to be able to decompress general deflate streams. See inflateBack() for the usage of these routines. inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of the parameters are invalid, Z_MEM_ERROR if the internal state could not be allocated, or Z_VERSION_ERROR if the version of the library does not match the version of the header file. */ typedef unsigned (*in_func) OF((void FAR *, z_const unsigned char FAR * FAR *)); typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, in_func in, void FAR *in_desc, out_func out, void FAR *out_desc)); /* inflateBack() does a raw inflate with a single call using a call-back interface for input and output. This is potentially more efficient than inflate() for file i/o applications, in that it avoids copying between the output and the sliding window by simply making the window itself the output buffer. inflate() can be faster on modern CPUs when used with large buffers. inflateBack() trusts the application to not change the output buffer passed by the output function, at least until inflateBack() returns. inflateBackInit() must be called first to allocate the internal state and to initialize the state with the user-provided window buffer. inflateBack() may then be used multiple times to inflate a complete, raw deflate stream with each call. inflateBackEnd() is then called to free the allocated state. A raw deflate stream is one with no zlib or gzip header or trailer. This routine would normally be used in a utility that reads zip or gzip files and writes out uncompressed files. The utility would decode the header and process the trailer on its own, hence this routine expects only the raw deflate stream to decompress. This is different from the normal behavior of inflate(), which expects either a zlib or gzip header and trailer around the deflate stream. inflateBack() uses two subroutines supplied by the caller that are then called by inflateBack() for input and output. inflateBack() calls those routines until it reads a complete deflate stream and writes out all of the uncompressed data, or until it encounters an error. The function's parameters and return types are defined above in the in_func and out_func typedefs. inflateBack() will call in(in_desc, &buf) which should return the number of bytes of provided input, and a pointer to that input in buf. If there is no input available, in() must return zero--buf is ignored in that case--and inflateBack() will return a buffer error. inflateBack() will call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() should return zero on success, or non-zero on failure. If out() returns non-zero, inflateBack() will return with an error. Neither in() nor out() are permitted to change the contents of the window provided to inflateBackInit(), which is also the buffer that out() uses to write from. The length written by out() will be at most the window size. Any non-zero amount of input may be provided by in(). For convenience, inflateBack() can be provided input on the first call by setting strm->next_in and strm->avail_in. If that input is exhausted, then in() will be called. Therefore strm->next_in must be initialized before calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in must also be initialized, and then if strm->avail_in is not zero, input will initially be taken from strm->next_in[0 .. strm->avail_in - 1]. The in_desc and out_desc parameters of inflateBack() is passed as the first parameter of in() and out() respectively when they are called. These descriptors can be optionally used to pass any information that the caller- supplied in() and out() functions need to do their job. On return, inflateBack() will set strm->next_in and strm->avail_in to pass back any unused input that was provided by the last in() call. The return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR if in() or out() returned an error, Z_DATA_ERROR if there was a format error in the deflate stream (in which case strm->msg is set to indicate the nature of the error), or Z_STREAM_ERROR if the stream was not properly initialized. In the case of Z_BUF_ERROR, an input or output error can be distinguished using strm->next_in which will be Z_NULL only if in() returned an error. If strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning non-zero. (in() will always be called before out(), so strm->next_in is assured to be defined if out() returns non-zero.) Note that inflateBack() cannot return Z_OK. */ ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); /* All memory allocated by inflateBackInit() is freed. inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream state was inconsistent. */ ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); /* Return flags indicating compile-time options. Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: 1.0: size of uInt 3.2: size of uLong 5.4: size of voidpf (pointer) 7.6: size of z_off_t Compiler, assembler, and debug options: 8: DEBUG 9: ASMV or ASMINF -- use ASM code 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention 11: 0 (reserved) One-time table building (smaller code, but not thread-safe if true): 12: BUILDFIXED -- build static block decoding tables when needed 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed 14,15: 0 (reserved) Library content (indicates missing functionality): 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking deflate code when not needed) 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect and decode gzip streams (to avoid linking crc code) 18-19: 0 (reserved) Operation variations (changes in library functionality): 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate 21: FASTEST -- deflate algorithm with only one, lowest compression level 22,23: 0 (reserved) The sprintf variant used by gzprintf (zero is best): 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! 26: 0 = returns value, 1 = void -- 1 means inferred string length returned Remainder: 27-31: 0 (reserved) */ #ifndef Z_SOLO /* utility functions */ /* The following utility functions are implemented on top of the basic stream-oriented functions. To simplify the interface, some default options are assumed (compression level and memory usage, standard memory allocation functions). The source code of these utility functions can be modified if you need special options. */ ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)); /* Compresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be at least the value returned by compressBound(sourceLen). Upon exit, destLen is the actual size of the compressed buffer. compress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer. */ ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level)); /* Compresses the source buffer into the destination buffer. The level parameter has the same meaning as in deflateInit. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be at least the value returned by compressBound(sourceLen). Upon exit, destLen is the actual size of the compressed buffer. compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, Z_STREAM_ERROR if the level parameter is invalid. */ ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); /* compressBound() returns an upper bound on the compressed size after compress() or compress2() on sourceLen bytes. It would be used before a compress() or compress2() call to allocate the destination buffer. */ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)); /* Decompresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be large enough to hold the entire uncompressed data. (The size of the uncompressed data must have been saved previously by the compressor and transmitted to the decompressor by some mechanism outside the scope of this compression library.) Upon exit, destLen is the actual size of the uncompressed buffer. uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In the case where there is not enough room, uncompress() will fill the output buffer with the uncompressed data up to that point. */ /* gzip file access functions */ /* This library supports reading and writing files in gzip (.gz) format with an interface similar to that of stdio, using the functions that start with "gz". The gzip format is different from the zlib format. gzip is a gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. */ typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ /* ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); Opens a gzip (.gz) file for reading or writing. The mode parameter is as in fopen ("rb" or "wb") but can also include a compression level ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' for fixed code compression as in "wb9F". (See the description of deflateInit2 for more information about the strategy parameter.) 'T' will request transparent writing or appending with no compression and not using the gzip format. "a" can be used instead of "w" to request that the gzip stream that will be written be appended to the file. "+" will result in an error, since reading and writing to the same gzip file is not supported. The addition of "x" when writing will create the file exclusively, which fails if the file already exists. On systems that support it, the addition of "e" when reading or writing will set the flag to close the file on an execve() call. These functions, as well as gzip, will read and decode a sequence of gzip streams in a file. The append function of gzopen() can be used to create such a file. (Also see gzflush() for another way to do this.) When appending, gzopen does not test whether the file begins with a gzip stream, nor does it look for the end of the gzip streams to begin appending. gzopen will simply append a gzip stream to the existing file. gzopen can be used to read a file which is not in gzip format; in this case gzread will directly read from the file without decompression. When reading, this will be detected automatically by looking for the magic two- byte gzip header. gzopen returns NULL if the file could not be opened, if there was insufficient memory to allocate the gzFile state, or if an invalid mode was specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). errno can be checked to determine if the reason gzopen failed was that the file could not be opened. */ ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); /* gzdopen associates a gzFile with the file descriptor fd. File descriptors are obtained from calls like open, dup, creat, pipe or fileno (if the file has been previously opened with fopen). The mode parameter is as in gzopen. The next call of gzclose on the returned gzFile will also close the file descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, mode);. The duplicated descriptor should be saved to avoid a leak, since gzdopen does not close fd if it fails. If you are using fileno() to get the file descriptor from a FILE *, then you will have to use dup() to avoid double-close()ing the file descriptor. Both gzclose() and fclose() will close the associated file descriptor, so they need to have different file descriptors. gzdopen returns NULL if there was insufficient memory to allocate the gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not provided, or '+' was provided), or if fd is -1. The file descriptor is not used until the next gz* read, write, seek, or close operation, so gzdopen will not detect if fd is invalid (unless fd is -1). */ ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); /* Set the internal buffer size used by this library's functions. The default buffer size is 8192 bytes. This function must be called after gzopen() or gzdopen(), and before any other calls that read or write the file. The buffer memory allocation is always deferred to the first read or write. Two buffers are allocated, either both of the specified size when writing, or one of the specified size and the other twice that size when reading. A larger buffer size of, for example, 64K or 128K bytes will noticeably increase the speed of decompression (reading). The new buffer size also affects the maximum length for gzprintf(). gzbuffer() returns 0 on success, or -1 on failure, such as being called too late. */ ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); /* Dynamically update the compression level or strategy. See the description of deflateInit2 for the meaning of these parameters. gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not opened for writing. */ ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); /* Reads the given number of uncompressed bytes from the compressed file. If the input file is not in gzip format, gzread copies the given number of bytes into the buffer directly from the file. After reaching the end of a gzip stream in the input, gzread will continue to read, looking for another gzip stream. Any number of gzip streams may be concatenated in the input file, and will all be decompressed by gzread(). If something other than a gzip stream is encountered after a gzip stream, that remaining trailing garbage is ignored (and no error is returned). gzread can be used to read a gzip file that is being concurrently written. Upon reaching the end of the input, gzread will return with the available data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then gzclearerr can be used to clear the end of file indicator in order to permit gzread to be tried again. Z_OK indicates that a gzip stream was completed on the last gzread. Z_BUF_ERROR indicates that the input file ended in the middle of a gzip stream. Note that gzread does not return -1 in the event of an incomplete gzip stream. This error is deferred until gzclose(), which will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip stream. Alternatively, gzerror can be used before gzclose to detect this case. gzread returns the number of uncompressed bytes actually read, less than len for end of file, or -1 for error. */ ZEXTERN int ZEXPORT gzwrite OF((gzFile file, voidpc buf, unsigned len)); /* Writes the given number of uncompressed bytes into the compressed file. gzwrite returns the number of uncompressed bytes written or 0 in case of error. */ ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); /* Converts, formats, and writes the arguments to the compressed file under control of the format string, as in fprintf. gzprintf returns the number of uncompressed bytes actually written, or 0 in case of error. The number of uncompressed bytes written is limited to 8191, or one less than the buffer size given to gzbuffer(). The caller should assure that this limit is not exceeded. If it is exceeded, then gzprintf() will return an error (0) with nothing written. In this case, there may also be a buffer overflow with unpredictable consequences, which is possible only if zlib was compiled with the insecure functions sprintf() or vsprintf() because the secure snprintf() or vsnprintf() functions were not available. This can be determined using zlibCompileFlags(). */ ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); /* Writes the given null-terminated string to the compressed file, excluding the terminating null character. gzputs returns the number of characters written, or -1 in case of error. */ ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); /* Reads bytes from the compressed file until len-1 characters are read, or a newline character is read and transferred to buf, or an end-of-file condition is encountered. If any characters are read or if len == 1, the string is terminated with a null character. If no characters are read due to an end-of-file or len < 1, then the buffer is left untouched. gzgets returns buf which is a null-terminated string, or it returns NULL for end-of-file or in case of error. If there was an error, the contents at buf are indeterminate. */ ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); /* Writes c, converted to an unsigned char, into the compressed file. gzputc returns the value that was written, or -1 in case of error. */ ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); /* Reads one byte from the compressed file. gzgetc returns this byte or -1 in case of end of file or error. This is implemented as a macro for speed. As such, it does not do all of the checking the other functions do. I.e. it does not check to see if file is NULL, nor whether the structure file points to has been clobbered or not. */ ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); /* Push one character back onto the stream to be read as the first character on the next read. At least one character of push-back is allowed. gzungetc() returns the character pushed, or -1 on failure. gzungetc() will fail if c is -1, and may fail if a character has been pushed but not read yet. If gzungetc is used immediately after gzopen or gzdopen, at least the output buffer size of pushed characters is allowed. (See gzbuffer above.) The pushed character will be discarded if the stream is repositioned with gzseek() or gzrewind(). */ ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); /* Flushes all pending output into the compressed file. The parameter flush is as in the deflate() function. The return value is the zlib error number (see function gzerror below). gzflush is only permitted when writing. If the flush parameter is Z_FINISH, the remaining data is written and the gzip stream is completed in the output. If gzwrite() is called again, a new gzip stream will be started in the output. gzread() is able to read such concatented gzip streams. gzflush should be called only when strictly necessary because it will degrade compression if called too often. */ /* ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, z_off_t offset, int whence)); Sets the starting position for the next gzread or gzwrite on the given compressed file. The offset represents a number of bytes in the uncompressed data stream. The whence parameter is defined as in lseek(2); the value SEEK_END is not supported. If the file is opened for reading, this function is emulated but can be extremely slow. If the file is opened for writing, only forward seeks are supported; gzseek then compresses a sequence of zeroes up to the new starting position. gzseek returns the resulting offset location as measured in bytes from the beginning of the uncompressed stream, or -1 in case of error, in particular if the file is opened for writing and the new starting position would be before the current position. */ ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); /* Rewinds the given file. This function is supported only for reading. gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) */ /* ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); Returns the starting position for the next gzread or gzwrite on the given compressed file. This position represents a number of bytes in the uncompressed data stream, and is zero when starting, even if appending or reading a gzip stream from the middle of a file using gzdopen(). gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) */ /* ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); Returns the current offset in the file being read or written. This offset includes the count of bytes that precede the gzip stream, for example when appending or when using gzdopen() for reading. When reading, the offset does not include as yet unused buffered input. This information can be used for a progress indicator. On error, gzoffset() returns -1. */ ZEXTERN int ZEXPORT gzeof OF((gzFile file)); /* Returns true (1) if the end-of-file indicator has been set while reading, false (0) otherwise. Note that the end-of-file indicator is set only if the read tried to go past the end of the input, but came up short. Therefore, just like feof(), gzeof() may return false even if there is no more data to read, in the event that the last read request was for the exact number of bytes remaining in the input file. This will happen if the input file size is an exact multiple of the buffer size. If gzeof() returns true, then the read functions will return no more data, unless the end-of-file indicator is reset by gzclearerr() and the input file has grown since the previous end of file was detected. */ ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); /* Returns true (1) if file is being copied directly while reading, or false (0) if file is a gzip stream being decompressed. If the input file is empty, gzdirect() will return true, since the input does not contain a gzip stream. If gzdirect() is used immediately after gzopen() or gzdopen() it will cause buffers to be allocated to allow reading the file to determine if it is a gzip file. Therefore if gzbuffer() is used, it should be called before gzdirect(). When writing, gzdirect() returns true (1) if transparent writing was requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: gzdirect() is not needed when writing. Transparent writing must be explicitly requested, so the application already knows the answer. When linking statically, using gzdirect() will include all of the zlib code for gzip file reading and decompression, which may not be desired.) */ ZEXTERN int ZEXPORT gzclose OF((gzFile file)); /* Flushes all pending output if necessary, closes the compressed file and deallocates the (de)compression state. Note that once file is closed, you cannot call gzerror with file, since its structures have been deallocated. gzclose must not be called more than once on the same file, just as free must not be called more than once on the same allocation. gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the last read ended in the middle of a gzip stream, or Z_OK on success. */ ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); /* Same as gzclose(), but gzclose_r() is only for use when reading, and gzclose_w() is only for use when writing or appending. The advantage to using these instead of gzclose() is that they avoid linking in zlib compression or decompression code that is not used when only reading or only writing respectively. If gzclose() is used, then both compression and decompression code will be included the application when linking to a static zlib library. */ ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); /* Returns the error message for the last error which occurred on the given compressed file. errnum is set to zlib error number. If an error occurred in the file system and not in the compression library, errnum is set to Z_ERRNO and the application may consult errno to get the exact error code. The application must not modify the returned string. Future calls to this function may invalidate the previously returned string. If file is closed, then the string previously returned by gzerror will no longer be available. gzerror() should be used to distinguish errors from end-of-file for those functions above that do not distinguish those cases in their return values. */ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); /* Clears the error and end-of-file flags for file. This is analogous to the clearerr() function in stdio. This is useful for continuing to read a gzip file that is being written concurrently. */ #endif /* !Z_SOLO */ /* checksum functions */ /* These functions are not related to compression but are exported anyway because they might be useful in applications using the compression library. */ ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); /* Update a running Adler-32 checksum with the bytes buf[0..len-1] and return the updated checksum. If buf is Z_NULL, this function returns the required initial value for the checksum. An Adler-32 checksum is almost as reliable as a CRC32 but can be computed much faster. Usage example: uLong adler = adler32(0L, Z_NULL, 0); while (read_buffer(buffer, length) != EOF) { adler = adler32(adler, buffer, length); } if (adler != original_adler) error(); */ /* ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, z_off_t len2)); Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note that the z_off_t type (like off_t) is a signed integer. If len2 is negative, the result has no meaning or utility. */ ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); /* Update a running CRC-32 with the bytes buf[0..len-1] and return the updated CRC-32. If buf is Z_NULL, this function returns the required initial value for the crc. Pre- and post-conditioning (one's complement) is performed within this function so it shouldn't be done by the application. Usage example: uLong crc = crc32(0L, Z_NULL, 0); while (read_buffer(buffer, length) != EOF) { crc = crc32(crc, buffer, length); } if (crc != original_crc) error(); */ /* ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); Combine two CRC-32 check values into one. For two sequences of bytes, seq1 and seq2 with lengths len1 and len2, CRC-32 check values were calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and len2. */ /* various hacks, don't look :) */ /* deflateInit and inflateInit are macros to allow checking the zlib version * and the compiler's view of z_stream: */ ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, const char *version, int stream_size)); ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, const char *version, int stream_size)); ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy, const char *version, int stream_size)); ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, const char *version, int stream_size)); ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, unsigned char FAR *window, const char *version, int stream_size)); #define deflateInit(strm, level) \ deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) #define inflateInit(strm) \ inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) #define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) #define inflateInit2(strm, windowBits) \ inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ (int)sizeof(z_stream)) #define inflateBackInit(strm, windowBits, window) \ inflateBackInit_((strm), (windowBits), (window), \ ZLIB_VERSION, (int)sizeof(z_stream)) #ifndef Z_SOLO /* gzgetc() macro and its supporting function and exposed data structure. Note * that the real internal state is much larger than the exposed structure. * This abbreviated structure exposes just enough for the gzgetc() macro. The * user should not mess with these exposed elements, since their names or * behavior could change in the future, perhaps even capriciously. They can * only be used by the gzgetc() macro. You have been warned. */ struct gzFile_s { unsigned have; unsigned char *next; z_off64_t pos; }; ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ #ifdef Z_PREFIX_SET # undef z_gzgetc # define z_gzgetc(g) \ ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) #else # define gzgetc(g) \ ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) #endif /* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if * both are true, the application gets the *64 functions, and the regular * functions are changed to 64 bits) -- in case these are set on systems * without large file support, _LFS64_LARGEFILE must also be true */ #ifdef Z_LARGE64 ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); #endif #if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) # ifdef Z_PREFIX_SET # define z_gzopen z_gzopen64 # define z_gzseek z_gzseek64 # define z_gztell z_gztell64 # define z_gzoffset z_gzoffset64 # define z_adler32_combine z_adler32_combine64 # define z_crc32_combine z_crc32_combine64 # else # define gzopen gzopen64 # define gzseek gzseek64 # define gztell gztell64 # define gzoffset gzoffset64 # define adler32_combine adler32_combine64 # define crc32_combine crc32_combine64 # endif # ifndef Z_LARGE64 ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); # endif #else ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); #endif #else /* Z_SOLO */ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); #endif /* !Z_SOLO */ /* hack for buggy compilers */ #if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) struct internal_state {int dummy;}; #endif /* undocumented functions */ ZEXTERN const char * ZEXPORT zError OF((int)); ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void)); ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp)); ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); #if defined(_WIN32) && !defined(Z_SOLO) ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path, const char *mode)); #endif #if defined(STDC) || defined(Z_HAVE_STDARG_H) # ifndef Z_SOLO ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file, const char *format, va_list va)); # endif #endif #ifdef __cplusplus } #endif #endif /* ZLIB_H */ gtkwave-3.3.66/src/libz/trees.h0000664000076400007640000002043011523063250015615 0ustar bybellbybell/* header created automatically with -DGEN_TREES_H */ local const ct_data static_ltree[L_CODES+2] = { {{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, {{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, {{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, {{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, {{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, {{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, {{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, {{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, {{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, {{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, {{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, {{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, {{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, {{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, {{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, {{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, {{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, {{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, {{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, {{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, {{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, {{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, {{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, {{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, {{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, {{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, {{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, {{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, {{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, {{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, {{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, {{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, {{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, {{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, {{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, {{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, {{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, {{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, {{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, {{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, {{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, {{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, {{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, {{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, {{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, {{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, {{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, {{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, {{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, {{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, {{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, {{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, {{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, {{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, {{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, {{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, {{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, {{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} }; local const ct_data static_dtree[D_CODES] = { {{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, {{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, {{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, {{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, {{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, {{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} }; const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 }; const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 }; local const int base_length[LENGTH_CODES] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 0 }; local const int base_dist[D_CODES] = { 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 }; gtkwave-3.3.66/src/libz/inffixed.h0000664000076400007640000001427412235606635016313 0ustar bybellbybell /* inffixed.h -- table for decoding fixed codes * Generated automatically by makefixed(). */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of this library and is subject to change. Applications should only use zlib.h. */ static const code lenfix[512] = { {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, {0,9,255} }; static const code distfix[32] = { {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, {22,5,193},{64,5,0} }; gtkwave-3.3.66/src/libz/gzread.c0000664000076400007640000004440612235606635015766 0ustar bybellbybell/* gzread.c -- zlib functions for reading gzip files * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ #include "gzguts.h" /* Local functions */ local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *)); local int gz_avail OF((gz_statep)); local int gz_look OF((gz_statep)); local int gz_decomp OF((gz_statep)); local int gz_fetch OF((gz_statep)); local int gz_skip OF((gz_statep, z_off64_t)); /* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from state->fd, and update state->eof, state->err, and state->msg as appropriate. This function needs to loop on read(), since read() is not guaranteed to read the number of bytes requested, depending on the type of descriptor. */ local int gz_load(state, buf, len, have) gz_statep state; unsigned char *buf; unsigned len; unsigned *have; { int ret; *have = 0; do { ret = read(state->fd, buf + *have, len - *have); if (ret <= 0) break; *have += ret; } while (*have < len); if (ret < 0) { gz_error(state, Z_ERRNO, zstrerror()); return -1; } if (ret == 0) state->eof = 1; return 0; } /* Load up input buffer and set eof flag if last data loaded -- return -1 on error, 0 otherwise. Note that the eof flag is set when the end of the input file is reached, even though there may be unused data in the buffer. Once that data has been used, no more attempts will be made to read the file. If strm->avail_in != 0, then the current data is moved to the beginning of the input buffer, and then the remainder of the buffer is loaded with the available data from the input file. */ local int gz_avail(state) gz_statep state; { unsigned got; z_streamp strm = &(state->strm); if (state->err != Z_OK && state->err != Z_BUF_ERROR) return -1; if (state->eof == 0) { if (strm->avail_in) { /* copy what's there to the start */ unsigned char *p = state->in; unsigned const char *q = strm->next_in; unsigned n = strm->avail_in; do { *p++ = *q++; } while (--n); } if (gz_load(state, state->in + strm->avail_in, state->size - strm->avail_in, &got) == -1) return -1; strm->avail_in += got; strm->next_in = state->in; } return 0; } /* Look for gzip header, set up for inflate or copy. state->x.have must be 0. If this is the first time in, allocate required memory. state->how will be left unchanged if there is no more input data available, will be set to COPY if there is no gzip header and direct copying will be performed, or it will be set to GZIP for decompression. If direct copying, then leftover input data from the input buffer will be copied to the output buffer. In that case, all further file reads will be directly to either the output buffer or a user buffer. If decompressing, the inflate state will be initialized. gz_look() will return 0 on success or -1 on failure. */ local int gz_look(state) gz_statep state; { z_streamp strm = &(state->strm); /* allocate read buffers and inflate memory */ if (state->size == 0) { /* allocate buffers */ state->in = (unsigned char *)malloc(state->want); state->out = (unsigned char *)malloc(state->want << 1); if (state->in == NULL || state->out == NULL) { if (state->out != NULL) free(state->out); if (state->in != NULL) free(state->in); gz_error(state, Z_MEM_ERROR, "out of memory"); return -1; } state->size = state->want; /* allocate inflate memory */ state->strm.zalloc = Z_NULL; state->strm.zfree = Z_NULL; state->strm.opaque = Z_NULL; state->strm.avail_in = 0; state->strm.next_in = Z_NULL; if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */ free(state->out); free(state->in); state->size = 0; gz_error(state, Z_MEM_ERROR, "out of memory"); return -1; } } /* get at least the magic bytes in the input buffer */ if (strm->avail_in < 2) { if (gz_avail(state) == -1) return -1; if (strm->avail_in == 0) return 0; } /* look for gzip magic bytes -- if there, do gzip decoding (note: there is a logical dilemma here when considering the case of a partially written gzip file, to wit, if a single 31 byte is written, then we cannot tell whether this is a single-byte file, or just a partially written gzip file -- for here we assume that if a gzip file is being written, then the header will be written in a single operation, so that reading a single byte is sufficient indication that it is not a gzip file) */ if (strm->avail_in > 1 && strm->next_in[0] == 31 && strm->next_in[1] == 139) { inflateReset(strm); state->how = GZIP; state->direct = 0; return 0; } /* no gzip header -- if we were decoding gzip before, then this is trailing garbage. Ignore the trailing garbage and finish. */ if (state->direct == 0) { strm->avail_in = 0; state->eof = 1; state->x.have = 0; return 0; } /* doing raw i/o, copy any leftover input to output -- this assumes that the output buffer is larger than the input buffer, which also assures space for gzungetc() */ state->x.next = state->out; if (strm->avail_in) { memcpy(state->x.next, strm->next_in, strm->avail_in); state->x.have = strm->avail_in; strm->avail_in = 0; } state->how = COPY; state->direct = 1; return 0; } /* Decompress from input to the provided next_out and avail_out in the state. On return, state->x.have and state->x.next point to the just decompressed data. If the gzip stream completes, state->how is reset to LOOK to look for the next gzip stream or raw data, once state->x.have is depleted. Returns 0 on success, -1 on failure. */ local int gz_decomp(state) gz_statep state; { int ret = Z_OK; unsigned had; z_streamp strm = &(state->strm); /* fill output buffer up to end of deflate stream */ had = strm->avail_out; do { /* get more input for inflate() */ if (strm->avail_in == 0 && gz_avail(state) == -1) return -1; if (strm->avail_in == 0) { gz_error(state, Z_BUF_ERROR, "unexpected end of file"); break; } /* decompress and handle errors */ ret = inflate(strm, Z_NO_FLUSH); if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { gz_error(state, Z_STREAM_ERROR, "internal error: inflate stream corrupt"); return -1; } if (ret == Z_MEM_ERROR) { gz_error(state, Z_MEM_ERROR, "out of memory"); return -1; } if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ gz_error(state, Z_DATA_ERROR, strm->msg == NULL ? "compressed data error" : strm->msg); return -1; } } while (strm->avail_out && ret != Z_STREAM_END); /* update available output */ state->x.have = had - strm->avail_out; state->x.next = strm->next_out - state->x.have; /* if the gzip stream completed successfully, look for another */ if (ret == Z_STREAM_END) state->how = LOOK; /* good decompression */ return 0; } /* Fetch data and put it in the output buffer. Assumes state->x.have is 0. Data is either copied from the input file or decompressed from the input file depending on state->how. If state->how is LOOK, then a gzip header is looked for to determine whether to copy or decompress. Returns -1 on error, otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the end of the input file has been reached and all data has been processed. */ local int gz_fetch(state) gz_statep state; { z_streamp strm = &(state->strm); do { switch(state->how) { case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ if (gz_look(state) == -1) return -1; if (state->how == LOOK) return 0; break; case COPY: /* -> COPY */ if (gz_load(state, state->out, state->size << 1, &(state->x.have)) == -1) return -1; state->x.next = state->out; return 0; case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ strm->avail_out = state->size << 1; strm->next_out = state->out; if (gz_decomp(state) == -1) return -1; } } while (state->x.have == 0 && (!state->eof || strm->avail_in)); return 0; } /* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ local int gz_skip(state, len) gz_statep state; z_off64_t len; { unsigned n; /* skip over len bytes or reach end-of-file, whichever comes first */ while (len) /* skip over whatever is in output buffer */ if (state->x.have) { n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? (unsigned)len : state->x.have; state->x.have -= n; state->x.next += n; state->x.pos += n; len -= n; } /* output buffer empty -- return if we're at the end of the input */ else if (state->eof && state->strm.avail_in == 0) break; /* need more data to skip -- load up output buffer */ else { /* get more output, looking for header if required */ if (gz_fetch(state) == -1) return -1; } return 0; } /* -- see zlib.h -- */ int ZEXPORT gzread(file, buf, len) gzFile file; voidp buf; unsigned len; { unsigned got, n; gz_statep state; z_streamp strm; /* get internal structure */ if (file == NULL) return -1; state = (gz_statep)file; strm = &(state->strm); /* check that we're reading and that there's no (serious) error */ if (state->mode != GZ_READ || (state->err != Z_OK && state->err != Z_BUF_ERROR)) return -1; /* since an int is returned, make sure len fits in one, otherwise return with an error (this avoids the flaw in the interface) */ if ((int)len < 0) { gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); return -1; } /* if len is zero, avoid unnecessary operations */ if (len == 0) return 0; /* process a skip request */ if (state->seek) { state->seek = 0; if (gz_skip(state, state->skip) == -1) return -1; } /* get len bytes to buf, or less than len if at the end */ got = 0; do { /* first just try copying data from the output buffer */ if (state->x.have) { n = state->x.have > len ? len : state->x.have; memcpy(buf, state->x.next, n); state->x.next += n; state->x.have -= n; } /* output buffer empty -- return if we're at the end of the input */ else if (state->eof && strm->avail_in == 0) { state->past = 1; /* tried to read past end */ break; } /* need output data -- for small len or new stream load up our output buffer */ else if (state->how == LOOK || len < (state->size << 1)) { /* get more output, looking for header if required */ if (gz_fetch(state) == -1) return -1; continue; /* no progress yet -- go back to copy above */ /* the copy above assures that we will leave with space in the output buffer, allowing at least one gzungetc() to succeed */ } /* large len -- read directly into user buffer */ else if (state->how == COPY) { /* read directly */ if (gz_load(state, (unsigned char *)buf, len, &n) == -1) return -1; } /* large len -- decompress directly into user buffer */ else { /* state->how == GZIP */ strm->avail_out = len; strm->next_out = (unsigned char *)buf; if (gz_decomp(state) == -1) return -1; n = state->x.have; state->x.have = 0; } /* update progress */ len -= n; buf = (char *)buf + n; got += n; state->x.pos += n; } while (len); /* return number of bytes read into user buffer (will fit in int) */ return (int)got; } /* -- see zlib.h -- */ #ifdef Z_PREFIX_SET # undef z_gzgetc #else # undef gzgetc #endif int ZEXPORT gzgetc(file) gzFile file; { int ret; unsigned char buf[1]; gz_statep state; /* get internal structure */ if (file == NULL) return -1; state = (gz_statep)file; /* check that we're reading and that there's no (serious) error */ if (state->mode != GZ_READ || (state->err != Z_OK && state->err != Z_BUF_ERROR)) return -1; /* try output buffer (no need to check for skip request) */ if (state->x.have) { state->x.have--; state->x.pos++; return *(state->x.next)++; } /* nothing there -- try gzread() */ ret = gzread(file, buf, 1); return ret < 1 ? -1 : buf[0]; } int ZEXPORT gzgetc_(file) gzFile file; { return gzgetc(file); } /* -- see zlib.h -- */ int ZEXPORT gzungetc(c, file) int c; gzFile file; { gz_statep state; /* get internal structure */ if (file == NULL) return -1; state = (gz_statep)file; /* check that we're reading and that there's no (serious) error */ if (state->mode != GZ_READ || (state->err != Z_OK && state->err != Z_BUF_ERROR)) return -1; /* process a skip request */ if (state->seek) { state->seek = 0; if (gz_skip(state, state->skip) == -1) return -1; } /* can't push EOF */ if (c < 0) return -1; /* if output buffer empty, put byte at end (allows more pushing) */ if (state->x.have == 0) { state->x.have = 1; state->x.next = state->out + (state->size << 1) - 1; state->x.next[0] = c; state->x.pos--; state->past = 0; return c; } /* if no room, give up (must have already done a gzungetc()) */ if (state->x.have == (state->size << 1)) { gz_error(state, Z_DATA_ERROR, "out of room to push characters"); return -1; } /* slide output data if needed and insert byte before existing data */ if (state->x.next == state->out) { unsigned char *src = state->out + state->x.have; unsigned char *dest = state->out + (state->size << 1); while (src > state->out) *--dest = *--src; state->x.next = dest; } state->x.have++; state->x.next--; state->x.next[0] = c; state->x.pos--; state->past = 0; return c; } /* -- see zlib.h -- */ char * ZEXPORT gzgets(file, buf, len) gzFile file; char *buf; int len; { unsigned left, n; char *str; unsigned char *eol; gz_statep state; /* check parameters and get internal structure */ if (file == NULL || buf == NULL || len < 1) return NULL; state = (gz_statep)file; /* check that we're reading and that there's no (serious) error */ if (state->mode != GZ_READ || (state->err != Z_OK && state->err != Z_BUF_ERROR)) return NULL; /* process a skip request */ if (state->seek) { state->seek = 0; if (gz_skip(state, state->skip) == -1) return NULL; } /* copy output bytes up to new line or len - 1, whichever comes first -- append a terminating zero to the string (we don't check for a zero in the contents, let the user worry about that) */ str = buf; left = (unsigned)len - 1; if (left) do { /* assure that something is in the output buffer */ if (state->x.have == 0 && gz_fetch(state) == -1) return NULL; /* error */ if (state->x.have == 0) { /* end of file */ state->past = 1; /* read past end */ break; /* return what we have */ } /* look for end-of-line in current output buffer */ n = state->x.have > left ? left : state->x.have; eol = (unsigned char *)memchr(state->x.next, '\n', n); if (eol != NULL) n = (unsigned)(eol - state->x.next) + 1; /* copy through end-of-line, or remainder if not found */ memcpy(buf, state->x.next, n); state->x.have -= n; state->x.next += n; state->x.pos += n; left -= n; buf += n; } while (left && eol == NULL); /* return terminated string, or if nothing, end of file */ if (buf == str) return NULL; buf[0] = 0; return str; } /* -- see zlib.h -- */ int ZEXPORT gzdirect(file) gzFile file; { gz_statep state; /* get internal structure */ if (file == NULL) return 0; state = (gz_statep)file; /* if the state is not known, but we can find out, then do so (this is mainly for right after a gzopen() or gzdopen()) */ if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) (void)gz_look(state); /* return 1 if transparent, 0 if processing a gzip stream */ return state->direct; } /* -- see zlib.h -- */ int ZEXPORT gzclose_r(file) gzFile file; { int ret, err; gz_statep state; /* get internal structure */ if (file == NULL) return Z_STREAM_ERROR; state = (gz_statep)file; /* check that we're reading */ if (state->mode != GZ_READ) return Z_STREAM_ERROR; /* free memory and close file */ if (state->size) { inflateEnd(&(state->strm)); free(state->out); free(state->in); } err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; gz_error(state, Z_OK, NULL); free(state->path); ret = close(state->fd); free(state); return ret ? Z_ERRNO : err; } gtkwave-3.3.66/src/libz/crc32.c0000664000076400007640000003156612235606635015431 0ustar bybellbybell/* crc32.c -- compute the CRC-32 of a data stream * Copyright (C) 1995-2006, 2010, 2011, 2012 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h * * Thanks to Rodney Brown for his contribution of faster * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing * tables for updating the shift register in one step with three exclusive-ors * instead of four steps with four exclusive-ors. This results in about a * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. */ /* @(#) $Id$ */ /* Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore protection on the static variables used to control the first-use generation of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should first call get_crc_table() to initialize the tables before allowing more than one thread to use crc32(). DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h. */ #ifdef MAKECRCH # include # ifndef DYNAMIC_CRC_TABLE # define DYNAMIC_CRC_TABLE # endif /* !DYNAMIC_CRC_TABLE */ #endif /* MAKECRCH */ #include "zutil.h" /* for STDC and FAR definitions */ #define local static /* Definitions for doing the crc four data bytes at a time. */ #if !defined(NOBYFOUR) && defined(Z_U4) # define BYFOUR #endif #ifdef BYFOUR local unsigned long crc32_little OF((unsigned long, const unsigned char FAR *, unsigned)); local unsigned long crc32_big OF((unsigned long, const unsigned char FAR *, unsigned)); # define TBLS 8 #else # define TBLS 1 #endif /* BYFOUR */ /* Local functions for crc concatenation */ local unsigned long gf2_matrix_times OF((unsigned long *mat, unsigned long vec)); local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2)); #ifdef DYNAMIC_CRC_TABLE local volatile int crc_table_empty = 1; local z_crc_t FAR crc_table[TBLS][256]; local void make_crc_table OF((void)); #ifdef MAKECRCH local void write_table OF((FILE *, const z_crc_t FAR *)); #endif /* MAKECRCH */ /* Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. Polynomials over GF(2) are represented in binary, one bit per coefficient, with the lowest powers in the most significant bit. Then adding polynomials is just exclusive-or, and multiplying a polynomial by x is a right shift by one. If we call the above polynomial p, and represent a byte as the polynomial q, also with the lowest power in the most significant bit (so the byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, where a mod b means the remainder after dividing a by b. This calculation is done using the shift-register method of multiplying and taking the remainder. The register is initialized to zero, and for each incoming bit, x^32 is added mod p to the register if the bit is a one (where x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by x (which is shifting right by one and adding x^32 mod p if the bit shifted out is a one). We start with the highest power (least significant bit) of q and repeat for all eight bits of q. The first table is simply the CRC of all possible eight bit values. This is all the information needed to generate CRCs on data a byte at a time for all combinations of CRC register values and incoming bytes. The remaining tables allow for word-at-a-time CRC calculation for both big-endian and little- endian machines, where a word is four bytes. */ local void make_crc_table() { z_crc_t c; int n, k; z_crc_t poly; /* polynomial exclusive-or pattern */ /* terms of polynomial defining this crc (except x^32): */ static volatile int first = 1; /* flag to limit concurrent making */ static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; /* See if another task is already doing this (not thread-safe, but better than nothing -- significantly reduces duration of vulnerability in case the advice about DYNAMIC_CRC_TABLE is ignored) */ if (first) { first = 0; /* make exclusive-or pattern from polynomial (0xedb88320UL) */ poly = 0; for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++) poly |= (z_crc_t)1 << (31 - p[n]); /* generate a crc for every 8-bit value */ for (n = 0; n < 256; n++) { c = (z_crc_t)n; for (k = 0; k < 8; k++) c = c & 1 ? poly ^ (c >> 1) : c >> 1; crc_table[0][n] = c; } #ifdef BYFOUR /* generate crc for each value followed by one, two, and three zeros, and then the byte reversal of those as well as the first table */ for (n = 0; n < 256; n++) { c = crc_table[0][n]; crc_table[4][n] = ZSWAP32(c); for (k = 1; k < 4; k++) { c = crc_table[0][c & 0xff] ^ (c >> 8); crc_table[k][n] = c; crc_table[k + 4][n] = ZSWAP32(c); } } #endif /* BYFOUR */ crc_table_empty = 0; } else { /* not first */ /* wait for the other guy to finish (not efficient, but rare) */ while (crc_table_empty) ; } #ifdef MAKECRCH /* write out CRC tables to crc32.h */ { FILE *out; out = fopen("crc32.h", "w"); if (out == NULL) return; fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); fprintf(out, "local const z_crc_t FAR "); fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); write_table(out, crc_table[0]); # ifdef BYFOUR fprintf(out, "#ifdef BYFOUR\n"); for (k = 1; k < 8; k++) { fprintf(out, " },\n {\n"); write_table(out, crc_table[k]); } fprintf(out, "#endif\n"); # endif /* BYFOUR */ fprintf(out, " }\n};\n"); fclose(out); } #endif /* MAKECRCH */ } #ifdef MAKECRCH local void write_table(out, table) FILE *out; const z_crc_t FAR *table; { int n; for (n = 0; n < 256; n++) fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", (unsigned long)(table[n]), n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); } #endif /* MAKECRCH */ #else /* !DYNAMIC_CRC_TABLE */ /* ======================================================================== * Tables of CRC-32s of all single-byte values, made by make_crc_table(). */ #include "crc32.h" #endif /* DYNAMIC_CRC_TABLE */ /* ========================================================================= * This function can be used by asm versions of crc32() */ const z_crc_t FAR * ZEXPORT get_crc_table() { #ifdef DYNAMIC_CRC_TABLE if (crc_table_empty) make_crc_table(); #endif /* DYNAMIC_CRC_TABLE */ return (const z_crc_t FAR *)crc_table; } /* ========================================================================= */ #define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) #define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 /* ========================================================================= */ unsigned long ZEXPORT crc32(crc, buf, len) unsigned long crc; const unsigned char FAR *buf; uInt len; { if (buf == Z_NULL) return 0UL; #ifdef DYNAMIC_CRC_TABLE if (crc_table_empty) make_crc_table(); #endif /* DYNAMIC_CRC_TABLE */ #ifdef BYFOUR if (sizeof(void *) == sizeof(ptrdiff_t)) { z_crc_t endian; endian = 1; if (*((unsigned char *)(&endian))) return crc32_little(crc, buf, len); else return crc32_big(crc, buf, len); } #endif /* BYFOUR */ crc = crc ^ 0xffffffffUL; while (len >= 8) { DO8; len -= 8; } if (len) do { DO1; } while (--len); return crc ^ 0xffffffffUL; } #ifdef BYFOUR /* ========================================================================= */ #define DOLIT4 c ^= *buf4++; \ c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] #define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 /* ========================================================================= */ local unsigned long crc32_little(crc, buf, len) unsigned long crc; const unsigned char FAR *buf; unsigned len; { register z_crc_t c; register const z_crc_t FAR *buf4; c = (z_crc_t)crc; c = ~c; while (len && ((ptrdiff_t)buf & 3)) { c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); len--; } buf4 = (const z_crc_t FAR *)(const void FAR *)buf; while (len >= 32) { DOLIT32; len -= 32; } while (len >= 4) { DOLIT4; len -= 4; } buf = (const unsigned char FAR *)buf4; if (len) do { c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); } while (--len); c = ~c; return (unsigned long)c; } /* ========================================================================= */ #define DOBIG4 c ^= *++buf4; \ c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] #define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 /* ========================================================================= */ local unsigned long crc32_big(crc, buf, len) unsigned long crc; const unsigned char FAR *buf; unsigned len; { register z_crc_t c; register const z_crc_t FAR *buf4; c = ZSWAP32((z_crc_t)crc); c = ~c; while (len && ((ptrdiff_t)buf & 3)) { c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); len--; } buf4 = (const z_crc_t FAR *)(const void FAR *)buf; buf4--; while (len >= 32) { DOBIG32; len -= 32; } while (len >= 4) { DOBIG4; len -= 4; } buf4++; buf = (const unsigned char FAR *)buf4; if (len) do { c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); } while (--len); c = ~c; return (unsigned long)(ZSWAP32(c)); } #endif /* BYFOUR */ #define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ /* ========================================================================= */ local unsigned long gf2_matrix_times(mat, vec) unsigned long *mat; unsigned long vec; { unsigned long sum; sum = 0; while (vec) { if (vec & 1) sum ^= *mat; vec >>= 1; mat++; } return sum; } /* ========================================================================= */ local void gf2_matrix_square(square, mat) unsigned long *square; unsigned long *mat; { int n; for (n = 0; n < GF2_DIM; n++) square[n] = gf2_matrix_times(mat, mat[n]); } /* ========================================================================= */ local uLong crc32_combine_(crc1, crc2, len2) uLong crc1; uLong crc2; z_off64_t len2; { int n; unsigned long row; unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ /* degenerate case (also disallow negative lengths) */ if (len2 <= 0) return crc1; /* put operator for one zero bit in odd */ odd[0] = 0xedb88320UL; /* CRC-32 polynomial */ row = 1; for (n = 1; n < GF2_DIM; n++) { odd[n] = row; row <<= 1; } /* put operator for two zero bits in even */ gf2_matrix_square(even, odd); /* put operator for four zero bits in odd */ gf2_matrix_square(odd, even); /* apply len2 zeros to crc1 (first square will put the operator for one zero byte, eight zero bits, in even) */ do { /* apply zeros operator for this bit of len2 */ gf2_matrix_square(even, odd); if (len2 & 1) crc1 = gf2_matrix_times(even, crc1); len2 >>= 1; /* if no more bits set, then done */ if (len2 == 0) break; /* another iteration of the loop with odd and even swapped */ gf2_matrix_square(odd, even); if (len2 & 1) crc1 = gf2_matrix_times(odd, crc1); len2 >>= 1; /* if no more bits set, then done */ } while (len2 != 0); /* return combined crc */ crc1 ^= crc2; return crc1; } /* ========================================================================= */ uLong ZEXPORT crc32_combine(crc1, crc2, len2) uLong crc1; uLong crc2; z_off_t len2; { return crc32_combine_(crc1, crc2, len2); } uLong ZEXPORT crc32_combine64(crc1, crc2, len2) uLong crc1; uLong crc2; z_off64_t len2; { return crc32_combine_(crc1, crc2, len2); } gtkwave-3.3.66/src/libz/README0000664000076400007640000001210112235606635015211 0ustar bybellbybellZLIB DATA COMPRESSION LIBRARY zlib 1.2.8 is a general purpose data compression library. All the code is thread safe. The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). All functions of the compression library are documented in the file zlib.h (volunteer to write man pages welcome, contact zlib@gzip.org). A usage example of the library is given in the file test/example.c which also tests that the library is working correctly. Another example is given in the file test/minigzip.c. The compression library itself is composed of all source files in the root directory. To compile all files and run the test program, follow the instructions given at the top of Makefile.in. In short "./configure; make test", and if that goes well, "make install" should work for most flavors of Unix. For Windows, use one of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use make_vms.com. Questions about zlib should be sent to , or to Gilles Vollant for the Windows DLL version. The zlib home page is http://zlib.net/ . Before reporting a problem, please check this site to verify that you have the latest version of zlib; otherwise get the latest version and check whether the problem still exists or not. PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help. Mark Nelson wrote an article about zlib for the Jan. 1997 issue of Dr. Dobb's Journal; a copy of the article is available at http://marknelson.us/1997/01/01/zlib-engine/ . The changes made in version 1.2.8 are documented in the file ChangeLog. Unsupported third party contributions are provided in directory contrib/ . zlib is available in Java using the java.util.zip package, documented at http://java.sun.com/developer/technicalArticles/Programming/compression/ . A Perl interface to zlib written by Paul Marquess is available at CPAN (Comprehensive Perl Archive Network) sites, including http://search.cpan.org/~pmqs/IO-Compress-Zlib/ . A Python interface to zlib written by A.M. Kuchling is available in Python 1.5 and later versions, see http://docs.python.org/library/zlib.html . zlib is built into tcl: http://wiki.tcl.tk/4610 . An experimental package to read and write files in .zip format, written on top of zlib by Gilles Vollant , is available in the contrib/minizip directory of zlib. Notes for some targets: - For Windows DLL versions, please see win32/DLL_FAQ.txt - For 64-bit Irix, deflate.c must be compiled without any optimization. With -O, one libpng test fails. The test works in 32 bit mode (with the -n32 compiler flag). The compiler bug has been reported to SGI. - zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works when compiled with cc. - On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is necessary to get gzprintf working correctly. This is done by configure. - zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with other compilers. Use "make test" to check your compiler. - gzdopen is not supported on RISCOS or BEOS. - For PalmOs, see http://palmzlib.sourceforge.net/ Acknowledgments: The deflate format used by zlib was defined by Phil Katz. The deflate and zlib specifications were written by L. Peter Deutsch. Thanks to all the people who reported problems and suggested various improvements in zlib; they are too numerous to cite here. Copyright notice: (C) 1995-2013 Jean-loup Gailly and Mark Adler 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. Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu If you use the zlib library in a product, we would appreciate *not* receiving lengthy legal documents to sign. The sources are provided for free but without warranty of any kind. The library has been entirely written by Jean-loup Gailly and Mark Adler; it does not include third-party code. If you redistribute modified sources, we would appreciate that you include in the file ChangeLog history information documenting your changes. Please read the FAQ for more information on the distribution of modified source versions. gtkwave-3.3.66/src/libz/zutil.c0000664000076400007640000001636612235606635015665 0ustar bybellbybell/* zutil.c -- target dependent utility functions for the compression library * Copyright (C) 1995-2005, 2010, 2011, 2012 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* @(#) $Id$ */ #include "zutil.h" #ifndef Z_SOLO # include "gzguts.h" #endif #ifndef NO_DUMMY_DECL struct internal_state {int dummy;}; /* for buggy compilers */ #endif z_const char * const z_errmsg[10] = { "need dictionary", /* Z_NEED_DICT 2 */ "stream end", /* Z_STREAM_END 1 */ "", /* Z_OK 0 */ "file error", /* Z_ERRNO (-1) */ "stream error", /* Z_STREAM_ERROR (-2) */ "data error", /* Z_DATA_ERROR (-3) */ "insufficient memory", /* Z_MEM_ERROR (-4) */ "buffer error", /* Z_BUF_ERROR (-5) */ "incompatible version",/* Z_VERSION_ERROR (-6) */ ""}; const char * ZEXPORT zlibVersion() { return ZLIB_VERSION; } uLong ZEXPORT zlibCompileFlags() { uLong flags; flags = 0; switch ((int)(sizeof(uInt))) { case 2: break; case 4: flags += 1; break; case 8: flags += 2; break; default: flags += 3; } switch ((int)(sizeof(uLong))) { case 2: break; case 4: flags += 1 << 2; break; case 8: flags += 2 << 2; break; default: flags += 3 << 2; } switch ((int)(sizeof(voidpf))) { case 2: break; case 4: flags += 1 << 4; break; case 8: flags += 2 << 4; break; default: flags += 3 << 4; } switch ((int)(sizeof(z_off_t))) { case 2: break; case 4: flags += 1 << 6; break; case 8: flags += 2 << 6; break; default: flags += 3 << 6; } #ifdef DEBUG flags += 1 << 8; #endif #if defined(ASMV) || defined(ASMINF) flags += 1 << 9; #endif #ifdef ZLIB_WINAPI flags += 1 << 10; #endif #ifdef BUILDFIXED flags += 1 << 12; #endif #ifdef DYNAMIC_CRC_TABLE flags += 1 << 13; #endif #ifdef NO_GZCOMPRESS flags += 1L << 16; #endif #ifdef NO_GZIP flags += 1L << 17; #endif #ifdef PKZIP_BUG_WORKAROUND flags += 1L << 20; #endif #ifdef FASTEST flags += 1L << 21; #endif #if defined(STDC) || defined(Z_HAVE_STDARG_H) # ifdef NO_vsnprintf flags += 1L << 25; # ifdef HAS_vsprintf_void flags += 1L << 26; # endif # else # ifdef HAS_vsnprintf_void flags += 1L << 26; # endif # endif #else flags += 1L << 24; # ifdef NO_snprintf flags += 1L << 25; # ifdef HAS_sprintf_void flags += 1L << 26; # endif # else # ifdef HAS_snprintf_void flags += 1L << 26; # endif # endif #endif return flags; } #ifdef DEBUG # ifndef verbose # define verbose 0 # endif int ZLIB_INTERNAL z_verbose = verbose; void ZLIB_INTERNAL z_error (m) char *m; { fprintf(stderr, "%s\n", m); exit(1); } #endif /* exported to allow conversion of error code to string for compress() and * uncompress() */ const char * ZEXPORT zError(err) int err; { return ERR_MSG(err); } #if defined(_WIN32_WCE) /* The Microsoft C Run-Time Library for Windows CE doesn't have * errno. We define it as a global variable to simplify porting. * Its value is always 0 and should not be used. */ int errno = 0; #endif #ifndef HAVE_MEMCPY void ZLIB_INTERNAL zmemcpy(dest, source, len) Bytef* dest; const Bytef* source; uInt len; { if (len == 0) return; do { *dest++ = *source++; /* ??? to be unrolled */ } while (--len != 0); } int ZLIB_INTERNAL zmemcmp(s1, s2, len) const Bytef* s1; const Bytef* s2; uInt len; { uInt j; for (j = 0; j < len; j++) { if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; } return 0; } void ZLIB_INTERNAL zmemzero(dest, len) Bytef* dest; uInt len; { if (len == 0) return; do { *dest++ = 0; /* ??? to be unrolled */ } while (--len != 0); } #endif #ifndef Z_SOLO #ifdef SYS16BIT #ifdef __TURBOC__ /* Turbo C in 16-bit mode */ # define MY_ZCALLOC /* Turbo C malloc() does not allow dynamic allocation of 64K bytes * and farmalloc(64K) returns a pointer with an offset of 8, so we * must fix the pointer. Warning: the pointer must be put back to its * original form in order to free it, use zcfree(). */ #define MAX_PTR 10 /* 10*64K = 640K */ local int next_ptr = 0; typedef struct ptr_table_s { voidpf org_ptr; voidpf new_ptr; } ptr_table; local ptr_table table[MAX_PTR]; /* This table is used to remember the original form of pointers * to large buffers (64K). Such pointers are normalized with a zero offset. * Since MSDOS is not a preemptive multitasking OS, this table is not * protected from concurrent access. This hack doesn't work anyway on * a protected system like OS/2. Use Microsoft C instead. */ voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size) { voidpf buf = opaque; /* just to make some compilers happy */ ulg bsize = (ulg)items*size; /* If we allocate less than 65520 bytes, we assume that farmalloc * will return a usable pointer which doesn't have to be normalized. */ if (bsize < 65520L) { buf = farmalloc(bsize); if (*(ush*)&buf != 0) return buf; } else { buf = farmalloc(bsize + 16L); } if (buf == NULL || next_ptr >= MAX_PTR) return NULL; table[next_ptr].org_ptr = buf; /* Normalize the pointer to seg:0 */ *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; *(ush*)&buf = 0; table[next_ptr++].new_ptr = buf; return buf; } void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) { int n; if (*(ush*)&ptr != 0) { /* object < 64K */ farfree(ptr); return; } /* Find the original pointer */ for (n = 0; n < next_ptr; n++) { if (ptr != table[n].new_ptr) continue; farfree(table[n].org_ptr); while (++n < next_ptr) { table[n-1] = table[n]; } next_ptr--; return; } ptr = opaque; /* just to make some compilers happy */ Assert(0, "zcfree: ptr not found"); } #endif /* __TURBOC__ */ #ifdef M_I86 /* Microsoft C in 16-bit mode */ # define MY_ZCALLOC #if (!defined(_MSC_VER) || (_MSC_VER <= 600)) # define _halloc halloc # define _hfree hfree #endif voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size) { if (opaque) opaque = 0; /* to make compiler happy */ return _halloc((long)items, size); } void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) { if (opaque) opaque = 0; /* to make compiler happy */ _hfree(ptr); } #endif /* M_I86 */ #endif /* SYS16BIT */ #ifndef MY_ZCALLOC /* Any system without a special alloc function */ #ifndef STDC extern voidp malloc OF((uInt size)); extern voidp calloc OF((uInt items, uInt size)); extern void free OF((voidpf ptr)); #endif voidpf ZLIB_INTERNAL zcalloc (opaque, items, size) voidpf opaque; unsigned items; unsigned size; { if (opaque) items += size - size; /* make compiler happy */ return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : (voidpf)calloc(items, size); } void ZLIB_INTERNAL zcfree (opaque, ptr) voidpf opaque; voidpf ptr; { free(ptr); if (opaque) return; /* make compiler happy */ } #endif /* MY_ZCALLOC */ #endif /* !Z_SOLO */ gtkwave-3.3.66/src/libz/zutil.h0000664000076400007640000001515612235606635015666 0ustar bybellbybell/* zutil.h -- internal interface and configuration of the compression library * Copyright (C) 1995-2013 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ /* @(#) $Id$ */ #ifndef ZUTIL_H #define ZUTIL_H #ifdef HAVE_HIDDEN # define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) #else # define ZLIB_INTERNAL #endif #include "zlib.h" #if defined(STDC) && !defined(Z_SOLO) # if !(defined(_WIN32_WCE) && defined(_MSC_VER)) # include # endif # include # include #endif #ifdef Z_SOLO typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */ #endif #ifndef local # define local static #endif /* compile with -Dlocal if your debugger can't find static symbols */ typedef unsigned char uch; typedef uch FAR uchf; typedef unsigned short ush; typedef ush FAR ushf; typedef unsigned long ulg; extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ /* (size given to avoid silly warnings with Visual C++) */ #define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] #define ERR_RETURN(strm,err) \ return (strm->msg = ERR_MSG(err), (err)) /* To be used only when the state is known to be valid */ /* common constants */ #ifndef DEF_WBITS # define DEF_WBITS MAX_WBITS #endif /* default windowBits for decompression. MAX_WBITS is for compression only */ #if MAX_MEM_LEVEL >= 8 # define DEF_MEM_LEVEL 8 #else # define DEF_MEM_LEVEL MAX_MEM_LEVEL #endif /* default memLevel */ #define STORED_BLOCK 0 #define STATIC_TREES 1 #define DYN_TREES 2 /* The three kinds of block type */ #define MIN_MATCH 3 #define MAX_MATCH 258 /* The minimum and maximum match lengths */ #define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ /* target dependencies */ #if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) # define OS_CODE 0x00 # ifndef Z_SOLO # if defined(__TURBOC__) || defined(__BORLANDC__) # if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) /* Allow compilation with ANSI keywords only enabled */ void _Cdecl farfree( void *block ); void *_Cdecl farmalloc( unsigned long nbytes ); # else # include # endif # else /* MSC or DJGPP */ # include # endif # endif #endif #ifdef AMIGA # define OS_CODE 0x01 #endif #if defined(VAXC) || defined(VMS) # define OS_CODE 0x02 # define F_OPEN(name, mode) \ fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") #endif #if defined(ATARI) || defined(atarist) # define OS_CODE 0x05 #endif #ifdef OS2 # define OS_CODE 0x06 # if defined(M_I86) && !defined(Z_SOLO) # include # endif #endif #if defined(MACOS) || defined(TARGET_OS_MAC) # define OS_CODE 0x07 # ifndef Z_SOLO # if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os # include /* for fdopen */ # else # ifndef fdopen # define fdopen(fd,mode) NULL /* No fdopen() */ # endif # endif # endif #endif #ifdef TOPS20 # define OS_CODE 0x0a #endif #ifdef WIN32 # ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ # define OS_CODE 0x0b # endif #endif #ifdef __50SERIES /* Prime/PRIMOS */ # define OS_CODE 0x0f #endif #if defined(_BEOS_) || defined(RISCOS) # define fdopen(fd,mode) NULL /* No fdopen() */ #endif #if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX # if defined(_WIN32_WCE) # define fdopen(fd,mode) NULL /* No fdopen() */ # ifndef _PTRDIFF_T_DEFINED typedef int ptrdiff_t; # define _PTRDIFF_T_DEFINED # endif # else # define fdopen(fd,type) _fdopen(fd,type) # endif #endif #if defined(__BORLANDC__) && !defined(MSDOS) #pragma warn -8004 #pragma warn -8008 #pragma warn -8066 #endif /* provide prototypes for these when building zlib without LFS */ #if !defined(_WIN32) && \ (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); #endif /* common defaults */ #ifndef OS_CODE # define OS_CODE 0x03 /* assume Unix */ #endif #ifndef F_OPEN # define F_OPEN(name, mode) fopen((name), (mode)) #endif /* functions */ #if defined(pyr) || defined(Z_SOLO) # define NO_MEMCPY #endif #if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) /* Use our own functions for small and medium model with MSC <= 5.0. * You may have to use the same strategy for Borland C (untested). * The __SC__ check is for Symantec. */ # define NO_MEMCPY #endif #if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) # define HAVE_MEMCPY #endif #ifdef HAVE_MEMCPY # ifdef SMALL_MEDIUM /* MSDOS small or medium model */ # define zmemcpy _fmemcpy # define zmemcmp _fmemcmp # define zmemzero(dest, len) _fmemset(dest, 0, len) # else # define zmemcpy memcpy # define zmemcmp memcmp # define zmemzero(dest, len) memset(dest, 0, len) # endif #else void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len)); #endif /* Diagnostic functions */ #ifdef DEBUG # include extern int ZLIB_INTERNAL z_verbose; extern void ZLIB_INTERNAL z_error OF((char *m)); # define Assert(cond,msg) {if(!(cond)) z_error(msg);} # define Trace(x) {if (z_verbose>=0) fprintf x ;} # define Tracev(x) {if (z_verbose>0) fprintf x ;} # define Tracevv(x) {if (z_verbose>1) fprintf x ;} # define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} # define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} #else # define Assert(cond,msg) # define Trace(x) # define Tracev(x) # define Tracevv(x) # define Tracec(c,x) # define Tracecv(c,x) #endif #ifndef Z_SOLO voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, unsigned size)); void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); #endif #define ZALLOC(strm, items, size) \ (*((strm)->zalloc))((strm)->opaque, (items), (size)) #define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) #define TRY_FREE(s, p) {if (p) ZFREE(s, p);} /* Reverse the bytes in a 32-bit value */ #define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) #endif /* ZUTIL_H */ gtkwave-3.3.66/src/libz/trees.c0000664000076400007640000012633712235606635015640 0ustar bybellbybell/* trees.c -- output deflated data using Huffman coding * Copyright (C) 1995-2012 Jean-loup Gailly * detect_data_type() function provided freely by Cosmin Truta, 2006 * For conditions of distribution and use, see copyright notice in zlib.h */ /* * ALGORITHM * * The "deflation" process uses several Huffman trees. The more * common source values are represented by shorter bit sequences. * * Each code tree is stored in a compressed form which is itself * a Huffman encoding of the lengths of all the code strings (in * ascending order by source values). The actual code strings are * reconstructed from the lengths in the inflate process, as described * in the deflate specification. * * REFERENCES * * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc * * Storer, James A. * Data Compression: Methods and Theory, pp. 49-50. * Computer Science Press, 1988. ISBN 0-7167-8156-5. * * Sedgewick, R. * Algorithms, p290. * Addison-Wesley, 1983. ISBN 0-201-06672-6. */ /* @(#) $Id$ */ /* #define GEN_TREES_H */ #include "deflate.h" #ifdef DEBUG # include #endif /* =========================================================================== * Constants */ #define MAX_BL_BITS 7 /* Bit length codes must not exceed MAX_BL_BITS bits */ #define END_BLOCK 256 /* end of block literal code */ #define REP_3_6 16 /* repeat previous bit length 3-6 times (2 bits of repeat count) */ #define REPZ_3_10 17 /* repeat a zero length 3-10 times (3 bits of repeat count) */ #define REPZ_11_138 18 /* repeat a zero length 11-138 times (7 bits of repeat count) */ local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; local const int extra_dbits[D_CODES] /* extra bits for each distance code */ = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; local const uch bl_order[BL_CODES] = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; /* The lengths of the bit length codes are sent in order of decreasing * probability, to avoid transmitting the lengths for unused bit length codes. */ /* =========================================================================== * Local data. These are initialized only once. */ #define DIST_CODE_LEN 512 /* see definition of array dist_code below */ #if defined(GEN_TREES_H) || !defined(STDC) /* non ANSI compilers may not accept trees.h */ local ct_data static_ltree[L_CODES+2]; /* The static literal tree. Since the bit lengths are imposed, there is no * need for the L_CODES extra codes used during heap construction. However * The codes 286 and 287 are needed to build a canonical tree (see _tr_init * below). */ local ct_data static_dtree[D_CODES]; /* The static distance tree. (Actually a trivial tree since all codes use * 5 bits.) */ uch _dist_code[DIST_CODE_LEN]; /* Distance codes. The first 256 values correspond to the distances * 3 .. 258, the last 256 values correspond to the top 8 bits of * the 15 bit distances. */ uch _length_code[MAX_MATCH-MIN_MATCH+1]; /* length code for each normalized match length (0 == MIN_MATCH) */ local int base_length[LENGTH_CODES]; /* First normalized length for each code (0 = MIN_MATCH) */ local int base_dist[D_CODES]; /* First normalized distance for each code (0 = distance of 1) */ #else # include "trees.h" #endif /* GEN_TREES_H */ struct static_tree_desc_s { const ct_data *static_tree; /* static tree or NULL */ const intf *extra_bits; /* extra bits for each code or NULL */ int extra_base; /* base index for extra_bits */ int elems; /* max number of elements in the tree */ int max_length; /* max bit length for the codes */ }; local static_tree_desc static_l_desc = {static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; local static_tree_desc static_d_desc = {static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; local static_tree_desc static_bl_desc = {(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; /* =========================================================================== * Local (static) routines in this file. */ local void tr_static_init OF((void)); local void init_block OF((deflate_state *s)); local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); local void build_tree OF((deflate_state *s, tree_desc *desc)); local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); local int build_bl_tree OF((deflate_state *s)); local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, int blcodes)); local void compress_block OF((deflate_state *s, const ct_data *ltree, const ct_data *dtree)); local int detect_data_type OF((deflate_state *s)); local unsigned bi_reverse OF((unsigned value, int length)); local void bi_windup OF((deflate_state *s)); local void bi_flush OF((deflate_state *s)); local void copy_block OF((deflate_state *s, charf *buf, unsigned len, int header)); #ifdef GEN_TREES_H local void gen_trees_header OF((void)); #endif #ifndef DEBUG # define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) /* Send a code of the given tree. c and tree must not have side effects */ #else /* DEBUG */ # define send_code(s, c, tree) \ { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ send_bits(s, tree[c].Code, tree[c].Len); } #endif /* =========================================================================== * Output a short LSB first on the stream. * IN assertion: there is enough room in pendingBuf. */ #define put_short(s, w) { \ put_byte(s, (uch)((w) & 0xff)); \ put_byte(s, (uch)((ush)(w) >> 8)); \ } /* =========================================================================== * Send a value on a given number of bits. * IN assertion: length <= 16 and value fits in length bits. */ #ifdef DEBUG local void send_bits OF((deflate_state *s, int value, int length)); local void send_bits(s, value, length) deflate_state *s; int value; /* value to send */ int length; /* number of bits */ { Tracevv((stderr," l %2d v %4x ", length, value)); Assert(length > 0 && length <= 15, "invalid length"); s->bits_sent += (ulg)length; /* If not enough room in bi_buf, use (valid) bits from bi_buf and * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) * unused bits in value. */ if (s->bi_valid > (int)Buf_size - length) { s->bi_buf |= (ush)value << s->bi_valid; put_short(s, s->bi_buf); s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); s->bi_valid += length - Buf_size; } else { s->bi_buf |= (ush)value << s->bi_valid; s->bi_valid += length; } } #else /* !DEBUG */ #define send_bits(s, value, length) \ { int len = length;\ if (s->bi_valid > (int)Buf_size - len) {\ int val = value;\ s->bi_buf |= (ush)val << s->bi_valid;\ put_short(s, s->bi_buf);\ s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ s->bi_valid += len - Buf_size;\ } else {\ s->bi_buf |= (ush)(value) << s->bi_valid;\ s->bi_valid += len;\ }\ } #endif /* DEBUG */ /* the arguments must not have side effects */ /* =========================================================================== * Initialize the various 'constant' tables. */ local void tr_static_init() { #if defined(GEN_TREES_H) || !defined(STDC) static int static_init_done = 0; int n; /* iterates over tree elements */ int bits; /* bit counter */ int length; /* length value */ int code; /* code value */ int dist; /* distance index */ ush bl_count[MAX_BITS+1]; /* number of codes at each bit length for an optimal tree */ if (static_init_done) return; /* For some embedded targets, global variables are not initialized: */ #ifdef NO_INIT_GLOBAL_POINTERS static_l_desc.static_tree = static_ltree; static_l_desc.extra_bits = extra_lbits; static_d_desc.static_tree = static_dtree; static_d_desc.extra_bits = extra_dbits; static_bl_desc.extra_bits = extra_blbits; #endif /* Initialize the mapping length (0..255) -> length code (0..28) */ length = 0; for (code = 0; code < LENGTH_CODES-1; code++) { base_length[code] = length; for (n = 0; n < (1< dist code (0..29) */ dist = 0; for (code = 0 ; code < 16; code++) { base_dist[code] = dist; for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ for ( ; code < D_CODES; code++) { base_dist[code] = dist << 7; for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { _dist_code[256 + dist++] = (uch)code; } } Assert (dist == 256, "tr_static_init: 256+dist != 512"); /* Construct the codes of the static literal tree */ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; n = 0; while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; /* Codes 286 and 287 do not exist, but we must include them in the * tree construction to get a canonical Huffman tree (longest code * all ones) */ gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); /* The static distance tree is trivial: */ for (n = 0; n < D_CODES; n++) { static_dtree[n].Len = 5; static_dtree[n].Code = bi_reverse((unsigned)n, 5); } static_init_done = 1; # ifdef GEN_TREES_H gen_trees_header(); # endif #endif /* defined(GEN_TREES_H) || !defined(STDC) */ } /* =========================================================================== * Genererate the file trees.h describing the static trees. */ #ifdef GEN_TREES_H # ifndef DEBUG # include # endif # define SEPARATOR(i, last, width) \ ((i) == (last)? "\n};\n\n" : \ ((i) % (width) == (width)-1 ? ",\n" : ", ")) void gen_trees_header() { FILE *header = fopen("trees.h", "w"); int i; Assert (header != NULL, "Can't open trees.h"); fprintf(header, "/* header created automatically with -DGEN_TREES_H */\n\n"); fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); for (i = 0; i < L_CODES+2; i++) { fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); } fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); for (i = 0; i < D_CODES; i++) { fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); } fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); for (i = 0; i < DIST_CODE_LEN; i++) { fprintf(header, "%2u%s", _dist_code[i], SEPARATOR(i, DIST_CODE_LEN-1, 20)); } fprintf(header, "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { fprintf(header, "%2u%s", _length_code[i], SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); } fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); for (i = 0; i < LENGTH_CODES; i++) { fprintf(header, "%1u%s", base_length[i], SEPARATOR(i, LENGTH_CODES-1, 20)); } fprintf(header, "local const int base_dist[D_CODES] = {\n"); for (i = 0; i < D_CODES; i++) { fprintf(header, "%5u%s", base_dist[i], SEPARATOR(i, D_CODES-1, 10)); } fclose(header); } #endif /* GEN_TREES_H */ /* =========================================================================== * Initialize the tree data structures for a new zlib stream. */ void ZLIB_INTERNAL _tr_init(s) deflate_state *s; { tr_static_init(); s->l_desc.dyn_tree = s->dyn_ltree; s->l_desc.stat_desc = &static_l_desc; s->d_desc.dyn_tree = s->dyn_dtree; s->d_desc.stat_desc = &static_d_desc; s->bl_desc.dyn_tree = s->bl_tree; s->bl_desc.stat_desc = &static_bl_desc; s->bi_buf = 0; s->bi_valid = 0; #ifdef DEBUG s->compressed_len = 0L; s->bits_sent = 0L; #endif /* Initialize the first block of the first file: */ init_block(s); } /* =========================================================================== * Initialize a new block. */ local void init_block(s) deflate_state *s; { int n; /* iterates over tree elements */ /* Initialize the trees. */ for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; s->dyn_ltree[END_BLOCK].Freq = 1; s->opt_len = s->static_len = 0L; s->last_lit = s->matches = 0; } #define SMALLEST 1 /* Index within the heap array of least frequent node in the Huffman tree */ /* =========================================================================== * Remove the smallest element from the heap and recreate the heap with * one less element. Updates heap and heap_len. */ #define pqremove(s, tree, top) \ {\ top = s->heap[SMALLEST]; \ s->heap[SMALLEST] = s->heap[s->heap_len--]; \ pqdownheap(s, tree, SMALLEST); \ } /* =========================================================================== * Compares to subtrees, using the tree depth as tie breaker when * the subtrees have equal frequency. This minimizes the worst case length. */ #define smaller(tree, n, m, depth) \ (tree[n].Freq < tree[m].Freq || \ (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) /* =========================================================================== * Restore the heap property by moving down the tree starting at node k, * exchanging a node with the smallest of its two sons if necessary, stopping * when the heap property is re-established (each father smaller than its * two sons). */ local void pqdownheap(s, tree, k) deflate_state *s; ct_data *tree; /* the tree to restore */ int k; /* node to move down */ { int v = s->heap[k]; int j = k << 1; /* left son of k */ while (j <= s->heap_len) { /* Set j to the smallest of the two sons: */ if (j < s->heap_len && smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { j++; } /* Exit if v is smaller than both sons */ if (smaller(tree, v, s->heap[j], s->depth)) break; /* Exchange v with the smallest son */ s->heap[k] = s->heap[j]; k = j; /* And continue down the tree, setting j to the left son of k */ j <<= 1; } s->heap[k] = v; } /* =========================================================================== * Compute the optimal bit lengths for a tree and update the total bit length * for the current block. * IN assertion: the fields freq and dad are set, heap[heap_max] and * above are the tree nodes sorted by increasing frequency. * OUT assertions: the field len is set to the optimal bit length, the * array bl_count contains the frequencies for each bit length. * The length opt_len is updated; static_len is also updated if stree is * not null. */ local void gen_bitlen(s, desc) deflate_state *s; tree_desc *desc; /* the tree descriptor */ { ct_data *tree = desc->dyn_tree; int max_code = desc->max_code; const ct_data *stree = desc->stat_desc->static_tree; const intf *extra = desc->stat_desc->extra_bits; int base = desc->stat_desc->extra_base; int max_length = desc->stat_desc->max_length; int h; /* heap index */ int n, m; /* iterate over the tree elements */ int bits; /* bit length */ int xbits; /* extra bits */ ush f; /* frequency */ int overflow = 0; /* number of elements with bit length too large */ for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; /* In a first pass, compute the optimal bit lengths (which may * overflow in the case of the bit length tree). */ tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ for (h = s->heap_max+1; h < HEAP_SIZE; h++) { n = s->heap[h]; bits = tree[tree[n].Dad].Len + 1; if (bits > max_length) bits = max_length, overflow++; tree[n].Len = (ush)bits; /* We overwrite tree[n].Dad which is no longer needed */ if (n > max_code) continue; /* not a leaf node */ s->bl_count[bits]++; xbits = 0; if (n >= base) xbits = extra[n-base]; f = tree[n].Freq; s->opt_len += (ulg)f * (bits + xbits); if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); } if (overflow == 0) return; Trace((stderr,"\nbit length overflow\n")); /* This happens for example on obj2 and pic of the Calgary corpus */ /* Find the first bit length which could increase: */ do { bits = max_length-1; while (s->bl_count[bits] == 0) bits--; s->bl_count[bits]--; /* move one leaf down the tree */ s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ s->bl_count[max_length]--; /* The brother of the overflow item also moves one step up, * but this does not affect bl_count[max_length] */ overflow -= 2; } while (overflow > 0); /* Now recompute all bit lengths, scanning in increasing frequency. * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all * lengths instead of fixing only the wrong ones. This idea is taken * from 'ar' written by Haruhiko Okumura.) */ for (bits = max_length; bits != 0; bits--) { n = s->bl_count[bits]; while (n != 0) { m = s->heap[--h]; if (m > max_code) continue; if ((unsigned) tree[m].Len != (unsigned) bits) { Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); s->opt_len += ((long)bits - (long)tree[m].Len) *(long)tree[m].Freq; tree[m].Len = (ush)bits; } n--; } } } /* =========================================================================== * Generate the codes for a given tree and bit counts (which need not be * optimal). * IN assertion: the array bl_count contains the bit length statistics for * the given tree and the field len is set for all tree elements. * OUT assertion: the field code is set for all tree elements of non * zero code length. */ local void gen_codes (tree, max_code, bl_count) ct_data *tree; /* the tree to decorate */ int max_code; /* largest code with non zero frequency */ ushf *bl_count; /* number of codes at each bit length */ { ush next_code[MAX_BITS+1]; /* next code value for each bit length */ ush code = 0; /* running code value */ int bits; /* bit index */ int n; /* code index */ /* The distribution counts are first used to generate the code values * without bit reversal. */ for (bits = 1; bits <= MAX_BITS; bits++) { next_code[bits] = code = (code + bl_count[bits-1]) << 1; } /* Check that the bit counts in bl_count are consistent. The last code * must be all ones. */ Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; const ct_data *stree = desc->stat_desc->static_tree; int elems = desc->stat_desc->elems; int n, m; /* iterate over heap elements */ int max_code = -1; /* largest code with non zero frequency */ int node; /* new node being created */ /* Construct the initial heap, with least frequent element in * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. * heap[0] is not used. */ s->heap_len = 0, s->heap_max = HEAP_SIZE; for (n = 0; n < elems; n++) { if (tree[n].Freq != 0) { s->heap[++(s->heap_len)] = max_code = n; s->depth[n] = 0; } else { tree[n].Len = 0; } } /* The pkzip format requires that at least one distance code exists, * and that at least one bit should be sent even if there is only one * possible code. So to avoid special checks later on we force at least * two codes of non zero frequency. */ while (s->heap_len < 2) { node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); tree[node].Freq = 1; s->depth[node] = 0; s->opt_len--; if (stree) s->static_len -= stree[node].Len; /* node is 0 or 1 so it does not have extra bits */ } desc->max_code = max_code; /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, * establish sub-heaps of increasing lengths: */ for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); /* Construct the Huffman tree by repeatedly combining the least two * frequent nodes. */ node = elems; /* next internal node of the tree */ do { pqremove(s, tree, n); /* n = node of least frequency */ m = s->heap[SMALLEST]; /* m = node of next least frequency */ s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ s->heap[--(s->heap_max)] = m; /* Create a new node father of n and m */ tree[node].Freq = tree[n].Freq + tree[m].Freq; s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? s->depth[n] : s->depth[m]) + 1); tree[n].Dad = tree[m].Dad = (ush)node; #ifdef DUMP_BL_TREE if (tree == s->bl_tree) { fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); } #endif /* and insert the new node in the heap */ s->heap[SMALLEST] = node++; pqdownheap(s, tree, SMALLEST); } while (s->heap_len >= 2); s->heap[--(s->heap_max)] = s->heap[SMALLEST]; /* At this point, the fields freq and dad are set. We can now * generate the bit lengths. */ gen_bitlen(s, (tree_desc *)desc); /* The field len is now set, we can generate the bit codes */ gen_codes ((ct_data *)tree, max_code, s->bl_count); } /* =========================================================================== * Scan a literal or distance tree to determine the frequencies of the codes * in the bit length tree. */ local void scan_tree (s, tree, max_code) deflate_state *s; ct_data *tree; /* the tree to be scanned */ int max_code; /* and its largest code of non zero frequency */ { int n; /* iterates over all tree elements */ int prevlen = -1; /* last emitted length */ int curlen; /* length of current code */ int nextlen = tree[0].Len; /* length of next code */ int count = 0; /* repeat count of the current code */ int max_count = 7; /* max repeat count */ int min_count = 4; /* min repeat count */ if (nextlen == 0) max_count = 138, min_count = 3; tree[max_code+1].Len = (ush)0xffff; /* guard */ for (n = 0; n <= max_code; n++) { curlen = nextlen; nextlen = tree[n+1].Len; if (++count < max_count && curlen == nextlen) { continue; } else if (count < min_count) { s->bl_tree[curlen].Freq += count; } else if (curlen != 0) { if (curlen != prevlen) s->bl_tree[curlen].Freq++; s->bl_tree[REP_3_6].Freq++; } else if (count <= 10) { s->bl_tree[REPZ_3_10].Freq++; } else { s->bl_tree[REPZ_11_138].Freq++; } count = 0; prevlen = curlen; if (nextlen == 0) { max_count = 138, min_count = 3; } else if (curlen == nextlen) { max_count = 6, min_count = 3; } else { max_count = 7, min_count = 4; } } } /* =========================================================================== * Send a literal or distance tree in compressed form, using the codes in * bl_tree. */ local void send_tree (s, tree, max_code) deflate_state *s; ct_data *tree; /* the tree to be scanned */ int max_code; /* and its largest code of non zero frequency */ { int n; /* iterates over all tree elements */ int prevlen = -1; /* last emitted length */ int curlen; /* length of current code */ int nextlen = tree[0].Len; /* length of next code */ int count = 0; /* repeat count of the current code */ int max_count = 7; /* max repeat count */ int min_count = 4; /* min repeat count */ /* tree[max_code+1].Len = -1; */ /* guard already set */ if (nextlen == 0) max_count = 138, min_count = 3; for (n = 0; n <= max_code; n++) { curlen = nextlen; nextlen = tree[n+1].Len; if (++count < max_count && curlen == nextlen) { continue; } else if (count < min_count) { do { send_code(s, curlen, s->bl_tree); } while (--count != 0); } else if (curlen != 0) { if (curlen != prevlen) { send_code(s, curlen, s->bl_tree); count--; } Assert(count >= 3 && count <= 6, " 3_6?"); send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); } else if (count <= 10) { send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); } else { send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); } count = 0; prevlen = curlen; if (nextlen == 0) { max_count = 138, min_count = 3; } else if (curlen == nextlen) { max_count = 6, min_count = 3; } else { max_count = 7, min_count = 4; } } } /* =========================================================================== * Construct the Huffman tree for the bit lengths and return the index in * bl_order of the last bit length code to send. */ local int build_bl_tree(s) deflate_state *s; { int max_blindex; /* index of last bit length code of non zero freq */ /* Determine the bit length frequencies for literal and distance trees */ scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); /* Build the bit length tree: */ build_tree(s, (tree_desc *)(&(s->bl_desc))); /* opt_len now includes the length of the tree representations, except * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. */ /* Determine the number of bit length codes to send. The pkzip format * requires that at least 4 bit length codes be sent. (appnote.txt says * 3 but the actual value used is 4.) */ for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; } /* Update opt_len to include the bit length tree and counts */ s->opt_len += 3*(max_blindex+1) + 5+5+4; Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", s->opt_len, s->static_len)); return max_blindex; } /* =========================================================================== * Send the header for a block using dynamic Huffman trees: the counts, the * lengths of the bit length codes, the literal tree and the distance tree. * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. */ local void send_all_trees(s, lcodes, dcodes, blcodes) deflate_state *s; int lcodes, dcodes, blcodes; /* number of codes for each tree */ { int rank; /* index in bl_order */ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, "too many codes"); Tracev((stderr, "\nbl counts: ")); send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ send_bits(s, dcodes-1, 5); send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ for (rank = 0; rank < blcodes; rank++) { Tracev((stderr, "\nbl code %2d ", bl_order[rank])); send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); } Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); } /* =========================================================================== * Send a stored block */ void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) deflate_state *s; charf *buf; /* input block */ ulg stored_len; /* length of input block */ int last; /* one if this is the last block for a file */ { send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */ #ifdef DEBUG s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; s->compressed_len += (stored_len + 4) << 3; #endif copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ } /* =========================================================================== * Flush the bits in the bit buffer to pending output (leaves at most 7 bits) */ void ZLIB_INTERNAL _tr_flush_bits(s) deflate_state *s; { bi_flush(s); } /* =========================================================================== * Send one empty static block to give enough lookahead for inflate. * This takes 10 bits, of which 7 may remain in the bit buffer. */ void ZLIB_INTERNAL _tr_align(s) deflate_state *s; { send_bits(s, STATIC_TREES<<1, 3); send_code(s, END_BLOCK, static_ltree); #ifdef DEBUG s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ #endif bi_flush(s); } /* =========================================================================== * Determine the best encoding for the current block: dynamic trees, static * trees or store, and output the encoded block to the zip file. */ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) deflate_state *s; charf *buf; /* input block, or NULL if too old */ ulg stored_len; /* length of input block */ int last; /* one if this is the last block for a file */ { ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ int max_blindex = 0; /* index of last bit length code of non zero freq */ /* Build the Huffman trees unless a stored block is forced */ if (s->level > 0) { /* Check if the file is binary or text */ if (s->strm->data_type == Z_UNKNOWN) s->strm->data_type = detect_data_type(s); /* Construct the literal and distance trees */ build_tree(s, (tree_desc *)(&(s->l_desc))); Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, s->static_len)); build_tree(s, (tree_desc *)(&(s->d_desc))); Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, s->static_len)); /* At this point, opt_len and static_len are the total bit lengths of * the compressed block data, excluding the tree representations. */ /* Build the bit length tree for the above two trees, and get the index * in bl_order of the last bit length code to send. */ max_blindex = build_bl_tree(s); /* Determine the best encoding. Compute the block lengths in bytes. */ opt_lenb = (s->opt_len+3+7)>>3; static_lenb = (s->static_len+3+7)>>3; Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, s->last_lit)); if (static_lenb <= opt_lenb) opt_lenb = static_lenb; } else { Assert(buf != (char*)0, "lost buf"); opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ } #ifdef FORCE_STORED if (buf != (char*)0) { /* force stored block */ #else if (stored_len+4 <= opt_lenb && buf != (char*)0) { /* 4: two words for the lengths */ #endif /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. * Otherwise we can't have processed more than WSIZE input bytes since * the last block flush, because compression would have been * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to * transform a block into a stored block. */ _tr_stored_block(s, buf, stored_len, last); #ifdef FORCE_STATIC } else if (static_lenb >= 0) { /* force static trees */ #else } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { #endif send_bits(s, (STATIC_TREES<<1)+last, 3); compress_block(s, (const ct_data *)static_ltree, (const ct_data *)static_dtree); #ifdef DEBUG s->compressed_len += 3 + s->static_len; #endif } else { send_bits(s, (DYN_TREES<<1)+last, 3); send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, max_blindex+1); compress_block(s, (const ct_data *)s->dyn_ltree, (const ct_data *)s->dyn_dtree); #ifdef DEBUG s->compressed_len += 3 + s->opt_len; #endif } Assert (s->compressed_len == s->bits_sent, "bad compressed size"); /* The above check is made mod 2^32, for files larger than 512 MB * and uLong implemented on 32 bits. */ init_block(s); if (last) { bi_windup(s); #ifdef DEBUG s->compressed_len += 7; /* align on byte boundary */ #endif } Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, s->compressed_len-7*last)); } /* =========================================================================== * Save the match info and tally the frequency counts. Return true if * the current block must be flushed. */ int ZLIB_INTERNAL _tr_tally (s, dist, lc) deflate_state *s; unsigned dist; /* distance of matched string */ unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ { s->d_buf[s->last_lit] = (ush)dist; s->l_buf[s->last_lit++] = (uch)lc; if (dist == 0) { /* lc is the unmatched char */ s->dyn_ltree[lc].Freq++; } else { s->matches++; /* Here, lc is the match length - MIN_MATCH */ dist--; /* dist = match distance - 1 */ Assert((ush)dist < (ush)MAX_DIST(s) && (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; s->dyn_dtree[d_code(dist)].Freq++; } #ifdef TRUNCATE_BLOCK /* Try to guess if it is profitable to stop the current block here */ if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { /* Compute an upper bound for the compressed length */ ulg out_length = (ulg)s->last_lit*8L; ulg in_length = (ulg)((long)s->strstart - s->block_start); int dcode; for (dcode = 0; dcode < D_CODES; dcode++) { out_length += (ulg)s->dyn_dtree[dcode].Freq * (5L+extra_dbits[dcode]); } out_length >>= 3; Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", s->last_lit, in_length, out_length, 100L - out_length*100L/in_length)); if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; } #endif return (s->last_lit == s->lit_bufsize-1); /* We avoid equality with lit_bufsize because of wraparound at 64K * on 16 bit machines and because stored blocks are restricted to * 64K-1 bytes. */ } /* =========================================================================== * Send the block data compressed using the given Huffman trees */ local void compress_block(s, ltree, dtree) deflate_state *s; const ct_data *ltree; /* literal tree */ const ct_data *dtree; /* distance tree */ { unsigned dist; /* distance of matched string */ int lc; /* match length or unmatched char (if dist == 0) */ unsigned lx = 0; /* running index in l_buf */ unsigned code; /* the code to send */ int extra; /* number of extra bits to send */ if (s->last_lit != 0) do { dist = s->d_buf[lx]; lc = s->l_buf[lx++]; if (dist == 0) { send_code(s, lc, ltree); /* send a literal byte */ Tracecv(isgraph(lc), (stderr," '%c' ", lc)); } else { /* Here, lc is the match length - MIN_MATCH */ code = _length_code[lc]; send_code(s, code+LITERALS+1, ltree); /* send the length code */ extra = extra_lbits[code]; if (extra != 0) { lc -= base_length[code]; send_bits(s, lc, extra); /* send the extra length bits */ } dist--; /* dist is now the match distance - 1 */ code = d_code(dist); Assert (code < D_CODES, "bad d_code"); send_code(s, code, dtree); /* send the distance code */ extra = extra_dbits[code]; if (extra != 0) { dist -= base_dist[code]; send_bits(s, dist, extra); /* send the extra distance bits */ } } /* literal or match pair ? */ /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, "pendingBuf overflow"); } while (lx < s->last_lit); send_code(s, END_BLOCK, ltree); } /* =========================================================================== * Check if the data type is TEXT or BINARY, using the following algorithm: * - TEXT if the two conditions below are satisfied: * a) There are no non-portable control characters belonging to the * "black list" (0..6, 14..25, 28..31). * b) There is at least one printable character belonging to the * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). * - BINARY otherwise. * - The following partially-portable control characters form a * "gray list" that is ignored in this detection algorithm: * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). * IN assertion: the fields Freq of dyn_ltree are set. */ local int detect_data_type(s) deflate_state *s; { /* black_mask is the bit mask of black-listed bytes * set bits 0..6, 14..25, and 28..31 * 0xf3ffc07f = binary 11110011111111111100000001111111 */ unsigned long black_mask = 0xf3ffc07fUL; int n; /* Check for non-textual ("black-listed") bytes. */ for (n = 0; n <= 31; n++, black_mask >>= 1) if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) return Z_BINARY; /* Check for textual ("white-listed") bytes. */ if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 || s->dyn_ltree[13].Freq != 0) return Z_TEXT; for (n = 32; n < LITERALS; n++) if (s->dyn_ltree[n].Freq != 0) return Z_TEXT; /* There are no "black-listed" or "white-listed" bytes: * this stream either is empty or has tolerated ("gray-listed") bytes only. */ return Z_BINARY; } /* =========================================================================== * Reverse the first len bits of a code, using straightforward code (a faster * method would use a table) * IN assertion: 1 <= len <= 15 */ local unsigned bi_reverse(code, len) unsigned code; /* the value to invert */ int len; /* its bit length */ { register unsigned res = 0; do { res |= code & 1; code >>= 1, res <<= 1; } while (--len > 0); return res >> 1; } /* =========================================================================== * Flush the bit buffer, keeping at most 7 bits in it. */ local void bi_flush(s) deflate_state *s; { if (s->bi_valid == 16) { put_short(s, s->bi_buf); s->bi_buf = 0; s->bi_valid = 0; } else if (s->bi_valid >= 8) { put_byte(s, (Byte)s->bi_buf); s->bi_buf >>= 8; s->bi_valid -= 8; } } /* =========================================================================== * Flush the bit buffer and align the output on a byte boundary */ local void bi_windup(s) deflate_state *s; { if (s->bi_valid > 8) { put_short(s, s->bi_buf); } else if (s->bi_valid > 0) { put_byte(s, (Byte)s->bi_buf); } s->bi_buf = 0; s->bi_valid = 0; #ifdef DEBUG s->bits_sent = (s->bits_sent+7) & ~7; #endif } /* =========================================================================== * Copy a stored block, storing first the length and its * one's complement if requested. */ local void copy_block(s, buf, len, header) deflate_state *s; charf *buf; /* the input data */ unsigned len; /* its length */ int header; /* true if block header must be written */ { bi_windup(s); /* align on byte boundary */ if (header) { put_short(s, (ush)len); put_short(s, (ush)~len); #ifdef DEBUG s->bits_sent += 2*16; #endif } #ifdef DEBUG s->bits_sent += (ulg)len<<3; #endif while (len--) { put_byte(s, *buf++); } } gtkwave-3.3.66/src/libz/inflate.c0000664000076400007640000015041012235606635016125 0ustar bybellbybell/* inflate.c -- zlib decompression * Copyright (C) 1995-2012 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* * Change history: * * 1.2.beta0 24 Nov 2002 * - First version -- complete rewrite of inflate to simplify code, avoid * creation of window when not needed, minimize use of window when it is * needed, make inffast.c even faster, implement gzip decoding, and to * improve code readability and style over the previous zlib inflate code * * 1.2.beta1 25 Nov 2002 * - Use pointers for available input and output checking in inffast.c * - Remove input and output counters in inffast.c * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 * - Remove unnecessary second byte pull from length extra in inffast.c * - Unroll direct copy to three copies per loop in inffast.c * * 1.2.beta2 4 Dec 2002 * - Change external routine names to reduce potential conflicts * - Correct filename to inffixed.h for fixed tables in inflate.c * - Make hbuf[] unsigned char to match parameter type in inflate.c * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) * to avoid negation problem on Alphas (64 bit) in inflate.c * * 1.2.beta3 22 Dec 2002 * - Add comments on state->bits assertion in inffast.c * - Add comments on op field in inftrees.h * - Fix bug in reuse of allocated window after inflateReset() * - Remove bit fields--back to byte structure for speed * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths * - Change post-increments to pre-increments in inflate_fast(), PPC biased? * - Add compile time option, POSTINC, to use post-increments instead (Intel?) * - Make MATCH copy in inflate() much faster for when inflate_fast() not used * - Use local copies of stream next and avail values, as well as local bit * buffer and bit count in inflate()--for speed when inflate_fast() not used * * 1.2.beta4 1 Jan 2003 * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings * - Move a comment on output buffer sizes from inffast.c to inflate.c * - Add comments in inffast.c to introduce the inflate_fast() routine * - Rearrange window copies in inflate_fast() for speed and simplification * - Unroll last copy for window match in inflate_fast() * - Use local copies of window variables in inflate_fast() for speed * - Pull out common wnext == 0 case for speed in inflate_fast() * - Make op and len in inflate_fast() unsigned for consistency * - Add FAR to lcode and dcode declarations in inflate_fast() * - Simplified bad distance check in inflate_fast() * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new * source file infback.c to provide a call-back interface to inflate for * programs like gzip and unzip -- uses window as output buffer to avoid * window copying * * 1.2.beta5 1 Jan 2003 * - Improved inflateBack() interface to allow the caller to provide initial * input in strm. * - Fixed stored blocks bug in inflateBack() * * 1.2.beta6 4 Jan 2003 * - Added comments in inffast.c on effectiveness of POSTINC * - Typecasting all around to reduce compiler warnings * - Changed loops from while (1) or do {} while (1) to for (;;), again to * make compilers happy * - Changed type of window in inflateBackInit() to unsigned char * * * 1.2.beta7 27 Jan 2003 * - Changed many types to unsigned or unsigned short to avoid warnings * - Added inflateCopy() function * * 1.2.0 9 Mar 2003 * - Changed inflateBack() interface to provide separate opaque descriptors * for the in() and out() functions * - Changed inflateBack() argument and in_func typedef to swap the length * and buffer address return values for the input function * - Check next_in and next_out for Z_NULL on entry to inflate() * * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. */ #include "zutil.h" #include "inftrees.h" #include "inflate.h" #include "inffast.h" #ifdef MAKEFIXED # ifndef BUILDFIXED # define BUILDFIXED # endif #endif /* function prototypes */ local void fixedtables OF((struct inflate_state FAR *state)); local int updatewindow OF((z_streamp strm, const unsigned char FAR *end, unsigned copy)); #ifdef BUILDFIXED void makefixed OF((void)); #endif local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf, unsigned len)); int ZEXPORT inflateResetKeep(strm) z_streamp strm; { struct inflate_state FAR *state; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; strm->total_in = strm->total_out = state->total = 0; strm->msg = Z_NULL; if (state->wrap) /* to support ill-conceived Java test suite */ strm->adler = state->wrap & 1; state->mode = HEAD; state->last = 0; state->havedict = 0; state->dmax = 32768U; state->head = Z_NULL; state->hold = 0; state->bits = 0; state->lencode = state->distcode = state->next = state->codes; state->sane = 1; state->back = -1; Tracev((stderr, "inflate: reset\n")); return Z_OK; } int ZEXPORT inflateReset(strm) z_streamp strm; { struct inflate_state FAR *state; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; state->wsize = 0; state->whave = 0; state->wnext = 0; return inflateResetKeep(strm); } int ZEXPORT inflateReset2(strm, windowBits) z_streamp strm; int windowBits; { int wrap; struct inflate_state FAR *state; /* get the state */ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; /* extract wrap request from windowBits parameter */ if (windowBits < 0) { wrap = 0; windowBits = -windowBits; } else { wrap = (windowBits >> 4) + 1; #ifdef GUNZIP if (windowBits < 48) windowBits &= 15; #endif } /* set number of window bits, free window if different */ if (windowBits && (windowBits < 8 || windowBits > 15)) return Z_STREAM_ERROR; if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { ZFREE(strm, state->window); state->window = Z_NULL; } /* update state and reset the rest of it */ state->wrap = wrap; state->wbits = (unsigned)windowBits; return inflateReset(strm); } int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) z_streamp strm; int windowBits; const char *version; int stream_size; { int ret; struct inflate_state FAR *state; if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || stream_size != (int)(sizeof(z_stream))) return Z_VERSION_ERROR; if (strm == Z_NULL) return Z_STREAM_ERROR; strm->msg = Z_NULL; /* in case we return an error */ if (strm->zalloc == (alloc_func)0) { #ifdef Z_SOLO return Z_STREAM_ERROR; #else strm->zalloc = zcalloc; strm->opaque = (voidpf)0; #endif } if (strm->zfree == (free_func)0) #ifdef Z_SOLO return Z_STREAM_ERROR; #else strm->zfree = zcfree; #endif state = (struct inflate_state FAR *) ZALLOC(strm, 1, sizeof(struct inflate_state)); if (state == Z_NULL) return Z_MEM_ERROR; Tracev((stderr, "inflate: allocated\n")); strm->state = (struct internal_state FAR *)state; state->window = Z_NULL; ret = inflateReset2(strm, windowBits); if (ret != Z_OK) { ZFREE(strm, state); strm->state = Z_NULL; } return ret; } int ZEXPORT inflateInit_(strm, version, stream_size) z_streamp strm; const char *version; int stream_size; { return inflateInit2_(strm, DEF_WBITS, version, stream_size); } int ZEXPORT inflatePrime(strm, bits, value) z_streamp strm; int bits; int value; { struct inflate_state FAR *state; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (bits < 0) { state->hold = 0; state->bits = 0; return Z_OK; } if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; value &= (1L << bits) - 1; state->hold += value << state->bits; state->bits += bits; return Z_OK; } /* Return state with length and distance decoding tables and index sizes set to fixed code decoding. Normally this returns fixed tables from inffixed.h. If BUILDFIXED is defined, then instead this routine builds the tables the first time it's called, and returns those tables the first time and thereafter. This reduces the size of the code by about 2K bytes, in exchange for a little execution time. However, BUILDFIXED should not be used for threaded applications, since the rewriting of the tables and virgin may not be thread-safe. */ local void fixedtables(state) struct inflate_state FAR *state; { #ifdef BUILDFIXED static int virgin = 1; static code *lenfix, *distfix; static code fixed[544]; /* build fixed huffman tables if first call (may not be thread safe) */ if (virgin) { unsigned sym, bits; static code *next; /* literal/length table */ sym = 0; while (sym < 144) state->lens[sym++] = 8; while (sym < 256) state->lens[sym++] = 9; while (sym < 280) state->lens[sym++] = 7; while (sym < 288) state->lens[sym++] = 8; next = fixed; lenfix = next; bits = 9; inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); /* distance table */ sym = 0; while (sym < 32) state->lens[sym++] = 5; distfix = next; bits = 5; inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); /* do this just once */ virgin = 0; } #else /* !BUILDFIXED */ # include "inffixed.h" #endif /* BUILDFIXED */ state->lencode = lenfix; state->lenbits = 9; state->distcode = distfix; state->distbits = 5; } #ifdef MAKEFIXED #include /* Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also defines BUILDFIXED, so the tables are built on the fly. makefixed() writes those tables to stdout, which would be piped to inffixed.h. A small program can simply call makefixed to do this: void makefixed(void); int main(void) { makefixed(); return 0; } Then that can be linked with zlib built with MAKEFIXED defined and run: a.out > inffixed.h */ void makefixed() { unsigned low, size; struct inflate_state state; fixedtables(&state); puts(" /* inffixed.h -- table for decoding fixed codes"); puts(" * Generated automatically by makefixed()."); puts(" */"); puts(""); puts(" /* WARNING: this file should *not* be used by applications."); puts(" It is part of the implementation of this library and is"); puts(" subject to change. Applications should only use zlib.h."); puts(" */"); puts(""); size = 1U << 9; printf(" static const code lenfix[%u] = {", size); low = 0; for (;;) { if ((low % 7) == 0) printf("\n "); printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, state.lencode[low].bits, state.lencode[low].val); if (++low == size) break; putchar(','); } puts("\n };"); size = 1U << 5; printf("\n static const code distfix[%u] = {", size); low = 0; for (;;) { if ((low % 6) == 0) printf("\n "); printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, state.distcode[low].val); if (++low == size) break; putchar(','); } puts("\n };"); } #endif /* MAKEFIXED */ /* Update the window with the last wsize (normally 32K) bytes written before returning. If window does not exist yet, create it. This is only called when a window is already in use, or when output has been written during this inflate call, but the end of the deflate stream has not been reached yet. It is also called to create a window for dictionary data when a dictionary is loaded. Providing output buffers larger than 32K to inflate() should provide a speed advantage, since only the last 32K of output is copied to the sliding window upon return from inflate(), and since all distances after the first 32K of output will fall in the output data, making match copies simpler and faster. The advantage may be dependent on the size of the processor's data caches. */ local int updatewindow(strm, end, copy) z_streamp strm; const Bytef *end; unsigned copy; { struct inflate_state FAR *state; unsigned dist; state = (struct inflate_state FAR *)strm->state; /* if it hasn't been done already, allocate space for the window */ if (state->window == Z_NULL) { state->window = (unsigned char FAR *) ZALLOC(strm, 1U << state->wbits, sizeof(unsigned char)); if (state->window == Z_NULL) return 1; } /* if window not in use yet, initialize */ if (state->wsize == 0) { state->wsize = 1U << state->wbits; state->wnext = 0; state->whave = 0; } /* copy state->wsize or less output bytes into the circular window */ if (copy >= state->wsize) { zmemcpy(state->window, end - state->wsize, state->wsize); state->wnext = 0; state->whave = state->wsize; } else { dist = state->wsize - state->wnext; if (dist > copy) dist = copy; zmemcpy(state->window + state->wnext, end - copy, dist); copy -= dist; if (copy) { zmemcpy(state->window, end - copy, copy); state->wnext = copy; state->whave = state->wsize; } else { state->wnext += dist; if (state->wnext == state->wsize) state->wnext = 0; if (state->whave < state->wsize) state->whave += dist; } } return 0; } /* Macros for inflate(): */ /* check function to use adler32() for zlib or crc32() for gzip */ #ifdef GUNZIP # define UPDATE(check, buf, len) \ (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) #else # define UPDATE(check, buf, len) adler32(check, buf, len) #endif /* check macros for header crc */ #ifdef GUNZIP # define CRC2(check, word) \ do { \ hbuf[0] = (unsigned char)(word); \ hbuf[1] = (unsigned char)((word) >> 8); \ check = crc32(check, hbuf, 2); \ } while (0) # define CRC4(check, word) \ do { \ hbuf[0] = (unsigned char)(word); \ hbuf[1] = (unsigned char)((word) >> 8); \ hbuf[2] = (unsigned char)((word) >> 16); \ hbuf[3] = (unsigned char)((word) >> 24); \ check = crc32(check, hbuf, 4); \ } while (0) #endif /* Load registers with state in inflate() for speed */ #define LOAD() \ do { \ put = strm->next_out; \ left = strm->avail_out; \ next = strm->next_in; \ have = strm->avail_in; \ hold = state->hold; \ bits = state->bits; \ } while (0) /* Restore state from registers in inflate() */ #define RESTORE() \ do { \ strm->next_out = put; \ strm->avail_out = left; \ strm->next_in = next; \ strm->avail_in = have; \ state->hold = hold; \ state->bits = bits; \ } while (0) /* Clear the input bit accumulator */ #define INITBITS() \ do { \ hold = 0; \ bits = 0; \ } while (0) /* Get a byte of input into the bit accumulator, or return from inflate() if there is no input available. */ #define PULLBYTE() \ do { \ if (have == 0) goto inf_leave; \ have--; \ hold += (unsigned long)(*next++) << bits; \ bits += 8; \ } while (0) /* Assure that there are at least n bits in the bit accumulator. If there is not enough available input to do that, then return from inflate(). */ #define NEEDBITS(n) \ do { \ while (bits < (unsigned)(n)) \ PULLBYTE(); \ } while (0) /* Return the low n bits of the bit accumulator (n < 16) */ #define BITS(n) \ ((unsigned)hold & ((1U << (n)) - 1)) /* Remove n bits from the bit accumulator */ #define DROPBITS(n) \ do { \ hold >>= (n); \ bits -= (unsigned)(n); \ } while (0) /* Remove zero to seven bits as needed to go to a byte boundary */ #define BYTEBITS() \ do { \ hold >>= bits & 7; \ bits -= bits & 7; \ } while (0) /* inflate() uses a state machine to process as much input data and generate as much output data as possible before returning. The state machine is structured roughly as follows: for (;;) switch (state) { ... case STATEn: if (not enough input data or output space to make progress) return; ... make progress ... state = STATEm; break; ... } so when inflate() is called again, the same case is attempted again, and if the appropriate resources are provided, the machine proceeds to the next state. The NEEDBITS() macro is usually the way the state evaluates whether it can proceed or should return. NEEDBITS() does the return if the requested bits are not available. The typical use of the BITS macros is: NEEDBITS(n); ... do something with BITS(n) ... DROPBITS(n); where NEEDBITS(n) either returns from inflate() if there isn't enough input left to load n bits into the accumulator, or it continues. BITS(n) gives the low n bits in the accumulator. When done, DROPBITS(n) drops the low n bits off the accumulator. INITBITS() clears the accumulator and sets the number of available bits to zero. BYTEBITS() discards just enough bits to put the accumulator on a byte boundary. After BYTEBITS() and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return if there is no input available. The decoding of variable length codes uses PULLBYTE() directly in order to pull just enough bytes to decode the next code, and no more. Some states loop until they get enough input, making sure that enough state information is maintained to continue the loop where it left off if NEEDBITS() returns in the loop. For example, want, need, and keep would all have to actually be part of the saved state in case NEEDBITS() returns: case STATEw: while (want < need) { NEEDBITS(n); keep[want++] = BITS(n); DROPBITS(n); } state = STATEx; case STATEx: As shown above, if the next state is also the next case, then the break is omitted. A state may also return if there is not enough output space available to complete that state. Those states are copying stored data, writing a literal byte, and copying a matching string. When returning, a "goto inf_leave" is used to update the total counters, update the check value, and determine whether any progress has been made during that inflate() call in order to return the proper return code. Progress is defined as a change in either strm->avail_in or strm->avail_out. When there is a window, goto inf_leave will update the window with the last output written. If a goto inf_leave occurs in the middle of decompression and there is no window currently, goto inf_leave will create one and copy output to the window for the next call of inflate(). In this implementation, the flush parameter of inflate() only affects the return code (per zlib.h). inflate() always writes as much as possible to strm->next_out, given the space available and the provided input--the effect documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers the allocation of and copying into a sliding window until necessary, which provides the effect documented in zlib.h for Z_FINISH when the entire input stream available. So the only thing the flush parameter actually does is: when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it will return Z_BUF_ERROR if it has not reached the end of the stream. */ int ZEXPORT inflate(strm, flush) z_streamp strm; int flush; { struct inflate_state FAR *state; z_const unsigned char FAR *next; /* next input */ unsigned char FAR *put; /* next output */ unsigned have, left; /* available input and output */ unsigned long hold; /* bit buffer */ unsigned bits; /* bits in bit buffer */ unsigned in, out; /* save starting available input and output */ unsigned copy; /* number of stored or match bytes to copy */ unsigned char FAR *from; /* where to copy match bytes from */ code here; /* current decoding table entry */ code last; /* parent table entry */ unsigned len; /* length to copy for repeats, bits to drop */ int ret; /* return code */ #ifdef GUNZIP unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ #endif static const unsigned short order[19] = /* permutation of code lengths */ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || (strm->next_in == Z_NULL && strm->avail_in != 0)) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ LOAD(); in = have; out = left; ret = Z_OK; for (;;) switch (state->mode) { case HEAD: if (state->wrap == 0) { state->mode = TYPEDO; break; } NEEDBITS(16); #ifdef GUNZIP if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ state->check = crc32(0L, Z_NULL, 0); CRC2(state->check, hold); INITBITS(); state->mode = FLAGS; break; } state->flags = 0; /* expect zlib header */ if (state->head != Z_NULL) state->head->done = -1; if (!(state->wrap & 1) || /* check if zlib header allowed */ #else if ( #endif ((BITS(8) << 8) + (hold >> 8)) % 31) { strm->msg = (char *)"incorrect header check"; state->mode = BAD; break; } if (BITS(4) != Z_DEFLATED) { strm->msg = (char *)"unknown compression method"; state->mode = BAD; break; } DROPBITS(4); len = BITS(4) + 8; if (state->wbits == 0) state->wbits = len; else if (len > state->wbits) { strm->msg = (char *)"invalid window size"; state->mode = BAD; break; } state->dmax = 1U << len; Tracev((stderr, "inflate: zlib header ok\n")); strm->adler = state->check = adler32(0L, Z_NULL, 0); state->mode = hold & 0x200 ? DICTID : TYPE; INITBITS(); break; #ifdef GUNZIP case FLAGS: NEEDBITS(16); state->flags = (int)(hold); if ((state->flags & 0xff) != Z_DEFLATED) { strm->msg = (char *)"unknown compression method"; state->mode = BAD; break; } if (state->flags & 0xe000) { strm->msg = (char *)"unknown header flags set"; state->mode = BAD; break; } if (state->head != Z_NULL) state->head->text = (int)((hold >> 8) & 1); if (state->flags & 0x0200) CRC2(state->check, hold); INITBITS(); state->mode = TIME; case TIME: NEEDBITS(32); if (state->head != Z_NULL) state->head->time = hold; if (state->flags & 0x0200) CRC4(state->check, hold); INITBITS(); state->mode = OS; case OS: NEEDBITS(16); if (state->head != Z_NULL) { state->head->xflags = (int)(hold & 0xff); state->head->os = (int)(hold >> 8); } if (state->flags & 0x0200) CRC2(state->check, hold); INITBITS(); state->mode = EXLEN; case EXLEN: if (state->flags & 0x0400) { NEEDBITS(16); state->length = (unsigned)(hold); if (state->head != Z_NULL) state->head->extra_len = (unsigned)hold; if (state->flags & 0x0200) CRC2(state->check, hold); INITBITS(); } else if (state->head != Z_NULL) state->head->extra = Z_NULL; state->mode = EXTRA; case EXTRA: if (state->flags & 0x0400) { copy = state->length; if (copy > have) copy = have; if (copy) { if (state->head != Z_NULL && state->head->extra != Z_NULL) { len = state->head->extra_len - state->length; zmemcpy(state->head->extra + len, next, len + copy > state->head->extra_max ? state->head->extra_max - len : copy); } if (state->flags & 0x0200) state->check = crc32(state->check, next, copy); have -= copy; next += copy; state->length -= copy; } if (state->length) goto inf_leave; } state->length = 0; state->mode = NAME; case NAME: if (state->flags & 0x0800) { if (have == 0) goto inf_leave; copy = 0; do { len = (unsigned)(next[copy++]); if (state->head != Z_NULL && state->head->name != Z_NULL && state->length < state->head->name_max) state->head->name[state->length++] = len; } while (len && copy < have); if (state->flags & 0x0200) state->check = crc32(state->check, next, copy); have -= copy; next += copy; if (len) goto inf_leave; } else if (state->head != Z_NULL) state->head->name = Z_NULL; state->length = 0; state->mode = COMMENT; case COMMENT: if (state->flags & 0x1000) { if (have == 0) goto inf_leave; copy = 0; do { len = (unsigned)(next[copy++]); if (state->head != Z_NULL && state->head->comment != Z_NULL && state->length < state->head->comm_max) state->head->comment[state->length++] = len; } while (len && copy < have); if (state->flags & 0x0200) state->check = crc32(state->check, next, copy); have -= copy; next += copy; if (len) goto inf_leave; } else if (state->head != Z_NULL) state->head->comment = Z_NULL; state->mode = HCRC; case HCRC: if (state->flags & 0x0200) { NEEDBITS(16); if (hold != (state->check & 0xffff)) { strm->msg = (char *)"header crc mismatch"; state->mode = BAD; break; } INITBITS(); } if (state->head != Z_NULL) { state->head->hcrc = (int)((state->flags >> 9) & 1); state->head->done = 1; } strm->adler = state->check = crc32(0L, Z_NULL, 0); state->mode = TYPE; break; #endif case DICTID: NEEDBITS(32); strm->adler = state->check = ZSWAP32(hold); INITBITS(); state->mode = DICT; case DICT: if (state->havedict == 0) { RESTORE(); return Z_NEED_DICT; } strm->adler = state->check = adler32(0L, Z_NULL, 0); state->mode = TYPE; case TYPE: if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; case TYPEDO: if (state->last) { BYTEBITS(); state->mode = CHECK; break; } NEEDBITS(3); state->last = BITS(1); DROPBITS(1); switch (BITS(2)) { case 0: /* stored block */ Tracev((stderr, "inflate: stored block%s\n", state->last ? " (last)" : "")); state->mode = STORED; break; case 1: /* fixed block */ fixedtables(state); Tracev((stderr, "inflate: fixed codes block%s\n", state->last ? " (last)" : "")); state->mode = LEN_; /* decode codes */ if (flush == Z_TREES) { DROPBITS(2); goto inf_leave; } break; case 2: /* dynamic block */ Tracev((stderr, "inflate: dynamic codes block%s\n", state->last ? " (last)" : "")); state->mode = TABLE; break; case 3: strm->msg = (char *)"invalid block type"; state->mode = BAD; } DROPBITS(2); break; case STORED: BYTEBITS(); /* go to byte boundary */ NEEDBITS(32); if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { strm->msg = (char *)"invalid stored block lengths"; state->mode = BAD; break; } state->length = (unsigned)hold & 0xffff; Tracev((stderr, "inflate: stored length %u\n", state->length)); INITBITS(); state->mode = COPY_; if (flush == Z_TREES) goto inf_leave; case COPY_: state->mode = COPY; case COPY: copy = state->length; if (copy) { if (copy > have) copy = have; if (copy > left) copy = left; if (copy == 0) goto inf_leave; zmemcpy(put, next, copy); have -= copy; next += copy; left -= copy; put += copy; state->length -= copy; break; } Tracev((stderr, "inflate: stored end\n")); state->mode = TYPE; break; case TABLE: NEEDBITS(14); state->nlen = BITS(5) + 257; DROPBITS(5); state->ndist = BITS(5) + 1; DROPBITS(5); state->ncode = BITS(4) + 4; DROPBITS(4); #ifndef PKZIP_BUG_WORKAROUND if (state->nlen > 286 || state->ndist > 30) { strm->msg = (char *)"too many length or distance symbols"; state->mode = BAD; break; } #endif Tracev((stderr, "inflate: table sizes ok\n")); state->have = 0; state->mode = LENLENS; case LENLENS: while (state->have < state->ncode) { NEEDBITS(3); state->lens[order[state->have++]] = (unsigned short)BITS(3); DROPBITS(3); } while (state->have < 19) state->lens[order[state->have++]] = 0; state->next = state->codes; state->lencode = (const code FAR *)(state->next); state->lenbits = 7; ret = inflate_table(CODES, state->lens, 19, &(state->next), &(state->lenbits), state->work); if (ret) { strm->msg = (char *)"invalid code lengths set"; state->mode = BAD; break; } Tracev((stderr, "inflate: code lengths ok\n")); state->have = 0; state->mode = CODELENS; case CODELENS: while (state->have < state->nlen + state->ndist) { for (;;) { here = state->lencode[BITS(state->lenbits)]; if ((unsigned)(here.bits) <= bits) break; PULLBYTE(); } if (here.val < 16) { DROPBITS(here.bits); state->lens[state->have++] = here.val; } else { if (here.val == 16) { NEEDBITS(here.bits + 2); DROPBITS(here.bits); if (state->have == 0) { strm->msg = (char *)"invalid bit length repeat"; state->mode = BAD; break; } len = state->lens[state->have - 1]; copy = 3 + BITS(2); DROPBITS(2); } else if (here.val == 17) { NEEDBITS(here.bits + 3); DROPBITS(here.bits); len = 0; copy = 3 + BITS(3); DROPBITS(3); } else { NEEDBITS(here.bits + 7); DROPBITS(here.bits); len = 0; copy = 11 + BITS(7); DROPBITS(7); } if (state->have + copy > state->nlen + state->ndist) { strm->msg = (char *)"invalid bit length repeat"; state->mode = BAD; break; } while (copy--) state->lens[state->have++] = (unsigned short)len; } } /* handle error breaks in while */ if (state->mode == BAD) break; /* check for end-of-block code (better have one) */ if (state->lens[256] == 0) { strm->msg = (char *)"invalid code -- missing end-of-block"; state->mode = BAD; break; } /* build code tables -- note: do not change the lenbits or distbits values here (9 and 6) without reading the comments in inftrees.h concerning the ENOUGH constants, which depend on those values */ state->next = state->codes; state->lencode = (const code FAR *)(state->next); state->lenbits = 9; ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), &(state->lenbits), state->work); if (ret) { strm->msg = (char *)"invalid literal/lengths set"; state->mode = BAD; break; } state->distcode = (const code FAR *)(state->next); state->distbits = 6; ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, &(state->next), &(state->distbits), state->work); if (ret) { strm->msg = (char *)"invalid distances set"; state->mode = BAD; break; } Tracev((stderr, "inflate: codes ok\n")); state->mode = LEN_; if (flush == Z_TREES) goto inf_leave; case LEN_: state->mode = LEN; case LEN: if (have >= 6 && left >= 258) { RESTORE(); inflate_fast(strm, out); LOAD(); if (state->mode == TYPE) state->back = -1; break; } state->back = 0; for (;;) { here = state->lencode[BITS(state->lenbits)]; if ((unsigned)(here.bits) <= bits) break; PULLBYTE(); } if (here.op && (here.op & 0xf0) == 0) { last = here; for (;;) { here = state->lencode[last.val + (BITS(last.bits + last.op) >> last.bits)]; if ((unsigned)(last.bits + here.bits) <= bits) break; PULLBYTE(); } DROPBITS(last.bits); state->back += last.bits; } DROPBITS(here.bits); state->back += here.bits; state->length = (unsigned)here.val; if ((int)(here.op) == 0) { Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? "inflate: literal '%c'\n" : "inflate: literal 0x%02x\n", here.val)); state->mode = LIT; break; } if (here.op & 32) { Tracevv((stderr, "inflate: end of block\n")); state->back = -1; state->mode = TYPE; break; } if (here.op & 64) { strm->msg = (char *)"invalid literal/length code"; state->mode = BAD; break; } state->extra = (unsigned)(here.op) & 15; state->mode = LENEXT; case LENEXT: if (state->extra) { NEEDBITS(state->extra); state->length += BITS(state->extra); DROPBITS(state->extra); state->back += state->extra; } Tracevv((stderr, "inflate: length %u\n", state->length)); state->was = state->length; state->mode = DIST; case DIST: for (;;) { here = state->distcode[BITS(state->distbits)]; if ((unsigned)(here.bits) <= bits) break; PULLBYTE(); } if ((here.op & 0xf0) == 0) { last = here; for (;;) { here = state->distcode[last.val + (BITS(last.bits + last.op) >> last.bits)]; if ((unsigned)(last.bits + here.bits) <= bits) break; PULLBYTE(); } DROPBITS(last.bits); state->back += last.bits; } DROPBITS(here.bits); state->back += here.bits; if (here.op & 64) { strm->msg = (char *)"invalid distance code"; state->mode = BAD; break; } state->offset = (unsigned)here.val; state->extra = (unsigned)(here.op) & 15; state->mode = DISTEXT; case DISTEXT: if (state->extra) { NEEDBITS(state->extra); state->offset += BITS(state->extra); DROPBITS(state->extra); state->back += state->extra; } #ifdef INFLATE_STRICT if (state->offset > state->dmax) { strm->msg = (char *)"invalid distance too far back"; state->mode = BAD; break; } #endif Tracevv((stderr, "inflate: distance %u\n", state->offset)); state->mode = MATCH; case MATCH: if (left == 0) goto inf_leave; copy = out - left; if (state->offset > copy) { /* copy from window */ copy = state->offset - copy; if (copy > state->whave) { if (state->sane) { strm->msg = (char *)"invalid distance too far back"; state->mode = BAD; break; } #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR Trace((stderr, "inflate.c too far\n")); copy -= state->whave; if (copy > state->length) copy = state->length; if (copy > left) copy = left; left -= copy; state->length -= copy; do { *put++ = 0; } while (--copy); if (state->length == 0) state->mode = LEN; break; #endif } if (copy > state->wnext) { copy -= state->wnext; from = state->window + (state->wsize - copy); } else from = state->window + (state->wnext - copy); if (copy > state->length) copy = state->length; } else { /* copy from output */ from = put - state->offset; copy = state->length; } if (copy > left) copy = left; left -= copy; state->length -= copy; do { *put++ = *from++; } while (--copy); if (state->length == 0) state->mode = LEN; break; case LIT: if (left == 0) goto inf_leave; *put++ = (unsigned char)(state->length); left--; state->mode = LEN; break; case CHECK: if (state->wrap) { NEEDBITS(32); out -= left; strm->total_out += out; state->total += out; if (out) strm->adler = state->check = UPDATE(state->check, put - out, out); out = left; if (( #ifdef GUNZIP state->flags ? hold : #endif ZSWAP32(hold)) != state->check) { strm->msg = (char *)"incorrect data check"; state->mode = BAD; break; } INITBITS(); Tracev((stderr, "inflate: check matches trailer\n")); } #ifdef GUNZIP state->mode = LENGTH; case LENGTH: if (state->wrap && state->flags) { NEEDBITS(32); if (hold != (state->total & 0xffffffffUL)) { strm->msg = (char *)"incorrect length check"; state->mode = BAD; break; } INITBITS(); Tracev((stderr, "inflate: length matches trailer\n")); } #endif state->mode = DONE; case DONE: ret = Z_STREAM_END; goto inf_leave; case BAD: ret = Z_DATA_ERROR; goto inf_leave; case MEM: return Z_MEM_ERROR; case SYNC: default: return Z_STREAM_ERROR; } /* Return from inflate(), updating the total counts and the check value. If there was no progress during the inflate() call, return a buffer error. Call updatewindow() to create and/or update the window state. Note: a memory error from inflate() is non-recoverable. */ inf_leave: RESTORE(); if (state->wsize || (out != strm->avail_out && state->mode < BAD && (state->mode < CHECK || flush != Z_FINISH))) if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { state->mode = MEM; return Z_MEM_ERROR; } in -= strm->avail_in; out -= strm->avail_out; strm->total_in += in; strm->total_out += out; state->total += out; if (state->wrap && out) strm->adler = state->check = UPDATE(state->check, strm->next_out - out, out); strm->data_type = state->bits + (state->last ? 64 : 0) + (state->mode == TYPE ? 128 : 0) + (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) ret = Z_BUF_ERROR; return ret; } int ZEXPORT inflateEnd(strm) z_streamp strm; { struct inflate_state FAR *state; if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (state->window != Z_NULL) ZFREE(strm, state->window); ZFREE(strm, strm->state); strm->state = Z_NULL; Tracev((stderr, "inflate: end\n")); return Z_OK; } int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength) z_streamp strm; Bytef *dictionary; uInt *dictLength; { struct inflate_state FAR *state; /* check state */ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; /* copy dictionary */ if (state->whave && dictionary != Z_NULL) { zmemcpy(dictionary, state->window + state->wnext, state->whave - state->wnext); zmemcpy(dictionary + state->whave - state->wnext, state->window, state->wnext); } if (dictLength != Z_NULL) *dictLength = state->whave; return Z_OK; } int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) z_streamp strm; const Bytef *dictionary; uInt dictLength; { struct inflate_state FAR *state; unsigned long dictid; int ret; /* check state */ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (state->wrap != 0 && state->mode != DICT) return Z_STREAM_ERROR; /* check for correct dictionary identifier */ if (state->mode == DICT) { dictid = adler32(0L, Z_NULL, 0); dictid = adler32(dictid, dictionary, dictLength); if (dictid != state->check) return Z_DATA_ERROR; } /* copy dictionary to window using updatewindow(), which will amend the existing dictionary if appropriate */ ret = updatewindow(strm, dictionary + dictLength, dictLength); if (ret) { state->mode = MEM; return Z_MEM_ERROR; } state->havedict = 1; Tracev((stderr, "inflate: dictionary set\n")); return Z_OK; } int ZEXPORT inflateGetHeader(strm, head) z_streamp strm; gz_headerp head; { struct inflate_state FAR *state; /* check state */ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; /* save header structure */ state->head = head; head->done = 0; return Z_OK; } /* Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found or when out of input. When called, *have is the number of pattern bytes found in order so far, in 0..3. On return *have is updated to the new state. If on return *have equals four, then the pattern was found and the return value is how many bytes were read including the last byte of the pattern. If *have is less than four, then the pattern has not been found yet and the return value is len. In the latter case, syncsearch() can be called again with more data and the *have state. *have is initialized to zero for the first call. */ local unsigned syncsearch(have, buf, len) unsigned FAR *have; const unsigned char FAR *buf; unsigned len; { unsigned got; unsigned next; got = *have; next = 0; while (next < len && got < 4) { if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) got++; else if (buf[next]) got = 0; else got = 4 - got; next++; } *have = got; return next; } int ZEXPORT inflateSync(strm) z_streamp strm; { unsigned len; /* number of bytes to look at or looked at */ unsigned long in, out; /* temporary to save total_in and total_out */ unsigned char buf[4]; /* to restore bit buffer to byte string */ struct inflate_state FAR *state; /* check parameters */ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; /* if first time, start search in bit buffer */ if (state->mode != SYNC) { state->mode = SYNC; state->hold <<= state->bits & 7; state->bits -= state->bits & 7; len = 0; while (state->bits >= 8) { buf[len++] = (unsigned char)(state->hold); state->hold >>= 8; state->bits -= 8; } state->have = 0; syncsearch(&(state->have), buf, len); } /* search available input */ len = syncsearch(&(state->have), strm->next_in, strm->avail_in); strm->avail_in -= len; strm->next_in += len; strm->total_in += len; /* return no joy or set up to restart inflate() on a new block */ if (state->have != 4) return Z_DATA_ERROR; in = strm->total_in; out = strm->total_out; inflateReset(strm); strm->total_in = in; strm->total_out = out; state->mode = TYPE; return Z_OK; } /* Returns true if inflate is currently at the end of a block generated by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored block. When decompressing, PPP checks that at the end of input packet, inflate is waiting for these length bytes. */ int ZEXPORT inflateSyncPoint(strm) z_streamp strm; { struct inflate_state FAR *state; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; return state->mode == STORED && state->bits == 0; } int ZEXPORT inflateCopy(dest, source) z_streamp dest; z_streamp source; { struct inflate_state FAR *state; struct inflate_state FAR *copy; unsigned char FAR *window; unsigned wsize; /* check input */ if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)source->state; /* allocate space */ copy = (struct inflate_state FAR *) ZALLOC(source, 1, sizeof(struct inflate_state)); if (copy == Z_NULL) return Z_MEM_ERROR; window = Z_NULL; if (state->window != Z_NULL) { window = (unsigned char FAR *) ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); if (window == Z_NULL) { ZFREE(source, copy); return Z_MEM_ERROR; } } /* copy state */ zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); if (state->lencode >= state->codes && state->lencode <= state->codes + ENOUGH - 1) { copy->lencode = copy->codes + (state->lencode - state->codes); copy->distcode = copy->codes + (state->distcode - state->codes); } copy->next = copy->codes + (state->next - state->codes); if (window != Z_NULL) { wsize = 1U << state->wbits; zmemcpy(window, state->window, wsize); } copy->window = window; dest->state = (struct internal_state FAR *)copy; return Z_OK; } int ZEXPORT inflateUndermine(strm, subvert) z_streamp strm; int subvert; { struct inflate_state FAR *state; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; state->sane = !subvert; #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR return Z_OK; #else state->sane = 1; return Z_DATA_ERROR; #endif } long ZEXPORT inflateMark(strm) z_streamp strm; { struct inflate_state FAR *state; if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16; state = (struct inflate_state FAR *)strm->state; return ((long)(state->back) << 16) + (state->mode == COPY ? state->length : (state->mode == MATCH ? state->was - state->length : 0)); } gtkwave-3.3.66/src/libz/inffast.h0000664000076400007640000000065311523063250016132 0ustar bybellbybell/* inffast.h -- header to use inffast.c * Copyright (C) 1995-2003, 2010 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start)); gtkwave-3.3.66/src/libz/crc32.h0000664000076400007640000007354212235606635015436 0ustar bybellbybell/* crc32.h -- tables for rapid CRC calculation * Generated automatically by crc32.c */ local const z_crc_t FAR crc_table[TBLS][256] = { { 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, 0x2d02ef8dUL #ifdef BYFOUR }, { 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, 0x9324fd72UL }, { 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, 0xbe9834edUL }, { 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, 0xde0506f1UL }, { 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, 0x8def022dUL }, { 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, 0x72fd2493UL }, { 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, 0xed3498beUL }, { 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, 0xf10605deUL #endif } }; gtkwave-3.3.66/src/libz/inftrees.c0000664000076400007640000003134412235606635016326 0ustar bybellbybell/* inftrees.c -- generate Huffman trees for efficient decoding * Copyright (C) 1995-2013 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ #include "zutil.h" #include "inftrees.h" #define MAXBITS 15 const char inflate_copyright[] = " inflate 1.2.8 Copyright 1995-2013 Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot include such an acknowledgment, I would appreciate that you keep this copyright string in the executable of your product. */ /* Build a set of tables to decode the provided canonical Huffman code. The code lengths are lens[0..codes-1]. The result starts at *table, whose indices are 0..2^bits-1. work is a writable array of at least lens shorts, which is used as a work area. type is the type of code to be generated, CODES, LENS, or DISTS. On return, zero is success, -1 is an invalid code, and +1 means that ENOUGH isn't enough. table on return points to the next available entry's address. bits is the requested root table index bits, and on return it is the actual root table index bits. It will differ if the request is greater than the longest code or if it is less than the shortest code. */ int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work) codetype type; unsigned short FAR *lens; unsigned codes; code FAR * FAR *table; unsigned FAR *bits; unsigned short FAR *work; { unsigned len; /* a code's length in bits */ unsigned sym; /* index of code symbols */ unsigned min, max; /* minimum and maximum code lengths */ unsigned root; /* number of index bits for root table */ unsigned curr; /* number of index bits for current table */ unsigned drop; /* code bits to drop for sub-table */ int left; /* number of prefix codes available */ unsigned used; /* code entries in table used */ unsigned huff; /* Huffman code */ unsigned incr; /* for incrementing code, index */ unsigned fill; /* index for replicating entries */ unsigned low; /* low bits for current root entry */ unsigned mask; /* mask for low root bits */ code here; /* table entry for duplication */ code FAR *next; /* next available space in table */ const unsigned short FAR *base; /* base value table to use */ const unsigned short FAR *extra; /* extra bits table to use */ int end; /* use base and extra for symbol > end */ unsigned short count[MAXBITS+1]; /* number of codes of each length */ unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ static const unsigned short lbase[31] = { /* Length codes 257..285 base */ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78}; static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0}; static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 64, 64}; /* Process a set of code lengths to create a canonical Huffman code. The code lengths are lens[0..codes-1]. Each length corresponds to the symbols 0..codes-1. The Huffman code is generated by first sorting the symbols by length from short to long, and retaining the symbol order for codes with equal lengths. Then the code starts with all zero bits for the first code of the shortest length, and the codes are integer increments for the same length, and zeros are appended as the length increases. For the deflate format, these bits are stored backwards from their more natural integer increment ordering, and so when the decoding tables are built in the large loop below, the integer codes are incremented backwards. This routine assumes, but does not check, that all of the entries in lens[] are in the range 0..MAXBITS. The caller must assure this. 1..MAXBITS is interpreted as that code length. zero means that that symbol does not occur in this code. The codes are sorted by computing a count of codes for each length, creating from that a table of starting indices for each length in the sorted table, and then entering the symbols in order in the sorted table. The sorted table is work[], with that space being provided by the caller. The length counts are used for other purposes as well, i.e. finding the minimum and maximum length codes, determining if there are any codes at all, checking for a valid set of lengths, and looking ahead at length counts to determine sub-table sizes when building the decoding tables. */ /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ for (len = 0; len <= MAXBITS; len++) count[len] = 0; for (sym = 0; sym < codes; sym++) count[lens[sym]]++; /* bound code lengths, force root to be within code lengths */ root = *bits; for (max = MAXBITS; max >= 1; max--) if (count[max] != 0) break; if (root > max) root = max; if (max == 0) { /* no symbols to code at all */ here.op = (unsigned char)64; /* invalid code marker */ here.bits = (unsigned char)1; here.val = (unsigned short)0; *(*table)++ = here; /* make a table to force an error */ *(*table)++ = here; *bits = 1; return 0; /* no symbols, but wait for decoding to report error */ } for (min = 1; min < max; min++) if (count[min] != 0) break; if (root < min) root = min; /* check for an over-subscribed or incomplete set of lengths */ left = 1; for (len = 1; len <= MAXBITS; len++) { left <<= 1; left -= count[len]; if (left < 0) return -1; /* over-subscribed */ } if (left > 0 && (type == CODES || max != 1)) return -1; /* incomplete set */ /* generate offsets into symbol table for each length for sorting */ offs[1] = 0; for (len = 1; len < MAXBITS; len++) offs[len + 1] = offs[len] + count[len]; /* sort symbols by length, by symbol order within each length */ for (sym = 0; sym < codes; sym++) if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; /* Create and fill in decoding tables. In this loop, the table being filled is at next and has curr index bits. The code being used is huff with length len. That code is converted to an index by dropping drop bits off of the bottom. For codes where len is less than drop + curr, those top drop + curr - len bits are incremented through all values to fill the table with replicated entries. root is the number of index bits for the root table. When len exceeds root, sub-tables are created pointed to by the root entry with an index of the low root bits of huff. This is saved in low to check for when a new sub-table should be started. drop is zero when the root table is being filled, and drop is root when sub-tables are being filled. When a new sub-table is needed, it is necessary to look ahead in the code lengths to determine what size sub-table is needed. The length counts are used for this, and so count[] is decremented as codes are entered in the tables. used keeps track of how many table entries have been allocated from the provided *table space. It is checked for LENS and DIST tables against the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in the initial root table size constants. See the comments in inftrees.h for more information. sym increments through all symbols, and the loop terminates when all codes of length max, i.e. all codes, have been processed. This routine permits incomplete codes, so another loop after this one fills in the rest of the decoding tables with invalid code markers. */ /* set up for code type */ switch (type) { case CODES: base = extra = work; /* dummy value--not used */ end = 19; break; case LENS: base = lbase; base -= 257; extra = lext; extra -= 257; end = 256; break; default: /* DISTS */ base = dbase; extra = dext; end = -1; } /* initialize state for loop */ huff = 0; /* starting code */ sym = 0; /* starting code symbol */ len = min; /* starting code length */ next = *table; /* current table to fill in */ curr = root; /* current table index bits */ drop = 0; /* current bits to drop from code for index */ low = (unsigned)(-1); /* trigger new sub-table when len > root */ used = 1U << root; /* use root table entries */ mask = used - 1; /* mask for comparing low */ /* check available table space */ if ((type == LENS && used > ENOUGH_LENS) || (type == DISTS && used > ENOUGH_DISTS)) return 1; /* process all codes and make table entries */ for (;;) { /* create table entry */ here.bits = (unsigned char)(len - drop); if ((int)(work[sym]) < end) { here.op = (unsigned char)0; here.val = work[sym]; } else if ((int)(work[sym]) > end) { here.op = (unsigned char)(extra[work[sym]]); here.val = base[work[sym]]; } else { here.op = (unsigned char)(32 + 64); /* end of block */ here.val = 0; } /* replicate for those indices with low len bits equal to huff */ incr = 1U << (len - drop); fill = 1U << curr; min = fill; /* save offset to next table */ do { fill -= incr; next[(huff >> drop) + fill] = here; } while (fill != 0); /* backwards increment the len-bit code huff */ incr = 1U << (len - 1); while (huff & incr) incr >>= 1; if (incr != 0) { huff &= incr - 1; huff += incr; } else huff = 0; /* go to next symbol, update count, len */ sym++; if (--(count[len]) == 0) { if (len == max) break; len = lens[work[sym]]; } /* create new sub-table if needed */ if (len > root && (huff & mask) != low) { /* if first time, transition to sub-tables */ if (drop == 0) drop = root; /* increment past last table */ next += min; /* here min is 1 << curr */ /* determine length of next table */ curr = len - drop; left = (int)(1 << curr); while (curr + drop < max) { left -= count[curr + drop]; if (left <= 0) break; curr++; left <<= 1; } /* check for enough space */ used += 1U << curr; if ((type == LENS && used > ENOUGH_LENS) || (type == DISTS && used > ENOUGH_DISTS)) return 1; /* point entry in root table to sub-table */ low = huff & mask; (*table)[low].op = (unsigned char)curr; (*table)[low].bits = (unsigned char)root; (*table)[low].val = (unsigned short)(next - *table); } } /* fill in remaining table entry if code is incomplete (guaranteed to have at most one remaining entry, since if the code is incomplete, the maximum code length that was allowed to get this far is one bit) */ if (huff != 0) { here.op = (unsigned char)64; /* invalid code marker */ here.bits = (unsigned char)(len - drop); here.val = (unsigned short)0; next[huff] = here; } /* set return parameters */ *table += used; *bits = root; return 0; } gtkwave-3.3.66/src/libz/gzlib.c0000664000076400007640000004003712235606635015615 0ustar bybellbybell/* gzlib.c -- zlib functions common to reading and writing gzip files * Copyright (C) 2004, 2010, 2011, 2012, 2013 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ #include "gzguts.h" #if defined(_WIN32) && !defined(__BORLANDC__) # define LSEEK _lseeki64 #else #if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 # define LSEEK lseek64 #else # define LSEEK lseek #endif #endif /* Local functions */ local void gz_reset OF((gz_statep)); local gzFile gz_open OF((const void *, int, const char *)); #if defined UNDER_CE /* Map the Windows error number in ERROR to a locale-dependent error message string and return a pointer to it. Typically, the values for ERROR come from GetLastError. The string pointed to shall not be modified by the application, but may be overwritten by a subsequent call to gz_strwinerror The gz_strwinerror function does not change the current setting of GetLastError. */ char ZLIB_INTERNAL *gz_strwinerror (error) DWORD error; { static char buf[1024]; wchar_t *msgbuf; DWORD lasterr = GetLastError(); DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, error, 0, /* Default language */ (LPVOID)&msgbuf, 0, NULL); if (chars != 0) { /* If there is an \r\n appended, zap it. */ if (chars >= 2 && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { chars -= 2; msgbuf[chars] = 0; } if (chars > sizeof (buf) - 1) { chars = sizeof (buf) - 1; msgbuf[chars] = 0; } wcstombs(buf, msgbuf, chars + 1); LocalFree(msgbuf); } else { sprintf(buf, "unknown win32 error (%ld)", error); } SetLastError(lasterr); return buf; } #endif /* UNDER_CE */ /* Reset gzip file state */ local void gz_reset(state) gz_statep state; { state->x.have = 0; /* no output data available */ if (state->mode == GZ_READ) { /* for reading ... */ state->eof = 0; /* not at end of file */ state->past = 0; /* have not read past end yet */ state->how = LOOK; /* look for gzip header */ } state->seek = 0; /* no seek request pending */ gz_error(state, Z_OK, NULL); /* clear error */ state->x.pos = 0; /* no uncompressed data yet */ state->strm.avail_in = 0; /* no input data yet */ } /* Open a gzip file either by name or file descriptor. */ local gzFile gz_open(path, fd, mode) const void *path; int fd; const char *mode; { gz_statep state; size_t len; int oflag; #ifdef O_CLOEXEC int cloexec = 0; #endif #ifdef O_EXCL int exclusive = 0; #endif /* check input */ if (path == NULL) return NULL; /* allocate gzFile structure to return */ state = (gz_statep)malloc(sizeof(gz_state)); if (state == NULL) return NULL; state->size = 0; /* no buffers allocated yet */ state->want = GZBUFSIZE; /* requested buffer size */ state->msg = NULL; /* no error message yet */ /* interpret mode */ state->mode = GZ_NONE; state->level = Z_DEFAULT_COMPRESSION; state->strategy = Z_DEFAULT_STRATEGY; state->direct = 0; while (*mode) { if (*mode >= '0' && *mode <= '9') state->level = *mode - '0'; else switch (*mode) { case 'r': state->mode = GZ_READ; break; #ifndef NO_GZCOMPRESS case 'w': state->mode = GZ_WRITE; break; case 'a': state->mode = GZ_APPEND; break; #endif case '+': /* can't read and write at the same time */ free(state); return NULL; case 'b': /* ignore -- will request binary anyway */ break; #ifdef O_CLOEXEC case 'e': cloexec = 1; break; #endif #ifdef O_EXCL case 'x': exclusive = 1; break; #endif case 'f': state->strategy = Z_FILTERED; break; case 'h': state->strategy = Z_HUFFMAN_ONLY; break; case 'R': state->strategy = Z_RLE; break; case 'F': state->strategy = Z_FIXED; break; case 'T': state->direct = 1; break; default: /* could consider as an error, but just ignore */ ; } mode++; } /* must provide an "r", "w", or "a" */ if (state->mode == GZ_NONE) { free(state); return NULL; } /* can't force transparent read */ if (state->mode == GZ_READ) { if (state->direct) { free(state); return NULL; } state->direct = 1; /* for empty file */ } /* save the path name for error messages */ #ifdef _WIN32 if (fd == -2) { len = wcstombs(NULL, path, 0); if (len == (size_t)-1) len = 0; } else #endif len = strlen((const char *)path); state->path = (char *)malloc(len + 1); if (state->path == NULL) { free(state); return NULL; } #ifdef _WIN32 if (fd == -2) if (len) wcstombs(state->path, path, len + 1); else *(state->path) = 0; else #endif #if !defined(NO_snprintf) && !defined(NO_vsnprintf) snprintf(state->path, len + 1, "%s", (const char *)path); #else strcpy(state->path, path); #endif /* compute the flags for open() */ oflag = #ifdef O_LARGEFILE O_LARGEFILE | #endif #ifdef O_BINARY O_BINARY | #endif #ifdef O_CLOEXEC (cloexec ? O_CLOEXEC : 0) | #endif (state->mode == GZ_READ ? O_RDONLY : (O_WRONLY | O_CREAT | #ifdef O_EXCL (exclusive ? O_EXCL : 0) | #endif (state->mode == GZ_WRITE ? O_TRUNC : O_APPEND))); /* open the file with the appropriate flags (or just use fd) */ state->fd = fd > -1 ? fd : ( #ifdef _WIN32 fd == -2 ? _wopen(path, oflag, 0666) : #endif open((const char *)path, oflag, 0666)); if (state->fd == -1) { free(state->path); free(state); return NULL; } if (state->mode == GZ_APPEND) state->mode = GZ_WRITE; /* simplify later checks */ /* save the current position for rewinding (only if reading) */ if (state->mode == GZ_READ) { state->start = LSEEK(state->fd, 0, SEEK_CUR); if (state->start == -1) state->start = 0; } /* initialize stream */ gz_reset(state); /* return stream */ return (gzFile)state; } /* -- see zlib.h -- */ gzFile ZEXPORT gzopen(path, mode) const char *path; const char *mode; { return gz_open(path, -1, mode); } /* -- see zlib.h -- */ gzFile ZEXPORT gzopen64(path, mode) const char *path; const char *mode; { return gz_open(path, -1, mode); } /* -- see zlib.h -- */ gzFile ZEXPORT gzdopen(fd, mode) int fd; const char *mode; { char *path; /* identifier for error messages */ gzFile gz; if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) return NULL; #if !defined(NO_snprintf) && !defined(NO_vsnprintf) snprintf(path, 7 + 3 * sizeof(int), "", fd); /* for debugging */ #else sprintf(path, "", fd); /* for debugging */ #endif gz = gz_open(path, fd, mode); free(path); return gz; } /* -- see zlib.h -- */ #ifdef _WIN32 gzFile ZEXPORT gzopen_w(path, mode) const wchar_t *path; const char *mode; { return gz_open(path, -2, mode); } #endif /* -- see zlib.h -- */ int ZEXPORT gzbuffer(file, size) gzFile file; unsigned size; { gz_statep state; /* get internal structure and check integrity */ if (file == NULL) return -1; state = (gz_statep)file; if (state->mode != GZ_READ && state->mode != GZ_WRITE) return -1; /* make sure we haven't already allocated memory */ if (state->size != 0) return -1; /* check and set requested size */ if (size < 2) size = 2; /* need two bytes to check magic header */ state->want = size; return 0; } /* -- see zlib.h -- */ int ZEXPORT gzrewind(file) gzFile file; { gz_statep state; /* get internal structure */ if (file == NULL) return -1; state = (gz_statep)file; /* check that we're reading and that there's no error */ if (state->mode != GZ_READ || (state->err != Z_OK && state->err != Z_BUF_ERROR)) return -1; /* back up and start over */ if (LSEEK(state->fd, state->start, SEEK_SET) == -1) return -1; gz_reset(state); return 0; } /* -- see zlib.h -- */ z_off64_t ZEXPORT gzseek64(file, offset, whence) gzFile file; z_off64_t offset; int whence; { unsigned n; z_off64_t ret; gz_statep state; /* get internal structure and check integrity */ if (file == NULL) return -1; state = (gz_statep)file; if (state->mode != GZ_READ && state->mode != GZ_WRITE) return -1; /* check that there's no error */ if (state->err != Z_OK && state->err != Z_BUF_ERROR) return -1; /* can only seek from start or relative to current position */ if (whence != SEEK_SET && whence != SEEK_CUR) return -1; /* normalize offset to a SEEK_CUR specification */ if (whence == SEEK_SET) offset -= state->x.pos; else if (state->seek) offset += state->skip; state->seek = 0; /* if within raw area while reading, just go there */ if (state->mode == GZ_READ && state->how == COPY && state->x.pos + offset >= 0) { ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR); if (ret == -1) return -1; state->x.have = 0; state->eof = 0; state->past = 0; state->seek = 0; gz_error(state, Z_OK, NULL); state->strm.avail_in = 0; state->x.pos += offset; return state->x.pos; } /* calculate skip amount, rewinding if needed for back seek when reading */ if (offset < 0) { if (state->mode != GZ_READ) /* writing -- can't go backwards */ return -1; offset += state->x.pos; if (offset < 0) /* before start of file! */ return -1; if (gzrewind(file) == -1) /* rewind, then skip to offset */ return -1; } /* if reading, skip what's in output buffer (one less gzgetc() check) */ if (state->mode == GZ_READ) { n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? (unsigned)offset : state->x.have; state->x.have -= n; state->x.next += n; state->x.pos += n; offset -= n; } /* request skip (if not zero) */ if (offset) { state->seek = 1; state->skip = offset; } return state->x.pos + offset; } /* -- see zlib.h -- */ z_off_t ZEXPORT gzseek(file, offset, whence) gzFile file; z_off_t offset; int whence; { z_off64_t ret; ret = gzseek64(file, (z_off64_t)offset, whence); return ret == (z_off_t)ret ? (z_off_t)ret : -1; } /* -- see zlib.h -- */ z_off64_t ZEXPORT gztell64(file) gzFile file; { gz_statep state; /* get internal structure and check integrity */ if (file == NULL) return -1; state = (gz_statep)file; if (state->mode != GZ_READ && state->mode != GZ_WRITE) return -1; /* return position */ return state->x.pos + (state->seek ? state->skip : 0); } /* -- see zlib.h -- */ z_off_t ZEXPORT gztell(file) gzFile file; { z_off64_t ret; ret = gztell64(file); return ret == (z_off_t)ret ? (z_off_t)ret : -1; } /* -- see zlib.h -- */ z_off64_t ZEXPORT gzoffset64(file) gzFile file; { z_off64_t offset; gz_statep state; /* get internal structure and check integrity */ if (file == NULL) return -1; state = (gz_statep)file; if (state->mode != GZ_READ && state->mode != GZ_WRITE) return -1; /* compute and return effective offset in file */ offset = LSEEK(state->fd, 0, SEEK_CUR); if (offset == -1) return -1; if (state->mode == GZ_READ) /* reading */ offset -= state->strm.avail_in; /* don't count buffered input */ return offset; } /* -- see zlib.h -- */ z_off_t ZEXPORT gzoffset(file) gzFile file; { z_off64_t ret; ret = gzoffset64(file); return ret == (z_off_t)ret ? (z_off_t)ret : -1; } /* -- see zlib.h -- */ int ZEXPORT gzeof(file) gzFile file; { gz_statep state; /* get internal structure and check integrity */ if (file == NULL) return 0; state = (gz_statep)file; if (state->mode != GZ_READ && state->mode != GZ_WRITE) return 0; /* return end-of-file state */ return state->mode == GZ_READ ? state->past : 0; } /* -- see zlib.h -- */ const char * ZEXPORT gzerror(file, errnum) gzFile file; int *errnum; { gz_statep state; /* get internal structure and check integrity */ if (file == NULL) return NULL; state = (gz_statep)file; if (state->mode != GZ_READ && state->mode != GZ_WRITE) return NULL; /* return error information */ if (errnum != NULL) *errnum = state->err; return state->err == Z_MEM_ERROR ? "out of memory" : (state->msg == NULL ? "" : state->msg); } /* -- see zlib.h -- */ void ZEXPORT gzclearerr(file) gzFile file; { gz_statep state; /* get internal structure and check integrity */ if (file == NULL) return; state = (gz_statep)file; if (state->mode != GZ_READ && state->mode != GZ_WRITE) return; /* clear error and end-of-file */ if (state->mode == GZ_READ) { state->eof = 0; state->past = 0; } gz_error(state, Z_OK, NULL); } /* Create an error message in allocated memory and set state->err and state->msg accordingly. Free any previous error message already there. Do not try to free or allocate space if the error is Z_MEM_ERROR (out of memory). Simply save the error message as a static string. If there is an allocation failure constructing the error message, then convert the error to out of memory. */ void ZLIB_INTERNAL gz_error(state, err, msg) gz_statep state; int err; const char *msg; { /* free previously allocated message and clear */ if (state->msg != NULL) { if (state->err != Z_MEM_ERROR) free(state->msg); state->msg = NULL; } /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ if (err != Z_OK && err != Z_BUF_ERROR) state->x.have = 0; /* set error code, and if no message, then done */ state->err = err; if (msg == NULL) return; /* for an out of memory error, return literal string when requested */ if (err == Z_MEM_ERROR) return; /* construct error message with path */ if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) == NULL) { state->err = Z_MEM_ERROR; return; } #if !defined(NO_snprintf) && !defined(NO_vsnprintf) snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, "%s%s%s", state->path, ": ", msg); #else strcpy(state->msg, state->path); strcat(state->msg, ": "); strcat(state->msg, msg); #endif return; } #ifndef INT_MAX /* portably return maximum value for an int (when limits.h presumed not available) -- we need to do this to cover cases where 2's complement not used, since C standard permits 1's complement and sign-bit representations, otherwise we could just use ((unsigned)-1) >> 1 */ unsigned ZLIB_INTERNAL gz_intmax() { unsigned p, q; p = 1; do { q = p; p <<= 1; p++; } while (p > q); return q >> 1; } #endif gtkwave-3.3.66/src/libz/gzwrite.c0000664000076400007640000003750712235606635016211 0ustar bybellbybell/* gzwrite.c -- zlib functions for writing gzip files * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ #include "gzguts.h" /* Local functions */ local int gz_init OF((gz_statep)); local int gz_comp OF((gz_statep, int)); local int gz_zero OF((gz_statep, z_off64_t)); /* Initialize state for writing a gzip file. Mark initialization by setting state->size to non-zero. Return -1 on failure or 0 on success. */ local int gz_init(state) gz_statep state; { int ret; z_streamp strm = &(state->strm); /* allocate input buffer */ state->in = (unsigned char *)malloc(state->want); if (state->in == NULL) { gz_error(state, Z_MEM_ERROR, "out of memory"); return -1; } /* only need output buffer and deflate state if compressing */ if (!state->direct) { /* allocate output buffer */ state->out = (unsigned char *)malloc(state->want); if (state->out == NULL) { free(state->in); gz_error(state, Z_MEM_ERROR, "out of memory"); return -1; } /* allocate deflate memory, set up for gzip compression */ strm->zalloc = Z_NULL; strm->zfree = Z_NULL; strm->opaque = Z_NULL; ret = deflateInit2(strm, state->level, Z_DEFLATED, MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); if (ret != Z_OK) { free(state->out); free(state->in); gz_error(state, Z_MEM_ERROR, "out of memory"); return -1; } } /* mark state as initialized */ state->size = state->want; /* initialize write buffer if compressing */ if (!state->direct) { strm->avail_out = state->size; strm->next_out = state->out; state->x.next = strm->next_out; } return 0; } /* Compress whatever is at avail_in and next_in and write to the output file. Return -1 if there is an error writing to the output file, otherwise 0. flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH, then the deflate() state is reset to start a new gzip stream. If gz->direct is true, then simply write to the output file without compressing, and ignore flush. */ local int gz_comp(state, flush) gz_statep state; int flush; { int ret, got; unsigned have; z_streamp strm = &(state->strm); /* allocate memory if this is the first time through */ if (state->size == 0 && gz_init(state) == -1) return -1; /* write directly if requested */ if (state->direct) { got = write(state->fd, strm->next_in, strm->avail_in); if (got < 0 || (unsigned)got != strm->avail_in) { gz_error(state, Z_ERRNO, zstrerror()); return -1; } strm->avail_in = 0; return 0; } /* run deflate() on provided input until it produces no more output */ ret = Z_OK; do { /* write out current buffer contents if full, or if flushing, but if doing Z_FINISH then don't write until we get to Z_STREAM_END */ if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && (flush != Z_FINISH || ret == Z_STREAM_END))) { have = (unsigned)(strm->next_out - state->x.next); if (have && ((got = write(state->fd, state->x.next, have)) < 0 || (unsigned)got != have)) { gz_error(state, Z_ERRNO, zstrerror()); return -1; } if (strm->avail_out == 0) { strm->avail_out = state->size; strm->next_out = state->out; } state->x.next = strm->next_out; } /* compress */ have = strm->avail_out; ret = deflate(strm, flush); if (ret == Z_STREAM_ERROR) { gz_error(state, Z_STREAM_ERROR, "internal error: deflate stream corrupt"); return -1; } have -= strm->avail_out; } while (have); /* if that completed a deflate stream, allow another to start */ if (flush == Z_FINISH) deflateReset(strm); /* all done, no errors */ return 0; } /* Compress len zeros to output. Return -1 on error, 0 on success. */ local int gz_zero(state, len) gz_statep state; z_off64_t len; { int first; unsigned n; z_streamp strm = &(state->strm); /* consume whatever's left in the input buffer */ if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) return -1; /* compress len zeros (len guaranteed > 0) */ first = 1; while (len) { n = GT_OFF(state->size) || (z_off64_t)state->size > len ? (unsigned)len : state->size; if (first) { memset(state->in, 0, n); first = 0; } strm->avail_in = n; strm->next_in = state->in; state->x.pos += n; if (gz_comp(state, Z_NO_FLUSH) == -1) return -1; len -= n; } return 0; } /* -- see zlib.h -- */ int ZEXPORT gzwrite(file, buf, len) gzFile file; voidpc buf; unsigned len; { unsigned put = len; gz_statep state; z_streamp strm; /* get internal structure */ if (file == NULL) return 0; state = (gz_statep)file; strm = &(state->strm); /* check that we're writing and that there's no error */ if (state->mode != GZ_WRITE || state->err != Z_OK) return 0; /* since an int is returned, make sure len fits in one, otherwise return with an error (this avoids the flaw in the interface) */ if ((int)len < 0) { gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); return 0; } /* if len is zero, avoid unnecessary operations */ if (len == 0) return 0; /* allocate memory if this is the first time through */ if (state->size == 0 && gz_init(state) == -1) return 0; /* check for seek request */ if (state->seek) { state->seek = 0; if (gz_zero(state, state->skip) == -1) return 0; } /* for small len, copy to input buffer, otherwise compress directly */ if (len < state->size) { /* copy to input buffer, compress when full */ do { unsigned have, copy; if (strm->avail_in == 0) strm->next_in = state->in; have = (unsigned)((strm->next_in + strm->avail_in) - state->in); copy = state->size - have; if (copy > len) copy = len; memcpy(state->in + have, buf, copy); strm->avail_in += copy; state->x.pos += copy; buf = (const char *)buf + copy; len -= copy; if (len && gz_comp(state, Z_NO_FLUSH) == -1) return 0; } while (len); } else { /* consume whatever's left in the input buffer */ if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) return 0; /* directly compress user buffer to file */ strm->avail_in = len; strm->next_in = (z_const Bytef *)buf; state->x.pos += len; if (gz_comp(state, Z_NO_FLUSH) == -1) return 0; } /* input was all buffered or compressed (put will fit in int) */ return (int)put; } /* -- see zlib.h -- */ int ZEXPORT gzputc(file, c) gzFile file; int c; { unsigned have; unsigned char buf[1]; gz_statep state; z_streamp strm; /* get internal structure */ if (file == NULL) return -1; state = (gz_statep)file; strm = &(state->strm); /* check that we're writing and that there's no error */ if (state->mode != GZ_WRITE || state->err != Z_OK) return -1; /* check for seek request */ if (state->seek) { state->seek = 0; if (gz_zero(state, state->skip) == -1) return -1; } /* try writing to input buffer for speed (state->size == 0 if buffer not initialized) */ if (state->size) { if (strm->avail_in == 0) strm->next_in = state->in; have = (unsigned)((strm->next_in + strm->avail_in) - state->in); if (have < state->size) { state->in[have] = c; strm->avail_in++; state->x.pos++; return c & 0xff; } } /* no room in buffer or not initialized, use gz_write() */ buf[0] = c; if (gzwrite(file, buf, 1) != 1) return -1; return c & 0xff; } /* -- see zlib.h -- */ int ZEXPORT gzputs(file, str) gzFile file; const char *str; { int ret; unsigned len; /* write string */ len = (unsigned)strlen(str); ret = gzwrite(file, str, len); return ret == 0 && len != 0 ? -1 : ret; } #if defined(STDC) || defined(Z_HAVE_STDARG_H) #include /* -- see zlib.h -- */ int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) { int size, len; gz_statep state; z_streamp strm; /* get internal structure */ if (file == NULL) return -1; state = (gz_statep)file; strm = &(state->strm); /* check that we're writing and that there's no error */ if (state->mode != GZ_WRITE || state->err != Z_OK) return 0; /* make sure we have some buffer space */ if (state->size == 0 && gz_init(state) == -1) return 0; /* check for seek request */ if (state->seek) { state->seek = 0; if (gz_zero(state, state->skip) == -1) return 0; } /* consume whatever's left in the input buffer */ if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) return 0; /* do the printf() into the input buffer, put length in len */ size = (int)(state->size); state->in[size - 1] = 0; #ifdef NO_vsnprintf # ifdef HAS_vsprintf_void (void)vsprintf((char *)(state->in), format, va); for (len = 0; len < size; len++) if (state->in[len] == 0) break; # else len = vsprintf((char *)(state->in), format, va); # endif #else # ifdef HAS_vsnprintf_void (void)vsnprintf((char *)(state->in), size, format, va); len = strlen((char *)(state->in)); # else len = vsnprintf((char *)(state->in), size, format, va); # endif #endif /* check that printf() results fit in buffer */ if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) return 0; /* update buffer and position, defer compression until needed */ strm->avail_in = (unsigned)len; strm->next_in = state->in; state->x.pos += len; return len; } int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) { va_list va; int ret; va_start(va, format); ret = gzvprintf(file, format, va); va_end(va); return ret; } #else /* !STDC && !Z_HAVE_STDARG_H */ /* -- see zlib.h -- */ int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) gzFile file; const char *format; int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; { int size, len; gz_statep state; z_streamp strm; /* get internal structure */ if (file == NULL) return -1; state = (gz_statep)file; strm = &(state->strm); /* check that can really pass pointer in ints */ if (sizeof(int) != sizeof(void *)) return 0; /* check that we're writing and that there's no error */ if (state->mode != GZ_WRITE || state->err != Z_OK) return 0; /* make sure we have some buffer space */ if (state->size == 0 && gz_init(state) == -1) return 0; /* check for seek request */ if (state->seek) { state->seek = 0; if (gz_zero(state, state->skip) == -1) return 0; } /* consume whatever's left in the input buffer */ if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) return 0; /* do the printf() into the input buffer, put length in len */ size = (int)(state->size); state->in[size - 1] = 0; #ifdef NO_snprintf # ifdef HAS_sprintf_void sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); for (len = 0; len < size; len++) if (state->in[len] == 0) break; # else len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); # endif #else # ifdef HAS_snprintf_void snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); len = strlen((char *)(state->in)); # else len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); # endif #endif /* check that printf() results fit in buffer */ if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) return 0; /* update buffer and position, defer compression until needed */ strm->avail_in = (unsigned)len; strm->next_in = state->in; state->x.pos += len; return len; } #endif /* -- see zlib.h -- */ int ZEXPORT gzflush(file, flush) gzFile file; int flush; { gz_statep state; /* get internal structure */ if (file == NULL) return -1; state = (gz_statep)file; /* check that we're writing and that there's no error */ if (state->mode != GZ_WRITE || state->err != Z_OK) return Z_STREAM_ERROR; /* check flush parameter */ if (flush < 0 || flush > Z_FINISH) return Z_STREAM_ERROR; /* check for seek request */ if (state->seek) { state->seek = 0; if (gz_zero(state, state->skip) == -1) return -1; } /* compress remaining data with requested flush */ gz_comp(state, flush); return state->err; } /* -- see zlib.h -- */ int ZEXPORT gzsetparams(file, level, strategy) gzFile file; int level; int strategy; { gz_statep state; z_streamp strm; /* get internal structure */ if (file == NULL) return Z_STREAM_ERROR; state = (gz_statep)file; strm = &(state->strm); /* check that we're writing and that there's no error */ if (state->mode != GZ_WRITE || state->err != Z_OK) return Z_STREAM_ERROR; /* if no change is requested, then do nothing */ if (level == state->level && strategy == state->strategy) return Z_OK; /* check for seek request */ if (state->seek) { state->seek = 0; if (gz_zero(state, state->skip) == -1) return -1; } /* change compression parameters for subsequent input */ if (state->size) { /* flush previous input with previous parameters before changing */ if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1) return state->err; deflateParams(strm, level, strategy); } state->level = level; state->strategy = strategy; return Z_OK; } /* -- see zlib.h -- */ int ZEXPORT gzclose_w(file) gzFile file; { int ret = Z_OK; gz_statep state; /* get internal structure */ if (file == NULL) return Z_STREAM_ERROR; state = (gz_statep)file; /* check that we're writing */ if (state->mode != GZ_WRITE) return Z_STREAM_ERROR; /* check for seek request */ if (state->seek) { state->seek = 0; if (gz_zero(state, state->skip) == -1) ret = state->err; } /* flush, free memory, and close file */ if (gz_comp(state, Z_FINISH) == -1) ret = state->err; if (state->size) { if (!state->direct) { (void)deflateEnd(&(state->strm)); free(state->out); } free(state->in); } gz_error(state, Z_OK, NULL); free(state->path); if (close(state->fd) == -1) ret = Z_ERRNO; free(state); return ret; } gtkwave-3.3.66/src/libz/gzguts.h0000664000076400007640000001463012235606635016036 0ustar bybellbybell/* gzguts.h -- zlib internal header definitions for gz* operations * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ #ifdef _LARGEFILE64_SOURCE # ifndef _LARGEFILE_SOURCE # define _LARGEFILE_SOURCE 1 # endif # ifdef _FILE_OFFSET_BITS # undef _FILE_OFFSET_BITS # endif #endif #ifdef HAVE_HIDDEN # define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) #else # define ZLIB_INTERNAL #endif #include #include "zlib.h" #ifdef STDC # include # include # include #endif #include #ifdef _WIN32 # include #endif #if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32) # include #endif #ifdef WINAPI_FAMILY # define open _open # define read _read # define write _write # define close _close #endif #ifdef NO_DEFLATE /* for compatibility with old definition */ # define NO_GZCOMPRESS #endif #if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) # ifndef HAVE_VSNPRINTF # define HAVE_VSNPRINTF # endif #endif #if defined(__CYGWIN__) # ifndef HAVE_VSNPRINTF # define HAVE_VSNPRINTF # endif #endif #if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) # ifndef HAVE_VSNPRINTF # define HAVE_VSNPRINTF # endif #endif #ifndef HAVE_VSNPRINTF # ifdef MSDOS /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), but for now we just assume it doesn't. */ # define NO_vsnprintf # endif # ifdef __TURBOC__ # define NO_vsnprintf # endif # ifdef WIN32 /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ # if !defined(vsnprintf) && !defined(NO_vsnprintf) # if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) # define vsnprintf _vsnprintf # endif # endif # endif # ifdef __SASC # define NO_vsnprintf # endif # ifdef VMS # define NO_vsnprintf # endif # ifdef __OS400__ # define NO_vsnprintf # endif # ifdef __MVS__ # define NO_vsnprintf # endif #endif /* unlike snprintf (which is required in C99, yet still not supported by Microsoft more than a decade later!), _snprintf does not guarantee null termination of the result -- however this is only used in gzlib.c where the result is assured to fit in the space provided */ #ifdef _MSC_VER # define snprintf _snprintf #endif #ifndef local # define local static #endif /* compile with -Dlocal if your debugger can't find static symbols */ /* gz* functions always use library allocation functions */ #ifndef STDC extern voidp malloc OF((uInt size)); extern void free OF((voidpf ptr)); #endif /* get errno and strerror definition */ #if defined UNDER_CE # include # define zstrerror() gz_strwinerror((DWORD)GetLastError()) #else # ifndef NO_STRERROR # include # define zstrerror() strerror(errno) # else # define zstrerror() "stdio error (consult errno)" # endif #endif /* provide prototypes for these when building zlib without LFS */ #if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); #endif /* default memLevel */ #if MAX_MEM_LEVEL >= 8 # define DEF_MEM_LEVEL 8 #else # define DEF_MEM_LEVEL MAX_MEM_LEVEL #endif /* default i/o buffer size -- double this for output when reading (this and twice this must be able to fit in an unsigned type) */ #define GZBUFSIZE 8192 /* gzip modes, also provide a little integrity check on the passed structure */ #define GZ_NONE 0 #define GZ_READ 7247 #define GZ_WRITE 31153 #define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ /* values for gz_state how */ #define LOOK 0 /* look for a gzip header */ #define COPY 1 /* copy input directly */ #define GZIP 2 /* decompress a gzip stream */ /* internal gzip file state data structure */ typedef struct { /* exposed contents for gzgetc() macro */ struct gzFile_s x; /* "x" for exposed */ /* x.have: number of bytes available at x.next */ /* x.next: next output data to deliver or write */ /* x.pos: current position in uncompressed data */ /* used for both reading and writing */ int mode; /* see gzip modes above */ int fd; /* file descriptor */ char *path; /* path or fd for error messages */ unsigned size; /* buffer size, zero if not allocated yet */ unsigned want; /* requested buffer size, default is GZBUFSIZE */ unsigned char *in; /* input buffer */ unsigned char *out; /* output buffer (double-sized when reading) */ int direct; /* 0 if processing gzip, 1 if transparent */ /* just for reading */ int how; /* 0: get header, 1: copy, 2: decompress */ z_off64_t start; /* where the gzip data started, for rewinding */ int eof; /* true if end of input file reached */ int past; /* true if read requested past end */ /* just for writing */ int level; /* compression level */ int strategy; /* compression strategy */ /* seek request */ z_off64_t skip; /* amount to skip (already rewound if backwards) */ int seek; /* true if seek request pending */ /* error information */ int err; /* error code */ char *msg; /* error message */ /* zlib inflate or deflate stream */ z_stream strm; /* stream structure in-place (not a pointer) */ } gz_state; typedef gz_state FAR *gz_statep; /* shared functions */ void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *)); #if defined UNDER_CE char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error)); #endif /* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t value -- needed when comparing unsigned to z_off64_t, which is signed (possible z_off64_t types off_t, off64_t, and long are all signed) */ #ifdef INT_MAX # define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) #else unsigned ZLIB_INTERNAL gz_intmax OF((void)); # define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) #endif gtkwave-3.3.66/src/libz/example.c0000664000076400007640000004010011523063250016115 0ustar bybellbybell/* example.c -- usage example of the zlib compression library * Copyright (C) 1995-2006 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* @(#) $Id: example.c,v 1.1 2010/06/30 04:58:25 gtkwave Exp $ */ #include "zlib.h" #include #ifdef STDC # include # include #endif #if defined(VMS) || defined(RISCOS) # define TESTFILE "foo-gz" #else # define TESTFILE "foo.gz" #endif #define CHECK_ERR(err, msg) { \ if (err != Z_OK) { \ fprintf(stderr, "%s error: %d\n", msg, err); \ exit(1); \ } \ } const char hello[] = "hello, hello!"; /* "hello world" would be more standard, but the repeated "hello" * stresses the compression code better, sorry... */ const char dictionary[] = "hello"; uLong dictId; /* Adler32 value of the dictionary */ void test_compress OF((Byte *compr, uLong comprLen, Byte *uncompr, uLong uncomprLen)); void test_gzio OF((const char *fname, Byte *uncompr, uLong uncomprLen)); void test_deflate OF((Byte *compr, uLong comprLen)); void test_inflate OF((Byte *compr, uLong comprLen, Byte *uncompr, uLong uncomprLen)); void test_large_deflate OF((Byte *compr, uLong comprLen, Byte *uncompr, uLong uncomprLen)); void test_large_inflate OF((Byte *compr, uLong comprLen, Byte *uncompr, uLong uncomprLen)); void test_flush OF((Byte *compr, uLong *comprLen)); void test_sync OF((Byte *compr, uLong comprLen, Byte *uncompr, uLong uncomprLen)); void test_dict_deflate OF((Byte *compr, uLong comprLen)); void test_dict_inflate OF((Byte *compr, uLong comprLen, Byte *uncompr, uLong uncomprLen)); int main OF((int argc, char *argv[])); /* =========================================================================== * Test compress() and uncompress() */ void test_compress(compr, comprLen, uncompr, uncomprLen) Byte *compr, *uncompr; uLong comprLen, uncomprLen; { int err; uLong len = (uLong)strlen(hello)+1; err = compress(compr, &comprLen, (const Bytef*)hello, len); CHECK_ERR(err, "compress"); strcpy((char*)uncompr, "garbage"); err = uncompress(uncompr, &uncomprLen, compr, comprLen); CHECK_ERR(err, "uncompress"); if (strcmp((char*)uncompr, hello)) { fprintf(stderr, "bad uncompress\n"); exit(1); } else { printf("uncompress(): %s\n", (char *)uncompr); } } /* =========================================================================== * Test read/write of .gz files */ void test_gzio(fname, uncompr, uncomprLen) const char *fname; /* compressed file name */ Byte *uncompr; uLong uncomprLen; { #ifdef NO_GZCOMPRESS fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n"); #else int err; int len = (int)strlen(hello)+1; gzFile file; z_off_t pos; file = gzopen(fname, "wb"); if (file == NULL) { fprintf(stderr, "gzopen error\n"); exit(1); } gzputc(file, 'h'); if (gzputs(file, "ello") != 4) { fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err)); exit(1); } if (gzprintf(file, ", %s!", "hello") != 8) { fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err)); exit(1); } gzseek(file, 1L, SEEK_CUR); /* add one zero byte */ gzclose(file); file = gzopen(fname, "rb"); if (file == NULL) { fprintf(stderr, "gzopen error\n"); exit(1); } strcpy((char*)uncompr, "garbage"); if (gzread(file, uncompr, (unsigned)uncomprLen) != len) { fprintf(stderr, "gzread err: %s\n", gzerror(file, &err)); exit(1); } if (strcmp((char*)uncompr, hello)) { fprintf(stderr, "bad gzread: %s\n", (char*)uncompr); exit(1); } else { printf("gzread(): %s\n", (char*)uncompr); } pos = gzseek(file, -8L, SEEK_CUR); if (pos != 6 || gztell(file) != pos) { fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n", (long)pos, (long)gztell(file)); exit(1); } if (gzgetc(file) != ' ') { fprintf(stderr, "gzgetc error\n"); exit(1); } if (gzungetc(' ', file) != ' ') { fprintf(stderr, "gzungetc error\n"); exit(1); } gzgets(file, (char*)uncompr, (int)uncomprLen); if (strlen((char*)uncompr) != 7) { /* " hello!" */ fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err)); exit(1); } if (strcmp((char*)uncompr, hello + 6)) { fprintf(stderr, "bad gzgets after gzseek\n"); exit(1); } else { printf("gzgets() after gzseek: %s\n", (char*)uncompr); } gzclose(file); #endif } /* =========================================================================== * Test deflate() with small buffers */ void test_deflate(compr, comprLen) Byte *compr; uLong comprLen; { z_stream c_stream; /* compression stream */ int err; uLong len = (uLong)strlen(hello)+1; c_stream.zalloc = (alloc_func)0; c_stream.zfree = (free_func)0; c_stream.opaque = (voidpf)0; err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); CHECK_ERR(err, "deflateInit"); c_stream.next_in = (Bytef*)hello; c_stream.next_out = compr; while (c_stream.total_in != len && c_stream.total_out < comprLen) { c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ err = deflate(&c_stream, Z_NO_FLUSH); CHECK_ERR(err, "deflate"); } /* Finish the stream, still forcing small buffers: */ for (;;) { c_stream.avail_out = 1; err = deflate(&c_stream, Z_FINISH); if (err == Z_STREAM_END) break; CHECK_ERR(err, "deflate"); } err = deflateEnd(&c_stream); CHECK_ERR(err, "deflateEnd"); } /* =========================================================================== * Test inflate() with small buffers */ void test_inflate(compr, comprLen, uncompr, uncomprLen) Byte *compr, *uncompr; uLong comprLen, uncomprLen; { int err; z_stream d_stream; /* decompression stream */ strcpy((char*)uncompr, "garbage"); d_stream.zalloc = (alloc_func)0; d_stream.zfree = (free_func)0; d_stream.opaque = (voidpf)0; d_stream.next_in = compr; d_stream.avail_in = 0; d_stream.next_out = uncompr; err = inflateInit(&d_stream); CHECK_ERR(err, "inflateInit"); while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) { d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */ err = inflate(&d_stream, Z_NO_FLUSH); if (err == Z_STREAM_END) break; CHECK_ERR(err, "inflate"); } err = inflateEnd(&d_stream); CHECK_ERR(err, "inflateEnd"); if (strcmp((char*)uncompr, hello)) { fprintf(stderr, "bad inflate\n"); exit(1); } else { printf("inflate(): %s\n", (char *)uncompr); } } /* =========================================================================== * Test deflate() with large buffers and dynamic change of compression level */ void test_large_deflate(compr, comprLen, uncompr, uncomprLen) Byte *compr, *uncompr; uLong comprLen, uncomprLen; { z_stream c_stream; /* compression stream */ int err; c_stream.zalloc = (alloc_func)0; c_stream.zfree = (free_func)0; c_stream.opaque = (voidpf)0; err = deflateInit(&c_stream, Z_BEST_SPEED); CHECK_ERR(err, "deflateInit"); c_stream.next_out = compr; c_stream.avail_out = (uInt)comprLen; /* At this point, uncompr is still mostly zeroes, so it should compress * very well: */ c_stream.next_in = uncompr; c_stream.avail_in = (uInt)uncomprLen; err = deflate(&c_stream, Z_NO_FLUSH); CHECK_ERR(err, "deflate"); if (c_stream.avail_in != 0) { fprintf(stderr, "deflate not greedy\n"); exit(1); } /* Feed in already compressed data and switch to no compression: */ deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY); c_stream.next_in = compr; c_stream.avail_in = (uInt)comprLen/2; err = deflate(&c_stream, Z_NO_FLUSH); CHECK_ERR(err, "deflate"); /* Switch back to compressing mode: */ deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED); c_stream.next_in = uncompr; c_stream.avail_in = (uInt)uncomprLen; err = deflate(&c_stream, Z_NO_FLUSH); CHECK_ERR(err, "deflate"); err = deflate(&c_stream, Z_FINISH); if (err != Z_STREAM_END) { fprintf(stderr, "deflate should report Z_STREAM_END\n"); exit(1); } err = deflateEnd(&c_stream); CHECK_ERR(err, "deflateEnd"); } /* =========================================================================== * Test inflate() with large buffers */ void test_large_inflate(compr, comprLen, uncompr, uncomprLen) Byte *compr, *uncompr; uLong comprLen, uncomprLen; { int err; z_stream d_stream; /* decompression stream */ strcpy((char*)uncompr, "garbage"); d_stream.zalloc = (alloc_func)0; d_stream.zfree = (free_func)0; d_stream.opaque = (voidpf)0; d_stream.next_in = compr; d_stream.avail_in = (uInt)comprLen; err = inflateInit(&d_stream); CHECK_ERR(err, "inflateInit"); for (;;) { d_stream.next_out = uncompr; /* discard the output */ d_stream.avail_out = (uInt)uncomprLen; err = inflate(&d_stream, Z_NO_FLUSH); if (err == Z_STREAM_END) break; CHECK_ERR(err, "large inflate"); } err = inflateEnd(&d_stream); CHECK_ERR(err, "inflateEnd"); if (d_stream.total_out != 2*uncomprLen + comprLen/2) { fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out); exit(1); } else { printf("large_inflate(): OK\n"); } } /* =========================================================================== * Test deflate() with full flush */ void test_flush(compr, comprLen) Byte *compr; uLong *comprLen; { z_stream c_stream; /* compression stream */ int err; uInt len = (uInt)strlen(hello)+1; c_stream.zalloc = (alloc_func)0; c_stream.zfree = (free_func)0; c_stream.opaque = (voidpf)0; err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); CHECK_ERR(err, "deflateInit"); c_stream.next_in = (Bytef*)hello; c_stream.next_out = compr; c_stream.avail_in = 3; c_stream.avail_out = (uInt)*comprLen; err = deflate(&c_stream, Z_FULL_FLUSH); CHECK_ERR(err, "deflate"); compr[3]++; /* force an error in first compressed block */ c_stream.avail_in = len - 3; err = deflate(&c_stream, Z_FINISH); if (err != Z_STREAM_END) { CHECK_ERR(err, "deflate"); } err = deflateEnd(&c_stream); CHECK_ERR(err, "deflateEnd"); *comprLen = c_stream.total_out; } /* =========================================================================== * Test inflateSync() */ void test_sync(compr, comprLen, uncompr, uncomprLen) Byte *compr, *uncompr; uLong comprLen, uncomprLen; { int err; z_stream d_stream; /* decompression stream */ strcpy((char*)uncompr, "garbage"); d_stream.zalloc = (alloc_func)0; d_stream.zfree = (free_func)0; d_stream.opaque = (voidpf)0; d_stream.next_in = compr; d_stream.avail_in = 2; /* just read the zlib header */ err = inflateInit(&d_stream); CHECK_ERR(err, "inflateInit"); d_stream.next_out = uncompr; d_stream.avail_out = (uInt)uncomprLen; inflate(&d_stream, Z_NO_FLUSH); CHECK_ERR(err, "inflate"); d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */ err = inflateSync(&d_stream); /* but skip the damaged part */ CHECK_ERR(err, "inflateSync"); err = inflate(&d_stream, Z_FINISH); if (err != Z_DATA_ERROR) { fprintf(stderr, "inflate should report DATA_ERROR\n"); /* Because of incorrect adler32 */ exit(1); } err = inflateEnd(&d_stream); CHECK_ERR(err, "inflateEnd"); printf("after inflateSync(): hel%s\n", (char *)uncompr); } /* =========================================================================== * Test deflate() with preset dictionary */ void test_dict_deflate(compr, comprLen) Byte *compr; uLong comprLen; { z_stream c_stream; /* compression stream */ int err; c_stream.zalloc = (alloc_func)0; c_stream.zfree = (free_func)0; c_stream.opaque = (voidpf)0; err = deflateInit(&c_stream, Z_BEST_COMPRESSION); CHECK_ERR(err, "deflateInit"); err = deflateSetDictionary(&c_stream, (const Bytef*)dictionary, sizeof(dictionary)); CHECK_ERR(err, "deflateSetDictionary"); dictId = c_stream.adler; c_stream.next_out = compr; c_stream.avail_out = (uInt)comprLen; c_stream.next_in = (Bytef*)hello; c_stream.avail_in = (uInt)strlen(hello)+1; err = deflate(&c_stream, Z_FINISH); if (err != Z_STREAM_END) { fprintf(stderr, "deflate should report Z_STREAM_END\n"); exit(1); } err = deflateEnd(&c_stream); CHECK_ERR(err, "deflateEnd"); } /* =========================================================================== * Test inflate() with a preset dictionary */ void test_dict_inflate(compr, comprLen, uncompr, uncomprLen) Byte *compr, *uncompr; uLong comprLen, uncomprLen; { int err; z_stream d_stream; /* decompression stream */ strcpy((char*)uncompr, "garbage"); d_stream.zalloc = (alloc_func)0; d_stream.zfree = (free_func)0; d_stream.opaque = (voidpf)0; d_stream.next_in = compr; d_stream.avail_in = (uInt)comprLen; err = inflateInit(&d_stream); CHECK_ERR(err, "inflateInit"); d_stream.next_out = uncompr; d_stream.avail_out = (uInt)uncomprLen; for (;;) { err = inflate(&d_stream, Z_NO_FLUSH); if (err == Z_STREAM_END) break; if (err == Z_NEED_DICT) { if (d_stream.adler != dictId) { fprintf(stderr, "unexpected dictionary"); exit(1); } err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary, sizeof(dictionary)); } CHECK_ERR(err, "inflate with dict"); } err = inflateEnd(&d_stream); CHECK_ERR(err, "inflateEnd"); if (strcmp((char*)uncompr, hello)) { fprintf(stderr, "bad inflate with dict\n"); exit(1); } else { printf("inflate with dictionary: %s\n", (char *)uncompr); } } /* =========================================================================== * Usage: example [output.gz [input.gz]] */ int main(argc, argv) int argc; char *argv[]; { Byte *compr, *uncompr; uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */ uLong uncomprLen = comprLen; static const char* myVersion = ZLIB_VERSION; if (zlibVersion()[0] != myVersion[0]) { fprintf(stderr, "incompatible zlib version\n"); exit(1); } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) { fprintf(stderr, "warning: different zlib version\n"); } printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n", ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags()); compr = (Byte*)calloc((uInt)comprLen, 1); uncompr = (Byte*)calloc((uInt)uncomprLen, 1); /* compr and uncompr are cleared to avoid reading uninitialized * data and to ensure that uncompr compresses well. */ if (compr == Z_NULL || uncompr == Z_NULL) { printf("out of memory\n"); exit(1); } test_compress(compr, comprLen, uncompr, uncomprLen); test_gzio((argc > 1 ? argv[1] : TESTFILE), uncompr, uncomprLen); test_deflate(compr, comprLen); test_inflate(compr, comprLen, uncompr, uncomprLen); test_large_deflate(compr, comprLen, uncompr, uncomprLen); test_large_inflate(compr, comprLen, uncompr, uncomprLen); test_flush(compr, &comprLen); test_sync(compr, comprLen, uncompr, uncomprLen); comprLen = uncomprLen; test_dict_deflate(compr, comprLen); test_dict_inflate(compr, comprLen, uncompr, uncomprLen); free(compr); free(uncompr); return 0; } gtkwave-3.3.66/src/libz/Makefile.am0000664000076400007640000000063611523063250016364 0ustar bybellbybell## -*- makefile -*- ## noinst_LIBRARIES= libz.a AM_CFLAGS= -DNO_VIZ libz_a_SOURCES= adler32.c deflate.h gzread.c inffixed.h trees.c zutil.c \ compress.c example.c gzwrite.c inflate.c trees.h zutil.h \ crc32.c gzclose.c infback.c inflate.h uncompr.c \ crc32.h gzguts.h inffast.c inftrees.c zconf.h \ deflate.c gzlib.c inffast.h inftrees.h zlib.h EXTRA_DIST= README gtkwave-3.3.66/src/libz/deflate.c0000664000076400007640000021346412235606635016120 0ustar bybellbybell/* deflate.c -- compress data using the deflation algorithm * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* * ALGORITHM * * The "deflation" process depends on being able to identify portions * of the input text which are identical to earlier input (within a * sliding window trailing behind the input currently being processed). * * The most straightforward technique turns out to be the fastest for * most input files: try all possible matches and select the longest. * The key feature of this algorithm is that insertions into the string * dictionary are very simple and thus fast, and deletions are avoided * completely. Insertions are performed at each input character, whereas * string matches are performed only when the previous match ends. So it * is preferable to spend more time in matches to allow very fast string * insertions and avoid deletions. The matching algorithm for small * strings is inspired from that of Rabin & Karp. A brute force approach * is used to find longer strings when a small match has been found. * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze * (by Leonid Broukhis). * A previous version of this file used a more sophisticated algorithm * (by Fiala and Greene) which is guaranteed to run in linear amortized * time, but has a larger average cost, uses more memory and is patented. * However the F&G algorithm may be faster for some highly redundant * files if the parameter max_chain_length (described below) is too large. * * ACKNOWLEDGEMENTS * * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and * I found it in 'freeze' written by Leonid Broukhis. * Thanks to many people for bug reports and testing. * * REFERENCES * * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". * Available in http://tools.ietf.org/html/rfc1951 * * A description of the Rabin and Karp algorithm is given in the book * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. * * Fiala,E.R., and Greene,D.H. * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 * */ /* @(#) $Id$ */ #include "deflate.h" const char deflate_copyright[] = " deflate 1.2.8 Copyright 1995-2013 Jean-loup Gailly and Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot include such an acknowledgment, I would appreciate that you keep this copyright string in the executable of your product. */ /* =========================================================================== * Function prototypes. */ typedef enum { need_more, /* block not completed, need more input or more output */ block_done, /* block flush performed */ finish_started, /* finish started, need only more output at next deflate */ finish_done /* finish done, accept no more input or output */ } block_state; typedef block_state (*compress_func) OF((deflate_state *s, int flush)); /* Compression function. Returns the block state after the call. */ local void fill_window OF((deflate_state *s)); local block_state deflate_stored OF((deflate_state *s, int flush)); local block_state deflate_fast OF((deflate_state *s, int flush)); #ifndef FASTEST local block_state deflate_slow OF((deflate_state *s, int flush)); #endif local block_state deflate_rle OF((deflate_state *s, int flush)); local block_state deflate_huff OF((deflate_state *s, int flush)); local void lm_init OF((deflate_state *s)); local void putShortMSB OF((deflate_state *s, uInt b)); local void flush_pending OF((z_streamp strm)); local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); #ifdef ASMV void match_init OF((void)); /* asm code initialization */ uInt longest_match OF((deflate_state *s, IPos cur_match)); #else local uInt longest_match OF((deflate_state *s, IPos cur_match)); #endif #ifdef DEBUG local void check_match OF((deflate_state *s, IPos start, IPos match, int length)); #endif /* =========================================================================== * Local data */ #define NIL 0 /* Tail of hash chains */ #ifndef TOO_FAR # define TOO_FAR 4096 #endif /* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ /* Values for max_lazy_match, good_match and max_chain_length, depending on * the desired pack level (0..9). The values given below have been tuned to * exclude worst case performance for pathological files. Better values may be * found for specific files. */ typedef struct config_s { ush good_length; /* reduce lazy search above this match length */ ush max_lazy; /* do not perform lazy search above this match length */ ush nice_length; /* quit search above this match length */ ush max_chain; compress_func func; } config; #ifdef FASTEST local const config configuration_table[2] = { /* good lazy nice chain */ /* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ /* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ #else local const config configuration_table[10] = { /* good lazy nice chain */ /* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ /* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ /* 2 */ {4, 5, 16, 8, deflate_fast}, /* 3 */ {4, 6, 32, 32, deflate_fast}, /* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ /* 5 */ {8, 16, 32, 32, deflate_slow}, /* 6 */ {8, 16, 128, 128, deflate_slow}, /* 7 */ {8, 32, 128, 256, deflate_slow}, /* 8 */ {32, 128, 258, 1024, deflate_slow}, /* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ #endif /* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 * For deflate_fast() (levels <= 3) good is ignored and lazy has a different * meaning. */ #define EQUAL 0 /* result of memcmp for equal strings */ #ifndef NO_DUMMY_DECL struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ #endif /* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */ #define RANK(f) (((f) << 1) - ((f) > 4 ? 9 : 0)) /* =========================================================================== * Update a hash value with the given input byte * IN assertion: all calls to to UPDATE_HASH are made with consecutive * input characters, so that a running hash key can be computed from the * previous key instead of complete recalculation each time. */ #define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) /* =========================================================================== * Insert string str in the dictionary and set match_head to the previous head * of the hash chain (the most recent string with same hash key). Return * the previous length of the hash chain. * If this file is compiled with -DFASTEST, the compression level is forced * to 1, and no hash chains are maintained. * IN assertion: all calls to to INSERT_STRING are made with consecutive * input characters and the first MIN_MATCH bytes of str are valid * (except for the last MIN_MATCH-1 bytes of the input file). */ #ifdef FASTEST #define INSERT_STRING(s, str, match_head) \ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ match_head = s->head[s->ins_h], \ s->head[s->ins_h] = (Pos)(str)) #else #define INSERT_STRING(s, str, match_head) \ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ s->head[s->ins_h] = (Pos)(str)) #endif /* =========================================================================== * Initialize the hash table (avoiding 64K overflow for 16 bit systems). * prev[] will be initialized on the fly. */ #define CLEAR_HASH(s) \ s->head[s->hash_size-1] = NIL; \ zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); /* ========================================================================= */ int ZEXPORT deflateInit_(strm, level, version, stream_size) z_streamp strm; int level; const char *version; int stream_size; { return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, version, stream_size); /* To do: ignore strm->next_in if we use it as window */ } /* ========================================================================= */ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, version, stream_size) z_streamp strm; int level; int method; int windowBits; int memLevel; int strategy; const char *version; int stream_size; { deflate_state *s; int wrap = 1; static const char my_version[] = ZLIB_VERSION; ushf *overlay; /* We overlay pending_buf and d_buf+l_buf. This works since the average * output size for (length,distance) codes is <= 24 bits. */ if (version == Z_NULL || version[0] != my_version[0] || stream_size != sizeof(z_stream)) { return Z_VERSION_ERROR; } if (strm == Z_NULL) return Z_STREAM_ERROR; strm->msg = Z_NULL; if (strm->zalloc == (alloc_func)0) { #ifdef Z_SOLO return Z_STREAM_ERROR; #else strm->zalloc = zcalloc; strm->opaque = (voidpf)0; #endif } if (strm->zfree == (free_func)0) #ifdef Z_SOLO return Z_STREAM_ERROR; #else strm->zfree = zcfree; #endif #ifdef FASTEST if (level != 0) level = 1; #else if (level == Z_DEFAULT_COMPRESSION) level = 6; #endif if (windowBits < 0) { /* suppress zlib wrapper */ wrap = 0; windowBits = -windowBits; } #ifdef GZIP else if (windowBits > 15) { wrap = 2; /* write gzip wrapper instead */ windowBits -= 16; } #endif if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { return Z_STREAM_ERROR; } if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); if (s == Z_NULL) return Z_MEM_ERROR; strm->state = (struct internal_state FAR *)s; s->strm = strm; s->wrap = wrap; s->gzhead = Z_NULL; s->w_bits = windowBits; s->w_size = 1 << s->w_bits; s->w_mask = s->w_size - 1; s->hash_bits = memLevel + 7; s->hash_size = 1 << s->hash_bits; s->hash_mask = s->hash_size - 1; s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); s->high_water = 0; /* nothing written to s->window yet */ s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); s->pending_buf = (uchf *) overlay; s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || s->pending_buf == Z_NULL) { s->status = FINISH_STATE; strm->msg = ERR_MSG(Z_MEM_ERROR); deflateEnd (strm); return Z_MEM_ERROR; } s->d_buf = overlay + s->lit_bufsize/sizeof(ush); s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; s->level = level; s->strategy = strategy; s->method = (Byte)method; return deflateReset(strm); } /* ========================================================================= */ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) z_streamp strm; const Bytef *dictionary; uInt dictLength; { deflate_state *s; uInt str, n; int wrap; unsigned avail; z_const unsigned char *next; if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL) return Z_STREAM_ERROR; s = strm->state; wrap = s->wrap; if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead) return Z_STREAM_ERROR; /* when using zlib wrappers, compute Adler-32 for provided dictionary */ if (wrap == 1) strm->adler = adler32(strm->adler, dictionary, dictLength); s->wrap = 0; /* avoid computing Adler-32 in read_buf */ /* if dictionary would fill window, just replace the history */ if (dictLength >= s->w_size) { if (wrap == 0) { /* already empty otherwise */ CLEAR_HASH(s); s->strstart = 0; s->block_start = 0L; s->insert = 0; } dictionary += dictLength - s->w_size; /* use the tail */ dictLength = s->w_size; } /* insert dictionary into window and hash */ avail = strm->avail_in; next = strm->next_in; strm->avail_in = dictLength; strm->next_in = (z_const Bytef *)dictionary; fill_window(s); while (s->lookahead >= MIN_MATCH) { str = s->strstart; n = s->lookahead - (MIN_MATCH-1); do { UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); #ifndef FASTEST s->prev[str & s->w_mask] = s->head[s->ins_h]; #endif s->head[s->ins_h] = (Pos)str; str++; } while (--n); s->strstart = str; s->lookahead = MIN_MATCH-1; fill_window(s); } s->strstart += s->lookahead; s->block_start = (long)s->strstart; s->insert = s->lookahead; s->lookahead = 0; s->match_length = s->prev_length = MIN_MATCH-1; s->match_available = 0; strm->next_in = next; strm->avail_in = avail; s->wrap = wrap; return Z_OK; } /* ========================================================================= */ int ZEXPORT deflateResetKeep (strm) z_streamp strm; { deflate_state *s; if (strm == Z_NULL || strm->state == Z_NULL || strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { return Z_STREAM_ERROR; } strm->total_in = strm->total_out = 0; strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ strm->data_type = Z_UNKNOWN; s = (deflate_state *)strm->state; s->pending = 0; s->pending_out = s->pending_buf; if (s->wrap < 0) { s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ } s->status = s->wrap ? INIT_STATE : BUSY_STATE; strm->adler = #ifdef GZIP s->wrap == 2 ? crc32(0L, Z_NULL, 0) : #endif adler32(0L, Z_NULL, 0); s->last_flush = Z_NO_FLUSH; _tr_init(s); return Z_OK; } /* ========================================================================= */ int ZEXPORT deflateReset (strm) z_streamp strm; { int ret; ret = deflateResetKeep(strm); if (ret == Z_OK) lm_init(strm->state); return ret; } /* ========================================================================= */ int ZEXPORT deflateSetHeader (strm, head) z_streamp strm; gz_headerp head; { if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; if (strm->state->wrap != 2) return Z_STREAM_ERROR; strm->state->gzhead = head; return Z_OK; } /* ========================================================================= */ int ZEXPORT deflatePending (strm, pending, bits) unsigned *pending; int *bits; z_streamp strm; { if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; if (pending != Z_NULL) *pending = strm->state->pending; if (bits != Z_NULL) *bits = strm->state->bi_valid; return Z_OK; } /* ========================================================================= */ int ZEXPORT deflatePrime (strm, bits, value) z_streamp strm; int bits; int value; { deflate_state *s; int put; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; s = strm->state; if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3)) return Z_BUF_ERROR; do { put = Buf_size - s->bi_valid; if (put > bits) put = bits; s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid); s->bi_valid += put; _tr_flush_bits(s); value >>= put; bits -= put; } while (bits); return Z_OK; } /* ========================================================================= */ int ZEXPORT deflateParams(strm, level, strategy) z_streamp strm; int level; int strategy; { deflate_state *s; compress_func func; int err = Z_OK; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; s = strm->state; #ifdef FASTEST if (level != 0) level = 1; #else if (level == Z_DEFAULT_COMPRESSION) level = 6; #endif if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { return Z_STREAM_ERROR; } func = configuration_table[s->level].func; if ((strategy != s->strategy || func != configuration_table[level].func) && strm->total_in != 0) { /* Flush the last buffer: */ err = deflate(strm, Z_BLOCK); if (err == Z_BUF_ERROR && s->pending == 0) err = Z_OK; } if (s->level != level) { s->level = level; s->max_lazy_match = configuration_table[level].max_lazy; s->good_match = configuration_table[level].good_length; s->nice_match = configuration_table[level].nice_length; s->max_chain_length = configuration_table[level].max_chain; } s->strategy = strategy; return err; } /* ========================================================================= */ int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) z_streamp strm; int good_length; int max_lazy; int nice_length; int max_chain; { deflate_state *s; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; s = strm->state; s->good_match = good_length; s->max_lazy_match = max_lazy; s->nice_match = nice_length; s->max_chain_length = max_chain; return Z_OK; } /* ========================================================================= * For the default windowBits of 15 and memLevel of 8, this function returns * a close to exact, as well as small, upper bound on the compressed size. * They are coded as constants here for a reason--if the #define's are * changed, then this function needs to be changed as well. The return * value for 15 and 8 only works for those exact settings. * * For any setting other than those defaults for windowBits and memLevel, * the value returned is a conservative worst case for the maximum expansion * resulting from using fixed blocks instead of stored blocks, which deflate * can emit on compressed data for some combinations of the parameters. * * This function could be more sophisticated to provide closer upper bounds for * every combination of windowBits and memLevel. But even the conservative * upper bound of about 14% expansion does not seem onerous for output buffer * allocation. */ uLong ZEXPORT deflateBound(strm, sourceLen) z_streamp strm; uLong sourceLen; { deflate_state *s; uLong complen, wraplen; Bytef *str; /* conservative upper bound for compressed data */ complen = sourceLen + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; /* if can't get parameters, return conservative bound plus zlib wrapper */ if (strm == Z_NULL || strm->state == Z_NULL) return complen + 6; /* compute wrapper length */ s = strm->state; switch (s->wrap) { case 0: /* raw deflate */ wraplen = 0; break; case 1: /* zlib wrapper */ wraplen = 6 + (s->strstart ? 4 : 0); break; case 2: /* gzip wrapper */ wraplen = 18; if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ if (s->gzhead->extra != Z_NULL) wraplen += 2 + s->gzhead->extra_len; str = s->gzhead->name; if (str != Z_NULL) do { wraplen++; } while (*str++); str = s->gzhead->comment; if (str != Z_NULL) do { wraplen++; } while (*str++); if (s->gzhead->hcrc) wraplen += 2; } break; default: /* for compiler happiness */ wraplen = 6; } /* if not default parameters, return conservative bound */ if (s->w_bits != 15 || s->hash_bits != 8 + 7) return complen + wraplen; /* default settings: return tight bound for that case */ return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + (sourceLen >> 25) + 13 - 6 + wraplen; } /* ========================================================================= * Put a short in the pending buffer. The 16-bit value is put in MSB order. * IN assertion: the stream state is correct and there is enough room in * pending_buf. */ local void putShortMSB (s, b) deflate_state *s; uInt b; { put_byte(s, (Byte)(b >> 8)); put_byte(s, (Byte)(b & 0xff)); } /* ========================================================================= * Flush as much pending output as possible. All deflate() output goes * through this function so some applications may wish to modify it * to avoid allocating a large strm->next_out buffer and copying into it. * (See also read_buf()). */ local void flush_pending(strm) z_streamp strm; { unsigned len; deflate_state *s = strm->state; _tr_flush_bits(s); len = s->pending; if (len > strm->avail_out) len = strm->avail_out; if (len == 0) return; zmemcpy(strm->next_out, s->pending_out, len); strm->next_out += len; s->pending_out += len; strm->total_out += len; strm->avail_out -= len; s->pending -= len; if (s->pending == 0) { s->pending_out = s->pending_buf; } } /* ========================================================================= */ int ZEXPORT deflate (strm, flush) z_streamp strm; int flush; { int old_flush; /* value of flush param for previous deflate call */ deflate_state *s; if (strm == Z_NULL || strm->state == Z_NULL || flush > Z_BLOCK || flush < 0) { return Z_STREAM_ERROR; } s = strm->state; if (strm->next_out == Z_NULL || (strm->next_in == Z_NULL && strm->avail_in != 0) || (s->status == FINISH_STATE && flush != Z_FINISH)) { ERR_RETURN(strm, Z_STREAM_ERROR); } if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); s->strm = strm; /* just in case */ old_flush = s->last_flush; s->last_flush = flush; /* Write the header */ if (s->status == INIT_STATE) { #ifdef GZIP if (s->wrap == 2) { strm->adler = crc32(0L, Z_NULL, 0); put_byte(s, 31); put_byte(s, 139); put_byte(s, 8); if (s->gzhead == Z_NULL) { put_byte(s, 0); put_byte(s, 0); put_byte(s, 0); put_byte(s, 0); put_byte(s, 0); put_byte(s, s->level == 9 ? 2 : (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? 4 : 0)); put_byte(s, OS_CODE); s->status = BUSY_STATE; } else { put_byte(s, (s->gzhead->text ? 1 : 0) + (s->gzhead->hcrc ? 2 : 0) + (s->gzhead->extra == Z_NULL ? 0 : 4) + (s->gzhead->name == Z_NULL ? 0 : 8) + (s->gzhead->comment == Z_NULL ? 0 : 16) ); put_byte(s, (Byte)(s->gzhead->time & 0xff)); put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); put_byte(s, s->level == 9 ? 2 : (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? 4 : 0)); put_byte(s, s->gzhead->os & 0xff); if (s->gzhead->extra != Z_NULL) { put_byte(s, s->gzhead->extra_len & 0xff); put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); } if (s->gzhead->hcrc) strm->adler = crc32(strm->adler, s->pending_buf, s->pending); s->gzindex = 0; s->status = EXTRA_STATE; } } else #endif { uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; uInt level_flags; if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) level_flags = 0; else if (s->level < 6) level_flags = 1; else if (s->level == 6) level_flags = 2; else level_flags = 3; header |= (level_flags << 6); if (s->strstart != 0) header |= PRESET_DICT; header += 31 - (header % 31); s->status = BUSY_STATE; putShortMSB(s, header); /* Save the adler32 of the preset dictionary: */ if (s->strstart != 0) { putShortMSB(s, (uInt)(strm->adler >> 16)); putShortMSB(s, (uInt)(strm->adler & 0xffff)); } strm->adler = adler32(0L, Z_NULL, 0); } } #ifdef GZIP if (s->status == EXTRA_STATE) { if (s->gzhead->extra != Z_NULL) { uInt beg = s->pending; /* start of bytes to update crc */ while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { if (s->pending == s->pending_buf_size) { if (s->gzhead->hcrc && s->pending > beg) strm->adler = crc32(strm->adler, s->pending_buf + beg, s->pending - beg); flush_pending(strm); beg = s->pending; if (s->pending == s->pending_buf_size) break; } put_byte(s, s->gzhead->extra[s->gzindex]); s->gzindex++; } if (s->gzhead->hcrc && s->pending > beg) strm->adler = crc32(strm->adler, s->pending_buf + beg, s->pending - beg); if (s->gzindex == s->gzhead->extra_len) { s->gzindex = 0; s->status = NAME_STATE; } } else s->status = NAME_STATE; } if (s->status == NAME_STATE) { if (s->gzhead->name != Z_NULL) { uInt beg = s->pending; /* start of bytes to update crc */ int val; do { if (s->pending == s->pending_buf_size) { if (s->gzhead->hcrc && s->pending > beg) strm->adler = crc32(strm->adler, s->pending_buf + beg, s->pending - beg); flush_pending(strm); beg = s->pending; if (s->pending == s->pending_buf_size) { val = 1; break; } } val = s->gzhead->name[s->gzindex++]; put_byte(s, val); } while (val != 0); if (s->gzhead->hcrc && s->pending > beg) strm->adler = crc32(strm->adler, s->pending_buf + beg, s->pending - beg); if (val == 0) { s->gzindex = 0; s->status = COMMENT_STATE; } } else s->status = COMMENT_STATE; } if (s->status == COMMENT_STATE) { if (s->gzhead->comment != Z_NULL) { uInt beg = s->pending; /* start of bytes to update crc */ int val; do { if (s->pending == s->pending_buf_size) { if (s->gzhead->hcrc && s->pending > beg) strm->adler = crc32(strm->adler, s->pending_buf + beg, s->pending - beg); flush_pending(strm); beg = s->pending; if (s->pending == s->pending_buf_size) { val = 1; break; } } val = s->gzhead->comment[s->gzindex++]; put_byte(s, val); } while (val != 0); if (s->gzhead->hcrc && s->pending > beg) strm->adler = crc32(strm->adler, s->pending_buf + beg, s->pending - beg); if (val == 0) s->status = HCRC_STATE; } else s->status = HCRC_STATE; } if (s->status == HCRC_STATE) { if (s->gzhead->hcrc) { if (s->pending + 2 > s->pending_buf_size) flush_pending(strm); if (s->pending + 2 <= s->pending_buf_size) { put_byte(s, (Byte)(strm->adler & 0xff)); put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); strm->adler = crc32(0L, Z_NULL, 0); s->status = BUSY_STATE; } } else s->status = BUSY_STATE; } #endif /* Flush as much pending output as possible */ if (s->pending != 0) { flush_pending(strm); if (strm->avail_out == 0) { /* Since avail_out is 0, deflate will be called again with * more output space, but possibly with both pending and * avail_in equal to zero. There won't be anything to do, * but this is not an error situation so make sure we * return OK instead of BUF_ERROR at next call of deflate: */ s->last_flush = -1; return Z_OK; } /* Make sure there is something to do and avoid duplicate consecutive * flushes. For repeated and useless calls with Z_FINISH, we keep * returning Z_STREAM_END instead of Z_BUF_ERROR. */ } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && flush != Z_FINISH) { ERR_RETURN(strm, Z_BUF_ERROR); } /* User must not provide more input after the first FINISH: */ if (s->status == FINISH_STATE && strm->avail_in != 0) { ERR_RETURN(strm, Z_BUF_ERROR); } /* Start a new block or continue the current one. */ if (strm->avail_in != 0 || s->lookahead != 0 || (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { block_state bstate; bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : (s->strategy == Z_RLE ? deflate_rle(s, flush) : (*(configuration_table[s->level].func))(s, flush)); if (bstate == finish_started || bstate == finish_done) { s->status = FINISH_STATE; } if (bstate == need_more || bstate == finish_started) { if (strm->avail_out == 0) { s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ } return Z_OK; /* If flush != Z_NO_FLUSH && avail_out == 0, the next call * of deflate should use the same flush parameter to make sure * that the flush is complete. So we don't have to output an * empty block here, this will be done at next call. This also * ensures that for a very small output buffer, we emit at most * one empty block. */ } if (bstate == block_done) { if (flush == Z_PARTIAL_FLUSH) { _tr_align(s); } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ _tr_stored_block(s, (char*)0, 0L, 0); /* For a full flush, this empty block will be recognized * as a special marker by inflate_sync(). */ if (flush == Z_FULL_FLUSH) { CLEAR_HASH(s); /* forget history */ if (s->lookahead == 0) { s->strstart = 0; s->block_start = 0L; s->insert = 0; } } } flush_pending(strm); if (strm->avail_out == 0) { s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ return Z_OK; } } } Assert(strm->avail_out > 0, "bug2"); if (flush != Z_FINISH) return Z_OK; if (s->wrap <= 0) return Z_STREAM_END; /* Write the trailer */ #ifdef GZIP if (s->wrap == 2) { put_byte(s, (Byte)(strm->adler & 0xff)); put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); put_byte(s, (Byte)(strm->total_in & 0xff)); put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); } else #endif { putShortMSB(s, (uInt)(strm->adler >> 16)); putShortMSB(s, (uInt)(strm->adler & 0xffff)); } flush_pending(strm); /* If avail_out is zero, the application will call deflate again * to flush the rest. */ if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ return s->pending != 0 ? Z_OK : Z_STREAM_END; } /* ========================================================================= */ int ZEXPORT deflateEnd (strm) z_streamp strm; { int status; if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; status = strm->state->status; if (status != INIT_STATE && status != EXTRA_STATE && status != NAME_STATE && status != COMMENT_STATE && status != HCRC_STATE && status != BUSY_STATE && status != FINISH_STATE) { return Z_STREAM_ERROR; } /* Deallocate in reverse order of allocations: */ TRY_FREE(strm, strm->state->pending_buf); TRY_FREE(strm, strm->state->head); TRY_FREE(strm, strm->state->prev); TRY_FREE(strm, strm->state->window); ZFREE(strm, strm->state); strm->state = Z_NULL; return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; } /* ========================================================================= * Copy the source state to the destination state. * To simplify the source, this is not supported for 16-bit MSDOS (which * doesn't have enough memory anyway to duplicate compression states). */ int ZEXPORT deflateCopy (dest, source) z_streamp dest; z_streamp source; { #ifdef MAXSEG_64K return Z_STREAM_ERROR; #else deflate_state *ds; deflate_state *ss; ushf *overlay; if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { return Z_STREAM_ERROR; } ss = source->state; zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); if (ds == Z_NULL) return Z_MEM_ERROR; dest->state = (struct internal_state FAR *) ds; zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state)); ds->strm = dest; ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); ds->pending_buf = (uchf *) overlay; if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || ds->pending_buf == Z_NULL) { deflateEnd (dest); return Z_MEM_ERROR; } /* following zmemcpy do not work for 16-bit MSDOS */ zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos)); zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos)); zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; ds->l_desc.dyn_tree = ds->dyn_ltree; ds->d_desc.dyn_tree = ds->dyn_dtree; ds->bl_desc.dyn_tree = ds->bl_tree; return Z_OK; #endif /* MAXSEG_64K */ } /* =========================================================================== * Read a new buffer from the current input stream, update the adler32 * and total number of bytes read. All deflate() input goes through * this function so some applications may wish to modify it to avoid * allocating a large strm->next_in buffer and copying from it. * (See also flush_pending()). */ local int read_buf(strm, buf, size) z_streamp strm; Bytef *buf; unsigned size; { unsigned len = strm->avail_in; if (len > size) len = size; if (len == 0) return 0; strm->avail_in -= len; zmemcpy(buf, strm->next_in, len); if (strm->state->wrap == 1) { strm->adler = adler32(strm->adler, buf, len); } #ifdef GZIP else if (strm->state->wrap == 2) { strm->adler = crc32(strm->adler, buf, len); } #endif strm->next_in += len; strm->total_in += len; return (int)len; } /* =========================================================================== * Initialize the "longest match" routines for a new zlib stream */ local void lm_init (s) deflate_state *s; { s->window_size = (ulg)2L*s->w_size; CLEAR_HASH(s); /* Set the default configuration parameters: */ s->max_lazy_match = configuration_table[s->level].max_lazy; s->good_match = configuration_table[s->level].good_length; s->nice_match = configuration_table[s->level].nice_length; s->max_chain_length = configuration_table[s->level].max_chain; s->strstart = 0; s->block_start = 0L; s->lookahead = 0; s->insert = 0; s->match_length = s->prev_length = MIN_MATCH-1; s->match_available = 0; s->ins_h = 0; #ifndef FASTEST #ifdef ASMV match_init(); /* initialize the asm code */ #endif #endif } #ifndef FASTEST /* =========================================================================== * Set match_start to the longest match starting at the given string and * return its length. Matches shorter or equal to prev_length are discarded, * in which case the result is equal to prev_length and match_start is * garbage. * IN assertions: cur_match is the head of the hash chain for the current * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 * OUT assertion: the match length is not greater than s->lookahead. */ #ifndef ASMV /* For 80x86 and 680x0, an optimized version will be provided in match.asm or * match.S. The code will be functionally equivalent. */ local uInt longest_match(s, cur_match) deflate_state *s; IPos cur_match; /* current match */ { unsigned chain_length = s->max_chain_length;/* max hash chain length */ register Bytef *scan = s->window + s->strstart; /* current string */ register Bytef *match; /* matched string */ register int len; /* length of current match */ int best_len = s->prev_length; /* best match length so far */ int nice_match = s->nice_match; /* stop if match long enough */ IPos limit = s->strstart > (IPos)MAX_DIST(s) ? s->strstart - (IPos)MAX_DIST(s) : NIL; /* Stop when cur_match becomes <= limit. To simplify the code, * we prevent matches with the string of window index 0. */ Posf *prev = s->prev; uInt wmask = s->w_mask; #ifdef UNALIGNED_OK /* Compare two bytes at a time. Note: this is not always beneficial. * Try with and without -DUNALIGNED_OK to check. */ register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; register ush scan_start = *(ushf*)scan; register ush scan_end = *(ushf*)(scan+best_len-1); #else register Bytef *strend = s->window + s->strstart + MAX_MATCH; register Byte scan_end1 = scan[best_len-1]; register Byte scan_end = scan[best_len]; #endif /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. * It is easy to get rid of this optimization if necessary. */ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); /* Do not waste too much time if we already have a good match: */ if (s->prev_length >= s->good_match) { chain_length >>= 2; } /* Do not look for matches beyond the end of the input. This is necessary * to make deflate deterministic. */ if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); do { Assert(cur_match < s->strstart, "no future"); match = s->window + cur_match; /* Skip to next match if the match length cannot increase * or if the match length is less than 2. Note that the checks below * for insufficient lookahead only occur occasionally for performance * reasons. Therefore uninitialized memory will be accessed, and * conditional jumps will be made that depend on those values. * However the length of the match is limited to the lookahead, so * the output of deflate is not affected by the uninitialized values. */ #if (defined(UNALIGNED_OK) && MAX_MATCH == 258) /* This code assumes sizeof(unsigned short) == 2. Do not use * UNALIGNED_OK if your compiler uses a different size. */ if (*(ushf*)(match+best_len-1) != scan_end || *(ushf*)match != scan_start) continue; /* It is not necessary to compare scan[2] and match[2] since they are * always equal when the other bytes match, given that the hash keys * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at * strstart+3, +5, ... up to strstart+257. We check for insufficient * lookahead only every 4th comparison; the 128th check will be made * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is * necessary to put more guard bytes at the end of the window, or * to check more often for insufficient lookahead. */ Assert(scan[2] == match[2], "scan[2]?"); scan++, match++; do { } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && *(ushf*)(scan+=2) == *(ushf*)(match+=2) && *(ushf*)(scan+=2) == *(ushf*)(match+=2) && *(ushf*)(scan+=2) == *(ushf*)(match+=2) && scan < strend); /* The funny "do {}" generates better code on most compilers */ /* Here, scan <= window+strstart+257 */ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); if (*scan == *match) scan++; len = (MAX_MATCH - 1) - (int)(strend-scan); scan = strend - (MAX_MATCH-1); #else /* UNALIGNED_OK */ if (match[best_len] != scan_end || match[best_len-1] != scan_end1 || *match != *scan || *++match != scan[1]) continue; /* The check at best_len-1 can be removed because it will be made * again later. (This heuristic is not always a win.) * It is not necessary to compare scan[2] and match[2] since they * are always equal when the other bytes match, given that * the hash keys are equal and that HASH_BITS >= 8. */ scan += 2, match++; Assert(*scan == *match, "match[2]?"); /* We check for insufficient lookahead only every 8th comparison; * the 256th check will be made at strstart+258. */ do { } while (*++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && scan < strend); Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); len = MAX_MATCH - (int)(strend - scan); scan = strend - MAX_MATCH; #endif /* UNALIGNED_OK */ if (len > best_len) { s->match_start = cur_match; best_len = len; if (len >= nice_match) break; #ifdef UNALIGNED_OK scan_end = *(ushf*)(scan+best_len-1); #else scan_end1 = scan[best_len-1]; scan_end = scan[best_len]; #endif } } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length != 0); if ((uInt)best_len <= s->lookahead) return (uInt)best_len; return s->lookahead; } #endif /* ASMV */ #else /* FASTEST */ /* --------------------------------------------------------------------------- * Optimized version for FASTEST only */ local uInt longest_match(s, cur_match) deflate_state *s; IPos cur_match; /* current match */ { register Bytef *scan = s->window + s->strstart; /* current string */ register Bytef *match; /* matched string */ register int len; /* length of current match */ register Bytef *strend = s->window + s->strstart + MAX_MATCH; /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. * It is easy to get rid of this optimization if necessary. */ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); Assert(cur_match < s->strstart, "no future"); match = s->window + cur_match; /* Return failure if the match length is less than 2: */ if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; /* The check at best_len-1 can be removed because it will be made * again later. (This heuristic is not always a win.) * It is not necessary to compare scan[2] and match[2] since they * are always equal when the other bytes match, given that * the hash keys are equal and that HASH_BITS >= 8. */ scan += 2, match += 2; Assert(*scan == *match, "match[2]?"); /* We check for insufficient lookahead only every 8th comparison; * the 256th check will be made at strstart+258. */ do { } while (*++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && scan < strend); Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); len = MAX_MATCH - (int)(strend - scan); if (len < MIN_MATCH) return MIN_MATCH - 1; s->match_start = cur_match; return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; } #endif /* FASTEST */ #ifdef DEBUG /* =========================================================================== * Check that the match at match_start is indeed a match. */ local void check_match(s, start, match, length) deflate_state *s; IPos start, match; int length; { /* check that the match is indeed a match */ if (zmemcmp(s->window + match, s->window + start, length) != EQUAL) { fprintf(stderr, " start %u, match %u, length %d\n", start, match, length); do { fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); } while (--length != 0); z_error("invalid match"); } if (z_verbose > 1) { fprintf(stderr,"\\[%d,%d]", start-match, length); do { putc(s->window[start++], stderr); } while (--length != 0); } } #else # define check_match(s, start, match, length) #endif /* DEBUG */ /* =========================================================================== * Fill the window when the lookahead becomes insufficient. * Updates strstart and lookahead. * * IN assertion: lookahead < MIN_LOOKAHEAD * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD * At least one byte has been read, or avail_in == 0; reads are * performed for at least two bytes (required for the zip translate_eol * option -- not supported here). */ local void fill_window(s) deflate_state *s; { register unsigned n, m; register Posf *p; unsigned more; /* Amount of free space at the end of the window. */ uInt wsize = s->w_size; Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); do { more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); /* Deal with !@#$% 64K limit: */ if (sizeof(int) <= 2) { if (more == 0 && s->strstart == 0 && s->lookahead == 0) { more = wsize; } else if (more == (unsigned)(-1)) { /* Very unlikely, but possible on 16 bit machine if * strstart == 0 && lookahead == 1 (input done a byte at time) */ more--; } } /* If the window is almost full and there is insufficient lookahead, * move the upper half to the lower one to make room in the upper half. */ if (s->strstart >= wsize+MAX_DIST(s)) { zmemcpy(s->window, s->window+wsize, (unsigned)wsize); s->match_start -= wsize; s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ s->block_start -= (long) wsize; /* Slide the hash table (could be avoided with 32 bit values at the expense of memory usage). We slide even when level == 0 to keep the hash table consistent if we switch back to level > 0 later. (Using level 0 permanently is not an optimal usage of zlib, so we don't care about this pathological case.) */ n = s->hash_size; p = &s->head[n]; do { m = *--p; *p = (Pos)(m >= wsize ? m-wsize : NIL); } while (--n); n = wsize; #ifndef FASTEST p = &s->prev[n]; do { m = *--p; *p = (Pos)(m >= wsize ? m-wsize : NIL); /* If n is not on any hash chain, prev[n] is garbage but * its value will never be used. */ } while (--n); #endif more += wsize; } if (s->strm->avail_in == 0) break; /* If there was no sliding: * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && * more == window_size - lookahead - strstart * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) * => more >= window_size - 2*WSIZE + 2 * In the BIG_MEM or MMAP case (not yet supported), * window_size == input_size + MIN_LOOKAHEAD && * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. * Otherwise, window_size == 2*WSIZE so more >= 2. * If there was sliding, more >= WSIZE. So in all cases, more >= 2. */ Assert(more >= 2, "more < 2"); n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); s->lookahead += n; /* Initialize the hash value now that we have some input: */ if (s->lookahead + s->insert >= MIN_MATCH) { uInt str = s->strstart - s->insert; s->ins_h = s->window[str]; UPDATE_HASH(s, s->ins_h, s->window[str + 1]); #if MIN_MATCH != 3 Call UPDATE_HASH() MIN_MATCH-3 more times #endif while (s->insert) { UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); #ifndef FASTEST s->prev[str & s->w_mask] = s->head[s->ins_h]; #endif s->head[s->ins_h] = (Pos)str; str++; s->insert--; if (s->lookahead + s->insert < MIN_MATCH) break; } } /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, * but this is not important since only literal bytes will be emitted. */ } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); /* If the WIN_INIT bytes after the end of the current data have never been * written, then zero those bytes in order to avoid memory check reports of * the use of uninitialized (or uninitialised as Julian writes) bytes by * the longest match routines. Update the high water mark for the next * time through here. WIN_INIT is set to MAX_MATCH since the longest match * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. */ if (s->high_water < s->window_size) { ulg curr = s->strstart + (ulg)(s->lookahead); ulg init; if (s->high_water < curr) { /* Previous high water mark below current data -- zero WIN_INIT * bytes or up to end of window, whichever is less. */ init = s->window_size - curr; if (init > WIN_INIT) init = WIN_INIT; zmemzero(s->window + curr, (unsigned)init); s->high_water = curr + init; } else if (s->high_water < (ulg)curr + WIN_INIT) { /* High water mark at or above current data, but below current data * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up * to end of window, whichever is less. */ init = (ulg)curr + WIN_INIT - s->high_water; if (init > s->window_size - s->high_water) init = s->window_size - s->high_water; zmemzero(s->window + s->high_water, (unsigned)init); s->high_water += init; } } Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, "not enough room for search"); } /* =========================================================================== * Flush the current block, with given end-of-file flag. * IN assertion: strstart is set to the end of the current match. */ #define FLUSH_BLOCK_ONLY(s, last) { \ _tr_flush_block(s, (s->block_start >= 0L ? \ (charf *)&s->window[(unsigned)s->block_start] : \ (charf *)Z_NULL), \ (ulg)((long)s->strstart - s->block_start), \ (last)); \ s->block_start = s->strstart; \ flush_pending(s->strm); \ Tracev((stderr,"[FLUSH]")); \ } /* Same but force premature exit if necessary. */ #define FLUSH_BLOCK(s, last) { \ FLUSH_BLOCK_ONLY(s, last); \ if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ } /* =========================================================================== * Copy without compression as much as possible from the input stream, return * the current block state. * This function does not insert new strings in the dictionary since * uncompressible data is probably not useful. This function is used * only for the level=0 compression option. * NOTE: this function should be optimized to avoid extra copying from * window to pending_buf. */ local block_state deflate_stored(s, flush) deflate_state *s; int flush; { /* Stored blocks are limited to 0xffff bytes, pending_buf is limited * to pending_buf_size, and each stored block has a 5 byte header: */ ulg max_block_size = 0xffff; ulg max_start; if (max_block_size > s->pending_buf_size - 5) { max_block_size = s->pending_buf_size - 5; } /* Copy as much as possible from input to output: */ for (;;) { /* Fill the window as much as possible: */ if (s->lookahead <= 1) { Assert(s->strstart < s->w_size+MAX_DIST(s) || s->block_start >= (long)s->w_size, "slide too late"); fill_window(s); if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; if (s->lookahead == 0) break; /* flush the current block */ } Assert(s->block_start >= 0L, "block gone"); s->strstart += s->lookahead; s->lookahead = 0; /* Emit a stored block if pending_buf will be full: */ max_start = s->block_start + max_block_size; if (s->strstart == 0 || (ulg)s->strstart >= max_start) { /* strstart == 0 is possible when wraparound on 16-bit machine */ s->lookahead = (uInt)(s->strstart - max_start); s->strstart = (uInt)max_start; FLUSH_BLOCK(s, 0); } /* Flush if we may have to slide, otherwise block_start may become * negative and the data will be gone: */ if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { FLUSH_BLOCK(s, 0); } } s->insert = 0; if (flush == Z_FINISH) { FLUSH_BLOCK(s, 1); return finish_done; } if ((long)s->strstart > s->block_start) FLUSH_BLOCK(s, 0); return block_done; } /* =========================================================================== * Compress as much as possible from the input stream, return the current * block state. * This function does not perform lazy evaluation of matches and inserts * new strings in the dictionary only for unmatched strings or for short * matches. It is used only for the fast compression options. */ local block_state deflate_fast(s, flush) deflate_state *s; int flush; { IPos hash_head; /* head of the hash chain */ int bflush; /* set if current block must be flushed */ for (;;) { /* Make sure that we always have enough lookahead, except * at the end of the input file. We need MAX_MATCH bytes * for the next match, plus MIN_MATCH bytes to insert the * string following the next match. */ if (s->lookahead < MIN_LOOKAHEAD) { fill_window(s); if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { return need_more; } if (s->lookahead == 0) break; /* flush the current block */ } /* Insert the string window[strstart .. strstart+2] in the * dictionary, and set hash_head to the head of the hash chain: */ hash_head = NIL; if (s->lookahead >= MIN_MATCH) { INSERT_STRING(s, s->strstart, hash_head); } /* Find the longest match, discarding those <= prev_length. * At this point we have always match_length < MIN_MATCH */ if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { /* To simplify the code, we prevent matches with the string * of window index 0 (in particular we have to avoid a match * of the string with itself at the start of the input file). */ s->match_length = longest_match (s, hash_head); /* longest_match() sets match_start */ } if (s->match_length >= MIN_MATCH) { check_match(s, s->strstart, s->match_start, s->match_length); _tr_tally_dist(s, s->strstart - s->match_start, s->match_length - MIN_MATCH, bflush); s->lookahead -= s->match_length; /* Insert new strings in the hash table only if the match length * is not too large. This saves time but degrades compression. */ #ifndef FASTEST if (s->match_length <= s->max_insert_length && s->lookahead >= MIN_MATCH) { s->match_length--; /* string at strstart already in table */ do { s->strstart++; INSERT_STRING(s, s->strstart, hash_head); /* strstart never exceeds WSIZE-MAX_MATCH, so there are * always MIN_MATCH bytes ahead. */ } while (--s->match_length != 0); s->strstart++; } else #endif { s->strstart += s->match_length; s->match_length = 0; s->ins_h = s->window[s->strstart]; UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); #if MIN_MATCH != 3 Call UPDATE_HASH() MIN_MATCH-3 more times #endif /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not * matter since it will be recomputed at next deflate call. */ } } else { /* No match, output a literal byte */ Tracevv((stderr,"%c", s->window[s->strstart])); _tr_tally_lit (s, s->window[s->strstart], bflush); s->lookahead--; s->strstart++; } if (bflush) FLUSH_BLOCK(s, 0); } s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; if (flush == Z_FINISH) { FLUSH_BLOCK(s, 1); return finish_done; } if (s->last_lit) FLUSH_BLOCK(s, 0); return block_done; } #ifndef FASTEST /* =========================================================================== * Same as above, but achieves better compression. We use a lazy * evaluation for matches: a match is finally adopted only if there is * no better match at the next window position. */ local block_state deflate_slow(s, flush) deflate_state *s; int flush; { IPos hash_head; /* head of hash chain */ int bflush; /* set if current block must be flushed */ /* Process the input block. */ for (;;) { /* Make sure that we always have enough lookahead, except * at the end of the input file. We need MAX_MATCH bytes * for the next match, plus MIN_MATCH bytes to insert the * string following the next match. */ if (s->lookahead < MIN_LOOKAHEAD) { fill_window(s); if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { return need_more; } if (s->lookahead == 0) break; /* flush the current block */ } /* Insert the string window[strstart .. strstart+2] in the * dictionary, and set hash_head to the head of the hash chain: */ hash_head = NIL; if (s->lookahead >= MIN_MATCH) { INSERT_STRING(s, s->strstart, hash_head); } /* Find the longest match, discarding those <= prev_length. */ s->prev_length = s->match_length, s->prev_match = s->match_start; s->match_length = MIN_MATCH-1; if (hash_head != NIL && s->prev_length < s->max_lazy_match && s->strstart - hash_head <= MAX_DIST(s)) { /* To simplify the code, we prevent matches with the string * of window index 0 (in particular we have to avoid a match * of the string with itself at the start of the input file). */ s->match_length = longest_match (s, hash_head); /* longest_match() sets match_start */ if (s->match_length <= 5 && (s->strategy == Z_FILTERED #if TOO_FAR <= 32767 || (s->match_length == MIN_MATCH && s->strstart - s->match_start > TOO_FAR) #endif )) { /* If prev_match is also MIN_MATCH, match_start is garbage * but we will ignore the current match anyway. */ s->match_length = MIN_MATCH-1; } } /* If there was a match at the previous step and the current * match is not better, output the previous match: */ if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; /* Do not insert strings in hash table beyond this. */ check_match(s, s->strstart-1, s->prev_match, s->prev_length); _tr_tally_dist(s, s->strstart -1 - s->prev_match, s->prev_length - MIN_MATCH, bflush); /* Insert in hash table all strings up to the end of the match. * strstart-1 and strstart are already inserted. If there is not * enough lookahead, the last two strings are not inserted in * the hash table. */ s->lookahead -= s->prev_length-1; s->prev_length -= 2; do { if (++s->strstart <= max_insert) { INSERT_STRING(s, s->strstart, hash_head); } } while (--s->prev_length != 0); s->match_available = 0; s->match_length = MIN_MATCH-1; s->strstart++; if (bflush) FLUSH_BLOCK(s, 0); } else if (s->match_available) { /* If there was no match at the previous position, output a * single literal. If there was a match but the current match * is longer, truncate the previous match to a single literal. */ Tracevv((stderr,"%c", s->window[s->strstart-1])); _tr_tally_lit(s, s->window[s->strstart-1], bflush); if (bflush) { FLUSH_BLOCK_ONLY(s, 0); } s->strstart++; s->lookahead--; if (s->strm->avail_out == 0) return need_more; } else { /* There is no previous match to compare with, wait for * the next step to decide. */ s->match_available = 1; s->strstart++; s->lookahead--; } } Assert (flush != Z_NO_FLUSH, "no flush?"); if (s->match_available) { Tracevv((stderr,"%c", s->window[s->strstart-1])); _tr_tally_lit(s, s->window[s->strstart-1], bflush); s->match_available = 0; } s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; if (flush == Z_FINISH) { FLUSH_BLOCK(s, 1); return finish_done; } if (s->last_lit) FLUSH_BLOCK(s, 0); return block_done; } #endif /* FASTEST */ /* =========================================================================== * For Z_RLE, simply look for runs of bytes, generate matches only of distance * one. Do not maintain a hash table. (It will be regenerated if this run of * deflate switches away from Z_RLE.) */ local block_state deflate_rle(s, flush) deflate_state *s; int flush; { int bflush; /* set if current block must be flushed */ uInt prev; /* byte at distance one to match */ Bytef *scan, *strend; /* scan goes up to strend for length of run */ for (;;) { /* Make sure that we always have enough lookahead, except * at the end of the input file. We need MAX_MATCH bytes * for the longest run, plus one for the unrolled loop. */ if (s->lookahead <= MAX_MATCH) { fill_window(s); if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) { return need_more; } if (s->lookahead == 0) break; /* flush the current block */ } /* See how many times the previous byte repeats */ s->match_length = 0; if (s->lookahead >= MIN_MATCH && s->strstart > 0) { scan = s->window + s->strstart - 1; prev = *scan; if (prev == *++scan && prev == *++scan && prev == *++scan) { strend = s->window + s->strstart + MAX_MATCH; do { } while (prev == *++scan && prev == *++scan && prev == *++scan && prev == *++scan && prev == *++scan && prev == *++scan && prev == *++scan && prev == *++scan && scan < strend); s->match_length = MAX_MATCH - (int)(strend - scan); if (s->match_length > s->lookahead) s->match_length = s->lookahead; } Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); } /* Emit match if have run of MIN_MATCH or longer, else emit literal */ if (s->match_length >= MIN_MATCH) { check_match(s, s->strstart, s->strstart - 1, s->match_length); _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); s->lookahead -= s->match_length; s->strstart += s->match_length; s->match_length = 0; } else { /* No match, output a literal byte */ Tracevv((stderr,"%c", s->window[s->strstart])); _tr_tally_lit (s, s->window[s->strstart], bflush); s->lookahead--; s->strstart++; } if (bflush) FLUSH_BLOCK(s, 0); } s->insert = 0; if (flush == Z_FINISH) { FLUSH_BLOCK(s, 1); return finish_done; } if (s->last_lit) FLUSH_BLOCK(s, 0); return block_done; } /* =========================================================================== * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. * (It will be regenerated if this run of deflate switches away from Huffman.) */ local block_state deflate_huff(s, flush) deflate_state *s; int flush; { int bflush; /* set if current block must be flushed */ for (;;) { /* Make sure that we have a literal to write. */ if (s->lookahead == 0) { fill_window(s); if (s->lookahead == 0) { if (flush == Z_NO_FLUSH) return need_more; break; /* flush the current block */ } } /* Output a literal byte */ s->match_length = 0; Tracevv((stderr,"%c", s->window[s->strstart])); _tr_tally_lit (s, s->window[s->strstart], bflush); s->lookahead--; s->strstart++; if (bflush) FLUSH_BLOCK(s, 0); } s->insert = 0; if (flush == Z_FINISH) { FLUSH_BLOCK(s, 1); return finish_done; } if (s->last_lit) FLUSH_BLOCK(s, 0); return block_done; } gtkwave-3.3.66/src/libz/gzclose.c0000664000076400007640000000124611523063250016140 0ustar bybellbybell/* gzclose.c -- zlib gzclose() function * Copyright (C) 2004, 2010 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ #include "gzguts.h" /* gzclose() is in a separate file so that it is linked in only if it is used. That way the other gzclose functions can be used instead to avoid linking in unneeded compression or decompression routines. */ int ZEXPORT gzclose(file) gzFile file; { #ifndef NO_GZCOMPRESS gz_statep state; if (file == NULL) return Z_STREAM_ERROR; state = (gz_statep)file; return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); #else return gzclose_r(file); #endif } gtkwave-3.3.66/src/libz/inftrees.h0000664000076400007640000000556011523063250016321 0ustar bybellbybell/* inftrees.h -- header to use inftrees.c * Copyright (C) 1995-2005, 2010 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ /* Structure for decoding tables. Each entry provides either the information needed to do the operation requested by the code that indexed that table entry, or it provides a pointer to another table that indexes more bits of the code. op indicates whether the entry is a pointer to another table, a literal, a length or distance, an end-of-block, or an invalid code. For a table pointer, the low four bits of op is the number of index bits of that table. For a length or distance, the low four bits of op is the number of extra bits to get after the code. bits is the number of bits in this code or part of the code to drop off of the bit buffer. val is the actual byte to output in the case of a literal, the base length or distance, or the offset from the current table to the next table. Each entry is four bytes. */ typedef struct { unsigned char op; /* operation, extra bits, table bits */ unsigned char bits; /* bits in this part of the code */ unsigned short val; /* offset in table or code value */ } code; /* op values as set by inflate_table(): 00000000 - literal 0000tttt - table link, tttt != 0 is the number of table index bits 0001eeee - length or distance, eeee is the number of extra bits 01100000 - end of block 01000000 - invalid code */ /* Maximum size of the dynamic table. The maximum number of code structures is 1444, which is the sum of 852 for literal/length codes and 592 for distance codes. These values were found by exhaustive searches using the program examples/enough.c found in the zlib distribtution. The arguments to that program are the number of symbols, the initial root table size, and the maximum bit length of a code. "enough 286 9 15" for literal/length codes returns returns 852, and "enough 30 6 15" for distance codes returns 592. The initial root table size (9 or 6) is found in the fifth argument of the inflate_table() calls in inflate.c and infback.c. If the root table size is changed, then these maximum sizes would be need to be recalculated and updated. */ #define ENOUGH_LENS 852 #define ENOUGH_DISTS 592 #define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) /* Type of code to build for inflate_table() */ typedef enum { CODES, LENS, DISTS } codetype; int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, unsigned codes, code FAR * FAR *table, unsigned FAR *bits, unsigned short FAR *work)); gtkwave-3.3.66/src/libz/inffast.c0000664000076400007640000003221712235606635016141 0ustar bybellbybell/* inffast.c -- fast decoding * Copyright (C) 1995-2008, 2010, 2013 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ #include "zutil.h" #include "inftrees.h" #include "inflate.h" #include "inffast.h" #ifndef ASMINF /* Allow machine dependent optimization for post-increment or pre-increment. Based on testing to date, Pre-increment preferred for: - PowerPC G3 (Adler) - MIPS R5000 (Randers-Pehrson) Post-increment preferred for: - none No measurable difference: - Pentium III (Anderson) - M68060 (Nikl) */ #ifdef POSTINC # define OFF 0 # define PUP(a) *(a)++ #else # define OFF 1 # define PUP(a) *++(a) #endif /* Decode literal, length, and distance codes and write out the resulting literal and match bytes until either not enough input or output is available, an end-of-block is encountered, or a data error is encountered. When large enough input and output buffers are supplied to inflate(), for example, a 16K input buffer and a 64K output buffer, more than 95% of the inflate execution time is spent in this routine. Entry assumptions: state->mode == LEN strm->avail_in >= 6 strm->avail_out >= 258 start >= strm->avail_out state->bits < 8 On return, state->mode is one of: LEN -- ran out of enough output space or enough available input TYPE -- reached end of block code, inflate() to interpret next block BAD -- error in block data Notes: - The maximum input bits used by a length/distance pair is 15 bits for the length code, 5 bits for the length extra, 15 bits for the distance code, and 13 bits for the distance extra. This totals 48 bits, or six bytes. Therefore if strm->avail_in >= 6, then there is enough input to avoid checking for available input while decoding. - The maximum bytes that a single length/distance pair can output is 258 bytes, which is the maximum length that can be coded. inflate_fast() requires strm->avail_out >= 258 for each loop to avoid checking for output space. */ void ZLIB_INTERNAL inflate_fast(strm, start) z_streamp strm; unsigned start; /* inflate()'s starting value for strm->avail_out */ { struct inflate_state FAR *state; z_const unsigned char FAR *in; /* local strm->next_in */ z_const unsigned char FAR *last; /* have enough input while in < last */ unsigned char FAR *out; /* local strm->next_out */ unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ unsigned char FAR *end; /* while out < end, enough space available */ #ifdef INFLATE_STRICT unsigned dmax; /* maximum distance from zlib header */ #endif unsigned wsize; /* window size or zero if not using window */ unsigned whave; /* valid bytes in the window */ unsigned wnext; /* window write index */ unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ unsigned long hold; /* local strm->hold */ unsigned bits; /* local strm->bits */ code const FAR *lcode; /* local strm->lencode */ code const FAR *dcode; /* local strm->distcode */ unsigned lmask; /* mask for first level of length codes */ unsigned dmask; /* mask for first level of distance codes */ code here; /* retrieved table entry */ unsigned op; /* code bits, operation, extra bits, or */ /* window position, window bytes to copy */ unsigned len; /* match length, unused bytes */ unsigned dist; /* match distance */ unsigned char FAR *from; /* where to copy match from */ /* copy state to local variables */ state = (struct inflate_state FAR *)strm->state; in = strm->next_in - OFF; last = in + (strm->avail_in - 5); out = strm->next_out - OFF; beg = out - (start - strm->avail_out); end = out + (strm->avail_out - 257); #ifdef INFLATE_STRICT dmax = state->dmax; #endif wsize = state->wsize; whave = state->whave; wnext = state->wnext; window = state->window; hold = state->hold; bits = state->bits; lcode = state->lencode; dcode = state->distcode; lmask = (1U << state->lenbits) - 1; dmask = (1U << state->distbits) - 1; /* decode literals and length/distances until end-of-block or not enough input data or output space */ do { if (bits < 15) { hold += (unsigned long)(PUP(in)) << bits; bits += 8; hold += (unsigned long)(PUP(in)) << bits; bits += 8; } here = lcode[hold & lmask]; dolen: op = (unsigned)(here.bits); hold >>= op; bits -= op; op = (unsigned)(here.op); if (op == 0) { /* literal */ Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? "inflate: literal '%c'\n" : "inflate: literal 0x%02x\n", here.val)); PUP(out) = (unsigned char)(here.val); } else if (op & 16) { /* length base */ len = (unsigned)(here.val); op &= 15; /* number of extra bits */ if (op) { if (bits < op) { hold += (unsigned long)(PUP(in)) << bits; bits += 8; } len += (unsigned)hold & ((1U << op) - 1); hold >>= op; bits -= op; } Tracevv((stderr, "inflate: length %u\n", len)); if (bits < 15) { hold += (unsigned long)(PUP(in)) << bits; bits += 8; hold += (unsigned long)(PUP(in)) << bits; bits += 8; } here = dcode[hold & dmask]; dodist: op = (unsigned)(here.bits); hold >>= op; bits -= op; op = (unsigned)(here.op); if (op & 16) { /* distance base */ dist = (unsigned)(here.val); op &= 15; /* number of extra bits */ if (bits < op) { hold += (unsigned long)(PUP(in)) << bits; bits += 8; if (bits < op) { hold += (unsigned long)(PUP(in)) << bits; bits += 8; } } dist += (unsigned)hold & ((1U << op) - 1); #ifdef INFLATE_STRICT if (dist > dmax) { strm->msg = (char *)"invalid distance too far back"; state->mode = BAD; break; } #endif hold >>= op; bits -= op; Tracevv((stderr, "inflate: distance %u\n", dist)); op = (unsigned)(out - beg); /* max distance in output */ if (dist > op) { /* see if copy from window */ op = dist - op; /* distance back in window */ if (op > whave) { if (state->sane) { strm->msg = (char *)"invalid distance too far back"; state->mode = BAD; break; } #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR if (len <= op - whave) { do { PUP(out) = 0; } while (--len); continue; } len -= op - whave; do { PUP(out) = 0; } while (--op > whave); if (op == 0) { from = out - dist; do { PUP(out) = PUP(from); } while (--len); continue; } #endif } from = window - OFF; if (wnext == 0) { /* very common case */ from += wsize - op; if (op < len) { /* some from window */ len -= op; do { PUP(out) = PUP(from); } while (--op); from = out - dist; /* rest from output */ } } else if (wnext < op) { /* wrap around window */ from += wsize + wnext - op; op -= wnext; if (op < len) { /* some from end of window */ len -= op; do { PUP(out) = PUP(from); } while (--op); from = window - OFF; if (wnext < len) { /* some from start of window */ op = wnext; len -= op; do { PUP(out) = PUP(from); } while (--op); from = out - dist; /* rest from output */ } } } else { /* contiguous in window */ from += wnext - op; if (op < len) { /* some from window */ len -= op; do { PUP(out) = PUP(from); } while (--op); from = out - dist; /* rest from output */ } } while (len > 2) { PUP(out) = PUP(from); PUP(out) = PUP(from); PUP(out) = PUP(from); len -= 3; } if (len) { PUP(out) = PUP(from); if (len > 1) PUP(out) = PUP(from); } } else { from = out - dist; /* copy direct from output */ do { /* minimum length is three */ PUP(out) = PUP(from); PUP(out) = PUP(from); PUP(out) = PUP(from); len -= 3; } while (len > 2); if (len) { PUP(out) = PUP(from); if (len > 1) PUP(out) = PUP(from); } } } else if ((op & 64) == 0) { /* 2nd level distance code */ here = dcode[here.val + (hold & ((1U << op) - 1))]; goto dodist; } else { strm->msg = (char *)"invalid distance code"; state->mode = BAD; break; } } else if ((op & 64) == 0) { /* 2nd level length code */ here = lcode[here.val + (hold & ((1U << op) - 1))]; goto dolen; } else if (op & 32) { /* end-of-block */ Tracevv((stderr, "inflate: end of block\n")); state->mode = TYPE; break; } else { strm->msg = (char *)"invalid literal/length code"; state->mode = BAD; break; } } while (in < last && out < end); /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ len = bits >> 3; in -= len; bits -= len << 3; hold &= (1U << bits) - 1; /* update state and return */ strm->next_in = in + OFF; strm->next_out = out + OFF; strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); strm->avail_out = (unsigned)(out < end ? 257 + (end - out) : 257 - (out - end)); state->hold = hold; state->bits = bits; return; } /* inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): - Using bit fields for code structure - Different op definition to avoid & for extra bits (do & for table bits) - Three separate decoding do-loops for direct, window, and wnext == 0 - Special case for distance > 1 copies to do overlapped load and store copy - Explicit branch predictions (based on measured branch probabilities) - Deferring match copy and interspersed it with decoding subsequent codes - Swapping literal/length else - Swapping window/direct else - Larger unrolled copy loops (three is about right) - Moving len -= 3 statement into middle of loop */ #endif /* !ASMINF */ gtkwave-3.3.66/src/libz/deflate.h0000664000076400007640000003074612235606635016125 0ustar bybellbybell/* deflate.h -- internal compression state * Copyright (C) 1995-2012 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ /* @(#) $Id$ */ #ifndef DEFLATE_H #define DEFLATE_H #include "zutil.h" /* define NO_GZIP when compiling if you want to disable gzip header and trailer creation by deflate(). NO_GZIP would be used to avoid linking in the crc code when it is not needed. For shared libraries, gzip encoding should be left enabled. */ #ifndef NO_GZIP # define GZIP #endif /* =========================================================================== * Internal compression state. */ #define LENGTH_CODES 29 /* number of length codes, not counting the special END_BLOCK code */ #define LITERALS 256 /* number of literal bytes 0..255 */ #define L_CODES (LITERALS+1+LENGTH_CODES) /* number of Literal or Length codes, including the END_BLOCK code */ #define D_CODES 30 /* number of distance codes */ #define BL_CODES 19 /* number of codes used to transfer the bit lengths */ #define HEAP_SIZE (2*L_CODES+1) /* maximum heap size */ #define MAX_BITS 15 /* All codes must not exceed MAX_BITS bits */ #define Buf_size 16 /* size of bit buffer in bi_buf */ #define INIT_STATE 42 #define EXTRA_STATE 69 #define NAME_STATE 73 #define COMMENT_STATE 91 #define HCRC_STATE 103 #define BUSY_STATE 113 #define FINISH_STATE 666 /* Stream status */ /* Data structure describing a single value and its code string. */ typedef struct ct_data_s { union { ush freq; /* frequency count */ ush code; /* bit string */ } fc; union { ush dad; /* father node in Huffman tree */ ush len; /* length of bit string */ } dl; } FAR ct_data; #define Freq fc.freq #define Code fc.code #define Dad dl.dad #define Len dl.len typedef struct static_tree_desc_s static_tree_desc; typedef struct tree_desc_s { ct_data *dyn_tree; /* the dynamic tree */ int max_code; /* largest code with non zero frequency */ static_tree_desc *stat_desc; /* the corresponding static tree */ } FAR tree_desc; typedef ush Pos; typedef Pos FAR Posf; typedef unsigned IPos; /* A Pos is an index in the character window. We use short instead of int to * save space in the various tables. IPos is used only for parameter passing. */ typedef struct internal_state { z_streamp strm; /* pointer back to this zlib stream */ int status; /* as the name implies */ Bytef *pending_buf; /* output still pending */ ulg pending_buf_size; /* size of pending_buf */ Bytef *pending_out; /* next pending byte to output to the stream */ uInt pending; /* nb of bytes in the pending buffer */ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ gz_headerp gzhead; /* gzip header information to write */ uInt gzindex; /* where in extra, name, or comment */ Byte method; /* can only be DEFLATED */ int last_flush; /* value of flush param for previous deflate call */ /* used by deflate.c: */ uInt w_size; /* LZ77 window size (32K by default) */ uInt w_bits; /* log2(w_size) (8..16) */ uInt w_mask; /* w_size - 1 */ Bytef *window; /* Sliding window. Input bytes are read into the second half of the window, * and move to the first half later to keep a dictionary of at least wSize * bytes. With this organization, matches are limited to a distance of * wSize-MAX_MATCH bytes, but this ensures that IO is always * performed with a length multiple of the block size. Also, it limits * the window size to 64K, which is quite useful on MSDOS. * To do: use the user input buffer as sliding window. */ ulg window_size; /* Actual size of window: 2*wSize, except when the user input buffer * is directly used as sliding window. */ Posf *prev; /* Link to older string with same hash index. To limit the size of this * array to 64K, this link is maintained only for the last 32K strings. * An index in this array is thus a window index modulo 32K. */ Posf *head; /* Heads of the hash chains or NIL. */ uInt ins_h; /* hash index of string to be inserted */ uInt hash_size; /* number of elements in hash table */ uInt hash_bits; /* log2(hash_size) */ uInt hash_mask; /* hash_size-1 */ uInt hash_shift; /* Number of bits by which ins_h must be shifted at each input * step. It must be such that after MIN_MATCH steps, the oldest * byte no longer takes part in the hash key, that is: * hash_shift * MIN_MATCH >= hash_bits */ long block_start; /* Window position at the beginning of the current output block. Gets * negative when the window is moved backwards. */ uInt match_length; /* length of best match */ IPos prev_match; /* previous match */ int match_available; /* set if previous match exists */ uInt strstart; /* start of string to insert */ uInt match_start; /* start of matching string */ uInt lookahead; /* number of valid bytes ahead in window */ uInt prev_length; /* Length of the best match at previous step. Matches not greater than this * are discarded. This is used in the lazy match evaluation. */ uInt max_chain_length; /* To speed up deflation, hash chains are never searched beyond this * length. A higher limit improves compression ratio but degrades the * speed. */ uInt max_lazy_match; /* Attempt to find a better match only when the current match is strictly * smaller than this value. This mechanism is used only for compression * levels >= 4. */ # define max_insert_length max_lazy_match /* Insert new strings in the hash table only if the match length is not * greater than this length. This saves time but degrades compression. * max_insert_length is used only for compression levels <= 3. */ int level; /* compression level (1..9) */ int strategy; /* favor or force Huffman coding*/ uInt good_match; /* Use a faster search when the previous match is longer than this */ int nice_match; /* Stop searching when current match exceeds this */ /* used by trees.c: */ /* Didn't use ct_data typedef below to suppress compiler warning */ struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ struct tree_desc_s l_desc; /* desc. for literal tree */ struct tree_desc_s d_desc; /* desc. for distance tree */ struct tree_desc_s bl_desc; /* desc. for bit length tree */ ush bl_count[MAX_BITS+1]; /* number of codes at each bit length for an optimal tree */ int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ int heap_len; /* number of elements in the heap */ int heap_max; /* element of largest frequency */ /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. * The same heap array is used to build all trees. */ uch depth[2*L_CODES+1]; /* Depth of each subtree used as tie breaker for trees of equal frequency */ uchf *l_buf; /* buffer for literals or lengths */ uInt lit_bufsize; /* Size of match buffer for literals/lengths. There are 4 reasons for * limiting lit_bufsize to 64K: * - frequencies can be kept in 16 bit counters * - if compression is not successful for the first block, all input * data is still in the window so we can still emit a stored block even * when input comes from standard input. (This can also be done for * all blocks if lit_bufsize is not greater than 32K.) * - if compression is not successful for a file smaller than 64K, we can * even emit a stored file instead of a stored block (saving 5 bytes). * This is applicable only for zip (not gzip or zlib). * - creating new Huffman trees less frequently may not provide fast * adaptation to changes in the input data statistics. (Take for * example a binary file with poorly compressible code followed by * a highly compressible string table.) Smaller buffer sizes give * fast adaptation but have of course the overhead of transmitting * trees more frequently. * - I can't count above 4 */ uInt last_lit; /* running index in l_buf */ ushf *d_buf; /* Buffer for distances. To simplify the code, d_buf and l_buf have * the same number of elements. To use different lengths, an extra flag * array would be necessary. */ ulg opt_len; /* bit length of current block with optimal trees */ ulg static_len; /* bit length of current block with static trees */ uInt matches; /* number of string matches in current block */ uInt insert; /* bytes at end of window left to insert */ #ifdef DEBUG ulg compressed_len; /* total bit length of compressed file mod 2^32 */ ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ #endif ush bi_buf; /* Output buffer. bits are inserted starting at the bottom (least * significant bits). */ int bi_valid; /* Number of valid bits in bi_buf. All bits above the last valid bit * are always zero. */ ulg high_water; /* High water mark offset in window for initialized bytes -- bytes above * this are set to zero in order to avoid memory check warnings when * longest match routines access bytes past the input. This is then * updated to the new high water mark. */ } FAR deflate_state; /* Output a byte on the stream. * IN assertion: there is enough room in pending_buf. */ #define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} #define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) /* Minimum amount of lookahead, except at the end of the input file. * See deflate.c for comments about the MIN_MATCH+1. */ #define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) /* In order to simplify the code, particularly on 16 bit machines, match * distances are limited to MAX_DIST instead of WSIZE. */ #define WIN_INIT MAX_MATCH /* Number of bytes after end of data in window to initialize in order to avoid memory checker errors from longest match routines */ /* in trees.c */ void ZLIB_INTERNAL _tr_init OF((deflate_state *s)); int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, int last)); void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s)); void ZLIB_INTERNAL _tr_align OF((deflate_state *s)); void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, int last)); #define d_code(dist) \ ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) /* Mapping from a distance to a distance code. dist is the distance - 1 and * must not have side effects. _dist_code[256] and _dist_code[257] are never * used. */ #ifndef DEBUG /* Inline versions of _tr_tally for speed: */ #if defined(GEN_TREES_H) || !defined(STDC) extern uch ZLIB_INTERNAL _length_code[]; extern uch ZLIB_INTERNAL _dist_code[]; #else extern const uch ZLIB_INTERNAL _length_code[]; extern const uch ZLIB_INTERNAL _dist_code[]; #endif # define _tr_tally_lit(s, c, flush) \ { uch cc = (c); \ s->d_buf[s->last_lit] = 0; \ s->l_buf[s->last_lit++] = cc; \ s->dyn_ltree[cc].Freq++; \ flush = (s->last_lit == s->lit_bufsize-1); \ } # define _tr_tally_dist(s, distance, length, flush) \ { uch len = (length); \ ush dist = (distance); \ s->d_buf[s->last_lit] = dist; \ s->l_buf[s->last_lit++] = len; \ dist--; \ s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ s->dyn_dtree[d_code(dist)].Freq++; \ flush = (s->last_lit == s->lit_bufsize-1); \ } #else # define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) # define _tr_tally_dist(s, distance, length, flush) \ flush = _tr_tally(s, distance, length) #endif #endif /* DEFLATE_H */ gtkwave-3.3.66/src/libz/compress.c0000664000076400007640000000474112235606635016343 0ustar bybellbybell/* compress.c -- compress a memory buffer * Copyright (C) 1995-2005 Jean-loup Gailly. * For conditions of distribution and use, see copyright notice in zlib.h */ /* @(#) $Id$ */ #define ZLIB_INTERNAL #include "zlib.h" /* =========================================================================== Compresses the source buffer into the destination buffer. The level parameter has the same meaning as in deflateInit. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be at least 0.1% larger than sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, Z_STREAM_ERROR if the level parameter is invalid. */ int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) Bytef *dest; uLongf *destLen; const Bytef *source; uLong sourceLen; int level; { z_stream stream; int err; stream.next_in = (z_const Bytef *)source; stream.avail_in = (uInt)sourceLen; #ifdef MAXSEG_64K /* Check for source > 64K on 16-bit machine: */ if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; #endif stream.next_out = dest; stream.avail_out = (uInt)*destLen; if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; stream.zalloc = (alloc_func)0; stream.zfree = (free_func)0; stream.opaque = (voidpf)0; err = deflateInit(&stream, level); if (err != Z_OK) return err; err = deflate(&stream, Z_FINISH); if (err != Z_STREAM_END) { deflateEnd(&stream); return err == Z_OK ? Z_BUF_ERROR : err; } *destLen = stream.total_out; err = deflateEnd(&stream); return err; } /* =========================================================================== */ int ZEXPORT compress (dest, destLen, source, sourceLen) Bytef *dest; uLongf *destLen; const Bytef *source; uLong sourceLen; { return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); } /* =========================================================================== If the default memLevel or windowBits for deflateInit() is changed, then this function needs to be updated. */ uLong ZEXPORT compressBound (sourceLen) uLong sourceLen; { return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + (sourceLen >> 25) + 13; } gtkwave-3.3.66/src/libz/inflate.h0000664000076400007640000001437711523063250016132 0ustar bybellbybell/* inflate.h -- internal inflate state definition * Copyright (C) 1995-2009 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ /* WARNING: this file should *not* be used by applications. It is part of the implementation of the compression library and is subject to change. Applications should only use zlib.h. */ /* define NO_GZIP when compiling if you want to disable gzip header and trailer decoding by inflate(). NO_GZIP would be used to avoid linking in the crc code when it is not needed. For shared libraries, gzip decoding should be left enabled. */ #ifndef NO_GZIP # define GUNZIP #endif /* Possible inflate modes between inflate() calls */ typedef enum { HEAD, /* i: waiting for magic header */ FLAGS, /* i: waiting for method and flags (gzip) */ TIME, /* i: waiting for modification time (gzip) */ OS, /* i: waiting for extra flags and operating system (gzip) */ EXLEN, /* i: waiting for extra length (gzip) */ EXTRA, /* i: waiting for extra bytes (gzip) */ NAME, /* i: waiting for end of file name (gzip) */ COMMENT, /* i: waiting for end of comment (gzip) */ HCRC, /* i: waiting for header crc (gzip) */ DICTID, /* i: waiting for dictionary check value */ DICT, /* waiting for inflateSetDictionary() call */ TYPE, /* i: waiting for type bits, including last-flag bit */ TYPEDO, /* i: same, but skip check to exit inflate on new block */ STORED, /* i: waiting for stored size (length and complement) */ COPY_, /* i/o: same as COPY below, but only first time in */ COPY, /* i/o: waiting for input or output to copy stored block */ TABLE, /* i: waiting for dynamic block table lengths */ LENLENS, /* i: waiting for code length code lengths */ CODELENS, /* i: waiting for length/lit and distance code lengths */ LEN_, /* i: same as LEN below, but only first time in */ LEN, /* i: waiting for length/lit/eob code */ LENEXT, /* i: waiting for length extra bits */ DIST, /* i: waiting for distance code */ DISTEXT, /* i: waiting for distance extra bits */ MATCH, /* o: waiting for output space to copy string */ LIT, /* o: waiting for output space to write literal */ CHECK, /* i: waiting for 32-bit check value */ LENGTH, /* i: waiting for 32-bit length (gzip) */ DONE, /* finished check, done -- remain here until reset */ BAD, /* got a data error -- remain here until reset */ MEM, /* got an inflate() memory error -- remain here until reset */ SYNC /* looking for synchronization bytes to restart inflate() */ } inflate_mode; /* State transitions between above modes - (most modes can go to BAD or MEM on error -- not shown for clarity) Process header: HEAD -> (gzip) or (zlib) or (raw) (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> HCRC -> TYPE (zlib) -> DICTID or TYPE DICTID -> DICT -> TYPE (raw) -> TYPEDO Read deflate blocks: TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK STORED -> COPY_ -> COPY -> TYPE TABLE -> LENLENS -> CODELENS -> LEN_ LEN_ -> LEN Read deflate codes in fixed or dynamic block: LEN -> LENEXT or LIT or TYPE LENEXT -> DIST -> DISTEXT -> MATCH -> LEN LIT -> LEN Process trailer: CHECK -> LENGTH -> DONE */ /* state maintained between inflate() calls. Approximately 10K bytes. */ struct inflate_state { inflate_mode mode; /* current inflate mode */ int last; /* true if processing last block */ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ int havedict; /* true if dictionary provided */ int flags; /* gzip header method and flags (0 if zlib) */ unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ unsigned long check; /* protected copy of check value */ unsigned long total; /* protected copy of output count */ gz_headerp head; /* where to save gzip header information */ /* sliding window */ unsigned wbits; /* log base 2 of requested window size */ unsigned wsize; /* window size or zero if not using window */ unsigned whave; /* valid bytes in the window */ unsigned wnext; /* window write index */ unsigned char FAR *window; /* allocated sliding window, if needed */ /* bit accumulator */ unsigned long hold; /* input bit accumulator */ unsigned bits; /* number of bits in "in" */ /* for string and stored block copying */ unsigned length; /* literal or length of data to copy */ unsigned offset; /* distance back to copy string from */ /* for table and code decoding */ unsigned extra; /* extra bits needed */ /* fixed and dynamic code tables */ code const FAR *lencode; /* starting table for length/literal codes */ code const FAR *distcode; /* starting table for distance codes */ unsigned lenbits; /* index bits for lencode */ unsigned distbits; /* index bits for distcode */ /* dynamic table building */ unsigned ncode; /* number of code length code lengths */ unsigned nlen; /* number of length code lengths */ unsigned ndist; /* number of distance code lengths */ unsigned have; /* number of code lengths in lens[] */ code FAR *next; /* next available space in codes[] */ unsigned short lens[320]; /* temporary storage for code lengths */ unsigned short work[288]; /* work area for code table building */ code codes[ENOUGH]; /* space for code tables */ int sane; /* if false, allow invalid distance too far */ int back; /* bits back of last unprocessed length/lit */ unsigned was; /* initial length of match */ }; gtkwave-3.3.66/src/globals.h0000664000076400007640000014126412523024113015163 0ustar bybellbybell/* * Copyright (c) Kermin Elliott Fleming 2007-2014. * * 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. */ #ifndef GLOBALS_H #define GLOBALS_H #include #include #if defined __MINGW32__ || defined _MSC_VER #include #include #endif #include "ae2.h" #include "analyzer.h" #include "bsearch.h" #include "busy.h" #include "clipping.h" #include "color.h" #include "currenttime.h" #include "debug.h" #include "fgetdynamic.h" #include "fonts.h" #include "fstapi.h" #include "gconf.h" #include "ghw.h" #include "globals.h" #include "gnu_regex.h" #include "gtk12compat.h" #include "lx2.h" #include "lxt.h" #include "main.h" #include "memory.h" #include "menu.h" #include "pipeio.h" #include "pixmaps.h" #include "print.h" #include "ptranslate.h" #include "ttranslate.h" #include "rc.h" #include "regex_wave.h" #include "savefile.h" #include "strace.h" #include "symbol.h" #include "tcl_helper.h" #include "translate.h" #include "tree.h" #include "vcd.h" #include "vcd_saver.h" #include "vlist.h" #include "vzt.h" #include "version.h" #include "wavealloca.h" #include "jrb.h" #include "extload.h" #ifdef _WAVE_HAVE_JUDY #include #endif struct Global{ /* * ae2.c */ #ifdef AET2_IS_PRESENT #ifdef AET2_ALIASDB_IS_PRESENT FILE *adb_alias_stream_file; ADB_DB adb; unsigned long adb_max_terms; ADB_TERM *adb_terms; ADB_TERM **adb_aliases; unsigned short *adb_num_terms; unsigned short *adb_idx_first; unsigned short *adb_idx_last; unsigned char *adb_alloc_pool_base; size_t adb_alloc_idx; #endif unsigned long ae2_num_facs; unsigned long ae2_num_aliases; unsigned long ae2_num_sections; struct lx2_entry **ae2_lx2_table; FILE *ae2_f; AE2_HANDLE *ae2; AE2_FACREF *ae2_fr; TimeType ae2_start_limit_cyc; TimeType ae2_end_limit_cyc; char *ae2_process_mask; #endif TimeType ae2_start_cyc; TimeType ae2_end_cyc; TimeType *ae2_time_xlate; char disable_ae2_alias; /* * analyzer.c */ unsigned int default_flags; /* from analyzer.c 5 */ Times tims; /* from analyzer.c 6 */ Traces traces; /* from analyzer.c 7 */ int hier_max_level; /* from analyzer.c 8 */ int hier_max_level_shadow; /* from analyzer.c */ TimeType timestart_from_savefile; char timestart_from_savefile_valid; int group_depth; /* * baseconvert.c */ char color_active_in_filter; /* from baseconvert.c 9 */ /* * bsearch.c */ TimeType shift_timebase; /* from bsearch.c 10 */ TimeType shift_timebase_default_for_add; /* from bsearch.c 11 */ TimeType max_compare_time_tc_bsearch_c_1; /* from bsearch.c 12 */ TimeType *max_compare_pos_tc_bsearch_c_1; /* from bsearch.c 13 */ TimeType max_compare_time_bsearch_c_1; /* from bsearch.c 14 */ struct HistEnt *max_compare_pos_bsearch_c_1; /* from bsearch.c 15 */ struct HistEnt **max_compare_index; /* from bsearch.c 16 */ TimeType vmax_compare_time_bsearch_c_1; /* from bsearch.c 17 */ struct VectorEnt *vmax_compare_pos_bsearch_c_1; /* from bsearch.c 18 */ struct VectorEnt **vmax_compare_index; /* from bsearch.c 19 */ int maxlen_trunc; /* from bsearch.c 20 */ char *maxlen_trunc_pos_bsearch_c_1; /* from bsearch.c 21 */ char *trunc_asciibase_bsearch_c_1; /* from bsearch.c 22 */ /* * busy.c */ GdkCursor *busycursor_busy_c_1; /* from busy.c 23 */ int busy_busy_c_1; /* from busy.c 24 */ /* * color.c */ char keep_xz_colors; struct wave_gcchain_t *wave_gcchain; int color_back; /* from color.c 25 */ int color_baseline; /* from color.c 26 */ int color_grid; /* from color.c 27 */ int color_grid2; /* from color.c */ int color_high; /* from color.c 28 */ int color_low; /* from color.c 29 */ int color_mark; /* from color.c 30 */ int color_mid; /* from color.c 31 */ int color_time; /* from color.c 32 */ int color_timeb; /* from color.c 33 */ int color_trans; /* from color.c 34 */ int color_umark; /* from color.c 35 */ int color_value; /* from color.c 36 */ int color_vbox; /* from color.c 37 */ int color_vtrans; /* from color.c 38 */ int color_x; /* from color.c 39 */ int color_xfill; /* from color.c 40 */ int color_0; /* from color.c 41 */ int color_1; /* from color.c 42 */ int color_ufill; /* from color.c 43 */ int color_u; /* from color.c 44 */ int color_wfill; /* from color.c 45 */ int color_w; /* from color.c 46 */ int color_dashfill; /* from color.c 47 */ int color_dash; /* from color.c 48 */ int color_white; /* from color.c 49 */ int color_black; /* from color.c 50 */ int color_ltgray; /* from color.c 51 */ int color_normal; /* from color.c 52 */ int color_mdgray; /* from color.c 53 */ int color_dkgray; /* from color.c 54 */ int color_dkblue; /* from color.c 55 */ int color_brkred; int color_ltblue; int color_gmstrd; /* * currenttime.c */ TimeType global_time_offset; char is_vcd; /* from currenttime.c 56 */ char partial_vcd; /* from currenttime.c 57 */ char use_maxtime_display; /* from currenttime.c 58 */ char use_frequency_delta; /* from currenttime.c 59 */ GtkWidget *max_or_marker_label_currenttime_c_1; /* from currenttime.c 60 */ GtkWidget *base_or_curtime_label_currenttime_c_1; /* from currenttime.c 61 */ TimeType cached_currenttimeval_currenttime_c_1; /* from currenttime.c 62 */ TimeType currenttime; /* from currenttime.c 63 */ TimeType max_time; /* from currenttime.c 64 */ TimeType min_time; /* from currenttime.c 65 */ char display_grid; /* from currenttime.c 66 */ TimeType time_scale; /* from currenttime.c 67 */ char time_dimension; /* from currenttime.c 68 */ char scale_to_time_dimension; /* from currenttime.c */ GtkWidget *maxtimewid_currenttime_c_1; /* from currenttime.c 70 */ GtkWidget *curtimewid_currenttime_c_1; /* from currenttime.c 71 */ char *maxtext_currenttime_c_1; /* from currenttime.c 72 */ char *curtext_currenttime_c_1; /* from currenttime.c 73 */ TimeType time_trunc_val_currenttime_c_1; /* from currenttime.c 77 */ char use_full_precision; /* from currenttime.c 78 */ /* * debug.c */ void **alloc2_chain; /* from debug.c */ int outstanding; /* from debug.c */ const char *atoi_cont_ptr; /* from debug.c 79 */ char disable_tooltips; /* from debug.c 80 */ /* * entry.c */ GtkWidget *window_entry_c_1; /* from entry.c 81 */ GtkWidget *entry_entry_c_1; /* from entry.c 82 */ char *entrybox_text; /* from entry.c 83 */ void (*cleanup_entry_c_1)(void); /* from entry.c 84 */ int entry_raise_timer; /* extload.c */ unsigned int extload_ffr_import_count; /* from extload.c */ void *extload_ffr_ctx; /* from extload.c */ FILE *extload; /* from extload.c */ unsigned int *extload_idcodes; /* from extload.c */ int *extload_inv_idcodes; /* from extload.c */ #if !defined __MINGW32__ && !defined _MSC_VER time_t extload_lastmod; /* from extload.c */ char extload_already_errored; /* from extload.c */ #endif char **extload_namecache; int *extload_namecache_max; int *extload_namecache_lens; struct symbol *extload_sym_block; struct Node *extload_node_block; void *extload_xc; struct symbol *extload_prevsymroot; struct symbol *extload_prevsym; int extload_i; int extload_hlen; unsigned char extload_vt_prev; unsigned char extload_vd_prev; int f_name_build_buf_len; char *f_name_build_buf; /* * fetchbuttons.c */ TimeType fetchwindow; /* from fetchbuttons.c 85 */ /* * fgetdynamic.c */ int fgetmalloc_len; /* from fgetdynamic.c 86 */ /* * file.c */ #if GTK_CHECK_VERSION(2,4,0) GtkWidget *pFileChoose; char *pFileChooseFilterName; GPatternSpec *pPatternSpec; #endif GtkWidget *fs_file_c_1; /* from file.c 87 */ char **fileselbox_text; /* from file.c 88 */ char filesel_ok; /* from file.c 89 */ void (*cleanup_file_c_2)(void); /* from file.c 90 */ void (*bad_cleanup_file_c_1)(void); /* from file.c 91 */ /* * fonts.c */ char *fontname_signals; /* from fonts.c 92 */ char *fontname_waves; /* from fonts.c 93 */ #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) && GTK_CHECK_VERSION(2,8,0) PangoRenderer *fonts_renderer; GdkGC *fonts_gc; GdkScreen *fonts_screen; PangoContext *fonts_context; PangoLayout *fonts_layout; #endif char use_pango_fonts; /* * fst.c */ void *fst_fst_c_1; const char *fst_scope_name; int fst_scope_name_len; TimeType first_cycle_fst_c_3; TimeType last_cycle_fst_c_3; TimeType total_cycles_fst_c_3; struct lx2_entry *fst_table_fst_c_1; struct fac *mvlfacs_fst_c_3; fstHandle *mvlfacs_fst_alias; fstHandle *mvlfacs_fst_rvs_alias; fstHandle fst_maxhandle; int busycnt_fst_c_2; double *double_curr_fst; double *double_fini_fst; char nonimplicit_direction_encountered; char supplemental_datatypes_encountered; char supplemental_vartypes_encountered; char is_vhdl_component_format; JRB subvar_jrb; unsigned int subvar_jrb_count; char **subvar_pnt; unsigned char fst_filetype; unsigned subvar_jrb_count_locked : 1; uint32_t stem_file_idx; uint32_t stem_line_number; char **stem_path_string_table; struct stem_struct_t *stem_struct_base; struct stem_struct_t *istem_struct_base; uint32_t stem_path_string_table_siz; uint32_t stem_path_string_table_alloc; uint32_t stem_struct_base_siz; uint32_t stem_struct_base_siz_alloc; uint32_t istem_struct_base_siz; uint32_t istem_struct_base_siz_alloc; unsigned stem_valid : 1; unsigned istem_valid : 1; char *fst_synclock_str; JRB synclock_jrb; /* * ghw.c */ struct Node **nxp_ghw_c_1; /* from ghw.c 95 */ int sym_which_ghw_c_1; /* from ghw.c 98 */ struct ghw_tree_node *gwt_ghw_c_1; /* from ghw.c 99 */ struct ghw_tree_node *gwt_corr_ghw_c_1; /* from ghw.c 100 */ int xlat_1164_ghw_c_1; /* from ghw.c 101 */ char is_ghw; /* from ghw.c 102 */ char *asbuf; /* from ghw.c 103 */ int nbr_sig_ref_ghw_c_1; /* from ghw.c 104 */ int num_glitches_ghw_c_1; /* from ghw.c 105 */ int num_glitch_regions_ghw_c_1; /* from ghw.c 106 */ char *fac_name_ghw_c_1; /* from ghw.c 108 */ int fac_name_len_ghw_c_1; /* from ghw.c 109 */ int fac_name_max_ghw_c_1; /* from ghw.c 110 */ int last_fac_ghw_c_1; /* from ghw.c 111 */ int warned_ghw_c_1; /* from ghw.c 112 */ /* * globals.c */ struct Global ***dead_context; /* for deallocating tabbed contexts later (when no race conditions exist) */ struct Global **gtk_context_bridge_ptr; /* from globals.c, migrates to reloaded contexts to link buttons to ctx */ /* * help.c */ int helpbox_is_active; /* from help.c 114 */ GtkWidget *text_help_c_1; /* from help.c 115 */ GtkWidget *vscrollbar_help_c_1; /* from help.c 116 */ #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) GtkTextIter iter_help_c_1; /* from help.c 117 */ GtkTextTag *bold_tag_help_c_1; /* from help.c 118 */ #endif GtkWidget *window_help_c_2; /* from help.c 119 */ /* * hierpack.c */ unsigned char *hp_buf; size_t *hp_offs; size_t hp_prev; size_t hp_buf_siz; unsigned char *fmem_buf; size_t fmem_buf_siz; size_t fmem_buf_offs; size_t fmem_uncompressed_siz; /* * hiersearch.c */ char hier_grouping; /* from hiersearch.c 120 */ GtkWidget *window_hiersearch_c_3; /* from hiersearch.c 121 */ GtkWidget *entry_main_hiersearch_c_1; /* from hiersearch.c 122 */ GtkWidget *clist_hiersearch_c_1; /* from hiersearch.c 123 */ char bundle_direction_hiersearch_c_1; /* from hiersearch.c 124 */ void (*cleanup_hiersearch_c_3)(void); /* from hiersearch.c 125 */ int num_rows_hiersearch_c_1; /* from hiersearch.c 126 */ int selected_rows_hiersearch_c_1; /* from hiersearch.c 127 */ GtkWidget *window1_hiersearch_c_1; /* from hiersearch.c 128 */ GtkWidget *entry_hiersearch_c_2; /* from hiersearch.c 129 */ char *entrybox_text_local_hiersearch_c_1; /* from hiersearch.c 130 */ void (*cleanup_e_hiersearch_c_1)(void); /* from hiersearch.c 131 */ struct tree *h_selectedtree_hiersearch_c_1; /* from hiersearch.c 132 */ struct tree *current_tree_hiersearch_c_1; /* from hiersearch.c 133 */ struct treechain *treechain_hiersearch_c_1; /* from hiersearch.c 134 */ int is_active_hiersearch_c_1; /* from hiersearch.c 135 */ /* * logfile.c */ void **logfiles; char *fontname_logfile; /* from logfile.c 137 */ GdkFont *font_logfile_c_1; /* from logfile.c 138 */ #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) GtkTextIter iter_logfile_c_2; /* from logfile.c 139 */ GtkTextTag *bold_tag_logfile_c_2; /* from logfile.c 140 */ GtkTextTag *mono_tag_logfile_c_1; /* from logfile.c 141 */ GtkTextTag *size_tag_logfile_c_1; /* from logfile.c 142 */ #endif /* * lx2.c */ unsigned char is_lx2; /* from lx2.c 143 */ struct lxt2_rd_trace *lx2_lx2_c_1; /* from lx2.c 144 */ TimeType first_cycle_lx2_c_1; /* from lx2.c 145 */ TimeType last_cycle_lx2_c_1; /* from lx2.c 146 */ TimeType total_cycles_lx2_c_1; /* from lx2.c 147 */ struct lx2_entry *lx2_table_lx2_c_1; /* from lx2.c 148 */ struct fac *mvlfacs_lx2_c_1; /* from lx2.c 149 */ int busycnt_lx2_c_1; /* from lx2.c 150 */ /* * lxt.c */ char *mm_lxt_mmap_addr; size_t mm_lxt_mmap_len; #if defined __MINGW32__ || defined _MSC_VER HANDLE hIn, hInMap; char *win_fname; #endif int fpos_lxt_c_1; /* from lxt.c 151 */ char is_lxt; /* from lxt.c 152 */ char lxt_clock_compress_to_z; /* from lxt.c 153 */ void *mm_lxt_c_1; /* from lxt.c 154 */ void *mmcache_lxt_c_1; /* from lxt.c 155 */ int version_lxt_c_1; /* from lxt.c 156 */ struct fac *mvlfacs_lxt_c_2; /* from lxt.c 157 */ TimeType first_cycle_lxt_c_2; /* from lxt.c 158 */ TimeType last_cycle_lxt_c_2; /* from lxt.c 159 */ TimeType total_cycles_lxt_c_2; /* from lxt.c 160 */ int maxchange_lxt_c_1; /* from lxt.c 161 */ int maxindex_lxt_c_1; /* from lxt.c 162 */ int f_len_lxt_c_1; /* from lxt.c 163 */ int *positional_information_lxt_c_1; /* from lxt.c 164 */ TimeType *time_information; /* from lxt.c 165 */ int change_field_offset_lxt_c_1; /* from lxt.c 166 */ int facname_offset_lxt_c_1; /* from lxt.c 167 */ int facgeometry_offset_lxt_c_1; /* from lxt.c 168 */ int time_table_offset_lxt_c_1; /* from lxt.c 169 */ int time_table_offset64_lxt_c_1; /* from lxt.c 170 */ int sync_table_offset_lxt_c_1; /* from lxt.c 171 */ int initial_value_offset_lxt_c_1; /* from lxt.c 172 */ int timescale_offset_lxt_c_1; /* from lxt.c 173 */ int double_test_offset_lxt_c_1; /* from lxt.c 174 */ int zdictionary_offset_lxt_c_1; /* from lxt.c 175 */ unsigned int zfacname_predec_size_lxt_c_1; /* from lxt.c 176 */ unsigned int zfacname_size_lxt_c_1; /* from lxt.c 177 */ unsigned int zfacgeometry_size_lxt_c_1; /* from lxt.c 178 */ unsigned int zsync_table_size_lxt_c_1; /* from lxt.c 179 */ unsigned int ztime_table_size_lxt_c_1; /* from lxt.c 180 */ unsigned int zchg_predec_size_lxt_c_1; /* from lxt.c 181 */ unsigned int zchg_size_lxt_c_1; /* from lxt.c 182 */ unsigned int zdictionary_predec_size_lxt_c_1; /* from lxt.c 183 */ unsigned char initial_value_lxt_c_1; /* from lxt.c 184 */ unsigned int dict_num_entries_lxt_c_1; /* from lxt.c 185 */ unsigned int dict_string_mem_required_lxt_c_1; /* from lxt.c 186 */ int dict_16_offset_lxt_c_1; /* from lxt.c 187 */ int dict_24_offset_lxt_c_1; /* from lxt.c 188 */ int dict_32_offset_lxt_c_1; /* from lxt.c 189 */ unsigned int dict_width_lxt_c_1; /* from lxt.c 190 */ char **dict_string_mem_array_lxt_c_1; /* from lxt.c 191 */ int exclude_offset_lxt_c_1; /* from lxt.c 192 */ int lxt_timezero_offset; char *lt_buf_lxt_c_1; /* from lxt.c 193 */ int lt_len_lxt_c_1; /* from lxt.c 194 */ int fd_lxt_c_1; /* from lxt.c 195 */ unsigned char double_mask_lxt_c_1[8]; /* from lxt.c 196 */ char double_is_native_lxt_c_1; /* from lxt.c 197 */ int max_compare_time_tc_lxt_c_2; /* from lxt.c 199 */ int max_compare_pos_tc_lxt_c_2; /* from lxt.c 200 */ struct Node **resolve_lxt_alias_to; unsigned int *lastchange; /* * main.c */ char is_gtkw_save_file; gboolean dumpfile_is_modified; GtkWidget *missing_file_toolbar; char *argvlist; #ifdef HAVE_LIBTCL Tcl_Interp *interp; #endif char *repscript_name; unsigned int repscript_period; char *tcl_init_cmd; char tcl_running; char block_xy_update; char *winname; unsigned int num_notebook_pages; unsigned int num_notebook_pages_cumulative; unsigned char context_tabposition; unsigned int this_context_page; unsigned char second_page_created; struct Global ***contexts; GtkWidget *notebook; char *loaded_file_name; char *unoptimized_vcd_file_name; char *skip_start; char *skip_end; enum FileType loaded_file_type; char is_optimized_stdin_vcd; char *whoami; /* from main.c 201 */ struct logfile_chain *logfile; /* from main.c 202 */ char *stems_name; /* from main.c 203 */ int stems_type; /* from main.c 204 */ char *aet_name; /* from main.c 205 */ struct gtkwave_annotate_ipc_t *anno_ctx; /* from main.c 206 */ struct gtkwave_dual_ipc_t *dual_ctx; /* from main.c 207 */ int dual_id; /* from main.c 208 */ unsigned int dual_attach_id_main_c_1; /* from main.c 209 */ int dual_race_lock; /* from main.c 210 */ GtkWidget *mainwindow; /* from main.c 211 */ GtkWidget *signalwindow; /* from main.c 212 */ GtkWidget *wavewindow; /* from main.c 213 */ GtkWidget *toppanedwindow; /* from main.c 214 */ GtkWidget *panedwindow; gint toppanedwindow_size_cache; gint panedwindow_size_cache; gint vpanedwindow_size_cache; GtkWidget *sstpane; /* from main.c 215 */ GtkWidget *expanderwindow; /* from main.c 216 */ char disable_window_manager; /* from main.c 217 */ char disable_empty_gui; /* from main.c */ char paned_pack_semantics; /* from main.c 218 */ char zoom_was_explicitly_set; /* from main.c 219 */ int initial_window_x; /* from main.c 220 */ int initial_window_y; /* from main.c 221 */ int initial_window_width; /* from main.c 222 */ int initial_window_height; /* from main.c 223 */ int xy_ignore_main_c_1; /* from main.c 224 */ int optimize_vcd; /* from main.c 225 */ int num_cpus; /* from main.c 226 */ int initial_window_xpos; /* from main.c 227 */ int initial_window_ypos; /* from main.c 228 */ int initial_window_set_valid; /* from main.c 229 */ int initial_window_xpos_set; /* from main.c 230 */ int initial_window_ypos_set; /* from main.c 231 */ int initial_window_get_valid; /* from main.c 232 */ int initial_window_xpos_get; /* from main.c 233 */ int initial_window_ypos_get; /* from main.c 234 */ int xpos_delta; /* from main.c 235 */ int ypos_delta; /* from main.c 236 */ char use_scrollbar_only; /* from main.c 237 */ char force_toolbars; /* from main.c 238 */ int hide_sst; /* from main.c 239 */ int sst_expanded; /* from main.c 240 */ #ifdef WAVE_USE_GTK2 GdkNativeWindow socket_xid; /* from main.c 241 */ #endif int disable_menus; /* from main.c 242 */ char *ftext_main_main_c_1; /* from main.c 243 */ char use_toolbutton_interface; /* from main.c */ /* * markerbox.c */ GtkWidget *window_markerbox_c_4; /* from markerbox.c 248 */ GtkWidget *entries_markerbox_c_1[WAVE_NUM_NAMED_MARKERS]; /* from markerbox.c 249 */ void (*cleanup_markerbox_c_4)(void); /* from markerbox.c 250 */ int dirty_markerbox_c_1; /* from markerbox.c 251 */ TimeType shadow_markers_markerbox_c_1[WAVE_NUM_NAMED_MARKERS]; /* from markerbox.c 252 */ char *marker_names[WAVE_NUM_NAMED_MARKERS]; /* from markerbox.c */ char *shadow_marker_names[WAVE_NUM_NAMED_MARKERS]; /* from markerbox.c */ /* * menu.c */ char *cutcopylist; /* from menu.c */ char enable_fast_exit; /* from menu.c 253 */ char quiet_checkmenu; struct wave_script_args *wave_script_args; /* from tcl_helper.c */ char ignore_savefile_pane_pos; char ignore_savefile_pos; /* from menu.c 255 */ char ignore_savefile_size; /* from menu.c 256 */ #ifndef WAVE_USE_MLIST_T GtkItemFactory *item_factory_menu_c_1; /* from menu.c 258 */ #endif char *regexp_string_menu_c_1; /* from menu.c 259 */ struct TraceEnt *trace_to_alias_menu_c_1; /* from menu.c 260 */ struct TraceEnt *showchangeall_menu_c_1; /* from menu.c 261 */ char *filesel_newviewer_menu_c_1; /* from menu.c 262 */ char *filesel_logfile_menu_c_1; /* from menu.c 263 */ char *filesel_scriptfile_menu; /* from menu.c */ char *filesel_writesave; /* from menu.c 264 */ char *filesel_imagegrab; /* from menu.c */ char save_success_menu_c_1; /* from menu.c 265 */ char *filesel_vcd_writesave; /* from menu.c 266 */ char *filesel_lxt_writesave; /* from menu.c 267 */ char *filesel_tim_writesave; /* from menu.c */ int lock_menu_c_1; /* from menu.c 268 */ int lock_menu_c_2; /* from menu.c 269 */ char *buf_menu_c_1; /* from menu.c 270 */ GtkWidget *signal_popup_menu; /* from menu.c */ GtkWidget *sst_signal_popup_menu; /* from menu.c */ /* * mouseover.c */ char disable_mouseover; /* from mouseover.c 271 */ GtkWidget *mouseover_mouseover_c_1; /* from mouseover.c 272 */ GtkWidget *mo_area_mouseover_c_1; /* from mouseover.c 273 */ GdkDrawable *mo_pixmap_mouseover_c_1; /* from mouseover.c 274 */ GdkGC *mo_dk_gray_mouseover_c_1; /* from mouseover.c 275 */ GdkGC *mo_black_mouseover_c_1; /* from mouseover.c 276 */ int mo_width_mouseover_c_1; /* from mouseover.c 277 */ int mo_height_mouseover_c_1; /* from mouseover.c 278 */ /* * pagebuttons.c */ double page_divisor; /* from pagebuttons.c 279 */ /* * pixmaps.c */ GdkDrawable *redo_pixmap; /* from pixmaps.c */ GdkDrawable *redo_mask; /* from pixmaps.c */ GdkDrawable *larrow_pixmap; /* from pixmaps.c 281 */ GdkDrawable *larrow_mask; /* from pixmaps.c 282 */ GdkDrawable *rarrow_pixmap; /* from pixmaps.c 284 */ GdkDrawable *rarrow_mask; /* from pixmaps.c 285 */ GdkDrawable *zoomin_pixmap; /* from pixmaps.c 287 */ GdkDrawable *zoomin_mask; /* from pixmaps.c 288 */ GdkDrawable *zoomout_pixmap; /* from pixmaps.c 290 */ GdkDrawable *zoomout_mask; /* from pixmaps.c 291 */ GdkDrawable *zoomfit_pixmap; /* from pixmaps.c 293 */ GdkDrawable *zoomfit_mask; /* from pixmaps.c 294 */ GdkDrawable *zoomundo_pixmap; /* from pixmaps.c 296 */ GdkDrawable *zoomundo_mask; /* from pixmaps.c 297 */ GdkDrawable *zoom_larrow_pixmap; /* from pixmaps.c 299 */ GdkDrawable *zoom_larrow_mask; /* from pixmaps.c 300 */ GdkDrawable *zoom_rarrow_pixmap; /* from pixmaps.c 302 */ GdkDrawable *zoom_rarrow_mask; /* from pixmaps.c 303 */ GdkDrawable *prev_page_pixmap; /* from pixmaps.c 305 */ GdkDrawable *prev_page_mask; /* from pixmaps.c 306 */ GdkDrawable *next_page_pixmap; /* from pixmaps.c 308 */ GdkDrawable *next_page_mask; /* from pixmaps.c 309 */ GdkDrawable *wave_info_pixmap; /* from pixmaps.c 311 */ GdkDrawable *wave_info_mask; /* from pixmaps.c 312 */ GdkDrawable *wave_alert_pixmap; /* from pixmaps.c 314 */ GdkDrawable *wave_alert_mask; /* from pixmaps.c 315 */ GdkDrawable *hiericon_module_pixmap; /* from pixmaps.c */ GdkDrawable *hiericon_module_mask; /* from pixmaps.c */ GdkDrawable *hiericon_task_pixmap; /* from pixmaps.c */ GdkDrawable *hiericon_task_mask; /* from pixmaps.c */ GdkDrawable *hiericon_function_pixmap; /* from pixmaps.c */ GdkDrawable *hiericon_function_mask; /* from pixmaps.c */ GdkDrawable *hiericon_begin_pixmap; /* from pixmaps.c */ GdkDrawable *hiericon_begin_mask; /* from pixmaps.c */ GdkDrawable *hiericon_fork_pixmap; /* from pixmaps.c */ GdkDrawable *hiericon_fork_mask; /* from pixmaps.c */ GdkDrawable *hiericon_interface_pixmap; GdkDrawable *hiericon_interface_mask; GdkDrawable *hiericon_svpackage_pixmap; GdkDrawable *hiericon_svpackage_mask; GdkDrawable *hiericon_program_pixmap; GdkDrawable *hiericon_program_mask; GdkDrawable *hiericon_class_pixmap; GdkDrawable *hiericon_class_mask; GdkDrawable *hiericon_record_pixmap; GdkDrawable *hiericon_record_mask; GdkDrawable *hiericon_generate_pixmap; GdkDrawable *hiericon_generate_mask; GdkDrawable *hiericon_design_pixmap; GdkDrawable *hiericon_design_mask; GdkDrawable *hiericon_block_pixmap; GdkDrawable *hiericon_block_mask; GdkDrawable *hiericon_generateif_pixmap; GdkDrawable *hiericon_generateif_mask; GdkDrawable *hiericon_generatefor_pixmap; GdkDrawable *hiericon_generatefor_mask; GdkDrawable *hiericon_instance_pixmap; GdkDrawable *hiericon_instance_mask; GdkDrawable *hiericon_package_pixmap; GdkDrawable *hiericon_package_mask; GdkDrawable *hiericon_signal_pixmap; GdkDrawable *hiericon_signal_mask; GdkDrawable *hiericon_portin_pixmap; GdkDrawable *hiericon_portin_mask; GdkDrawable *hiericon_portout_pixmap; GdkDrawable *hiericon_portout_mask; GdkDrawable *hiericon_portinout_pixmap; GdkDrawable *hiericon_portinout_mask; GdkDrawable *hiericon_buffer_pixmap; GdkDrawable *hiericon_buffer_mask; GdkDrawable *hiericon_linkage_pixmap; GdkDrawable *hiericon_linkage_mask; /* * print.c */ int inch_print_c_1; /* from print.c 316 */ double ps_chwidth_print_c_1; /* from print.c 317 */ double ybound_print_c_1; /* from print.c 318 */ int pr_signal_fill_width_print_c_1; /* from print.c 319 */ int ps_nummaxchars_print_c_1; /* from print.c 320 */ char ps_fullpage; /* from print.c 321 */ int ps_maxveclen; /* from print.c 322 */ int liney_max; /* from print.c 323 */ /* * ptranslate.c */ int current_translate_proc; /* from ptranslate.c 326 */ int current_filter_ptranslate_c_1; /* from ptranslate.c 327 */ int num_proc_filters; /* from ptranslate.c 328 */ char **procsel_filter; /* from ptranslate.c 329 */ struct pipe_ctx **proc_filter; /* from ptranslate.c 330 */ int is_active_ptranslate_c_2; /* from ptranslate.c 331 */ char *fcurr_ptranslate_c_1; /* from ptranslate.c 332 */ GtkWidget *window_ptranslate_c_5; /* from ptranslate.c 333 */ GtkWidget *clist_ptranslate_c_2; /* from ptranslate.c 334 */ /* * rc.c */ int rc_line_no; /* from rc.c 336 */ int possibly_use_rc_defaults; /* from rc.c 337 */ char *editor_name; /* from rc.c */ /* * regex.c */ struct re_pattern_buffer *preg_regex_c_1; /* from regex.c 339 */ int *regex_ok_regex_c_1; /* from regex.c 340 */ /* * renderopt.c */ #ifdef WAVE_GTK_UNIX_PRINT GtkPrintSettings *gprs; GtkPageSetup *gps; char *gp_tfn; #endif char is_active_renderopt_c_3; /* from renderopt.c 341 */ GtkWidget *window_renderopt_c_6; /* from renderopt.c 342 */ char *filesel_print_pdf_renderopt_c_1; /* from renderopt.c */ char *filesel_print_ps_renderopt_c_1; /* from renderopt.c 343 */ char *filesel_print_mif_renderopt_c_1; /* from renderopt.c 344 */ char target_mutex_renderopt_c_1[4]; /* from renderopt.c 346 */ char page_mutex_renderopt_c_1[5]; /* from renderopt.c 348 */ char render_mutex_renderopt_c_1[3]; /* from renderopt.c 350 */ int page_size_type_renderopt_c_1; /* from renderopt.c 351 */ /* * savefile.c */ char *sfn; char *lcname; /* * search.c */ GtkWidget *menuitem_search[5]; /* from search.c */ GtkWidget *window1_search_c_2; /* from search.c 359 */ GtkWidget *entry_a_search_c_1; /* from search.c 360 */ char *entrybox_text_local_search_c_2; /* from search.c 361 */ void (*cleanup_e_search_c_2)(void); /* from search.c 362 */ SearchProgressData *pdata; /* from search.c 363 */ int is_active_search_c_4; /* from search.c 364 */ char is_insert_running_search_c_1; /* from search.c 365 */ char is_replace_running_search_c_1; /* from search.c 366 */ char is_append_running_search_c_1; /* from search.c 367 */ char is_searching_running_search_c_1; /* from search.c 368 */ char regex_mutex_search_c_1[5]; /* from search.c 371 */ int regex_which_search_c_1; /* from search.c 372 */ GtkWidget *window_search_c_7; /* from search.c 373 */ GtkWidget *entry_search_c_3; /* from search.c 374 */ GtkWidget *clist_search_c_3; /* from search.c 375 */ char *searchbox_text_search_c_1; /* from search.c 377 */ char bundle_direction_search_c_2; /* from search.c 378 */ void (*cleanup_search_c_5)(void); /* from search.c 379 */ int num_rows_search_c_2; /* from search.c 380 */ int selected_rows_search_c_2; /* from search.c 381 */ /* * showchange.c */ GtkWidget *button1_showchange_c_1; /* from showchange.c 382 */ GtkWidget *button2_showchange_c_1; /* from showchange.c 383 */ GtkWidget *button3_showchange_c_1; /* from showchange.c 384 */ GtkWidget *button4_showchange_c_1; /* from showchange.c 385 */ GtkWidget *button5_showchange_c_1; /* from showchange.c 386 */ GtkWidget *button6_showchange_c_1; /* from showchange.c 387 */ GtkWidget *toggle1_showchange_c_1; /* from showchange.c 388 */ GtkWidget *toggle2_showchange_c_1; /* from showchange.c 389 */ GtkWidget *toggle3_showchange_c_1; /* from showchange.c 390 */ GtkWidget *toggle4_showchange_c_1; /* from showchange.c 391 */ GtkWidget *window_showchange_c_8; /* from showchange.c 392 */ void (*cleanup_showchange_c_6)(void); /* from showchange.c 393 */ struct TraceEnt *tcache_showchange_c_1; /* from showchange.c 394 */ unsigned int flags_showchange_c_1; /* from showchange.c 395 */ /* * signalwindow.c */ GtkWidget *signalarea; /* from signalwindow.c 396 */ struct font_engine_font_t *signalfont; /* from signalwindow.c 397 */ GdkDrawable *signalpixmap; /* from signalwindow.c 398 */ #ifdef WAVE_ALLOW_QUARTZ_FLUSH_WORKAROUND char force_hide_show; #endif int max_signal_name_pixel_width; /* from signalwindow.c 399 */ int signal_pixmap_width; /* from signalwindow.c 400 */ int signal_fill_width; /* from signalwindow.c 401 */ int old_signal_fill_width; /* from signalwindow.c 402 */ int old_signal_fill_height; /* from signalwindow.c 403 */ int right_align_active; /* from signalwindow.c */ int fontheight; /* from signalwindow.c 404 */ char dnd_state; /* from signalwindow.c 405 */ unsigned int dnd_cursor_timer; /* from signalwindow.c */ GtkWidget *hscroll_signalwindow_c_1; /* from signalwindow.c 406 */ GtkObject *signal_hslider; /* from signalwindow.c 407 */ unsigned int cachedhiflag_signalwindow_c_1; /* from signalwindow.c 408 */ int cachedwhich_signalwindow_c_1; /* from signalwindow.c 409 */ struct TraceEnt *cachedtrace; /* from signalwindow.c 410 */ struct TraceEnt *shift_click_trace; /* from signalwindow.c 411 */ int trtarget_signalwindow_c_1; /* from signalwindow.c 412 */ Trptr starting_unshifted_trace; /* from signalwindow.c */ unsigned char standard_trace_dnd_degate; /* from signalwindow.c */ unsigned char use_standard_trace_select; /* from signalwindow.c */ unsigned char use_standard_clicking; /* from signalwindow.c */ unsigned char std_collapse_pressed; /* from signalwindow.c */ unsigned char std_dnd_tgt_on_signalarea; /* from signalwindow.c */ unsigned char std_dnd_tgt_on_wavearea; /* from signalwindow.c */ unsigned char signalarea_has_focus; /* from signalwindow.c */ GtkWidget *signalarea_event_box; /* from signalwindow.c */ gint keypress_handler_id; /* from signalwindow.c */ gint cached_mouseover_x; /* from signalwindow.c */ gint cached_mouseover_y; /* from signalwindow.c */ gint mouseover_counter; /* from signalwindow.c */ unsigned button2_debounce_flag : 1; /* * simplereq.c */ GtkWidget *window_simplereq_c_9; /* from simplereq.c 413 */ void (*cleanup)(GtkWidget *, void *); /* from simplereq.c 414 */ /* * splash.c */ char splash_is_loading; char splash_fix_win_title; char splash_disable; /* from splash.c 415 */ GdkDrawable *wave_splash_pixmap; /* from splash.c 417 */ GdkDrawable *wave_splash_mask; /* from splash.c 418 */ GtkWidget *splash_splash_c_1; /* from splash.c 419 */ GtkWidget *darea_splash_c_1; /* from splash.c 420 */ GTimer *gt_splash_c_1; /* from splash.c 421 */ int timeout_tag; /* from splash.c 422 */ int load_complete_splash_c_1; /* from splash.c 423 */ int cnt_splash_c_1; /* from splash.c 424 */ int prev_bar_x_splash_c_1; /* from splash.c 425 */ /* * status.c */ GtkWidget *text_status_c_2; /* from status.c 426 */ GtkWidget *vscrollbar_status_c_2; /* from status.c 427 */ #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) GtkTextIter iter_status_c_3; /* from status.c 428 */ GtkTextTag *bold_tag_status_c_3; /* from status.c 429 */ #endif /* * strace.c */ struct strace_ctx_t *strace_ctx; /* moved to strace.h */ struct strace_ctx_t strace_windows[WAVE_NUM_STRACE_WINDOWS]; int strace_current_window; int strace_repeat_count; /* * symbol.c */ #ifdef _WAVE_HAVE_JUDY Pvoid_t sym_judy; /* from symbol.c */ Pvoid_t s_selected; /* from symbol.c */ #endif struct symbol **sym_hash; /* from symbol.c 453 */ struct symbol **facs; /* from symbol.c 454 */ char facs_are_sorted; /* from symbol.c 455 */ char facs_have_symbols_state_machine; /* from symbol.c */ int numfacs; /* from symbol.c 456 */ int regions; /* from symbol.c 457 */ int longestname; /* from symbol.c 458 */ struct symchain *firstnode; /* from symbol.c 459 */ struct symchain *curnode; /* from symbol.c 460 */ int hashcache; /* from symbol.c 461 */ /* * tcl_commands.c */ char *previous_braced_tcl_string; /* * tcl_helper.c */ char in_tcl_callback; /* * timeentry.c */ GtkWidget *from_entry; /* from timeentry.c 462 */ GtkWidget *to_entry; /* from timeentry.c 463 */ /* * translate.c */ int current_translate_file; /* from translate.c 464 */ int current_filter_translate_c_2; /* from translate.c 465 */ int num_file_filters; /* from translate.c 466 */ char **filesel_filter; /* from translate.c 467 */ struct xl_tree_node **xl_file_filter; /* from translate.c 468 */ int is_active_translate_c_5; /* from translate.c 469 */ char *fcurr_translate_c_2; /* from translate.c 470 */ GtkWidget *window_translate_c_11; /* from translate.c 471 */ GtkWidget *clist_translate_c_4; /* from translate.c 472 */ /* * tree.c */ #ifdef _WAVE_HAVE_JUDY Pvoid_t sym_tree; Pvoid_t sym_tree_addresses; #endif struct tree *treeroot; /* from tree.c 473 */ struct tree *mod_tree_parent; /* from tree.c */ char *module_tree_c_1; /* from tree.c 474 */ int module_len_tree_c_1; /* from tree.c 475 */ struct tree *terminals_tchain_tree_c_1; /* from tree.c 476 */ char hier_delimeter; /* from tree.c 477 */ char hier_was_explicitly_set; /* from tree.c 478 */ char alt_hier_delimeter; /* from tree.c 479 */ int fast_tree_sort; /* from tree.c 480 */ struct symbol **facs2_tree_c_1; /* from tree.c 481 */ int facs2_pos_tree_c_1; /* from tree.c 482 */ unsigned char *talloc_pool_base; size_t talloc_idx; /* * tree_component.c */ #ifdef _WAVE_HAVE_JUDY Pvoid_t comp_name_judy; #else JRB comp_name_jrb; #endif char **comp_name_idx; int comp_name_serial; size_t comp_name_total_stringmem; int comp_name_longest; /* * treesearch_gtk1.c */ GtkWidget *window1_treesearch_gtk1_c; /* manual adds by ajb... */ GtkWidget *entry_a_treesearch_gtk1_c; char *entrybox_text_local_treesearch_gtk1_c; void (*cleanup_e_treesearch_gtk1_c)(void); struct tree *selectedtree_treesearch_gtk1_c; int is_active_treesearch_gtk1_c; GtkWidget *window_treesearch_gtk1_c; GtkWidget *tree_treesearch_gtk1_c; char bundle_direction_treesearch_gtk1_c; void (*cleanup_treesearch_gtk1_c)(void); /* ...end of manual adds */ /* * treesearch_gtk2.c */ #ifdef MAC_INTEGRATION char *dnd_helper_quartz; #endif struct string_chain_t *treeopen_chain_head; /* from bitvec.c */ struct string_chain_t *treeopen_chain_curr; /* from bitvec.c */ char tree_dnd_begin; /* from treesearch_gtk2.c */ char tree_dnd_requested; /* from treesearch_gtk2.c */ char do_dynamic_treefilter; /* from treesearch_gtk2.c */ GtkWidget *treesearch_gtk2_window_vbox; /* from treesearch_gtk2.c */ char *selected_hierarchy_name; /* from treesearch_gtk2.c */ char *selected_sig_name; /* from treesearch_gtk2.c */ GtkWidget *gtk2_tree_frame; /* from treesearch_gtk2.c */ GtkWidget *filter_entry; /* from treesearch_gtk2.c */ GtkCTreeNode *any_tree_node; /* from treesearch_gtk2.c */ struct xl_tree_node *open_tree_nodes; /* from treesearch_gtk2.c */ char autoname_bundles; /* from treesearch_gtk2.c 483 */ GtkWidget *window1_treesearch_gtk2_c_3; /* from treesearch_gtk2.c 484 */ GtkWidget *entry_a_treesearch_gtk2_c_2; /* from treesearch_gtk2.c 485 */ char *entrybox_text_local_treesearch_gtk2_c_3; /* from treesearch_gtk2.c 486 */ void (*cleanup_e_treesearch_gtk2_c_3)(void); /* from treesearch_gtk2.c 487 */ struct tree *sig_root_treesearch_gtk2_c_1; /* from treesearch_gtk2.c 488 */ struct tree *sst_sig_root_treesearch_gtk2_c_1; /* from treesearch_gtk2.c */ char *filter_str_treesearch_gtk2_c_1; /* from treesearch_gtk2.c 489 */ int filter_typ_treesearch_gtk2_c_1; int filter_typ_polarity_treesearch_gtk2_c_1; int filter_matlen_treesearch_gtk2_c_1; unsigned char filter_noregex_treesearch_gtk2_c_1; #if defined(WAVE_USE_GTK2) GtkListStore *sig_store_treesearch_gtk2_c_1; /* from treesearch_gtk2.c 490 */ GtkTreeSelection *sig_selection_treesearch_gtk2_c_1; /* from treesearch_gtk2.c 491 */ #endif int is_active_treesearch_gtk2_c_6; /* from treesearch_gtk2.c 492 */ GtkCTree *ctree_main; /* from treesearch_gtk2.c 493 */ struct autocoalesce_free_list *afl_treesearch_gtk2_c_1; /* from treesearch_gtk2.c 494 */ GtkWidget *window_treesearch_gtk2_c_12; /* from treesearch_gtk2.c 495 */ GtkWidget *tree_treesearch_gtk2_c_1; /* from treesearch_gtk2.c 496 */ char bundle_direction_treesearch_gtk2_c_3; /* from treesearch_gtk2.c 497 */ void (*cleanup_treesearch_gtk2_c_8)(void); /* from treesearch_gtk2.c 498 */ int pre_import_treesearch_gtk2_c_1; /* from treesearch_gtk2.c 499 */ Traces tcache_treesearch_gtk2_c_2; /* from treesearch_gtk2.c 500 */ unsigned char dnd_tgt_on_signalarea_treesearch_gtk2_c_1; /* from treesearch_gtk2.c 501 */ unsigned char dnd_tgt_on_wavearea_treesearch_gtk2_c_1; /* from treesearch_gtk2.c */ GtkWidget *dnd_sigview; /* from treesearch_gtk2.c */ GtkPaned *sst_vpaned; /* from treesearch_gtk2.c */ /* * ttranslate.c */ int current_translate_ttrans; int current_filter_ttranslate_c_1; int num_ttrans_filters; char **ttranssel_filter; struct pipe_ctx **ttrans_filter; int is_active_ttranslate_c_2; char *fcurr_ttranslate_c_1; GtkWidget *window_ttranslate_c_5; GtkWidget *clist_ttranslate_c_2; char *ttranslate_args; /* * vcd.c */ unsigned char do_hier_compress; /* from vcd.c */ char *prev_hier_uncompressed_name; /* from vcd.c */ jmp_buf *vcd_jmp_buf; /* from vcd.c */ int vcd_warning_filesize; /* from vcd.c 502 */ char autocoalesce; /* from vcd.c 503 */ char autocoalesce_reversal; /* from vcd.c 504 */ int vcd_explicit_zero_subscripts; /* from vcd.c 505 */ char convert_to_reals; /* from vcd.c 506 */ char atomic_vectors; /* from vcd.c 507 */ char make_vcd_save_file; /* from vcd.c 508 */ char vcd_preserve_glitches; /* from vcd.c 509 */ char vcd_preserve_glitches_real; FILE *vcd_save_handle; /* from vcd.c 510 */ FILE *vcd_handle_vcd_c_1; /* from vcd.c 511 */ char vcd_is_compressed_vcd_c_1; /* from vcd.c 512 */ off_t vcdbyteno_vcd_c_1; /* from vcd.c 513 */ int error_count_vcd_c_1; /* from vcd.c 514 */ int header_over_vcd_c_1; /* from vcd.c 515 */ int dumping_off_vcd_c_1; /* from vcd.c 516 */ TimeType start_time_vcd_c_1; /* from vcd.c 517 */ TimeType end_time_vcd_c_1; /* from vcd.c 518 */ TimeType current_time_vcd_c_1; /* from vcd.c 519 */ int num_glitches_vcd_c_2; /* from vcd.c 520 */ int num_glitch_regions_vcd_c_2; /* from vcd.c 521 */ char vcd_hier_delimeter[2]; /* from vcd.c 522 */ struct vcdsymbol *pv_vcd_c_1; /* from vcd.c 523 */ struct vcdsymbol *rootv_vcd_c_1; /* from vcd.c 524 */ char *vcdbuf_vcd_c_1; /* from vcd.c 525 */ char *vst_vcd_c_1; /* from vcd.c 526 */ char *vend_vcd_c_1; /* from vcd.c 527 */ int escaped_names_found_vcd_c_1; /* from vcd.c 528 */ struct slist *slistroot; /* from vcd.c 529 */ struct slist *slistcurr; /* from vcd.c 530 */ char *slisthier; /* from vcd.c 531 */ int slisthier_len; /* from vcd.c 532 */ int T_MAX_STR_vcd_c_1; /* from vcd.c 534 */ char *yytext_vcd_c_1; /* from vcd.c 535 */ int yylen_vcd_c_1; /* from vcd.c 536 */ int yylen_cache_vcd_c_1; /* from vcd.c 537 */ struct vcdsymbol *vcdsymroot_vcd_c_1; /* from vcd.c 538 */ struct vcdsymbol *vcdsymcurr_vcd_c_1; /* from vcd.c 539 */ struct vcdsymbol **sorted_vcd_c_1; /* from vcd.c 540 */ struct vcdsymbol **indexed_vcd_c_1; /* from vcd.c 541 */ int numsyms_vcd_c_1; /* from vcd.c 542 */ struct HistEnt *he_curr_vcd_c_1; /* from vcd.c 543 */ struct HistEnt *he_fini_vcd_c_1; /* from vcd.c 544 */ unsigned int vcd_minid_vcd_c_1; /* from vcd.c 546 */ unsigned int vcd_maxid_vcd_c_1; /* from vcd.c 547 */ int err_vcd_c_1; /* from vcd.c 548 */ off_t vcd_fsiz_vcd_c_1; /* from vcd.c 549 */ char *varsplit_vcd_c_1; /* from vcd.c 550 */ char *vsplitcurr_vcd_c_1; /* from vcd.c 551 */ int var_prevch_vcd_c_1; /* from vcd.c 552 */ /* * vcd_partial.c */ off_t vcdbyteno_vcd_partial_c_2; /* from vcd_partial.c 555 */ int error_count_vcd_partial_c_2; /* from vcd_partial.c 556 */ int header_over_vcd_partial_c_2; /* from vcd_partial.c 557 */ int dumping_off_vcd_partial_c_2; /* from vcd_partial.c 558 */ TimeType start_time_vcd_partial_c_2; /* from vcd_partial.c 559 */ TimeType end_time_vcd_partial_c_2; /* from vcd_partial.c 560 */ TimeType current_time_vcd_partial_c_2; /* from vcd_partial.c 561 */ int num_glitches_vcd_partial_c_3; /* from vcd_partial.c 562 */ int num_glitch_regions_vcd_partial_c_3; /* from vcd_partial.c 563 */ struct vcdsymbol *pv_vcd_partial_c_2; /* from vcd_partial.c 564 */ struct vcdsymbol *rootv_vcd_partial_c_2; /* from vcd_partial.c 565 */ char *vcdbuf_vcd_partial_c_2; /* from vcd_partial.c 566 */ char *vst_vcd_partial_c_2; /* from vcd_partial.c 567 */ char *vend_vcd_partial_c_2; /* from vcd_partial.c 568 */ char *consume_ptr_vcd_partial_c_1; /* from vcd_partial.c 569 */ char *buf_vcd_partial_c_2; /* from vcd_partial.c 570 */ int consume_countdown_vcd_partial_c_1; /* from vcd_partial.c 571 */ int T_MAX_STR_vcd_partial_c_2; /* from vcd_partial.c 573 */ char *yytext_vcd_partial_c_2; /* from vcd_partial.c 574 */ int yylen_vcd_partial_c_2; /* from vcd_partial.c 575 */ int yylen_cache_vcd_partial_c_2; /* from vcd_partial.c 576 */ struct vcdsymbol *vcdsymroot_vcd_partial_c_2; /* from vcd_partial.c 577 */ struct vcdsymbol *vcdsymcurr_vcd_partial_c_2; /* from vcd_partial.c 578 */ struct vcdsymbol **sorted_vcd_partial_c_2; /* from vcd_partial.c 579 */ struct vcdsymbol **indexed_vcd_partial_c_2; /* from vcd_partial.c 580 */ int numsyms_vcd_partial_c_2; /* from vcd_partial.c 582 */ unsigned int vcd_minid_vcd_partial_c_2; /* from vcd_partial.c 584 */ unsigned int vcd_maxid_vcd_partial_c_2; /* from vcd_partial.c 585 */ int err_vcd_partial_c_2; /* from vcd_partial.c 586 */ char *varsplit_vcd_partial_c_2; /* from vcd_partial.c 587 */ char *vsplitcurr_vcd_partial_c_2; /* from vcd_partial.c 588 */ int var_prevch_vcd_partial_c_2; /* from vcd_partial.c 589 */ int timeset_vcd_partial_c_1; /* from vcd_partial.c 592 */ /* * vcd_recoder.c */ struct vlist_t *time_vlist_vcd_recoder_c_1; /* from vcd_recoder.c 593 */ struct vlist_t *time_vlist_vcd_recoder_write; /* from vcd_recoder.c */ char *fastload_depacked; /* from vcd_recoder.c */ char *fastload_current; /* from vcd_recoder.c */ unsigned int time_vlist_count_vcd_recoder_c_1; /* from vcd_recoder.c 594 */ FILE *vcd_handle_vcd_recoder_c_2; /* from vcd_recoder.c 595 */ char vcd_is_compressed_vcd_recoder_c_2; /* from vcd_recoder.c 596 */ char use_fastload; off_t vcdbyteno_vcd_recoder_c_3; /* from vcd_recoder.c 597 */ int error_count_vcd_recoder_c_3; /* from vcd_recoder.c 598 */ int header_over_vcd_recoder_c_3; /* from vcd_recoder.c 599 */ int dumping_off_vcd_recoder_c_3; /* from vcd_recoder.c 600 */ TimeType start_time_vcd_recoder_c_3; /* from vcd_recoder.c 601 */ TimeType end_time_vcd_recoder_c_3; /* from vcd_recoder.c 602 */ TimeType current_time_vcd_recoder_c_3; /* from vcd_recoder.c 603 */ int num_glitches_vcd_recoder_c_4; /* from vcd_recoder.c 604 */ int num_glitch_regions_vcd_recoder_c_4; /* from vcd_recoder.c 605 */ struct vcdsymbol *pv_vcd_recoder_c_3; /* from vcd_recoder.c 606 */ struct vcdsymbol *rootv_vcd_recoder_c_3; /* from vcd_recoder.c 607 */ char *vcdbuf_vcd_recoder_c_3; /* from vcd_recoder.c 608 */ char *vst_vcd_recoder_c_3; /* from vcd_recoder.c 609 */ char *vend_vcd_recoder_c_3; /* from vcd_recoder.c 610 */ int T_MAX_STR_vcd_recoder_c_3; /* from vcd_recoder.c 612 */ char *yytext_vcd_recoder_c_3; /* from vcd_recoder.c 613 */ int yylen_vcd_recoder_c_3; /* from vcd_recoder.c 614 */ int yylen_cache_vcd_recoder_c_3; /* from vcd_recoder.c 615 */ struct vcdsymbol *vcdsymroot_vcd_recoder_c_3; /* from vcd_recoder.c 616 */ struct vcdsymbol *vcdsymcurr_vcd_recoder_c_3; /* from vcd_recoder.c 617 */ struct vcdsymbol **sorted_vcd_recoder_c_3; /* from vcd_recoder.c 618 */ struct vcdsymbol **indexed_vcd_recoder_c_3; /* from vcd_recoder.c 619 */ int numsyms_vcd_recoder_c_3; /* from vcd_recoder.c 620 */ unsigned int vcd_minid_vcd_recoder_c_3; /* from vcd_recoder.c 621 */ unsigned int vcd_maxid_vcd_recoder_c_3; /* from vcd_recoder.c 622 */ int err_vcd_recoder_c_3; /* from vcd_recoder.c 623 */ off_t vcd_fsiz_vcd_recoder_c_2; /* from vcd_recoder.c 624 */ char *varsplit_vcd_recoder_c_3; /* from vcd_recoder.c 625 */ char *vsplitcurr_vcd_recoder_c_3; /* from vcd_recoder.c 626 */ int var_prevch_vcd_recoder_c_3; /* from vcd_recoder.c 627 */ unsigned int vcd_hash_max; /* from vcd_recoder.c */ int vcd_hash_kill; /* from vcd_recoder.c */ /* * vcd_saver.c */ FILE *f_vcd_saver_c_1; /* from vcd_saver.c 630 */ char buf_vcd_saver_c_3[16]; /* from vcd_saver.c 631 */ struct vcdsav_tree_node **hp_vcd_saver_c_1; /* from vcd_saver.c 632 */ struct namehier *nhold_vcd_saver_c_1; /* from vcd_saver.c 633 */ /* * vlist.c */ char vlist_spill_to_disk; char vlist_prepack; FILE *vlist_handle; off_t vlist_bytes_written; int vlist_compression_depth; /* from vlist.c 634 */ /* * vzt.c */ struct vzt_rd_trace *vzt_vzt_c_1; /* from vzt.c 635 */ TimeType first_cycle_vzt_c_3; /* from vzt.c 636 */ TimeType last_cycle_vzt_c_3; /* from vzt.c 637 */ TimeType total_cycles_vzt_c_3; /* from vzt.c 638 */ struct lx2_entry *vzt_table_vzt_c_1; /* from vzt.c 639 */ struct fac *mvlfacs_vzt_c_3; /* from vzt.c 640 */ int busycnt_vzt_c_2; /* from vzt.c 641 */ /* * wavewindow.c */ char highlight_wavewindow; /* from wavewindow.c */ char alt_wheel_mode; /* from wavewindow.c */ char use_scrollwheel_as_y; /* from wavewindow.c */ char enable_slider_zoom; /* from wavewindow.c */ int m1x_wavewindow_c_1; /* from wavewindow.c 642 */ int m2x_wavewindow_c_1; /* from wavewindow.c 643 */ char black_and_white; /* from wavewindow.c */ char signalwindow_width_dirty; /* from wavewindow.c 644 */ char enable_ghost_marker; /* from wavewindow.c 645 */ char enable_horiz_grid; /* from wavewindow.c 646 */ char enable_vert_grid; /* from wavewindow.c 647 */ char use_big_fonts; /* from wavewindow.c 648 */ char use_nonprop_fonts; /* from wavewindow.c 649 */ char do_resize_signals; /* from wavewindow.c 650 */ char first_unsized_signals; int initial_signal_window_width; char constant_marker_update; /* from wavewindow.c 651 */ char use_roundcaps; /* from wavewindow.c 652 */ char show_base; /* from wavewindow.c 653 */ char wave_scrolling; /* from wavewindow.c 654 */ int vector_padding; /* from wavewindow.c 655 */ unsigned int in_button_press_wavewindow_c_1; /* from wavewindow.c 656 */ char left_justify_sigs; /* from wavewindow.c 657 */ char zoom_pow10_snap; /* from wavewindow.c 658 */ char zoom_dyn; /* from menu.c */ char zoom_dyne; /* from menu.c */ int cursor_snap; /* from wavewindow.c 659 */ float old_wvalue; /* from wavewindow.c 660 */ struct blackout_region_t *blackout_regions; /* from wavewindow.c 661 */ TimeType zoom; /* from wavewindow.c 662 */ TimeType scale; /* from wavewindow.c 663 */ TimeType nsperframe; /* from wavewindow.c 664 */ double pixelsperframe; /* from wavewindow.c 665 */ double hashstep; /* from wavewindow.c 666 */ TimeType prevtim_wavewindow_c_1; /* from wavewindow.c 667 */ double pxns; /* from wavewindow.c 668 */ double nspx; /* from wavewindow.c 669 */ double zoombase; /* from wavewindow.c 670 */ struct TraceEnt *topmost_trace; /* from wavewindow.c 671 */ int waveheight; /* from wavewindow.c 672 */ int wavecrosspiece; /* from wavewindow.c 673 */ int wavewidth; /* from wavewindow.c 674 */ struct font_engine_font_t *wavefont; /* from wavewindow.c 675 */ struct font_engine_font_t *wavefont_smaller; /* from wavewindow.c 676 */ GtkWidget *wavearea; /* from wavewindow.c 677 */ GtkWidget *vscroll_wavewindow_c_1; /* from wavewindow.c 678 */ GtkWidget *hscroll_wavewindow_c_2; /* from wavewindow.c 679 */ GdkDrawable *wavepixmap_wavewindow_c_1; /* from wavewindow.c 680 */ GtkObject *wave_vslider; /* from wavewindow.c 681 */ GtkObject *wave_hslider; /* from wavewindow.c 682 */ TimeType named_markers[WAVE_NUM_NAMED_MARKERS]; /* from wavewindow.c 683 */ int named_marker_lock_idx; /* from menu.c */ char made_gc_contexts_wavewindow_c_1; /* from wavewindow.c 684 */ int which_t_color; GdkGC *gc_white; /* from wavewindow.c 710 */ GdkGC *gc_black; /* from wavewindow.c 711 */ struct wave_gcmaster_t gc; GdkGC *gc_rainbow[2*WAVE_NUM_RAINBOW]; char made_sgc_contexts_wavewindow_c_1; /* from wavewindow.c 709 */ char fill_in_smaller_rgb_areas_wavewindow_c_1; /* from wavewindow.c 719 */ TimeType prev_markertime; /* from wavewindow.c */ struct wave_gcmaster_t gccache; int analog_redraw_skip_count; /* from wavewindow.c */ int str_wid_x; int str_wid_width; int str_wid_bigw; int str_wid_state; int str_wid_slider; int str_wid_height; TimeType ruler_origin; TimeType ruler_step; /* * zoombuttons.c */ char do_zoom_center; /* from zoombuttons.c 720 */ char do_initial_zoom_fit; /* from zoombuttons.c 721 */ char do_initial_zoom_fit_used; }; struct Global *initialize_globals(void); void reload_into_new_context(void); void strcpy2_into_new_context(struct Global *g, char **newstrref, char **oldstrref); void free_and_destroy_page_context(void); void dead_context_sweep(void); void install_focus_cb(GtkWidget *w, unsigned long ptr_offset); gulong gtkwave_signal_connect_x(GtkObject *object, const gchar *name, GtkSignalFunc func, gpointer data, char *f, unsigned long line); gulong gtkwave_signal_connect_object_x(GtkObject *object, const gchar *name, GtkSignalFunc func, gpointer data, char *f, unsigned long line); #ifdef GTKWAVE_SIGNAL_CONNECT_DEBUG #define gtkwave_signal_connect(a,b,c,d) gtkwave_signal_connect_x(a,b,c,d,__FILE__,__LINE__) #define gtkwave_signal_connect_object(a,b,c,d) gtkwave_signal_connect_object_x(a,b,c,d,__FILE__,__LINE__) #else #define gtkwave_signal_connect(a,b,c,d) gtkwave_signal_connect_x(a,b,c,d,NULL,0) #define gtkwave_signal_connect_object(a,b,c,d) gtkwave_signal_connect_object_x(a,b,c,d,NULL,0) #endif void set_GLOBALS_x(struct Global *g, const char *file, int line); #ifdef GTKWAVE_GLOBALS_DEBUG #define set_GLOBALS(a) set_GLOBALS_x(a,__FILE__,__LINE__) #else #define set_GLOBALS(a) set_GLOBALS_x(a,NULL,0) #endif void logbox_reload(void); void clone_icon_pointers_across_contexts(struct Global *a, struct Global *b); extern struct Global *GLOBALS; #endif gtkwave-3.3.66/src/hierpack.c0000664000076400007640000001042512360312657015327 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2008-2011. * * 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. */ #include "hierpack.h" #define VLI_SIZE (10) void out_c(unsigned char ch) { if((GLOBALS->fmem_buf_offs+1) >= GLOBALS->fmem_buf_siz) { GLOBALS->fmem_buf = realloc_2(GLOBALS->fmem_buf, GLOBALS->fmem_buf_siz = 2 * GLOBALS->fmem_buf_siz); } GLOBALS->fmem_buf[GLOBALS->fmem_buf_offs++] = ch; } static int enc_var(size_t v, unsigned char *buf) { size_t nxt; unsigned char *pnt = buf+VLI_SIZE; while((nxt = v>>7)) { *(--pnt) = (v&0x7f) | 0x80; v = nxt; } *(--pnt) = (v&0x7f); return(buf+VLI_SIZE-pnt); } static void out_write(unsigned char *s, int len) { int i; for(i=0;ido_hier_compress) { fprintf(stderr, "FACPACK | Using compressed facilities\n"); GLOBALS->fmem_buf_offs = 0; GLOBALS->fmem_buf_siz = 1024*1024; GLOBALS->fmem_buf = malloc_2(GLOBALS->fmem_buf_siz); GLOBALS->hp_buf_siz = 1024; GLOBALS->hp_buf = calloc_2(GLOBALS->hp_buf_siz, sizeof(unsigned char)); GLOBALS->hp_offs = calloc_2(GLOBALS->hp_buf_siz, sizeof(size_t)); } } void freeze_facility_pack(void) { if(GLOBALS->do_hier_compress) { free_2(GLOBALS->hp_buf); GLOBALS->hp_buf = NULL; free_2(GLOBALS->hp_offs); GLOBALS->hp_offs = NULL; GLOBALS->hp_buf_siz = 0; if(GLOBALS->fmem_buf) { GLOBALS->fmem_buf = realloc_2(GLOBALS->fmem_buf, GLOBALS->hp_prev); } fprintf(stderr, "FACPACK | Compressed %lu to %lu bytes.\n", (unsigned long)GLOBALS->fmem_uncompressed_siz, (unsigned long)GLOBALS->hp_prev); } } char *compress_facility(unsigned char *key, unsigned int len) { size_t mat = 0; size_t plen; size_t i; unsigned char vli[VLI_SIZE]; if(len > GLOBALS->hp_buf_siz) { GLOBALS->hp_buf_siz = len; GLOBALS->hp_buf = realloc_2(GLOBALS->hp_buf, GLOBALS->hp_buf_siz * sizeof(unsigned char)); GLOBALS->hp_offs = realloc_2(GLOBALS->hp_offs, GLOBALS->hp_buf_siz * sizeof(size_t)); } GLOBALS->fmem_uncompressed_siz += (len + 1); for(i=0;i<=len;i++) { if(!key[i]) break; mat = i; if(key[i] != GLOBALS->hp_buf[i]) break; } if(!mat) { GLOBALS->hp_prev += (plen = enc_var(mat, vli)); out_write(vli+VLI_SIZE-plen, plen); } else { size_t back = GLOBALS->hp_prev - GLOBALS->hp_offs[mat-1]; plen = enc_var(back, vli); if(mat > plen) { GLOBALS->hp_prev += plen; out_write(vli+VLI_SIZE-plen, plen); } else { mat = 0; GLOBALS->hp_prev += (plen = enc_var(mat, vli)); out_write(vli+VLI_SIZE-plen, plen); } } out_c(0); GLOBALS->hp_prev++; for(i=mat;ihp_buf[i] = key[i]; GLOBALS->hp_offs[i] = GLOBALS->hp_prev; GLOBALS->hp_prev++; } GLOBALS->hp_buf[i] = 0; GLOBALS->hp_offs[i] = 0; return( (((GLOBALS->hp_prev-1)<<1)|1) + ((char *)NULL) ); /* flag value with |1 to indicate is compressed */ } char *hier_decompress_flagged(char *n, int *was_packed) { size_t dcd; size_t dcd2; size_t val; char *str; int ob; int shamt; int avoid_strdup = *was_packed; *was_packed = GLOBALS->do_hier_compress; if(!GLOBALS->do_hier_compress) { return(n); } dcd = n - ((char *)NULL); if(!(dcd & 1)) /* value was flagged with |1 to indicate is compressed; malloc never returns this */ { *was_packed = 0; return(n); } dcd >>= 1; str = GLOBALS->module_tree_c_1; ob = GLOBALS->longestname + 1; str[--ob] = 0; do { while(GLOBALS->fmem_buf[dcd]) { str[--ob] = GLOBALS->fmem_buf[dcd]; dcd--; } dcd2 = --dcd; val = 0; shamt = 0; for(;;) { val |= ((GLOBALS->fmem_buf[dcd2] & 0x7f) << shamt); shamt += 7; if(!(GLOBALS->fmem_buf[dcd2] & 0x80)) break; dcd2--; } dcd = dcd2 - val; } while(val); return((avoid_strdup != HIER_DEPACK_ALLOC) ? (str+ob) : strdup_2(str+ob)); } gtkwave-3.3.66/src/gconf.c0000664000076400007640000002526112374745343014650 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2012. * * 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. */ #include #include "gconf.h" #include "wavealloca.h" #include "globals.h" int wave_rpc_id = 0; #ifdef WAVE_HAVE_GCONF static GConfClient* client = NULL; /************************************************************/ static void open_callback(GConfClient* gclient, guint cnxn_id, GConfEntry *entry, gpointer user_data) { (void)gclient; (void)cnxn_id; (void)user_data; if (gconf_entry_get_value (entry) == NULL) { /* value is unset */ } else { if (gconf_entry_get_value (entry)->type == GCONF_VALUE_STRING) { fprintf(stderr, "GTKWAVE | RPC Open: '%s'\n", gconf_value_get_string (gconf_entry_get_value (entry)) ); deal_with_rpc_open(gconf_value_get_string (gconf_entry_get_value (entry)), NULL); gconf_entry_set_value(entry, NULL); } else { /* value is of wrong type */ } } } static void quit_callback(GConfClient* gclient, guint cnxn_id, GConfEntry *entry, gpointer user_data) { (void)gclient; (void)cnxn_id; (void)user_data; if (gconf_entry_get_value (entry) == NULL) { /* value is unset */ } else { if (gconf_entry_get_value (entry)->type == GCONF_VALUE_STRING) { const char *rc = gconf_value_get_string (gconf_entry_get_value (entry)); int rcv = atoi(rc); fprintf(stderr, "GTKWAVE | RPC Quit: exit return code %d\n", rcv); gconf_entry_set_value(entry, NULL); exit(rcv); } else { /* value is of wrong type */ } } } static void reload_callback(GConfClient* gclient, guint cnxn_id, GConfEntry *entry, gpointer user_data) { (void)gclient; (void)cnxn_id; (void)user_data; if (gconf_entry_get_value (entry) == NULL) { /* value is unset */ } else { if (gconf_entry_get_value (entry)->type == GCONF_VALUE_STRING) { if(in_main_iteration()) return; reload_into_new_context(); gconf_entry_set_value(entry, NULL); } else { /* value is of wrong type */ } } } static void zoomfull_callback(GConfClient* gclient, guint cnxn_id, GConfEntry *entry, gpointer user_data) { (void)gclient; (void)cnxn_id; (void)user_data; if (gconf_entry_get_value (entry) == NULL) { /* value is unset */ } else { if (gconf_entry_get_value (entry)->type == GCONF_VALUE_STRING) { if(in_main_iteration()) return; service_zoom_full(NULL, NULL); gconf_entry_set_value(entry, NULL); } else { /* value is of wrong type */ } } } static void writesave_callback(GConfClient* gclient, guint cnxn_id, GConfEntry *entry, gpointer user_data) { (void)gclient; (void)cnxn_id; (void)user_data; if (gconf_entry_get_value (entry) == NULL) { /* value is unset */ } else { if (gconf_entry_get_value (entry)->type == GCONF_VALUE_STRING) { const char *fni = gconf_value_get_string (gconf_entry_get_value (entry)); if(fni && !in_main_iteration()) { int use_arg = strcmp(fni, "+"); /* plus filename uses default */ const char *fn = use_arg ? fni : GLOBALS->filesel_writesave; if(fn) { FILE *wave; if(!(wave=fopen(fn, "wb"))) { fprintf(stderr, "GTKWAVE | RPC Writesave: error opening save file '%s' for writing.\n", fn); perror("Why"); errno=0; } else { write_save_helper(fn, wave); if(use_arg) { if(GLOBALS->filesel_writesave) { free_2(GLOBALS->filesel_writesave); } GLOBALS->filesel_writesave = strdup_2(fn); } wave_gconf_client_set_string("/current/savefile", fn); fclose(wave); fprintf(stderr, "GTKWAVE | RPC Writesave: wrote save file '%s'.\n", GLOBALS->filesel_writesave); } } } gconf_entry_set_value(entry, NULL); } else { /* value is of wrong type */ } } } static void move_to_time_callback(GConfClient* gclient, guint cnxn_id, GConfEntry *entry, gpointer user_data) { (void)gclient; (void)cnxn_id; (void)user_data; if (gconf_entry_get_value (entry) == NULL) { /* value is unset */ } else { if (gconf_entry_get_value (entry)->type == GCONF_VALUE_STRING) { const char *str = gconf_value_get_string (gconf_entry_get_value (entry)); if(str && !in_main_iteration()) { char *e_copy = GLOBALS->entrybox_text; GLOBALS->entrybox_text=strdup_2(str); movetotime_cleanup(NULL, NULL); GLOBALS->entrybox_text = e_copy; } gconf_entry_set_value(entry, NULL); } else { /* value is of wrong type */ } } } static void zoom_size_callback(GConfClient* gclient, guint cnxn_id, GConfEntry *entry, gpointer user_data) { (void)gclient; (void)cnxn_id; (void)user_data; if (gconf_entry_get_value (entry) == NULL) { /* value is unset */ } else { if (gconf_entry_get_value (entry)->type == GCONF_VALUE_STRING) { const char *str = gconf_value_get_string (gconf_entry_get_value (entry)); if(str && !in_main_iteration()) { char *e_copy = GLOBALS->entrybox_text; GLOBALS->entrybox_text=strdup_2(str); zoomsize_cleanup(NULL, NULL); GLOBALS->entrybox_text = e_copy; } gconf_entry_set_value(entry, NULL); } else { /* value is of wrong type */ } } } /************************************************************/ static void remove_client(void) { if(client) { g_object_unref(client); } } void wave_gconf_init(int argc, char **argv) { if(!client) { char *ks = wave_alloca(WAVE_GCONF_DIR_LEN + 32 + 32 + 1); int len = sprintf(ks, WAVE_GCONF_DIR"/%d", wave_rpc_id); gconf_init(argc, argv, NULL); client = gconf_client_get_default(); atexit(remove_client); gconf_client_add_dir(client, ks, GCONF_CLIENT_PRELOAD_NONE, NULL); strcpy(ks + len, "/open"); gconf_client_notify_add(client, ks, open_callback, NULL, /* user data */ NULL, NULL); strcpy(ks + len, "/quit"); gconf_client_notify_add(client, ks, quit_callback, NULL, /* user data */ NULL, NULL); strcpy(ks + len, "/writesave"); gconf_client_notify_add(client, ks, writesave_callback, NULL, /* user data */ NULL, NULL); strcpy(ks + len, "/reload"); gconf_client_notify_add(client, ks, reload_callback, NULL, /* user data */ NULL, NULL); strcpy(ks + len, "/zoom_full"); gconf_client_notify_add(client, ks, zoomfull_callback, NULL, /* user data */ NULL, NULL); strcpy(ks + len, "/move_to_time"); gconf_client_notify_add(client, ks, move_to_time_callback, NULL, /* user data */ NULL, NULL); strcpy(ks + len, "/zoom_size"); gconf_client_notify_add(client, ks, zoom_size_callback, NULL, /* user data */ NULL, NULL); } } gboolean wave_gconf_client_set_string(const gchar *key, const gchar *val) { if(key && client) { char *ks = wave_alloca(WAVE_GCONF_DIR_LEN + 32 + strlen(key) + 1); sprintf(ks, WAVE_GCONF_DIR"/%d%s", wave_rpc_id, key); return(gconf_client_set_string(client, ks, val ? val : "", NULL)); } return(FALSE); } static gchar *wave_gconf_client_get_string(const gchar *key) { if(key && client) { char *ks = wave_alloca(WAVE_GCONF_DIR_LEN + 32 + strlen(key) + 1); sprintf(ks, WAVE_GCONF_DIR"/%d%s", wave_rpc_id, key); return(gconf_client_get_string(client, ks, NULL)); } return(NULL); } void wave_gconf_restore(char **dumpfile, char **savefile, char **rcfile, char **wave_pwd, int *opt_vcd) { char *s; if(dumpfile && savefile && rcfile && wave_pwd && opt_vcd) { if(*dumpfile) { free_2(*dumpfile); *dumpfile = NULL; } s = wave_gconf_client_get_string("/current/dumpfile"); if(s) { if(s[0]) *dumpfile = strdup_2(s); g_free(s); } if(*savefile) { free_2(*savefile); *savefile = NULL; } s = wave_gconf_client_get_string("/current/savefile"); if(s) { if(s[0]) *savefile = strdup_2(s); g_free(s); } if(*rcfile) { free_2(*rcfile); *rcfile = NULL; } s = wave_gconf_client_get_string("/current/rcfile"); if(s) { if(s[0]) *rcfile = strdup_2(s); g_free(s); } if(*wave_pwd) { free_2(*wave_pwd); *wave_pwd = NULL; } s = wave_gconf_client_get_string("/current/pwd"); if(s) { if(s[0]) *wave_pwd = strdup_2(s); g_free(s); } s = wave_gconf_client_get_string("/current/optimized_vcd"); if(s) { if(s[0]) *opt_vcd = atoi(s); g_free(s); } } } #else void wave_gconf_init(int argc, char **argv) { (void)argc; (void)argv; } gboolean wave_gconf_client_set_string(const gchar *key, const gchar *val) { (void)key; (void)val; return(FALSE); } void wave_gconf_restore(char **dumpfile, char **savefile, char **rcfile, char **wave_pwd, int *opt_vcd) { (void)dumpfile; (void)savefile; (void)rcfile; (void)wave_pwd; (void)opt_vcd; /* nothing */ } #endif /* Examples of RPC manipulation: gconftool-2 --dump /com.geda.gtkwave gconftool-2 --dump /com.geda.gtkwave --recursive-unset gconftool-2 --type string --set /com.geda.gtkwave/0/open /pub/systema_packed.fst gconftool-2 --type string --set /com.geda.gtkwave/0/open `pwd`/`basename -- des.gtkw` gconftool-2 --type string --set /com.geda.gtkwave/0/writesave /tmp/this.gtkw gconftool-2 --type string --set /com.geda.gtkwave/0/writesave + gconftool-2 --type string --set /com.geda.gtkwave/0/quit 0 gconftool-2 --type string --set /com.geda.gtkwave/0/reload 0 gconftool-2 --type string --set /com.geda.gtkwave/0/zoom_full 0 gconftool-2 --type string --set /com.geda.gtkwave/0/zoom_size -- -4.6 gconftool-2 --type string --set /com.geda.gtkwave/0/move_to_time 123ns gconftool-2 --type string --set /com.geda.gtkwave/0/move_to_time A */ gtkwave-3.3.66/src/vcd_partial.h0000664000076400007640000000063111523063250016024 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2010 * * 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. */ #ifndef WAVE_VCD_PARTIAL_H #define WAVE_VCD_PARTIAL_H void update_endcap_times_for_partial_vcd(void); #endif gtkwave-3.3.66/src/fetchbuttons.h0000664000076400007640000000106511523063250016246 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2010 * * 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. */ #ifndef WAVE_FETCHBUTTONS_H #define WAVE_FETCHBUTTONS_H void fetch_left(GtkWidget *text, gpointer data); void fetch_right(GtkWidget *text, gpointer data); void discard_left(GtkWidget *text, gpointer data); void discard_right(GtkWidget *text, gpointer data); #endif gtkwave-3.3.66/src/pixmaps.h0000664000076400007640000000115612341266475015235 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2011. * * 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. */ #include "globals.h" #ifndef WAVE_PIXMAPS_H #define WAVE_PIXMAPS_H #include #ifdef MAC_INTEGRATION GdkPixbuf * #else void #endif make_pixmaps(GtkWidget *window); #ifdef WAVE_USE_GTK2 #define WAVE_SPLASH_X (512) #define WAVE_SPLASH_Y (384) void make_splash_pixmaps(GtkWidget *window); #endif #endif gtkwave-3.3.66/src/tcl_helper.c0000664000076400007640000022620712372010236015660 0ustar bybellbybell/* * Copyright (c) Tony Bybell and Concept Engineering GmbH 2008-2014. * * 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. */ #include #include "globals.h" #include #include #if WAVE_USE_GTK2 #include #endif #include #include #include #include #include #include "gtk12compat.h" #include "analyzer.h" #include "tree.h" #include "symbol.h" #include "vcd.h" #include "lx2.h" #include "busy.h" #include "debug.h" #include "hierpack.h" #include "menu.h" #include "tcl_helper.h" #include "tcl_np.h" #if !defined __MINGW32__ && !defined _MSC_VER #include #include #endif #ifdef _MSC_VER #define strcasecmp _stricmp #endif #if (defined(__MACH__) && defined(__APPLE__)) #include #endif /*---------------------------------------------------------------------- * tclBackslash -- Figure out how to handle a backslash sequence in tcl list. * * Results: * The return value is the character that should be substituted * in place of the backslash sequence that starts at src. If * readPtr isn't NULL then it is filled in with a count of the * number of characters in the backslash sequence. *---------------------------------------------------------------------- */ static char tclBackslash(const char* src, int* readPtr) { const char* p = src+1; char result; int count = 2; switch (*p) { /* * Note: in the conversions below, use absolute values (e.g., * 0xa) rather than symbolic values (e.g. \n) that get converted * by the compiler. It's possible that compilers on some * platforms will do the symbolic conversions differently, which * could result in non-portable Tcl scripts. */ case 'a': result = 0x7; break; case 'b': result = 0x8; break; case 'f': result = 0xc; break; case 'n': result = 0xa; break; case 'r': result = 0xd; break; case 't': result = 0x9; break; case 'v': result = 0xb; break; case 'x': if (isxdigit((int)(unsigned char)p[1])) { char* end; result = (char)strtoul(p+1, &end, 16); count = end - src; } else { count = 2; result = 'x'; } break; case '\n': do { p++; } while ((*p == ' ') || (*p == '\t')); result = ' '; count = p - src; break; case 0: result = '\\'; count = 1; break; default: /* Check for an octal number \oo?o? */ if (isdigit((int)(unsigned char)*p)) { result = *p - '0'; p++; if (!isdigit((int)(unsigned char)*p)) break; count = 3; result = (result << 3) + (*p - '0'); p++; if (!isdigit((int)(unsigned char)*p)) break; count = 4; result = (result << 3) + (*p - '0'); break; } result = *p; count = 2; break; } if (readPtr) *readPtr = count; return result; } /*---------------------------------------------------------------------- * tclFindElement -- locate the first (or next) element in the list. * * Results: * The return value is normally 1 (OK), which means that the * element was successfully located. If 0 (ERROR) is returned * it means that list didn't have proper tcl list structure * (no detailed error message). * * If 1 (OK) is returned, then *elementPtr will be set to point * to the first element of list, and *nextPtr will be set to point * to the character just after any white space following the last * character that's part of the element. If this is the last argument * in the list, then *nextPtr will point to the NULL character at the * end of list. If sizePtr is non-NULL, *sizePtr is filled in with * the number of characters in the element. If the element is in * braces, then *elementPtr will point to the character after the * opening brace and *sizePtr will not include either of the braces. * If there isn't an element in the list, *sizePtr will be zero, and * both *elementPtr and *termPtr will refer to the null character at * the end of list. Note: this procedure does NOT collapse backslash * sequences. *---------------------------------------------------------------------- */ static int tclFindElement(const char* list, const char** elementPtr, const char** nextPtr, int* sizePtr, int *bracePtr) { register const char *p; int openBraces = 0; int inQuotes = 0; int size; /* * Skim off leading white space and check for an opening brace or * quote. */ while (isspace((int)(unsigned char)*list)) list++; if (*list == '{') { /* } */ openBraces = 1; list++; } else if (*list == '"') { inQuotes = 1; list++; } if (bracePtr) *bracePtr = openBraces; /* * Find the end of the element (either a space or a close brace or * the end of the string). */ for (p=list; 1; p++) { switch (*p) { /* * Open brace: don't treat specially unless the element is * in braces. In this case, keep a nesting count. */ case '{': if (openBraces) openBraces++; break; /* * Close brace: if element is in braces, keep nesting * count and quit when the last close brace is seen. */ case '}': if (openBraces == 1) { size = p - list; p++; if (isspace((int)(unsigned char)*p) || (*p == 0)) goto done; /* list element in braces followed by garbage instead of * space */ return 0/*ERROR*/; } else if (openBraces) { openBraces--; } break; /* * Backslash: skip over everything up to the end of the * backslash sequence. */ case '\\': { int siz; tclBackslash(p, &siz); p += siz - 1; break; } /* * Space: ignore if element is in braces or quotes; otherwise * terminate element. */ case ' ': case '\f': case '\n': case '\r': case '\t': case '\v': if ((openBraces == 0) && !inQuotes) { size = p - list; goto done; } break; /* * Double-quote: if element is in quotes then terminate it. */ case '"': if (inQuotes) { size = p-list; p++; if (isspace((int)(unsigned char)*p) || (*p == 0)) goto done; /* list element in quotes followed by garbage instead of * space */ return 0/*ERROR*/; } break; /* * End of list: terminate element. */ case 0: if (openBraces || inQuotes) { /* unmatched open brace or quote in list */ return 0/*ERROR*/; } size = p - list; goto done; } } done: while (isspace((int)(unsigned char)*p)) p++; *elementPtr = list; *nextPtr = p; if (sizePtr) *sizePtr = size; return 1/*OK*/; } /*---------------------------------------------------------------------- * tclCopyAndCollapse -- Copy a string and eliminate any backslashes that * aren't in braces. * * Results: * Count characters get copied from src to dst. Along the way, if * backslash sequences are found outside braces, the backslashes are * eliminated in the copy. After scanning count chars from source, a * null character is placed at the end of dst. *---------------------------------------------------------------------- */ static void tclCopyAndCollapse(int count, const char *src, char *dst) { register char c; int numRead; for (c = *src; count > 0; src++, c = *src, count--) { if (c == '\\') { *dst = tclBackslash(src, &numRead); dst++; src += numRead-1; count -= numRead-1; } else { *dst = c; dst++; } } *dst = 0; } /* ---------------------------------------------------------------------------- * zSplitTclList - Splits a list up into its constituent fields. * * Results: * The return value is a pointer to a list of element points, * which means that the list was successfully split up. * If NULL is returned, it means that "list" didn't have proper tcl list * structure (we don't return an error message about the details). * * This procedure does allocate a single memory block * by calling malloc to store both, the the argv pointer array and * the extracted list elements. The returned element * pointer array must be freed by calling free_2(). * * *argcPtr will get filled in with the number of valid elements * in the array. Note: *argcPtr is only modified if the procedure * returns not NULL. * ---------------------------------------------------------------------------- */ char** zSplitTclList(const char* list, int* argcPtr) { char** argv; const char* l; register char* p; int size, i, ok, elSize, brace; const char *element; /* * Figure out how much space to allocate. There must be enough * space for both the array of pointers and also for a copy of * the list. To estimate the number of pointers needed, count * the number of space characters in the list. */ for (size = 1, l = list; *l != 0; l++) { if (isspace((int)(unsigned char)*l)) size++; } size++; /* Leave space for final NULL */ i = (size * sizeof(char*)) + (l - list) + 1; argv = malloc_2(i); for (i = 0, p = (char*) (argv+size); *list != 0; i++) { ok = tclFindElement(list, &element, &list, &elSize, &brace); if (!ok) { free_2(argv); return NULL; } if (*element == 0) break; if (i >= size) { free_2(argv); /* internal error in zSplitTclList */ return NULL; } argv[i] = p; if (brace) { strncpy(p, element, elSize); p += elSize; *p = 0; p++; } else { tclCopyAndCollapse(elSize, element, p); p += elSize+1; } } argv[i] = NULL; *argcPtr = i; return argv; } /*---------------------------------------------------------------------- * tclScanElement -- scan a tcl list string to see what needs to be done. * * This procedure is a companion procedure to tclConvertElement. * * Results: * The return value is an overestimate of the number of characters * that will be needed by tclConvertElement to produce a valid * list element from string. The word at *flagPtr is filled in * with a value needed by tclConvertElement when doing the actual * conversion. * * * This procedure and tclConvertElement together do two things: * * 1. They produce a proper list, one that will yield back the * argument strings when evaluated or when disassembled with * zSplitTclList. This is the most important thing. * * 2. They try to produce legible output, which means minimizing the * use of backslashes (using braces instead). However, there are * some situations where backslashes must be used (e.g. an element * like "{abc": the leading brace will have to be backslashed. For * each element, one of three things must be done: * * (a) Use the element as-is (it doesn't contain anything special * characters). This is the most desirable option. * * (b) Enclose the element in braces, but leave the contents alone. * This happens if the element contains embedded space, or if it * contains characters with special interpretation ($, [, ;, or \), * or if it starts with a brace or double-quote, or if there are * no characters in the element. * * (c) Don't enclose the element in braces, but add backslashes to * prevent special interpretation of special characters. This is a * last resort used when the argument would normally fall under case * (b) but contains unmatched braces. It also occurs if the last * character of the argument is a backslash or if the element contains * a backslash followed by newline. * * The procedure figures out how many bytes will be needed to store * the result (actually, it overestimates). It also collects information * about the element in the form of a flags word. *---------------------------------------------------------------------- */ #define DONT_USE_BRACES 1 #define USE_BRACES 2 #define BRACES_UNMATCHED 4 static int tclScanElement(const char* string, int* flagPtr) { register const char *p; int nestingLevel = 0; int flags = 0; if (string == NULL) string = ""; p = string; if ((*p == '{') || (*p == '"') || (*p == 0)) { /* } */ flags |= USE_BRACES; } for ( ; *p != 0; p++) { switch (*p) { case '{': nestingLevel++; break; case '}': nestingLevel--; if (nestingLevel < 0) { flags |= DONT_USE_BRACES | BRACES_UNMATCHED; } break; case '[': case '$': case ';': case ' ': case '\f': case '\r': case '\t': case '\v': flags |= USE_BRACES; break; case '\n': /* lld: dont want line breaks inside a list */ flags |= DONT_USE_BRACES; break; case '\\': if ((p[1] == 0) || (p[1] == '\n')) { flags = DONT_USE_BRACES | BRACES_UNMATCHED; } else { int size; tclBackslash(p, &size); p += size-1; flags |= USE_BRACES; } break; } } if (nestingLevel != 0) { flags = DONT_USE_BRACES | BRACES_UNMATCHED; } *flagPtr = flags; /* Allow enough space to backslash every character plus leave * two spaces for braces. */ return 2*(p-string) + 2; } /*---------------------------------------------------------------------- * * tclConvertElement - convert a string into a list element * * This is a companion procedure to tclScanElement. Given the * information produced by tclScanElement, this procedure converts * a string to a list element equal to that string. * * See the comment block at tclScanElement above for details of how this * works. * * Results: * Information is copied to *dst in the form of a list element * identical to src (i.e. if zSplitTclList is applied to dst it * will produce a string identical to src). The return value is * a count of the number of characters copied (not including the * terminating NULL character). *---------------------------------------------------------------------- */ static int tclConvertElement(const char* src, char* dst, int flags) { register char *p = dst; if ((src == NULL) || (*src == 0)) { p[0] = '{'; p[1] = '}'; p[2] = 0; return 2; } if ((flags & USE_BRACES) && !(flags & DONT_USE_BRACES)) { *p = '{'; p++; for ( ; *src != 0; src++, p++) { *p = *src; } *p = '}'; p++; } else { if (*src == '{') { /* } */ /* Can't have a leading brace unless the whole element is * enclosed in braces. Add a backslash before the brace. * Furthermore, this may destroy the balance between open * and close braces, so set BRACES_UNMATCHED. */ p[0] = '\\'; p[1] = '{'; /* } */ p += 2; src++; flags |= BRACES_UNMATCHED; } for (; *src != 0 ; src++) { switch (*src) { case ']': case '[': case '$': case ';': case ' ': case '\\': case '"': *p = '\\'; p++; break; case '{': case '}': /* It may not seem necessary to backslash braces, but * it is. The reason for this is that the resulting * list element may actually be an element of a sub-list * enclosed in braces, so there may be a brace mismatch * if the braces aren't backslashed. */ if (flags & BRACES_UNMATCHED) { *p = '\\'; p++; } break; case '\f': *p = '\\'; p++; *p = 'f'; p++; continue; case '\n': *p = '\\'; p++; *p = 'n'; p++; continue; case '\r': *p = '\\'; p++; *p = 'r'; p++; continue; case '\t': *p = '\\'; p++; *p = 't'; p++; continue; case '\v': *p = '\\'; p++; *p = 'v'; p++; continue; } *p = *src; p++; } } *p = '\0'; return p-dst; } /* ============================================================================ * zMergeTclList - Creates a tcl list from a set of element strings. * * Given a collection of strings, merge them together into a * single string that has proper Tcl list structured (i.e. * zSplitTclList may be used to retrieve strings equal to the * original elements). * The merged list is stored in dynamically-allocated memory. * * Results: * The return value is the address of a dynamically-allocated string. * ============================================================================ */ char* zMergeTclList(int argc, const char** argv) { enum {LOCAL_SIZE = 20}; int localFlags[LOCAL_SIZE]; int* flagPtr; int numChars; int i; char* result; char* dst; /* Pass 1: estimate space, gather flags */ if (argc <= LOCAL_SIZE) flagPtr = localFlags; else flagPtr = malloc_2(argc*sizeof(int)); numChars = 1; for (i=0; idnd_tgt_on_signalarea_treesearch_gtk2_c_1) { WAVE_GDK_GET_POINTER(GLOBALS->signalarea->window, &x, &y, &xi, &yi, &state); WAVE_GDK_GET_POINTER_COPY; if((x<0)||(y<0)||(x>=GLOBALS->signalarea->allocation.width)||(y>=GLOBALS->signalarea->allocation.height)) return(NULL); } else if(GLOBALS->dnd_tgt_on_wavearea_treesearch_gtk2_c_1) { WAVE_GDK_GET_POINTER(GLOBALS->wavearea->window, &x, &y, &xi, &yi, &state); WAVE_GDK_GET_POINTER_COPY; if((x<0)||(y<0)||(x>=GLOBALS->wavearea->allocation.width)||(y>=GLOBALS->wavearea->allocation.height)) return(NULL); } else { return(NULL); } if((t=GLOBALS->traces.first)) { while(t) { t->flags&=~TR_HIGHLIGHT; t=t->t_next; } signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } trtarget = ((int)y / (int)GLOBALS->fontheight) - 2; if(trtarget < 0) { return(NULL); } else { t=GLOBALS->topmost_trace; } trwhich=0; while(t) { if((trwhichhier_delimeter; delim_str[1] = 0; len = 0; for(i=1;ihier_delimeter) ) { esc++; } pnt++; } if(esc) { s_new2 = calloc_2(1, len + esc); pnt = s_new; pnt2 = s_new2; while(*pnt) { if( (!isalnum((int)(unsigned char)*pnt)) && (!isspace((int)(unsigned char)*pnt)) && (*pnt != GLOBALS->hier_delimeter) ) { *(pnt2++) = '\\'; } *(pnt2++) = *(pnt++); } *unescaped_str = s_new; /* free_2(s_new); */ s_new = s_new2; } else { *unescaped_str = s_new; } } return(s_new); } /* ---------------------------------------------------------------------------- * process_tcl_list - given a tcl list, inserts traces into viewer * * Results: * Inserts traces if found in dumpfile, returns number of traces inserted * ---------------------------------------------------------------------------- */ int process_tcl_list(char *sl, gboolean track_mouse_y) { char *s_new = NULL; char *this_regex = "\\(\\[.*\\]\\)*$"; char *entry_suffixed; int c, i, ii; char **list; char **s_new_list; char **most_recent_lbrack_list; int *match_idx_list; int *match_type_list; Trptr t = NULL; int found = 0; int lbrack_adj; int net_processing_is_off = 0; int unesc_len; int curr_srch_idx = 0; char *unescaped_str = NULL; if(!sl) { return(0); } list = zSplitTclList(sl, &c); if(!list) { return(0); } read_save_helper_relative_init(NULL); /* should be passing canonicalized filter names here...so no need for relative processing */ s_new_list = calloc_2(c, sizeof(char *)); match_idx_list = calloc_2(c, sizeof(int *)); match_type_list = calloc_2(c, sizeof(int *)); most_recent_lbrack_list = calloc_2(c, sizeof(char *)); GLOBALS->default_flags=TR_RJUSTIFY; GLOBALS->strace_current_window = 0; /* in case there are shadow traces; in reality this should never happen */ for(ii=0;iiis_lx2) { lx2_import_masked(); } if(track_mouse_y) { t = determine_trace_from_y(); if(t) { t->flags |= TR_HIGHLIGHT; } } memcpy(&GLOBALS->tcache_treesearch_gtk2_c_2,&GLOBALS->traces,sizeof(Traces)); GLOBALS->traces.total=0; GLOBALS->traces.first=GLOBALS->traces.last=NULL; continue; } else { goto cleanup; } } else if(is==3) { goto paste_routine; } else /* (is == 0) or (is == 2) */ for(;;) { if(*pnt == 0) { if(!(*nxt_hd)) { break; } if((!is)&&(GLOBALS->is_lx2)) { parsewavline_lx2(nxt_hd, NULL, 0); found++; } else { parsewavline(nxt_hd, NULL, 0); } break; } else if(*pnt == '\n') { *pnt = 0; if((!is)&&(GLOBALS->is_lx2)) { parsewavline_lx2(nxt_hd, NULL, 0); found++; } else { parsewavline(nxt_hd, NULL, 0); } *pnt = '\n'; nxt_hd = pnt+1; pnt++; } else { pnt++; } } } } break; default: break; } free_2(gdirect); } continue; } s_new_list[ii] = s_new; lbrack_adj = 0; most_recent_lbrack_list[ii] = strrchr(s_new, '['); if((most_recent_lbrack_list[ii])&&(most_recent_lbrack_list[ii] != s_new)) { char *chp = most_recent_lbrack_list[ii]-1; if(*chp == '\\') { most_recent_lbrack_list[ii] = chp; lbrack_adj = 1; } } unesc_len = strlen(unescaped_str); for(i=0;inumfacs;i++) { int was_packed = HIER_DEPACK_ALLOC; char *hfacname = NULL; hfacname = hier_decompress_flagged(GLOBALS->facs[curr_srch_idx]->name, &was_packed); if(!strncmp(unescaped_str, hfacname, unesc_len)) { int hfacname_len = strlen(hfacname); if((unesc_len == hfacname_len) || ((hfacname_len > unesc_len) && (hfacname[unesc_len] == '['))) { found++; match_idx_list[ii] = curr_srch_idx; match_type_list[ii] = 1; /* match was on normal search */ if(was_packed) { free_2(hfacname); } if(s_new != unescaped_str) { free_2(unescaped_str); } goto import; } } curr_srch_idx++; if(curr_srch_idx == GLOBALS->numfacs) curr_srch_idx = 0; /* optimization for rtlbrowse as names should be in order */ if(was_packed) { free_2(hfacname); } } if(s_new != unescaped_str) { free_2(unescaped_str); } entry_suffixed=wave_alloca(2+strlen(s_new)+strlen(this_regex)+1); *entry_suffixed=0x00; strcpy(entry_suffixed, "\\<"); strcat(entry_suffixed,s_new); strcat(entry_suffixed,this_regex); wave_regex_compile(entry_suffixed, WAVE_REGEX_DND); for(i=0;inumfacs;i++) { int was_packed = HIER_DEPACK_ALLOC; char *hfacname = NULL; hfacname = hier_decompress_flagged(GLOBALS->facs[i]->name, &was_packed); if(wave_regex_match(hfacname, WAVE_REGEX_DND)) { found++; match_idx_list[ii] = i; match_type_list[ii] = 1; /* match was on normal search */ if(was_packed) { free_2(hfacname); } goto import; } if(was_packed) { free_2(hfacname); } } if(most_recent_lbrack_list[ii]) { *most_recent_lbrack_list[ii] = 0; entry_suffixed=wave_alloca(2+strlen(s_new)+strlen(this_regex)+1); *entry_suffixed=0x00; strcpy(entry_suffixed, "\\<"); strcat(entry_suffixed,s_new); strcat(entry_suffixed,this_regex); wave_regex_compile(entry_suffixed, WAVE_REGEX_DND); for(i=0;inumfacs;i++) { int was_packed = HIER_DEPACK_ALLOC; char *hfacname = NULL; hfacname = hier_decompress_flagged(GLOBALS->facs[i]->name, &was_packed); if(wave_regex_match(hfacname, WAVE_REGEX_DND)) { found++; match_idx_list[ii] = i; match_type_list[ii] = 2+lbrack_adj; /* match was on lbrack removal */ if(was_packed) { free_2(hfacname); } goto import; } if(was_packed) { free_2(hfacname); } } } import: if(match_type_list[ii]) { struct symbol *s = GLOBALS->facs[match_idx_list[ii]]; struct symbol *schain = s->vec_root; if(GLOBALS->is_lx2) { if(schain) { while(schain) { lx2_set_fac_process_mask(schain->n); schain = schain-> vec_chain; } } else { lx2_set_fac_process_mask(s->n); } } } } if(!found) goto cleanup; if(GLOBALS->is_lx2) { lx2_import_masked(); } if(track_mouse_y) { t = determine_trace_from_y(); if(t) { t->flags |= TR_HIGHLIGHT; } } memcpy(&GLOBALS->tcache_treesearch_gtk2_c_2,&GLOBALS->traces,sizeof(Traces)); GLOBALS->traces.total=0; GLOBALS->traces.first=GLOBALS->traces.last=NULL; for(ii=0;iifacs[match_idx_list[ii]]; if((match_type_list[ii] >= 2)&&(s->n->extvals)) { nptr nexp; int bit = atoi(most_recent_lbrack_list[ii]+1 + (match_type_list[ii] == 3)); /* == 3 for adjustment when lbrack is escaped */ int which, cnt; if(s->n->lsi > s->n->msi) { for(which=0,cnt=s->n->lsi ; cnt>=s->n->msi ; cnt--,which++) { if(cnt==bit) break; } } else { for(which=0,cnt=s->n->msi ; cnt>=s->n->lsi ; cnt--,which++) { if(cnt==bit) break; } } nexp = ExtractNodeSingleBit(s->n, which); *most_recent_lbrack_list[ii] = '['; if(nexp) { AddNode(nexp, NULL); } else { AddNodeUnroll(s->n, NULL); } } else { struct symbol *schain = s->vec_root; if(!schain) { AddNodeUnroll(s->n, NULL); } else { int len = 0; while(schain) { len++; schain = schain->vec_chain; } add_vector_chain(s->vec_root, len); } } } } paste_routine: GLOBALS->default_flags=TR_RJUSTIFY; GLOBALS->traces.buffercount=GLOBALS->traces.total; GLOBALS->traces.buffer=GLOBALS->traces.first; GLOBALS->traces.bufferlast=GLOBALS->traces.last; GLOBALS->traces.first=GLOBALS->tcache_treesearch_gtk2_c_2.first; GLOBALS->traces.last=GLOBALS->tcache_treesearch_gtk2_c_2.last; GLOBALS->traces.total=GLOBALS->tcache_treesearch_gtk2_c_2.total; if((t) || (!track_mouse_y)) { PasteBuffer(); } else { PrependBuffer(); } GLOBALS->traces.buffercount=GLOBALS->tcache_treesearch_gtk2_c_2.buffercount; GLOBALS->traces.buffer=GLOBALS->tcache_treesearch_gtk2_c_2.buffer; GLOBALS->traces.bufferlast=GLOBALS->tcache_treesearch_gtk2_c_2.bufferlast; if(track_mouse_y) { if(t) { t->flags &= ~TR_HIGHLIGHT; } } cleanup: for(ii=0;iitims.marker != -1) { char mrkbuf[128]; reformat_time(mrkbuf, GLOBALS->tims.marker, GLOBALS->time_dimension); sprintf(pidstr+strlen(pidstr), "{marker %s} ", mrkbuf); } return(strdup_2(pidstr)); #else return(NULL); #endif } /* ---------------------------------------------------------------------------- * make_single_tcl_list_name - generates tcl name from a gtkwave one * * Results: * generated tcl list string * ---------------------------------------------------------------------------- */ char *make_single_tcl_list_name(char *s, char *opt_value, int promote_to_bus, int preserve_range) { char *rpnt = NULL; char *pnt, *pnt2; int delim_cnt = 0; char *lbrack=NULL, *colon=NULL, *rbrack=NULL; const char **names = NULL; char *tcllist = NULL; int tcllist_len; int names_idx = 0; char is_bus = 0; if(s) { int len; int was_packed = HIER_DEPACK_ALLOC; char *s2; s = hier_decompress_flagged(s, &was_packed); len = strlen(s); s2 = wave_alloca(len+1); strcpy(s2, s); if(was_packed) { free_2(s); s = NULL; } pnt = s2; while(*pnt) { if(*pnt == GLOBALS->hier_delimeter) { delim_cnt++; } else if(*pnt == '[') { lbrack = pnt; } else if(*pnt == ':') { colon = pnt; } else if(*pnt == ']') { rbrack = pnt; } pnt++; } if(!preserve_range) /* added for gtkwave::addSignalsFromList */ { if((lbrack && colon && rbrack && ((colon-lbrack)>0) && ((rbrack - colon)>0) && ((rbrack-lbrack)>0)) || (lbrack && promote_to_bus)) { is_bus = 1; *lbrack = 0; /* len = lbrack - s2; */ /* scan-build */ } } names = calloc_2(delim_cnt+1, sizeof(char *)); pnt = s2; names[0] = pnt; while(*pnt) { if(*pnt == GLOBALS->hier_delimeter) { *pnt = 0; names_idx++; pnt++; if(*pnt) { names[names_idx] = pnt; } } else { pnt++; } } tcllist = zMergeTclList(delim_cnt+1, names); tcllist_len = strlen(tcllist); free_2(names); if(!opt_value) { if(is_bus) { len = 8 + strlen(tcllist) + 1 + 1 + 1; /* "{netBus ...} " + trailing null char */ /* pnt = s2; */ /* scan-build */ rpnt = malloc_2(len+1); strcpy(rpnt, "{netBus "); pnt2 = rpnt + 8; } else { len = 5 + strlen(tcllist) + 1 + 1 + 1; /* "{net ...} " + trailing null char */ /* pnt = s2; */ /* scan-build */ rpnt = malloc_2(len+1); strcpy(rpnt, "{net "); pnt2 = rpnt + 5; } } else { int len_value = strlen(opt_value); if(is_bus) { len = 15 + (len_value + 1) + strlen(tcllist) + 1 + 1 + 1; /* "{netBusValue 0x...} " + trailing null char */ /* pnt = s2; */ /* scan-build */ rpnt = malloc_2(len+1); sprintf(rpnt, "{netBusValue 0x%s ", opt_value); pnt2 = rpnt + 15 + (len_value + 1); } else { len = 10 + (len_value + 1) + strlen(tcllist) + 1 + 1 + 1; /* "{netValue ...} " + trailing null char */ /* pnt = s2; */ /* scan-build */ rpnt = malloc_2(len+1); sprintf(rpnt, "{netValue %s ", opt_value); pnt2 = rpnt + 10 + (len_value + 1); } } strcpy(pnt2, tcllist); strcpy(pnt2 + tcllist_len, "} "); free_2(tcllist); } return(rpnt); } /* ---------------------------------------------------------------------------- * give_value_string - generates value string from trace @ markertime * * Results: * generated value which is similar to that generated in the signalwindow * pane when the marker button is pressed. note that this modifies the * flags so it is always TR_RJUSTIFY | TR_HEX * ---------------------------------------------------------------------------- */ static char *give_value_string(Trptr t) { char *rc = NULL; unsigned int flags; int f_filter, p_filter; if(t) { flags = t->flags; f_filter = t->f_filter; p_filter = t->p_filter; t->flags = TR_RJUSTIFY | TR_HEX; t->f_filter = 0; t->p_filter = 0; if(GLOBALS->tims.marker != -1) { if(t->vector) { /* this is currently unused as vectors are exploded into single bits */ vptr v = bsearch_vector(t->n.vec, GLOBALS->tims.marker - t->shift); rc = convert_ascii(t, v); } else { hptr h_ptr = bsearch_node(t->n.nd, GLOBALS->tims.marker - t->shift); if(h_ptr) { if(!t->n.nd->extvals) { rc = (char *)calloc_2(2, 2*sizeof(char)); rc[0] = AN_STR[h_ptr->v.h_val]; } else { if(h_ptr->flags&HIST_REAL) { if(!(h_ptr->flags&HIST_STRING)) { #ifdef WAVE_HAS_H_DOUBLE rc = convert_ascii_real(t, &h_ptr->v.h_double); #else rc = convert_ascii_real(t, (double *)h_ptr->v.h_vector); #endif } else { rc = convert_ascii_string((char *)h_ptr->v.h_vector); } } else { rc = convert_ascii_vec(t,h_ptr->v.h_vector); } } } } } t->flags = flags; t->f_filter = f_filter; t->p_filter = p_filter; } return(rc); } /* ---------------------------------------------------------------------------- * add_dnd_from_searchbox - generates tcl names from selected searchbox ones * * Results: * tcl list containing all generated names * ---------------------------------------------------------------------------- */ char *add_dnd_from_searchbox(void) { int i; char *one_entry = NULL, *mult_entry = NULL; unsigned int mult_len = 0; for(i=0;inum_rows_search_c_2;i++) { struct symbol *s, *t; s=(struct symbol *)gtk_clist_get_row_data(GTK_CLIST(GLOBALS->clist_search_c_3), i); if(get_s_selected(s)) { if((!s->vec_root)||(!GLOBALS->autocoalesce)) { } else { t=s->vec_root; set_s_selected(t, 1); t=t->vec_chain; while(t) { if(get_s_selected(t)) { set_s_selected(t, 0); } t=t->vec_chain; } } } } for(i=0;inum_rows_search_c_2;i++) { int len; struct symbol *s, *t; s=(struct symbol *)gtk_clist_get_row_data(GTK_CLIST(GLOBALS->clist_search_c_3), i); if(get_s_selected(s)) { if((!s->vec_root)||(!GLOBALS->autocoalesce)) { one_entry = make_single_tcl_list_name(s->n->nname, NULL, 0, 0); WAVE_OE_ME } else { len=0; t=s->vec_root; while(t) { one_entry = make_single_tcl_list_name(t->n->nname, NULL, 1, 0); WAVE_OE_ME if(get_s_selected(t)) { if(len) set_s_selected(t, 0); } /* len++; */ /* scan-build : artifact of below being removed */ break; /* t=t->vec_chain; ...no longer needed because of for() loop above and handler in process_tcl_list() */ } } } } return(mult_entry); } /* ---------------------------------------------------------------------------- * add_dnd_from_signal_window - generates tcl names from selected sigwin ones * * Results: * tcl list containing all generated names * ---------------------------------------------------------------------------- */ char *add_dnd_from_signal_window(void) { return(add_traces_from_signal_window(FALSE)); } /* ---------------------------------------------------------------------------- * add_traces_from_signal_window - generates tcl names from all sigwin ones * * Results: * tcl list containing all generated names, does not contain * {gtkwave NET OFF} directive as this is intended for tcl program usage. * ---------------------------------------------------------------------------- */ char *add_traces_from_signal_window(gboolean is_from_tcl_command) { Trptr t; char *one_entry = NULL, *mult_entry = NULL; unsigned int mult_len = 0; char *netoff = "{gtkwave NET OFF} "; char *trace_val = NULL; static const char xfwd[AN_COUNT]= AN_NORMAL; char trace_val_vec_single[2] = { 0, 0 }; if(is_from_tcl_command) { mult_entry = strdup_2(""); } t=GLOBALS->traces.first; while(t) { if( (!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH))) && ((t->flags & TR_HIGHLIGHT)||is_from_tcl_command) ) { if(t->vector) { int i; nptr *nodes; vptr v = (GLOBALS->tims.marker != -1) ? bsearch_vector(t->n.vec, GLOBALS->tims.marker - t->shift) : NULL; unsigned char *bits = v ? (v->v) : NULL; char *first_str = NULL; int coalesce_pass = 1; nodes=t->n.vec->bits->nodes; for(i=0;in.vec->bits->nnbits;i++) { if(!nodes[i]->expansion) { nptr n = nodes[i]; char *str = append_array_row(n); char *p = strrchr(str, '['); if(p) { *p = 0; } else { coalesce_pass = 0; break; } if(!i) { first_str = strdup_2(str); } else { if((!first_str /*scan-build */) || strcmp(str, first_str)) { coalesce_pass = 0; break; } } } else { coalesce_pass = 0; } } if(coalesce_pass) { if(t->n.vec->bits->nnbits < 2) { coalesce_pass = 0; } else { nptr nl = nodes[0]; char *strl = append_array_row(nl); char *pl = strrchr(strl, '['); int lidx = atoi(pl+1); nptr nr = nodes[t->n.vec->bits->nnbits - 1]; char *strr = append_array_row(nr); char *pr = strrchr(strr, '['); int ridx = atoi(pr+1); int first_str_len = strlen(first_str ? first_str : (first_str = strdup_2("INTERNAL_ERROR"))); /* : case added for scan-build */ char *newname = malloc_2(first_str_len + 40); sprintf(newname, "%s[%d:%d]", first_str, lidx, ridx); /* this disappears in make_single_tcl_list_name() but might be used in future code */ if(!mult_entry) { one_entry = make_gtkwave_pid(); WAVE_OE_ME one_entry = strdup_2(netoff); WAVE_OE_ME} one_entry = is_from_tcl_command ? strdup_2s(newname) : make_single_tcl_list_name(newname, NULL, 0, 0); WAVE_OE_ME if(!is_from_tcl_command) { trace_val = give_value_string(t); if(trace_val) { one_entry = make_single_tcl_list_name(newname, trace_val, 0, 0); WAVE_OE_ME free_2(trace_val); } } free_2(newname); } free_2(first_str); first_str = NULL; } if(!coalesce_pass) for(i=0;in.vec->bits->nnbits;i++) { if(nodes[i]->expansion) { int which, cnt; int bit = nodes[i]->expansion->parentbit; nptr n = nodes[i]->expansion->parent; char *str = append_array_row(n); char *p = strrchr(str, '['); if(p) { *p = 0; } if(n->lsi > n->msi) { for(which=0,cnt=n->lsi ; cnt>=n->msi ; cnt--,which++) { if(cnt==bit) break; } } else { for(which=0,cnt=n->msi ; cnt>=n->lsi ; cnt--,which++) { if(cnt==bit) break; } } sprintf(str+strlen(str), "[%d]", which); if(!mult_entry) { one_entry = make_gtkwave_pid(); WAVE_OE_ME one_entry = strdup_2(netoff); WAVE_OE_ME } one_entry = is_from_tcl_command ? strdup_2s(str) : make_single_tcl_list_name(str, NULL, 0, 0); WAVE_OE_ME if((bits)&&(!is_from_tcl_command)) { int bitnum = bits[i]; if(bitnum < 0) bitnum = AN_DASH; else if(bitnum >= AN_COUNT) bitnum = AN_DASH; trace_val_vec_single[0] = AN_STR[(int)xfwd[bitnum]]; one_entry = make_single_tcl_list_name(str, trace_val_vec_single, 0, 0); WAVE_OE_ME } } else { if(!mult_entry) { one_entry = make_gtkwave_pid(); WAVE_OE_ME one_entry = strdup_2(netoff); WAVE_OE_ME} one_entry = is_from_tcl_command ? strdup_2s(append_array_row(nodes[i])) : make_single_tcl_list_name(append_array_row(nodes[i]), NULL, 0, 0); WAVE_OE_ME if(!is_from_tcl_command) { trace_val = give_value_string(t); if(trace_val) { one_entry = make_single_tcl_list_name(append_array_row(nodes[i]), trace_val, 0, 0); WAVE_OE_ME free_2(trace_val); } } } } } else { if(t->n.nd->expansion) { int which, cnt; int bit = t->n.nd->expansion->parentbit; nptr n = t->n.nd->expansion->parent; char *str = append_array_row(n); char *p = strrchr(str, '['); if(p) { *p = 0; } if(n->lsi > n->msi) { for(which=0,cnt=n->lsi ; cnt>=n->msi ; cnt--,which++) { if(cnt==bit) break; } } else { for(which=0,cnt=n->msi ; cnt>=n->lsi ; cnt--,which++) { if(cnt==bit) break; } } sprintf(str+strlen(str), "[%d]", which); if(!mult_entry) { one_entry = make_gtkwave_pid(); WAVE_OE_ME one_entry = strdup_2(netoff); WAVE_OE_ME} one_entry = is_from_tcl_command ? strdup_2s(str) : make_single_tcl_list_name(str, NULL, 0, 0); WAVE_OE_ME if(!is_from_tcl_command) { trace_val = give_value_string(t); if(trace_val) { one_entry = make_single_tcl_list_name(str, trace_val, 0, 0); WAVE_OE_ME free_2(trace_val); } } } else { if(!mult_entry) { one_entry = make_gtkwave_pid(); WAVE_OE_ME one_entry = strdup_2(netoff); WAVE_OE_ME} one_entry = is_from_tcl_command ? strdup_2s(append_array_row(t->n.nd)) : make_single_tcl_list_name(append_array_row(t->n.nd), NULL, 0, 0); WAVE_OE_ME if(!is_from_tcl_command) { trace_val = give_value_string(t); if(trace_val) { one_entry = make_single_tcl_list_name(append_array_row(t->n.nd), trace_val, 0, 0); WAVE_OE_ME free_2(trace_val); } } } } } else { if(!mult_entry) { one_entry = strdup_2(netoff); WAVE_OE_ME } } t = t->t_next; } return(mult_entry); } /* ---------------------------------------------------------------------------- * sig_selection_foreach_dnd - generates tcl names from iterated clist ones * * Results: * tcl list containing all generated names coalesced back into *data * ---------------------------------------------------------------------------- */ #if WAVE_USE_GTK2 static void sig_selection_foreach_dnd (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) { (void)path; struct tree *sel; int i; int low, high; struct iter_dnd_strings *it; char *one_entry, *mult_entry; unsigned int mult_len; enum { NAME_COLUMN, TREE_COLUMN, N_COLUMNS }; it = (struct iter_dnd_strings *)data; one_entry = it->one_entry; mult_entry = it->mult_entry; mult_len = it->mult_len; /* Get the tree. */ gtk_tree_model_get (model, iter, TREE_COLUMN, &sel, -1); if(!sel) return; low = fetchlow(sel)->t_which; high = fetchhigh(sel)->t_which; /* If signals are vectors, iterate through them if so. */ for(i=low;i<=high;i++) { struct symbol *s; s=GLOBALS->facs[i]; if((s->vec_root)&&(GLOBALS->autocoalesce)) { struct symbol *t = s->vec_root; while(t) { one_entry = make_single_tcl_list_name(t->n->nname, NULL, 1, 0); WAVE_OE_ME break; /* t=t->vec_chain; ...no longer needed as this is resolved in process_tcl_list() */ } } else { one_entry = make_single_tcl_list_name(s->n->nname, NULL, 0, 0); WAVE_OE_ME } } it->one_entry = one_entry; it->mult_entry = mult_entry; it->mult_len = mult_len; } #endif /* ---------------------------------------------------------------------------- * add_dnd_from_tree_window - generates tcl names from selected tree clist ones * * Results: * tcl list containing all generated names * ---------------------------------------------------------------------------- */ char *add_dnd_from_tree_window(void) { #if WAVE_USE_GTK2 struct iter_dnd_strings it; memset(&it, 0, sizeof(struct iter_dnd_strings)); gtk_tree_selection_selected_foreach(GLOBALS->sig_selection_treesearch_gtk2_c_1, &sig_selection_foreach_dnd, (gpointer)&it); return(it.mult_entry); #else return(NULL); #endif } /* ---------------------------------------------------------------------------- * make_message - printf() which mallocs into a string * * Results: * dynamically allocated string * ---------------------------------------------------------------------------- */ static char *make_message (const char *fmt, ...) { /* Guess we need no more than 100 bytes. */ int n, size = 100; char *p, *np; va_list ap; if ((p = malloc_2(size)) == NULL) return NULL; while (1) { /* Try to print in the allocated space. */ va_start (ap, fmt); n = vsnprintf (p, size, fmt, ap); va_end (ap); /* If that worked, return the string. */ if (n > -1 && n < size) return p; /* Else try again with more space. */ if (n > -1) /* glibc 2.1 */ size = n + 1; /* precisely what is needed */ else /* glibc 2.0 */ size *= 2; /* twice the old size */ if ((np = realloc_2(p, size)) == NULL) { free (p); return NULL; } else { p = np; } } } /* ---------------------------------------------------------------------------- * emit_gtkwave_savefile_formatted_entries_in_tcl_list - performs as named * * Results: * tcl list which mimics a gtkwave save file for cut and paste entries * which is later iteratively run through the normal gtkwave save file * loader parsewavline() on the distant end. the reason this is * necessary is in order to pass attribute and concatenation information * along to the distant end. * ---------------------------------------------------------------------------- */ char *emit_gtkwave_savefile_formatted_entries_in_tcl_list(Trptr t, gboolean use_tcl_mode) { char *one_entry, *mult_entry = NULL; unsigned int mult_len = 0; unsigned int prev_flags = 0; unsigned int def=0; TimeType prevshift=LLDescriptor(0); char is_first = 1; char flag_skip; while(t) { flag_skip = 0; if(use_tcl_mode) { if(IsSelected(t) || (t->t_grp && IsSelected(t->t_grp))) { /* members of closed groups may not be highlighted */ /* so propogate highlighting here */ t->flags |= TR_HIGHLIGHT; } else { if((prev_flags & TR_ANALOGMASK) && (t->flags &TR_ANALOG_BLANK_STRETCH)) { flag_skip = 1; } else { t = t->t_next; continue; } } } if((t->flags!=def)||(is_first)) { is_first = 0; if((t->flags & TR_PTRANSLATED) && (!t->p_filter)) t->flags &= (~TR_PTRANSLATED); if((t->flags & TR_FTRANSLATED) && (!t->f_filter)) t->flags &= (~TR_FTRANSLATED); one_entry = make_message("@%x\n",(def=t->flags) & ~TR_HIGHLIGHT); WAVE_OE_ME if(!flag_skip) prev_flags = def; } if(t->t_color) { one_entry = make_message("[color] %d\n", t->t_color); WAVE_OE_ME } if((t->shift)||((prevshift)&&(!t->shift))) { one_entry = make_message(">"TTFormat"\n", t->shift); WAVE_OE_ME } prevshift=t->shift; if(!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH))) { if(t->flags & TR_FTRANSLATED) { if(t->f_filter && GLOBALS->filesel_filter[t->f_filter]) { one_entry = make_message("^%d %s\n", t->f_filter, GLOBALS->filesel_filter[t->f_filter]); WAVE_OE_ME } else { one_entry = make_message("^%d %s\n", 0, "disabled"); WAVE_OE_ME } } else if(t->flags & TR_PTRANSLATED) { if(t->p_filter && GLOBALS->procsel_filter[t->p_filter]) { one_entry = make_message("^>%d %s\n", t->p_filter, GLOBALS->procsel_filter[t->p_filter]); WAVE_OE_ME } else { one_entry = make_message("^>%d %s\n", 0, "disabled"); WAVE_OE_ME } } /* NOT an else! */ if(t->flags & TR_TTRANSLATED) { if(t->transaction_args) { one_entry = make_message("[transaction_args] \"%s\"\n", t->transaction_args); WAVE_OE_ME } else { one_entry = make_message("[transaction_args] \"%s\"\n", ""); WAVE_OE_ME } if(t->t_filter && GLOBALS->ttranssel_filter[t->t_filter]) { one_entry = make_message("^<%d %s\n", t->t_filter, GLOBALS->ttranssel_filter[t->t_filter]); WAVE_OE_ME } else { one_entry = make_message("^<%d %s\n", 0, "disabled"); WAVE_OE_ME } } if(t->vector && !(t->n.vec->transaction_cache && t->n.vec->transaction_cache->transaction_nd)) { int i; nptr *nodes; bptr bits; baptr ba; if(HasAlias(t)) { one_entry = make_message("+{%s} ",t->name_full); WAVE_OE_ME } bits = t->n.vec->bits; ba = bits ? bits->attribs : NULL; one_entry = make_message("%c{%s}", ba ? ':' : '#', t->n.vec->transaction_cache ? t->n.vec->transaction_cache->bvname : t->n.vec->bvname); WAVE_OE_ME nodes=t->n.vec->bits->nodes; for(i=0;in.vec->bits->nnbits;i++) { if(nodes[i]->expansion) { one_entry = make_message(" (%d)%s",nodes[i]->expansion->parentbit, append_array_row(nodes[i]->expansion->parent)); WAVE_OE_ME } else { one_entry = make_message(" %s",append_array_row(nodes[i])); WAVE_OE_ME } if(ba) { one_entry = make_message(" "TTFormat" %x", ba[i].shift, ba[i].flags); WAVE_OE_ME } } one_entry = make_message("\n"); WAVE_OE_ME } else { nptr nd = (t->vector && t->n.vec->transaction_cache && t->n.vec->transaction_cache->transaction_nd) ? t->n.vec->transaction_cache->transaction_nd : t->n.nd; if(HasAlias(t)) { if(nd->expansion) { one_entry = make_message("+{%s} (%d)%s\n",t->name_full,nd->expansion->parentbit, append_array_row(nd->expansion->parent)); WAVE_OE_ME } else { one_entry = make_message("+{%s} %s\n",t->name_full,append_array_row(nd)); WAVE_OE_ME } } else { if(nd->expansion) { one_entry = make_message("(%d)%s\n",nd->expansion->parentbit, append_array_row(nd->expansion->parent)); WAVE_OE_ME } else { one_entry = make_message("%s\n",append_array_row(nd)); WAVE_OE_ME } } } } else { if(!t->name) { one_entry = make_message("-\n"); WAVE_OE_ME } else { one_entry = make_message("-%s\n",t->name); WAVE_OE_ME } } t=t->t_next; } if(mult_entry) { const char *hdr = "{gtkwave SAVELIST "; int hdr_len = strlen(hdr); const char *av[1]; char *zm; int zm_len; av[0] = mult_entry; zm = zMergeTclList(1, av); zm_len = strlen(zm); free_2(mult_entry); mult_entry = malloc_2(hdr_len + zm_len + 2 + 1); memcpy(mult_entry, hdr, hdr_len); memcpy(mult_entry + hdr_len, zm, zm_len); strcpy(mult_entry + hdr_len + zm_len, "} "); free_2(zm); } return(mult_entry); } /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ /* XXX functions for URL (not TCL list) handling XXX */ /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ enum GtkwaveFtype { WAVE_FTYPE_UNKNOWN, WAVE_FTYPE_DUMPFILE, WAVE_FTYPE_STEMSFILE, WAVE_FTYPE_SAVEFILE }; /* ---------------------------------------------------------------------------- * determine_ftype - examines filename (perhaps initial contents) and * determines file type * * Results: * enum of ftype determination * ---------------------------------------------------------------------------- */ static int determine_ftype(char *s, char **dotpnt) { char *pnt = s; char *dot = NULL, *dot2 = NULL; int ftype = WAVE_FTYPE_UNKNOWN; while(*pnt) { if(*pnt == '.') { dot2 = dot; dot = pnt; } pnt++; } *dotpnt = dot; if(dot) { if(!strcasecmp("sav", dot+1)) { ftype = WAVE_FTYPE_SAVEFILE; } else if(!strcasecmp("gtkw", dot+1)) { ftype = WAVE_FTYPE_SAVEFILE; } else if(!strcasecmp("stems", dot+1)) { ftype = WAVE_FTYPE_STEMSFILE; } else /* detect dumpfile type */ if ( #ifdef EXTLOAD_SUFFIX (!strcasecmp(EXTLOAD_SUFFIX, dot+1)) || #endif (!strcasecmp("vcd", dot+1)) || (!strcasecmp("dmp", dot+1)) || (!strcasecmp("lxt", dot+1)) || (!strcasecmp("lx2", dot+1)) || (!strcasecmp("lxt2", dot+1)) || (!strcasecmp("vzt", dot+1)) || (!strcasecmp("fst", dot+1)) || (!strcasecmp("ghw", dot+1)) || (!strcasecmp("aet", dot+1)) || /* ignore .aet? filename types */ (!strcasecmp("ae2", dot+1)) ) { ftype = WAVE_FTYPE_DUMPFILE; } else if(dot2) { if ( (!strcasecmp("ghw.gz", dot2+1)) || (!strcasecmp("ghw.bz2", dot2+1)) || (!strcasecmp("ghw.bz2", dot2+1)) || (!strcasecmp("vcd.gz", dot2+1)) || (!strcasecmp("vcd.zip", dot2+1)) ) { ftype = WAVE_FTYPE_DUMPFILE; } } } else { FILE *f = fopen(s, "rb"); if(f) { int ch0 = getc(f); int ch1 = getc(f); if(ch0 == EOF) { ch0 = ch1 = 0; } else if(ch1 == EOF) { ch1 = 0; } if((ch0 == '+') && (ch1 == '+')) { ftype = WAVE_FTYPE_STEMSFILE; /* stems file */ } else if(ch0 == '[') { ftype = WAVE_FTYPE_SAVEFILE; /* save file */ } fclose(f); } } return(ftype); } /* ---------------------------------------------------------------------------- * process_url_file - examines filename and performs appropriate side-effect * * Results: * Loads save file, new dump file, or stems file viewer * ---------------------------------------------------------------------------- */ int process_url_file(char *s) { static int processing_missing_file = 0; /* in case of malformed save files causing recursion */ int rc = 0; char *dotpnt = NULL; int ftype = determine_ftype(s, &dotpnt); switch(ftype) { case WAVE_FTYPE_SAVEFILE: if((GLOBALS->loaded_file_type == MISSING_FILE)&&(!processing_missing_file)) { gboolean modified; int opt_vcd; char *dfn = extract_dumpname_from_save_file(s, &modified, &opt_vcd); if(dfn) { char *dfn_local = strdup(dfn); free_2(dfn); processing_missing_file = 1; if(process_url_file(dfn_local)) { GLOBALS->dumpfile_is_modified = modified; } free(dfn_local); processing_missing_file = 0; } } GLOBALS->fileselbox_text = &GLOBALS->filesel_writesave; GLOBALS->filesel_ok=1; if(*GLOBALS->fileselbox_text) free_2(*GLOBALS->fileselbox_text); *GLOBALS->fileselbox_text=(char *)strdup_2(s); #ifndef MAC_INTEGRATION GLOBALS->block_xy_update = 1; #else GLOBALS->block_xy_update = (GLOBALS->num_notebook_pages > 1); /* let window always resize if 1 tab */ #endif wave_gconf_client_set_string("/current/savefile", s); read_save_helper(s, NULL, NULL, NULL, NULL, NULL); GLOBALS->block_xy_update = 0; rc = 1; break; case WAVE_FTYPE_STEMSFILE: #if !defined _MSC_VER && !defined __MINGW32__ GLOBALS->fileselbox_text = &GLOBALS->stems_name; GLOBALS->filesel_ok=1; if(*GLOBALS->fileselbox_text) free_2(*GLOBALS->fileselbox_text); *GLOBALS->fileselbox_text=(char *)strdup_2(s); menu_read_stems_cleanup(NULL, NULL); #endif rc = 1; break; case WAVE_FTYPE_DUMPFILE: GLOBALS->fileselbox_text = &GLOBALS->filesel_newviewer_menu_c_1; GLOBALS->filesel_ok=1; if(*GLOBALS->fileselbox_text) free_2(*GLOBALS->fileselbox_text); *GLOBALS->fileselbox_text=(char *)strdup_2(s); menu_new_viewer_tab_cleanup(NULL, NULL); rc = 1; break; default: break; } return(rc); } /* ---------------------------------------------------------------------------- * uri_cmp - qsort compare function that ensures save files and stems are * ordered after their respective dumpfiles * * Results: * returns correct sort order for processing (based on name and * GtkwaveFtype * ---------------------------------------------------------------------------- */ #ifdef WAVE_USE_GTK2 static int uri_cmp(const void *v1, const void *v2) { char *s1 = *(char **)v1; char *s2 = *(char **)v2; char *d1, *d2; int typ1 = determine_ftype(s1, &d1); int typ2 = determine_ftype(s2, &d2); int rc; if(!d1 || !d2) { return(strcmp(s1, s2)); } *d1 = 0; *d2 = 0; rc = strcmp(s1, s2); if(!rc) { rc = (typ1 - typ2); /* use suffix ftype to manipulate sort */ } *d1 = '.'; *d2 = '.'; return(rc); } #endif /* ---------------------------------------------------------------------------- * process_url_list - examines list of URLs and processes if valid files * * Results: * Indicates if any URLs were processed * ---------------------------------------------------------------------------- */ int process_url_list(char *s) { int is_url = 0; #if WAVE_USE_GTK2 int i; int url_cnt = 0; char pch = 0; char *nxt_hd = s; char *pnt = s; char *path; char **url_list = g_malloc(sizeof(gchar *)); /* deliberate g_funcs() as context can swap out from under us */ if(*pnt == '{') { g_free(url_list); return(0); } /* exit early if tcl list */ for(;;) { if(*pnt == 0) { if(!(*nxt_hd)) { break; } path = g_filename_from_uri(nxt_hd, NULL, NULL); if(path) { url_list[url_cnt++] = path; url_list = g_realloc(url_list, (url_cnt+1) * sizeof(gchar *)); } break; } else if((*pnt == '\n')||(*pnt == '\r')) { if((pch != '\n') && (pch != '\r')) { char sav = *pnt; *pnt = 0; path = g_filename_from_uri(nxt_hd, NULL, NULL); if(path) { url_list[url_cnt++] = path; url_list = g_realloc(url_list, (url_cnt+1) * sizeof(gchar *)); } *pnt = sav; } pch = *pnt; nxt_hd = pnt+1; pnt++; } else { pch = *pnt; pnt++; } } if(url_list) { if(url_cnt > 2) { qsort(url_list, url_cnt, sizeof(struct gchar *), uri_cmp); } else if(url_cnt == 2) /* in case there are only 2 files, make the savefile last */ { char *d1, *d2; int typ1 = determine_ftype(url_list[0], &d1); int typ2 = determine_ftype(url_list[1], &d2); if(typ1 > typ2) { char *tmp_swap = url_list[0]; url_list[0] = url_list[1]; url_list[1] = tmp_swap; } } for(i=0;ibusy_busy_c_1 && !in_timer) { Tcl_Interp *interp = (Tcl_Interp *)arg; const char *tv = NULL; in_timer = TRUE; tv = Tcl_GetVar(interp, WAVE_TCLCB_TIMER_PERIOD, WAVE_TCLCB_TIMER_PERIOD_FLAGS); if(tv) { gtkwavetcl_setvar_nonblocking(WAVE_TCLCB_TIMER_PERIOD,tv,WAVE_TCLCB_TIMER_PERIOD_FLAGS); tv = Tcl_GetVar(interp, WAVE_TCLCB_TIMER_PERIOD, WAVE_TCLCB_TIMER_PERIOD_FLAGS); } in_timer = FALSE; if(tv) { g_timeout_add(atoi(tv), setvar_timer, arg); } return(FALSE); } else { return(TRUE); } } } static void init_setvar_timer(Tcl_Interp *interp) { g_timeout_add(atoi(WAVE_TCLCB_TIMER_PERIOD_INIT), setvar_timer, (gpointer)interp); } static int menu_func(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { gtkwave_mlist_t *ife = (gtkwave_mlist_t *)clientData; int i; struct wave_script_args *old_wave_script_args = GLOBALS->wave_script_args; /* stackable args */ char fexit = GLOBALS->enable_fast_exit; if(GLOBALS->in_tcl_callback) /* don't allow callbacks to call menu functions (yet) */ { char reportString[1024]; char menuItem[512]; Tcl_Obj *aobj; char *src = ife->path; char *dst = menuItem; while(*src) { *dst = (*src != ' ') ? *src : '_'; src++; dst++; } *dst = 0; sprintf(reportString, "gtkwave::%s prohibited in callback", menuItem); gtkwavetcl_setvar_nonblocking(WAVE_TCLCB_ERROR,reportString,WAVE_TCLCB_ERROR_FLAGS); aobj = Tcl_NewStringObj(reportString, -1); Tcl_SetObjResult(interp, aobj); return(TCL_ERROR); } GLOBALS->wave_script_args = NULL; GLOBALS->enable_fast_exit = 1; if(objc > 1) { struct wave_script_args *wc = NULL; for(i=1;ipayload, s); /* scan-build complains but it thinks payload[1] is the actual memory allocated */ } w->curr = NULL; /* yes, curr is only ever used for the 1st struct, but there is no sense creating head/follower structs for this */ w->next = NULL; if(!GLOBALS->wave_script_args) { GLOBALS->wave_script_args = w; w->curr = w; } else { if(wc) /* scan-build: suppress warning, this will never happen */ { wc->next = w; /* we later really traverse through curr->next from the head pointer */ } } wc = w; } if(!GLOBALS->wave_script_args) /* create a dummy list in order to keep requesters from popping up in file.c, etc. */ { GLOBALS->wave_script_args = wave_alloca(sizeof(struct wave_script_args) + 1); GLOBALS->wave_script_args->curr = NULL; GLOBALS->wave_script_args->next = NULL; GLOBALS->wave_script_args->payload[0] = 0; } ife->callback(); gtkwave_main_iteration(); GLOBALS->wave_script_args = NULL; } else { ife->callback(); gtkwave_main_iteration(); } GLOBALS->enable_fast_exit = fexit; GLOBALS->wave_script_args = old_wave_script_args; return(TCL_OK); /* signal error with rc=TCL_ERROR, Tcl_Obj *aobj = Tcl_NewStringObj(reportString, -1); Tcl_SetObjResult(interp, aobj); */ } /* XXXXXXXXXXXXXXXXXXXXXXXXX */ /* XXX RPC Tcl Variant XXX */ /* XXXXXXXXXXXXXXXXXXXXXXXXX */ char *rpc_script_execute(const char *nam) { char *tpnt = NULL; char *s; if((nam) && (strlen(nam)) && (!GLOBALS->tcl_running)) { int tclrc; int nlen = strlen(nam); char *tcl_cmd = wave_alloca(7 + nlen + 1); strcpy(tcl_cmd, "source "); strcpy(tcl_cmd+7, nam); GLOBALS->tcl_running = 1; tclrc = Tcl_Eval (GLOBALS->interp, tcl_cmd); GLOBALS->tcl_running = 0; if(tclrc != TCL_OK) { tpnt = strdup_2(Tcl_GetStringResult (GLOBALS->interp)); } else { tpnt = strdup_2("TCL_OK"); } } if(!tpnt) tpnt = strdup_2("TCL_ERROR : no filename specified"); s = malloc_2(strlen("--script ") + strlen(tpnt) + 1 + 1); sprintf(s, "%s%s\n", "--script ", tpnt); free_2(tpnt); return(s); } /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ /* XXX Bluespec Tcl Variant XXX */ /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ void gtkUpdate(ClientData ignore) { (void)ignore; while (gtk_events_pending()) { gtk_main_iteration(); } Tcl_CreateTimerHandler(50,gtkUpdate, (ClientData) NULL); /* ajb: was 0 period ...caused 100% CPU spike */ } int gtkwaveInterpreterInit(Tcl_Interp *interp) { int i; char commandName[128]; gtkwave_mlist_t *ife; int num_menu_items; #ifdef WAVE_TCL_STUBIFY /* not needed...this does a double init if enabled: set_globals_interp(); */ #else if(Tcl_Init(interp) == TCL_ERROR) return TCL_ERROR; if(Tk_Init(interp) == TCL_ERROR) return TCL_ERROR; Tcl_SetVar(interp,"tcl_rcFileName","~/.wishrc",TCL_GLOBAL_ONLY); #endif strcpy(commandName, "gtkwave::"); ife = retrieve_menu_items_array(&num_menu_items); for(i=0;itcl_init_cmd) { Tcl_Eval(interp, GLOBALS->tcl_init_cmd); } Tcl_CreateTimerHandler(50,gtkUpdate, (ClientData) NULL); init_setvar_timer(interp); return TCL_OK; } /* XXXXXXXXXXXXXXXXXXXXXXXXXXXX */ /* XXX Simpod Tcl Variant XXX */ /* XXXXXXXXXXXXXXXXXXXXXXXXXXXX */ static gboolean repscript_timer(gpointer dummy) { (void)dummy; static gboolean run_once = FALSE; if(run_once == FALSE) /* avoid any race conditions with the toolkit for uninitialized data */ { run_once = TRUE; return(TRUE); } if((GLOBALS->repscript_name) && (!GLOBALS->tcl_running)) { int tclrc; int nlen = strlen(GLOBALS->repscript_name); char *tcl_cmd = wave_alloca(7 + nlen + 1); strcpy(tcl_cmd, "source "); strcpy(tcl_cmd+7, GLOBALS->repscript_name); GLOBALS->tcl_running = 1; tclrc = Tcl_Eval (GLOBALS->interp, tcl_cmd); GLOBALS->tcl_running = 0; #if WAVE_TCL_CHECK_VERSION(8,5,0) if(tclrc != TCL_OK) { Tcl_Obj *options; Tcl_Obj *key; Tcl_Obj *stackTrace; fprintf(stderr, "GTKWAVE | %s\n", Tcl_GetStringResult (GLOBALS->interp)); options = Tcl_GetReturnOptions(GLOBALS->interp, tclrc); key = Tcl_NewStringObj("-errorinfo", -1); Tcl_IncrRefCount(key); Tcl_DictObjGet(NULL, options, key, &stackTrace); Tcl_DecrRefCount(key); fprintf(stderr, "TCL Stack Trace\n%s\n", Tcl_GetStringFromObj(stackTrace, NULL)) ; /* Do something with stackTrace */ } #else if(tclrc != TCL_OK) { fprintf (stderr, "GTKWAVE | %s\n", Tcl_GetStringResult (GLOBALS->interp)); } #endif return(TRUE); } else { return(FALSE); } } void set_globals_interp(char *me, int install_tk) { #ifdef WAVE_TCL_STUBIFY if(NpCreateMainInterp(me, install_tk)) { GLOBALS->interp = NpGetMainInterp(); } else { fprintf(stderr, "GTKWAVE | Error, failed to find Tcl/Tk runtime libraries.\n"); fprintf(stderr, "GTKWAVE | Set the environment variable TCL_PLUGIN_DLL to point to\n"); fprintf(stderr, "GTKWAVE | the Tcl shared object file.\n"); exit(255); } #else (void)me; (void)install_tk; GLOBALS->interp = Tcl_CreateInterp(); #endif } void make_tcl_interpreter(char *argv[]) { int i; char commandName[32768]; gtkwave_mlist_t *ife; int num_menu_items; #if !((defined(__MACH__) && defined(__APPLE__))) int n = 0; #endif #ifndef WAVE_TCL_STUBIFY Tcl_FindExecutable(argv[0]); #endif #if (defined(__MACH__) && defined(__APPLE__)) { uint32_t size = sizeof(commandName); if(_NSGetExecutablePath(commandName, &size) == 0) { set_globals_interp(commandName, 0); } else { char *p = calloc_2(1, size+1); size++; if(_NSGetExecutablePath(p, &size) == 0) { set_globals_interp(p, 0); } else { fprintf(stderr, "GTKWAVE | Problem with _NSGetExecutablePath, exiting.\n"); exit(255); } free_2(p); } } #else #ifdef WIN32 if(!GetModuleFileName(NULL, commandName, 256)) n = -1 ; #else n = readlink("/proc/self/exe", commandName, 256) ; #endif if(n == -1) { fprintf(stderr, "GTKWAVE | Tcl_Init error: Failed to get my fullpath\n"); exit(EXIT_FAILURE); } else { commandName[n] = '\0' ; } set_globals_interp(commandName, 0); #endif #ifndef WAVE_TCL_STUBIFY if (TCL_OK != Tcl_Init(GLOBALS->interp)) { fprintf(stderr, "GTKWAVE | Tcl_Init error: %s\n", Tcl_GetStringResult (GLOBALS->interp)); exit(EXIT_FAILURE); } #endif strcpy(commandName, "gtkwave::"); ife = retrieve_menu_items_array(&num_menu_items); for(i=0;iinterp, commandName, (Tcl_ObjCmdProc *)menu_func, (ClientData)(ife+i), (Tcl_CmdDeleteProc *)NULL); } } for (i = 0; gtkwave_commands[i].func != NULL; i++) { strcpy(commandName + 9, gtkwave_commands[i].cmdstr); Tcl_CreateObjCommand(GLOBALS->interp, commandName, (Tcl_ObjCmdProc *)gtkwave_commands[i].func, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); } declare_tclcb_variables(GLOBALS->interp); if(GLOBALS->repscript_name) { FILE *f = fopen(GLOBALS->repscript_name, "rb"); if(f) { fclose(f); g_timeout_add(GLOBALS->repscript_period, repscript_timer, NULL); } else { fprintf(stderr, "GTKWAVE | Could not open repscript '%s', exiting.\n", GLOBALS->repscript_name); perror("Why"); exit(255); } } init_setvar_timer(GLOBALS->interp); } /* blocking version which keeps recursive setvars from happening */ const char *gtkwavetcl_setvar(const char *name1, const char *val, int flags) { const char *rc = NULL; if(GLOBALS->interp && !GLOBALS->in_tcl_callback) { GLOBALS->in_tcl_callback = 1; rc = Tcl_SetVar(GLOBALS->interp, name1, val, flags); GLOBALS->in_tcl_callback = 0; } return(rc); } /* version which would be used, for example by timer interrupts */ const char *gtkwavetcl_setvar_nonblocking(const char *name1, const char *val, int flags) { const char *rc = NULL; if(GLOBALS->interp) { rc = Tcl_SetVar(GLOBALS->interp, name1, val, flags); } return(rc); } #else void make_tcl_interpreter(char *argv[]) { (void)argv; /* nothing */ } const char *gtkwavetcl_setvar(const char *name1, const char *val, int flags) { (void)name1; (void)val; (void) flags; return(NULL); } const char *gtkwavetcl_setvar_nonblocking(const char *name1, const char *val, int flags) { (void) name1; (void) val; (void) flags; return(NULL); } char *rpc_script_execute(const char *nam) { (void) nam; return(strdup_2("--script TCL_ERROR : Tcl support not compiled into gtkwave\n")); } #endif gtkwave-3.3.66/src/status.c0000664000076400007640000001165512360623564015074 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2008 * * 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. */ #include "globals.h" #include #include #include "symbol.h" #include "lxt2_read.h" #include "lx2.h" /* Add some text to our text widget - this is a callback that is invoked when our window is realized. We could also force our window to be realized with gtk_widget_realize, but it would have to be part of a hierarchy first */ void status_text(char *str) { if(!GLOBALS->quiet_checkmenu) /* when gtkwave_mlist_t check menuitems are being initialized */ { int len = strlen(str); char ch = len ? str[len-1] : 0; if(GLOBALS->text_status_c_2) { #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) gtk_text_buffer_insert (GTK_TEXT_VIEW (GLOBALS->text_status_c_2)->buffer, &GLOBALS->iter_status_c_3, str, -1); #else gtk_text_insert (GTK_TEXT (GLOBALS->text_status_c_2), NULL, &GLOBALS->text_status_c_2->style->black, NULL, str, -1); #endif } else { fprintf(stderr, "GTKWAVE | %s%s", str, (ch=='\n') ? "" : "\n"); } { char *stemp = wave_alloca(len+1); strcpy(stemp, str); if(ch == '\n') { stemp[len-1] = 0; } gtkwavetcl_setvar(WAVE_TCLCB_STATUS_TEXT, stemp, WAVE_TCLCB_STATUS_TEXT_FLAGS); } } } void realize_text (GtkWidget *text, gpointer data) { (void)text; (void)data; char buf[128]; if(GLOBALS->is_vcd) { if(GLOBALS->partial_vcd) { status_text("VCD loading interactively.\n"); } else { status_text("VCD loaded successfully.\n"); } } else if(GLOBALS->is_lxt) { status_text("LXT loaded successfully.\n"); } else if(GLOBALS->is_ghw) { status_text("GHW loaded successfully.\n"); } else if(GLOBALS->is_lx2) { switch(GLOBALS->is_lx2) { case LXT2_IS_LXT2: status_text("LXT2 loaded successfully.\n"); break; case LXT2_IS_AET2: status_text("AET2 loaded successfully.\n"); break; case LXT2_IS_VZT: status_text("VZT loaded successfully.\n"); break; case LXT2_IS_VLIST: status_text("VCD loaded successfully.\n"); break; case LXT2_IS_FSDB: status_text("FSDB loaded successfully.\n"); break; } } sprintf(buf,"[%d] facilities found.\n",GLOBALS->numfacs); status_text(buf); if((GLOBALS->is_vcd)||(GLOBALS->is_ghw)) { if(!GLOBALS->partial_vcd) { sprintf(buf,"[%d] regions found.\n",GLOBALS->regions); status_text(buf); } } else { if(GLOBALS->is_lx2 == LXT2_IS_VLIST) { sprintf(buf,"Regions formed on demand.\n"); } else { sprintf(buf,"Regions loaded on demand.\n"); } status_text(buf); } } /* Create a scrolled text area that displays a "message" */ GtkWidget * create_text (void) { GtkWidget *table; GtkTooltips *tooltips; tooltips=gtk_tooltips_new_2(); gtk_tooltips_set_delay_2(tooltips,1500); /* Create a table to hold the text widget and scrollbars */ table = gtk_table_new (1, 16, FALSE); /* Put a text widget in the upper left hand corner. Note the use of * GTK_SHRINK in the y direction */ #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) GLOBALS->text_status_c_2 = gtk_text_view_new (); gtk_text_view_set_editable (GTK_TEXT_VIEW(GLOBALS->text_status_c_2), FALSE); gtk_text_buffer_get_start_iter (gtk_text_view_get_buffer(GTK_TEXT_VIEW (GLOBALS->text_status_c_2)), &GLOBALS->iter_status_c_3); GLOBALS->bold_tag_status_c_3 = gtk_text_buffer_create_tag (GTK_TEXT_VIEW (GLOBALS->text_status_c_2)->buffer, "bold", "weight", PANGO_WEIGHT_BOLD, NULL); #else GLOBALS->text_status_c_2 = gtk_text_new (NULL, NULL); gtk_text_set_editable(GTK_TEXT(GLOBALS->text_status_c_2), FALSE); #endif gtk_table_attach (GTK_TABLE (table), GLOBALS->text_status_c_2, 0, 14, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_SHRINK | GTK_EXPAND, 0, 0); gtk_widget_set_usize(GTK_WIDGET(GLOBALS->text_status_c_2), 100, 50); gtk_widget_show (GLOBALS->text_status_c_2); /* And a VScrollbar in the upper right */ #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) { GtkTextViewClass *tc = (GtkTextViewClass*)GTK_OBJECT_GET_CLASS(GTK_OBJECT(GLOBALS->text_status_c_2)); tc->set_scroll_adjustments(GTK_TEXT_VIEW (GLOBALS->text_status_c_2), NULL, NULL); GLOBALS->vscrollbar_status_c_2 = gtk_vscrollbar_new (GTK_TEXT_VIEW (GLOBALS->text_status_c_2)->vadjustment); } #else GLOBALS->vscrollbar_status_c_2 = gtk_vscrollbar_new ((GTK_TEXT (GLOBALS->text_status_c_2))->vadj); #endif gtk_table_attach (GTK_TABLE (table), GLOBALS->vscrollbar_status_c_2, 15, 16, 0, 1, GTK_FILL, GTK_FILL | GTK_SHRINK | GTK_EXPAND, 0, 0); gtk_widget_show (GLOBALS->vscrollbar_status_c_2); /* Add a handler to put a message in the text widget when it is realized */ gtk_signal_connect (GTK_OBJECT (GLOBALS->text_status_c_2), "realize", GTK_SIGNAL_FUNC (realize_text), NULL); gtk_tooltips_set_tip_2(tooltips, GLOBALS->text_status_c_2, "Status Window", NULL); return(table); } gtkwave-3.3.66/src/fsdb_wrapper_api.h0000664000076400007640000000426012540444674017062 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2013-2015. * * 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. */ #ifndef FSDB_WRAPPER_API_H #define FSDB_WRAPPER_API_H #if defined(FSDB_IS_PRESENT) && defined(FSDB_NSYS_IS_PRESENT) #define WAVE_FSDB_READER_IS_PRESENT #endif #ifdef __cplusplus extern "C" { #endif #include #include #include #include #ifdef HAVE_INTTYPES_H #include #endif struct fsdbReaderGetStatistics_t { int varCount; int scopeCount; }; struct fsdbReaderBlackoutChain_t { uint64_t tim; unsigned active : 1; }; void *fsdbReaderOpenFile(char *nam); void fsdbReaderReadScopeVarTree(void *ctx,void (*cb)(void *)); int fsdbReaderGetMaxVarIdcode(void *ctx); struct fsdbReaderGetStatistics_t *fsdbReaderGetStatistics(void *ctx); void fsdbReaderAddToSignalList(void *ctx, int i); void fsdbReaderResetSignalList(void *ctx); void fsdbReaderLoadSignals(void *ctx); void *fsdbReaderCreateVCTraverseHandle(void *ctx, int i); int fsdbReaderHasIncoreVC(void *ctx, void *hdl); void fsdbReaderFree(void *ctx, void *hdl); uint64_t fsdbReaderGetMinXTag(void *ctx, void *hdl); uint64_t fsdbReaderGetMaxXTag(void *ctx, void *hdl); int fsdbReaderGotoXTag(void *ctx, void *hdl, uint64_t tim); uint64_t fsdbReaderGetXTag(void *ctx, void *hdl, int *rc); int fsdbReaderGetVC(void *ctx, void *hdl, void **val_ptr); int fsdbReaderGotoNextVC(void *ctx, void *hdl); void fsdbReaderUnloadSignals(void *ctx); void fsdbReaderClose(void *ctx); int fsdbReaderGetBytesPerBit(void *hdl); int fsdbReaderGetBitSize(void *hdl); int fsdbReaderGetVarType(void *hdl); char *fsdbReaderTranslateVC(void *hdl, void *val_ptr); int fsdbReaderExtractScaleUnit(void *ctx, int *mult, char *scale); int fsdbReaderGetMinFsdbTag64(void *ctx, uint64_t *tim); int fsdbReaderGetMaxFsdbTag64(void *ctx, uint64_t *tim); unsigned int fsdbReaderGetDumpOffRange(void *ctx, struct fsdbReaderBlackoutChain_t **r); int fsdbReaderGetTransInfo(void *ctx, int idx, void **trans_info); #ifdef __cplusplus } #endif #endif gtkwave-3.3.66/src/zoombuttons.h0000664000076400007640000000147611523063250016147 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2010 * * 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. */ #ifndef WAVE_ZOOMBUTTONS_H #define WAVE_ZOOMBUTTONS_H void fix_wavehadj(void); void service_zoom_in(GtkWidget *text, gpointer data); void service_zoom_out(GtkWidget *text, gpointer data); void service_zoom_fit(GtkWidget *text, gpointer data); void service_zoom_full(GtkWidget *text, gpointer data); void service_zoom_undo(GtkWidget *text, gpointer data); void service_zoom_left(GtkWidget *text, gpointer data); void service_zoom_right(GtkWidget *text, gpointer data); void service_dragzoom(TimeType time1, TimeType time2); #endif gtkwave-3.3.66/src/liblzma/0000775000076400007640000000000012546303363015025 5ustar bybellbybellgtkwave-3.3.66/src/liblzma/Makefile.in0000664000076400007640000003761412261434733017105 0ustar bybellbybell# Makefile.in generated by automake 1.13.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 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__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } 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 = : subdir = src/liblzma DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru AM_V_AR = $(am__v_AR_@AM_V@) am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) am__v_AR_0 = @echo " AR " $@; am__v_AR_1 = libgwlzma_a_AR = $(AR) $(ARFLAGS) libgwlzma_a_LIBADD = am_libgwlzma_a_OBJECTS = LzmaLib.$(OBJEXT) libgwlzma_a_OBJECTS = $(am_libgwlzma_a_OBJECTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f 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 = $(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 = SOURCES = $(libgwlzma_a_SOURCES) DIST_SOURCES = $(libgwlzma_a_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)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AET2_CFLAGS = @AET2_CFLAGS@ AET2_LDADD = @AET2_LDADD@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COCOA_GTK_CFLAGS = @COCOA_GTK_CFLAGS@ COCOA_GTK_LDADD = @COCOA_GTK_LDADD@ COCOA_GTK_LDFLAGS = @COCOA_GTK_LDFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTDEBUG = @EXTDEBUG@ EXTDEBUG2 = @EXTDEBUG2@ EXTDEBUG3 = @EXTDEBUG3@ EXTDEBUG4 = @EXTDEBUG4@ EXTLOAD_CFLAGS = @EXTLOAD_CFLAGS@ FASTTREE_CFLAGS = @FASTTREE_CFLAGS@ FSDB_CFLAGS = @FSDB_CFLAGS@ FSDB_LDADD = @FSDB_LDADD@ GCONF_CFLAGS = @GCONF_CFLAGS@ GCONF_LIBS = @GCONF_LIBS@ GEDITTEST = @GEDITTEST@ GEDIT_CFLAGS = @GEDIT_CFLAGS@ GPERF = @GPERF@ GREP = @GREP@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_CONFIG = @GTK_CONFIG@ GTK_LIBS = @GTK_LIBS@ GTK_MAC_CFLAGS = @GTK_MAC_CFLAGS@ GTK_MAC_LIBS = @GTK_MAC_LIBS@ GTK_UNIX_PRINT_CFLAGS = @GTK_UNIX_PRINT_CFLAGS@ GTK_UNIX_PRINT_LIBS = @GTK_UNIX_PRINT_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBBZ2_CFLAGS = @LIBBZ2_CFLAGS@ LIBBZ2_DIR = @LIBBZ2_DIR@ LIBBZ2_LDADD = @LIBBZ2_LDADD@ LIBJUDY_CFLAGS = @LIBJUDY_CFLAGS@ LIBJUDY_LDADD = @LIBJUDY_LDADD@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBXZ_CFLAGS = @LIBXZ_CFLAGS@ LIBXZ_LDADD = @LIBXZ_LDADD@ LIBZ_CFLAGS = @LIBZ_CFLAGS@ LIBZ_DIR = @LIBZ_DIR@ LIBZ_LDADD = @LIBZ_LDADD@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MINGW_LDADD = @MINGW_LDADD@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ 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@ POW_LIB = @POW_LIB@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ STRUCT_PACK = @STRUCT_PACK@ TCL_DEFADD = @TCL_DEFADD@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LDADD = @TCL_LDADD@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_MAJOR_VERSION = @TCL_MAJOR_VERSION@ TCL_MINOR_VERSION = @TCL_MINOR_VERSION@ TK_INCLUDE_SPEC = @TK_INCLUDE_SPEC@ TK_LDADD = @TK_LDADD@ TK_LIB_SPEC = @TK_LIB_SPEC@ UPDATE_DESKTOP_DATABASE = @UPDATE_DESKTOP_DATABASE@ UPDATE_MIME_DATABASE = @UPDATE_MIME_DATABASE@ VERSION = @VERSION@ XDGDATADIR = @XDGDATADIR@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ 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_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ 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@ 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@ noinst_LIBRARIES = libgwlzma.a AM_CFLAGS = $(LIBXZ_CFLAGS) libgwlzma_a_SOURCES = LzmaLib.c LzmaLib.h EXTRA_DIST = lzma.txt all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(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) --foreign src/liblzma/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/liblzma/Makefile .PRECIOUS: 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__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libgwlzma.a: $(libgwlzma_a_OBJECTS) $(libgwlzma_a_DEPENDENCIES) $(EXTRA_libgwlzma_a_DEPENDENCIES) $(AM_V_at)-rm -f libgwlzma.a $(AM_V_AR)$(libgwlzma_a_AR) libgwlzma.a $(libgwlzma_a_OBJECTS) $(libgwlzma_a_LIBADD) $(AM_V_at)$(RANLIB) libgwlzma.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LzmaLib.Po@am__quote@ .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 $< .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 `$(CYGPATH_W) '$<'` 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: $(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 $(LIBRARIES) installdirs: 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-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -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-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 -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic 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 maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am # 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: gtkwave-3.3.66/src/liblzma/LzmaLib.c0000664000076400007640000001777212361774171016545 0ustar bybellbybell/* * Copyright (c) 2009 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #ifdef _WAVE_HAVE_XZ #include "lzma.h" #endif #include "LzmaLib.h" #ifndef _MSC_VER #include #endif #define LZMA_BLOCK_LEN (4*1024*1024) #define LZMA_DECODER_SIZE (256*1024*1024) enum lzma_state_t { LZMA_STATE_WRITE, LZMA_STATE_READ_ERROR, LZMA_STATE_READ_INIT, LZMA_STATE_READ_GETBLOCK, LZMA_STATE_READ_GETBYTES }; struct lzma_handle_t { int fd; unsigned int offs, blklen; unsigned int depth; enum lzma_state_t state; unsigned int blksiz; unsigned char *mem, *dmem; size_t write_cnt, read_cnt; }; static void LZMA_write_varint(struct lzma_handle_t *h, size_t v) { size_t nxt; unsigned char buf[16]; unsigned char *pnt = buf; while((nxt = v>>7)) { *(pnt++) = (v&0x7f); v = nxt; } *(pnt++) = (v&0x7f) | 0x80; h->write_cnt += write(h->fd, buf, pnt-buf); } #ifdef _WAVE_HAVE_XZ /* ifdef is warnings fix if XZ is not present */ static size_t LZMA_read_varint(struct lzma_handle_t *h) { unsigned char buf[16]; int idx = 0; size_t rc = 0; for(;;) { h->read_cnt += read(h->fd, buf+idx, 1); if(buf[idx++] & 0x80) break; } do { idx--; rc <<= 7; rc |= (buf[idx] & 0x7f); } while(idx); return(rc); } #endif static size_t LZMA_write_compress(struct lzma_handle_t *h, unsigned char *mem, size_t len) { #ifdef _WAVE_HAVE_XZ size_t srclen = len; size_t destlen = h->blksiz; lzma_stream strm = LZMA_STREAM_INIT; lzma_options_lzma preset; lzma_ret lrc; size_t wcnt; lzma_lzma_preset(&preset, h->depth); lrc = lzma_alone_encoder(&strm, &preset); if(lrc != LZMA_OK) { fprintf(stderr, "Error in lzma_alone_encoder(), exiting!\n"); exit(255); } strm.next_in = mem; strm.avail_in = len; strm.next_out = h->dmem; strm.avail_out = destlen; lrc = lzma_code(&strm, LZMA_FINISH); lzma_end(&strm); if(((lrc == LZMA_OK)||(lrc == LZMA_STREAM_END))&&(strm.total_outfd, h->dmem, strm.total_out); h->write_cnt += wcnt; return(wcnt); } else { LZMA_write_varint(h, srclen); LZMA_write_varint(h, 0); wcnt = write(h->fd, mem, len); h->write_cnt += wcnt; return(wcnt); } #else (void)h; (void)mem; (void)len; fprintf(stderr, "LZMA support was not compiled into this executable, sorry.\n"); exit(255); #endif } void *LZMA_fdopen(int fd, const char *mode) { static const char z7[] = "z7"; struct lzma_handle_t *h = calloc(1, sizeof(struct lzma_handle_t)); /* scan-build flagged malloc, add to h->write_cnt below */ h->fd = fd; h->offs = 0; h->depth = 4; if(mode[0] == 'w') { h->blksiz = LZMA_BLOCK_LEN; h->mem = malloc(h->blksiz); h->dmem = malloc(h->blksiz); if(mode[1]) { if(isdigit((int)(unsigned char)mode[1])) { h->depth = mode[1] - '0'; } else if(mode[2]) { if(isdigit((int)(unsigned char)mode[2])) { h->depth = mode[2] - '0'; } } } h->state = LZMA_STATE_WRITE; h->write_cnt += write(h->fd, z7, 2); return(h); } else if(mode[0] == 'r') { h->blksiz = 0; /* allocate as needed in the reader */ h->mem = NULL; h->dmem = NULL; h->state = LZMA_STATE_READ_INIT; return(h); } else { close(h->fd); free(h->dmem); free(h->mem); free(h); return(NULL); } } size_t LZMA_flush(void *handle) { struct lzma_handle_t *h = (struct lzma_handle_t *)handle; if((h) && (h->offs)) { LZMA_write_compress(h, h->mem, h->offs); h->offs = 0; } return(0); } void LZMA_close(void *handle) { struct lzma_handle_t *h = (struct lzma_handle_t *)handle; if(h) { if(h->state == LZMA_STATE_WRITE) { LZMA_flush(h); LZMA_write_varint(h, 0); } if(h->dmem) { free(h->dmem); } if(h->mem) { free(h->mem); } close(h->fd); free(h); } } size_t LZMA_write(void *handle, void *mem, size_t len) { struct lzma_handle_t *h = (struct lzma_handle_t *)handle; if(h->state == LZMA_STATE_WRITE) { while((h)&&(len)) { if((h->offs + len) <= h->blksiz) { memcpy(h->mem + h->offs, mem, len); h->offs += len; break; } else { size_t new_len = h->blksiz - h->offs; if(new_len) { memcpy(h->mem + h->offs, mem, new_len); } LZMA_write_compress(h, h->mem, h->blksiz); h->offs = 0; len -= new_len; mem = ((char *)mem) + new_len; } } } return(len); } size_t LZMA_read(void *handle, void *mem, size_t len) { #ifdef _WAVE_HAVE_XZ struct lzma_handle_t *h = (struct lzma_handle_t *)handle; size_t rc = 0; char hdr[2] = {0, 0}; size_t srclen, dstlen; if(h) { top: switch(h->state) { case LZMA_STATE_READ_INIT: h->read_cnt += read(h->fd, hdr, 2); if((hdr[0] == 'z') && (hdr[1] == '7')) { h->state = LZMA_STATE_READ_GETBLOCK; } else { h->state = LZMA_STATE_READ_ERROR; } goto top; break; case LZMA_STATE_READ_GETBLOCK: dstlen = LZMA_read_varint(h); if(!dstlen) { return(0); } if(dstlen > h->blksiz) /* reallocate buffers if ones in stream data are larger */ { if(h->dmem) { free(h->dmem); } if(h->mem) { free(h->mem); } h->blksiz = dstlen; h->mem = malloc(h->blksiz); h->dmem = malloc(h->blksiz); } srclen = LZMA_read_varint(h); if(!srclen) { h->read_cnt += (rc = read(h->fd, h->mem, dstlen)); h->blklen = rc; h->offs = 0; } else { lzma_stream strm = LZMA_STREAM_INIT; lzma_ret lrc; h->read_cnt += (rc = read(h->fd, h->dmem, srclen)); lrc = lzma_alone_decoder(&strm, LZMA_DECODER_SIZE); if(lrc != LZMA_OK) { fprintf(stderr, "Error in lzma_alone_decoder(), exiting!\n"); exit(255); } strm.next_in = h->dmem; strm.avail_in = srclen; strm.next_out = h->mem; strm.avail_out = h->blksiz; lrc = lzma_code(&strm, LZMA_RUN); lzma_end(&strm); if((lrc == LZMA_OK)||(lrc == LZMA_STREAM_END)) { dstlen = strm.total_out; h->blklen = dstlen; h->offs = 0; } else { h->state = LZMA_STATE_READ_ERROR; goto top; } } if(len <= dstlen) { memcpy(mem, h->mem, len); h->offs = len; rc = len; h->state = LZMA_STATE_READ_GETBYTES; } else { memcpy(mem, h->mem, dstlen); rc = dstlen + LZMA_read(h, ((char *)mem) + dstlen, len - dstlen); } break; case LZMA_STATE_READ_GETBYTES: if((len + h->offs) < h->blklen) { memcpy(mem, h->mem + h->offs, len); h->offs += len; rc = len; } else if((len + h->offs) == h->blklen) { memcpy(mem, h->mem + h->offs, len); h->offs = 0; rc = len; h->state = LZMA_STATE_READ_GETBLOCK; } else { size_t cpylen = h->blklen - h->offs; memcpy(mem, h->mem + h->offs, cpylen); h->state = LZMA_STATE_READ_GETBLOCK; rc = cpylen + LZMA_read(h, ((char *)mem) + cpylen, len - cpylen); } break; case LZMA_STATE_READ_ERROR: default: break; } } return(rc); #else (void)handle; (void)mem; (void)len; fprintf(stderr, "LZMA support was not compiled into this executable, sorry.\n"); exit(255); #endif } gtkwave-3.3.66/src/liblzma/LzmaLib.h0000664000076400007640000000270511523063250016524 0ustar bybellbybell/* * Copyright (c) 2009-2010 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifndef LIBLZMA_H #define LIBLZMA_H #include #ifdef __cplusplus extern "C" { #endif void *LZMA_fdopen(int fd, const char *mode); void LZMA_close(void *handle); size_t LZMA_flush(void *handle); size_t LZMA_write(void *handle, void *mem, size_t len); size_t LZMA_read(void *handle, void *mem, size_t len); #ifdef __cplusplus } #endif #endif gtkwave-3.3.66/src/liblzma/Makefile.am0000664000076400007640000000022211523063250017045 0ustar bybellbybell## -*- makefile -*- ## noinst_LIBRARIES= libgwlzma.a AM_CFLAGS= $(LIBXZ_CFLAGS) libgwlzma_a_SOURCES= LzmaLib.c LzmaLib.h EXTRA_DIST= lzma.txt gtkwave-3.3.66/src/liblzma/lzma.txt0000775000076400007640000000036311523063250016526 0ustar bybellbybellLZMA has been replaced with XZ. VZT files created using the old LZMA compression (-z 2) are no longer compatible with new XZ file format. In order to read them, convert them to VCD using a version of gtkwave earlier than 3.3.0. 23dec09 -ajb gtkwave-3.3.66/src/pixmaps.c0000664000076400007640000030471712341266475015241 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2012. * * 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. */ #include "globals.h" #include #include "pixmaps.h" #ifdef WAVE_USE_GTK2 /* Apply GMASK to GPIX and return a GdkPixbuf with an alpha channel. */ /* this function from gtkutil.c in emacs */ static GdkPixbuf * xg_get_pixbuf_from_pix_and_mask (GdkPixmap *gpix, GdkPixmap *gmask, GdkColormap *cmap) { int width, height; GdkPixbuf *icon_buf, *tmp_buf; gdk_drawable_get_size (gpix, &width, &height); tmp_buf = gdk_pixbuf_get_from_drawable (NULL, gpix, cmap, 0, 0, 0, 0, width, height); icon_buf = gdk_pixbuf_add_alpha (tmp_buf, FALSE, 0, 0, 0); g_object_unref (G_OBJECT (tmp_buf)); if (gmask) { GdkPixbuf *mask_buf = gdk_pixbuf_get_from_drawable (NULL, gmask, NULL, 0, 0, 0, 0, width, height); guchar *pixels = gdk_pixbuf_get_pixels (icon_buf); guchar *mask_pixels = gdk_pixbuf_get_pixels (mask_buf); int rowstride = gdk_pixbuf_get_rowstride (icon_buf); int mask_rowstride = gdk_pixbuf_get_rowstride (mask_buf); int y; for (y = 0; y < height; ++y) { guchar *iconptr, *maskptr; int x; iconptr = pixels + y * rowstride; maskptr = mask_pixels + y * mask_rowstride; for (x = 0; x < width; ++x) { /* In a bitmap, RGB is either 255/255/255 or 0/0/0. Checking just R is sufficient. */ if (maskptr[0] == 0) iconptr[3] = 0; /* 0, 1, 2 is R, G, B. 3 is alpha. */ iconptr += rowstride/width; maskptr += mask_rowstride/width; } } g_object_unref (G_OBJECT (mask_buf)); } return(icon_buf); } #endif /* XPM */ static char * icon_redo[] = { "24 24 126 2", " c None", ". c #000000", "+ c #F0FFEE", "@ c #CAE3C6", "# c #F5FFF4", "$ c #0D110C", "% c #729C6C", "& c #A6CAA1", "* c #CBE4C7", "= c #EFFDEE", "- c #172116", "; c #88B583", "> c #CCE5C8", ", c #CDE6C9", "' c #CFE7CB", ") c #F3FFF2", "! c #7FA879", "~ c #689063", "{ c #CDE5C9", "] c #CFE7CA", "^ c #D0E9CC", "/ c #D4EAD0", "( c #D5ECD1", "_ c #AED5A9", ": c #9ABC95", "< c #63865F", "[ c #2B3A29", "} c #8CB887", "| c #70986A", "1 c #71986B", "2 c #729A6B", "3 c #759C6D", "4 c #759F6F", "5 c #76A170", "6 c #567453", "7 c #AFCBAC", "8 c #7EAB77", "9 c #78A472", "0 c #6F9669", "a c #70976A", "b c #71996B", "c c #739B6D", "d c #759F6E", "e c #77A170", "f c #526F4C", "g c #B7D2B2", "h c #60835B", "i c #A5C9A0", "j c #9AC195", "k c #4F6B4C", "l c #769F70", "m c #516D4C", "n c #B9D5B4", "o c #7BA574", "p c #C7E0C3", "q c #6D9568", "r c #51714E", "s c #B6D3B2", "t c #81AB7C", "u c #C3DBBF", "v c #6B9265", "w c #C8EFC3", "x c #A7CCA2", "y c #B5D2B1", "z c #80A87A", "A c #90B68B", "B c #79A674", "C c #C6EAC1", "D c #DEF7D9", "E c #B3D7AE", "F c #BBD9B8", "G c #AFCCAB", "H c #749E6D", "I c #5B7B57", "J c #8CB087", "K c #BBE1B6", "L c #DAF5D6", "M c #E1F7DD", "N c #DCF4D6", "O c #D7F0D3", "P c #CFECCB", "Q c #C6E3C3", "R c #BCD6B9", "S c #7EA778", "T c #64885F", "U c #A6C1A3", "V c #B3D5AE", "W c #CDEAC9", "X c #D0EBCB", "Y c #CAE9C5", "Z c #C7E6C3", "` c #C3E3BF", " . c #BDDCBA", ".. c #B5D2B2", "+. c #96B991", "@. c #76A071", "#. c #3A4E37", "$. c #5E7F5A", "%. c #8FAF8B", "&. c #9CBE97", "*. c #C7E0C4", "=. c #CBE3C6", "-. c #CDE4C9", ";. c #CBE4C8", ">. c #C7E1C4", ",. c #C2DBBF", "'. c #88AF82", "). c #6B9266", "!. c #557451", "~. c #63885E", "{. c #759C70", "]. c #749E6F", "^. c #72996B", "/. c #739A6D", "(. c #71996C", "_. c #6E9668", ":. c #6C9367", "<. c #5F815A", "[. c #70996B", "}. c #6E9467", "|. c #698F63", "1. c #6B9166", "2. c #5D8059", "3. c #4D6A49", "4. c #6A8F64", "5. c #283926", " . ", " . . ", " . + . ", " . . . . @ # . ", " $ % & @ @ * * = . . . ", " - ; @ @ * * > , ' ) . . ! ~ . ", " . % @ * * > { ] ^ / ( _ . . : < . ", " [ & @ } | 1 2 3 4 5 6 . . 7 . ", ". 8 @ 9 0 a b c d e f . . g h . ", ". i j 0 k . . . l m . . . n o . ", ". p q h . . r . . . . s t . ", ". u v . . . . w . . x y z . ", ". A B . . . C D . . . E F G H . ", ". I J . . K L M N O P Q R S T . ", " . U . . V W X Y Z ` ...+.@.#.. ", " . $.%.. . &.*.=., -.;.>.,.'.).!.. ", " . ~.{.. . ].^.c /.(.| _.:.<.. . ", " . . . [.}.|.~ 1.2.3.. . ", " . q 4.. . . . ", " 5.).. ", " . . ", " . ", " ", " "}; /* XPM */ static char * icon_larrow[] = { "24 24 43 1", " c None", ". c #000000", "+ c #B9D0B9", "@ c #CDDECB", "# c #B6C7B6", "$ c #B1C9B0", "% c #B3C4B3", "& c #B4CBB2", "* c #B5CEB5", "= c #B7CCB5", "- c #B9CEB7", "; c #BAD1BA", "> c #BBCFBA", ", c #BBD0B9", "' c #B2C9B0", ") c #7EAB78", "! c #AAC7A8", "~ c #B3CAB1", "{ c #B0C9B0", "] c #B0C9AE", "^ c #AEC7AC", "/ c #AAC5A8", "( c #A9C4A7", "_ c #698267", ": c #2D2D2D", "< c #CFDFCC", "[ c #ADC8AB", "} c #B0C7AE", "| c #ADC6AB", "1 c #678C63", "2 c #9BAD9A", "3 c #85AE81", "4 c #87AF84", "5 c #87B083", "6 c #88AF84", "7 c #88B085", "8 c #86AF82", "9 c #547150", "0 c #3C5235", "a c #5B7950", "b c #4A6342", "c c #3B5035", "d c #415639", " ", " ", " ", " . ", " .. ", " .+. ", " .@#. ", " .@$%........ ", " .@&*=-;->,'). ", " .@!~{]^///^(_. ", " :<[}||[!^^}^[1. ", " .23444445645789. ", " .0aaaaaaaaaaab. ", " .0aaaaaaaaaab. ", " .0aabccccccd. ", " .0ab........ ", " .0b. ", " .b. ", " .. ", " . ", " ", " ", " ", " "}; /* XPM */ static char * icon_rarrow[] = { "24 24 41 1", " c None", ". c #000000", "+ c #8CA782", "@ c #B1CDAE", "# c #77A16E", "$ c #B4CEB1", "% c #ACC8A9", "& c #709867", "* c #C1D6BD", "= c #BDD3B8", "- c #BFD4BB", "; c #C2D7BE", "> c #B0CAAD", ", c #B2CBB0", "' c #AAC7A8", ") c #0F1308", "! c #AEC5A8", "~ c #AEC8AD", "{ c #ABC7A8", "] c #AAC6A7", "^ c #A8C6A5", "/ c #ADC8AD", "( c #A8C7A8", "_ c #A5C4A3", ": c #7F9F76", "< c #A6BFA0", "[ c #ABC7AA", "} c #A7C5A4", "| c #A9C7A6", "1 c #AFC8AD", "2 c #A4C3A2", "3 c #6B9060", "4 c #778E6F", "5 c #698D60", "6 c #6B9063", "7 c #445B2C", "8 c #6B8661", "9 c #5B7950", "0 c #6C8562", "a c #65815C", "b c #506B46", " ", " ", " ", " . ", " .. ", " .+. ", " .@#. ", " ........$%&. ", " .*=-;;;;>,'&) ", " .!~{{{]^'/(_:. ", " .<[^}^|{%'{123. ", " .45666666666657. ", " .8999999999997. ", " .099999999997. ", " .abbbbbb9997. ", " ........b97. ", " .b7. ", " .7. ", " .. ", " . ", " ", " ", " ", " "}; /* XPM */ static char * icon_zoomin[] = { "24 24 131 2", " c None", ". c #343434", "+ c #2D2D2D", "@ c #292929", "# c #262626", "$ c #2E2E2E", "% c #303030", "& c #737373", "* c #A1A1A1", "= c #B4B4B4", "- c #B2B2B2", "; c #9D9D9D", "> c #676767", ", c #202020", "' c #1C1C1C", ") c #272727", "! c #616161", "~ c #CACACA", "{ c #CFCFCF", "] c #D0D0D0", "^ c #CECECE", "/ c #C9C9C9", "( c #C1C1C1", "_ c #A7A7A7", ": c #4C4C4C", "< c #131313", "[ c #222222", "} c #757575", "| c #D3D3D3", "1 c #DBDBDB", "2 c #E7E7E7", "3 c #EFEFEF", "4 c #F3F3F3", "5 c #F1F1F1", "6 c #E5E5E5", "7 c #D2D2D2", "8 c #BCBCBC", "9 c #5E5E5E", "0 c #101010", "a c #212121", "b c #5B5B5B", "c c #CCCCCC", "d c #D7D7D7", "e c #F5F5F5", "f c #FAFAFA", "g c #FBFBFB", "h c #F8F8F8", "i c #F0F0F0", "j c #E1E1E1", "k c #C2C2C2", "l c #434343", "m c #0F0F0F", "n c #1F1F1F", "o c #B9B9B9", "p c #D6D6D6", "q c #F9F9F9", "r c #FDFDFD", "s c #FCFCFC", "t c #F2F2F2", "u c #ECECEC", "v c #E4E4E4", "w c #ABABAB", "x c #0E0E0E", "y c #1B1B1B", "z c #6D6D6D", "A c #FEFEFE", "B c #EEEEEE", "C c #E6E6E6", "D c #575757", "E c #090909", "F c #141414", "G c #A8A8A8", "H c #D8D8D8", "I c #F6F6F6", "J c #F4F4F4", "K c #DCDCDC", "L c #9B9B9B", "M c #060606", "N c #111111", "O c #C5C5C5", "P c #DFDFDF", "Q c #444444", "R c #454545", "S c #424242", "T c #EDEDED", "U c #BFBFBF", "V c #C6C6C6", "W c #E3E3E3", "X c #414141", "Y c #EAEAEA", "Z c #E0E0E0", "` c #BABABA", " . c #050505", ".. c #0B0B0B", "+. c #A5A5A5", "@. c #D1D1D1", "#. c #939393", "$. c #020202", "%. c #0A0A0A", "&. c #5F5F5F", "*. c #D9D9D9", "=. c #EBEBEB", "-. c #E9E9E9", ";. c #D4D4D4", ">. c #000000", ",. c #E2E2E2", "'. c #DADADA", "). c #CBCBCB", "!. c #3B3B3B", "~. c #D5D5D5", "{. c #C8C8C8", "]. c #BDBDBD", "^. c #515151", "/. c #C7C7C7", "(. c #CDCDCD", "_. c #B8B8B8", ":. c #030303", "<. c #313131", "[. c #999999", "}. c #BBBBBB", "|. c #B6B6B6", "1. c #909090", "2. c #2B2B2B", "3. c #010101", "4. c #7A7A7A", "5. c #9A9A9A", "6. c #777777", "7. c #3C3C3C", "8. c #686868", "9. c #797979", "0. c #3A3A3A", " ", " . + @ # # # ", " $ % & * = - ; > , ' ", " ) ! = ~ { ] ^ / ( _ : < ", " [ } ~ | 1 2 3 4 5 6 7 8 9 0 ", " a b c d 6 e f g f h e i j k l m ", " n o p 2 q g r r s g h t u v w x ", " y z 7 j e f r A A r s q e B C 1 D E ", " F G H B I q s A A r g h J B C K L M ", " N O P 3 e Q Q R R R Q l S T 6 1 U M ", " x V W u t l Q Q Q Q l S X Y Z d ` . ", " ..+.j 2 T 5 J I I e 4 3 u v 1 @.#.$. ", " %.&.*.j C =.B 3 3 B T -.v 1 ;.~ : >. ", " %.= H K ,.6 C C 2 W P '.;.).* $. ", " M !.c 7 ;.'.1 '.1 H ~.] {.].$ >. ", " .^.k /.).c (.).).{.k _.R >. ", " :.<.[.}.].8 8 8 |.1.2.>.>.>. ", " 3.:.X 4.5.5.6.7.>.>. >.>.>.>. ", " >.>.>.>.>.>. , , >.>. ", " >.8.. >.>. ", " >.9.0.>.>. ", " >.8.n >. ", " >.>. ", " "}; /* XPM */ static char * icon_zoomout[] = { "24 24 132 2", " c None", ". c #343434", "+ c #2D2D2D", "@ c #292929", "# c #262626", "$ c #2E2E2E", "% c #303030", "& c #737373", "* c #A1A1A1", "= c #B4B4B4", "- c #B2B2B2", "; c #9D9D9D", "> c #676767", ", c #202020", "' c #1C1C1C", ") c #272727", "! c #616161", "~ c #CACACA", "{ c #CFCFCF", "] c #D0D0D0", "^ c #CECECE", "/ c #C9C9C9", "( c #C1C1C1", "_ c #A7A7A7", ": c #4C4C4C", "< c #131313", "[ c #222222", "} c #757575", "| c #D3D3D3", "1 c #DBDBDB", "2 c #E7E7E7", "3 c #EFEFEF", "4 c #F3F3F3", "5 c #F1F1F1", "6 c #E5E5E5", "7 c #D2D2D2", "8 c #BCBCBC", "9 c #5E5E5E", "0 c #101010", "a c #212121", "b c #5B5B5B", "c c #CCCCCC", "d c #D7D7D7", "e c #F5F5F5", "f c #FAFAFA", "g c #FBFBFB", "h c #F8F8F8", "i c #F0F0F0", "j c #E1E1E1", "k c #C2C2C2", "l c #434343", "m c #0F0F0F", "n c #1F1F1F", "o c #B9B9B9", "p c #D6D6D6", "q c #F9F9F9", "r c #FDFDFD", "s c #454545", "t c #F2F2F2", "u c #ECECEC", "v c #E4E4E4", "w c #ABABAB", "x c #0E0E0E", "y c #1B1B1B", "z c #6D6D6D", "A c #FEFEFE", "B c #FCFCFC", "C c #EEEEEE", "D c #E6E6E6", "E c #575757", "F c #090909", "G c #141414", "H c #A8A8A8", "I c #D8D8D8", "J c #F6F6F6", "K c #F4F4F4", "L c #DCDCDC", "M c #9B9B9B", "N c #060606", "O c #111111", "P c #C5C5C5", "Q c #DFDFDF", "R c #444444", "S c #424242", "T c #EDEDED", "U c #BFBFBF", "V c #C6C6C6", "W c #E3E3E3", "X c #414141", "Y c #EAEAEA", "Z c #E0E0E0", "` c #BABABA", " . c #050505", ".. c #0B0B0B", "+. c #A5A5A5", "@. c #D1D1D1", "#. c #939393", "$. c #020202", "%. c #0A0A0A", "&. c #5F5F5F", "*. c #D9D9D9", "=. c #EBEBEB", "-. c #E9E9E9", ";. c #D4D4D4", ">. c #000000", ",. c #E2E2E2", "'. c #3F3F3F", "). c #DADADA", "!. c #CBCBCB", "~. c #3B3B3B", "{. c #D5D5D5", "]. c #C8C8C8", "^. c #BDBDBD", "/. c #515151", "(. c #C7C7C7", "_. c #CDCDCD", ":. c #B8B8B8", "<. c #030303", "[. c #313131", "}. c #999999", "|. c #BBBBBB", "1. c #B6B6B6", "2. c #909090", "3. c #2B2B2B", "4. c #010101", "5. c #7A7A7A", "6. c #9A9A9A", "7. c #777777", "8. c #3C3C3C", "9. c #686868", "0. c #797979", "a. c #3A3A3A", " ", " . + @ # # # ", " $ % & * = - ; > , ' ", " ) ! = ~ { ] ^ / ( _ : < ", " [ } ~ | 1 2 3 4 5 6 7 8 9 0 ", " a b c d 6 e f g f h e i j k l m ", " n o p 2 q g r s s g h t u v w x ", " y z 7 j e f r A s s B q e C D 1 E F ", " G H I C J q B A s s g h K C D L M N ", " O P Q 3 e R R s s s R l S T 6 1 U N ", " x V W u t l R R R R l S X Y Z d ` . ", " ..+.j 2 T 5 K J l l 4 3 u v 1 @.#.$. ", " %.&.*.j D =.C 3 X X T -.v 1 ;.~ : >. ", " %.= I L ,.6 D '.'.W Q ).;.!.* $. ", " N ~.c 7 ;.).1 ).1 I {.] ].^.$ >. ", " ./.k (.!.c _.!.!.].k :.s >. ", " <.[.}.|.^.8 8 8 1.2.3.>.>.>. ", " 4.<.X 5.6.6.7.8.>.>. >.>.>.>. ", " >.>.>.>.>.>. , , >.>. ", " >.9.. >.>. ", " >.0.a.>.>. ", " >.9.n >. ", " >.>. ", " "}; /* XPM */ static char * icon_zoomfit[] = { "24 24 140 2", " c None", ". c #343434", "+ c #2D2D2D", "@ c #292929", "# c #262626", "$ c #2E2E2E", "% c #303030", "& c #737373", "* c #A1A1A1", "= c #B4B4B4", "- c #B2B2B2", "; c #9D9D9D", "> c #676767", ", c #202020", "' c #1C1C1C", ") c #272727", "! c #616161", "~ c #CACACA", "{ c #CFCFCF", "] c #D0D0D0", "^ c #CECECE", "/ c #C9C9C9", "( c #C1C1C1", "_ c #A7A7A7", ": c #4C4C4C", "< c #131313", "[ c #222222", "} c #757575", "| c #D3D3D3", "1 c #DBDBDB", "2 c #E7E7E7", "3 c #EFEFEF", "4 c #F3F3F3", "5 c #F1F1F1", "6 c #E5E5E5", "7 c #D2D2D2", "8 c #BCBCBC", "9 c #5E5E5E", "0 c #101010", "a c #212121", "b c #5B5B5B", "c c #CCCCCC", "d c #464646", "e c #4B4B4B", "f c #505050", "g c #525252", "h c #FBFBFB", "i c #FAFAFA", "j c #515151", "k c #4F4F4F", "l c #4A4A4A", "m c #C2C2C2", "n c #434343", "o c #0F0F0F", "p c #1F1F1F", "q c #B9B9B9", "r c #D6D6D6", "s c #535353", "t c #FDFDFD", "u c #FCFCFC", "v c #4D4D4D", "w c #E4E4E4", "x c #ABABAB", "y c #0E0E0E", "z c #1B1B1B", "A c #6D6D6D", "B c #E1E1E1", "C c #FEFEFE", "D c #F9F9F9", "E c #4E4E4E", "F c #E6E6E6", "G c #575757", "H c #090909", "I c #141414", "J c #A8A8A8", "K c #D8D8D8", "L c #EEEEEE", "M c #F8F8F8", "N c #DCDCDC", "O c #9B9B9B", "P c #060606", "Q c #111111", "R c #C5C5C5", "S c #DFDFDF", "T c #F5F5F5", "U c #F7F7F7", "V c #F2F2F2", "W c #EDEDED", "X c #BFBFBF", "Y c #C6C6C6", "Z c #E3E3E3", "` c #ECECEC", " . c #F4F4F4", ".. c #F0F0F0", "+. c #EAEAEA", "@. c #E0E0E0", "#. c #D7D7D7", "$. c #BABABA", "%. c #050505", "&. c #0B0B0B", "*. c #A5A5A5", "=. c #F6F6F6", "-. c #D1D1D1", ";. c #939393", ">. c #020202", ",. c #0A0A0A", "'. c #5F5F5F", "). c #D9D9D9", "!. c #E9E9E9", "~. c #484848", "{. c #D4D4D4", "]. c #000000", "^. c #494949", "/. c #474747", "(. c #454545", "_. c #CBCBCB", ":. c #3B3B3B", "<. c #DADADA", "[. c #444444", "}. c #414141", "|. c #BDBDBD", "1. c #C7C7C7", "2. c #CDCDCD", "3. c #C8C8C8", "4. c #B8B8B8", "5. c #030303", "6. c #313131", "7. c #999999", "8. c #BBBBBB", "9. c #B6B6B6", "0. c #909090", "a. c #2B2B2B", "b. c #010101", "c. c #7A7A7A", "d. c #9A9A9A", "e. c #777777", "f. c #3C3C3C", "g. c #686868", "h. c #797979", "i. c #3A3A3A", " ", " . + @ # # # ", " $ % & * = - ; > , ' ", " ) ! = ~ { ] ^ / ( _ : < ", " [ } ~ | 1 2 3 4 5 6 7 8 9 0 ", " a b c d e f g h i j f k l m n o ", " p q r : g g s t u g j k v w x y ", " z A 7 B f g t C C t u D f E F 1 G H ", " I J K L j g u C C t h M f E F N O P ", " Q R S 3 T M h t t u i U V W 6 1 X P ", " y Y Z ` V T M i i i U ...+.@.#.$.%. ", " &.*.B 2 E k .=.=.T 4 3 v e 1 -.;.>. ", " ,.'.).B e v L 3 3 L W !.e ~.{.~ : ]. ", " ,.= K ~.l e e F 2 l ^./.(._.* >. ", " P :.c (.(./.~.<.1 /.d [.}.|.$ ]. ", " %.j m 1._.c 2._._.3.m 4.(.]. ", " 5.6.7.8.|.8 8 8 9.0.a.].].]. ", " b.5.}.c.d.d.e.f.].]. ].].].]. ", " ].].].].].]. , , ].]. ", " ].g.. ].]. ", " ].h.i.].]. ", " ].g.p ]. ", " ].]. ", " "}; /* XPM */ static char * icon_zoomundo[] = { "24 24 31 1", " c None", ". c #000000", "+ c #EFE5BA", "@ c #EFE7C1", "# c #EED680", "$ c #EFE4B6", "% c #D5B75D", "& c #B29544", "* c #D1B051", "= c #C0AF73", "- c #C0A048", "; c #986B07", "> c #D1940C", ", c #E0B74C", "' c #D9C374", ") c #8F6406", "! c #D59D1C", "~ c #B1933F", "{ c #DFB74A", "] c #CCB76D", "^ c #B8820A", "/ c #D9A72E", "( c #D7A62C", "_ c #C7B26A", ": c #D4B150", "< c #A39256", "[ c #E2CB79", "} c #C9B46B", "| c #8D7E4A", "1 c #AE9C5C", "2 c #96864F", " ", " ", " ", " . ", " .. ", " .+. ", " .@#.... ", " .$####%&. ", " .+#######*. ", " .=#########-. ", " .;>>>>>>,#'.. ", " .)>>>>>>!#~. ", " .)>...;>{]. ", " .;. ..^/#. ", " .. ..>#. ", " . .(_. ", " .:<. ", " .[. ", " .}|. ", " .12. ", " .. ", " ", " ", " "}; /* XPM */ static char * zoom_larrow[] = { "24 24 57 1", " c None", ". c #000000", "+ c #F7F7F7", "@ c #CBD6CA", "# c #E7EFE7", "$ c #ACC8A9", "% c #C9DBC9", "& c #E6EEE5", "* c #BFCEBF", "= c #E7EFE6", "- c #BBCFBA", "; c #B3C4B3", "> c #E6EEE6", ", c #B9CEB7", "' c #B5CEB5", ") c #B7CCB5", "! c #BFD4BF", "~ c #C7D7C5", "{ c #DBE5DB", "] c #DAE5D9", "^ c #CBDAC9", "/ c #7EAB78", "( c #BAD1B9", "_ c #B3CAB1", ": c #B0C9B0", "< c #B0C9AE", "[ c #AEC7AC", "} c #AAC5A8", "| c #A9C4A7", "1 c #698267", "2 c #E4ECE3", "3 c #2D2D2D", "4 c #E0EADE", "5 c #B3CCB1", "6 c #B0C7AE", "7 c #ADC6AB", "8 c #ADC8AB", "9 c #AAC7A8", "0 c #678C63", "a c #9FB79B", "b c #6B9063", "c c #C2CDC2", "d c #8EB48A", "e c #87AF84", "f c #87B083", "g c #88AF84", "h c #88B085", "i c #86AF82", "j c #547150", "k c #95A88F", "l c #5B7950", "m c #3C5235", "n c #4A6342", "o c #3B5035", "p c #415639", "q c #889D7F", "r c #475E3E", " ", " ", " ", " .... . ", " .+@. .. ", " .#$. .%. ", " .#$. .&*. ", " .#$. .=-;........ ", " .#$. .>,'),!~{]^/. ", " .#$. .>(_:<[}}}[|1. ", " .2$. 34567789[[6[80. ", " .ab..cdeeeeefgefhij. ", " .kl. .mllllllllllln. ", " .kl. .mlllllllllln. ", " .kl. .mllnoooooop. ", " .kl. .mln........ ", " .kl. .mn. ", " .kl. .n. ", " .qr. .. ", " .... . ", " ", " ", " ", " "}; /* XPM */ static char * zoom_rarrow[] = { "24 24 52 1", " c None", ". c #000000", "+ c #F7F7F7", "@ c #CBD6CA", "# c #BECEBA", "$ c #E7EFE7", "% c #ACC8A9", "& c #EBF2EA", "* c #77A16E", "= c #E3EBE2", "- c #709867", "; c #F8F8F7", "> c #F1F5F0", ", c #ECF2EB", "' c #E5EEE3", ") c #E0EBDF", "! c #D8E6D6", "~ c #C6D9C2", "{ c #C5D7C3", "] c #B2CBB0", "^ c #AAC7A8", "/ c #0F1308", "( c #DDE6DB", "_ c #AEC8AD", ": c #ABC7A8", "< c #AAC6A7", "[ c #A8C6A5", "} c #ADC8AD", "| c #A8C7A8", "1 c #A5C4A3", "2 c #7F9F76", "3 c #D6E1D4", "4 c #ABC7AA", "5 c #A7C5A4", "6 c #A9C7A6", "7 c #AFC8AD", "8 c #A4C3A2", "9 c #6B9060", "0 c #E4ECE3", "a c #A7B6A2", "b c #698D60", "c c #6B9063", "d c #445B2C", "e c #9FB79B", "f c #9FB199", "g c #5B7950", "h c #95A88F", "i c #9FAF99", "j c #789171", "k c #506B46", "l c #889D7F", "m c #475E3E", " ", " ", " ", " . .... ", " .. .+@. ", " .#. .$%. ", " .&*. .$%. ", " ........=%-. .$%. ", " .;>,')!~{]^-/ .$%. ", " .(_:::<[^}|12. .$%. ", " .34[5[6:%^:789. .0%. ", " .abccccccccccbd..ec. ", " .fgggggggggggd. .hg. ", " .iggggggggggd. .hg. ", " .jkkkkkkgggd. .hg. ", " ........kgd. .hg. ", " .kd. .hg. ", " .d. .hg. ", " .. .lm. ", " . .... ", " ", " ", " ", " "}; /* XPM */ static char * prev_page_xpm[] = { "24 24 170 2", " c None", ". c #000000", "+ c #040506", "@ c #0B0F12", "# c #959FAA", "$ c #C3C6CA", "% c #82909E", "& c #F1F1F1", "* c #D5D7D8", "= c #0A0D10", "- c #11171C", "; c #8693A0", "> c #EFF0F0", ", c #DEDEDE", "' c #D5D5D5", ") c #9B9FA4", "! c #0E1317", "~ c #85929F", "{ c #DBDBDB", "] c #CACACA", "^ c #C8C8C8", "/ c #C8C9CA", "( c #0C0F13", "_ c #141A20", ": c #798895", "< c #D2D2D2", "[ c #C3C3C3", "} c #CDCDCD", "| c #74797E", "1 c #171F26", "2 c #7F8D9A", "3 c #DADADA", "4 c #D3D3D3", "5 c #C4C4C4", "6 c #CECECE", "7 c #C0C0C0", "8 c #B1B1B1", "9 c #0D1115", "0 c #768592", "a c #EEEFEF", "b c #D9D9D9", "c c #D0D0D0", "d c #C2C2C2", "e c #CBCBCB", "f c #C9C9C9", "g c #BCBCBC", "h c #A4A7A9", "i c #686B6C", "j c #333333", "k c #414F5D", "l c #ADB5BC", "m c #EAEAEA", "n c #BFBFBF", "o c #BDBDBD", "p c #C6C6C6", "q c #B5B6B7", "r c #899096", "s c #B8B8B8", "t c #FFFFFF", "u c #404142", "v c #4D6074", "w c #EBEBEB", "x c #D1D1D1", "y c #C1C1C1", "z c #B7B7B7", "A c #979FA7", "B c #A1A3A4", "C c #FCFDFD", "D c #F3F4F4", "E c #EBECED", "F c #EAEBEC", "G c #E9EAEB", "H c #EEEFF1", "I c #F6F7F8", "J c #E4E5E6", "K c #929395", "L c #32414F", "M c #8C98A2", "N c #E7E7E7", "O c #BBBBBB", "P c #A4A7AB", "Q c #939699", "R c #D7D8D8", "S c #FAFCFC", "T c #F9FAFB", "U c #F8F9FA", "V c #F7F8F9", "W c #F5F6F8", "X c #F7F7F9", "Y c #C6C7C7", "Z c #4F5E6A", "` c #4C5F72", " . c #E8E8E8", ".. c #BEBEBE", "+. c #1F1F1F", "@. c #B5B5B6", "#. c #979EA4", "$. c #A8A8A8", "%. c #FDFEFE", "&. c #F5F6F6", "*. c #E7E9E9", "=. c #F0F1F2", "-. c #E0E2E3", ";. c #8F969D", ">. c #151C22", ",. c #354453", "'. c #8D99A2", "). c #E3E3E3", "!. c #8E949A", "~. c #9D9F9F", "{. c #F2F3F4", "]. c #F1F2F3", "^. c #F6F6F7", "/. c #A6A8AB", "(. c #737F8A", "_. c #4B5F71", ":. c #CDDECB", "<. c #97999B", "[. c #E7E8E8", "}. c #F4F5F5", "|. c #FBFBFB", "1. c #D8D8DA", "2. c #939BA3", "3. c #0F1418", "4. c #B1C9B0", "5. c #E6E7E8", "6. c #FAFAFB", "7. c #F5F5F7", "8. c #AEB2B6", "9. c #5C6C7C", "0. c #B4CBB2", "a. c #B5CEB5", "b. c #B9CEB7", "c. c #BAD1BA", "d. c #BBD0B9", "e. c #B2C9B0", "f. c #7EAB78", "g. c #FBFCFC", "h. c #DEE1E3", "i. c #9DA6AE", "j. c #AAC7A8", "k. c #B3CAB1", "l. c #B0C9B0", "m. c #AEC7AC", "n. c #AAC5A8", "o. c #A9C4A7", "p. c #698267", "q. c #F9F9FA", "r. c #BBBFC4", "s. c #566779", "t. c #2D2D2D", "u. c #CFDFCC", "v. c #ADC8AB", "w. c #B0C7AE", "x. c #ADC6AB", "y. c #678C63", "z. c #D1D2D4", "A. c #9AA3AC", "B. c #3C5235", "C. c #5B7950", "D. c #4A6342", "E. c #E8ECEE", "F. c #B2B8BE", "G. c #717D88", "H. c #3B5035", "I. c #415639", "J. c #7A8695", "K. c #768594", "L. c #2C343D", "M. c #21272E", " . + ", " @ # $ . ", " @ % & * = ", " - ; > , ' ) . ", " ! ~ > { ] ^ / ( ", " _ : & ' ] < [ } | . ", " 1 2 > 3 4 5 6 7 ] 8 9 ", ". 0 a b 4 c d e f g h i j . . . . . . . ", "k l m < n } e o p q r s t t t t t t t u . ", ". v w x [ y ^ z [ A B C D E F G H I J K . ", " L M N f O 5 d P Q R C S T U V W X Y Z . ", " . ` .p ..+.@.#.$.%.&.*.E F =.U -.;.>.. ", " ,.'.).. . !.~.t %.C S {.].V ^./.(.+ ", " . _.. :.. <.b t [.a }.T U |.1.2.3. ", " . :.4.. . . . . . . 5.6.7.8.9.. ", " . :.0.a.b.c.b.d.e.f.. T g.h.i.= ", " . :.j.k.l.m.n.n.m.o.p.. g.q.r.s.. ", "t.u.v.w.x.x.j.m.m.m.v.y.. t z.A.+ ", " . B.C.C.C.C.C.C.C.C.D.. E.F.G.. ", " . B.C.C.H.H.H.H.H.I.. J.K.. ", " . B.C.. . . . . . . L.M. ", " . B.. ", " . . ", " . "}; /* XPM */ static char * next_page_xpm[] = { "24 24 172 2", " c None", ". c #000000", "+ c #040506", "@ c #0B0F12", "# c #959FAA", "$ c #C3C6CA", "% c #82909E", "& c #F1F1F1", "* c #D5D7D8", "= c #0A0D10", "- c #11171C", "; c #8693A0", "> c #EFF0F0", ", c #DEDEDE", "' c #D5D5D5", ") c #9B9FA4", "! c #0E1317", "~ c #85929F", "{ c #DBDBDB", "] c #CACACA", "^ c #C8C8C8", "/ c #C8C9CA", "( c #0C0F13", "_ c #141A20", ": c #798895", "< c #D2D2D2", "[ c #C3C3C3", "} c #CDCDCD", "| c #74797E", "1 c #171F26", "2 c #7F8D9A", "3 c #DADADA", "4 c #D3D3D3", "5 c #C4C4C4", "6 c #CECECE", "7 c #C0C0C0", "8 c #B1B1B1", "9 c #0D1115", "0 c #768592", "a c #EEEFEF", "b c #D9D9D9", "c c #D0D0D0", "d c #C2C2C2", "e c #CBCBCB", "f c #C9C9C9", "g c #BCBCBC", "h c #A4A7A9", "i c #686B6C", "j c #333333", "k c #414F5D", "l c #ADB5BC", "m c #EAEAEA", "n c #BFBFBF", "o c #BDBDBD", "p c #C6C6C6", "q c #B5B6B7", "r c #899096", "s c #B8B8B8", "t c #FFFFFF", "u c #404142", "v c #4D6074", "w c #EBEBEB", "x c #D1D1D1", "y c #C1C1C1", "z c #B7B7B7", "A c #979FA7", "B c #A1A3A4", "C c #FCFDFD", "D c #F3F4F4", "E c #EBECED", "F c #EAEBEC", "G c #E9EAEB", "H c #EEEFF1", "I c #F6F7F8", "J c #E4E5E6", "K c #929395", "L c #32414F", "M c #8C98A2", "N c #E7E7E7", "O c #BBBBBB", "P c #A4A7AB", "Q c #939699", "R c #D7D8D8", "S c #FAFCFC", "T c #F9FAFB", "U c #F8F9FA", "V c #F7F8F9", "W c #F5F6F8", "X c #F7F7F9", "Y c #C6C7C7", "Z c #4F5E6A", "` c #4C5F72", " . c #E8E8E8", ".. c #BEBEBE", "+. c #B5B5B6", "@. c #979EA4", "#. c #A8A8A8", "$. c #FDFEFE", "%. c #F5F6F6", "&. c #E7E9E9", "*. c #F0F1F2", "=. c #8F969D", "-. c #151C22", ";. c #354453", ">. c #8D99A2", ",. c #E3E3E3", "'. c #8E949A", "). c #9D9F9F", "!. c #F2F3F4", "~. c #F1F2F3", "{. c #F6F6F7", "]. c #4B5F71", "^. c #E5E5E5", "/. c #9E9FA0", "(. c #97999B", "_. c #E7E8E8", ":. c #F4F5F5", "<. c #FBFBFB", "[. c #D8D8DA", "}. c #77A16E", "|. c #394957", "1. c #828F97", "2. c #8A8E92", "3. c #B4B4B4", "4. c #ACC8A9", "5. c #709867", "6. c #4A5D70", "7. c #ABABAB", "8. c #F8F8F8", "9. c #C1D6BD", "0. c #BDD3B8", "a. c #BFD4BB", "b. c #C2D7BE", "c. c #B2CBB0", "d. c #AAC7A8", "e. c #0F1308", "f. c #242F3A", "g. c #696D71", "h. c #777879", "i. c #F2F3F3", "j. c #AEC5A8", "k. c #AEC8AD", "l. c #ABC7A8", "m. c #AAC6A7", "n. c #A8C6A5", "o. c #ADC8AD", "p. c #A8C7A8", "q. c #A5C4A3", "r. c #7F9F76", "s. c #4A5F74", "t. c #313E4B", "u. c #B3BDC6", "v. c #D1D7DD", "w. c #D9DEE3", "x. c #F6F7F7", "y. c #A6BFA0", "z. c #ABC7AA", "A. c #A9C7A6", "B. c #AFC8AD", "C. c #A4C3A2", "D. c #6B9060", "E. c #2B343C", "F. c #29323B", "G. c #4F5F70", "H. c #5E7184", "I. c #919EAB", "J. c #6C8562", "K. c #5B7950", "L. c #445B2C", "M. c #252D35", "N. c #65815C", "O. c #506B46", " . + ", " @ # $ . ", " @ % & * = ", " - ; > , ' ) . ", " ! ~ > { ] ^ / ( ", " _ : & ' ] < [ } | . ", " 1 2 > 3 4 5 6 7 ] 8 9 ", ". 0 a b 4 c d e f g h i j . . . . . . . ", "k l m < n } e o p q r s t t t t t t t u . ", ". v w x [ y ^ z [ A B C D E F G H I J K . ", " L M N f O 5 d P Q R C S T U V W X Y Z . ", " . ` .p ..s +.@.#.$.%.&.E F *.U . =.-.. ", " ;.>.,.y ..'.).t $.C S !.~.V {.. . + ", " . ].^.y /.(.b t _.a :.T U <.[.. }.. ", " |.1.{ 2.3.t t $.. . . . . . . 4.5.. ", " . 6.O 7.t 8.& > . 9.0.a.b.b.b.c.d.5.e. ", " f.g.h.i.t t t . j.k.l.l.m.n.o.p.q.r.. ", " . s.t.u.v.w.x.. y.z.n.n.A.l.d.l.B.C.D.. ", " . E.F.G.H.I.. J.K.K.K.K.K.K.K.K.L.. ", " . . M.. N.O.O.O.O.O.K.K.L.. ", " . . . . . . . K.L.. ", " . L.. ", " . . ", " . "}; /* XPM */ static char *wave_info[] = { /* columns rows colors chars-per-pixel */ "64 64 24 1", " c #030401", ". c #1A2A0A", "X c #243910", "o c #345414", "O c #3C6317", "+ c #45711A", "@ c #4C7722", "# c #51841F", "$ c #599222", "% c #609E24", "& c #69AD28", "* c #7AC82E", "= c #7A965E", "- c #7C9861", "; c #85DA32", ": c #8BE434", "> c #809C64", ", c #8FB26D", "< c #99C370", "1 c #A3CE79", "2 c #ACD485", "3 c #BDE992", "4 c #C1EC98", "5 c #C7EEA1", /* pixels */ "3333333333333333333333333333333333333333333334333333333333333343", "3323333233332333333333333333333333333333333333333333333333333333", "3333433334333333433334343333334433344433333534343343333434333333", "332>>>,,>>,<<,,>>,>,>>,><<,>,>,,>,,>,,1,,>,,,>,>>,,<<,,,,>,>,233", "33- . X@+X . . .+@o . o@+. . X@@. . >43", "23= .+O. O+o o+o .++. >43", "33= .O+. O+o o+O .++. -33", "33= .++. +%&$O+++OO+++O$&%+ .++. -34", "33- .++. o*::::::::::::::::*o .++. -43", "33= .O+. +::::;:::::::::::::O .OO. -43", "33= .++. $:;:;;;;*;;*;;;;:::$ .++. -33", "33= .++. &:*%+oooooooooo@%;:& .++. -34", "33= .+O. X*:&+o o+&:;X .++. >43", "33= .++. O::&+o X+%::o .++. >44", "33= .++X $::$+o o+$;:$ .++. .-33", "33,+OOOOOOO++OOOOO+oO*:*@+OoOO+OOOOOO++@*:*OOOOOOOO+++OOOOOoO,43", "33,+++++++++++++++++#;:&++++++++++++++++*:;#++++++++++++++++@<33", "33<+++O#++++++++++++%::&++++++++++++++++&:;%+++++++++++++++++<33", "33>OoOooooO++OoooOoO%::#O+OooooOooooo++O@;:&ooooooO++ooooOooO,33", "33= .O+. &:*XO+o o+OX*:& .++. -43", "33- .++. .*:%.O+o oOO.%:*. .++. -44", "33= .++. o;:+ O+X o+O +:;o .O+. >44", "33= .+O. +::o O+o o@O o::+ .++. -34", "33= .++. %:*. O+X o+O .*:% .+O. -43", "33= .++. .&:& .O+o X+O. &:*. .++. -43", "33= .+O. X;:# O+o o+O #:*X .OO. -44", "33= .++. +;:o .O+X o+O o::O .++. -43", "33- .O+. $:*. OOo o+O X*:$ .++. -43", "33= .++. .&:&. O+o oOO &:&. .++. =43", "33- .++. .;:$ .O+o o+O. .$:*. .++X .-43", "33,OOOOOOOO++OOOo%::%OoO+++oOOOoOOOoOO++OoO%::$OOOO++OoOOOOO+,43", "33,++++++++++++++&:;$++++++++++++++++++++++$::&++++++++++++++,44", "33,@++++++++++++@*:*#++++++++++++++++++++++#*:*++++++++++++++,44", "33,OooooooO++Ooo+;:&oooO++Ooooooooooo+++oooo&:;+ooO++OooooooO,43", "33- .++. O;:+ O+o o+O. +:;O .++. -44", "33- .++. #:*o .O+o o+O o;:+ .++. -44", "33= .++. &:*. O+o X+O. .*:& .++. .=44", "33= .+O. .*:% O+o o+O %:*. .O+. =43", "33= .++. o;;+ O+X o+O +:;o .+O. -44", "33- .O+. +:;o OOo o+O o;:+ .++. -44", "33- .+O. &:*. O+o o+O .*:& .++. -44", "33- .++. *:& O+o X+o &:* .+O. -44", "33= .++.X;:@ O+o o+O #:;X.O+. -44", "33= .++.O:;o .OOo o+O o::O.++. -43", "33- X++X$:*X .++o o+O. X*:$X++. .-44", "33,OooOOOOOO++*:*OOOoOoo++OoOoOOoOoOO+++OooOOO+*:*+++OOOOoOOo,44", "33,++++++++++#;:&@+++++++++++++++++++++++++++++&:;$++++@+++++<43", "33<@+++++++++%::&++++++++++++++++++++++++++++++&::%O+++++++++<44", "33,OoOoOoOO++&::+ooOOooO++OOOooOOOoooO++OOoooOo+;:*++OoOooOoO,44", "33- .+@*:&. .O+o o+O .&:*@+. >44", "33- .+#;:% O+o o+O. $:;#+. -44", "33- .O%::+ OOo o+O +::%O. -44", "33- .oooo+%*:*o O+X o+O o*:*$+oOoo =44", "33- O;;:;:;::* .O+o X+o. .*:::::;;;O .=44", "33- #::::::::% O+o o+O %::::::::# -44", "33- O;:::::::+ O+o o++ +;:;:;::;O -44", "35- oOoO+%%+. O@X X+O .@%%+OOOo -55", "35- .++. O@o o+O .++. >53", "33- .++. O+X o+O X+O. -43", "33-. . . .X@@X. . .. ..@@o.. . . . o@@.. . .. . X@@X . . ..>44", "332,,,,,,,,22,,<,,<,<,<,22,,,<<,<,<,12<2<<,<,<,<<,1211<<<<,<2243", "3333333343333335335353533335355354455433445455545533445444543335", "4233333333333333333333333333333333333333434344343335333334333334", "5353533353353435444444535355354555455455545555555455555555555555" }; /* XPM */ static char *wave_alert[] = { /* columns rows colors chars-per-pixel */ "64 64 55 1", " c #030200", ". c #1A1501", "X c #1A1A1A", "o c #241E02", "O c #2C2402", "+ c #352B03", "@ c #3E3303", "# c #272212", "$ c #262626", "% c #322F23", "& c #333022", "* c #463903", "= c #5B4B05", "- c #7D6306", "; c #836806", ": c #8E6D16", "> c #916F15", ", c #977314", "< c #A77C12", "1 c #DD550F", "2 c #E15E13", "3 c #E86801", "4 c #F46E00", "5 c #EE7601", "6 c #F57A00", "7 c #E86B1A", "8 c #E9771B", "9 c #ED7923", "0 c #AB8708", "q c #B08D08", "w c #B78914", "e c #CB910A", "r c #D89907", "t c #CB9412", "y c #F78900", "u c #E29E05", "i c #F89600", "p c #F68D19", "a c #F79518", "s c #CFA008", "d c #D7A508", "f c #E8A305", "g c #FAA601", "h c #EBB207", "j c #FBB100", "k c #F8A11C", "l c #EE8426", "z c #F2882A", "x c #F79C2D", "c c #F28D31", "v c #F59937", "b c #F8A62B", "n c #F8A736", "m c #F9B036", "M c None", /* pixels */ "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM", "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM", "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM", "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM", "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM", "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM", "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM", "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM9v9MMMMMMMMMMMMMMMMMMMMMMMMMMMMMM", "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMvnvMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM", "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMM9nxn9MMMMMMMMMMMMMMMMMMMMMMMMMMMMM", "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMvnxnv9MMMMMMMMMMMMMMMMMMMMMMMMMMMM", "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMvnbbxvcMMMMMMMMMMMMMMMMMMMMMMMMMMMM", "MMMMMMMMMMMMMMMMMMMMMMMMMMMM8nbxxbvn9MMMMMMMMMMMMMMMMMMMMMMMMMMM", "MMMMMMMMMMMMMMMMMMMMMMMMMMMMcnxbbxbbv1MMMMMMMMMMMMMMMMMMMMMMMMMM", "MMMMMMMMMMMMMMMMMMMMMMMMMMMznbbxvxbxvzMMMMMMMMMMMMMMMMMMMMMMMMMM", "MMMMMMMMMMMMMMMMMMMMMMMMMM7nnxbbxbxxbv7MMMMMMMMMMMMMMMMMMMMMMMMM", "MMMMMMMMMMMMMMMMMMMMMMMMMMvnbxxbnxbxxncMMMMMMMMMMMMMMMMMMMMMMMMM", "MMMMMMMMMMMMMMMMMMMMMMMMMlnbbbbxxbxxxvn9MMMMMMMMMMMMMMMMMMMMMMMM", "MMMMMMMMMMMMMMMMMMMMMMMMMvvbbnxbbxbxxxnv7MMMMMMMMMMMMMMMMMMMMMMM", "MMMMMMMMMMMMMMMMMMMMMMMMzmbbbbbxxbxbxxxnzMMMMMMMMMMMMMMMMMMMMMMM", "MMMMMMMMMMMMMMMMMMMMMMM7nbbnbxxbbbxxxxxxn7MMMMMMMMMMMMMMMMMMMMMM", "MMMMMMMMMMMMMMMMMMMMMMMvnbbbbbbbbxbxbxxxvvMMMMMMMMMMMMMMMMMMMMMM", "MMMMMMMMMMMMMMMMMMMMMMzmbbbbbbbbbbbbxxxxxnzMMMMMMMMMMMMMMMMMMMMM", "MMMMMMMMMMMMMMMMMMMMMMnbbbbbbe<0<<$$$$$>bnxxxxbxxv9MMMMMMMMMMMMMMMMM", "MMMMMMMMMMMMMMMMMMbmbbbmbbbbb,$$$$$>kbxxxxxcxxcMMMMMMMMMMMMMMMMM", "MMMMMMMMMMMMMMMMMlnbbbbbbbbbb,%$$$% c #A050A050A050", ", c #A75FA75FA75F", "< c #AEE1AEE1AEE1", "1 c #B6C8B6C8B6C8", "2 c #BF08BF08BF08", "3 c #8D95CFC9852A", "4 c #8F63D1058715", "5 c #9587D4AD8BC2", "6 c #93CDD23F8E7D", "7 c #9587D2DB8F63", "8 c #9663D5488CAC", "9 c #98EDD5E28F63", "0 c #9663D3779048", "q c #9816D412920D", "w c #9B6DD714920D", "e c #9C40D7AD92ED", "r c #9DE3D84593CD", "t c #9F82D9759587", "y c #A050D9759663", "u c #A37CDB3998ED", "i c #A37CDB3999C4", "p c #A50DDC649B6D", "a c #A69ADCF99C40", "s c #A75FDD8E9D12", "d c #A9A8DEB69F82", "f c #B284DE22AB2A", "g c #BAF4E194B4A9", "h c #BDAFE2B7B77C", "j c #C457E4F8BF08", "k c #823DB3F3E06F", "l c #8F63BDAFE588", "z c #9048BE5CE617", "x c #9C40C64BEB10", "c c #9D12C83AEB9C", "v c #A75FCD4CF077", "b c #A9A8CFC9F100", "n c #B33CD4ADF4B4", "m c #B4A9D5E2F53B", "M c #BD01DA0CF85A", "N c #BD01DAA3F85A", "B c #C64BC64BC64B", "V c #CC0BCC0BCC0B", "C c #D23FD23FD23F", "Z c #D548D548D548", "A c #D714D714D714", "S c #D845D845D845", "D c #D9C0D9C0D9C0", "F c #DBCFDBCFDBCF", "G c #DCF9DCF9DCF9", "H c #D23FEB10CDEC", "J c #D377EB9CCFC9", "K c #D412EC27D067", "L c #D548ECB2D23F", "P c #C3AFDE22FA6A", "I c #D975DFDDF53B", "U c #DE22E468F6CC", "Y c #DF4AE588F751", "T c #E348E96BF85A", "R c None", /* pixels */ "RRRRRRRRRRRRRRRR", "RRRRRRPNmbRRRRRR", "RRRRRRMTYcRRRRRR", "RRRRRRnUIzRRRRRR", "RRRRRRvxlkRRRRRR", "RRRRRRRRRRRRRRRR", "RRRRRRRSZRRRRRRR", "RRGFDACVB21<,>RR", "RRDRRRRRRRRRR:RR", "RRRRRRRRRRRRRRRR", "dspuRRe84;RR%#+o", "aLKtRR5jh=RR@q0X", "iJHeRR3gf&RRO76 ", "yrw9RR-*&$RRX. ", "RRRRRRRRRRRRRRRR", "RRRRRRRRRRRRRRRR" }; /* XPM */ static char *cog[] = { /* columns rows colors chars-per-pixel */ "16 16 103 2", " c #494949", ". c #4E4E4E", "X c #515151", "o c gray32", "O c #535353", "+ c #585858", "@ c #5A5A5A", "# c #5B5B5B", "$ c gray36", "% c gray38", "& c #626262", "* c #646464", "= c #676767", "- c DimGray", "; c #6A6A6A", ": c gray42", "> c #6D6D6D", ", c gray43", "< c #6F6F6F", "1 c #717171", "2 c #767676", "3 c #777777", "4 c #797979", "5 c gray48", "6 c #7E7E7E", "7 c #808080", "8 c #818181", "9 c gray51", "0 c #838383", "q c #848484", "w c gray52", "e c gray53", "r c #898989", "t c #8B8B8B", "y c gray55", "u c gray56", "i c #939393", "p c gray58", "a c #959595", "s c gray60", "d c #9A9A9A", "f c gray61", "g c gray62", "h c #A0A0A0", "j c gray63", "k c gray64", "l c #A4A4A4", "z c #A5A5A5", "x c gray65", "c c #A7A7A7", "v c gray66", "b c #AAAAAA", "n c gray67", "m c #ACACAC", "M c gray68", "N c gray69", "B c #B1B1B1", "V c #B2B2B2", "C c gray71", "Z c #B6B6B6", "A c #B7B7B7", "S c #B9B9B9", "D c gray73", "F c #BCBCBC", "G c gray74", "H c gray", "J c gray75", "K c #C0C0C0", "L c #C1C1C1", "P c gray76", "I c #C3C3C3", "U c gray77", "Y c #C5C5C5", "T c #C6C6C6", "R c gray78", "E c #C8C8C8", "W c gray79", "Q c #CACACA", "! c #CBCBCB", "~ c gray80", "^ c #CDCDCD", "/ c #CECECE", "( c gray81", ") c #D0D0D0", "_ c gray82", "` c #D2D2D2", "' c gray83", "] c #D5D5D5", "[ c gray84", "{ c #D8D8D8", "} c gray85", "| c gray86", " . c gainsboro", ".. c #DDDDDD", "X. c gray87", "o. c #E2E2E2", "O. c #E4E4E4", "+. c gray90", "@. c #E7E7E7", "#. c #E9E9E9", "$. c gray93", "%. c gray100", "&. c None", /* pixels */ "&.&.&.&.&.&.W I I L &.&.&.&.&.&.", "&.&.&._ / / W +.+.M Z N M &.&.&.", "&.&._ / / I I . .N N M c k &.&.", "&._ .$. .I D [ [ N M / #.Z t &.", "&.W I .[ { { { [ { _ / W 3 1 &.", "&.&.I [ / W D f j I I L Z t &.&.", "W I L { / D 0 3 6 u I L / u q q ", "I #.[ W / k q &.&.d M I D I .: ", "D o.[ I / N u &.&.a c I D L _ & ", "k u j _ I / j d a u L D D & + O ", "&.&.M I L I W c k L D Z c : &.&.", "&.M c [ I / _ W W / I L W , = &.", "&.k D .k q q L L , , k _ 0 O &.", "&.&.0 1 & 3 q / W & @ @ . &.&.", "&.&.&., : 4 0 D N $ @ @ . &.&.&.", "&.&.&.&.&.&., + O O &.&.&.&.&.&." }; /* XPM */ static char *chart_line[] = { /* columns rows colors chars-per-pixel */ "16 16 78 1", " c #2E5FA5", ". c #3062A9", "X c #3062AA", "o c #3264AC", "O c #3366AE", "+ c #3468B1", "@ c #3568B2", "# c #366BB5", "$ c #376BB6", "% c #3C72BF", "& c #3D74C2", "* c #3E75C3", "= c #3E76C4", "- c #3F76C5", "; c #3F77C6", ": c #4670BB", "> c #5A6BAD", ", c #4277C6", "< c #4078C7", "1 c #4179C9", "2 c #417ACA", "3 c #427ACB", "4 c #427BCC", "5 c #437CCC", "6 c #437CCD", "7 c #447DCE", "8 c #457ED0", "9 c #457FD1", "0 c #709FBD", "q c #8D527D", "w c #AE4565", "e c #ED222B", "r c #EE262E", "t c #EE272F", "y c #EF2830", "u c #EF2B32", "i c #EF2D34", "p c #F02E35", "a c #F03137", "s c #F03238", "d c #F13339", "f c #F1363C", "g c #F1373C", "h c #F2383D", "j c #F2393E", "k c #E73741", "l c #E83841", "z c #F23B40", "x c #F03D43", "c c #F23C41", "v c #F33D42", "b c #F33F43", "n c #CC4D62", "m c #F44246", "M c #F44347", "N c #F44548", "B c #F54A4D", "V c #F64D4F", "C c #F75254", "Z c #F85758", "A c #F85859", "S c #F95C5C", "D c #F95D5D", "F c #F96160", "G c #FA6362", "H c #FB6665", "J c #FB6765", "K c #FB6B69", "L c #8F6493", "P c #A85E82", "I c #8CA1C0", "U c #93ACD1", "Y c #9CB1D0", "T c #FE9694", "R c #FC9997", "E c #FEB5B2", "W c gray100", "Q c None", /* pixels */ "QQQQQQQQQQQQQQQQ", "QQQQQQQQQQQQQBNb", "QQQQQQQQQQQQQmRj", "QQQQQQQQQQQQmbjd", "QQQQQQQQQQQQzfdQ", "QQQQQQQ971QjfaQQ", "KHGQQQQ5Y0>kq$+O", "HEDAQQ51-:kw$+IX", "FDACVP,-QdiQQO. ", "QQQ7LnlfdiyQQQQQ", "QQ51,=faTrQQQQQQ", "951-QQQyreQQQQQQ", "1U=QQQQQQQQQQQQQ", "1=%QQQQQQQQQQQQQ", "QQQQQQQQQQQQQQQQ", "QQQQQQQQQQQQQQQQ" }; /* XPM */ static char *flag_green[] = { /* columns rows colors chars-per-pixel */ "16 16 107 2", " c #321D16", ". c #507A51", "X c #87581D", "o c #8F5F21", "O c #9A6A2B", "+ c #9C6B2C", "@ c #886534", "# c #976E35", "$ c #A4722E", "% c #AC7935", "& c #AC7B38", "* c #B07E3A", "= c #4DA630", "- c #4CA631", "; c #4DA631", ": c #4CA534", "> c #47A538", ", c #45A33C", "< c #52A035", "1 c #47B133", "2 c #47B233", "3 c #4CB335", "4 c #3B9477", "5 c #44864D", "6 c #548D49", "7 c #4C984C", "8 c #539447", "9 c #5B9946", "0 c #478856", "q c #428559", "w c #4B8C59", "e c #79B75E", "r c #63A76A", "t c #74CD5F", "y c #77CE63", "u c #78CF64", "i c #7ACF66", "p c #75C568", "a c #7BCD6A", "s c #7CCF68", "d c #7DD06A", "f c #7ED16C", "g c #70C777", "h c #BB8436", "j c #B1803C", "k c #BE8C45", "l c #C08C42", "z c #C79246", "x c #CA974D", "c c #D49E53", "v c #D6A256", "b c #DBAF6E", "n c #DFB77D", "m c #80D16D", "M c #3C7BA0", "N c #3084A1", "B c #478787", "V c #78BCB3", "C c #90AB8D", "Z c #ACB3AC", "A c #E2BC86", "S c #C0B4A0", "D c #96C282", "F c #96CF8E", "G c #8ED680", "H c #92D884", "J c #94D986", "K c #9BDB90", "L c #A2C99D", "P c #A1DE95", "I c #A3DE97", "U c #A3DF98", "Y c #A4DF99", "T c #A5DE9B", "R c #A5DF9B", "E c #A7E09E", "W c #9EDCA7", "Q c #98D7B6", "! c #A9D3A0", "~ c #A9E0A1", "^ c #ABE1A2", "/ c #AAE0A3", "( c #ABE0A3", ") c #AFE3A7", "_ c #B0E3A8", "` c #B0E3AA", "' c #B1E3AB", "] c #B6E4AE", "[ c #B7E6B0", "{ c #B7E6B2", "} c #B9E6B4", "| c #B9E7B4", " . c #BAE7B6", ".. c #BCE7B7", "X. c #BCE7B8", "o. c #BFE9B9", "O. c #BEE8BA", "+. c #E4C18F", "@. c #C0E9BD", "#. c #C2E9BF", "$. c #C3EBC1", "%. c #C6EBC3", "&. c #C7ECC5", "*. c #C8ECC6", "=. c #CBEDC9", "-. c #FBF7EF", ";. c None", /* pixels */ ";.;.;.;.;.;.;.;.;.;.;.;.;.;.;.;.", ";.;.;.;.;.;.;.. 6 7 0 @ X X ;.;.", ";.;.;.;.;.;.< e #.] m 8 -.h X ;.", ";.B : - ; = D %.=.o...S A $ ;.;.", ";.w @.X...$.*._ O.Y W # +.o ;.;.", ";.8 ~ u u H I [ { U F % b X ;.;.", ";.9 ^ i s H R ._ P L l n X ;.;.", "M ! K d f J E &.} [ C v z X ;.;.", "N ` y t G ) | ( p g Z v * X ;.;.", "4 T / / ' a 3 r Q V c O ;.;.;.", "q , 2 1 > 5 ;.;.;.;.+ v X ;.;.;.", ";.;.;.;.;.;.;.;.;.X j v X ;.;.;.", ";.;.;.;.;.;.;.;.;.X x v X ;.;.;.", ";.;.;.;.;.;.;.;.;.X v k X ;.;.;.", ";.;.;.;.;.;.;.;.;.X v & ;.;.;.;.", ";.;.;.;.;.;.;.;.;.X X X ;.;.;.;." }; /* XPM */ static char *arrow_divide[] = { /* columns rows colors chars-per-pixel */ "16 16 127 2", " c #2C6C27", ". c #2F702A", "X c #2F712B", "o c #31732C", "O c #32742D", "+ c #32752D", "@ c #33762E", "# c #34772F", "$ c #35782F", "% c #357830", "& c #367930", "* c #367A31", "= c #387C32", "- c #3A7E34", "; c #3B7F35", ": c #3E8438", "> c #3F8538", ", c #408539", "< c #43863D", "1 c #438A3C", "2 c #448B3D", "3 c #478E3F", "4 c #478C41", "5 c #498B43", "6 c #489040", "7 c #499141", "8 c #499142", "9 c #4B9443", "0 c #4C9145", "q c #4C9344", "w c #4C9544", "e c #4E9746", "r c #4E9846", "t c #4F9847", "y c #53974C", "u c #509A48", "i c #539D4A", "p c #55A04C", "a c #56A24D", "s c #57A34E", "d c #58A44F", "f c #59A550", "g c #5AA651", "h c #5BA751", "j c #5BA852", "k c #5CA952", "l c #5EAA55", "z c #5EAB54", "x c #5EAC54", "c c #5FAC55", "v c #61A35B", "b c #62A45B", "n c #65A75E", "m c #60AE56", "M c #61AF57", "N c #62B057", "B c #62B158", "V c #65B45A", "C c #66B55B", "Z c #69B95E", "A c #6BAB63", "S c #6BAC65", "D c #6CAF64", "F c #6FAF68", "G c #6BB560", "H c #6BBC60", "J c #6EBA64", "K c #6CBD61", "L c #71B16B", "P c #71B268", "I c #73B36D", "U c #72B469", "Y c #74B66C", "T c #76B66D", "R c #76B76D", "E c #72BE67", "W c #78B670", "Q c #78B770", "! c #7BB974", "~ c #7ABE75", "^ c #7CBE77", "/ c #7DBF77", "( c #6FC164", ") c #70C265", "_ c #71C466", "` c #72C466", "' c #72C566", "] c #73C668", "[ c #7FC079", "{ c #80C176", "} c #82C27C", "| c #84C37D", " . c #85C37E", ".. c #84C579", "X. c #87C47F", "o. c #89CA7E", "O. c #8ACC7F", "+. c #87C580", "@. c #88C582", "#. c #89C682", "$. c #8BC784", "%. c #8CC683", "&. c #8ACC80", "*. c #8CC885", "=. c #8FCC85", "-. c #90C988", ";. c #90CA89", ":. c #92CA8A", ">. c #94CB8C", ",. c #95CC8D", "<. c #95CC8E", "1. c #97CE8F", "2. c #98CE90", "3. c #9ACF92", "4. c #9BCF93", "5. c #9ED196", "6. c #A1D398", "7. c #A2D499", "8. c #A4D49C", "9. c #A6D59D", "0. c #A8D79F", "q. c #A9D7A0", "w. c #AAD7A1", "e. c #ABD8A2", "r. c #ADDAA4", "t. c gray100", "y. c None", /* pixels */ "y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.", "y.y.y.' _ y.y.y.y.y.y.z d y.y.y.", "y.y.' &.o.H y.y.y.y.h Y U u y.y.", "] ' O.r.q...C N z g Y 4.1.A 3 2 ", "_ K =.e.q.{ m z g p P 1.,.F 1 , ", "y.K E 0.8.m y.y.y.y.r >.;.0 > y.", "y.Z J 8.7.l g y.y.e 0 ;.*.4 ; y.", "y.C G 6.5.R p y.y.8 n $.@.< * y.", "y.N m *.4.,.D e 8 b X.X.L * + y.", "y.y.g p W ;.;.! W @.| v * o y.y.", "y.y.y.i t q I @.X.S = $ o y.y.y.", "y.y.y.y.y.3 y | } 5 # y.y.y.y.y.", "y.y.y.y.y.y.> / ^ + y.y.y.y.y.y.", "y.y.y.y.y.y.; ^ ~ X y.y.y.y.y.y.", "y.y.y.y.y.y.$ + X y.y.y.y.y.y.", "y.y.y.y.y.y.y.y.y.y.y.y.y.y.y.y." }; /* XPM */ static char *arrow_inout[] = { /* columns rows colors chars-per-pixel */ "16 16 109 2", " c #418A3E", ". c #428B3F", "X c #428C3F", "o c #438D40", "O c #448D40", "+ c #458E41", "@ c #458F41", "# c #469042", "$ c #479143", "% c #499244", "& c #499445", "* c #4A9545", "= c #4B9646", "- c #4C9747", "; c #4E974A", ": c #4D9948", "> c #4E9948", ", c #4F9B4A", "< c #509C4A", "1 c #519E4B", "2 c #529F4C", "3 c #5A9C56", "4 c #5B9E57", "5 c #54A14E", "6 c #55A24E", "7 c #56A34F", "8 c #57A450", "9 c #57A550", "0 c #58A551", "q c #58A651", "w c #59A752", "e c #5AA852", "r c #5AA853", "t c #5BA953", "y c #5BAA54", "u c #5CAA54", "i c #5CAB54", "p c #5DAB55", "a c #5EAA57", "s c #5DAC55", "d c #5EAD56", "f c #5FAD56", "g c #5FAE57", "h c #5EA15A", "j c #60A15C", "k c #62A45F", "l c #60AF58", "z c #61B058", "x c #61B159", "c c #62B159", "v c #62B259", "b c #63B35A", "n c #64B35A", "m c #64B25B", "M c #64B45B", "N c #64B05C", "B c #66B65C", "V c #67B75D", "C c #68B95E", "Z c #69B95F", "A c #68A963", "S c #6DB167", "D c #6ABB60", "F c #6BBC60", "G c #6CBD61", "H c #6CBE62", "J c #6DBF62", "K c #6DBF63", "L c #6EB168", "P c #6FB369", "I c #77B96F", "U c #75B071", "Y c #77B373", "T c #79B374", "R c #77B871", "E c #78BB70", "W c #79BB71", "Q c #79B972", "! c #7ABA73", "~ c #7BB874", "^ c #7EB679", "/ c #6EC063", "( c #70C365", ") c #71C365", "_ c #72C466", "` c #72C566", "' c #72C467", "] c #73C667", "[ c #73C269", "{ c #74C768", "} c #85BF7D", "| c #87CA7E", " . c #86BD80", ".. c #89BF83", "X. c #8AC184", "o. c #8BC186", "O. c #8DC387", "+. c #8ACD80", "@. c #8BCE81", "#. c #8CCC83", "$. c #90CF86", "%. c #92C68C", "&. c #93C78C", "*. c #94C78D", "=. c #98CD8E", "-. c #9FD197", ";. c #A0D098", ":. c #A7D69E", ">. c None", /* pixels */ "{ { ] ] ( >.>.>.>.>.>.B M c l d ", "{ @.$.( >.K >.>.>.>.B >.n W R u ", "] @.:.#.[ K >.>.>.>.n c W *.W r ", "( ( | =.-.F >.>.>.>.c &.} W 0 0 ", "( >.K -.-.Z >.>.>.>.g &.O.u >.8 ", ">.K K F Z Z >.>.>.>.u t 0 0 6 >.", ">.>.>.>.>.>.>.>.>.>.>.>.>.>.>.>.", ">.>.>.>.>.>.>.>.>.>.>.>.>.>.>.>.", ">.>.>.>.>.>.>.>.>.>.>.>.>.>.>.>.", ">.>.>.>.>.>.>.>.>.>.>.>.>.>.>.>.", ">.c c g d r >.>.>.>.1 < : ; * >.", "B >.c X.o.r >.>.>.>., ^ T * >.$ ", "l g R ~ .8 >.>.>.>., T A h % @ ", "d R ..L 8 6 >.>.>.>.* ; k U 4 X ", "d L L 9 >.5 >.>.>.>.* >.@ h 3 X ", "0 9 8 6 1 >.>.>.>.>.>.@ @ @ X " }; /* XPM */ static char *application[] = { /* columns rows colors chars-per-pixel */ "16 16 90 1", " c #5171A9", ". c #5172A9", "X c #5373A9", "o c #5373AA", "O c #5475AB", "+ c #5475AC", "@ c #5676AD", "# c #5779AE", "$ c #587AB0", "% c #587BB1", "& c #5A7CB2", "* c #5C7EB4", "= c #5C7EB5", "- c #5E81B7", "; c #5F83B9", ": c #6085BA", "> c #6185BB", ", c #6387BD", "< c #6488BE", "1 c #668BC0", "2 c #688EC3", "3 c #6F90C1", "4 c #6C92C8", "5 c #6C94C9", "6 c #6E94CA", "7 c #6F96CB", "8 c #6F97CC", "9 c #7A9AC4", "0 c #7099CE", "q c #729ACF", "w c #739CD1", "e c #739DD2", "r c #759ED4", "t c #76A0D5", "y c #79A2D8", "u c #79A3D9", "i c #7AA4DA", "p c #7AA4DB", "a c #7AA6DC", "s c #7BA7DC", "d c #85ACDD", "f c #8DB1DD", "g c #92B9E8", "h c #DEE7F2", "j c #E4EAF3", "k c #E7EBF5", "l c #E8ECF6", "z c #EAEFF6", "x c #EAF0F7", "c c #EBF2F7", "v c #EDF3F7", "b c #ECF2F8", "n c #EFF3FA", "m c #EEF4F8", "M c #F0F5F9", "N c #F2F5FB", "B c #F1F6FB", "V c #F2F7FA", "C c #F2F7FB", "Z c #F3F7FB", "A c #F4F7FB", "S c #F4F8FB", "D c #F5F8FB", "F c #F5F9FB", "G c #F7F9FB", "H c #F6FAFB", "J c #F7FAFB", "K c #F6FBFB", "L c #F7FBFC", "P c #F7FCFC", "I c #F9FBFB", "U c #F8FBFC", "Y c #F9FBFC", "T c #F8FCFC", "R c #F9FCFC", "E c #F8FDFD", "W c #F9FDFD", "Q c #FAFCFC", "! c #FAFDFD", "~ c #FBFDFD", "^ c #FAFEFE", "/ c #FBFEFE", "( c #FCFDFD", ") c #FCFEFE", "_ c #FDFEFE", "` c #FCFFFF", "' c #FDFFFF", "] c #FEFFFF", "[ c #FFFFFF", "{ c None", /* pixels */ "{{{{{{{{{{{{{{{{", "{faaputreqq759{{", "dggggggggggggg3{", "sssssssaassssa1{", "p[[[[[[[[[[[[[,{", "u[UUGASmvzjjh[:{", "u[!IUGGSBmbxl[-{", "t[[I!!GSGBAbb[={", "r[!![!!PGGSCC[&{", "e[[[!!!!PIHPC[${", "8[!![!!!!!!PG[+{", "5[[[[[[!![!!![o{", "4[[[[[[[[[[[[[ {", "o21,,;*&$#+Oooo{", "{{{{{{{{{{{{{{{{", "{{{{{{{{{{{{{{{{" }; /* XPM */ static char *package[] = { /* columns rows colors chars-per-pixel */ "16 16 176 2", " c #C38322", ". c #C38423", "X c #C48524", "o c #C48625", "O c #C58726", "+ c #C58928", "@ c #C68A28", "# c #C78D2B", "$ c #C88E2C", "% c #C88F2D", "& c #C9902E", "* c #C9922F", "= c #CB9532", "- c #CC9834", "; c #C8943B", ": c #CE9D39", "> c #DE9F32", ", c #D1A43F", "< c #E2AA37", "1 c #E2A938", "2 c #E3AB3A", "3 c #E6B53A", "4 c #E6B43D", "5 c #E6B53F", "6 c #ECB638", "7 c #E9B53D", "8 c #F0BD3B", "9 c #C88E40", "0 c #CA904A", "q c #D09753", "w c #D2A540", "e c #D3A842", "r c #D4AA44", "t c #D5AC45", "y c #D5AD47", "u c #D6B049", "i c #D7B04A", "p c #D7B24B", "a c #D8B24B", "s c #D8B44C", "d c #D8B44D", "f c #D9B54D", "g c #D9B54E", "h c #D9B74F", "j c #D5A651", "k c #DAAD50", "l c #D7A45F", "z c #DBB156", "x c #E1A740", "c c #E6B542", "v c #E4B145", "b c #E6B147", "n c #E7BA41", "m c #E9BD40", "M c #E8BE43", "N c #E9BD45", "B c #E4B14C", "V c #E9B44C", "C c #E8BF48", "Z c #E8BB4F", "A c #F5BD40", "S c #E5AF56", "D c #DBB262", "F c #DDB969", "G c #D6B870", "H c #DCBD77", "J c #E6B66B", "K c #E2B76F", "L c #E5BF6F", "P c #E4B374", "I c #EAC443", "U c #EAC146", "Y c #ECC547", "T c #EBC648", "R c #EFC748", "E c #F9C248", "W c #F9C448", "Q c #F1C156", "! c #F5C969", "~ c #E1C072", "^ c #E0C07D", "/ c #E0C67E", "( c #F5CF7F", ") c #FFD577", "_ c #F5D078", "` c #F5D07F", "' c #FED678", "] c #FED97C", "[ c #DBC389", "{ c #DEC995", "} c #E5C482", "| c #EBC182", " . c #ECC583", ".. c #EEC483", "X. c #EDC687", "o. c #ECCA84", "O. c #EBCC84", "+. c #E7CC88", "@. c #EECA88", "#. c #EFCA8A", "$. c #EBCD8F", "%. c #F1CF86", "&. c #F0CE8A", "*. c #FBDC84", "=. c #F1D28B", "-. c #F7D589", ";. c #F7D78B", ":. c #F0D08C", ">. c #FBDA8D", ",. c #FFDC8C", "<. c #E5CF92", "1. c #EDD292", "2. c #EAD59C", "3. c #F1D590", "4. c #F5D790", "5. c #F2D695", "6. c #FBDB92", "7. c #FEDF95", "8. c #F8DB9D", "9. c #FEE094", "0. c #FEE194", "q. c #FEE196", "w. c #FFE19B", "e. c #FFE39F", "r. c #EDD9A5", "t. c #F2DDAF", "y. c #EDDEBE", "u. c #FFE4A4", "i. c #FFE4A5", "p. c #FFE5A5", "a. c #F9E1AA", "s. c #FAE3AA", "d. c #FFE7AD", "f. c #FFE8A8", "g. c #FFE8AB", "h. c #F7E4B2", "j. c #FAE4B0", "k. c #FFEAB3", "l. c #FFE9B6", "z. c #FFEBB7", "x. c #F6E5BF", "c. c #FFEAB9", "v. c #FFEBBA", "b. c #FFEBBD", "n. c #FFEDBE", "m. c #FFEEC1", "M. c #FFEFC1", "N. c #FFEFC4", "B. c #FCEEC7", "V. c #FBEDCB", "C. c #FFEFC8", "Z. c #F9EBCD", "A. c #FAECCE", "S. c #FFF0C9", "D. c #FFF2CC", "F. c #FFF2CE", "G. c #FFF4CC", "H. c #F5EBD2", "J. c #F7EED1", "K. c #FFF3D4", "L. c #FFF3D5", "P. c #FFF4D7", "I. c #FFF5D9", "U. c #FFF4DA", "Y. c #FFF6DB", "T. c #FFF6DD", "R. c #FCF6E2", "E. c #FDF6E2", "W. c #FEF6E3", "Q. c #FEF8E1", "!. c #FDF8E2", "~. c #FCF8E6", "^. c #FEFBE7", "/. c #FFFEF0", "(. c #FFFFF6", "). c None", /* pixels */ ").).).).).).).a p ).).).).).).).", ").).).).).g p 2.+.r r ).).).).).", ").).).).g <.~.R.t.j.~ w ).).).).", ").).g / J.(./.V.k ;.a.5.D : ).).", "g g r.H.y.{ [ G F 4.( 8.a.o.j = ", "g Q.A.1.O.L z ; A.I.c.7.' p.*.* ", "p R.K.s.&.` _ B j.l.w.' A 7 3.% ", "p R.I.K.b.-.! V >.,.W 6 C Z :.# ", "y R.P.D.N.c.6.Q E 8 R N c b #.+ ", "r R.K.D.m.k.d.] R I M 4 1 x .O ", "e ~.T.M.l.g.u.q.T m 4 1 > J .o ", ", H x.T.m.p.e.q.U 3 < S .P 0 ", ").).: ^ B.D.p.q.n v #.| q . ).).", ").).).- = } G.N.:.&.l o o ).).).", ").).).).).* % $.K 9 o ).).).).).", ").).).).).).).+ O ).).).).).).)." }; /* XPM */ static char *plugin[] = { /* columns rows colors chars-per-pixel */ "16 16 123 2", " c #3A8A36", ". c #3D8C39", "X c #3D8D39", "o c #3F8E3A", "O c #408F3B", "+ c #41903C", "@ c #42913D", "# c #42923E", "$ c #43923E", "% c #459440", "& c #469641", "* c #479642", "= c #4A9945", "- c #4D9C48", "; c #4E9D48", ": c #4F9E49", "> c #51A04B", ", c #52A14C", "< c #55A44F", "1 c #59B54F", "2 c #59A752", "3 c #5AA953", "4 c #5DAB56", "5 c #5EAD57", "6 c #5BB651", "7 c #5DB752", "8 c #5FB853", "9 c #61AF5A", "0 c #62AC5C", "q c #63AD5D", "w c #60B955", "e c #61B956", "r c #61BA56", "t c #63B15B", "y c #65B45E", "u c #67B55F", "i c #63BA58", "p c #64BB58", "a c #64BB59", "s c #66BB5A", "d c #66BB5D", "f c #68BC5B", "g c #69BC5D", "h c #69BD5D", "j c #6ABD5E", "k c #6CBE5F", "l c #6CB565", "z c #6DB566", "x c #6AB862", "c c #6BB963", "v c #6BBD62", "b c #6DBF60", "n c #6EBC65", "m c #6FBF65", "M c #6FBD66", "N c #6FC062", "B c #71C164", "V c #72C165", "C c #73C265", "Z c #71C066", "A c #73C267", "S c #72C069", "D c #72C169", "F c #77C369", "G c #76C46D", "H c #77C46D", "J c #78C66F", "K c #7AC072", "L c #7AC770", "P c #7CC376", "I c #7BC971", "U c #7CC972", "Y c #7DCA73", "T c #7DCB73", "R c #7ECB74", "E c #80CD75", "W c #80CE76", "Q c #81CE76", "! c #81C67A", "~ c #81C67B", "^ c #83C77C", "/ c #87CB79", "( c #82CD78", ") c #82CF78", "_ c #85C97C", "` c #84C87E", "' c #85C87E", "] c #83D079", "[ c #87CA80", "{ c #88CA80", "} c #88CA81", "| c #89CA82", " . c #89CA83", ".. c #8ACB83", "X. c #8BCC83", "o. c #8CCC84", "O. c #8DCD85", "+. c #8ECD86", "@. c #90CF88", "#. c #91CF88", "$. c #92CF8A", "%. c #93CF8B", "&. c #94CF8A", "*. c #94CF8B", "=. c #95CF8B", "-. c #95D08C", ";. c #96D18D", ":. c #97D28D", ">. c #98D18F", ",. c #99D290", "<. c #9CD493", "1. c #9DD593", "2. c #9ED595", "3. c #A1D796", "4. c #A1D797", "5. c #A2D897", "6. c #A2D798", "7. c #A2D898", "8. c #A3D899", "9. c #A4D899", "0. c #A6D99B", "q. c #A7D99C", "w. c None", /* pixels */ "w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.", "w.w.w.w.w.( W T L w.w.w.w.w.w.w.", "w.w.w.w.w.( q.5.H w.w.w.w.w.w.w.", "w.w.w.w.w.T 5.>.S w.w.w.w.w.w.w.", "w.] W W T H 4.1.n x u t w.w.w.w.", "w.W 9.9.4.4.1.<.>.-.*.5 w.w.w.w.", "w.T 8.4./ F C B V V *.3 w.w.w.w.", "w.L H _ <.V m k j s @.z , ; = w.", "w.w.w.M ,.k j s a r n X. .[ & w.", "w.w.w.x ;.j s s 8 7 v [ _ [ # w.", "w.n x K @.s r 7 6 6 _ 0 % # o w.", "w.x *.-.S O.O.X. .d [ % w.w.w.w.", "w.y @.r O.z > ; q ~ ~ o w.w.w.w.", "w.t O.o. ., w.w.& ~ P o w.w.w.w.", "w.4 2 < , - w.w.$ O o w.w.w.w.", "w.w.w.w.w.w.w.w.w.w.w.w.w.w.w.w." }; /* XPM */ static char *cd_img[] = { /* columns rows colors chars-per-pixel */ "16 16 131 2", " c #5887B8", ". c #A5BFD9", "X c #94BCE7", "o c #96BEE7", "O c #96BCE8", "+ c #97BEE9", "@ c #97BDEC", "# c #99BFE9", "$ c #99BFEB", "% c #AAC3DC", "& c #AAC3DD", "* c #ACC4DD", "= c #97C0E9", "- c #99C0E9", "; c #9AC1E9", ": c #9BC1E9", "> c #9BC1EB", ", c #A1C4EA", "< c #A3C7EC", "1 c #A0C6EE", "2 c #A4C9ED", "3 c #A4C9EF", "4 c #B9CDE1", "5 c #BACEE2", "6 c #BBCEE2", "7 c #A3C1F0", "8 c #A4CAF2", "9 c #A5CBF3", "0 c #AECAF2", "q c #A9CCF0", "w c #ABCCF0", "e c #ABCDF1", "r c #A8CDF2", "t c #A8CCF3", "y c #A9CDF3", "u c #ABCFF5", "i c #A8CDF6", "p c #A9CEF6", "a c #B2CEF1", "s c #B6CDF7", "d c #ADD2F2", "f c #AED1F4", "g c #ACD0F6", "h c #ACD1F7", "j c #B2D2F2", "k c #B6D2F1", "l c #B2D2F4", "z c #B3D4F6", "x c #B8D6F5", "c c #BBD8F6", "v c #B2D3F9", "b c #B3D5F9", "n c #B2D6FB", "m c #BBDBFC", "M c #BADBFE", "N c #BBDCFC", "B c #C7DAF3", "V c #C6DEF7", "C c #C9DDF3", "Z c #CADEF3", "A c #CCDDF0", "S c #CFDFF1", "D c #C3DDF8", "F c #C4DDF8", "G c #C7DFFB", "H c #D0E0EF", "J c #CEE0F1", "K c #C2E1FF", "L c #C3E1FF", "P c #CAE1FA", "I c #CDE7FF", "U c #CFE7FF", "Y c #C8EDF9", "T c #D1E1F0", "R c #D1E1F1", "E c #D4E2F1", "W c #D3E3F6", "Q c #D2E4F6", "! c #D3E4F6", "~ c #D5E4F5", "^ c #D4E6F8", "/ c #D6E7F9", "( c #D1E5FC", ") c #D3E4FF", "_ c #D7E9FA", "` c #D1E9FF", "' c #D1EBFF", "] c #D9E8F8", "[ c #D9EAF8", "{ c #D9EAFA", "} c #DFECF9", "| c #DBE8FF", " . c #DAECFE", ".. c #DAECFF", "X. c #D8EFFF", "o. c #DAEEFF", "O. c #D1F0FD", "+. c #DDF0FF", "@. c #DDF2FF", "#. c #DCF4FF", "$. c #E4EDF4", "%. c #E1EDFA", "&. c #E4F1F8", "*. c #E5F3FB", "=. c #E4F1FF", "-. c #E4F2FE", ";. c #E2F6FF", ":. c #E5F4FF", ">. c #E8F7FF", ",. c #E9F7FF", "<. c #E9F9FF", "1. c #EBF8FF", "2. c #EDF8FF", "3. c #EFFCFF", "4. c #F0FAFF", "5. c #F0FDFF", "6. c #F1FDFF", "7. c #F2FCFF", "8. c #F3FCFF", "9. c #F3FDFF", "0. c #F1FEFF", "q. c #F3FFFF", "w. c #F7FFFF", "e. c #F9FEFE", "r. c #F9FFFF", "t. c #FAFEFE", "y. c #FCFDFE", "u. c #FDFFFF", "i. c #FEFFFF", "p. c #FFFFFF", "a. c None", /* pixels */ "a.a.a.a.a. a.a.a.a.a.", "a.a.a. 5 E } *.$.5 a.a.a.", "a.a. . p.%.0 f Y w.p.t.. a.a.", "a. . 4.p.8.7 1 O.p.3.8.p.% a.", "a. %.2 .p.s @ #.w.>.8.w.t. a.", " 5 k > # ) .B &.3.>.8.3.4.5 ", " T , - + a & & 8.:.o.( T ", " ~ # - - Z a.a. ] j w w ! ", " ~ # + X Z a.a. W w 8 2 ! ", " H X X w o.* & D l z x S ", " 5 V ' ;.+.+.] ^ G u 8 t D 5 ", "a. t.1.O.I K N b g u 8 u ] a.", "a. . 3.' K M b g u 8 r P . a.", "a.a. . -.U m v g g c _ . a.a.", "a.a.a. 5 J ^ ^ S 5 a.a.a.", "a.a.a.a.a. a.a.a.a.a." }; /* XPM */ static char *arrow_redo[] = { /* columns rows colors chars-per-pixel */ "16 16 110 2", " c #215F1E", ". c #236220", "X c #246220", "o c #266522", "O c #276623", "+ c #296925", "@ c #2A6B26", "# c #2C6C27", "$ c #2D6E29", "% c #2F702A", "& c #31732C", "* c #32752D", "= c #34772F", "- c #367930", "; c #387B32", ": c #397E33", "> c #3B8035", ", c #3E8337", "< c #3E8438", "1 c #3F8538", "2 c #41883B", "3 c #438A3C", "4 c #458D3E", "5 c #478F40", "6 c #4A9242", "7 c #4B9443", "8 c #4C9444", "9 c #4E9746", "0 c #509947", "q c #519C49", "w c #549F4B", "e c #55A04C", "r c #57A34E", "t c #58A34F", "y c #58A44F", "u c #5AA651", "i c #5BA751", "p c #5EAC54", "a c #60A259", "s c #60A35A", "d c #61A35A", "f c #62A35B", "g c #64A65D", "h c #67A85F", "j c #62B057", "k c #62B158", "l c #65B45A", "z c #66B55B", "x c #68B85D", "c c #6ABA5F", "v c #6ABB5F", "b c #6FAF66", "n c #70B268", "m c #71B369", "M c #70B16A", "N c #76B56E", "B c #73B96D", "V c #76B86D", "C c #74BB70", "Z c #75BB70", "A c #77BC71", "S c #7AB972", "D c #78BD72", "F c #79BD74", "G c #7ABD74", "H c #7CBC75", "J c #7FBC76", "K c #7CBE76", "L c #7EBF77", "P c #7DBF78", "I c #7FC178", "U c #80C179", "Y c #84C57A", "T c #85C57B", "R c #82C27C", "E c #85C17E", "W c #87C27F", "Q c #86C47F", "! c #8BC785", "~ c #8CC685", "^ c #90CA87", "/ c #90CA89", "( c #91CA8A", ") c #93CB8B", "_ c #92CC88", "` c #93CC8A", "' c #94CC8D", "] c #95CC8D", "[ c #96CE8D", "{ c #98CE90", "} c #99CE90", "| c #99CF91", " . c #9ACE91", ".. c #9ACF92", "X. c #9BCF93", "o. c #9DD193", "O. c #9DD094", "+. c #9CD194", "@. c #9ED195", "#. c #9ED196", "$. c #9FD297", "%. c #A0D396", "&. c #A1D398", "*. c #A1D399", "=. c #A2D499", "-. c #A3D49B", ";. c #A5D59C", ":. c #A7D69E", ">. c #A9D7A0", ",. c None", /* pixels */ ",.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.", ",.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.", ",.,.,.,.,.,.,.,.,.,.,.i w ,.,.,.", ",.,.,.,.,.x z j p i e m b 8 ,.,.", ",.,.,.c Y [ *.:.&.&.X.} [ b 1 ,.", ",.,.c ` >.%.-.*.#.X.} [ / f 1 ,.", ",.,.Y :.:.} V e q 8 6 g s 1 ,.,.", ",.z ` o.} y e ,.,.,.,.2 , ,.,.,.", ",.k #.#.J w ,.,.,.,.,.,.,.,.,.,.", ",.p [ } S q ,.,.,.,.,.,.,.,.,.,.", ",.i W ^ ~ 8 5 ,.,.,.,.,.,.,.,.,.", ",.,.M ) / W u 2 , - - & $ @ ,.,.", ",.,.8 N ! I Q R U P G A Z O ,.,.", ",.,.,.5 s M K K K G A C B X ,.,.", ",.,.,.,.,.: - * % $ + O . ,.,.", ",.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,." }; /* XPM */ static char *arrow_rotate_clockwise[] = { /* columns rows colors chars-per-pixel */ "16 16 97 2", " c #31732C", ". c #33762E", "X c #367930", "o c #377B31", "O c #3A7E34", "+ c #3B7F35", "@ c #3E8337", "# c #3E8438", "$ c #43893C", "% c #458C3E", "& c #468D3F", "* c #489040", "= c #499141", "- c #499142", "; c #4E9746", ": c #4E9846", "> c #509947", ", c #52954D", "< c #54964E", "1 c #509A48", "2 c #529C4A", "3 c #539D4A", "4 c #539E4B", "5 c #549F4B", "6 c #5B9D55", "7 c #5A9E55", "8 c #55A04C", "9 c #56A14D", "0 c #58A34F", "q c #59A650", "w c #5EA157", "e c #5CA953", "r c #5DAA53", "t c #60AE56", "y c #61A35A", "u c #66A95F", "i c #63B158", "p c #63B259", "a c #66B55B", "s c #66B65C", "d c #69B95E", "f c #6ABA5F", "g c #68AA60", "h c #69AB61", "j c #6AAB63", "k c #6AAD63", "l c #6CAE63", "z c #6FAF67", "x c #6CBC60", "c c #6DBF62", "v c #6EBF62", "b c #74B56D", "n c #77B771", "m c #79B871", "M c #78BA70", "N c #7EBC75", "B c #7CBF75", "V c #7EC177", "C c #81C077", "Z c #82C27B", "A c #85C77B", "S c #82C27C", "D c #84C17C", "F c #84C07D", "G c #85C37E", "H c #85C47E", "J c #87C47F", "K c #87C87C", "L c #87C581", "P c #88C582", "I c #89C682", "U c #8BC683", "Y c #8AC783", "T c #8BC785", "R c #8CCA82", "E c #8CC885", "W c #8FC987", "Q c #8FC988", "! c #90C989", "~ c #97CC8E", "^ c #98CE90", "/ c #99CE90", "( c #9BCF93", ") c #9BD092", "_ c #9DD194", "` c #9ED196", "' c #A0D197", "] c #A1D396", "[ c #A2D499", "{ c #A4D49B", "} c #A6D59C", "| c #A6D59D", " . c #A7D69E", ".. c #A9D7A0", "X. c #AAD8A0", "o. c #ABD8A1", "O. c None", /* pixels */ "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.x d a i O.O.O.O.O.O.", "O.O.O.O.v K ] X. ./ M 0 O.O.O.O.", "O.O.O.c R o.[ } { ) ` m > O.O.O.", "O.O.O.A .. .' C N ~ ( ^ h O.O.O.", "O.O.f _ | ( r q 9 2 ! E F $ O.O.", "O.O.s p t e O.O.O.; z Q E # O.O.", "O.O.O.O.O.O.8 O.O.- j Y P O O.O.", "O.O.O.O.O.5 1 O.= % D V n X O.O.", "O.O.O.O.4 l g * y L H S < O.O.O.", "O.O.O.3 k W T I J B Z 6 O.O.O.", "O.O.O.: u U L G S b , O.O.O.O.", "O.O.O.O.& w 7 + 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.X O.O.O.O.O.O.O.O.O." }; /* XPM */ static char *arrow_switch[] = { /* columns rows colors chars-per-pixel */ "16 16 124 2", " c #174414", ". c #174515", "X c #184515", "o c #184616", "O c #1A4917", "+ c #1C4B19", "@ c #23561F", "# c #255821", "$ c #295E24", "% c #2C6227", "& c #2D6328", "* c #2F672A", "= c #30682A", "- c #33762E", "; c #34772E", ": c #35782F", "> c #3A6D36", ", c #367230", "< c #377B31", "1 c #3C7936", "2 c #3D7A36", "3 c #3A7E34", "4 c #4B7D47", "5 c #4B7E48", "6 c #3B8035", "7 c #408539", "8 c #41863A", "9 c #43863B", "0 c #438A3C", "q c #448B3D", "w c #4C8E43", "e c #4F824B", "r c #538B4E", "t c #548E4D", "y c #499141", "u c #4D9645", "i c #529949", "p c #509A48", "a c #539B4A", "s c #519C49", "d c #529D4A", "f c #549F4B", "g c #568A52", "h c #5A8E54", "j c #589951", "k c #599A53", "l c #599D50", "z c #5B9E53", "x c #5B9D55", "c c #5D9C55", "v c #5E9F57", "b c #62985D", "n c #55A04C", "m c #57A24E", "M c #57A34E", "N c #58A44F", "B c #59A550", "V c #5FA755", "C c #5DA952", "Z c #5CA953", "A c #5DAA54", "S c #5FAB54", "D c #60AD55", "F c #62AF56", "G c #60A658", "H c #67A85F", "J c #63B057", "K c #64B258", "L c #65B459", "P c #66B55A", "I c #679C63", "U c #69AA63", "Y c #6AAD61", "T c #6BAD63", "R c #6EAF65", "E c #73B16C", "W c #77B471", "Q c #7BB373", "! c #7BB873", "~ c #81B679", "^ c #83B67C", "/ c #84B77D", "( c #84BC7B", ") c #8BBE85", "_ c #87C480", "` c #8AC683", "' c #8BC784", "] c #8DC886", "[ c #8FC987", "{ c #91C989", "} c #90CA89", "| c #92CB8B", " . c #92CA8E", ".. c #94CB8C", "X. c #95CC8E", "o. c #96CD8E", "O. c #94CB90", "+. c #96CC91", "@. c #97CC92", "#. c #99CB91", "$. c #99CF90", "%. c #98CC93", "&. c #99CE94", "*. c #9BCE96", "=. c #9DCF98", "-. c #9ECF98", ";. c #A3CF9A", ":. c #A2D29C", ">. c #A7D3A0", ",. c #A6D4A0", "<. c #A8D4A2", "1. c #AFD7A7", "2. c #B1DAAA", "3. c #B4DCAD", "4. c #BADFB3", "5. c #BCE0B4", "6. c #BEE1B6", "7. c #BEE1B7", "8. c #BFE2B7", "9. c #C0E2B8", "0. c #C0E3B9", "q. c #C1E3B9", "w. c #C2E3BA", "e. c None", /* pixels */ "e.e.e.e.e.e.e.e.e.e.e.e.e.e.e.e.", "e.e.e.e.e.e.e.e.e.e.e.m e.e.e.e.", "e.e.e.e.e.e.e.e.e.e.e.s u e.e.e.", "P P P K F S e.A B n G ! H 0 e.e.", "P w.q.9.7.#.R Y { $.X.| [ v 3 e.", "L 0.8.6.5.4.;.l o...} ] ` k : e.", "J D C V ( 1.3.c E z 8 x j ; e.e.", "e.e.e.e.i Q 2.~ 9 e.e., - e.e.e.", "e.e.e.e.p w >.<.2 e.e.= % e.e.e.", "Z N f a T c ^ ,./ r * h g @ e.e.", "M X.| [ ' W t :.-.=.*.%.+.e + e.", "d } ] ` _ U 1 b ) &.@.O. .5 o e.", "u y q 7 6 < e.& $ # > I 4 X e.e.", "e.e.e.e.e.e.e.e.e.e.e.O . e.e.e.", "e.e.e.e.e.e.e.e.e.e.e. e.e.e.e.", "e.e.e.e.e.e.e.e.e.e.e.e.e.e.e.e." }; /* XPM */ static char *box[] = { /* columns rows colors chars-per-pixel */ "16 16 163 2", " c #774C15", ". c #7A4C12", "X c #7E4E12", "o c #784D15", "O c #794D16", "+ c #794E16", "@ c #7A4E16", "# c #7B4F16", "$ c #7C5017", "% c #7D5017", "& c #7E5117", "* c #7F5218", "= c #825114", "- c #875414", "; c #8B5615", ": c #8E5915", "> c #805318", ", c #815318", "< c #825419", "1 c #835419", "2 c #845519", "3 c #85551A", "4 c #86561A", "5 c #87571A", "6 c #88581B", "7 c #89591B", "8 c #8A591D", "9 c #8B5A1C", "0 c #8C5B1C", "q c #8D5B1C", "w c #8E5C1D", "e c #8F5C1D", "r c #8F5D1D", "t c #8F5D1E", "y c #925B16", "u c #965C17", "i c #995E17", "p c #905D1D", "a c #915E1E", "s c #915F1E", "d c #925F1E", "f c #9B6117", "g c #94601F", "h c #95601F", "j c #95611F", "k c #96611F", "l c #96621F", "z c #99621F", "x c #976220", "c c #9C6420", "v c #9F6520", "b c #8C6839", "n c #946B38", "m c #986D38", "M c #98703F", "N c #A16820", "B c #A46E29", "V c #A66F2B", "C c #A87A3F", "Z c #C86530", "A c #C86731", "S c #C96832", "D c #C96932", "F c #CA6B33", "G c #CA6D34", "H c #CB6E34", "J c #CB6E35", "K c #CC7036", "L c #CC7137", "P c #CD7237", "I c #CD7338", "U c #CE7438", "Y c #CE763A", "T c #CF773B", "R c #D07A3C", "E c #D07B3C", "W c #D17C3D", "Q c #D17D3E", "! c #D37F3F", "~ c #AA7C41", "^ c #A6845B", "/ c #AB885A", "( c #B08C5F", ") c #B38E5F", "_ c #B58F60", "` c #B08E67", "' c #B79060", "] c #B99160", "[ c #BB9260", "{ c #BC9360", "} c #BC9361", "| c #BC9461", " . c #BE9664", ".. c #D48040", "X. c #D48240", "o. c #D58341", "O. c #D58542", "+. c #D68743", "@. c #D78944", "#. c #D88A44", "$. c #D88C47", "%. c #D98D47", "&. c #DA8F48", "*. c #DA9149", "=. c #DB924A", "-. c #DC944B", ";. c #DC964C", ":. c #DD984D", ">. c #DE994D", ",. c #DE9B4F", "<. c #DC9451", "1. c #DF9D55", "2. c #E09C4F", "3. c #E19E50", "4. c #E2A051", "5. c #E2A252", "6. c #E3A354", "7. c #E3A554", "8. c #E4A655", "9. c #E5A957", "0. c #E3A459", "q. c #E6AA58", "w. c #E7AE59", "e. c #E6AC5E", "r. c #E9B25B", "t. c #DA9874", "y. c #DA9875", "u. c #DA9975", "i. c #DB9B76", "p. c #DC9E77", "a. c #DD9F78", "s. c #E19E62", "d. c #DDA079", "f. c #DEA27A", "g. c #DEA37B", "h. c #DFA67C", "j. c #D9B177", "k. c #E3A366", "l. c #E5A769", "z. c #E6AB6E", "x. c #E9B362", "c. c #EBB865", "v. c #E0A87E", "b. c #E2AB7F", "n. c #E0AD7E", "m. c #E8B071", "M. c #EAB475", "N. c #EBB87A", "B. c #EEBC7D", "V. c #E3AD80", "C. c #E4AF81", "Z. c #E3B280", "A. c #E5B783", "S. c #E6BD85", "D. c #EFBF80", "F. c #E8C188", "G. c #EAC68B", "H. c #EDC88D", "J. c #EECC8F", "K. c #F1C383", "L. c #F2C587", "P. c #F4CC8F", "I. c None", /* pixels */ "I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.", "I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.", "I.I.x l k j g d a p e q 0 I.I.I.", "I.x C { | } [ ] ' _ ) ( / m 5 I.", "x ~ .V N v c z h s t 8 M ^ n 2 ", "l j.B f i u y : ; - = X . b ` < ", "j J.P.L.K.D.B.N.M.m.z.l.k.s.V., ", "g H.c.r.w.9.7.4.,.;.*.$.+.X.v.* ", "d G.x.q.8.5.2.:.=.%.@.o.! E g.& ", "a F.e.6.3.>.-.&.#.O...W T I a.$ ", "r S.0.,.;.*.$.+.X.Q R U L H i.# ", "w A.1.=.%.@.o.! E Y P J F S y.@ ", "0 Z.<.#.O...W T I K G D A Z t.O ", "9 n.C.b.v.h.f.d.p.i.u.t.t.t.t.o ", "7 6 4 3 1 < > * & % # @ + O o ", "I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I." }; /* XPM */ static char *brick[] = { /* columns rows colors chars-per-pixel */ "16 16 72 1", " c gray58", ". c #959595", "X c gray59", "o c #979797", "O c #989898", "+ c gray60", "@ c #9A9A9A", "# c #9B9B9B", "$ c #9D9D9D", "% c gray62", "& c gray63", "* c #A2A2A2", "= c gray64", "- c #A5A5A5", "; c gray65", ": c #A9A9A9", "> c #AAAAAA", ", c gray67", "< c #ACACAC", "1 c #AEAEAE", "2 c #B1B1B1", "3 c gray70", "4 c gray71", "5 c #BBBBBB", "6 c gray74", "7 c gray", "8 c #C0C0C0", "9 c #C1C1C1", "0 c gray76", "q c #C3C3C3", "w c gray77", "e c #C5C5C5", "r c gray78", "t c gray79", "y c #CBCBCB", "u c gray80", "i c #CDCDCD", "p c #CECECE", "a c gray81", "s c gray82", "d c #D2D2D2", "f c LightGray", "g c #D5D5D5", "h c gray84", "j c #D7D7D7", "k c #D8D8D8", "l c #DADADA", "z c gray86", "x c #DDDDDD", "c c gray87", "v c #DFDFDF", "b c gray88", "n c #E1E1E1", "m c gray89", "M c #E4E4E4", "N c #E7E7E7", "B c gray91", "V c #E9E9E9", "C c #EAEAEA", "Z c gray92", "A c #ECECEC", "S c #EEEEEE", "D c gray94", "F c #F1F1F1", "G c gray95", "H c #F3F3F3", "J c gray96", "K c #FBFBFB", "L c gray99", "P c #FDFDFD", "I c gray100", "U c None", /* pixels */ "UUUUU03**30UUUUU", "UUUUU:IIII:UUUUU", "U03**2hPLf2**30U", "U:IIIbHFSnryssu2588p+", ":HDACMlkw570q8yO", ";JGNMvzh800067t.", "-7mFNxlh7995y8; ", "UU&9BZch55yr, UU", "UUU%$eZBui3. UUU", "UUUUU#@i6&.UUUUU", "UUUUUUUoXUUUUUUU", "UUUUUUUUUUUUUUUU" }; /* XPM */ static char *database[] = { /* columns rows colors chars-per-pixel */ "16 16 82 1", " c #898989", ". c gray54", "X c #8B8B8B", "o c #8D8D8D", "O c #909090", "+ c #959595", "@ c gray59", "# c #9B9B9B", "$ c gray62", "% c #9F9F9F", "& c #A0A0A0", "* c gray63", "= c gray64", "- c #A5A5A5", "; c #A7A7A7", ": c #A9A9A9", "> c gray67", ", c #ACACAC", "< c gray68", "1 c #AEAEAE", "2 c gray69", "3 c #B2B2B2", "4 c gray70", "5 c #B4B4B4", "6 c gray71", "7 c #B6B6B6", "8 c #B7B7B7", "9 c gray72", "0 c #B9B9B9", "q c gray73", "w c #BBBBBB", "e c #BCBCBC", "r c gray74", "t c gray75", "y c #C0C0C0", "u c gray76", "i c #C3C3C3", "p c gray77", "a c gray79", "s c #CDCDCD", "d c #CECECE", "f c gray81", "g c #D0D0D0", "h c gray82", "j c #D2D2D2", "k c gray83", "l c #D5D5D5", "z c gray84", "x c #D8D8D8", "c c gray85", "v c gray86", "b c gainsboro", "n c #DDDDDD", "m c gray87", "M c gray88", "N c #E1E1E1", "B c #E2E2E2", "V c gray89", "C c gray90", "Z c #E6E6E6", "A c #E7E7E7", "S c gray91", "D c #EAEAEA", "F c gray92", "G c gray93", "H c #EEEEEE", "J c #EFEFEF", "K c gray94", "L c gray95", "P c #F3F3F3", "I c #F4F4F4", "U c gray96", "Y c #F6F6F6", "T c gray97", "R c #F8F8F8", "E c gray98", "W c #FBFBFB", "Q c gray99", "! c #FDFDFD", "~ c #FEFEFE", "^ c gray100", "/ c None", /* pixels */ "////////////////", "/////q98754/////", "///wgSP!QGMu;+o ////", "////////////////" }; /* XPM */ static char *signal_gtkwave[] = { /* columns rows colors chars-per-pixel */ "16 16 19 1", " c #070905", ". c #18270A", "X c #243910", "o c #325014", "O c #3E6617", "+ c #45701A", "@ c #446822", "# c #52861F", "$ c #599321", "% c #609D24", "& c #69AC27", "* c #74905A", "= c #7DA05B", "- c #7C9861", "; c #82A65E", ": c #96BA73", "> c #9DC279", ", c #A2C77D", "< c #AAD184", /* pixels */ "<::,::<::<>><>><", "-.XX..@oo@X XX.-", "* .. o&$$&O .. *", "*.oX.$+..@#.XX.-", "=oooo&OooO&oooo;", "* ...#X X#... *", "* . oOX .Oo.. *", "*Xoo$OoXXoO+ooX-", "=.oo%oo.Xoo%oo.=", "* .o+ X X +o. *", "* .+O X X O+. *", "=oo%+o@Xooo+%oo=", "*.o%X.o..o..%o.=", "*o&$ X X $&o*", "-X@o Xo .o. o@X-", "<>,,,<<,><<<<<<<" }; /* XPM */ static char *icon_component[] = { /* columns rows colors chars-per-pixel */ "16 16 128 2", " c gray99", ". c #EB6D79", "X c #73CAE5", "o c #CF5960", "O c #FFB2B7", "+ c #8FDDF9", "@ c #70AC33", "# c #FE8992", "$ c #EA6C74", "% c #72C5E4", "& c #E7FBD4", "* c #A3DEF4", "= c gray100", "- c #F4767E", "; c #9DDBF2", ": c #7CCFEE", "> c #D8F8B9", ", c #9AC86D", "< c #DF696F", "1 c #FFEEEE", "2 c #D1414B", "3 c #49AACE", "4 c #6FBBDA", "5 c #F8D4D6", "6 c #F9D8DA", "7 c #F5FEEF", "8 c #DAEFF7", "9 c #59ADCC", "0 c #D5424C", "q c #CD3E47", "w c #78C5E3", "e c #EEF9FF", "r c #F08E93", "t c #E7FAD5", "y c #3E8FAF", "u c #C7EDFD", "i c #F3B7BB", "p c #EDF8FC", "a c #FFC5C8", "s c #F9D3D5", "d c #D8EEF7", "f c #D5EEF7", "g c #FDECEE", "h c #5EABC6", "j c #CB5861", "k c #D2535C", "l c #E4FBD3", "z c #EAFBD9", "x c #9DD070", "c c #A3D375", "v c #45A3C6", "b c #AFDE79", "n c #72C2DF", "m c #9ECA72", "M c #A2CF74", "N c #B5383E", "B c #D5EDF7", "V c #E57076", "C c #6CBBD7", "Z c #F9D7D9", "A c #76C2E0", "S c #48A7CA", "D c #BAE1F0", "F c #D6EDF6", "G c #D7EEC0", "H c #B3E3FF", "J c #C8EDA2", "K c #FFB5B3", "L c #93D2EC", "P c #DC666E", "I c #F9D3D6", "U c #93C064", "Y c #63AFCC", "T c #93C365", "R c #BB242F", "E c #2B90B4", "W c #B5E8FC", "Q c #5FACCA", "! c #FBFBFB", "~ c None", "^ c black", "/ c black", "( c black", ") c black", "_ c black", "` c black", "' c black", "] c black", "[ c black", "{ c black", "} c black", "| c black", " . c black", ".. c black", "X. c black", "o. c black", "O. c black", "+. c black", "@. c black", "#. c black", "$. c black", "%. c black", "&. c black", "*. c black", "=. c black", "-. c black", ";. c black", ":. c black", ">. c black", ",. c black", "<. c black", "1. c black", "2. c black", "3. c black", "4. c black", "5. c black", "6. c black", "7. c black", "8. c black", "9. c black", "0. c black", "q. c black", "w. c black", "e. c black", "r. c black", "t. c black", "y. c black", "u. c black", /* pixels */ "~ ~ ~ ~ ~ ~ ~ ! ! ! ~ ~ ~ ~ ~ ~ ", "~ ~ ~ ~ ~ ! ! Q Q Q ! ! ~ ~ ~ ~ ", "~ ~ ~ ~ ! Q Y * w W Q Q ! ~ ~ ~ ", "~ ~ ! ! Q W ; * n ; W W y ! ~ ~ ", "~ T , Q = W W A W W : 3 ! ~ ~ ", "! T > J Q 8 e u 9 X X : S ~ ~ ", "! T = > Q d L p C % % + v ~ ~ ", "! T z 7 Q D H f 4 + + % E o ! ", "! T l M G h F B X X E E O O N ! ", "! T m x & c E E E E V O O - 0 ! ", "! ! U t & b o 6 1 a k . . - 2 ! ", "~ ~ ! @ @ @ o Z r g P $ $ # q ! ", "~ ~ ~ ! ! ! o i K I < # # $ R ! ", "~ ~ ~ ~ ~ ! ! j 5 s . . R R ! ! ", "~ ~ ~ ~ ~ ~ ~ ! R R R R ! ~ ~ ", "~ ~ ~ ~ ~ ~ ~ ~ ! ! ! ! ~ ~ ~ ~ " }; /* XPM */ static char *icon_extension[] = { /* columns rows colors chars-per-pixel */ "16 16 32 1", " c #A9EB56", ". c #C7EF95", "X c #89D538", "o c #7CBC2A", "O c #77C92C", "+ c #99DE45", "@ c #6AB224", "# c #BBED87", "$ c #55BB1B", "% c #319311", "& c #55A71D", "* c #3D9A14", "= c #83CD32", "- c #4BA21A", "; c #6ACA24", ": c #62AD22", "> c #8EDE39", ", c #76B929", "< c #4EB818", "1 c #389613", "2 c #5CAA20", "3 c #72B728", "4 c #76B927", "5 c #459E18", "6 c #60BF20", "7 c #6FB525", "8 c #6FC528", "9 c #68C224", "0 c #79D12D", "q c #6ACE20", "w c gray100", "e c None", /* pixels */ "eeeeewwweeeeeeee", "eeeewoooweeeeeee", "eeewo. +oweeeeee", "eeewo X+4weeeeee", "wwwww, ,wwwweeee", "wooo,. 77@:weeee", "wo...+=+>>2wwwee", "wooo>==OOX&w-5we", "woww3XOO80O5#>*w", "ewew7XO8966$$<1w", "w4ww@X006;*1<<%w", "w,7@X2&-0;1w%%we", "w,#X:www*q1wwwee", "w3+X2wew*q%weeee", "w7@:&-w*11%weeee", "wwwwwwewwwwweeee" }; /* XPM */ static char *door_in[] = { /* columns rows colors chars-per-pixel */ "16 16 178 2", " c #34752E", ". c #397136", "X c #377931", "o c #3B7E34", "O c #3D7339", "+ c #3F743B", "@ c #40733C", "# c #41763D", "$ c gray27", "% c gray28", "& c gray29", "* c #4C4C4C", "= c gray31", "- c #515151", "; c gray33", ": c #585858", "> c gray36", ", c #467C41", "< c #577F54", "1 c #606060", "2 c #717171", "3 c #727272", "4 c gray46", "5 c #777777", "6 c gray48", "7 c #7C7C7C", "8 c gray49", "9 c #7E7E7E", "0 c #8F570C", "q c #90580D", "w c #91590F", "e c #925A10", "r c #925C13", "t c #945C13", "y c #986019", "u c #9C641F", "i c #9D6725", "p c #A16925", "a c #A66E2C", "s c #A56F2F", "d c #A87432", "f c #AB7334", "g c #AA7436", "h c #AF7C3D", "j c #AD7E3E", "k c #B1793B", "l c #B0793D", "z c #AE7F40", "x c #B67E43", "c c #B47E45", "v c #3E8237", "b c #42873B", "n c #45893D", "m c #458A3D", "M c #468B3E", "N c #488D3F", "B c #4B8345", "V c #4C8F46", "C c #4D8F47", "Z c #4F8A49", "A c #4A9041", "S c #4B9142", "D c #4D9444", "F c #4F9049", "G c #509149", "H c #599152", "J c #589851", "K c #61A05A", "L c #65A45D", "P c #7CC073", "I c #7CC074", "U c #7FC177", "Y c #AE8041", "T c #AF8143", "R c #B18345", "E c #B18547", "W c #B58447", "Q c #B88B42", "! c #BC844B", "~ c #BA844C", "^ c #B3884B", "/ c #B4894F", "( c #BA8A4E", ") c #B58B51", "_ c #B68D53", "` c #B78F56", "' c #BF8954", "] c #B89058", "[ c #B9915A", "{ c #C18952", "} c #C68E59", "| c #C48E5A", " . c #C79554", ".. c #C89658", "X. c #C99A5A", "o. c #C99A5B", "O. c #CA9B5E", "+. c #DFB45F", "@. c #C99260", "#. c #CB9360", "$. c #CC9666", "%. c #CF9766", "&. c #CC9E61", "*. c #CC9F62", "=. c #CC9F63", "-. c #D29A6A", ";. c #D09A6C", ":. c #D39D6F", ">. c #D49C6D", ",. c #D69E6F", "<. c #D49E71", "1. c #D69E70", "2. c #CFA367", "3. c #CDA069", "4. c #D1A666", "5. c #D1A86E", "6. c #D1A773", "7. c #D4AD75", "8. c #D6AF74", "9. c #D2AB78", "0. c #D3AB78", "q. c #D4AF7D", "w. c #D7B37C", "e. c #D7B37E", "r. c #D7B47D", "t. c #E1B863", "y. c #81C378", "u. c #81C279", "i. c #83C37B", "p. c #87C67D", "a. c #FFD44B", "s. c #EDC45E", "d. c #808080", "f. c gray60", "g. c #999A99", "h. c #9A9A9A", "j. c #9B9B9B", "k. c gray61", "l. c #9D9D9D", "z. c gray62", "x. c #9F9F9F", "c. c #A0A0A0", "v. c #A1A1A0", "b. c gray63", "n. c #A2A2A2", "m. c gray64", "M. c #A4A4A4", "N. c #A5A5A5", "B. c #D7B382", "V. c #DAB185", "C. c #DCB287", "Z. c #DAB883", "A. c #DAB983", "S. c #DAB984", "D. c #D9B788", "F. c #DCBD89", "G. c #DCBD8B", "H. c #DBBB8D", "J. c #DDBF94", "K. c #88C680", "L. c #8DC884", "P. c #92CB89", "I. c #96CD8D", "U. c #99CE8F", "Y. c #9AD091", "T. c #9FD294", "R. c #DFC18F", "E. c #DEC291", "W. c #E0C398", "Q. c #E1C798", "!. c #E2C79E", "~. c #E3CBA2", "^. c #E5CEA7", "/. c #E6D0A9", "(. c #E7D1AA", "). c #E7D1AB", "_. c #E8D3AB", "`. c None", /* pixels */ "`.`.`.`.`.`.`.`.`.`.`.`.`.>.-.%.", "`.`.`.`.`.`.`.`.`.`.`.1.>.V.[ #.", "`.`.d.9 7 6 5 4 3 <.,.C._./.] } ", "`.`.8 f.f.h.h.j.j.:.(.).Q.E.` { ", "`.`.6 f.H g.j.k.k.;.^.R.F.G._ ! ", "`.`.5 h.m Z k.l.l.$.~.F.A.S.) x ", "D S N n L K B z.z.@.!.Z.r.e./ k ", "A T.Y.I.P.L.J , x.| W.w.8.s.^ f ", "M U.p.y.P I u.F < ' J.7.t.a.Q a ", "b P.L.K.i.U C + b.~ H.5.4.+.E p ", "v o X G V O b.n.c D.2.&.=.R u ", "`.`.1 c.# . n.n.m.l B.*.X.O.T y ", "`.`.> b.@ v.m.m.M.g q.o. ...Y t ", "`.`.: n.n.m.M.M.N.s 9.0.6.3.z w ", "f.2 ; - = * & % $ i d h W ( j 0 ", "`.`.`.`.`.`.`.`.`.`.`.`.e q r 0 " }; /* XPM */ static char *door_open[] = { /* columns rows colors chars-per-pixel */ "16 16 138 2", " c gray27", ". c gray28", "X c gray29", "o c #4C4C4C", "O c gray31", "+ c #515151", "@ c gray33", "# c #585858", "$ c gray36", "% c #606060", "& c #646464", "* c #686868", "= c #6C6C6C", "- c gray44", "; c #717171", ": c #727272", "> c gray45", ", c gray46", "< c #777777", "1 c gray48", "2 c #7C7C7C", "3 c gray49", "4 c #7E7E7E", "5 c #8F570C", "6 c #90580D", "7 c #91590F", "8 c #925A10", "9 c #925C13", "0 c #945C13", "q c #986019", "w c #9C641F", "e c #9D6725", "r c #A16925", "t c #A66E2C", "y c #A56F2F", "u c #A87432", "i c #AB7334", "p c #AA7436", "a c #AF7C3D", "s c #AD7E3E", "d c #B1793B", "f c #B0793D", "g c #AE7F40", "h c #B67E43", "j c #B47E45", "k c #AE8041", "l c #AF8143", "z c #B18345", "x c #B18547", "c c #B58447", "v c #B88B42", "b c #BC844B", "n c #BA844C", "m c #B3884B", "M c #B4894F", "N c #BA8A4E", "B c #B58B51", "V c #B68D53", "C c #B78F56", "Z c #BF8954", "A c #B89058", "S c #B9915A", "D c #C18952", "F c #C68E59", "G c #C48E5A", "H c #C79554", "J c #C89658", "K c #C99A5A", "L c #C99A5B", "P c #CA9B5E", "I c #DFB45F", "U c #C99260", "Y c #CB9360", "T c #CC9666", "R c #CF9766", "E c #CC9E61", "W c #CC9F62", "Q c #CC9F63", "! c #D29A6A", "~ c #D09A6C", "^ c #D39D6F", "/ c #D49C6D", "( c #D69E6F", ") c #D49E71", "_ c #D69E70", "` c #CFA367", "' c #CDA069", "] c #D1A666", "[ c #D1A86E", "{ c #D1A773", "} c #D4AD75", "| c #D6AF74", " . c #D2AB78", ".. c #D3AB78", "X. c #D4AF7D", "o. c #D7B37C", "O. c #D7B37E", "+. c #D7B47D", "@. c #E1B863", "#. c #FFD44B", "$. c #EDC45E", "%. c #808080", "&. c gray60", "*. c #9A9A9A", "=. c #9B9B9B", "-. c gray61", ";. c #9D9D9D", ":. c gray62", ">. c #9F9F9F", ",. c #A0A0A0", "<. c gray63", "1. c #A2A2A2", "2. c gray64", "3. c #A4A4A4", "4. c #A5A5A5", "5. c #D7B382", "6. c #DAB185", "7. c #DCB287", "8. c #DAB883", "9. c #DAB983", "0. c #DAB984", "q. c #D9B788", "w. c #DCBD89", "e. c #DCBD8B", "r. c #DBBB8D", "t. c #DDBF94", "y. c #DFC18F", "u. c #DEC291", "i. c #E0C398", "p. c #E1C798", "a. c #E2C79E", "s. c #E3CBA2", "d. c #E5CEA7", "f. c #E6D0A9", "g. c #E7D1AA", "h. c #E7D1AB", "j. c #E8D3AB", "k. c None", /* pixels */ "k.k.k.k.k.k.k.k.k.k.k.k.k./ ! R ", "k.k.k.k.k.k.k.k.k.k.k._ / 6.S Y ", "k.k.%.4 2 1 < , : ) ( 7.j.f.A F ", "k.k.3 &.&.*.*.=.=.^ g.h.p.u.C D ", "k.k.1 &.*.*.=.-.-.~ d.y.w.e.V b ", "k.k.< *.=.=.-.;.;.T s.w.9.0.B h ", "k.k.> =.-.-.;.:.:.U a.8.+.O.M d ", "k.k.- -.;.;.:.>.>.G i.o.| $.m i ", "k.k.= ;.:.:.>.>.,.Z t.} @.#.v t ", "k.k.* :.>.>.,.,.<.n r.[ ] I x r ", "k.k.& >.>.,.<.<.1.j q.` E Q z w ", "k.k.% ,.,.<.1.1.2.f 5.W K P l q ", "k.k.$ <.<.1.2.2.3.p X.L H J k 0 ", "k.k.# 1.1.2.3.3.4.y ...{ ' g 7 ", "&.; @ + O o X . e u a c N s 5 ", "k.k.k.k.k.k.k.k.k.k.k.k.8 6 9 5 " }; /* XPM */ static char *door_out[] = { /* columns rows colors chars-per-pixel */ "16 16 175 2", " c #256321", ". c #276623", "X c #286724", "o c #2A6A26", "O c #2C6C27", "+ c #2D6E28", "@ c #30702A", "# c #34752E", "$ c #377931", "% c #3B7E34", "& c #3E7639", "* c #3F773A", "= c #40733C", "- c #41763D", "; c gray27", ": c gray28", "> c gray29", ", c #4C4C4C", "< c gray31", "1 c #515151", "2 c gray33", "3 c #585858", "4 c gray36", "5 c #606060", "6 c #717171", "7 c #727272", "8 c gray46", "9 c #777777", "0 c gray48", "q c #7C7C7C", "w c gray49", "e c #7E7E7E", "r c #8F570C", "t c #90580D", "y c #91590F", "u c #925A10", "i c #925C13", "p c #945C13", "a c #986019", "s c #9C641F", "d c #9D6725", "f c #A16925", "g c #A66E2C", "h c #A56F2F", "j c #A87432", "k c #AB7334", "l c #AA7436", "z c #AF7C3D", "x c #AD7E3E", "c c #B1793B", "v c #B0793D", "b c #AE7F40", "n c #B67E43", "m c #B47E45", "M c #3E8237", "N c #3F8338", "B c #458A3D", "V c #468B3E", "C c #478C3F", "Z c #4F8947", "A c #509149", "S c #54904D", "D c #54954D", "F c #599152", "G c #5D9D56", "H c #65A45D", "J c #66A55E", "K c #67A65F", "L c #69A760", "P c #71BB69", "I c #75BC6F", "U c #77BD6E", "Y c #79BE72", "T c #7CBF75", "R c #7CC073", "E c #7FC177", "W c #AE8041", "Q c #AF8143", "! c #B18345", "~ c #B18547", "^ c #B58447", "/ c #B88B42", "( c #BC844B", ") c #BA844C", "_ c #B3884B", "` c #B4894F", "' c #BA8A4E", "] c #B58B51", "[ c #B68D53", "{ c #B78F56", "} c #BF8954", "| c #B89058", " . c #B9915A", ".. c #C18952", "X. c #C68E59", "o. c #C48E5A", "O. c #C79554", "+. c #C89658", "@. c #C99A5A", "#. c #C99A5B", "$. c #CA9B5E", "%. c #DFB45F", "&. c #C99260", "*. c #CB9360", "=. c #CC9666", "-. c #CF9766", ";. c #CC9E61", ":. c #CC9F62", ">. c #CC9F63", ",. c #D29A6A", "<. c #D09A6C", "1. c #D39D6F", "2. c #D49C6D", "3. c #D69E6F", "4. c #D49E71", "5. c #D69E70", "6. c #CFA367", "7. c #CDA069", "8. c #D1A666", "9. c #D1A86E", "0. c #D1A773", "q. c #D4AD75", "w. c #D6AF74", "e. c #D2AB78", "r. c #D3AB78", "t. c #D4AF7D", "y. c #D7B37C", "u. c #D7B37E", "i. c #D7B47D", "p. c #E1B863", "a. c #83C37B", "s. c #86C57D", "d. c #FFD44B", "f. c #EDC45E", "g. c #808080", "h. c #989998", "j. c gray60", "k. c #9A9A9A", "l. c #9B9B9B", "z. c gray61", "x. c #9D9D9D", "c. c #A0A0A0", "v. c gray63", "b. c #A2A2A2", "n. c gray64", "m. c #A4A4A4", "M. c #A5A5A5", "N. c #D7B382", "B. c #DAB185", "V. c #DCB287", "C. c #DAB883", "Z. c #DAB983", "A. c #DAB984", "S. c #D9B788", "D. c #DCBD89", "F. c #DCBD8B", "G. c #DBBB8D", "H. c #DDBF94", "J. c #88C680", "K. c #8DC884", "L. c #92CB89", "P. c #94CC8B", "I. c #96CD8D", "U. c #DFC18F", "Y. c #DEC291", "T. c #E0C398", "R. c #E1C798", "E. c #E2C79E", "W. c #E3CBA2", "Q. c #E5CEA7", "!. c #E6D0A9", "~. c #E7D1AA", "^. c #E7D1AB", "/. c #E8D3AB", "(. c None", /* pixels */ "(.(.(.(.(.(.(.(.(.(.(.(.(.2.,.-.", "(.(.(.(.(.(.(.(.(.(.(.5.2.B. .*.", "(.(.g.e q 0 9 8 7 4.3.V./.!.| X.", "(.(.w j.j.k.k.l.l.1.~.^.R.Y.{ ..", "(.(.0 h.F k.l.z.z.<.Q.U.D.F.[ ( ", "(.(.9 S B l.z.x.x.=.W.D.Z.A.] n ", "(.(.Z L H M % $ # &.E.C.i.u.` c ", "(.C K I.L.K.J.a.@ o.T.y.w.f._ k ", "V J P.s.R U P T O } H.q.p.d./ g ", "(.N G J.a.E Y I X ) G.9.8.%.~ f ", "(.(.& D A + o . m S.6.;.>.! s ", "(.(.5 * - v.b.b.n.v N.:.@.$.Q a ", "(.(.4 c.= b.n.n.m.l t.#.O.+.W p ", "(.(.3 b.b.n.m.m.M.h e.r.0.7.b y ", "j.6 2 1 < , > : ; d j z ^ ' x r ", "(.(.(.(.(.(.(.(.(.(.(.(.u t i r " }; /* XPM */ static char *icon_link[] = { /* columns rows colors chars-per-pixel */ "16 16 43 1", " c #323232", ". c #3F3F3F", "X c #414141", "o c #464646", "O c gray29", "+ c #4B4B4B", "@ c #4C4C4C", "# c gray30", "$ c #515151", "% c gray32", "& c #585858", "* c #646464", "= c #656565", "- c #676767", "; c gray42", ": c #717171", "> c gray45", ", c gray47", "< c #797979", "1 c #7B7B7B", "2 c #7C7C7C", "3 c #818181", "4 c gray51", "5 c gray52", "6 c #8D8D8D", "7 c gray57", "8 c #929292", "9 c #979797", "0 c gray62", "q c gray66", "w c #AAAAAA", "e c gray68", "r c #AEAEAE", "t c gray74", "y c #C1C1C1", "u c gray76", "i c gray77", "p c #CECECE", "a c #D5D5D5", "s c gray85", "d c #DDDDDD", "f c gray91", "g c None", /* pixels */ "gggggggggggggggg", "gggggggggggggggg", "gggggggggggggggg", "gggggggggggggggg", "gggg502gg205gggg", "gg@7fdy31sdi7@gg", "gg>a&+=8<=+&q>gg", "g 4gg.tpue.gg4 g", "gg-g%Xo$$oX%g-gg", "gg#6wr9:,9rw6#gg", "gggO*;;gg;;*Oggg", "gggggggggggggggg", "gggggggggggggggg", "gggggggggggggggg", "gggggggggggggggg", "gggggggggggggggg" }; #ifdef MAC_INTEGRATION #define wave_gdk_pixmap_create_from_xpm_d(A,B,C,D) gdk_pixmap_create_from_xpm_d(A,NULL,C,D) #else #define wave_gdk_pixmap_create_from_xpm_d(A,B,C,D) gdk_pixmap_create_from_xpm_d(A,B,C,D) #endif #ifdef MAC_INTEGRATION GdkPixbuf * #else void #endif make_pixmaps(GtkWidget *window) { GtkStyle *style; #ifdef WAVE_USE_GTK2 GdkPixbuf *gp; #endif style=gtk_widget_get_style(window); GLOBALS->redo_pixmap=wave_gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->redo_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)icon_redo); GLOBALS->larrow_pixmap=wave_gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->larrow_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)icon_larrow); GLOBALS->rarrow_pixmap=wave_gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->rarrow_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)icon_rarrow); GLOBALS->zoomout_pixmap=wave_gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->zoomout_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)icon_zoomout); GLOBALS->zoomin_pixmap=wave_gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->zoomin_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)icon_zoomin); GLOBALS->zoomfit_pixmap=wave_gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->zoomfit_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)icon_zoomfit); GLOBALS->zoomundo_pixmap=wave_gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->zoomundo_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)icon_zoomundo); GLOBALS->zoom_larrow_pixmap=wave_gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->zoom_larrow_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)zoom_larrow); GLOBALS->zoom_rarrow_pixmap=wave_gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->zoom_rarrow_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)zoom_rarrow); GLOBALS->prev_page_pixmap=wave_gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->prev_page_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)prev_page_xpm); GLOBALS->next_page_pixmap=wave_gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->next_page_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)next_page_xpm); GLOBALS->wave_info_pixmap=wave_gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->wave_info_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)wave_info); GLOBALS->wave_alert_pixmap=wave_gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->wave_alert_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)wave_alert); /* Verilog */ GLOBALS->hiericon_module_pixmap=gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->hiericon_module_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)chart_organisation); GLOBALS->hiericon_task_pixmap=gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->hiericon_task_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)cog); GLOBALS->hiericon_function_pixmap=gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->hiericon_function_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)chart_line); GLOBALS->hiericon_begin_pixmap=gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->hiericon_begin_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)flag_green); GLOBALS->hiericon_fork_pixmap=gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->hiericon_fork_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)arrow_divide); /* SV */ GLOBALS->hiericon_interface_pixmap=gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->hiericon_interface_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)arrow_inout); GLOBALS->hiericon_svpackage_pixmap=gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->hiericon_svpackage_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)package); GLOBALS->hiericon_program_pixmap=gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->hiericon_program_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)application); GLOBALS->hiericon_class_pixmap=gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->hiericon_class_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)plugin); /* VHDL */ GLOBALS->hiericon_design_pixmap=gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->hiericon_design_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)database); GLOBALS->hiericon_block_pixmap=gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->hiericon_block_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)brick); GLOBALS->hiericon_generateif_pixmap=gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->hiericon_generateif_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)arrow_switch); GLOBALS->hiericon_generatefor_pixmap=gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->hiericon_generatefor_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)arrow_rotate_clockwise); GLOBALS->hiericon_instance_pixmap=gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->hiericon_instance_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)icon_component); GLOBALS->hiericon_package_pixmap=gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->hiericon_package_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)box); GLOBALS->hiericon_signal_pixmap=gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->hiericon_signal_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)signal_gtkwave); GLOBALS->hiericon_portin_pixmap=gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->hiericon_portin_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)door_in); GLOBALS->hiericon_portout_pixmap=gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->hiericon_portout_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)door_out); GLOBALS->hiericon_portinout_pixmap=gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->hiericon_portinout_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)door_open); GLOBALS->hiericon_buffer_pixmap=gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->hiericon_buffer_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)icon_extension); GLOBALS->hiericon_linkage_pixmap=wave_gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->hiericon_linkage_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)icon_link); /* FSDB VHDL (on top of GHW's existing) */ GLOBALS->hiericon_record_pixmap=gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->hiericon_record_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)cd_img); GLOBALS->hiericon_generate_pixmap=gdk_pixmap_create_from_xpm_d(window->window, &GLOBALS->hiericon_generate_mask, &style->bg[GTK_STATE_NORMAL], (gchar **)arrow_redo); #ifdef WAVE_USE_GTK2 /* set icon for window manager */ gp = xg_get_pixbuf_from_pix_and_mask(GLOBALS->wave_info_pixmap, GLOBALS->wave_info_mask, NULL); gtk_window_set_icon(GTK_WINDOW(window), gp); #ifdef MAC_INTEGRATION return(gp); #endif #else return; #endif } gtkwave-3.3.66/src/baseconvert.h0000664000076400007640000000131511523063250016047 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2010 * * 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. */ #ifndef WAVE_BASECONVERT_H #define WAVE_BASECONVERT_H char *convert_ascii(Trptr t, vptr v); char *convert_ascii_vec(Trptr t, char *vec); char *convert_ascii_real(Trptr t, double *d); char *convert_ascii_string(char *s); char *convert_ascii_vec_2(Trptr t, char *vec); double convert_real_vec(Trptr t, char *vec); double convert_real(Trptr t, vptr v); int vtype(Trptr t, char *vec); int vtype2(Trptr t, vptr v); #endif gtkwave-3.3.66/src/clipping.c0000664000076400007640000000423712341266475015357 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2005-2010 * * 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. */ #include "globals.h" #include #include #include #define x1 coords[0] #define y1 coords[1] #define x2 coords[2] #define y2 coords[3] #define rx1 rect[0] #define ry1 rect[1] #define rx2 rect[2] #define ry2 rect[3] int wave_lineclip(int *coords, int *rect) { int msk1, msk2; /* these comparisons assume the bounding rectangle is set up as follows: rx1 rx2 ry1 +--------+ | | ry2 +--------+ */ msk1 = (x1rx2)<<1; msk1|= (y1ry2)<<3; msk2 = (x2rx2)<<1; msk2|= (y2ry2)<<3; if(!(msk1|msk2)) return(1); /* trivial accept, all points are inside rectangle */ if(msk1&msk2) return(0); /* trivial reject, common x or y out of range */ if(y1==y2) { if(x1rx2) x1 = rx2; if(x2rx2) x2 = rx2; } else if(x1==x2) { if(y1ry2) y1 = ry2; if(y2ry2) y2 = ry2; } else { double dx1 = x1, dy1 = y1, dx2 = x2, dy2 = y2; double m = (dy2-dy1)/(dx2-dx1); double b = dy1 - m*dx1; if((x1=rx1)) { dx1 = rx1; dy1 = m*dx1 + b; } else if((x1>rx2)&&(x2<=rx2)) { dx1 = rx2; dy1 = m*dx1 + b; } if((y1=ry1)) { dy1 = ry1; dx1 = (dy1 - b) / m; } else if((y1>ry2)&&(y2<=ry2)) { dy1 = ry2; dx1 = (dy1 - b) / m; } if((x2=rx1)) { dx2 = rx1; dy2 = m*dx2 + b; } else if((x2>rx2)&&(x1<=rx2)) { dx2 = rx2; dy2 = m*dx2 + b; } if((y2=ry1)) { dy2 = ry1; dx2 = (dy2 - b) / m; } else if((y2>ry2)&&(y1<=ry2)) { dy2 = ry2; dx2 = (dy2 - b) / m; } x1 = dx1; y1 = dy1; x2 = dx2; y2 = dy2; } msk1 = (x1rx2)<<1; msk1|= (y1ry2)<<3; msk2 = (x2rx2)<<1; msk2|= (y2ry2)<<3; return(!msk1 && !msk2); /* see if points are really inside */ } gtkwave-3.3.66/src/gtk12compat.h0000664000076400007640000000166211665216312015703 0ustar bybellbybell#ifndef WAVE_GTK12COMPAT_H #define WAVE_GTK12COMPAT_H #ifdef MAC_INTEGRATION /* #undef WAVE_ALLOW_QUARTZ_FLUSH_WORKAROUND */ #endif #if WAVE_USE_GTK2 #define WAVE_GTKIFE(a,b,c,d,e) {a,b,c,d,e,NULL} #define WAVE_GDK_GET_POINTER(a,b,c,bi,ci,d) gdk_window_get_pointer(a,bi,ci,d) #define WAVE_GDK_GET_POINTER_COPY x=xi; y=yi; #define WAVE_GTK_SFUNCAST(x) ((void (*)(GtkWidget *, gpointer))(x)) #else #if !defined __MINGW32__ && !defined _MSC_VER #ifndef G_CONST_RETURN #define G_CONST_RETURN #endif #endif #define WAVE_GTKIFE(a,b,c,d,e) {a,b,c,d,e} #define WAVE_GDK_GET_POINTER(a,b,c,bi,ci,d) gdk_input_window_get_pointer(a, event->deviceid, b, c, NULL, NULL, NULL, d) #define WAVE_GDK_GET_POINTER_COPY #define WAVE_GTK_SIGFONT wavearea->style->font #define WAVE_GTK_WAVEFONT wavearea->style->font #define WAVE_GTK_SFUNCAST(x) ((GtkSignalFunc)(x)) #define gtk_notebook_set_current_page(n,p) gtk_notebook_set_page((n),(p)) #endif #endif gtkwave-3.3.66/src/markerbox.c0000664000076400007640000003070412523241774015537 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2014. * * 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. */ #include "globals.h" #include #include #include #include "gtk12compat.h" #include "debug.h" #include "analyzer.h" #include "currenttime.h" static void gtkwave_strrev(char *p) { char *q = p; while(q && *q) ++q; for(--q; p < q; ++p, --q) *p = *p ^ *q, *q = *p ^ *q, *p = *p ^ *q; } char *make_bijective_marker_id_string(char *buf, unsigned int value) { char *pnt = buf; value++; /* bijective values start at one */ while (value) { value--; *(pnt++) = (char)('A' + value % ('Z'-'A'+1)); value = value / ('Z'-'A'+1); } *pnt = 0; gtkwave_strrev(buf); return(buf); } unsigned int bijective_marker_id_string_hash(char *so) { unsigned int val=0; int i; int len = strlen(so); char sn[16]; char *s = sn; strcpy(sn, so); gtkwave_strrev(sn); s += len; for(i=0;i 'Z')) break; val *= ('Z'-'A'+1); val += ((unsigned char)c) - ('A' - 1); } val--; /* bijective values start at one so decrement */ return(val); } unsigned int bijective_marker_id_string_len(char *s) { int len = 0; while(*s) { char c = toupper(*s); if((c >= 'A') && (c <= 'Z')) { len++; s++; continue; } else { break; } } return(len); } static void str_change_callback(GtkWidget *entry, gpointer which) { G_CONST_RETURN gchar *entry_text; int i; uint32_t hashmask = WAVE_NUM_NAMED_MARKERS; hashmask |= hashmask >> 1; hashmask |= hashmask >> 2; hashmask |= hashmask >> 4; hashmask |= hashmask >> 8; hashmask |= hashmask >> 16; i = ((int) (((intptr_t) which) & hashmask)) % WAVE_NUM_NAMED_MARKERS; GLOBALS->dirty_markerbox_c_1 = 1; entry_text = gtk_entry_get_text(GTK_ENTRY(entry)); if(entry_text && strlen(entry_text)) { if(GLOBALS->shadow_marker_names[i]) { free_2(GLOBALS->shadow_marker_names[i]); } GLOBALS->shadow_marker_names[i] = strdup_2(entry_text); } else { if(GLOBALS->shadow_marker_names[i]) { free_2(GLOBALS->shadow_marker_names[i]); GLOBALS->shadow_marker_names[i] = NULL; } } } static void str_enter_callback(GtkWidget *entry, gpointer which) { G_CONST_RETURN gchar *entry_text; int i; uint32_t hashmask = WAVE_NUM_NAMED_MARKERS; hashmask |= hashmask >> 1; hashmask |= hashmask >> 2; hashmask |= hashmask >> 4; hashmask |= hashmask >> 8; hashmask |= hashmask >> 16; i = ((int) (((intptr_t) which) & hashmask)) % WAVE_NUM_NAMED_MARKERS; GLOBALS->dirty_markerbox_c_1 = 1; entry_text = gtk_entry_get_text(GTK_ENTRY(entry)); if(entry_text && strlen(entry_text)) { if(GLOBALS->shadow_marker_names[i]) { free_2(GLOBALS->shadow_marker_names[i]); } GLOBALS->shadow_marker_names[i] = strdup_2(entry_text); gtk_entry_select_region (GTK_ENTRY (entry), 0, GTK_ENTRY(entry)->text_length); } else { if(GLOBALS->shadow_marker_names[i]) { free_2(GLOBALS->shadow_marker_names[i]); GLOBALS->shadow_marker_names[i] = NULL; } } } static void change_callback(GtkWidget *widget, gpointer which) { (void)widget; GtkWidget *entry; TimeType temp; G_CONST_RETURN gchar *entry_text; char buf[49]; int i; int ent_idx; uint32_t hashmask = WAVE_NUM_NAMED_MARKERS; hashmask |= hashmask >> 1; hashmask |= hashmask >> 2; hashmask |= hashmask >> 4; hashmask |= hashmask >> 8; hashmask |= hashmask >> 16; ent_idx = ((int) (((intptr_t) which) & hashmask)) % WAVE_NUM_NAMED_MARKERS; entry=GLOBALS->entries_markerbox_c_1[ent_idx]; entry_text = gtk_entry_get_text(GTK_ENTRY(entry)); entry_text = entry_text ? entry_text : ""; if(!strlen(entry_text)) goto failure; if(entry_text[0] != '-') { if(!isdigit((int)(unsigned char)entry_text[0])) goto failure; } temp=unformat_time(entry_text, GLOBALS->time_dimension); temp -= GLOBALS->global_time_offset; if((temptims.start)||(temp>GLOBALS->tims.last)) goto failure; for(i=0;ishadow_markers_markerbox_c_1[i]) { if(i!=ent_idx) { GLOBALS->shadow_markers_markerbox_c_1[ent_idx] = -1; } goto failure; } } reformat_time_simple(buf, temp + GLOBALS->global_time_offset, GLOBALS->time_dimension); GLOBALS->shadow_markers_markerbox_c_1[ent_idx]=temp; GLOBALS->dirty_markerbox_c_1=1; failure: return; } static void enter_callback(GtkWidget *widget, gpointer which) { (void)widget; GtkWidget *entry; /* TimeType *modify; */ /* scan-build */ TimeType temp; G_CONST_RETURN gchar *entry_text; char buf[49]; int i; int ent_idx; uint32_t hashmask = WAVE_NUM_NAMED_MARKERS; hashmask |= hashmask >> 1; hashmask |= hashmask >> 2; hashmask |= hashmask >> 4; hashmask |= hashmask >> 8; hashmask |= hashmask >> 16; ent_idx = ((int) (((intptr_t) which) & hashmask)) % WAVE_NUM_NAMED_MARKERS; entry=GLOBALS->entries_markerbox_c_1[ent_idx]; entry_text = gtk_entry_get_text(GTK_ENTRY(entry)); entry_text = entry_text ? entry_text : ""; if(!strlen(entry_text)) goto failure; temp=unformat_time(entry_text, GLOBALS->time_dimension); temp -= GLOBALS->global_time_offset; if((temptims.start)||(temp>GLOBALS->tims.last)) goto failure; for(i=0;ishadow_markers_markerbox_c_1[i]) goto failure; } reformat_time_simple(buf, temp + GLOBALS->global_time_offset, GLOBALS->time_dimension); gtk_entry_set_text (GTK_ENTRY (entry), buf); GLOBALS->shadow_markers_markerbox_c_1[ent_idx]=temp; GLOBALS->dirty_markerbox_c_1=1; gtk_entry_select_region (GTK_ENTRY (entry), 0, GTK_ENTRY(entry)->text_length); return; failure: /* modify=(TimeType *)which; */ /* scan-build */ if(GLOBALS->shadow_markers_markerbox_c_1[ent_idx]==-1) { sprintf(buf,""); } else { reformat_time_simple(buf, GLOBALS->shadow_markers_markerbox_c_1[ent_idx] + GLOBALS->global_time_offset, GLOBALS->time_dimension); } gtk_entry_set_text (GTK_ENTRY (entry), buf); } static void ok_callback(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; if(GLOBALS->dirty_markerbox_c_1) { int i; for(i=0;inamed_markers[i]=GLOBALS->shadow_markers_markerbox_c_1[i]; if(GLOBALS->marker_names[i]) free_2(GLOBALS->marker_names[i]); GLOBALS->marker_names[i] = GLOBALS->shadow_marker_names[i]; GLOBALS->shadow_marker_names[i] = NULL; } MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } wave_gtk_grab_remove(GLOBALS->window_markerbox_c_4); gtk_widget_destroy(GLOBALS->window_markerbox_c_4); GLOBALS->window_markerbox_c_4 = NULL; GLOBALS->cleanup_markerbox_c_4(); } static void destroy_callback(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; int i; for(i=0;imarker_names[i]) free_2(GLOBALS->marker_names[i]); GLOBALS->marker_names[i] = GLOBALS->shadow_marker_names[i]; GLOBALS->shadow_marker_names[i] = NULL; } wave_gtk_grab_remove(GLOBALS->window_markerbox_c_4); gtk_widget_destroy(GLOBALS->window_markerbox_c_4); GLOBALS->window_markerbox_c_4 = NULL; } void markerbox(char *title, GtkSignalFunc func) { GtkWidget *entry; GtkWidget *vbox, *hbox, *vbox_g, *label; GtkWidget *button1, *button2, *scrolled_win, *frame, *separator; GtkWidget *table; char labtitle[16]; int i; GLOBALS->cleanup_markerbox_c_4=func; GLOBALS->dirty_markerbox_c_1=0; for(i=0;ishadow_markers_markerbox_c_1[i] = GLOBALS->named_markers[i]; GLOBALS->shadow_marker_names[i] = strdup_2(GLOBALS->marker_names[i]); } /* fix problem where ungrab doesn't occur if button pressed + simultaneous accelerator key occurs */ if(GLOBALS->in_button_press_wavewindow_c_1) { gdk_pointer_ungrab(GDK_CURRENT_TIME); } /* create a new modal window */ GLOBALS->window_markerbox_c_4 = gtk_window_new(GLOBALS->disable_window_manager ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL); install_focus_cb(GLOBALS->window_markerbox_c_4, ((char *)&GLOBALS->window_markerbox_c_4) - ((char *)GLOBALS)); gtk_window_set_title(GTK_WINDOW (GLOBALS->window_markerbox_c_4), title); gtkwave_signal_connect(GTK_OBJECT (GLOBALS->window_markerbox_c_4), "delete_event",(GtkSignalFunc) destroy_callback, NULL); vbox = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox); vbox_g = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox_g); table = gtk_table_new (256, 1, FALSE); gtk_widget_show (table); gtk_table_attach (GTK_TABLE (table), vbox, 0, 1, 0, 255, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); frame = gtk_frame_new (NULL); gtk_container_border_width (GTK_CONTAINER (frame), 3); gtk_widget_show(frame); scrolled_win = gtk_scrolled_window_new (NULL, NULL); gtk_widget_set_usize( GTK_WIDGET (scrolled_win), 400, 300); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_widget_show(scrolled_win); gtk_container_add (GTK_CONTAINER (frame), scrolled_win); gtk_container_add (GTK_CONTAINER (vbox), frame); for(i=0;ientries_markerbox_c_1[i]=entry = gtk_entry_new_with_max_length (48); gtkwave_signal_connect(GTK_OBJECT(entry), "activate", GTK_SIGNAL_FUNC(enter_callback), (void *)((intptr_t) i)); gtkwave_signal_connect(GTK_OBJECT(entry), "changed", GTK_SIGNAL_FUNC(change_callback), (void *)((intptr_t) i)); if(GLOBALS->shadow_markers_markerbox_c_1[i]==-1) { sprintf(buf,""); } else { reformat_time_simple(buf, GLOBALS->shadow_markers_markerbox_c_1[i] + GLOBALS->global_time_offset, GLOBALS->time_dimension); } gtk_entry_set_text (GTK_ENTRY (entry), buf); gtk_widget_show (entry); gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0); /* string part */ entry = gtk_entry_new_with_max_length (48); if(GLOBALS->shadow_marker_names[i]) gtk_entry_set_text (GTK_ENTRY (entry), GLOBALS->shadow_marker_names[i]); gtk_widget_show (entry); gtkwave_signal_connect(GTK_OBJECT(entry), "activate", GTK_SIGNAL_FUNC(str_enter_callback), (void *)((intptr_t) i)); gtkwave_signal_connect(GTK_OBJECT(entry), "changed", GTK_SIGNAL_FUNC(str_change_callback), (void *)((intptr_t) i)); gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (vbox_g), hbox, TRUE, TRUE, 0); } gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_win), vbox_g); hbox = gtk_hbox_new (FALSE, 1); gtk_widget_show (hbox); gtk_table_attach (GTK_TABLE (table), hbox, 0, 1, 255, 256, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); button1 = gtk_button_new_with_label ("OK"); gtk_widget_set_usize(button1, 100, -1); gtkwave_signal_connect(GTK_OBJECT (button1), "clicked", GTK_SIGNAL_FUNC(ok_callback), NULL); gtk_widget_show (button1); gtk_container_add (GTK_CONTAINER (hbox), button1); GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT); gtkwave_signal_connect_object (GTK_OBJECT (button1), "realize", (GtkSignalFunc) gtk_widget_grab_default, GTK_OBJECT (button1)); button2 = gtk_button_new_with_label ("Cancel"); gtk_widget_set_usize(button2, 100, -1); gtkwave_signal_connect(GTK_OBJECT (button2), "clicked", GTK_SIGNAL_FUNC(destroy_callback), NULL); GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT); gtk_widget_show (button2); gtk_container_add (GTK_CONTAINER (hbox), button2); gtk_container_add (GTK_CONTAINER (GLOBALS->window_markerbox_c_4), table); /* need this table to keep ok/cancel buttons from stretching! */ gtk_widget_show(GLOBALS->window_markerbox_c_4); wave_gtk_grab_add(GLOBALS->window_markerbox_c_4); } gtkwave-3.3.66/src/color.h0000664000076400007640000000424112341266475014670 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2011. * * 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. */ #include "globals.h" #ifndef WAVE_COLOR_H #define WAVE_COLOR_H #include #include #define WAVE_COLOR_CYCLE (-1) #define WAVE_COLOR_NORMAL (0) #define WAVE_COLOR_RED (1) #define WAVE_COLOR_ORANGE (2) #define WAVE_COLOR_YELLOW (3) #define WAVE_COLOR_GREEN (4) #define WAVE_COLOR_BLUE (5) #define WAVE_COLOR_INDIGO (6) #define WAVE_COLOR_VIOLET (7) #define WAVE_NUM_RAINBOW (7) #define WAVE_RAINBOW_RGB {0xFF0000, 0xFF7F00, 0xFFFF00, 0x00FF00, 0x0000FF, 0x6600FF, 0x9B00FF} #define WAVE_RAINBOW_INITIALIZER {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL} struct wave_gcmaster_t { GdkGC *gc_ltgray; GdkGC *gc_normal; GdkGC *gc_mdgray; GdkGC *gc_dkgray; GdkGC *gc_dkblue; GdkGC *gc_brkred; GdkGC *gc_ltblue; GdkGC *gc_gmstrd; GdkGC *gc_back_wavewindow_c_1; GdkGC *gc_baseline_wavewindow_c_1; GdkGC *gc_grid_wavewindow_c_1; GdkGC *gc_grid2_wavewindow_c_1; GdkGC *gc_time_wavewindow_c_1; GdkGC *gc_timeb_wavewindow_c_1; GdkGC *gc_value_wavewindow_c_1; GdkGC *gc_low_wavewindow_c_1; GdkGC *gc_high_wavewindow_c_1; GdkGC *gc_trans_wavewindow_c_1; GdkGC *gc_mid_wavewindow_c_1; GdkGC *gc_xfill_wavewindow_c_1; GdkGC *gc_x_wavewindow_c_1; GdkGC *gc_vbox_wavewindow_c_1; GdkGC *gc_vtrans_wavewindow_c_1; GdkGC *gc_mark_wavewindow_c_1; GdkGC *gc_umark_wavewindow_c_1; GdkGC *gc_0_wavewindow_c_1; GdkGC *gc_1_wavewindow_c_1; GdkGC *gc_ufill_wavewindow_c_1; GdkGC *gc_u_wavewindow_c_1; GdkGC *gc_wfill_wavewindow_c_1; GdkGC *gc_w_wavewindow_c_1; GdkGC *gc_dashfill_wavewindow_c_1; GdkGC *gc_dash_wavewindow_c_1; }; struct wave_gcchain_t { struct wave_gcchain_t*next; GdkGC *gc; }; GdkGC *alloc_color(GtkWidget *widget, int tuple, GdkGC *fallback); /* tuple is encoded as 32bit: --RRGGBB (>=0 is valid) */ void dealloc_all_gcs(void); /* when tab is destroyed */ void set_alternate_gcs(GdkGC *ctx, GdkGC *ctx_fill); /* when another t_color is encountered */ #endif gtkwave-3.3.66/src/twinwave.c0000664000076400007640000002435212372010236015400 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2006-2009. * * 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. */ #include #include #include #include #ifdef __MINGW32__ #include #undef MINGW_USE_XID #endif #include "wave_locale.h" #include #include #include #include "debug.h" #ifdef WAVE_USE_GTK2 static int use_embedded = 1; #endif #if !defined _MSC_VER && defined WAVE_USE_GTK2 static int plug_removed(GtkWidget *widget, gpointer data) { (void)widget; (void)data; static int cnt = 2; fprintf(stderr, "GtkPlug removed\n"); cnt--; if(cnt==0) { fprintf(stderr, "No GtkPlugs left, exiting.\n"); gtk_exit(0); } return(FALSE); /* TRUE would keep xsocket open */ } int quit_callback (GtkWidget *widget, gpointer data) { (void)widget; fprintf(stderr,"%s\n", (char *)data); gtk_exit(0); return(FALSE); } int main(int argc, char **argv) { struct gtkwave_dual_ipc_t *dual_ctx; char buf[257], buf2[257]; int shmid; GtkWidget *main_vbox, *mainwindow, *vpan; int i; int split_point = -1; #ifdef __MINGW32__ char mapName[65]; HANDLE hMapFile; #endif GtkWidget *xsocket[2] = { NULL, NULL }; WAVE_LOCALE_FIX if(!gtk_init_check(&argc, &argv)) { printf("Could not initialize GTK! Is DISPLAY env var/xhost set?\n\n"); exit(255); } #ifdef __CYGWIN__ fprintf(stderr, "TWINWAVE| If the viewer crashes with a Bad system call error,\n"); fprintf(stderr, "TWINWAVE| make sure that Cygserver is enabled.\n"); #endif for(i=0;i=0) { struct shmid_ds ds; dual_ctx = shmat(shmid, NULL, 0); if(dual_ctx) { memset(dual_ctx, 0, 2 * sizeof(struct gtkwave_dual_ipc_t)); memcpy(&dual_ctx[0].matchword, DUAL_MATCHWORD, 4); memcpy(&dual_ctx[1].matchword, DUAL_MATCHWORD, 4); #ifdef __linux__ shmctl(shmid, IPC_RMID, &ds); /* mark for destroy */ #endif if(fork()) { if(fork()) { struct timeval tv; for(;;) { tv.tv_sec = 0; tv.tv_usec = 1000000 / 5; select(0, NULL, NULL, NULL, &tv); while (gtk_events_pending()) gtk_main_iteration(); if((!dual_ctx[0].viewer_is_initialized)&&(dual_ctx[1].viewer_is_initialized)) { gtk_window_set_title(GTK_WINDOW(mainwindow), "TwinWave Waiting on Viewer #1"); } else if((dual_ctx[0].viewer_is_initialized)&&(!dual_ctx[1].viewer_is_initialized)) { gtk_window_set_title(GTK_WINDOW(mainwindow), "TwinWave Waiting on Viewer #2"); } else if((dual_ctx[0].viewer_is_initialized)&&(dual_ctx[1].viewer_is_initialized)) { gtk_window_set_title(GTK_WINDOW(mainwindow), "TwinWave"); break; } } #ifndef __linux__ while (gtk_events_pending()) gtk_main_iteration(); sleep(2); shmctl(shmid, IPC_RMID, &ds); /* mark for destroy */ #endif if(use_embedded) { gtk_main(); } } else { int n_items = split_point + 5; char **arglist = calloc(n_items, sizeof(char *)); sprintf(buf, "0+%08X", shmid); if(use_embedded) { sprintf(buf2, "%x", gtk_socket_get_id (GTK_SOCKET(xsocket[0]))); } else { sprintf(buf2, "%x", 0); } arglist[0] = "gtkwave"; arglist[1] = "-D"; arglist[2] = buf; arglist[3] = "-X"; arglist[4] = buf2; for(i=1;i #include #include "debug.h" #include "symbol.h" #include "currenttime.h" /* Add some text to our text widget - this is a callback that is invoked when our window is realized. We could also force our window to be realized with gtk_widget_realize, but it would have to be part of a hierarchy first */ void help_text(char *str) { #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) gtk_text_buffer_insert (GTK_TEXT_VIEW (GLOBALS->text_help_c_1)->buffer, &GLOBALS->iter_help_c_1, str, -1); #else gtk_text_insert (GTK_TEXT (GLOBALS->text_help_c_1), NULL, &GLOBALS->text_help_c_1->style->black, NULL, str, -1); #endif gdk_window_raise(GLOBALS->window_help_c_2->window); } void help_text_bold(char *str) { #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) gtk_text_buffer_insert_with_tags (GTK_TEXT_VIEW (GLOBALS->text_help_c_1)->buffer, &GLOBALS->iter_help_c_1, str, -1, GLOBALS->bold_tag_help_c_1, NULL); #else gtk_text_insert (GTK_TEXT (GLOBALS->text_help_c_1), NULL, &GLOBALS->text_help_c_1->style->fg[GTK_STATE_SELECTED], &GLOBALS->text_help_c_1->style->bg[GTK_STATE_SELECTED], str, -1); #endif gdk_window_raise(GLOBALS->window_help_c_2->window); } static void help_realize_text (GtkWidget *text, gpointer data) { (void)text; (void)data; if(GLOBALS->loaded_file_type == MISSING_FILE) { help_text("To load a dumpfile into the viewer, either drag the icon" " for it from the desktop or use the appropriate option(s)" " from the "); help_text_bold("File"); help_text(" menu.\n\n"); } help_text("Click on any menu item or button that corresponds to a menu item" " for its full description. Pressing a hotkey for a menu item" " is also allowed."); } /* Create a scrolled text area that displays a "message" */ static GtkWidget *create_help_text (void) { GtkWidget *table; /* Create a table to hold the text widget and scrollbars */ table = gtk_table_new (1, 16, FALSE); /* Put a text widget in the upper left hand corner. Note the use of * GTK_SHRINK in the y direction */ #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) GLOBALS->text_help_c_1 = gtk_text_view_new (); gtk_text_view_set_editable (GTK_TEXT_VIEW(GLOBALS->text_help_c_1), FALSE); gtk_text_buffer_get_start_iter (gtk_text_view_get_buffer(GTK_TEXT_VIEW (GLOBALS->text_help_c_1)), &GLOBALS->iter_help_c_1); GLOBALS->bold_tag_help_c_1 = gtk_text_buffer_create_tag (GTK_TEXT_VIEW (GLOBALS->text_help_c_1)->buffer, "bold", "weight", PANGO_WEIGHT_BOLD, NULL); #else GLOBALS->text_help_c_1 = gtk_text_new (NULL, NULL); gtk_text_set_editable(GTK_TEXT(GLOBALS->text_help_c_1), FALSE); #endif gtk_table_attach (GTK_TABLE (table), GLOBALS->text_help_c_1, 0, 14, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_SHRINK | GTK_EXPAND, 0, 0); gtk_widget_set_usize(GTK_WIDGET(GLOBALS->text_help_c_1), 100, 50); gtk_widget_show (GLOBALS->text_help_c_1); /* And a VScrollbar in the upper right */ #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) { GtkTextViewClass *tc = (GtkTextViewClass*)GTK_OBJECT_GET_CLASS(GTK_OBJECT(GLOBALS->text_help_c_1)); tc->set_scroll_adjustments(GTK_TEXT_VIEW (GLOBALS->text_help_c_1), NULL, NULL); GLOBALS->vscrollbar_help_c_1 = gtk_vscrollbar_new (GTK_TEXT_VIEW (GLOBALS->text_help_c_1)->vadjustment); } #else GLOBALS->vscrollbar_help_c_1 = gtk_vscrollbar_new (GTK_TEXT (GLOBALS->text_help_c_1)->vadj); #endif gtk_table_attach (GTK_TABLE (table), GLOBALS->vscrollbar_help_c_1, 15, 16, 0, 1,GTK_FILL, GTK_FILL | GTK_SHRINK | GTK_EXPAND, 0, 0); gtk_widget_show (GLOBALS->vscrollbar_help_c_1); /* Add a handler to put a message in the text widget when it is realized */ gtkwave_signal_connect (GTK_OBJECT (GLOBALS->text_help_c_1), "realize", GTK_SIGNAL_FUNC (help_realize_text), NULL); #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(GLOBALS->text_help_c_1), GTK_WRAP_WORD); #else gtk_text_set_word_wrap(GTK_TEXT(GLOBALS->text_help_c_1), TRUE); #endif return(table); } /***********************************************************************************/ static void ok_callback(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; GLOBALS->helpbox_is_active=0; DEBUG(printf("OK\n")); gtk_widget_destroy(GLOBALS->window_help_c_2); GLOBALS->window_help_c_2 = NULL; } void helpbox(char *title, int width, char *default_text) { GtkWidget *vbox, *hbox; GtkWidget *button1; GtkWidget *label, *separator; GtkWidget *ctext; /* fix problem where ungrab doesn't occur if button pressed + simultaneous accelerator key occurs */ if(GLOBALS->in_button_press_wavewindow_c_1) { gdk_pointer_ungrab(GDK_CURRENT_TIME); } if(GLOBALS->helpbox_is_active) return; GLOBALS->helpbox_is_active=1; /* create a new nonmodal window */ GLOBALS->window_help_c_2 = gtk_window_new(GLOBALS->disable_window_manager ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL); install_focus_cb(GLOBALS->window_help_c_2, ((char *)&GLOBALS->window_help_c_2) - ((char *)GLOBALS)); gtk_widget_set_usize( GTK_WIDGET (GLOBALS->window_help_c_2), width, 400); gtk_window_set_title(GTK_WINDOW (GLOBALS->window_help_c_2), title); gtkwave_signal_connect(GTK_OBJECT (GLOBALS->window_help_c_2), "delete_event",(GtkSignalFunc) ok_callback, NULL); vbox = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (GLOBALS->window_help_c_2), vbox); gtk_widget_show (vbox); label=gtk_label_new(default_text); gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); gtk_widget_show (label); separator = gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, TRUE, 0); gtk_widget_show (separator); ctext=create_help_text(); gtk_box_pack_start (GTK_BOX (vbox), ctext, TRUE, TRUE, 0); gtk_widget_show (ctext); separator = gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, TRUE, 0); gtk_widget_show (separator); hbox = gtk_hbox_new (FALSE, 1); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_widget_show (hbox); button1 = gtk_button_new_with_label ("Close Help"); gtk_widget_set_usize(button1, 100, -1); gtkwave_signal_connect(GTK_OBJECT (button1), "clicked", GTK_SIGNAL_FUNC(ok_callback), NULL); gtk_widget_show (button1); gtk_container_add (GTK_CONTAINER (hbox), button1); GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT); gtkwave_signal_connect_object (GTK_OBJECT (button1), "realize", (GtkSignalFunc) gtk_widget_grab_default, GTK_OBJECT (button1)); gtk_widget_show(GLOBALS->window_help_c_2); } gtkwave-3.3.66/src/wavewindow.c0000664000076400007640000041442312411342727015737 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2012. * * 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. */ #include #include "globals.h" #include "gtk12compat.h" #include "currenttime.h" #include "pixmaps.h" #include "symbol.h" #include "bsearch.h" #include "color.h" #include "rc.h" #include "strace.h" #include "debug.h" #include "main.h" #if !defined _ISOC99_SOURCE #define _ISOC99_SOURCE 1 #endif #include static void rendertimebar(void); static void draw_hptr_trace(Trptr t, hptr h, int which, int dodraw, int kill_grid); static void draw_hptr_trace_vector(Trptr t, hptr h, int which); static void draw_vptr_trace(Trptr t, vptr v, int which); static void rendertraces(void); static void rendertimes(void); static const GdkModifierType bmask[4]= {0, GDK_BUTTON1_MASK, 0, GDK_BUTTON3_MASK }; /* button 1, 3 press/rel encodings */ static const GdkEventMask m_bmask[4]= {0, GDK_BUTTON1_MOTION_MASK, 0, GDK_BUTTON3_MOTION_MASK }; /* button 1, 3 motion encodings */ /******************************************************************/ static void update_dual(void) { if(GLOBALS->dual_ctx && !GLOBALS->dual_race_lock) { GLOBALS->dual_ctx[GLOBALS->dual_id].zoom = GLOBALS->tims.zoom; GLOBALS->dual_ctx[GLOBALS->dual_id].marker = GLOBALS->tims.marker; GLOBALS->dual_ctx[GLOBALS->dual_id].baseline = GLOBALS->tims.baseline; GLOBALS->dual_ctx[GLOBALS->dual_id].left_margin_time = GLOBALS->tims.start; GLOBALS->dual_ctx[GLOBALS->dual_id].use_new_times = 1; } } /******************************************************************/ #ifdef WAVE_USE_GTK2 static void (*draw_slider_p) (GtkStyle *style, GdkWindow *window, GtkStateType state_type, GtkShadowType shadow_type, GdkRectangle *area, GtkWidget *widget, const gchar *detail, gint x, gint y, gint width, gint height, GtkOrientation orientation) = NULL; /* This is intended to be global...only needed once per toolkit */ static void draw_slider (GtkStyle *style, GdkWindow *window, GtkStateType state_type, GtkShadowType shadow_type, GdkRectangle *area, GtkWidget *widget, const gchar *detail, gint x, gint y, gint width, gint height, GtkOrientation orientation) { if((GLOBALS)&&(widget == GLOBALS->hscroll_wavewindow_c_2)) { GLOBALS->str_wid_x = x - widget->allocation.x; GLOBALS->str_wid_width = width; GLOBALS->str_wid_bigw = widget->allocation.width; GLOBALS->str_wid_height = height; } draw_slider_p(style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, orientation); } static gint slider_bpr(GtkWidget *widget, GdkEventButton *event) { (void)widget; int xi = event->x; int xl = GLOBALS->str_wid_x; int xr = GLOBALS->str_wid_x + GLOBALS->str_wid_width; if((xi > (xr-8)) && (xi < (xr+8))) { GLOBALS->str_wid_state = 1; return(TRUE); } else if((xi < (xl+8)) && (xi > (xl-8))) { GLOBALS->str_wid_state = -1; return(TRUE); } return(FALSE); } static gint slider_brr(GtkWidget *widget, GdkEventButton *event) { (void)widget; (void)event; GLOBALS->str_wid_state = 0; return(FALSE); } static gint slider_mnr(GtkWidget *widget, GdkEventMotion *event) { (void)widget; #ifndef WAVE_USE_GTK2 gdouble x, y; #endif GdkModifierType state; gdouble my_x, xmax, ratio; TimeType l_margin, r_margin; #ifdef WAVE_USE_GTK2 gint xi, yi; #endif int dummy_x, dummy_y; get_window_xypos(&dummy_x, &dummy_y); if(event->is_hint) { WAVE_GDK_GET_POINTER(event->window, &x, &y, &xi, &yi, &state); #ifndef WAVE_USE_GTK2 WAVE_GDK_GET_POINTER_COPY; #endif } else { /* x = event->x; */ /* scan-build */ /* y = event->y; */ /* scan-build */ state = event->state; } if((GLOBALS->str_wid_state)&&(!(state & (GDK_BUTTON1_MASK|GDK_BUTTON3_MASK)))) { GLOBALS->str_wid_state = 0; } if(GLOBALS->str_wid_state == 1) { my_x = event->x - GLOBALS->str_wid_height; xmax = GLOBALS->str_wid_bigw - (2*GLOBALS->str_wid_height) - GLOBALS->str_wid_slider; if(xmax > 1.0) { ratio = my_x/xmax; r_margin = (gdouble)(GLOBALS->tims.last - GLOBALS->tims.first) * ratio + GLOBALS->tims.first; if((r_margin > GLOBALS->tims.start) && (r_margin <= GLOBALS->tims.last)) { service_dragzoom(GLOBALS->tims.start, r_margin); } return(TRUE); } } else if(GLOBALS->str_wid_state == -1) { my_x = event->x - GLOBALS->str_wid_height; xmax = GLOBALS->str_wid_bigw - (2*GLOBALS->str_wid_height) - GLOBALS->str_wid_slider; if(xmax > 1.0) { ratio = my_x/xmax; l_margin = (gdouble)(GLOBALS->tims.last - GLOBALS->tims.first) * ratio + GLOBALS->tims.first; r_margin = GLOBALS->tims.end; if((l_margin >= GLOBALS->tims.first) && (l_margin < GLOBALS->tims.end)) { if(r_margin > GLOBALS->tims.last) r_margin = GLOBALS->tims.last; service_dragzoom(l_margin, r_margin); } return(TRUE); } } return(FALSE); } #endif /******************************************************************/ /* * gtk_draw_line() acceleration for win32 by doing draw combining * now always enabled. if there need to be an exact correlation * between this and the printed data, this needs to be disabled. */ #if 1 #define WAVE_SEG_BUF_CNT 1024 static int seg_trans_cnt = 0, seg_low_cnt = 0, seg_high_cnt = 0, seg_mid_cnt = 0, seg_x_cnt = 0, seg_vtrans_cnt = 0, seg_0_cnt = 0, seg_1_cnt = 0, seg_vbox_cnt = 0; static GdkSegment seg_trans[WAVE_SEG_BUF_CNT], seg_low[WAVE_SEG_BUF_CNT], seg_high[WAVE_SEG_BUF_CNT], seg_mid[WAVE_SEG_BUF_CNT], seg_x[WAVE_SEG_BUF_CNT], seg_vtrans[WAVE_SEG_BUF_CNT], seg_0[WAVE_SEG_BUF_CNT], seg_1[WAVE_SEG_BUF_CNT], seg_vbox[WAVE_SEG_BUF_CNT]; static void wave_gdk_draw_line(GdkDrawable *drawable, GdkGC *gc, gint _x1, gint _y1, gint _x2, gint _y2) { GdkSegment *seg; int *seg_cnt; if(gc==GLOBALS->gc.gc_trans_wavewindow_c_1) { seg = seg_trans; seg_cnt = &seg_trans_cnt; } else if(gc==GLOBALS->gc.gc_low_wavewindow_c_1) { seg = seg_low; seg_cnt = &seg_low_cnt; } else if(gc==GLOBALS->gc.gc_high_wavewindow_c_1) { seg = seg_high; seg_cnt = &seg_high_cnt; } else if(gc==GLOBALS->gc.gc_mid_wavewindow_c_1) { seg = seg_mid; seg_cnt = &seg_mid_cnt; } else if(gc == GLOBALS->gc.gc_x_wavewindow_c_1) { seg = seg_x; seg_cnt = &seg_x_cnt; } else if(gc == GLOBALS->gc.gc_vtrans_wavewindow_c_1){ seg = seg_vtrans; seg_cnt = &seg_vtrans_cnt; } else if(gc == GLOBALS->gc.gc_0_wavewindow_c_1) { seg = seg_0; seg_cnt = &seg_0_cnt; } else if(gc == GLOBALS->gc.gc_1_wavewindow_c_1) { seg = seg_1; seg_cnt = &seg_1_cnt; } else if(gc == GLOBALS->gc.gc_vbox_wavewindow_c_1){ seg = seg_vbox; seg_cnt = &seg_vbox_cnt; } else { gdk_draw_line(drawable, gc, _x1, _y1, _x2, _y2); return; } seg[*seg_cnt].x1 = _x1; seg[*seg_cnt].y1 = _y1; seg[*seg_cnt].x2 = _x2; seg[*seg_cnt].y2 = _y2; (*seg_cnt)++; if(*seg_cnt == WAVE_SEG_BUF_CNT) { gdk_draw_segments(drawable, gc, seg, *seg_cnt); *seg_cnt = 0; } } static void wave_gdk_draw_line_flush(GdkDrawable *drawable) { if(seg_vtrans_cnt) { gdk_draw_segments (drawable, GLOBALS->gc.gc_vtrans_wavewindow_c_1, seg_vtrans, seg_vtrans_cnt); seg_vtrans_cnt = 0; } if(seg_mid_cnt) { gdk_draw_segments(drawable, GLOBALS->gc.gc_mid_wavewindow_c_1, seg_mid, seg_mid_cnt); seg_mid_cnt = 0; } if(seg_high_cnt) { gdk_draw_segments(drawable, GLOBALS->gc.gc_high_wavewindow_c_1, seg_high, seg_high_cnt); seg_high_cnt = 0; } if(seg_low_cnt) { gdk_draw_segments(drawable, GLOBALS->gc.gc_low_wavewindow_c_1, seg_low, seg_low_cnt); seg_low_cnt = 0; } if(seg_trans_cnt) { gdk_draw_segments(drawable, GLOBALS->gc.gc_trans_wavewindow_c_1, seg_trans, seg_trans_cnt); seg_trans_cnt = 0; } if(seg_0_cnt) { gdk_draw_segments (drawable, GLOBALS->gc.gc_0_wavewindow_c_1, seg_0, seg_0_cnt); seg_0_cnt = 0; } if(seg_1_cnt) { gdk_draw_segments (drawable, GLOBALS->gc.gc_1_wavewindow_c_1, seg_1, seg_1_cnt); seg_1_cnt = 0; } /* place x down here to propagate them over low/high transitions */ if(seg_x_cnt) { gdk_draw_segments (drawable, GLOBALS->gc.gc_x_wavewindow_c_1, seg_x, seg_x_cnt); seg_x_cnt = 0; } if(seg_vbox_cnt) { gdk_draw_segments (drawable, GLOBALS->gc.gc_vbox_wavewindow_c_1, seg_vbox, seg_vbox_cnt); seg_vbox_cnt = 0; } } #else /* completely unnecessary for linux ... unless there are extremely dense traces */ #define wave_gdk_draw_line(a,b,c,d,e,f) gdk_draw_line(a,b,c,d,e,f) #define wave_gdk_draw_line_flush(x) #endif /******************************************************************/ /* * aldec-like "snap" feature... */ TimeType cook_markertime(TimeType marker, gint x, gint y) { int i, num_traces_displayable; Trptr t = NULL; TimeType lft, rgh; char lftinv, rghinv; gdouble xlft, xrgh; gdouble xlftd, xrghd; TimeType closest_named = MAX_HISTENT_TIME; int closest_which = -1; gint xold = x, yold = y; TraceEnt t_trans; if(!GLOBALS->cursor_snap) return(marker); /* potential snapping to a named marker time */ for(i=0;inamed_markers[i] != -1) { TimeType dlt; if((GLOBALS->named_markers[i]>=GLOBALS->tims.start)&&(GLOBALS->named_markers[i]<=GLOBALS->tims.end)&&(GLOBALS->named_markers[i]<=GLOBALS->tims.last)) { if(marker < GLOBALS->named_markers[i]) { dlt = GLOBALS->named_markers[i] - marker; } else { dlt = marker - GLOBALS->named_markers[i]; } if(dlt < closest_named) { closest_named = dlt; closest_which = i; } } } } num_traces_displayable=GLOBALS->wavearea->allocation.height/(GLOBALS->fontheight); num_traces_displayable--; /* for the time trace that is always there */ y-=GLOBALS->fontheight; if(y<0) y=0; y/=GLOBALS->fontheight; /* y now indicates the trace in question */ if(y>num_traces_displayable) y=num_traces_displayable; t=GLOBALS->topmost_trace; for(i=0;iflags&(/*TR_BLANK|*/TR_EXCLUDE))) /* TR_BLANK removed because of transaction handling below... */ { t = NULL; goto bot; } if(t->flags & (TR_BLANK|TR_ANALOG_BLANK_STRETCH)) /* seek to real xact trace if present... */ { Trptr tscan = t; int bcnt = 0; while((tscan) && (tscan = GivePrevTrace(tscan))) { if(!(tscan->flags & (TR_BLANK|TR_ANALOG_BLANK_STRETCH))) { if(tscan->flags & TR_TTRANSLATED) { break; /* found it */ } else { tscan = NULL; } } else { bcnt++; /* bcnt is number of blank traces */ } } if((tscan)&&(tscan->vector)) { bvptr bv = tscan->n.vec; do { bv = bv->transaction_chain; /* correlate to blank trace */ } while(bv && (bcnt--)); if(bv) { memcpy(&t_trans, tscan, sizeof(TraceEnt)); /* substitute into a synthetic trace */ t_trans.n.vec = bv; t_trans.vector = 1; t_trans.name = bv->bvname; if(GLOBALS->hier_max_level) t_trans.name = hier_extract(t_trans.name, GLOBALS->hier_max_level); t = &t_trans; goto process_trace; } } } if((t->flags&TR_BLANK)) { t = NULL; goto bot; } if(t->flags & TR_ANALOG_BLANK_STRETCH) /* seek to real analog trace if present... */ { while((t) && (t = GivePrevTrace(t))) { if(!(t->flags & TR_ANALOG_BLANK_STRETCH)) { if(t->flags & TR_ANALOGMASK) { break; /* found it */ } else { t = NULL; } } } } if(!t) goto bot; process_trace: if(t->vector) { vptr v = bsearch_vector(t->n.vec, marker - t->shift); vptr v2 = v ? v->next : NULL; if((!v)||(!v2)) goto bot; /* should never happen */ lft = v->time; rgh = v2->time; } else { hptr h = bsearch_node(t->n.nd, marker - t->shift); hptr h2 = h ? h->next : NULL; if((!h)||(!h2)) goto bot; /* should never happen */ lft = h->time; rgh = h2->time; } lftinv = (lft < (GLOBALS->tims.start - t->shift))||(lft >= (GLOBALS->tims.end - t->shift))||(lft >= (GLOBALS->tims.last - t->shift)); rghinv = (rgh < (GLOBALS->tims.start - t->shift))||(rgh >= (GLOBALS->tims.end - t->shift))||(rgh >= (GLOBALS->tims.last - t->shift)); xlft = (lft + t->shift - GLOBALS->tims.start) * GLOBALS->pxns; xrgh = (rgh + t->shift - GLOBALS->tims.start) * GLOBALS->pxns; xlftd = xlft - x; if(xlftd<(gdouble)0.0) xlftd = ((gdouble)0.0) - xlftd; xrghd = xrgh - x; if(xrghd<(gdouble)0.0) xrghd = ((gdouble)0.0) - xrghd; if(xlftd<=xrghd) { if((!lftinv)&&(xlftd<=GLOBALS->cursor_snap)) { if(closest_which >= 0) { if((closest_named * GLOBALS->pxns) < xlftd) { marker = GLOBALS->named_markers[closest_which]; goto xit; } } marker = lft + t->shift; goto xit; } } else { if((!rghinv)&&(xrghd<=GLOBALS->cursor_snap)) { if(closest_which >= 0) { if((closest_named * GLOBALS->pxns) < xrghd) { marker = GLOBALS->named_markers[closest_which]; goto xit; } } marker = rgh + t->shift; goto xit; } } bot: if(closest_which >= 0) { if((closest_named * GLOBALS->pxns) <= GLOBALS->cursor_snap) { marker = GLOBALS->named_markers[closest_which]; } } xit: GLOBALS->mouseover_counter = -1; move_mouseover(t, xold, yold, marker); return(marker); } static void render_individual_named_marker(int i, GdkGC *gc, int blackout) { gdouble pixstep; gint xl, y; TimeType t; if((t=GLOBALS->named_markers[i])!=-1) { if((t>=GLOBALS->tims.start)&&(t<=GLOBALS->tims.last) &&(t<=GLOBALS->tims.end)) { /* this needs to be here rather than outside the loop as gcc does some optimizations that cause it to calculate slightly different from the marker if it's not here */ pixstep=((gdouble)GLOBALS->nsperframe)/((gdouble)GLOBALS->pixelsperframe); xl=((gdouble)(t-GLOBALS->tims.start))/pixstep; /* snap to integer */ if((xl>=0)&&(xlwavewidth)) { char nbuff[16]; make_bijective_marker_id_string(nbuff, i); for(y=GLOBALS->fontheight-1;y<=GLOBALS->waveheight-1;y+=8) { gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gc, xl, y, xl, y+5); } if((!GLOBALS->marker_names[i])||(!GLOBALS->marker_names[i][0])) { font_engine_draw_string(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->wavefont_smaller, gc, xl-(font_engine_string_measure(GLOBALS->wavefont_smaller, nbuff)>>1), GLOBALS->fontheight-2, nbuff); } else { int width = font_engine_string_measure(GLOBALS->wavefont_smaller, GLOBALS->marker_names[i]); if(blackout) /* blackout background so text is legible if overlaid with other marker labels */ { gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_timeb_wavewindow_c_1, TRUE, xl-(width>>1), GLOBALS->fontheight-2-GLOBALS->wavefont_smaller->ascent, width, GLOBALS->wavefont_smaller->ascent + GLOBALS->wavefont_smaller->descent); } font_engine_draw_string(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->wavefont_smaller, gc, xl-(width>>1), GLOBALS->fontheight-2, GLOBALS->marker_names[i]); } } } } } static void draw_named_markers(void) { int i; if(!GLOBALS->wavepixmap_wavewindow_c_1) return; for(i=0;inamed_marker_lock_idx) { render_individual_named_marker(i, GLOBALS->gc.gc_mark_wavewindow_c_1, 0); } } if(GLOBALS->named_marker_lock_idx >= 0) { render_individual_named_marker(GLOBALS->named_marker_lock_idx, GLOBALS->gc.gc_umark_wavewindow_c_1, 1); } } static void sync_marker(void) { if((GLOBALS->tims.prevmarker==-1)&&(GLOBALS->tims.marker!=-1)) { GLOBALS->signalwindow_width_dirty=1; } else if((GLOBALS->tims.marker==-1)&&(GLOBALS->tims.prevmarker!=-1)) { GLOBALS->signalwindow_width_dirty=1; } GLOBALS->tims.prevmarker=GLOBALS->tims.marker; } static void draw_marker(void) { gdouble pixstep; gint xl; if(!GLOBALS->wavearea->window) return; GLOBALS->m1x_wavewindow_c_1=GLOBALS->m2x_wavewindow_c_1=-1; if(GLOBALS->tims.baseline>=0) { if((GLOBALS->tims.baseline>=GLOBALS->tims.start)&&(GLOBALS->tims.baseline<=GLOBALS->tims.last) &&(GLOBALS->tims.baseline<=GLOBALS->tims.end)) { pixstep=((gdouble)GLOBALS->nsperframe)/((gdouble)GLOBALS->pixelsperframe); xl=((gdouble)(GLOBALS->tims.baseline-GLOBALS->tims.start))/pixstep; /* snap to integer */ if((xl>=0)&&(xlwavewidth)) { gdk_draw_line(GLOBALS->wavearea->window,GLOBALS->gc.gc_baseline_wavewindow_c_1,xl, GLOBALS->fontheight-1, xl, GLOBALS->waveheight-1); } } } if(GLOBALS->tims.marker>=0) { if((GLOBALS->tims.marker>=GLOBALS->tims.start)&&(GLOBALS->tims.marker<=GLOBALS->tims.last) &&(GLOBALS->tims.marker<=GLOBALS->tims.end)) { pixstep=((gdouble)GLOBALS->nsperframe)/((gdouble)GLOBALS->pixelsperframe); xl=((gdouble)(GLOBALS->tims.marker-GLOBALS->tims.start))/pixstep; /* snap to integer */ if((xl>=0)&&(xlwavewidth)) { gdk_draw_line(GLOBALS->wavearea->window,GLOBALS->gc.gc_umark_wavewindow_c_1,xl, GLOBALS->fontheight-1, xl, GLOBALS->waveheight-1); GLOBALS->m1x_wavewindow_c_1=xl; } } } if((GLOBALS->enable_ghost_marker)&&(GLOBALS->in_button_press_wavewindow_c_1)&&(GLOBALS->tims.lmbcache>=0)) { if((GLOBALS->tims.lmbcache>=GLOBALS->tims.start)&&(GLOBALS->tims.lmbcache<=GLOBALS->tims.last) &&(GLOBALS->tims.lmbcache<=GLOBALS->tims.end)) { pixstep=((gdouble)GLOBALS->nsperframe)/((gdouble)GLOBALS->pixelsperframe); xl=((gdouble)(GLOBALS->tims.lmbcache-GLOBALS->tims.start))/pixstep; /* snap to integer */ if((xl>=0)&&(xlwavewidth)) { gdk_draw_line(GLOBALS->wavearea->window,GLOBALS->gc.gc_umark_wavewindow_c_1,xl, GLOBALS->fontheight-1, xl, GLOBALS->waveheight-1); GLOBALS->m2x_wavewindow_c_1=xl; } } } if(GLOBALS->m1x_wavewindow_c_1>GLOBALS->m2x_wavewindow_c_1) /* ensure m1x <= m2x for partitioned refresh */ { gint t; t=GLOBALS->m1x_wavewindow_c_1; GLOBALS->m1x_wavewindow_c_1=GLOBALS->m2x_wavewindow_c_1; GLOBALS->m2x_wavewindow_c_1=t; } if(GLOBALS->m1x_wavewindow_c_1==-1) GLOBALS->m1x_wavewindow_c_1=GLOBALS->m2x_wavewindow_c_1; /* make both markers same if no ghost marker or v.v. */ update_dual(); } static void draw_marker_partitions(void) { draw_marker(); if(GLOBALS->m1x_wavewindow_c_1==GLOBALS->m2x_wavewindow_c_1) { gdk_draw_pixmap(GLOBALS->wavearea->window, GLOBALS->wavearea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->wavearea)],GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->m1x_wavewindow_c_1, 0, GLOBALS->m1x_wavewindow_c_1, 0, 1, GLOBALS->fontheight-2); if(GLOBALS->m1x_wavewindow_c_1<0) { gdk_draw_pixmap(GLOBALS->wavearea->window, GLOBALS->wavearea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->wavearea)],GLOBALS->wavepixmap_wavewindow_c_1, 0, 0, 0, 0, GLOBALS->wavewidth, GLOBALS->waveheight); } else { if(GLOBALS->m1x_wavewindow_c_1==0) { gdk_draw_pixmap(GLOBALS->wavearea->window, GLOBALS->wavearea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->wavearea)],GLOBALS->wavepixmap_wavewindow_c_1, 1, 0, 1, 0, GLOBALS->wavewidth-1, GLOBALS->waveheight); } else if(GLOBALS->m1x_wavewindow_c_1==GLOBALS->wavewidth-1) { gdk_draw_pixmap(GLOBALS->wavearea->window, GLOBALS->wavearea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->wavearea)],GLOBALS->wavepixmap_wavewindow_c_1, 0, 0, 0, 0, GLOBALS->wavewidth-1, GLOBALS->waveheight); } else { gdk_draw_pixmap(GLOBALS->wavearea->window, GLOBALS->wavearea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->wavearea)],GLOBALS->wavepixmap_wavewindow_c_1, 0, 0, 0, 0, GLOBALS->m1x_wavewindow_c_1, GLOBALS->waveheight); gdk_draw_pixmap(GLOBALS->wavearea->window, GLOBALS->wavearea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->wavearea)],GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->m1x_wavewindow_c_1+1, 0, GLOBALS->m1x_wavewindow_c_1+1, 0, GLOBALS->wavewidth-GLOBALS->m1x_wavewindow_c_1-1, GLOBALS->waveheight); } } } else { gdk_draw_pixmap(GLOBALS->wavearea->window, GLOBALS->wavearea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->wavearea)],GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->m1x_wavewindow_c_1, 0, GLOBALS->m1x_wavewindow_c_1, 0, 1, GLOBALS->fontheight-2); gdk_draw_pixmap(GLOBALS->wavearea->window, GLOBALS->wavearea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->wavearea)],GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->m2x_wavewindow_c_1, 0, GLOBALS->m2x_wavewindow_c_1, 0, 1, GLOBALS->fontheight-2); if(GLOBALS->m1x_wavewindow_c_1>0) { gdk_draw_pixmap(GLOBALS->wavearea->window, GLOBALS->wavearea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->wavearea)],GLOBALS->wavepixmap_wavewindow_c_1, 0, 0, 0, 0, GLOBALS->m1x_wavewindow_c_1, GLOBALS->waveheight); } if(GLOBALS->m2x_wavewindow_c_1-GLOBALS->m1x_wavewindow_c_1>1) { gdk_draw_pixmap(GLOBALS->wavearea->window, GLOBALS->wavearea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->wavearea)],GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->m1x_wavewindow_c_1+1, 0, GLOBALS->m1x_wavewindow_c_1+1, 0, GLOBALS->m2x_wavewindow_c_1-GLOBALS->m1x_wavewindow_c_1-1, GLOBALS->waveheight); } if(GLOBALS->m2x_wavewindow_c_1!=GLOBALS->wavewidth-1) { gdk_draw_pixmap(GLOBALS->wavearea->window, GLOBALS->wavearea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->wavearea)],GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->m2x_wavewindow_c_1+1, 0, GLOBALS->m2x_wavewindow_c_1+1, 0, GLOBALS->wavewidth-GLOBALS->m2x_wavewindow_c_1-1, GLOBALS->waveheight); } } /* keep baseline from getting obliterated */ #ifndef WAVE_DOUBLE_LINE_WIDTH_MODE if(GLOBALS->tims.baseline>=0) #endif { draw_marker(); } } static void renderblackout(void) { gfloat pageinc; TimeType lhs, rhs, lclip, rclip; struct blackout_region_t *bt = GLOBALS->blackout_regions; if(bt) { pageinc=(gfloat)(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx); lhs = GLOBALS->tims.start; rhs = pageinc + lhs; while(bt) { if((bt->bend < lhs) || (bt->bstart > rhs)) { /* nothing, out of bounds */ } else { lclip = bt->bstart; rclip = bt->bend; if(lclip < lhs) lclip = lhs; else if (lclip > rhs) lclip = rhs; if(rclip < lhs) rclip = lhs; lclip -= lhs; rclip -= lhs; if(rclip>((GLOBALS->wavewidth+1)*GLOBALS->nspx)) rclip = (GLOBALS->wavewidth+1)*(GLOBALS->nspx); gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_xfill_wavewindow_c_1, TRUE, (((gdouble)lclip)*GLOBALS->pxns), GLOBALS->fontheight,(((gdouble)(rclip-lclip))*GLOBALS->pxns), GLOBALS->waveheight-GLOBALS->fontheight); } bt=bt->next; } } } static void service_hslider(GtkWidget *text, gpointer data) { (void)text; (void)data; DEBUG(printf("Wave HSlider Moved\n")); if((GLOBALS->wavepixmap_wavewindow_c_1)&&(GLOBALS->wavewidth>1)) { GtkAdjustment *hadj; hadj=GTK_ADJUSTMENT(GLOBALS->wave_hslider); if(!GLOBALS->tims.timecache) { GLOBALS->tims.start=time_trunc(hadj->value); } else { GLOBALS->tims.start=time_trunc(GLOBALS->tims.timecache); GLOBALS->tims.timecache=0; /* reset */ } if(GLOBALS->tims.starttims.first) GLOBALS->tims.start=GLOBALS->tims.first; else if(GLOBALS->tims.start>GLOBALS->tims.last) GLOBALS->tims.start=GLOBALS->tims.last; GLOBALS->tims.laststart=GLOBALS->tims.start; gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_back_wavewindow_c_1, TRUE, 0, 0,GLOBALS->wavewidth, GLOBALS->waveheight); rendertimebar(); } } static void service_vslider(GtkWidget *text, gpointer data) { (void)text; (void)data; GtkAdjustment *sadj, *hadj; int trtarget; int xsrc; if(GLOBALS->signalpixmap) { hadj=GTK_ADJUSTMENT(GLOBALS->signal_hslider); sadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider); xsrc=(gint)hadj->value; trtarget=(int)(sadj->value); DEBUG(printf("Wave VSlider Moved to %d\n",trtarget)); gdk_draw_rectangle(GLOBALS->signalpixmap, GLOBALS->gc.gc_ltgray, TRUE, 0, 0, GLOBALS->signal_fill_width, GLOBALS->signalarea->allocation.height); sync_marker(); RenderSigs(trtarget,(GLOBALS->old_wvalue==sadj->value)?0:1); GLOBALS->old_wvalue=sadj->value; draw_named_markers(); if(GLOBALS->signalarea_has_focus) { gdk_draw_pixmap(GLOBALS->signalarea->window, GLOBALS->signalarea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->signalarea)], GLOBALS->signalpixmap, xsrc+1, 0+1, 0+1, 0+1, GLOBALS->signalarea->allocation.width-2, GLOBALS->signalarea->allocation.height-2); draw_signalarea_focus(); } else { gdk_draw_pixmap(GLOBALS->signalarea->window, GLOBALS->signalarea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->signalarea)], GLOBALS->signalpixmap, xsrc, 0, 0, 0, GLOBALS->signalarea->allocation.width, GLOBALS->signalarea->allocation.height); } draw_marker(); } } void button_press_release_common(void) { MaxSignalLength(); gdk_draw_rectangle(GLOBALS->signalpixmap, GLOBALS->gc.gc_ltgray, TRUE, 0, 0, GLOBALS->signal_fill_width, GLOBALS->signalarea->allocation.height); sync_marker(); RenderSigs((int)(GTK_ADJUSTMENT(GLOBALS->wave_vslider)->value),0); if(GLOBALS->signalarea_has_focus) { gdk_draw_pixmap(GLOBALS->signalarea->window, GLOBALS->signalarea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->signalarea)], GLOBALS->signalpixmap, (gint)(GTK_ADJUSTMENT(GLOBALS->signal_hslider)->value)+1, 0+1, 0+1, 0+1, GLOBALS->signalarea->allocation.width-2, GLOBALS->signalarea->allocation.height-2); draw_signalarea_focus(); } else { gdk_draw_pixmap(GLOBALS->signalarea->window, GLOBALS->signalarea->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->signalarea)], GLOBALS->signalpixmap, (gint)(GTK_ADJUSTMENT(GLOBALS->signal_hslider)->value), 0, 0, 0, GLOBALS->signalarea->allocation.width, GLOBALS->signalarea->allocation.height); } } static void button_motion_common(gint xin, gint yin, int pressrel, int is_button_2) { gdouble x,offset,pixstep; TimeType newcurr; if(xin<0) xin=0; if(xin>(GLOBALS->wavewidth-1)) xin=(GLOBALS->wavewidth-1); x=xin; /* for pix time calc */ pixstep=((gdouble)GLOBALS->nsperframe)/((gdouble)GLOBALS->pixelsperframe); newcurr=(TimeType)(offset=((gdouble)GLOBALS->tims.start)+(x*pixstep)); if(offset-newcurr>0.5) /* round to nearest integer ns */ { newcurr++; } if(newcurr>GLOBALS->tims.last) /* sanity checking */ { newcurr=GLOBALS->tims.last; } if(newcurr>GLOBALS->tims.end) { newcurr=GLOBALS->tims.end; } if(newcurrtims.start) { newcurr=GLOBALS->tims.start; } if(!is_button_2) { update_markertime(GLOBALS->tims.marker=cook_markertime(time_trunc(newcurr), xin, yin)); if(GLOBALS->tims.lmbcache<0) GLOBALS->tims.lmbcache=time_trunc(newcurr); draw_marker_partitions(); if((pressrel)||(GLOBALS->constant_marker_update)) { button_press_release_common(); } } else { GLOBALS->tims.baseline = ((GLOBALS->tims.baseline<0)||(is_button_2<0)) ? cook_markertime(time_trunc(newcurr), xin, yin) : -1; update_basetime(GLOBALS->tims.baseline); update_markertime(GLOBALS->tims.marker); wavearea_configure_event(GLOBALS->wavearea, NULL); } } static gint motion_notify_event(GtkWidget *widget, GdkEventMotion *event) { (void)widget; gdouble x, y, pixstep, offset; GdkModifierType state; TimeType newcurr; int scrolled; #ifdef WAVE_USE_GTK2 gint xi, yi; #endif int dummy_x, dummy_y; get_window_xypos(&dummy_x, &dummy_y); if(event->is_hint) { WAVE_GDK_GET_POINTER(event->window, &x, &y, &xi, &yi, &state); WAVE_GDK_GET_POINTER_COPY; } else { x = event->x; y = event->y; state = event->state; } do { scrolled=0; if(state&bmask[GLOBALS->in_button_press_wavewindow_c_1]) /* needed for retargeting in AIX/X11 */ { if(x<0) { if(GLOBALS->wave_scrolling) if(GLOBALS->tims.start>GLOBALS->tims.first) { if(GLOBALS->nsperframe<10) { GLOBALS->tims.start-=GLOBALS->nsperframe; } else { GLOBALS->tims.start-=(GLOBALS->nsperframe/10); } if(GLOBALS->tims.starttims.first) GLOBALS->tims.start=GLOBALS->tims.first; GTK_ADJUSTMENT(GLOBALS->wave_hslider)->value=GLOBALS->tims.marker=time_trunc(GLOBALS->tims.timecache=GLOBALS->tims.start); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed"); scrolled=1; } x=0; } else if(x>GLOBALS->wavewidth) { if(GLOBALS->wave_scrolling) if(GLOBALS->tims.start!=GLOBALS->tims.last) { gfloat pageinc; pageinc=(gfloat)(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx); if(GLOBALS->nsperframe<10) { GLOBALS->tims.start+=GLOBALS->nsperframe; } else { GLOBALS->tims.start+=(GLOBALS->nsperframe/10); } if(GLOBALS->tims.start>GLOBALS->tims.last-pageinc+1) GLOBALS->tims.start=time_trunc(GLOBALS->tims.last-pageinc+1); if(GLOBALS->tims.starttims.first) GLOBALS->tims.start=GLOBALS->tims.first; GLOBALS->tims.marker=time_trunc(GLOBALS->tims.start+pageinc); if(GLOBALS->tims.marker>GLOBALS->tims.last) GLOBALS->tims.marker=GLOBALS->tims.last; GTK_ADJUSTMENT(GLOBALS->wave_hslider)->value=GLOBALS->tims.timecache=GLOBALS->tims.start; gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed"); scrolled=1; } x=GLOBALS->wavewidth-1; } } else if((state&GDK_BUTTON2_MASK)&&(GLOBALS->tims.baseline>=0)) { button_motion_common(x,y,0,-1); /* neg one says don't clear tims.baseline */ } pixstep=((gdouble)GLOBALS->nsperframe)/((gdouble)GLOBALS->pixelsperframe); newcurr=GLOBALS->tims.start+(offset=x*pixstep); if((offset-((int)offset))>0.5) /* round to nearest integer ns */ { newcurr++; } if(newcurr>GLOBALS->tims.last) newcurr=GLOBALS->tims.last; if(newcurr!=GLOBALS->prevtim_wavewindow_c_1) { update_currenttime(time_trunc(newcurr)); GLOBALS->prevtim_wavewindow_c_1=newcurr; } if(state&bmask[GLOBALS->in_button_press_wavewindow_c_1]) { button_motion_common(x,y,0,0); } /* warp selected signals if CTRL is pressed */ #ifdef MAC_INTEGRATION if((event->state & GDK_MOD2_MASK)&&(state&GDK_BUTTON1_MASK)) #else if((event->state & GDK_CONTROL_MASK)&&(state&GDK_BUTTON1_MASK)) #endif { int warp = 0; Trptr t = GLOBALS->traces.first; TimeType gt, delta; while ( t ) { if ( t->flags & TR_HIGHLIGHT ) { warp++; if(!t->shift_drag_valid) { t->shift_drag = t->shift; t->shift_drag_valid = 1; } gt = t->shift_drag + (GLOBALS->tims.marker - GLOBALS->tims.lmbcache); if(gt<0) { delta=GLOBALS->tims.first-GLOBALS->tims.last; if(gt0) { delta=GLOBALS->tims.last-GLOBALS->tims.first; if(gt>delta) gt=delta; } t->shift = gt; } t = t->t_next; } if( warp ) { /* commented out to reduce on visual noise... GLOBALS->signalwindow_width_dirty = 1; MaxSignalLength( ); ...commented out to reduce on visual noise */ signalarea_configure_event( GLOBALS->signalarea, NULL ); wavearea_configure_event( GLOBALS->wavearea, NULL ); } } if(scrolled) /* make sure counters up top update.. */ { gtk_events_pending_gtk_main_iteration(); } WAVE_GDK_GET_POINTER(event->window, &x, &y, &xi, &yi, &state); WAVE_GDK_GET_POINTER_COPY; } while((scrolled)&&(state&bmask[GLOBALS->in_button_press_wavewindow_c_1])); return(TRUE); } #ifdef WAVE_USE_GTK2 static void alternate_y_scroll(int delta) { GtkAdjustment *wadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider); int value = (int)wadj->value; int target = value + delta; int num_traces_displayable=(GLOBALS->signalarea->allocation.height)/(GLOBALS->fontheight); num_traces_displayable--; /* for the time trace that is always there */ if(target > GLOBALS->traces.visible - num_traces_displayable) target = GLOBALS->traces.visible - num_traces_displayable; if(target < 0) target = 0; wadj->value = target; gtk_signal_emit_by_name (GTK_OBJECT (wadj), "changed"); /* force bar update */ gtk_signal_emit_by_name (GTK_OBJECT (wadj), "value_changed"); /* force text update */ } /* * Sane code starts here... :) * TomB 05Feb2012 */ #define SANE_INCREMENT 0.25 /* don't want to increment a whole page thereby completely losing where I am... */ void alt_move_left(gboolean fine_scroll) { TimeType ntinc, ntfrac; ntinc=(TimeType)(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx); /* really don't need this var but the speed of ui code is human dependent.. */ ntfrac=ntinc*GLOBALS->page_divisor*(SANE_INCREMENT / (fine_scroll ? 8.0 : 1.0)); if(!ntfrac) ntfrac = 1; if((GLOBALS->tims.start-ntfrac)>GLOBALS->tims.first) GLOBALS->tims.timecache=GLOBALS->tims.start-ntfrac; else GLOBALS->tims.timecache=GLOBALS->tims.first; GTK_ADJUSTMENT(GLOBALS->wave_hslider)->value=GLOBALS->tims.timecache; time_update(); DEBUG(printf("Alternate move left\n")); } void alt_move_right(gboolean fine_scroll) { TimeType ntinc, ntfrac; ntinc=(TimeType)(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx); ntfrac=ntinc*GLOBALS->page_divisor*(SANE_INCREMENT / (fine_scroll ? 8.0 : 1.0)); if(!ntfrac) ntfrac = 1; if((GLOBALS->tims.start+ntfrac)<(GLOBALS->tims.last-ntinc+1)) { GLOBALS->tims.timecache=GLOBALS->tims.start+ntfrac; } else { GLOBALS->tims.timecache=GLOBALS->tims.last-ntinc+1; if(GLOBALS->tims.timecachetims.first) GLOBALS->tims.timecache=GLOBALS->tims.first; } GTK_ADJUSTMENT(GLOBALS->wave_hslider)->value=GLOBALS->tims.timecache; time_update(); DEBUG(printf("Alternate move right\n")); } void alt_zoom_out(GtkWidget *text, gpointer data) { (void)text; (void)data; TimeType middle=0, width; TimeType marker = GLOBALS->cached_currenttimeval_currenttime_c_1; /* Zoom on mouse cursor, not marker */ if(GLOBALS->do_zoom_center) { if((marker<0)||(markertims.first)||(marker>GLOBALS->tims.last)) { if(GLOBALS->tims.end>GLOBALS->tims.last) GLOBALS->tims.end=GLOBALS->tims.last; middle=(GLOBALS->tims.start/2)+(GLOBALS->tims.end/2); if((GLOBALS->tims.start&1)&&(GLOBALS->tims.end&1)) middle++; } else { middle=marker; } } GLOBALS->tims.prevzoom=GLOBALS->tims.zoom; GLOBALS->tims.zoom--; calczoom(GLOBALS->tims.zoom); if(GLOBALS->do_zoom_center) { width=(TimeType)(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx); GLOBALS->tims.start=time_trunc(middle-(width/2)); if(GLOBALS->tims.start+width>GLOBALS->tims.last) GLOBALS->tims.start=time_trunc(GLOBALS->tims.last-width); if(GLOBALS->tims.starttims.first) GLOBALS->tims.start=GLOBALS->tims.first; GTK_ADJUSTMENT(GLOBALS->wave_hslider)->value=GLOBALS->tims.timecache=GLOBALS->tims.start; } else { GLOBALS->tims.timecache=0; } fix_wavehadj(); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */ gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed"); /* force zoom update */ DEBUG(printf("Alternate Zoom out\n")); } void alt_zoom_in(GtkWidget *text, gpointer data) { (void)text; (void)data; if(GLOBALS->tims.zoom<0) /* otherwise it's ridiculous and can cause */ { /* overflow problems in the scope */ TimeType middle=0, width; TimeType marker = GLOBALS->cached_currenttimeval_currenttime_c_1; /* Zoom on mouse cursor, not marker */ if(GLOBALS->do_zoom_center) { if((marker<0)||(markertims.first)||(marker>GLOBALS->tims.last)) { if(GLOBALS->tims.end>GLOBALS->tims.last) GLOBALS->tims.end=GLOBALS->tims.last; middle=(GLOBALS->tims.start/2)+(GLOBALS->tims.end/2); if((GLOBALS->tims.start&1)&&(GLOBALS->tims.end&1)) middle++; } else { middle=marker; } } GLOBALS->tims.prevzoom=GLOBALS->tims.zoom; GLOBALS->tims.zoom++; calczoom(GLOBALS->tims.zoom); if(GLOBALS->do_zoom_center) { width=(TimeType)(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx); GLOBALS->tims.start=time_trunc(middle-(width/2)); if(GLOBALS->tims.start+width>GLOBALS->tims.last) GLOBALS->tims.start=time_trunc(GLOBALS->tims.last-width); if(GLOBALS->tims.starttims.first) GLOBALS->tims.start=GLOBALS->tims.first; GTK_ADJUSTMENT(GLOBALS->wave_hslider)->value=GLOBALS->tims.timecache=GLOBALS->tims.start; } else { GLOBALS->tims.timecache=0; } fix_wavehadj(); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */ gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed"); /* force zoom update */ DEBUG(printf("Alternate zoom in\n")); } } static gint scroll_event( GtkWidget * widget, GdkEventScroll * event ) { (void)widget; int num_traces_displayable=(GLOBALS->signalarea->allocation.height)/(GLOBALS->fontheight); num_traces_displayable--; DEBUG(printf("Mouse Scroll Event\n")); if(GLOBALS->alt_wheel_mode) { /* TomB mouse wheel handling */ #ifdef MAC_INTEGRATION if ( event->state & GDK_MOD2_MASK ) #else if ( event->state & GDK_CONTROL_MASK ) #endif { /* CTRL+wheel - zoom in/out around current mouse cursor position */ if(event->direction == GDK_SCROLL_UP) alt_zoom_in(NULL, 0); else if(event->direction == GDK_SCROLL_DOWN) alt_zoom_out(NULL, 0); } else if( event->state & GDK_MOD1_MASK ) { /* ALT+wheel - edge left/right mode */ if(event->direction == GDK_SCROLL_UP) service_left_edge(NULL, 0); else if(event->direction == GDK_SCROLL_DOWN) service_right_edge(NULL, 0); } else { /* wheel alone - scroll part of a page along */ if(event->direction == GDK_SCROLL_UP) alt_move_left((event->state & GDK_SHIFT_MASK) != 0); /* finer scroll if shift */ else if(event->direction == GDK_SCROLL_DOWN) alt_move_right((event->state & GDK_SHIFT_MASK) != 0); /* finer scroll if shift */ } } else { /* Original 3.3.31 mouse wheel handling */ switch ( event->direction ) { case GDK_SCROLL_UP: if (GLOBALS->use_scrollwheel_as_y) { if(event->state & GDK_SHIFT_MASK) { alternate_y_scroll(-num_traces_displayable); } else { alternate_y_scroll(-1); } } else { #ifdef MAC_INTEGRATION if ( event->state & GDK_MOD2_MASK ) #else if ( event->state & GDK_CONTROL_MASK ) #endif service_left_shift(NULL, 0); else if ( event->state & GDK_MOD1_MASK ) service_zoom_out(NULL, 0); else service_left_page(NULL, 0); } break; case GDK_SCROLL_DOWN: if (GLOBALS->use_scrollwheel_as_y) { if(event->state & GDK_SHIFT_MASK) { alternate_y_scroll(num_traces_displayable); } else { alternate_y_scroll(1); } } { #ifdef MAC_INTEGRATION if ( event->state & GDK_MOD2_MASK ) #else if ( event->state & GDK_CONTROL_MASK ) #endif service_right_shift(NULL, 0); else if ( event->state & GDK_MOD1_MASK ) service_zoom_in(NULL, 0); else service_right_page(NULL, 0); } break; default: break; } } return(TRUE); } #endif static gint button_press_event(GtkWidget *widget, GdkEventButton *event) { if((event->button==1)||((event->button==3)&&(!GLOBALS->in_button_press_wavewindow_c_1))) { GLOBALS->in_button_press_wavewindow_c_1=event->button; DEBUG(printf("Button Press Event\n")); GLOBALS->prev_markertime = GLOBALS->tims.marker; button_motion_common(event->x,event->y,1,0); GLOBALS->tims.timecache=GLOBALS->tims.start; gdk_pointer_grab(widget->window, FALSE, m_bmask[GLOBALS->in_button_press_wavewindow_c_1] | /* key up on motion for button pressed ONLY */ GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_RELEASE_MASK, NULL, NULL, event->time); #ifdef MAC_INTEGRATION if ((event->state & GDK_MOD2_MASK) && (event->button==1)) #else if ((event->state & GDK_CONTROL_MASK) && (event->button==1)) #endif { Trptr t = GLOBALS->traces.first; while(t) { if((t->flags & TR_HIGHLIGHT)&&(!t->shift_drag_valid)) { t->shift_drag = t->shift; /* cache old value */ t->shift_drag_valid = 1; } t=t->t_next; } } } else if(event->button==2) { if(!GLOBALS->button2_debounce_flag) { GLOBALS->button2_debounce_flag = 1; /* cleared by mouseover_timer() interrupt */ button_motion_common(event->x,event->y,1,1); } } return(TRUE); } static gint button_release_event(GtkWidget *widget, GdkEventButton *event) { (void)widget; if((event->button)&&(event->button==GLOBALS->in_button_press_wavewindow_c_1)) { GLOBALS->in_button_press_wavewindow_c_1=0; DEBUG(printf("Button Release Event\n")); button_motion_common(event->x,event->y,1,0); /* warp selected signals if CTRL is pressed */ if(event->button==1) { int warp = 0; Trptr t = GLOBALS->traces.first; #ifdef MAC_INTEGRATION if(event->state & GDK_MOD2_MASK) #else if(event->state & GDK_CONTROL_MASK) #endif { TimeType gt, delta; while ( t ) { if ( t->flags & TR_HIGHLIGHT ) { warp++; gt = (t->shift_drag_valid ? t-> shift_drag : t->shift) + (GLOBALS->tims.marker - GLOBALS->tims.lmbcache); if(gt<0) { delta=GLOBALS->tims.first-GLOBALS->tims.last; if(gt0) { delta=GLOBALS->tims.last-GLOBALS->tims.first; if(gt>delta) gt=delta; } t->shift = gt; t->flags &= ( ~TR_HIGHLIGHT ); } t->shift_drag_valid = 0; t = t->t_next; } } else /* back out warp and keep highlighting */ { while(t) { if(t->shift_drag_valid) { t->shift = t->shift_drag; t->shift_drag_valid = 0; warp++; } t=t->t_next; } } if( warp ) { GLOBALS->signalwindow_width_dirty = 1; MaxSignalLength( ); signalarea_configure_event( GLOBALS->signalarea, NULL ); wavearea_configure_event( GLOBALS->wavearea, NULL ); } } GLOBALS->tims.timecache=GLOBALS->tims.start; gdk_pointer_ungrab(event->time); if(event->button==3) /* oh yeah, dragzoooooooom! */ { service_dragzoom(GLOBALS->tims.lmbcache, GLOBALS->tims.marker); } GLOBALS->tims.lmbcache=-1; update_markertime(GLOBALS->tims.marker); } GLOBALS->mouseover_counter = 11; move_mouseover(NULL, 0, 0, LLDescriptor(0)); GLOBALS->tims.timecache=0; if(GLOBALS->prev_markertime == LLDescriptor(-1)) { signalarea_configure_event( GLOBALS->signalarea, NULL ); } return(TRUE); } void make_sigarea_gcs(GtkWidget *signalarea) { if(!GLOBALS->made_sgc_contexts_wavewindow_c_1) { GLOBALS->gc_white = alloc_color(signalarea, GLOBALS->color_white, signalarea->style->white_gc); GLOBALS->gc_black = alloc_color(signalarea, GLOBALS->color_black, signalarea->style->black_gc); GLOBALS->gc.gc_ltgray= alloc_color(signalarea, GLOBALS->color_ltgray, signalarea->style->bg_gc[GTK_STATE_PRELIGHT]); GLOBALS->gc.gc_normal= alloc_color(signalarea, GLOBALS->color_normal, signalarea->style->bg_gc[GTK_STATE_NORMAL]); GLOBALS->gc.gc_mdgray= alloc_color(signalarea, GLOBALS->color_mdgray, signalarea->style->bg_gc[GTK_STATE_INSENSITIVE]); GLOBALS->gc.gc_dkgray= alloc_color(signalarea, GLOBALS->color_dkgray, signalarea->style->bg_gc[GTK_STATE_ACTIVE]); GLOBALS->gc.gc_dkblue= alloc_color(signalarea, GLOBALS->color_dkblue, signalarea->style->bg_gc[GTK_STATE_SELECTED]); GLOBALS->gc.gc_brkred= alloc_color(signalarea, GLOBALS->color_brkred, signalarea->style->bg_gc[GTK_STATE_SELECTED]); GLOBALS->gc.gc_ltblue= alloc_color(signalarea, GLOBALS->color_ltblue, signalarea->style->bg_gc[GTK_STATE_SELECTED]); GLOBALS->gc.gc_gmstrd= alloc_color(signalarea, GLOBALS->color_gmstrd, signalarea->style->bg_gc[GTK_STATE_SELECTED]); GLOBALS->made_sgc_contexts_wavewindow_c_1=~0; } } static const int wave_rgb_rainbow[WAVE_NUM_RAINBOW] = WAVE_RAINBOW_RGB; gint wavearea_configure_event(GtkWidget *widget, GdkEventConfigure *event) { (void)event; if((!widget)||(!widget->window)) return(TRUE); DEBUG(printf("WaveWin Configure Event h: %d, w: %d\n",widget->allocation.height, widget->allocation.width)); if(GLOBALS->wavepixmap_wavewindow_c_1) { if((GLOBALS->wavewidth!=widget->allocation.width)||(GLOBALS->waveheight!=widget->allocation.height)) { gdk_pixmap_unref(GLOBALS->wavepixmap_wavewindow_c_1); GLOBALS->wavepixmap_wavewindow_c_1=gdk_pixmap_new(widget->window, GLOBALS->wavewidth=widget->allocation.width, GLOBALS->waveheight=widget->allocation.height, -1); } GLOBALS->old_wvalue=-1.0; } else { GLOBALS->wavepixmap_wavewindow_c_1=gdk_pixmap_new(widget->window, GLOBALS->wavewidth=widget->allocation.width, GLOBALS->waveheight=widget->allocation.height, -1); } if(!GLOBALS->made_gc_contexts_wavewindow_c_1) { int i; GLOBALS->gc.gc_back_wavewindow_c_1 = alloc_color(GLOBALS->wavearea, GLOBALS->color_back, GLOBALS->wavearea->style->white_gc); GLOBALS->gc.gc_baseline_wavewindow_c_1 = alloc_color(GLOBALS->wavearea, GLOBALS->color_baseline, GLOBALS->wavearea->style->bg_gc[GTK_STATE_SELECTED]); GLOBALS->gc.gc_grid_wavewindow_c_1 = alloc_color(GLOBALS->wavearea, GLOBALS->color_grid, GLOBALS->wavearea->style->bg_gc[GTK_STATE_PRELIGHT]); GLOBALS->gc.gc_grid2_wavewindow_c_1 = alloc_color(GLOBALS->wavearea, GLOBALS->color_grid2, GLOBALS->wavearea->style->bg_gc[GTK_STATE_ACTIVE]); GLOBALS->gc.gc_time_wavewindow_c_1 = alloc_color(GLOBALS->wavearea, GLOBALS->color_time, GLOBALS->wavearea->style->black_gc); GLOBALS->gc.gc_timeb_wavewindow_c_1 = alloc_color(GLOBALS->wavearea, GLOBALS->color_timeb, GLOBALS->wavearea->style->bg_gc[GTK_STATE_ACTIVE]); GLOBALS->gc.gc_value_wavewindow_c_1 = alloc_color(GLOBALS->wavearea, GLOBALS->color_value, GLOBALS->wavearea->style->black_gc); GLOBALS->gc.gc_low_wavewindow_c_1 = alloc_color(GLOBALS->wavearea, GLOBALS->color_low, GLOBALS->wavearea->style->black_gc); GLOBALS->gc.gc_high_wavewindow_c_1 = alloc_color(GLOBALS->wavearea, GLOBALS->color_high, GLOBALS->wavearea->style->black_gc); GLOBALS->gc.gc_trans_wavewindow_c_1 = alloc_color(GLOBALS->wavearea, GLOBALS->color_trans, GLOBALS->wavearea->style->black_gc); GLOBALS->gc.gc_mid_wavewindow_c_1 = alloc_color(GLOBALS->wavearea, GLOBALS->color_mid, GLOBALS->wavearea->style->black_gc); GLOBALS->gc.gc_xfill_wavewindow_c_1 = alloc_color(GLOBALS->wavearea, GLOBALS->color_xfill, GLOBALS->wavearea->style->bg_gc[GTK_STATE_PRELIGHT]); GLOBALS->gc.gc_x_wavewindow_c_1 = alloc_color(GLOBALS->wavearea, GLOBALS->color_x, GLOBALS->wavearea->style->black_gc); GLOBALS->gc.gc_vbox_wavewindow_c_1 = alloc_color(GLOBALS->wavearea, GLOBALS->color_vbox, GLOBALS->wavearea->style->black_gc); GLOBALS->gc.gc_vtrans_wavewindow_c_1 = alloc_color(GLOBALS->wavearea, GLOBALS->color_vtrans, GLOBALS->wavearea->style->black_gc); GLOBALS->gc.gc_mark_wavewindow_c_1 = alloc_color(GLOBALS->wavearea, GLOBALS->color_mark, GLOBALS->wavearea->style->bg_gc[GTK_STATE_SELECTED]); GLOBALS->gc.gc_umark_wavewindow_c_1 = alloc_color(GLOBALS->wavearea, GLOBALS->color_umark, GLOBALS->wavearea->style->bg_gc[GTK_STATE_SELECTED]); #ifdef WAVE_DOUBLE_LINE_WIDTH_MODE gdk_gc_set_line_attributes(GLOBALS->gc.gc_value_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND); gdk_gc_set_line_attributes(GLOBALS->gc.gc_low_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND); gdk_gc_set_line_attributes(GLOBALS->gc.gc_high_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND); gdk_gc_set_line_attributes(GLOBALS->gc.gc_trans_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND); gdk_gc_set_line_attributes(GLOBALS->gc.gc_mid_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND); gdk_gc_set_line_attributes(GLOBALS->gc.gc_xfill_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND); gdk_gc_set_line_attributes(GLOBALS->gc.gc_x_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND); gdk_gc_set_line_attributes(GLOBALS->gc.gc_vbox_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND); gdk_gc_set_line_attributes(GLOBALS->gc.gc_vtrans_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND); gdk_gc_set_line_attributes(GLOBALS->gc.gc_mark_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND); gdk_gc_set_line_attributes(GLOBALS->gc.gc_umark_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND); #endif GLOBALS->gc.gc_0_wavewindow_c_1 = alloc_color(GLOBALS->wavearea, GLOBALS->color_0, GLOBALS->wavearea->style->black_gc); GLOBALS->gc.gc_1_wavewindow_c_1 = alloc_color(GLOBALS->wavearea, GLOBALS->color_1, GLOBALS->wavearea->style->black_gc); GLOBALS->gc.gc_ufill_wavewindow_c_1 = alloc_color(GLOBALS->wavearea, GLOBALS->color_ufill, GLOBALS->wavearea->style->bg_gc[GTK_STATE_PRELIGHT]); GLOBALS->gc.gc_u_wavewindow_c_1 = alloc_color(GLOBALS->wavearea, GLOBALS->color_u, GLOBALS->wavearea->style->black_gc); GLOBALS->gc.gc_wfill_wavewindow_c_1 = alloc_color(GLOBALS->wavearea, GLOBALS->color_wfill, GLOBALS->wavearea->style->bg_gc[GTK_STATE_PRELIGHT]); GLOBALS->gc.gc_w_wavewindow_c_1 = alloc_color(GLOBALS->wavearea, GLOBALS->color_w, GLOBALS->wavearea->style->black_gc); GLOBALS->gc.gc_dashfill_wavewindow_c_1= alloc_color(GLOBALS->wavearea, GLOBALS->color_dashfill, GLOBALS->wavearea->style->bg_gc[GTK_STATE_PRELIGHT]); GLOBALS->gc.gc_dash_wavewindow_c_1 = alloc_color(GLOBALS->wavearea, GLOBALS->color_dash, GLOBALS->wavearea->style->black_gc); #ifdef WAVE_DOUBLE_LINE_WIDTH_MODE gdk_gc_set_line_attributes(GLOBALS->gc.gc_0_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND); gdk_gc_set_line_attributes(GLOBALS->gc.gc_1_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND); gdk_gc_set_line_attributes(GLOBALS->gc.gc_ufill_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND); gdk_gc_set_line_attributes(GLOBALS->gc.gc_u_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND); gdk_gc_set_line_attributes(GLOBALS->gc.gc_wfill_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND); gdk_gc_set_line_attributes(GLOBALS->gc.gc_w_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND); gdk_gc_set_line_attributes(GLOBALS->gc.gc_dashfill_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND); gdk_gc_set_line_attributes(GLOBALS->gc.gc_dash_wavewindow_c_1, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND); #endif GLOBALS->made_gc_contexts_wavewindow_c_1=~0; memcpy(&GLOBALS->gccache, &GLOBALS->gc, sizeof(struct wave_gcmaster_t)); /* add rainbow colors */ for(i=0;igc_rainbow[i*2] = alloc_color(GLOBALS->wavearea, col, GLOBALS->wavearea->style->black_gc); col >>= 1; col &= 0x007F7F7F; GLOBALS->gc_rainbow[i*2+1] = alloc_color(GLOBALS->wavearea, col, GLOBALS->wavearea->style->black_gc); #ifdef WAVE_DOUBLE_LINE_WIDTH_MODE gdk_gc_set_line_attributes(GLOBALS->gc_rainbow[i*2], 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND); gdk_gc_set_line_attributes(GLOBALS->gc_rainbow[i*2+1], 2, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND); #endif } } if(GLOBALS->timestart_from_savefile_valid) { gfloat pageinc=(gfloat)(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx); if((GLOBALS->timestart_from_savefile >= GLOBALS->tims.first) && (GLOBALS->timestart_from_savefile <= (GLOBALS->tims.last-pageinc))) { GtkAdjustment *hadj = GTK_ADJUSTMENT(GLOBALS->wave_hslider); hadj->value = GLOBALS->timestart_from_savefile; fix_wavehadj(); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed"); /* force zoom update */ gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */ } GLOBALS->timestart_from_savefile_valid = 0; } if(GLOBALS->wavewidth>1) { if((!GLOBALS->do_initial_zoom_fit)||(GLOBALS->do_initial_zoom_fit_used)) { calczoom(GLOBALS->tims.zoom); fix_wavehadj(); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed"); /* force zoom update */ gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */ } else { GLOBALS->do_initial_zoom_fit_used=1; service_zoom_fit(NULL,NULL); } } /* tims.timecache=tims.laststart; */ return(TRUE); } /* * screengrab vs normal rendering gcs... */ void force_screengrab_gcs(void) { GLOBALS->black_and_white = 1; GLOBALS->gc.gc_ltgray= GLOBALS->gc_white ; GLOBALS->gc.gc_normal= GLOBALS->gc_white ; GLOBALS->gc.gc_mdgray= GLOBALS->gc_white ; GLOBALS->gc.gc_dkgray= GLOBALS->gc_white ; GLOBALS->gc.gc_dkblue= GLOBALS->gc_black ; GLOBALS->gc.gc_brkred= GLOBALS->gc_black ; GLOBALS->gc.gc_ltblue= GLOBALS->gc_black ; GLOBALS->gc.gc_gmstrd= GLOBALS->gc_black ; GLOBALS->gc.gc_back_wavewindow_c_1 = GLOBALS->gc_white ; GLOBALS->gc.gc_baseline_wavewindow_c_1 = GLOBALS->gc_black; GLOBALS->gc.gc_grid_wavewindow_c_1 = GLOBALS->gc_black; GLOBALS->gc.gc_grid2_wavewindow_c_1 = GLOBALS->gc_black; GLOBALS->gc.gc_time_wavewindow_c_1 = GLOBALS->gc_black; GLOBALS->gc.gc_timeb_wavewindow_c_1 = GLOBALS->gc_white; GLOBALS->gc.gc_value_wavewindow_c_1 = GLOBALS->gc_black; GLOBALS->gc.gc_low_wavewindow_c_1 = GLOBALS->gc_black; GLOBALS->gc.gc_high_wavewindow_c_1 = GLOBALS->gc_black; GLOBALS->gc.gc_trans_wavewindow_c_1 = GLOBALS->gc_black; GLOBALS->gc.gc_mid_wavewindow_c_1 = GLOBALS->gc_black; GLOBALS->gc.gc_xfill_wavewindow_c_1 = GLOBALS->gc_black; GLOBALS->gc.gc_x_wavewindow_c_1 = GLOBALS->gc_black; GLOBALS->gc.gc_vbox_wavewindow_c_1 = GLOBALS->gc_black; GLOBALS->gc.gc_vtrans_wavewindow_c_1 = GLOBALS->gc_black; GLOBALS->gc.gc_mark_wavewindow_c_1 = GLOBALS->gc_black; GLOBALS->gc.gc_umark_wavewindow_c_1 = GLOBALS->gc_black; GLOBALS->gc.gc_0_wavewindow_c_1 = GLOBALS->gc_black; GLOBALS->gc.gc_1_wavewindow_c_1 = GLOBALS->gc_black; GLOBALS->gc.gc_ufill_wavewindow_c_1 = GLOBALS->gc_black; GLOBALS->gc.gc_u_wavewindow_c_1 = GLOBALS->gc_black; GLOBALS->gc.gc_wfill_wavewindow_c_1 = GLOBALS->gc_black; GLOBALS->gc.gc_w_wavewindow_c_1 = GLOBALS->gc_black; GLOBALS->gc.gc_dashfill_wavewindow_c_1= GLOBALS->gc_black; GLOBALS->gc.gc_dash_wavewindow_c_1 = GLOBALS->gc_black; } void force_normal_gcs(void) { GLOBALS->black_and_white = 0; memcpy(&GLOBALS->gc, &GLOBALS->gccache, sizeof(struct wave_gcmaster_t)); } static gint wavearea_configure_event_local(GtkWidget *widget, GdkEventConfigure *event) { gint rc; gint page_num = gtk_notebook_get_current_page(GTK_NOTEBOOK(GLOBALS->notebook)); struct Global *g_old = GLOBALS; set_GLOBALS((*GLOBALS->contexts)[page_num]); rc = wavearea_configure_event(widget, event); set_GLOBALS(g_old); return(rc); } static gint expose_event(GtkWidget *widget, GdkEventExpose *event) { gdk_draw_pixmap(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE(widget)],GLOBALS->wavepixmap_wavewindow_c_1, event->area.x, event->area.y,event->area.x, event->area.y,event->area.width, event->area.height); draw_marker(); return(FALSE); } static gint expose_event_local(GtkWidget *widget, GdkEventExpose *event) { gint rc; gint page_num = gtk_notebook_get_current_page(GTK_NOTEBOOK(GLOBALS->notebook)); /* struct Global *g_old = GLOBALS; */ set_GLOBALS((*GLOBALS->contexts)[page_num]); rc = expose_event(widget, event); /* seems to cause a conflict flipping back so don't! */ /* set_GLOBALS(g_old); */ return(rc); } GtkWidget * create_wavewindow(void) { GtkWidget *table; GtkWidget *frame; GtkAdjustment *hadj, *vadj; table = gtk_table_new(10, 10, FALSE); GLOBALS->wavearea=gtk_drawing_area_new(); gtk_widget_show(GLOBALS->wavearea); gtk_widget_set_events(GLOBALS->wavearea, #ifdef WAVE_USE_GTK2 GDK_SCROLL_MASK | #endif GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK ); gtk_signal_connect(GTK_OBJECT(GLOBALS->wavearea), "configure_event",GTK_SIGNAL_FUNC(wavearea_configure_event_local), NULL); gtk_signal_connect(GTK_OBJECT(GLOBALS->wavearea), "expose_event",GTK_SIGNAL_FUNC(expose_event_local), NULL); gtkwave_signal_connect(GTK_OBJECT(GLOBALS->wavearea), "motion_notify_event",GTK_SIGNAL_FUNC(motion_notify_event), NULL); gtkwave_signal_connect(GTK_OBJECT(GLOBALS->wavearea), "button_press_event",GTK_SIGNAL_FUNC(button_press_event), NULL); gtkwave_signal_connect(GTK_OBJECT(GLOBALS->wavearea), "button_release_event",GTK_SIGNAL_FUNC(button_release_event), NULL); #ifdef WAVE_USE_GTK2 gtkwave_signal_connect(GTK_OBJECT(GLOBALS->wavearea), "scroll_event",GTK_SIGNAL_FUNC(scroll_event), NULL); GTK_WIDGET_SET_FLAGS( GLOBALS->wavearea, GTK_CAN_FOCUS ); #endif gtk_table_attach (GTK_TABLE (table), GLOBALS->wavearea, 0, 9, 0, 9,GTK_FILL | GTK_EXPAND,GTK_FILL | GTK_EXPAND, 3, 2); GLOBALS->wave_vslider=gtk_adjustment_new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); vadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider); gtkwave_signal_connect(GTK_OBJECT(GLOBALS->wave_vslider), "value_changed",GTK_SIGNAL_FUNC(service_vslider), NULL); GLOBALS->vscroll_wavewindow_c_1=gtk_vscrollbar_new(vadj); /* GTK_WIDGET_SET_FLAGS(GLOBALS->vscroll_wavewindow_c_1, GTK_CAN_FOCUS); */ gtk_widget_show(GLOBALS->vscroll_wavewindow_c_1); gtk_table_attach (GTK_TABLE (table), GLOBALS->vscroll_wavewindow_c_1, 9, 10, 0, 9, GTK_FILL, GTK_FILL | GTK_SHRINK, 3, 3); GLOBALS->wave_hslider=gtk_adjustment_new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); hadj=GTK_ADJUSTMENT(GLOBALS->wave_hslider); gtkwave_signal_connect(GTK_OBJECT(GLOBALS->wave_hslider), "value_changed",GTK_SIGNAL_FUNC(service_hslider), NULL); GLOBALS->hscroll_wavewindow_c_2=gtk_hscrollbar_new(hadj); /* GTK_WIDGET_SET_FLAGS(GLOBALS->hscroll_wavewindow_c_2, GTK_CAN_FOCUS); */ gtk_widget_show(GLOBALS->hscroll_wavewindow_c_2); #if WAVE_USE_GTK2 if(GLOBALS->enable_slider_zoom) { GValue gvalue; if(!draw_slider_p) { GtkStyle *gs = gtk_widget_get_style(GLOBALS->hscroll_wavewindow_c_2); draw_slider_p = GTK_STYLE_GET_CLASS(gs)->draw_slider; GTK_STYLE_GET_CLASS(gs)->draw_slider = draw_slider; } memset(&gvalue, 0, sizeof(GValue)); g_value_init(&gvalue, G_TYPE_INT); gtk_widget_style_get_property(GLOBALS->hscroll_wavewindow_c_2, "min-slider-length", &gvalue); gtkwave_signal_connect(GTK_OBJECT(GLOBALS->hscroll_wavewindow_c_2), "button_press_event",GTK_SIGNAL_FUNC(slider_bpr), NULL); gtkwave_signal_connect(GTK_OBJECT(GLOBALS->hscroll_wavewindow_c_2), "button_release_event",GTK_SIGNAL_FUNC(slider_brr), NULL); gtkwave_signal_connect(GTK_OBJECT(GLOBALS->hscroll_wavewindow_c_2), "motion_notify_event",GTK_SIGNAL_FUNC(slider_mnr), NULL); } #endif gtk_table_attach (GTK_TABLE (table), GLOBALS->hscroll_wavewindow_c_2, 0, 9, 9, 10, GTK_FILL, GTK_FILL | GTK_SHRINK, 3, 4); gtk_widget_show(table); frame=gtk_frame_new("Waves"); gtk_container_border_width(GTK_CONTAINER(frame),2); gtk_container_add(GTK_CONTAINER(frame),table); return(frame); } /**********************************************/ void RenderSigs(int trtarget, int update_waves) { Trptr t; int i, trwhich; int num_traces_displayable; GtkAdjustment *hadj; int xsrc; hadj=GTK_ADJUSTMENT(GLOBALS->signal_hslider); xsrc=(gint)hadj->value; num_traces_displayable=GLOBALS->signalarea->allocation.height/(GLOBALS->fontheight); num_traces_displayable--; /* for the time trace that is always there */ gdk_draw_rectangle(GLOBALS->signalpixmap, GLOBALS->gc.gc_mdgray, TRUE, 0, -1, GLOBALS->signal_fill_width, GLOBALS->fontheight); gdk_draw_line(GLOBALS->signalpixmap, GLOBALS->gc_white, 0, GLOBALS->fontheight-1, GLOBALS->signal_fill_width-1, GLOBALS->fontheight-1); font_engine_draw_string(GLOBALS->signalpixmap, GLOBALS->signalfont, GLOBALS->gc_black, 3+xsrc, GLOBALS->fontheight-4, "Time"); t=GLOBALS->traces.first; trwhich=0; while(t) { if((trwhichtopmost_trace=t; if(t) { for(i=0;(isignalarea_has_focus) { gdk_draw_rectangle(GLOBALS->signalpixmap, GLOBALS->gc_black, FALSE, 0, 0, GLOBALS->signal_fill_width-1, GLOBALS->signalarea->allocation.height-1); } if((GLOBALS->wavepixmap_wavewindow_c_1)&&(update_waves)) { gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_back_wavewindow_c_1, TRUE, 0, 0,GLOBALS->wavewidth, GLOBALS->waveheight); /* if(GLOBALS->display_grid) */ rendertimes(); rendertraces(); } } void populateBuffer (Trptr t, char *altname, char* buf) { char* ptr = buf; char *tname = altname ? altname : t->name; if (HasWave(t)) { if (tname) { strcpy(ptr, tname); ptr = ptr + strlen(ptr); if((tname)&&(t->shift)) { ptr[0]='`'; reformat_time(ptr+1, t->shift, GLOBALS->time_dimension); ptr = ptr + strlen(ptr+1) + 1; strcpy(ptr,"\'"); #ifdef WAVE_ARRAY_SUPPORT ptr = ptr + strlen(ptr); /* really needed for aet2 only */ #endif } #ifdef WAVE_ARRAY_SUPPORT if((!t->vector)&&(t->n.nd)&&(t->n.nd->array_height)) { sprintf(ptr, "{%d}", t->n.nd->this_row); /* ptr = ptr + strlen(ptr); */ /* scan-build */ } #endif } if (IsGroupBegin(t)) { char * pch; ptr = buf; if (IsClosed(t)) { pch = strstr (ptr,"[-]"); if(pch) {strncpy (pch,"[+]", 3); } } else { pch = strstr (ptr,"[+]"); if(pch) {strncpy (pch,"[-]", 3); } } } } else { if (tname) { if (IsGroupEnd(t)) { strcpy(ptr, "} "); ptr = ptr + strlen(ptr); } strcpy(ptr, tname); ptr = ptr + strlen(ptr); if (IsGroupBegin(t)) { if (IsClosed(t) && IsCollapsed(t->t_match)) { strcpy(ptr, " {}"); } else { strcpy(ptr, " {"); } /* ptr = ptr + strlen(ptr); */ /* scan-build */ } } } } /***************************************************************************/ int RenderSig(Trptr t, int i, int dobackground) { int texty, liney; int retval; char buf[2048]; GdkGC *clr_comment; GdkGC *clr_group; GdkGC *clr_shadowed; GdkGC *clr_signal; GdkGC* bg_color; GdkGC* text_color; unsigned left_justify; char *subname = NULL; bvptr bv = NULL; buf[0] = 0; if(t->flags & (TR_BLANK|TR_ANALOG_BLANK_STRETCH)) /* seek to real xact trace if present... */ { Trptr tscan = t; int bcnt = 0; while((tscan) && (tscan = GivePrevTrace(tscan))) { if(!(tscan->flags & (TR_BLANK|TR_ANALOG_BLANK_STRETCH))) { if(tscan->flags & TR_TTRANSLATED) { break; /* found it */ } else { tscan = NULL; } } else { bcnt++; /* bcnt is number of blank traces */ } } if((tscan)&&(tscan->vector)) { bv = tscan->n.vec; do { bv = bv->transaction_chain; /* correlate to blank trace */ } while(bv && (bcnt--)); if(bv) { subname = bv->bvname; if(GLOBALS->hier_max_level) subname = hier_extract(subname, GLOBALS->hier_max_level); } } } populateBuffer(t, subname, buf); clr_comment = GLOBALS->gc.gc_brkred; clr_group = GLOBALS->gc.gc_gmstrd; clr_shadowed = GLOBALS->gc.gc_ltblue; clr_signal = GLOBALS->gc.gc_dkblue; UpdateSigValue(t); /* in case it's stale on nonprop */ liney=((i+2)*GLOBALS->fontheight)-2; texty=liney-(GLOBALS->signalfont->descent); retval=liney-GLOBALS->fontheight+1; left_justify = ((IsGroupBegin(t) || IsGroupEnd(t)) && !HasWave(t))|| GLOBALS->left_justify_sigs; if (IsSelected(t)) { bg_color = (!HasWave(t)) ? ((IsGroupBegin(t) || IsGroupEnd(t)) ? clr_group : clr_comment) : ((IsShadowed(t)) ? clr_shadowed : clr_signal); text_color = GLOBALS->gc_white; } else { bg_color = (dobackground==2) ? GLOBALS->gc.gc_normal : GLOBALS->gc.gc_ltgray; if(HasWave(t)) { text_color = GLOBALS->gc_black; } else { text_color = (IsGroupBegin(t) || IsGroupEnd(t)) ? clr_group : clr_comment; } } if (dobackground || IsSelected(t)) { gdk_draw_rectangle(GLOBALS->signalpixmap, bg_color, TRUE, 0, retval, GLOBALS->signal_fill_width, GLOBALS->fontheight-1); } gdk_draw_line(GLOBALS->signalpixmap, GLOBALS->gc_white, 0, liney, GLOBALS->signal_fill_width-1, liney); if((t->name)||(subname)) { font_engine_draw_string(GLOBALS->signalpixmap, GLOBALS->signalfont, text_color, left_justify?3:3+GLOBALS->max_signal_name_pixel_width- font_engine_string_measure(GLOBALS->signalfont, buf), texty, buf); } if (HasWave(t) || bv) { if((t->asciivalue)&&(!(t->flags&TR_EXCLUDE))) font_engine_draw_string(GLOBALS->signalpixmap, GLOBALS->signalfont, text_color, GLOBALS->max_signal_name_pixel_width+6, texty, t->asciivalue); } return(retval); } /***************************************************************************/ void MaxSignalLength(void) { Trptr t; int len=0,maxlen=0; int vlen=0, vmaxlen=0; char buf[2048]; char dirty_kick; bvptr bv; Trptr tscan; DEBUG(printf("signalwindow_width_dirty: %d\n",GLOBALS->signalwindow_width_dirty)); if((!GLOBALS->signalwindow_width_dirty)&&(GLOBALS->use_nonprop_fonts)) return; dirty_kick = GLOBALS->signalwindow_width_dirty; GLOBALS->signalwindow_width_dirty=0; t=GLOBALS->traces.first; while(t) { char *subname = NULL; bv = NULL; tscan = NULL; if(t->flags & (TR_BLANK|TR_ANALOG_BLANK_STRETCH)) /* seek to real xact trace if present... */ { int bcnt = 0; tscan = t; while((tscan) && (tscan = GivePrevTrace(tscan))) { if(!(tscan->flags & (TR_BLANK|TR_ANALOG_BLANK_STRETCH))) { if(tscan->flags & TR_TTRANSLATED) { break; /* found it */ } else { tscan = NULL; } } else { bcnt++; /* bcnt is number of blank traces */ } } if((tscan)&&(tscan->vector)) { bv = tscan->n.vec; do { bv = bv->transaction_chain; /* correlate to blank trace */ } while(bv && (bcnt--)); if(bv) { subname = bv->bvname; if(GLOBALS->hier_max_level) subname = hier_extract(subname, GLOBALS->hier_max_level); } } } populateBuffer(t, subname, buf); if(!bv && (t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH))) /* for "comment" style blank traces */ { if(t->name || subname) { len=font_engine_string_measure(GLOBALS->signalfont, buf); if(len>maxlen) maxlen=len; } if(t->asciivalue) { free_2(t->asciivalue); t->asciivalue = NULL; } t=GiveNextTrace(t); } else if(t->name || subname) { len=font_engine_string_measure(GLOBALS->signalfont, buf); if(len>maxlen) maxlen=len; if((GLOBALS->tims.marker!=-1)&&(!(t->flags&TR_EXCLUDE))) { t->asciitime=GLOBALS->tims.marker; if(t->asciivalue) { free_2(t->asciivalue); } t->asciivalue = NULL; if(bv || t->vector) { char *str, *str2; vptr v; Trptr ts; TraceEnt t_temp; if(bv) { ts = &t_temp; memcpy(ts, tscan, sizeof(TraceEnt)); ts->vector = 1; ts->n.vec = bv; } else { ts = t; bv = t->n.vec; } v=bsearch_vector(bv, GLOBALS->tims.marker - ts->shift); str=convert_ascii(ts,v); if(str) { str2=(char *)malloc_2(strlen(str)+2); *str2='='; strcpy(str2+1,str); free_2(str); vlen=font_engine_string_measure(GLOBALS->signalfont,str2); t->asciivalue=str2; } else { vlen=0; t->asciivalue=NULL; } } else { char *str; hptr h_ptr; if((h_ptr=bsearch_node(t->n.nd,GLOBALS->tims.marker - t->shift))) { if(!t->n.nd->extvals) { unsigned char h_val = h_ptr->v.h_val; str=(char *)calloc_2(1,3*sizeof(char)); str[0]='='; if(t->n.nd->vartype == ND_VCD_EVENT) { h_val = (h_ptr->time >= GLOBALS->tims.first) && ((GLOBALS->tims.marker-GLOBALS->shift_timebase) == h_ptr->time) ? AN_1 : AN_0; /* generate impulse */ } if(t->flags&TR_INVERT) { str[1]=AN_STR_INV[h_val]; } else { str[1]=AN_STR[h_val]; } t->asciivalue=str; vlen=font_engine_string_measure(GLOBALS->signalfont,str); } else { char *str2; if(h_ptr->flags&HIST_REAL) { if(!(h_ptr->flags&HIST_STRING)) { #ifdef WAVE_HAS_H_DOUBLE str=convert_ascii_real(t, &h_ptr->v.h_double); #else str=convert_ascii_real(t, (double *)h_ptr->v.h_vector); #endif } else { str=convert_ascii_string((char *)h_ptr->v.h_vector); } } else { str=convert_ascii_vec(t,h_ptr->v.h_vector); } if(str) { str2=(char *)malloc_2(strlen(str)+2); *str2='='; strcpy(str2+1,str); free_2(str); vlen=font_engine_string_measure(GLOBALS->signalfont,str2); t->asciivalue=str2; } else { vlen=0; t->asciivalue=NULL; } } } else { vlen=0; t->asciivalue=NULL; } } if(vlen>vmaxlen) { vmaxlen=vlen; } } t=GiveNextTrace(t); } else { t=GiveNextTrace(t); } } GLOBALS->max_signal_name_pixel_width = maxlen; GLOBALS->signal_pixmap_width=maxlen+6; /* 2 * 3 pixel pad */ if(GLOBALS->tims.marker!=-1) { GLOBALS->signal_pixmap_width+=(vmaxlen+6); if(GLOBALS->signal_pixmap_width > 32767) GLOBALS->signal_pixmap_width = 32767; /* fixes X11 protocol limitation crash */ } if(GLOBALS->signal_pixmap_width<60) GLOBALS->signal_pixmap_width=60; if(!GLOBALS->in_button_press_wavewindow_c_1) { if(!GLOBALS->do_resize_signals) { int os; os=48; if(GLOBALS->initial_signal_window_width > os) { os = GLOBALS->initial_signal_window_width; } if(GLOBALS->signalwindow) { /* printf("VALUES: %d %d %d\n", GLOBALS->initial_signal_window_width, GLOBALS->signalwindow->allocation.width, GLOBALS->max_signal_name_pixel_width); */ if (GLOBALS->first_unsized_signals && GLOBALS->max_signal_name_pixel_width !=0) { GLOBALS->first_unsized_signals = 0; gtk_paned_set_position(GTK_PANED(GLOBALS->panedwindow), GLOBALS->max_signal_name_pixel_width+30); } else { gtk_widget_set_usize(GTK_WIDGET(GLOBALS->signalwindow), os+30, -1); } } } else if((GLOBALS->do_resize_signals)&&(GLOBALS->signalwindow)) { int oldusize; int rs; if(GLOBALS->initial_signal_window_width > GLOBALS->max_signal_name_pixel_width) { rs=GLOBALS->initial_signal_window_width; } else { rs=GLOBALS->max_signal_name_pixel_width; } oldusize=GLOBALS->signalwindow->allocation.width; if((oldusize!=rs)||(dirty_kick)) { /* keep signalwindow from expanding arbitrarily large */ #ifdef WAVE_USE_GTK2 int wx, wy; get_window_size(&wx, &wy); if((3*rs) < (2*wx)) /* 2/3 width max */ #else if((3*rs) < (2*(GLOBALS->wavewidth + GLOBALS->signalwindow->allocation.width))) #endif { int os; os=rs; os=(os<48)?48:os; gtk_widget_set_usize(GTK_WIDGET(GLOBALS->signalwindow), os+30, -1); } else { int os; os=48; if(GLOBALS->initial_signal_window_width > os) { os = GLOBALS->initial_signal_window_width; } gtk_widget_set_usize(GTK_WIDGET(GLOBALS->signalwindow), os+30, -1); } } } } } /***************************************************************************/ void UpdateSigValue(Trptr t) { bvptr bv = NULL; Trptr tscan = NULL; if(!t) return; if((t->asciivalue)&&(t->asciitime==GLOBALS->tims.marker))return; if(t->flags & (TR_BLANK|TR_ANALOG_BLANK_STRETCH)) /* seek to real xact trace if present... */ { int bcnt = 0; tscan = t; while((tscan) && (tscan = GivePrevTrace(tscan))) { if(!(tscan->flags & (TR_BLANK|TR_ANALOG_BLANK_STRETCH))) { if(tscan->flags & TR_TTRANSLATED) { break; /* found it */ } else { tscan = NULL; } } else { bcnt++; /* bcnt is number of blank traces */ } } if((tscan)&&(tscan->vector)) { bv = tscan->n.vec; do { bv = bv->transaction_chain; /* correlate to blank trace */ } while(bv && (bcnt--)); if(bv) { /* nothing, we just want to set bv */ } } } if((t->name || bv)&&(bv || !(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH)))) { GLOBALS->shift_timebase=t->shift; DEBUG(printf("UpdateSigValue: %s\n",t->name)); if((GLOBALS->tims.marker!=-1)&&(!(t->flags&TR_EXCLUDE))) { t->asciitime=GLOBALS->tims.marker; if(t->asciivalue) free_2(t->asciivalue); if(bv || t->vector) { char *str, *str2; vptr v; Trptr ts; TraceEnt t_temp; if(bv) { ts = &t_temp; memcpy(ts, tscan, sizeof(TraceEnt)); ts->vector = 1; ts->n.vec = bv; } else { ts = t; bv = t->n.vec; } v=bsearch_vector(bv,GLOBALS->tims.marker - ts->shift); str=convert_ascii(ts,v); if(str) { str2=(char *)malloc_2(strlen(str)+2); *str2='='; strcpy(str2+1,str); free_2(str); t->asciivalue=str2; } else { t->asciivalue=NULL; } } else { char *str; hptr h_ptr; if((h_ptr=bsearch_node(t->n.nd,GLOBALS->tims.marker - t->shift))) { if(!t->n.nd->extvals) { unsigned char h_val = h_ptr->v.h_val; if(t->n.nd->vartype == ND_VCD_EVENT) { h_val = (h_ptr->time >= GLOBALS->tims.first) && ((GLOBALS->tims.marker-GLOBALS->shift_timebase) == h_ptr->time) ? AN_1 : AN_0; /* generate impulse */ } str=(char *)calloc_2(1,3*sizeof(char)); str[0]='='; if(t->flags&TR_INVERT) { str[1]=AN_STR_INV[h_val]; } else { str[1]=AN_STR[h_val]; } t->asciivalue=str; } else { char *str2; if(h_ptr->flags&HIST_REAL) { if(!(h_ptr->flags&HIST_STRING)) { #ifdef WAVE_HAS_H_DOUBLE str=convert_ascii_real(t, &h_ptr->v.h_double); #else str=convert_ascii_real(t, (double *)h_ptr->v.h_vector); #endif } else { str=convert_ascii_string((char *)h_ptr->v.h_vector); } } else { str=convert_ascii_vec(t,h_ptr->v.h_vector); } if(str) { str2=(char *)malloc_2(strlen(str)+2); *str2='='; strcpy(str2+1,str); free_2(str); t->asciivalue=str2; } else { t->asciivalue=NULL; } } } else { t->asciivalue=NULL; } } } } } /***************************************************************************/ void calczoom(gdouble z0) { gdouble ppf, frame; ppf=((gdouble)(GLOBALS->pixelsperframe=200)); frame=pow(GLOBALS->zoombase,-z0); if(frame>((gdouble)MAX_HISTENT_TIME/(gdouble)4.0)) { GLOBALS->nsperframe=((gdouble)MAX_HISTENT_TIME/(gdouble)4.0); } else if(frame<(gdouble)1.0) { GLOBALS->nsperframe=1.0; } else { GLOBALS->nsperframe=frame; } GLOBALS->hashstep=10.0; if(GLOBALS->zoom_pow10_snap) if(GLOBALS->nsperframe>10.0) { TimeType nsperframe2; gdouble p=10.0; gdouble scale; int l; l=(int)((log(GLOBALS->nsperframe)/log(p))+0.5); /* nearest power of 10 */ nsperframe2=pow(p, (gdouble)l); scale = (gdouble)nsperframe2 / (gdouble)GLOBALS->nsperframe; ppf *= scale; GLOBALS->pixelsperframe = ppf; GLOBALS->nsperframe = nsperframe2; GLOBALS->hashstep = ppf / 10.0; } GLOBALS->nspx=GLOBALS->nsperframe/ppf; GLOBALS->pxns=ppf/GLOBALS->nsperframe; time_trunc_set(); /* map nspx to rounding value */ DEBUG(printf("Zoom: %e Pixelsperframe: %d, nsperframe: %e\n",z0, (int)GLOBALS->pixelsperframe,(float)GLOBALS->nsperframe)); } static void renderhash(int x, TimeType tim) { TimeType rborder; int fhminus2; int rhs; gdouble dx; gdouble hashoffset; int iter = 0; int s_ctx_iter; int timearray_encountered = (GLOBALS->ruler_step != 0); fhminus2=GLOBALS->fontheight-2; WAVE_STRACE_ITERATOR(s_ctx_iter) { GLOBALS->strace_ctx = &GLOBALS->strace_windows[GLOBALS->strace_current_window = s_ctx_iter]; if(GLOBALS->strace_ctx->timearray) { timearray_encountered = 1; break; } } gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1,x, 0,x, ((!timearray_encountered)&&(GLOBALS->display_grid)&&(GLOBALS->enable_vert_grid))?GLOBALS->waveheight:fhminus2); if(tim==GLOBALS->tims.last) return; rborder=(GLOBALS->tims.last-GLOBALS->tims.start)*GLOBALS->pxns; DEBUG(printf("Rborder: %lld, Wavewidth: %d\n", rborder, GLOBALS->wavewidth)); if(rborder>GLOBALS->wavewidth) rborder=GLOBALS->wavewidth; if((rhs=x+GLOBALS->pixelsperframe)>rborder) rhs=rborder; gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1,x, GLOBALS->wavecrosspiece,rhs, GLOBALS->wavecrosspiece); dx = x + (hashoffset=GLOBALS->hashstep); x = dx; while((hashoffsetpixelsperframe)&&(x<=rhs)&&(iter<9)) { gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1,x, GLOBALS->wavecrosspiece,x, fhminus2); hashoffset+=GLOBALS->hashstep; dx=dx+GLOBALS->hashstep; if((GLOBALS->pixelsperframe!=200)||(GLOBALS->hashstep!=10.0)) iter++; /* fix any roundoff errors */ x = dx; } } static void rendertimes(void) { int lastx = -1000; /* arbitrary */ int x, lenhalf; TimeType tim, rem; char timebuff[32]; char prevover=0; gdouble realx; int s_ctx_iter; int timearray_encountered = 0; renderblackout(); tim=GLOBALS->tims.start; GLOBALS->tims.end=GLOBALS->tims.start+(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx); wave_gdk_draw_line_flush(GLOBALS->wavepixmap_wavewindow_c_1); /* clear out state */ /***********/ WAVE_STRACE_ITERATOR_FWD(s_ctx_iter) { GdkGC * gc; if(!s_ctx_iter) { gc = GLOBALS->gc.gc_grid_wavewindow_c_1; } else { gc = GLOBALS->gc.gc_grid2_wavewindow_c_1; gdk_gc_set_line_attributes(gc, 1, GDK_LINE_ON_OFF_DASH, GDK_CAP_BUTT, GDK_JOIN_BEVEL); } GLOBALS->strace_ctx = &GLOBALS->strace_windows[GLOBALS->strace_current_window = s_ctx_iter]; if(GLOBALS->strace_ctx->timearray) { int pos, pos2; TimeType *t, tm; int y=GLOBALS->fontheight+2; int oldx=-1; timearray_encountered = 1; pos=bsearch_timechain(GLOBALS->tims.start); top: if((pos>=0)&&(posstrace_ctx->timearray_size)) { t=GLOBALS->strace_ctx->timearray+pos; for(;posstrace_ctx->timearray_size;t++, pos++) { tm=*t; if(tm>=GLOBALS->tims.start) { if(tm<=GLOBALS->tims.end) { x=(tm-GLOBALS->tims.start)*GLOBALS->pxns; if(oldx==x) { pos2=bsearch_timechain(GLOBALS->tims.start+(((gdouble)(x+1))*GLOBALS->nspx)); if(pos2>pos) { pos=pos2; goto top; } else continue; } oldx=x; gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gc, x, y, x, GLOBALS->waveheight); } else { break; } } } } } wave_gdk_draw_line_flush(GLOBALS->wavepixmap_wavewindow_c_1); /* clear out state */ if(s_ctx_iter) { gdk_gc_set_line_attributes(gc, 1, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_BEVEL); } } GLOBALS->strace_ctx = &GLOBALS->strace_windows[GLOBALS->strace_current_window = 0]; /***********/ if(GLOBALS->ruler_step && !timearray_encountered) { TimeType rhs = (GLOBALS->tims.end > GLOBALS->tims.last) ? GLOBALS->tims.last : GLOBALS->tims.end; TimeType low_x = (GLOBALS->tims.start - GLOBALS->ruler_origin) / GLOBALS->ruler_step; TimeType high_x = (rhs - GLOBALS->ruler_origin) / GLOBALS->ruler_step; TimeType iter_x, tm; int y=GLOBALS->fontheight+2; int oldx=-1; for(iter_x = low_x; iter_x <= high_x; iter_x++) { tm = GLOBALS->ruler_step * iter_x + GLOBALS->ruler_origin; x=(tm-GLOBALS->tims.start)*GLOBALS->pxns; if(oldx==x) { gdouble xd,offset,pixstep; TimeType newcurr; xd=x+1; /* for pix time calc */ pixstep=((gdouble)GLOBALS->nsperframe)/((gdouble)GLOBALS->pixelsperframe); newcurr=(TimeType)(offset=((gdouble)GLOBALS->tims.start)+(xd*pixstep)); if(offset-newcurr>0.5) /* round to nearest integer ns */ { newcurr++; } low_x = (newcurr - GLOBALS->ruler_origin) / GLOBALS->ruler_step; if(low_x <= iter_x) low_x = (iter_x+1); iter_x = low_x; tm = GLOBALS->ruler_step * iter_x + GLOBALS->ruler_origin; x=(tm-GLOBALS->tims.start)*GLOBALS->pxns; } if(x>=GLOBALS->wavewidth) break; oldx=x; gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1, x, y, x, GLOBALS->waveheight); } } wave_gdk_draw_line_flush(GLOBALS->wavepixmap_wavewindow_c_1); /* clear out state */ /***********/ DEBUG(printf("Ruler Start time: "TTFormat", Finish time: "TTFormat"\n",GLOBALS->tims.start, GLOBALS->tims.end)); x=0; realx=0; if(tim) { rem=tim%((TimeType)GLOBALS->nsperframe); if(rem) { tim=tim-GLOBALS->nsperframe-rem; x=-GLOBALS->pixelsperframe-((rem*GLOBALS->pixelsperframe)/GLOBALS->nsperframe); realx=-GLOBALS->pixelsperframe-((rem*GLOBALS->pixelsperframe)/GLOBALS->nsperframe); } } for(;;) { renderhash(realx, tim); if(tim + GLOBALS->global_time_offset) { if(tim != GLOBALS->min_time) { reformat_time(timebuff, time_trunc(tim) + GLOBALS->global_time_offset, GLOBALS->time_dimension); } else { timebuff[0] = 0; } } else { strcpy(timebuff, "0"); } lenhalf=font_engine_string_measure(GLOBALS->wavefont, timebuff) >> 1; if((x-lenhalf >= lastx) || (GLOBALS->pixelsperframe >= 200)) { font_engine_draw_string(GLOBALS->wavepixmap_wavewindow_c_1,GLOBALS->wavefont,GLOBALS->gc.gc_time_wavewindow_c_1,x-lenhalf, GLOBALS->wavefont->ascent-1,timebuff); lastx = x+lenhalf; } tim+=GLOBALS->nsperframe; x+=GLOBALS->pixelsperframe; realx+=GLOBALS->pixelsperframe; if((prevover)||(tim>GLOBALS->tims.last)) break; if(x>=GLOBALS->wavewidth) prevover=1; } } /***************************************************************************/ static void rendertimebar(void) { gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_timeb_wavewindow_c_1, TRUE,0, -1, GLOBALS->wavewidth, GLOBALS->fontheight); rendertimes(); rendertraces(); update_dual(); } static void gc_save(Trptr t, struct wave_gcmaster_t *gc_sav) { if((!GLOBALS->black_and_white) && (t->t_color)) { int color = t->t_color; color--; memcpy(gc_sav, &GLOBALS->gc, sizeof(struct wave_gcmaster_t)); if(color < WAVE_NUM_RAINBOW) { set_alternate_gcs(GLOBALS->gc_rainbow[2*color], GLOBALS->gc_rainbow[2*color+1]); } } } static void gc_restore(Trptr t, struct wave_gcmaster_t *gc_sav) { if((!GLOBALS->black_and_white) && (t->t_color)) { memcpy(&GLOBALS->gc, gc_sav, sizeof(struct wave_gcmaster_t)); } } static void rendertraces(void) { struct wave_gcmaster_t gc_sav; if(!GLOBALS->topmost_trace) { GLOBALS->topmost_trace=GLOBALS->traces.first; } if(GLOBALS->topmost_trace) { Trptr t = GLOBALS->topmost_trace; Trptr tback = t; hptr h; vptr v; int i = 0, num_traces_displayable; int iback = 0; num_traces_displayable=GLOBALS->wavearea->allocation.height/(GLOBALS->fontheight); num_traces_displayable--; /* for the time trace that is always there */ /* ensure that transaction traces are visible even if the topmost traces are blanks */ while(tback) { if(tback->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH)) { tback = GivePrevTrace(tback); iback--; } else if(tback->flags & TR_TTRANSLATED) { if(tback != t) { t = tback; i = iback; } break; } else { break; } } for(;((iflags&(TR_EXCLUDE|TR_BLANK|TR_ANALOG_BLANK_STRETCH))) { GLOBALS->shift_timebase=t->shift; if(!t->vector) { h=bsearch_node(t->n.nd, GLOBALS->tims.start - t->shift); DEBUG(printf("Start time: "TTFormat", Histent time: "TTFormat"\n", GLOBALS->tims.start,(h->time+GLOBALS->shift_timebase))); if(!t->n.nd->extvals) { if(i>=0) { gc_save(t, &gc_sav); draw_hptr_trace(t,h,i,1,0); gc_restore(t, &gc_sav); } } else { if(i>=0) { gc_save(t, &gc_sav); draw_hptr_trace_vector(t,h,i); gc_restore(t, &gc_sav); } } } else { Trptr t_orig, tn; bvptr bv = t->n.vec; v=bsearch_vector(bv, GLOBALS->tims.start - t->shift); DEBUG(printf("Vector Trace: %s, %s\n", t->name, bv->bvname)); DEBUG(printf("Start time: "TTFormat", Vectorent time: "TTFormat"\n", GLOBALS->tims.start,(v->time+GLOBALS->shift_timebase))); if(i>=0) { gc_save(t, &gc_sav); draw_vptr_trace(t,v,i); gc_restore(t, &gc_sav); } if((bv->transaction_chain) && (t->flags & TR_TTRANSLATED)) { t_orig = t; for(;;) { tn = GiveNextTrace(t); bv = bv->transaction_chain; if(bv && tn && (tn->flags & (TR_BLANK|TR_ANALOG_BLANK_STRETCH))) { i++; if(itims.start - t->shift); if(i>=0) { gc_save(t, &gc_sav); draw_vptr_trace(t_orig,v,i); gc_restore(t, &gc_sav); } t = tn; continue; } } break; } } } } else { int kill_dodraw_grid = t->flags & TR_ANALOG_BLANK_STRETCH; if(kill_dodraw_grid) { Trptr tn = GiveNextTrace(t); if(!tn) { kill_dodraw_grid = 0; } else if(!(tn->flags & TR_ANALOG_BLANK_STRETCH)) { kill_dodraw_grid = 0; } } if(i>=0) { gc_save(t, &gc_sav); draw_hptr_trace(NULL,NULL,i,0,kill_dodraw_grid); gc_restore(t, &gc_sav); } } t=GiveNextTrace(t); /* bot: 1; */ } } draw_named_markers(); draw_marker_partitions(); if(GLOBALS->traces.dirty) { char dbuf[32]; sprintf(dbuf, "%d", GLOBALS->traces.total); GLOBALS->traces.dirty = 0; gtkwavetcl_setvar(WAVE_TCLCB_TRACES_UPDATED, dbuf, WAVE_TCLCB_TRACES_UPDATED_FLAGS); } } /* * draw single traces and use this for rendering the grid lines * for "excluded" traces */ static void draw_hptr_trace(Trptr t, hptr h, int which, int dodraw, int kill_grid) { TimeType _x0, _x1, newtime; int _y0, _y1, yu, liney, ytext; TimeType tim, h2tim; hptr h2, h3; char hval, h2val, invert; GdkGC *c; GdkGC *gcx, *gcxf; char identifier_str[2]; int is_event = t && t->n.nd && (t->n.nd->vartype == ND_VCD_EVENT); GLOBALS->tims.start-=GLOBALS->shift_timebase; GLOBALS->tims.end-=GLOBALS->shift_timebase; liney=((which+2)*GLOBALS->fontheight)-2; if(((t)&&(t->flags&TR_INVERT))&&(!is_event)) { _y0=((which+1)*GLOBALS->fontheight)+2; _y1=liney-2; invert=1; } else { _y1=((which+1)*GLOBALS->fontheight)+2; _y0=liney-2; invert=0; } yu=(_y0+_y1)/2; ytext=yu-(GLOBALS->wavefont->ascent/2)+GLOBALS->wavefont->ascent; if((GLOBALS->display_grid)&&(GLOBALS->enable_horiz_grid)&&(!kill_grid)) { if((GLOBALS->highlight_wavewindow) && (t) && (t->flags & TR_HIGHLIGHT) && (!GLOBALS->black_and_white)) { gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1, TRUE,0, liney - GLOBALS->fontheight, GLOBALS->wavewidth, GLOBALS->fontheight); } else { gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1, (GLOBALS->tims.starttims.first)?(GLOBALS->tims.first-GLOBALS->tims.start)*GLOBALS->pxns:0, liney,(GLOBALS->tims.last<=GLOBALS->tims.end)?(GLOBALS->tims.last-GLOBALS->tims.start)*GLOBALS->pxns:GLOBALS->wavewidth-1, liney); } } if((h)&&(GLOBALS->tims.start==h->time)) if (h->v.h_val != AN_Z) { switch(h->v.h_val) { case AN_X: c = GLOBALS->gc.gc_x_wavewindow_c_1; break; case AN_U: c = GLOBALS->gc.gc_u_wavewindow_c_1; break; case AN_W: c = GLOBALS->gc.gc_w_wavewindow_c_1; break; case AN_DASH: c = GLOBALS->gc.gc_dash_wavewindow_c_1; break; default: c = (h->v.h_val == AN_X) ? GLOBALS->gc.gc_x_wavewindow_c_1: GLOBALS->gc.gc_trans_wavewindow_c_1; } gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c, 0, _y0, 0, _y1); } if(dodraw && t) for(;;) { if(!h) break; tim=(h->time); if((tim>GLOBALS->tims.end)||(tim>GLOBALS->tims.last)) break; _x0=(tim - GLOBALS->tims.start) * GLOBALS->pxns; if(_x0<-1) { _x0=-1; } else if(_x0>GLOBALS->wavewidth) { break; } h2=h->next; if(!h2) break; h2tim=tim=(h2->time); if(tim>GLOBALS->tims.last) tim=GLOBALS->tims.last; else if(tim>GLOBALS->tims.end+1) tim=GLOBALS->tims.end+1; _x1=(tim - GLOBALS->tims.start) * GLOBALS->pxns; if(_x1<-1) { _x1=-1; } else if(_x1>GLOBALS->wavewidth) { _x1=GLOBALS->wavewidth; } if(_x0!=_x1) { if(is_event) { if(h->time >= GLOBALS->tims.first) { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_w_wavewindow_c_1, _x0, _y0, _x0, _y1); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_w_wavewindow_c_1, _x0, _y1, _x0+2, _y1+2); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_w_wavewindow_c_1, _x0, _y1, _x0-2, _y1+2); } h=h->next; continue; } hval=h->v.h_val; h2val=h2->v.h_val; switch(h2val) { case AN_X: c = GLOBALS->gc.gc_x_wavewindow_c_1; break; case AN_U: c = GLOBALS->gc.gc_u_wavewindow_c_1; break; case AN_W: c = GLOBALS->gc.gc_w_wavewindow_c_1; break; case AN_DASH: c = GLOBALS->gc.gc_dash_wavewindow_c_1; break; default: c = (hval == AN_X) ? GLOBALS->gc.gc_x_wavewindow_c_1: GLOBALS->gc.gc_trans_wavewindow_c_1; } switch(hval) { case AN_0: /* 0 */ case AN_L: /* L */ wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, (hval==AN_0) ? GLOBALS->gc.gc_0_wavewindow_c_1 : GLOBALS->gc.gc_low_wavewindow_c_1,_x0, _y0,_x1, _y0); if(h2tim<=GLOBALS->tims.end) switch(h2val) { case AN_0: case AN_L: break; case AN_Z: wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c, _x1, _y0, _x1, yu); break; default: wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c, _x1, _y0, _x1, _y1); break; } break; case AN_X: /* X */ case AN_W: /* W */ case AN_U: /* U */ case AN_DASH: /* - */ identifier_str[1] = 0; switch(hval) { case AN_X: c = gcx = GLOBALS->gc.gc_x_wavewindow_c_1; gcxf = GLOBALS->gc.gc_xfill_wavewindow_c_1; identifier_str[0] = 0; break; case AN_W: c = gcx = GLOBALS->gc.gc_w_wavewindow_c_1; gcxf = GLOBALS->gc.gc_wfill_wavewindow_c_1; identifier_str[0] = 'W'; break; case AN_U: c = gcx = GLOBALS->gc.gc_u_wavewindow_c_1; gcxf = GLOBALS->gc.gc_ufill_wavewindow_c_1; identifier_str[0] = 'U'; break; default: c = gcx = GLOBALS->gc.gc_dash_wavewindow_c_1; gcxf = GLOBALS->gc.gc_dashfill_wavewindow_c_1; identifier_str[0] = '-'; break; } if(invert) { gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, gcx, TRUE,_x0+1, _y0, _x1-_x0, _y1-_y0+1); } else { gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, gcxf, TRUE,_x0+1, _y1, _x1-_x0, _y0-_y1+1); } if(identifier_str[0]) { int _x0_new = (_x0>=0) ? _x0 : 0; int width; if((width=_x1-_x0_new)>GLOBALS->vector_padding) { if((_x1>=GLOBALS->wavewidth)||(font_engine_string_measure(GLOBALS->wavefont, identifier_str)+GLOBALS->vector_padding<=width)) { font_engine_draw_string(GLOBALS->wavepixmap_wavewindow_c_1,GLOBALS->wavefont, GLOBALS->gc.gc_value_wavewindow_c_1, _x0+2,ytext,identifier_str); } } } wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gcx,_x0, _y0,_x1, _y0); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gcx,_x0, _y1,_x1, _y1); if(h2tim<=GLOBALS->tims.end) wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c, _x1, _y0, _x1, _y1); break; case AN_Z: /* Z */ wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_mid_wavewindow_c_1,_x0, yu,_x1, yu); if(h2tim<=GLOBALS->tims.end) switch(h2val) { case AN_0: case AN_L: wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c, _x1, yu, _x1, _y0); break; case AN_1: case AN_H: wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c, _x1, yu, _x1, _y1); break; default: wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c, _x1, _y0, _x1, _y1); break; } break; case AN_1: /* 1 */ case AN_H: /* 1 */ wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, (hval==AN_1) ? GLOBALS->gc.gc_1_wavewindow_c_1 : GLOBALS->gc.gc_high_wavewindow_c_1,_x0, _y1,_x1, _y1); if(h2tim<=GLOBALS->tims.end) switch(h2val) { case AN_1: case AN_H: break; case AN_0: case AN_L: wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c, _x1, _y1, _x1, _y0); break; case AN_Z: wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c, _x1, _y1, _x1, yu); break; default: wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c, _x1, _y0, _x1, _y1); break; } break; default: break; } } else { if(!is_event) { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_trans_wavewindow_c_1, _x1, _y0, _x1, _y1); } else { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_w_wavewindow_c_1, _x1, _y0, _x1, _y1); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_w_wavewindow_c_1, _x0, _y1, _x0+2, _y1+2); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_w_wavewindow_c_1, _x0, _y1, _x0-2, _y1+2); } newtime=(((gdouble)(_x1+WAVE_OPT_SKIP))*GLOBALS->nspx)+GLOBALS->tims.start/*+GLOBALS->shift_timebase*/; /* skip to next pixel */ h3=bsearch_node(t->n.nd,newtime); if(h3->time>h->time) { h=h3; continue; } } h=h->next; } wave_gdk_draw_line_flush(GLOBALS->wavepixmap_wavewindow_c_1); /* clear out state */ GLOBALS->tims.start+=GLOBALS->shift_timebase; GLOBALS->tims.end+=GLOBALS->shift_timebase; } /********************************************************************************************************/ static void draw_hptr_trace_vector_analog(Trptr t, hptr h, int which, int num_extension) { TimeType _x0, _x1, newtime; int _y0, _y1, yu, liney, yt0, yt1; TimeType tim, h2tim; hptr h2, h3; int endcnt = 0; int type; /* int lasttype=-1; */ /* scan-build */ GdkGC *c, *ci; GdkGC *cnan = GLOBALS->gc.gc_u_wavewindow_c_1; GdkGC *cinf = GLOBALS->gc.gc_w_wavewindow_c_1; GdkGC *cfixed; double mynan = strtod("NaN", NULL); double tmin = mynan, tmax = mynan, tv, tv2; gint rmargin; int is_nan = 0, is_nan2 = 0, is_inf = 0, is_inf2 = 0; int any_infs = 0, any_infp = 0, any_infm = 0; int skipcnt = 0; ci = GLOBALS->gc.gc_baseline_wavewindow_c_1; liney=((which+2+num_extension)*GLOBALS->fontheight)-2; _y1=((which+1)*GLOBALS->fontheight)+2; _y0=liney-2; yu=(_y0+_y1)/2; if(t->flags & TR_ANALOG_FULLSCALE) /* otherwise use dynamic */ { if((!t->minmax_valid)||(t->d_num_ext != num_extension)) { h3 = &t->n.nd->head; for(;;) { if(!h3) break; if((h3->time >= GLOBALS->tims.first) && (h3->time <= GLOBALS->tims.last)) { tv = mynan; if(h3->flags&HIST_REAL) { #ifdef WAVE_HAS_H_DOUBLE if(!(h3->flags&HIST_STRING)) tv = h3->v.h_double; #else if(!(h3->flags&HIST_STRING) && h3->v.h_vector) tv = *(double *)h3->v.h_vector; #endif } else { if(h3->time <= GLOBALS->tims.last) tv=convert_real_vec(t,h3->v.h_vector); } if (!isnan(tv) && !isinf(tv)) { if (isnan(tmin) || tv < tmin) tmin = tv; if (isnan(tmax) || tv > tmax) tmax = tv; } else if(isinf(tv)) { any_infs = 1; if(tv > 0) { any_infp = 1; } else { any_infm = 1; } } } h3 = h3->next; } if (isnan(tmin) || isnan(tmax)) { tmin = tmax = 0; } if(any_infs) { double tdelta = (tmax - tmin) * WAVE_INF_SCALING; if(any_infp) tmax = tmax + tdelta; if(any_infm) tmin = tmin - tdelta; } if ((tmax - tmin) < 1e-20) { tmax = 1; tmin -= 0.5 * (_y1 - _y0); } else { tmax = (_y1 - _y0) / (tmax - tmin); } t->minmax_valid = 1; t->d_minval = tmin; t->d_maxval = tmax; t->d_num_ext = num_extension; } else { tmin = t->d_minval; tmax = t->d_maxval; } } else { h3 = h; for(;;) { if(!h3) break; tim=(h3->time); if(tim>GLOBALS->tims.end) { endcnt++; if(endcnt==2) break; } if(tim>GLOBALS->tims.last) break; _x0=(tim - GLOBALS->tims.start) * GLOBALS->pxns; if((_x0>GLOBALS->wavewidth)&&(endcnt==2)) { break; } tv = mynan; if(h3->flags&HIST_REAL) { #ifdef WAVE_HAS_H_DOUBLE if(!(h3->flags&HIST_STRING)) tv = h3->v.h_double; #else if(!(h3->flags&HIST_STRING) && h3->v.h_vector) tv = *(double *)h3->v.h_vector; #endif } else { if(h3->time <= GLOBALS->tims.last) tv=convert_real_vec(t,h3->v.h_vector); } if (!isnan(tv) && !isinf(tv)) { if (isnan(tmin) || tv < tmin) tmin = tv; if (isnan(tmax) || tv > tmax) tmax = tv; } else if(isinf(tv)) { any_infs = 1; if(tv > 0) { any_infp = 1; } else { any_infm = 1; } } h3 = h3->next; } if (isnan(tmin) || isnan(tmax)) tmin = tmax = 0; if(any_infs) { double tdelta = (tmax - tmin) * WAVE_INF_SCALING; if(any_infp) tmax = tmax + tdelta; if(any_infm) tmin = tmin - tdelta; } if ((tmax - tmin) < 1e-20) { tmax = 1; tmin -= 0.5 * (_y1 - _y0); } else { tmax = (_y1 - _y0) / (tmax - tmin); } } if(GLOBALS->tims.last - GLOBALS->tims.start < GLOBALS->wavewidth) { rmargin=(GLOBALS->tims.last - GLOBALS->tims.start) * GLOBALS->pxns; } else { rmargin = GLOBALS->wavewidth; } /* now do the actual drawing */ h3 = NULL; for(;;) { if(!h) break; tim=(h->time); if((tim>GLOBALS->tims.end)||(tim>GLOBALS->tims.last)) break; _x0=(tim - GLOBALS->tims.start) * GLOBALS->pxns; /* if(_x0<-1) { _x0=-1; } else if(_x0>GLOBALS->wavewidth) { break; } */ h2=h->next; if(!h2) break; h2tim=tim=(h2->time); if(tim>GLOBALS->tims.last) tim=GLOBALS->tims.last; /* else if(tim>GLOBALS->tims.end+1) tim=GLOBALS->tims.end+1; */ _x1=(tim - GLOBALS->tims.start) * GLOBALS->pxns; /* if(_x1<-1) { _x1=-1; } else if(_x1>GLOBALS->wavewidth) { _x1=GLOBALS->wavewidth; } */ /* draw trans */ type = (!(h->flags&(HIST_REAL|HIST_STRING))) ? vtype(t,h->v.h_vector) : AN_0; tv = tv2 = mynan; if(h->flags&HIST_REAL) { #ifdef WAVE_HAS_H_DOUBLE if(!(h->flags&HIST_STRING)) tv = h->v.h_double; #else if(!(h->flags&HIST_STRING) && h->v.h_vector) tv = *(double *)h->v.h_vector; #endif } else { if(h->time <= GLOBALS->tims.last) tv=convert_real_vec(t,h->v.h_vector); } if(h2->flags&HIST_REAL) { #ifdef WAVE_HAS_H_DOUBLE if(!(h2->flags&HIST_STRING)) tv2 = h2->v.h_double; #else if(!(h2->flags&HIST_STRING) && h2->v.h_vector) tv2 = *(double *)h2->v.h_vector; #endif } else { if(h2->time <= GLOBALS->tims.last) tv2=convert_real_vec(t,h2->v.h_vector); } if((is_inf = isinf(tv))) { if(tv < 0) { yt0 = _y0; } else { yt0 = _y1; } } else if((is_nan = isnan(tv))) { yt0 = yu; } else { yt0 = _y0 + (tv - tmin) * tmax; } if((is_inf2 = isinf(tv2))) { if(tv2 < 0) { yt1 = _y0; } else { yt1 = _y1; } } else if((is_nan2 = isnan(tv2))) { yt1 = yu; } else { yt1 = _y0 + (tv2 - tmin) * tmax; } if((_x0!=_x1)||(skipcnt < GLOBALS->analog_redraw_skip_count)) /* lower number = better performance */ { if(_x0==_x1) { skipcnt++; } else { skipcnt = 0; } if(type == AN_0) { c = GLOBALS->gc.gc_vbox_wavewindow_c_1; } else { c = GLOBALS->gc.gc_x_wavewindow_c_1; } if(h->next) { if(h->next->time > GLOBALS->max_time) { yt1 = yt0; } } cfixed = is_inf ? cinf : c; if((is_nan2) && (h2tim > GLOBALS->max_time)) is_nan2 = 0; /* clamp to top/bottom because of integer rounding errors */ if(yt0 < _y1) yt0 = _y1; else if(yt0 > _y0) yt0 = _y0; if(yt1 < _y1) yt1 = _y1; else if(yt1 > _y0) yt1 = _y0; /* clipping... */ { int coords[4]; int rect[4]; if(_x0 < INT_MIN) { coords[0] = INT_MIN; } else if(_x0 > INT_MAX) { coords[0] = INT_MAX; } else { coords[0] = _x0; } if(_x1 < INT_MIN) { coords[2] = INT_MIN; } else if(_x1 > INT_MAX) { coords[2] = INT_MAX; } else { coords[2] = _x1; } coords[1] = yt0; coords[3] = yt1; rect[0] = -10; rect[1] = _y1; rect[2] = GLOBALS->wavewidth + 10; rect[3] = _y0; if((t->flags & (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP)) != TR_ANALOG_STEP) { wave_lineclip(coords, rect); } else { if(coords[0] < rect[0]) coords[0] = rect[0]; if(coords[2] < rect[0]) coords[2] = rect[0]; if(coords[0] > rect[2]) coords[0] = rect[2]; if(coords[2] > rect[2]) coords[2] = rect[2]; if(coords[1] < rect[1]) coords[1] = rect[1]; if(coords[3] < rect[1]) coords[3] = rect[1]; if(coords[1] > rect[3]) coords[1] = rect[3]; if(coords[3] > rect[3]) coords[3] = rect[3]; } _x0 = coords[0]; yt0 = coords[1]; _x1 = coords[2]; yt1 = coords[3]; } /* ...clipping */ if(is_nan || is_nan2) { if(is_nan) { gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, cnan, TRUE, _x0, _y1, _x1-_x0, _y0-_y1); if((t->flags & (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP)) == (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP)) { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x1-1, yt1,_x1+1, yt1); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x1, yt1-1,_x1, yt1+1); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x0-1, _y0,_x0+1, _y0); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x0, _y0-1,_x0, _y0+1); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x0-1, _y1,_x0+1, _y1); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x0, _y1-1,_x0, _y1+1); } } if(is_nan2) { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, cfixed,_x0, yt0, _x1, yt0); if((t->flags & (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP)) == (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP)) { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, cnan,_x1, yt1,_x1, yt0); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x1-1, _y0,_x1+1, _y0); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x1, _y0-1,_x1, _y0+1); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x1-1, _y1,_x1+1, _y1); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x1, _y1-1,_x1, _y1+1); } } } else if((t->flags & TR_ANALOG_INTERPOLATED) && !is_inf && !is_inf2) { if(t->flags & TR_ANALOG_STEP) { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x0-1, yt0,_x0+1, yt0); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x0, yt0-1,_x0, yt0+1); } if(rmargin != GLOBALS->wavewidth) /* the window is clipped in postscript */ { if((yt0==yt1)&&((_x0 > _x1)||(_x0 < 0))) { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, cfixed,0, yt0,_x1,yt1); } else { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, cfixed,_x0, yt0,_x1,yt1); } } else { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, cfixed,_x0, yt0,_x1,yt1); } } else /* if(t->flags & TR_ANALOG_STEP) */ { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, cfixed,_x0, yt0,_x1, yt0); if(is_inf2) cfixed = cinf; wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, cfixed,_x1, yt0,_x1, yt1); if ((t->flags & (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP)) == (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP)) { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x0-1, yt0,_x0+1, yt0); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x0, yt0-1,_x0, yt0+1); } } } else { newtime=(((gdouble)(_x1+WAVE_OPT_SKIP))*GLOBALS->nspx)+GLOBALS->tims.start/*+GLOBALS->shift_timebase*/; /* skip to next pixel */ h3=bsearch_node(t->n.nd,newtime); if(h3->time>h->time) { h=h3; /* lasttype=type; */ /* scan-build */ continue; } } h=h->next; /* lasttype=type; */ /* scan-build */ } wave_gdk_draw_line_flush(GLOBALS->wavepixmap_wavewindow_c_1); } /* * draw hptr vectors (integer+real) */ static void draw_hptr_trace_vector(Trptr t, hptr h, int which) { TimeType _x0, _x1, newtime, width; int _y0, _y1, yu, liney, ytext; TimeType tim /* , h2tim */; /* scan-build */ hptr h2, h3; char *ascii=NULL; int type; int lasttype=-1; GdkGC *c; GLOBALS->tims.start-=GLOBALS->shift_timebase; GLOBALS->tims.end-=GLOBALS->shift_timebase; liney=((which+2)*GLOBALS->fontheight)-2; _y1=((which+1)*GLOBALS->fontheight)+2; _y0=liney-2; yu=(_y0+_y1)/2; ytext=yu-(GLOBALS->wavefont->ascent/2)+GLOBALS->wavefont->ascent; if((GLOBALS->display_grid)&&(GLOBALS->enable_horiz_grid)) { Trptr tn = GiveNextTrace(t); if((t->flags & TR_ANALOGMASK) && (tn) && (tn->flags & TR_ANALOG_BLANK_STRETCH)) { if((GLOBALS->highlight_wavewindow) && (t) && (t->flags & TR_HIGHLIGHT) && (!GLOBALS->black_and_white)) { gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1, TRUE,0, liney - GLOBALS->fontheight, GLOBALS->wavewidth, GLOBALS->fontheight); } } else { if((GLOBALS->highlight_wavewindow) && (t) && (t->flags & TR_HIGHLIGHT) && (!GLOBALS->black_and_white)) { gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1, TRUE,0, liney - GLOBALS->fontheight, GLOBALS->wavewidth, GLOBALS->fontheight); } else { gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1, (GLOBALS->tims.starttims.first)?(GLOBALS->tims.first-GLOBALS->tims.start)*GLOBALS->pxns:0, liney,(GLOBALS->tims.last<=GLOBALS->tims.end)?(GLOBALS->tims.last-GLOBALS->tims.start)*GLOBALS->pxns:GLOBALS->wavewidth-1, liney); } } } if((t->flags & TR_ANALOGMASK) && (!(h->flags&HIST_STRING) || !(h->flags&HIST_REAL))) { Trptr te = GiveNextTrace(t); int ext = 0; while(te) { if(te->flags & TR_ANALOG_BLANK_STRETCH) { ext++; te = GiveNextTrace(te); } else { break; } } if((ext) && (GLOBALS->highlight_wavewindow) && (t) && (t->flags & TR_HIGHLIGHT) && (!GLOBALS->black_and_white)) { gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1, TRUE,0, liney, GLOBALS->wavewidth, GLOBALS->fontheight * ext); } draw_hptr_trace_vector_analog(t, h, which, ext); GLOBALS->tims.start+=GLOBALS->shift_timebase; GLOBALS->tims.end+=GLOBALS->shift_timebase; return; } GLOBALS->color_active_in_filter = 1; for(;;) { if(!h) break; tim=(h->time); if((tim>GLOBALS->tims.end)||(tim>GLOBALS->tims.last)) break; _x0=(tim - GLOBALS->tims.start) * GLOBALS->pxns; if(_x0<-1) { _x0=-1; } else if(_x0>GLOBALS->wavewidth) { break; } h2=h->next; if(!h2) break; /* h2tim= */ tim=(h2->time); /* scan-build */ if(tim>GLOBALS->tims.last) tim=GLOBALS->tims.last; else if(tim>GLOBALS->tims.end+1) tim=GLOBALS->tims.end+1; _x1=(tim - GLOBALS->tims.start) * GLOBALS->pxns; if(_x1<-1) { _x1=-1; } else if(_x1>GLOBALS->wavewidth) { _x1=GLOBALS->wavewidth; } /* draw trans */ if(!(h->flags&(HIST_REAL|HIST_STRING))) { type = vtype(t,h->v.h_vector); } else { /* s\000 ID is special "z" case */ type = AN_0; if(h->flags&HIST_STRING) { if(h->v.h_vector) { if(!h->v.h_vector[0]) { type = AN_Z; } else { if(!strcmp(h->v.h_vector, "UNDEF")) { type = AN_X; } } } else { type = AN_X; } } } /* type = (!(h->flags&(HIST_REAL|HIST_STRING))) ? vtype(t,h->v.h_vector) : AN_0; */ if(_x0>-1) { GdkGC *gltype, *gtype; switch(lasttype) { case AN_X: gltype = GLOBALS->gc.gc_x_wavewindow_c_1; break; case AN_U: gltype = GLOBALS->gc.gc_u_wavewindow_c_1; break; default: gltype = GLOBALS->gc.gc_vtrans_wavewindow_c_1; break; } switch(type) { case AN_X: gtype = GLOBALS->gc.gc_x_wavewindow_c_1; break; case AN_U: gtype = GLOBALS->gc.gc_u_wavewindow_c_1; break; default: gtype = GLOBALS->gc.gc_vtrans_wavewindow_c_1; break; } if(GLOBALS->use_roundcaps) { if (type == AN_Z) { if (lasttype != -1) { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gltype,_x0-1, _y0,_x0, yu); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gltype,_x0, yu,_x0-1, _y1); } } else if (lasttype==AN_Z) { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gtype,_x0+1, _y0,_x0, yu); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gtype,_x0, yu,_x0+1, _y1); } else { if (lasttype != type) { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gltype,_x0-1, _y0,_x0, yu); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gltype,_x0, yu,_x0-1, _y1); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gtype,_x0+1, _y0,_x0, yu); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gtype,_x0, yu,_x0+1, _y1); } else { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gtype,_x0-2, _y0,_x0+2, _y1); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gtype,_x0+2, _y0,_x0-2, _y1); } } } else { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gtype,_x0, _y0,_x0, _y1); } } if(_x0!=_x1) { if (type == AN_Z) { if(GLOBALS->use_roundcaps) { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_mid_wavewindow_c_1,_x0+1, yu,_x1-1, yu); } else { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_mid_wavewindow_c_1,_x0, yu,_x1, yu); } } else { if(type == AN_0) { c = GLOBALS->gc.gc_vbox_wavewindow_c_1; } else { c = GLOBALS->gc.gc_x_wavewindow_c_1; } if(GLOBALS->use_roundcaps) { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c,_x0+2, _y0,_x1-2, _y0); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c,_x0+2, _y1,_x1-2, _y1); } else { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c,_x0, _y0,_x1, _y0); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c,_x0, _y1,_x1, _y1); } if(_x0<0) _x0=0; /* fixup left margin */ if((width=_x1-_x0)>GLOBALS->vector_padding) { char *ascii2; if(h->flags&HIST_REAL) { if(!(h->flags&HIST_STRING)) { #ifdef WAVE_HAS_H_DOUBLE ascii=convert_ascii_real(t, &h->v.h_double); #else ascii=convert_ascii_real(t, (double *)h->v.h_vector); #endif } else { ascii=convert_ascii_string((char *)h->v.h_vector); } } else { ascii=convert_ascii_vec(t,h->v.h_vector); } ascii2 = ascii; if(*ascii == '?') { GdkGC *cb; char *srch_for_color = strchr(ascii+1, '?'); if(srch_for_color) { *srch_for_color = 0; cb = get_gc_from_name(ascii+1); if(cb) { ascii2 = srch_for_color + 1; if(GLOBALS->gc.gc_back_wavewindow_c_1 != GLOBALS->gc_white) { if(!GLOBALS->black_and_white) gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, cb, TRUE, _x0+1, _y1+1, width-1, (_y0-1) - (_y1+1) + 1); } GLOBALS->fill_in_smaller_rgb_areas_wavewindow_c_1 = 1; } else { *srch_for_color = '?'; /* replace name as color is a miss */ } } } if((_x1>=GLOBALS->wavewidth)||(font_engine_string_measure(GLOBALS->wavefont, ascii2)+GLOBALS->vector_padding<=width)) { font_engine_draw_string(GLOBALS->wavepixmap_wavewindow_c_1,GLOBALS->wavefont,GLOBALS->gc.gc_value_wavewindow_c_1,_x0+2,ytext,ascii2); } else { char *mod; mod=bsearch_trunc(ascii2,width-GLOBALS->vector_padding); if(mod) { *mod='+'; *(mod+1)=0; font_engine_draw_string(GLOBALS->wavepixmap_wavewindow_c_1,GLOBALS->wavefont,GLOBALS->gc.gc_value_wavewindow_c_1,_x0+2,ytext,ascii2); } } } else if(GLOBALS->fill_in_smaller_rgb_areas_wavewindow_c_1) { /* char *ascii2; */ /* scan-build */ if(h->flags&HIST_REAL) { if(!(h->flags&HIST_STRING)) { #ifdef WAVE_HAS_H_DOUBLE ascii=convert_ascii_real(t, &h->v.h_double); #else ascii=convert_ascii_real(t, (double *)h->v.h_vector); #endif } else { ascii=convert_ascii_string((char *)h->v.h_vector); } } else { ascii=convert_ascii_vec(t,h->v.h_vector); } /* ascii2 = ascii; */ /* scan-build */ if(*ascii == '?') { GdkGC *cb; char *srch_for_color = strchr(ascii+1, '?'); if(srch_for_color) { *srch_for_color = 0; cb = get_gc_from_name(ascii+1); if(cb) { /* ascii2 = srch_for_color + 1; */ /* scan-build */ if(GLOBALS->gc.gc_back_wavewindow_c_1 != GLOBALS->gc_white) { if(!GLOBALS->black_and_white) gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, cb, TRUE, _x0, _y1+1, width, (_y0-1) - (_y1+1) + 1); } } else { *srch_for_color = '?'; /* replace name as color is a miss */ } } } } } } else { newtime=(((gdouble)(_x1+WAVE_OPT_SKIP))*GLOBALS->nspx)+GLOBALS->tims.start/*+GLOBALS->shift_timebase*/; /* skip to next pixel */ h3=bsearch_node(t->n.nd,newtime); if(h3->time>h->time) { h=h3; lasttype=type; continue; } } if(ascii) { free_2(ascii); ascii=NULL; } h=h->next; lasttype=type; } GLOBALS->color_active_in_filter = 0; wave_gdk_draw_line_flush(GLOBALS->wavepixmap_wavewindow_c_1); GLOBALS->tims.start+=GLOBALS->shift_timebase; GLOBALS->tims.end+=GLOBALS->shift_timebase; } /********************************************************************************************************/ static void draw_vptr_trace_analog(Trptr t, vptr v, int which, int num_extension) { TimeType _x0, _x1, newtime; int _y0, _y1, yu, liney, yt0, yt1; TimeType tim, h2tim; vptr h, h2, h3; int endcnt = 0; int type; /* int lasttype=-1; */ /* scan-build */ GdkGC *c, *ci; GdkGC *cnan = GLOBALS->gc.gc_u_wavewindow_c_1; GdkGC *cinf = GLOBALS->gc.gc_w_wavewindow_c_1; GdkGC *cfixed; double mynan = strtod("NaN", NULL); double tmin = mynan, tmax = mynan, tv=0.0, tv2; gint rmargin; int is_nan = 0, is_nan2 = 0, is_inf = 0, is_inf2 = 0; int any_infs = 0, any_infp = 0, any_infm = 0; int skipcnt = 0; ci = GLOBALS->gc.gc_baseline_wavewindow_c_1; h=v; liney=((which+2+num_extension)*GLOBALS->fontheight)-2; _y1=((which+1)*GLOBALS->fontheight)+2; _y0=liney-2; yu=(_y0+_y1)/2; if(t->flags & TR_ANALOG_FULLSCALE) /* otherwise use dynamic */ { if((!t->minmax_valid)||(t->d_num_ext != num_extension)) { h3 = t->n.vec->vectors[0]; for(;;) { if(!h3) break; if((h3->time >= GLOBALS->tims.first) && (h3->time <= GLOBALS->tims.last)) { /* tv = mynan; */ /* scan-build */ tv=convert_real(t,h3); if (!isnan(tv) && !isinf(tv)) { if (isnan(tmin) || tv < tmin) tmin = tv; if (isnan(tmax) || tv > tmax) tmax = tv; } } else if(isinf(tv)) { any_infs = 1; if(tv > 0) { any_infp = 1; } else { any_infm = 1; } } h3 = h3->next; } if (isnan(tmin) || isnan(tmax)) tmin = tmax = 0; if(any_infs) { double tdelta = (tmax - tmin) * WAVE_INF_SCALING; if(any_infp) tmax = tmax + tdelta; if(any_infm) tmin = tmin - tdelta; } if ((tmax - tmin) < 1e-20) { tmax = 1; tmin -= 0.5 * (_y1 - _y0); } else { tmax = (_y1 - _y0) / (tmax - tmin); } t->minmax_valid = 1; t->d_minval = tmin; t->d_maxval = tmax; t->d_num_ext = num_extension; } else { tmin = t->d_minval; tmax = t->d_maxval; } } else { h3 = h; for(;;) { if(!h3) break; tim=(h3->time); if(tim>GLOBALS->tims.end) { endcnt++; if(endcnt==2) break; } if(tim>GLOBALS->tims.last) break; _x0=(tim - GLOBALS->tims.start) * GLOBALS->pxns; if((_x0>GLOBALS->wavewidth)&&(endcnt==2)) { break; } tv=convert_real(t,h3); if (!isnan(tv) && !isinf(tv)) { if (isnan(tmin) || tv < tmin) tmin = tv; if (isnan(tmax) || tv > tmax) tmax = tv; } else if(isinf(tv)) { any_infs = 1; if(tv > 0) { any_infp = 1; } else { any_infm = 1; } } h3 = h3->next; } if (isnan(tmin) || isnan(tmax)) tmin = tmax = 0; if(any_infs) { double tdelta = (tmax - tmin) * WAVE_INF_SCALING; if(any_infp) tmax = tmax + tdelta; if(any_infm) tmin = tmin - tdelta; } if ((tmax - tmin) < 1e-20) { tmax = 1; tmin -= 0.5 * (_y1 - _y0); } else { tmax = (_y1 - _y0) / (tmax - tmin); } } if(GLOBALS->tims.last - GLOBALS->tims.start < GLOBALS->wavewidth) { rmargin=(GLOBALS->tims.last - GLOBALS->tims.start) * GLOBALS->pxns; } else { rmargin = GLOBALS->wavewidth; } h3 = NULL; for(;;) { if(!h) break; tim=(h->time); if((tim>GLOBALS->tims.end)||(tim>GLOBALS->tims.last)) break; _x0=(tim - GLOBALS->tims.start) * GLOBALS->pxns; /* if(_x0<-1) { _x0=-1; } else if(_x0>GLOBALS->wavewidth) { break; } */ h2=h->next; if(!h2) break; h2tim=tim=(h2->time); if(tim>GLOBALS->tims.last) tim=GLOBALS->tims.last; /* else if(tim>GLOBALS->tims.end+1) tim=GLOBALS->tims.end+1; */ _x1=(tim - GLOBALS->tims.start) * GLOBALS->pxns; /* if(_x1<-1) { _x1=-1; } else if(_x1>GLOBALS->wavewidth) { _x1=GLOBALS->wavewidth; } */ /* draw trans */ type = vtype2(t,h); tv=convert_real(t,h); tv2=convert_real(t,h2); if((is_inf = isinf(tv))) { if(tv < 0) { yt0 = _y0; } else { yt0 = _y1; } } else if((is_nan = isnan(tv))) { yt0 = yu; } else { yt0 = _y0 + (tv - tmin) * tmax; } if((is_inf2 = isinf(tv2))) { if(tv2 < 0) { yt1 = _y0; } else { yt1 = _y1; } } else if((is_nan2 = isnan(tv2))) { yt1 = yu; } else { yt1 = _y0 + (tv2 - tmin) * tmax; } if((_x0!=_x1)||(skipcnt < GLOBALS->analog_redraw_skip_count)) /* lower number = better performance */ { if(_x0==_x1) { skipcnt++; } else { skipcnt = 0; } if(type == AN_0) { c = GLOBALS->gc.gc_vbox_wavewindow_c_1; } else { c = GLOBALS->gc.gc_x_wavewindow_c_1; } if(h->next) { if(h->next->time > GLOBALS->max_time) { yt1 = yt0; } } cfixed = is_inf ? cinf : c; if((is_nan2) && (h2tim > GLOBALS->max_time)) is_nan2 = 0; /* clamp to top/bottom because of integer rounding errors */ if(yt0 < _y1) yt0 = _y1; else if(yt0 > _y0) yt0 = _y0; if(yt1 < _y1) yt1 = _y1; else if(yt1 > _y0) yt1 = _y0; /* clipping... */ { int coords[4]; int rect[4]; if(_x0 < INT_MIN) { coords[0] = INT_MIN; } else if(_x0 > INT_MAX) { coords[0] = INT_MAX; } else { coords[0] = _x0; } if(_x1 < INT_MIN) { coords[2] = INT_MIN; } else if(_x1 > INT_MAX) { coords[2] = INT_MAX; } else { coords[2] = _x1; } coords[1] = yt0; coords[3] = yt1; rect[0] = -10; rect[1] = _y1; rect[2] = GLOBALS->wavewidth + 10; rect[3] = _y0; if((t->flags & (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP)) != TR_ANALOG_STEP) { wave_lineclip(coords, rect); } else { if(coords[0] < rect[0]) coords[0] = rect[0]; if(coords[2] < rect[0]) coords[2] = rect[0]; if(coords[0] > rect[2]) coords[0] = rect[2]; if(coords[2] > rect[2]) coords[2] = rect[2]; if(coords[1] < rect[1]) coords[1] = rect[1]; if(coords[3] < rect[1]) coords[3] = rect[1]; if(coords[1] > rect[3]) coords[1] = rect[3]; if(coords[3] > rect[3]) coords[3] = rect[3]; } _x0 = coords[0]; yt0 = coords[1]; _x1 = coords[2]; yt1 = coords[3]; } /* ...clipping */ if(is_nan || is_nan2) { if(is_nan) { gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, cnan, TRUE, _x0, _y1, _x1-_x0, _y0-_y1); if((t->flags & (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP)) == (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP)) { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x1-1, yt1,_x1+1, yt1); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x1, yt1-1,_x1, yt1+1); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x0-1, _y0,_x0+1, _y0); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x0, _y0-1,_x0, _y0+1); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x0-1, _y1,_x0+1, _y1); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x0, _y1-1,_x0, _y1+1); } } if(is_nan2) { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, cfixed,_x0, yt0, _x1, yt0); if((t->flags & (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP)) == (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP)) { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, cnan,_x1, yt1,_x1, yt0); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x1-1, _y0,_x1+1, _y0); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x1, _y0-1,_x1, _y0+1); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x1-1, _y1,_x1+1, _y1); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x1, _y1-1,_x1, _y1+1); } } } else if((t->flags & TR_ANALOG_INTERPOLATED) && !is_inf && !is_inf2) { if(t->flags & TR_ANALOG_STEP) { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x0-1, yt0,_x0+1, yt0); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x0, yt0-1,_x0, yt0+1); } if(rmargin != GLOBALS->wavewidth) /* the window is clipped in postscript */ { if((yt0==yt1)&&((_x0 > _x1)||(_x0 < 0))) { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, cfixed,0, yt0,_x1,yt1); } else { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, cfixed,_x0, yt0,_x1,yt1); } } else { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, cfixed,_x0, yt0,_x1,yt1); } } else /* if(t->flags & TR_ANALOG_STEP) */ { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, cfixed,_x0, yt0,_x1, yt0); if(is_inf2) cfixed = cinf; wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, cfixed,_x1, yt0,_x1, yt1); if ((t->flags & (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP)) == (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP)) { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x0-1, yt0,_x0+1, yt0); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, ci,_x0, yt0-1,_x0, yt0+1); } } } else { newtime=(((gdouble)(_x1+WAVE_OPT_SKIP))*GLOBALS->nspx)+GLOBALS->tims.start/*+GLOBALS->shift_timebase*/; /* skip to next pixel */ h3=bsearch_vector(t->n.vec,newtime); if(h3->time>h->time) { h=h3; /* lasttype=type; */ continue; } } h=h->next; /* lasttype=type; */ } wave_gdk_draw_line_flush(GLOBALS->wavepixmap_wavewindow_c_1); GLOBALS->tims.start+=GLOBALS->shift_timebase; GLOBALS->tims.end+=GLOBALS->shift_timebase; } /* * draw vector traces */ static void draw_vptr_trace(Trptr t, vptr v, int which) { TimeType _x0, _x1, newtime, width; int _y0, _y1, yu, liney, ytext; TimeType tim /* , h2tim */; /* scan-build */ vptr h, h2, h3; char *ascii=NULL; int type; int lasttype=-1; GdkGC *c; GLOBALS->tims.start-=GLOBALS->shift_timebase; GLOBALS->tims.end-=GLOBALS->shift_timebase; liney=((which+2)*GLOBALS->fontheight)-2; _y1=((which+1)*GLOBALS->fontheight)+2; _y0=liney-2; yu=(_y0+_y1)/2; ytext=yu-(GLOBALS->wavefont->ascent/2)+GLOBALS->wavefont->ascent; if((GLOBALS->display_grid)&&(GLOBALS->enable_horiz_grid)) { Trptr tn = GiveNextTrace(t); if((t->flags & TR_ANALOGMASK) && (tn) && (tn->flags & TR_ANALOG_BLANK_STRETCH)) { if((GLOBALS->highlight_wavewindow) && (t) && (t->flags & TR_HIGHLIGHT) && (!GLOBALS->black_and_white)) { gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1, TRUE,0, liney - GLOBALS->fontheight, GLOBALS->wavewidth, GLOBALS->fontheight); } } else { if((GLOBALS->highlight_wavewindow) && (t) && (t->flags & TR_HIGHLIGHT) && (!GLOBALS->black_and_white)) { gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1, TRUE,0, liney - GLOBALS->fontheight, GLOBALS->wavewidth, GLOBALS->fontheight); } else { gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1, (GLOBALS->tims.starttims.first)?(GLOBALS->tims.first-GLOBALS->tims.start)*GLOBALS->pxns:0, liney,(GLOBALS->tims.last<=GLOBALS->tims.end)?(GLOBALS->tims.last-GLOBALS->tims.start)*GLOBALS->pxns:GLOBALS->wavewidth-1, liney); } } } h = v; /* obsolete: if(t->flags & TR_TTRANSLATED) { traverse_vector_nodes(t); h=v=bsearch_vector(t->n.vec, GLOBALS->tims.start); } else { h=v; } */ if(t->flags & TR_ANALOGMASK) { Trptr te = GiveNextTrace(t); int ext = 0; while(te) { if(te->flags & TR_ANALOG_BLANK_STRETCH) { ext++; te = GiveNextTrace(te); } else { break; } } if((ext) && (GLOBALS->highlight_wavewindow) && (t) && (t->flags & TR_HIGHLIGHT) && (!GLOBALS->black_and_white)) { gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_grid_wavewindow_c_1, TRUE,0, liney, GLOBALS->wavewidth, GLOBALS->fontheight * ext); } draw_vptr_trace_analog(t, v, which, ext); GLOBALS->tims.start+=GLOBALS->shift_timebase; GLOBALS->tims.end+=GLOBALS->shift_timebase; return; } GLOBALS->color_active_in_filter = 1; for(;;) { if(!h) break; tim=(h->time); if((tim>GLOBALS->tims.end)||(tim>GLOBALS->tims.last)) break; _x0=(tim - GLOBALS->tims.start) * GLOBALS->pxns; if(_x0<-1) { _x0=-1; } else if(_x0>GLOBALS->wavewidth) { break; } h2=h->next; if(!h2) break; /* h2tim= */ tim=(h2->time); /* scan-build */ if(tim>GLOBALS->tims.last) tim=GLOBALS->tims.last; else if(tim>GLOBALS->tims.end+1) tim=GLOBALS->tims.end+1; _x1=(tim - GLOBALS->tims.start) * GLOBALS->pxns; if(_x1<-1) { _x1=-1; } else if(_x1>GLOBALS->wavewidth) { _x1=GLOBALS->wavewidth; } /* draw trans */ type = vtype2(t,h); if(_x0>-1) { GdkGC *gltype, *gtype; switch(lasttype) { case AN_X: gltype = GLOBALS->gc.gc_x_wavewindow_c_1; break; case AN_U: gltype = GLOBALS->gc.gc_u_wavewindow_c_1; break; default: gltype = GLOBALS->gc.gc_vtrans_wavewindow_c_1; break; } switch(type) { case AN_X: gtype = GLOBALS->gc.gc_x_wavewindow_c_1; break; case AN_U: gtype = GLOBALS->gc.gc_u_wavewindow_c_1; break; default: gtype = GLOBALS->gc.gc_vtrans_wavewindow_c_1; break; } if(GLOBALS->use_roundcaps) { if (type == AN_Z) { if (lasttype != -1) { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gltype,_x0-1, _y0,_x0, yu); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gltype,_x0, yu,_x0-1, _y1); } } else if (lasttype==AN_Z) { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gtype,_x0+1, _y0,_x0, yu); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gtype,_x0, yu,_x0+1, _y1); } else { if (lasttype != type) { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gltype,_x0-1, _y0,_x0, yu); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gltype,_x0, yu,_x0-1, _y1); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gtype,_x0+1, _y0,_x0, yu); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gtype,_x0, yu,_x0+1, _y1); } else { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gtype,_x0-2, _y0,_x0+2, _y1); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gtype,_x0+2, _y0,_x0-2, _y1); } } } else { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, gtype,_x0, _y0,_x0, _y1); } } if(_x0!=_x1) { if (type == AN_Z) { if(GLOBALS->use_roundcaps) { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_mid_wavewindow_c_1,_x0+1, yu,_x1-1, yu); } else { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, GLOBALS->gc.gc_mid_wavewindow_c_1,_x0, yu,_x1, yu); } } else { if(type == AN_0) { c = GLOBALS->gc.gc_vbox_wavewindow_c_1; } else { c = GLOBALS->gc.gc_x_wavewindow_c_1; } if(GLOBALS->use_roundcaps) { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c,_x0+2, _y0,_x1-2, _y0); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c,_x0+2, _y1,_x1-2, _y1); } else { wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c,_x0, _y0,_x1, _y0); wave_gdk_draw_line(GLOBALS->wavepixmap_wavewindow_c_1, c,_x0, _y1,_x1, _y1); } if(_x0<0) _x0=0; /* fixup left margin */ if((width=_x1-_x0)>GLOBALS->vector_padding) { char *ascii2; ascii=convert_ascii(t,h); ascii2 = ascii; if(*ascii == '?') { GdkGC *cb; char *srch_for_color = strchr(ascii+1, '?'); if(srch_for_color) { *srch_for_color = 0; cb = get_gc_from_name(ascii+1); if(cb) { ascii2 = srch_for_color + 1; if(!GLOBALS->black_and_white) gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, cb, TRUE, _x0+1, _y1+1, width-1, (_y0-1) - (_y1+1) + 1); GLOBALS->fill_in_smaller_rgb_areas_wavewindow_c_1 = 1; } else { *srch_for_color = '?'; /* replace name as color is a miss */ } } } if((_x1>=GLOBALS->wavewidth)||(font_engine_string_measure(GLOBALS->wavefont, ascii2)+GLOBALS->vector_padding<=width)) { font_engine_draw_string(GLOBALS->wavepixmap_wavewindow_c_1,GLOBALS->wavefont,GLOBALS->gc.gc_value_wavewindow_c_1,_x0+2,ytext,ascii2); } else { char *mod; mod=bsearch_trunc(ascii2,width-GLOBALS->vector_padding); if(mod) { *mod='+'; *(mod+1)=0; font_engine_draw_string(GLOBALS->wavepixmap_wavewindow_c_1,GLOBALS->wavefont,GLOBALS->gc.gc_value_wavewindow_c_1,_x0+2,ytext,ascii2); } } } else if(GLOBALS->fill_in_smaller_rgb_areas_wavewindow_c_1) { /* char *ascii2; */ /* scan-build */ ascii=convert_ascii(t,h); /* ascii2 = ascii; */ /* scan-build */ if(*ascii == '?') { GdkGC *cb; char *srch_for_color = strchr(ascii+1, '?'); if(srch_for_color) { *srch_for_color = 0; cb = get_gc_from_name(ascii+1); if(cb) { /* ascii2 = srch_for_color + 1; */ if(GLOBALS->gc.gc_back_wavewindow_c_1 != GLOBALS->gc_white) { if(!GLOBALS->black_and_white) gdk_draw_rectangle(GLOBALS->wavepixmap_wavewindow_c_1, cb, TRUE, _x0, _y1+1, width, (_y0-1) - (_y1+1) + 1); } } else { *srch_for_color = '?'; /* replace name as color is a miss */ } } } } } } else { newtime=(((gdouble)(_x1+WAVE_OPT_SKIP))*GLOBALS->nspx)+GLOBALS->tims.start/*+GLOBALS->shift_timebase*/; /* skip to next pixel */ h3=bsearch_vector(t->n.vec,newtime); if(h3->time>h->time) { h=h3; lasttype=type; continue; } } if(ascii) { free_2(ascii); ascii=NULL; } lasttype=type; h=h->next; } GLOBALS->color_active_in_filter = 0; wave_gdk_draw_line_flush(GLOBALS->wavepixmap_wavewindow_c_1); GLOBALS->tims.start+=GLOBALS->shift_timebase; GLOBALS->tims.end+=GLOBALS->shift_timebase; } gtkwave-3.3.66/src/tcl_callbacks.h0000664000076400007640000001503211523063250016316 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2010. * * 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. */ #ifndef WAVE_TCLCB_H #define WAVE_TCLCB_H #include #ifdef HAVE_LIBTCL #include #include #include "debug.h" #define WAVE_TCL_LIST_ELEMENT (TCL_LIST_ELEMENT) #define WAVE_TCL_APPEND_VALUE (TCL_APPEND_VALUE) #define WAVE_TCL_GLOBAL_ONLY (TCL_GLOBAL_ONLY) #else #define WAVE_TCL_LIST_ELEMENT (0) #define WAVE_TCL_APPEND_VALUE (0) #define WAVE_TCL_GLOBAL_ONLY (0) #endif #define WAVE_TCLCB_FLAGS_NONE (WAVE_TCL_LIST_ELEMENT|WAVE_TCL_GLOBAL_ONLY) #define WAVE_TCLCB_FLAGS_APPEND (WAVE_TCL_LIST_ELEMENT|WAVE_TCL_GLOBAL_ONLY|WAVE_TCL_APPEND_VALUE) /* ################################################################ */ #define WAVE_TCLCB_ERROR "gtkwave::cbError" #define WAVE_TCLCB_ERROR_FLAGS WAVE_TCLCB_FLAGS_NONE #define WAVE_TCLCB_ERROR_INIT "" #define WAVE_TCLCB_TIMER_PERIOD "gtkwave::cbTimerPeriod" #define WAVE_TCLCB_TIMER_PERIOD_FLAGS WAVE_TCLCB_FLAGS_NONE #define WAVE_TCLCB_TIMER_PERIOD_INIT "250" #define WAVE_TCLCB_CURRENT_ACTIVE_TAB "gtkwave::cbCurrentActiveTab" #define WAVE_TCLCB_CURRENT_ACTIVE_TAB_FLAGS WAVE_TCLCB_FLAGS_NONE #define WAVE_TCLCB_CURRENT_ACTIVE_INIT "" #define WAVE_TCLCB_QUIT_PROGRAM "gtkwave::cbQuitProgram" #define WAVE_TCLCB_QUIT_PROGRAM_FLAGS WAVE_TCLCB_FLAGS_NONE #define WAVE_TCLCB_QUIT_PROGRAM_INIT "" #define WAVE_TCLCB_CLOSE_TAB_NUMBER "gtkwave::cbCloseTabNumber" #define WAVE_TCLCB_CLOSE_TAB_NUMBER_FLAGS WAVE_TCLCB_FLAGS_NONE #define WAVE_TCLCB_CLOSE_TAB_NUMBER_INIT "" #define WAVE_TCLCB_RELOAD_BEGIN "gtkwave::cbReloadBegin" #define WAVE_TCLCB_RELOAD_BEGIN_FLAGS WAVE_TCLCB_FLAGS_NONE #define WAVE_TCLCB_RELOAD_BEGIN_INIT "" #define WAVE_TCLCB_RELOAD_END "gtkwave::cbReloadEnd" #define WAVE_TCLCB_RELOAD_END_FLAGS WAVE_TCLCB_FLAGS_NONE #define WAVE_TCLCB_RELOAD_END_INIT "" #define WAVE_TCLCB_TREE_EXPAND "gtkwave::cbTreeExpand" #define WAVE_TCLCB_TREE_EXPAND_FLAGS WAVE_TCLCB_FLAGS_NONE #define WAVE_TCLCB_TREE_EXPAND_INIT "" #define WAVE_TCLCB_TREE_COLLAPSE "gtkwave::cbTreeCollapse" #define WAVE_TCLCB_TREE_COLLAPSE_FLAGS WAVE_TCLCB_FLAGS_NONE #define WAVE_TCLCB_TREE_COLLAPSE_INIT "" #define WAVE_TCLCB_TREE_SELECT "gtkwave::cbTreeSelect" #define WAVE_TCLCB_TREE_SELECT_FLAGS WAVE_TCLCB_FLAGS_NONE #define WAVE_TCLCB_TREE_SELECT_INIT "" #define WAVE_TCLCB_TREE_UNSELECT "gtkwave::cbTreeUnselect" #define WAVE_TCLCB_TREE_UNSELECT_FLAGS WAVE_TCLCB_FLAGS_NONE #define WAVE_TCLCB_TREE_UNSELECT_INIT "" #define WAVE_TCLCB_TREE_SIG_SELECT "gtkwave::cbTreeSigSelect" #define WAVE_TCLCB_TREE_SIG_SELECT_FLAGS WAVE_TCLCB_FLAGS_NONE #define WAVE_TCLCB_TREE_SIG_SELECT_INIT "" #define WAVE_TCLCB_TREE_SIG_UNSELECT "gtkwave::cbTreeSigUnselect" #define WAVE_TCLCB_TREE_SIG_UNSELECT_FLAGS WAVE_TCLCB_FLAGS_NONE #define WAVE_TCLCB_TREE_SIG_UNSELECT_INIT "" #define WAVE_TCLCB_TREE_SIG_DOUBLE_CLICK "gtkwave::cbTreeSigDoubleClick" #define WAVE_TCLCB_TREE_SIG_DOUBLE_CLICK_FLAGS WAVE_TCLCB_FLAGS_NONE #define WAVE_TCLCB_TREE_SIG_DOUBLE_CLICK_INIT "" #define WAVE_TCLCB_OPEN_TRACE_GROUP "gtkwave::cbOpenTraceGroup" #define WAVE_TCLCB_OPEN_TRACE_GROUP_FLAGS WAVE_TCLCB_FLAGS_NONE #define WAVE_TCLCB_OPEN_TRACE_GROUP_INIT "" #define WAVE_TCLCB_CLOSE_TRACE_GROUP "gtkwave::cbCloseTraceGroup" #define WAVE_TCLCB_CLOSE_TRACE_GROUP_FLAGS WAVE_TCLCB_FLAGS_NONE #define WAVE_TCLCB_CLOSE_TRACE_GROUP_INIT "" #define WAVE_TCLCB_TRACES_UPDATED "gtkwave::cbTracesUpdated" #define WAVE_TCLCB_TRACES_UPDATED_FLAGS WAVE_TCLCB_FLAGS_NONE #define WAVE_TCLCB_TRACES_UPDATED_INIT "" #define WAVE_TCLCB_FROM_ENTRY_UPDATED "gtkwave::cbFromEntryUpdated" #define WAVE_TCLCB_FROM_ENTRY_UPDATED_FLAGS WAVE_TCLCB_FLAGS_NONE #define WAVE_TCLCB_FROM_ENTRY_UPDATED_INIT "" #define WAVE_TCLCB_TO_ENTRY_UPDATED "gtkwave::cbToEntryUpdated" #define WAVE_TCLCB_TO_ENTRY_UPDATED_FLAGS WAVE_TCLCB_FLAGS_NONE #define WAVE_TCLCB_TO_ENTRY_UPDATED_INIT "" #define WAVE_TCLCB_STATUS_TEXT "gtkwave::cbStatusText" #define WAVE_TCLCB_STATUS_TEXT_FLAGS WAVE_TCLCB_FLAGS_NONE #define WAVE_TCLCB_STATUS_TEXT_INIT "" /* ################################################################ */ #define WAVE_TCLCB_MACRO_EXPANSION \ WAVE_TCLCB_M(WAVE_TCLCB_ERROR, WAVE_TCLCB_ERROR_FLAGS, WAVE_TCLCB_ERROR_INIT),\ WAVE_TCLCB_M(WAVE_TCLCB_TIMER_PERIOD, WAVE_TCLCB_TIMER_PERIOD_FLAGS, WAVE_TCLCB_TIMER_PERIOD_INIT),\ WAVE_TCLCB_M(WAVE_TCLCB_CURRENT_ACTIVE_TAB, WAVE_TCLCB_CURRENT_ACTIVE_TAB_FLAGS, WAVE_TCLCB_CURRENT_ACTIVE_INIT),\ WAVE_TCLCB_M(WAVE_TCLCB_QUIT_PROGRAM, WAVE_TCLCB_QUIT_PROGRAM_FLAGS, WAVE_TCLCB_QUIT_PROGRAM_INIT),\ WAVE_TCLCB_M(WAVE_TCLCB_CLOSE_TAB_NUMBER, WAVE_TCLCB_CLOSE_TAB_NUMBER_FLAGS, WAVE_TCLCB_CLOSE_TAB_NUMBER_INIT),\ WAVE_TCLCB_M(WAVE_TCLCB_RELOAD_BEGIN, WAVE_TCLCB_RELOAD_BEGIN_FLAGS, WAVE_TCLCB_RELOAD_BEGIN_INIT),\ WAVE_TCLCB_M(WAVE_TCLCB_RELOAD_END, WAVE_TCLCB_RELOAD_END_FLAGS, WAVE_TCLCB_RELOAD_END_INIT),\ WAVE_TCLCB_M(WAVE_TCLCB_TREE_EXPAND, WAVE_TCLCB_TREE_EXPAND_FLAGS, WAVE_TCLCB_TREE_EXPAND_INIT),\ WAVE_TCLCB_M(WAVE_TCLCB_TREE_COLLAPSE, WAVE_TCLCB_TREE_COLLAPSE_FLAGS, WAVE_TCLCB_TREE_COLLAPSE_INIT),\ WAVE_TCLCB_M(WAVE_TCLCB_TREE_SELECT, WAVE_TCLCB_TREE_SELECT_FLAGS, WAVE_TCLCB_TREE_SELECT_INIT),\ WAVE_TCLCB_M(WAVE_TCLCB_TREE_UNSELECT, WAVE_TCLCB_TREE_UNSELECT_FLAGS, WAVE_TCLCB_TREE_UNSELECT_INIT),\ WAVE_TCLCB_M(WAVE_TCLCB_TREE_SIG_SELECT, WAVE_TCLCB_TREE_SIG_SELECT_FLAGS, WAVE_TCLCB_TREE_SIG_SELECT_INIT),\ WAVE_TCLCB_M(WAVE_TCLCB_TREE_SIG_UNSELECT, WAVE_TCLCB_TREE_SIG_UNSELECT_FLAGS, WAVE_TCLCB_TREE_SIG_UNSELECT_INIT),\ WAVE_TCLCB_M(WAVE_TCLCB_TREE_SIG_DOUBLE_CLICK, WAVE_TCLCB_TREE_SIG_DOUBLE_CLICK_FLAGS, WAVE_TCLCB_TREE_SIG_DOUBLE_CLICK_INIT),\ WAVE_TCLCB_M(WAVE_TCLCB_OPEN_TRACE_GROUP, WAVE_TCLCB_OPEN_TRACE_GROUP_FLAGS, WAVE_TCLCB_OPEN_TRACE_GROUP_INIT),\ WAVE_TCLCB_M(WAVE_TCLCB_CLOSE_TRACE_GROUP, WAVE_TCLCB_CLOSE_TRACE_GROUP_FLAGS, WAVE_TCLCB_CLOSE_TRACE_GROUP_INIT),\ WAVE_TCLCB_M(WAVE_TCLCB_TRACES_UPDATED, WAVE_TCLCB_TRACES_UPDATED_FLAGS, WAVE_TCLCB_TRACES_UPDATED_INIT),\ WAVE_TCLCB_M(WAVE_TCLCB_FROM_ENTRY_UPDATED, WAVE_TCLCB_FROM_ENTRY_UPDATED_FLAGS, WAVE_TCLCB_FROM_ENTRY_UPDATED_INIT),\ WAVE_TCLCB_M(WAVE_TCLCB_TO_ENTRY_UPDATED, WAVE_TCLCB_TO_ENTRY_UPDATED_FLAGS, WAVE_TCLCB_TO_ENTRY_UPDATED_INIT),\ WAVE_TCLCB_M(WAVE_TCLCB_STATUS_TEXT, WAVE_TCLCB_STATUS_TEXT_FLAGS, WAVE_TCLCB_STATUS_TEXT_INIT),\ WAVE_TCLCB_M("",-1,"") /* ################################################################ */ #endif gtkwave-3.3.66/src/translate.c0000664000076400007640000003766712360623564015561 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2005-2014. * * 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. */ #include #include "globals.h" #include #include "gtk12compat.h" #include "symbol.h" #include "translate.h" #include "debug.h" #ifdef _MSC_VER #define strcasecmp _stricmp #endif /************************ splay ************************/ xl_Tree * xl_splay (char *i, xl_Tree * t) { /* Simple top down splay, not requiring i to be in the tree t. */ /* What it does is described above. */ xl_Tree N, *l, *r, *y; int dir; if (t == NULL) return t; N.left = N.right = NULL; l = r = &N; for (;;) { dir = strcasecmp(i, t->item); if (dir < 0) { if (t->left == NULL) break; if (strcasecmp(i, t->left->item)<0) { y = t->left; /* rotate right */ t->left = y->right; y->right = t; t = y; if (t->left == NULL) break; } r->left = t; /* link right */ r = t; t = t->left; } else if (dir > 0) { if (t->right == NULL) break; if (strcasecmp(i, t->right->item)>0) { y = t->right; /* rotate left */ t->right = y->left; y->left = t; t = y; if (t->right == NULL) break; } l->right = t; /* link left */ l = t; t = t->right; } else { break; } } l->right = t->left; /* assemble */ r->left = t->right; t->left = N.right; t->right = N.left; return t; } xl_Tree * xl_insert(char *i, xl_Tree * t, char *trans) { /* Insert i into the tree t, unless it's already there. */ /* Return a pointer to the resulting tree. */ xl_Tree * n; int dir; n = (xl_Tree *) calloc_2(1, sizeof (xl_Tree)); if (n == NULL) { fprintf(stderr, "xl_insert: ran out of memory, exiting.\n"); exit(255); } n->item = strcpy(malloc_2(strlen(i)+1), i); if(trans) n->trans = strcpy(malloc_2(strlen(trans)+1), trans); if (t == NULL) { n->left = n->right = NULL; return n; } t = xl_splay(i,t); dir = strcasecmp(i,t->item); if (dir<0) { n->left = t->left; n->right = t; t->left = NULL; return n; } else if (dir>0) { n->right = t->right; n->left = t; t->right = NULL; return n; } else { /* We get here if it's already in the tree */ /* Don't add it again */ if(n->trans) free_2(n->trans); free_2(n->item); free_2(n); return t; } } xl_Tree * xl_delete(char *i, xl_Tree * t) { /* Deletes i from the tree if it's there. */ /* Return a pointer to the resulting tree. */ xl_Tree * x; if (t==NULL) return NULL; t = xl_splay(i,t); if (strcmp(i, t->item) == 0) { /* found it */ if (t->left == NULL) { x = t->right; } else { x = xl_splay(i, t->left); x->right = t->right; } if(t->trans) free_2(t->trans); free_2(t->item); free_2(t); return x; } return t; /* It wasn't there */ } /************************ splay ************************/ void init_filetrans_data(void) { int i; if(!GLOBALS->filesel_filter) { GLOBALS->filesel_filter = calloc_2(FILE_FILTER_MAX+1, sizeof(char *)); } if(!GLOBALS->xl_file_filter) { GLOBALS->xl_file_filter = calloc_2(FILE_FILTER_MAX+1, sizeof(struct xl_tree_node *)); } for(i=0;ifilesel_filter[i] = NULL; GLOBALS->xl_file_filter[i] = NULL; } } static void regen_display(void) { GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } static void remove_file_filter_2(xl_Tree *t) { if(t->left) remove_file_filter_2(t->left); if(t->right) remove_file_filter_2(t->right); if(t->item) free_2(t->item); if(t->trans) free_2(t->trans); free_2(t); } static void remove_file_filter(int which, int regen) { if(GLOBALS->xl_file_filter[which]) { remove_file_filter_2(GLOBALS->xl_file_filter[which]); GLOBALS->xl_file_filter[which] = NULL; } if(regen) { regen_display(); } } static void load_file_filter(int which, char *name) { FILE *f = fopen(name, "rb"); if(!f) { status_text("Could not open filter file!\n"); return; } remove_file_filter(which, 0); /* should never happen from GUI, but possible from save files or other weirdness */ while(!feof(f)) { char *s = fgetmalloc(f); if(s) { char *lhs = s; while(*lhs && isspace((int)(unsigned char)*lhs)) lhs++; if(lhs) { char *rhs = lhs; if(*lhs != '#') /* ignore comments */ { while(*rhs && !isspace((int)(unsigned char)*rhs)) rhs++; if(*rhs) { char *xlt = rhs+1; *rhs = 0; while(*xlt && isspace((int)(unsigned char)*xlt)) xlt++; if(*xlt) { GLOBALS->xl_file_filter[which] = xl_insert(lhs, GLOBALS->xl_file_filter[which], xlt); } } } } free_2(s); } } fclose(f); } static void load_enums_filter(int which, char *name) { int argc; char **spl = zSplitTclList(name, &argc); int i; if((!spl)||(!argc)||(argc&1)) { status_text("Malformed enums list!\n"); return; } remove_file_filter(which, 0); /* should never happen from GUI, but possible from save files or other weirdness */ for(i=0;ixl_file_filter[which] = xl_insert(lhs, GLOBALS->xl_file_filter[which], xlt); } free_2(spl); } int install_file_filter(int which) { int found = 0; if((which<0)||(which>=(FILE_FILTER_MAX+1))) { which = 0; } if(GLOBALS->traces.first) { Trptr t = GLOBALS->traces.first; while(t) { if(t->flags&TR_HIGHLIGHT) { if(!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH))) { t->f_filter = which; t->p_filter = 0; if(!which) { t->flags &= (~(TR_FTRANSLATED|TR_PTRANSLATED|TR_ANALOGMASK)); } else { t->flags &= (~(TR_ANALOGMASK)); t->flags |= TR_FTRANSLATED; } found++; } } t=t->t_next; } } if(found) { regen_display(); } return(found); } /************************************************************************/ static void destroy_callback(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; GLOBALS->is_active_translate_c_5=0; gtk_widget_destroy(GLOBALS->window_translate_c_11); GLOBALS->window_translate_c_11 = NULL; } static void ok_callback(GtkWidget *widget, GtkWidget *nothing) { install_file_filter(GLOBALS->current_filter_translate_c_2); destroy_callback(widget, nothing); } static void select_row_callback(GtkWidget *widget, gint row, gint column, GdkEventButton *event, gpointer data) { (void)widget; (void)row; (void)column; (void)event; (void)data; GLOBALS->current_filter_translate_c_2 = row + 1; } static void unselect_row_callback(GtkWidget *widget, gint row, gint column, GdkEventButton *event, gpointer data) { (void)widget; (void)row; (void)column; (void)event; (void)data; GLOBALS->current_filter_translate_c_2 = 0; /* none */ } static void add_filter_callback_2(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; int i; GtkCList *cl; if(!GLOBALS->filesel_ok) { return; } if(*GLOBALS->fileselbox_text) { for(i=0;inum_file_filters;i++) { if(GLOBALS->filesel_filter[i]) { if(!strcmp(GLOBALS->filesel_filter[i], *GLOBALS->fileselbox_text)) { status_text("Filter already imported.\n"); if(GLOBALS->is_active_translate_c_5) gdk_window_raise(GLOBALS->window_translate_c_11->window); return; } } } } GLOBALS->num_file_filters++; load_file_filter(GLOBALS->num_file_filters, *GLOBALS->fileselbox_text); if(GLOBALS->xl_file_filter[GLOBALS->num_file_filters] && (*GLOBALS->fileselbox_text /* scan-build */)) { if(GLOBALS->filesel_filter[GLOBALS->num_file_filters]) free_2(GLOBALS->filesel_filter[GLOBALS->num_file_filters]); GLOBALS->filesel_filter[GLOBALS->num_file_filters] = malloc_2(strlen(*GLOBALS->fileselbox_text) + 1); strcpy(GLOBALS->filesel_filter[GLOBALS->num_file_filters], *GLOBALS->fileselbox_text); cl=GTK_CLIST(GLOBALS->clist_translate_c_4); gtk_clist_freeze(cl); gtk_clist_append(cl,(gchar **)&(GLOBALS->filesel_filter[GLOBALS->num_file_filters])); gtk_clist_set_column_width(cl,0,gtk_clist_optimal_column_width(cl,0)); gtk_clist_thaw(cl); } else { GLOBALS->num_file_filters--; } if(GLOBALS->is_active_translate_c_5) gdk_window_raise(GLOBALS->window_translate_c_11->window); } static void add_filter_callback(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; if(GLOBALS->num_file_filters == FILE_FILTER_MAX) { status_text("Max number of file filters installed already.\n"); return; } fileselbox("Select Filter File",&GLOBALS->fcurr_translate_c_2,GTK_SIGNAL_FUNC(add_filter_callback_2), GTK_SIGNAL_FUNC(NULL),NULL, 0); } /* * mainline.. */ void trans_searchbox(char *title) { int i; GtkWidget *scrolled_win; GtkWidget *vbox1, *hbox, *hbox0; GtkWidget *button1, *button5, *button6; gchar *titles[]={"Filter Select"}; GtkWidget *frame2, *frameh, *frameh0; GtkWidget *table; GtkTooltips *tooltips; if(GLOBALS->is_active_translate_c_5) { gdk_window_raise(GLOBALS->window_translate_c_11->window); return; } GLOBALS->is_active_translate_c_5=1; GLOBALS->current_filter_translate_c_2 = 0; /* create a new modal window */ GLOBALS->window_translate_c_11 = gtk_window_new(GLOBALS->disable_window_manager ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL); install_focus_cb(GLOBALS->window_translate_c_11, ((char *)&GLOBALS->window_translate_c_11) - ((char *)GLOBALS)); gtk_window_set_title(GTK_WINDOW (GLOBALS->window_translate_c_11), title); gtkwave_signal_connect(GTK_OBJECT (GLOBALS->window_translate_c_11), "delete_event",(GtkSignalFunc) destroy_callback, NULL); tooltips=gtk_tooltips_new_2(); table = gtk_table_new (256, 1, FALSE); gtk_widget_show (table); vbox1 = gtk_vbox_new (FALSE, 0); gtk_container_border_width (GTK_CONTAINER (vbox1), 3); gtk_widget_show (vbox1); frame2 = gtk_frame_new (NULL); gtk_container_border_width (GTK_CONTAINER (frame2), 3); gtk_widget_show(frame2); gtk_table_attach (GTK_TABLE (table), frame2, 0, 1, 0, 254, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); GLOBALS->clist_translate_c_4=gtk_clist_new_with_titles(1,titles); gtk_clist_column_titles_passive(GTK_CLIST(GLOBALS->clist_translate_c_4)); gtk_clist_set_selection_mode(GTK_CLIST(GLOBALS->clist_translate_c_4), GTK_SELECTION_EXTENDED); gtkwave_signal_connect_object (GTK_OBJECT (GLOBALS->clist_translate_c_4), "select_row",GTK_SIGNAL_FUNC(select_row_callback),NULL); gtkwave_signal_connect_object (GTK_OBJECT (GLOBALS->clist_translate_c_4), "unselect_row",GTK_SIGNAL_FUNC(unselect_row_callback),NULL); for(i=0;inum_file_filters;i++) { gtk_clist_append(GTK_CLIST(GLOBALS->clist_translate_c_4),(gchar **)&(GLOBALS->filesel_filter[i+1])); } gtk_clist_set_column_width(GTK_CLIST(GLOBALS->clist_translate_c_4),0,gtk_clist_optimal_column_width(GTK_CLIST(GLOBALS->clist_translate_c_4),0)); gtk_widget_show (GLOBALS->clist_translate_c_4); scrolled_win = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_widget_set_usize( GTK_WIDGET (scrolled_win), -1, 300); gtk_widget_show(scrolled_win); /* gtk_scrolled_window_add_with_viewport doesn't seen to work right here.. */ gtk_container_add (GTK_CONTAINER (scrolled_win), GLOBALS->clist_translate_c_4); gtk_container_add (GTK_CONTAINER (frame2), scrolled_win); frameh0 = gtk_frame_new (NULL); gtk_container_border_width (GTK_CONTAINER (frameh0), 3); gtk_widget_show(frameh0); gtk_table_attach (GTK_TABLE (table), frameh0, 0, 1, 254, 255, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); hbox0 = gtk_hbox_new (FALSE, 1); gtk_widget_show (hbox0); button6 = gtk_button_new_with_label (" Add Filter to List "); gtk_container_border_width (GTK_CONTAINER (button6), 3); gtkwave_signal_connect_object (GTK_OBJECT (button6), "clicked",GTK_SIGNAL_FUNC(add_filter_callback),GTK_OBJECT (GLOBALS->window_translate_c_11)); gtk_widget_show (button6); gtk_tooltips_set_tip_2(tooltips, button6, "Bring up a file requester to add a filter to the filter select window.",NULL); gtk_box_pack_start (GTK_BOX (hbox0), button6, TRUE, FALSE, 0); gtk_container_add (GTK_CONTAINER (frameh0), hbox0); frameh = gtk_frame_new (NULL); gtk_container_border_width (GTK_CONTAINER (frameh), 3); gtk_widget_show(frameh); gtk_table_attach (GTK_TABLE (table), frameh, 0, 1, 255, 256, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); hbox = gtk_hbox_new (FALSE, 1); gtk_widget_show (hbox); button1 = gtk_button_new_with_label (" OK "); gtk_container_border_width (GTK_CONTAINER (button1), 3); gtkwave_signal_connect_object (GTK_OBJECT (button1), "clicked",GTK_SIGNAL_FUNC(ok_callback),GTK_OBJECT (GLOBALS->window_translate_c_11)); gtk_widget_show (button1); gtk_tooltips_set_tip_2(tooltips, button1, "Add selected signals to end of the display on the main window.",NULL); gtk_box_pack_start (GTK_BOX (hbox), button1, TRUE, FALSE, 0); button5 = gtk_button_new_with_label (" Cancel "); gtk_container_border_width (GTK_CONTAINER (button5), 3); gtkwave_signal_connect_object (GTK_OBJECT (button5), "clicked",GTK_SIGNAL_FUNC(destroy_callback),GTK_OBJECT (GLOBALS->window_translate_c_11)); gtk_tooltips_set_tip_2(tooltips, button5, "Do nothing and return to the main window.",NULL); gtk_widget_show (button5); gtk_box_pack_start (GTK_BOX (hbox), button5, TRUE, FALSE, 0); gtk_container_add (GTK_CONTAINER (frameh), hbox); gtk_container_add (GTK_CONTAINER (GLOBALS->window_translate_c_11), table); gtk_widget_set_usize(GTK_WIDGET(GLOBALS->window_translate_c_11), 400, 400); gtk_widget_show(GLOBALS->window_translate_c_11); } /* * currently only called by parsewavline+tcl */ static void set_current_translate_generic(char *name, int typ) { int i; if(typ) { for(i=1;inum_file_filters+1;i++) { if(!strcmp(GLOBALS->filesel_filter[i], name)) { GLOBALS->current_translate_file = i; return; } } if(!strcmp(WAVE_TCL_INSTALLED_FILTER, name)) { GLOBALS->current_translate_file = 0; return; } } if(GLOBALS->num_file_filters < FILE_FILTER_MAX) { GLOBALS->num_file_filters++; if(typ) { load_file_filter(GLOBALS->num_file_filters, name); } else { load_enums_filter(GLOBALS->num_file_filters, name); } if(!GLOBALS->xl_file_filter[GLOBALS->num_file_filters]) { GLOBALS->num_file_filters--; GLOBALS->current_translate_file = 0; } else { if(GLOBALS->filesel_filter[GLOBALS->num_file_filters]) free_2(GLOBALS->filesel_filter[GLOBALS->num_file_filters]); if(!typ) { name = WAVE_TCL_INSTALLED_FILTER; } GLOBALS->filesel_filter[GLOBALS->num_file_filters] = malloc_2(strlen(name) + 1); strcpy(GLOBALS->filesel_filter[GLOBALS->num_file_filters], name); GLOBALS->current_translate_file = GLOBALS->num_file_filters; } } } void set_current_translate_file(char *name) { set_current_translate_generic(name, 1); /* use file, not enums */ } void set_current_translate_enums(char *lst) { set_current_translate_generic(lst, 0); /* use enums */ } gtkwave-3.3.66/src/savefile.h0000664000076400007640000000324712542115425015344 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2012-2013. * * 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. */ #include "globals.h" #include #ifdef MAC_INTEGRATION #include #endif #ifndef __WAVE_SAVEFILE_H__ #define __WAVE_SAVEFILE_H__ /* These should eventually have error values */ void write_save_helper(const char *savnam, FILE *file); int read_save_helper(char *wname, char **dumpfile, char **savefile, off_t *dumpsiz, time_t *dumptim, int *opt_vcd); /* -1 = error, 0+ = number of lines read */ char *append_array_row(nptr n); int parsewavline(char *w, char *alias, int depth); int parsewavline_lx2(char *w, char *alias, int depth); char *find_dumpfile(char *orig_save, char *orig_dump, char *this_save); #ifdef MAC_INTEGRATION gboolean deal_with_finder_open(GtkosxApplication *app, gchar *path, gpointer user_data); gboolean deal_with_termination(GtkosxApplication *app, gpointer user_data); #endif gboolean deal_with_rpc_open(const gchar *path, gpointer user_data); gboolean deal_with_rpc_open_2(const gchar *path, gpointer user_data, gboolean is_save_file); gboolean process_finder_names_queued(void); char *process_finder_extract_queued_name(void); gboolean process_finder_name_integration(void); void read_save_helper_relative_init(char *wname); int suffix_check(const char *s, const char *sfx); char *extract_dumpname_from_save_file(char *lcname, gboolean *modified, int *opt_vcd); char *get_relative_adjusted_name(char *sfn, char *dfn, char *lcname); #endif gtkwave-3.3.66/src/signalwindow.h0000664000076400007640000000156411523063250016247 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2010 * * 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. */ #ifndef WAVE_SIGNALWINDOW_H #define WAVE_SIGNALWINDOW_H /* for dnd */ #define WAVE_DRAG_TAR_NAME_0 "text/plain" #define WAVE_DRAG_TAR_INFO_0 0 #define WAVE_DRAG_TAR_NAME_1 "text/uri-list" /* not url-list */ #define WAVE_DRAG_TAR_INFO_1 1 #define WAVE_DRAG_TAR_NAME_2 "STRING" #define WAVE_DRAG_TAR_INFO_2 2 void draw_signalarea_focus(void); gint signalarea_configure_event(GtkWidget *widget, GdkEventConfigure *event); void dnd_error(void); gint install_keypress_handler(void); void remove_keypress_handler(gint id); #endif gtkwave-3.3.66/src/mouseover_sigs.c0000664000076400007640000003066512341266475016627 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2006-2014. * * 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. */ /* AIX may need this for alloca to work */ #if defined _AIX #pragma alloca #endif #include "globals.h" #include #include #include #include #include #include "main.h" #include "currenttime.h" #include "color.h" #include "bsearch.h" #include "hierpack.h" WAVE_NODEVARTYPE_STR /************************************************************************************************/ static char *get_fullname(Trptr t) { char *s = NULL; if(!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH))) { if(t->vector==TRUE) { s = strdup_2(t->n.vec->bvname); } else { if(!HasAlias(t)) { int flagged = HIER_DEPACK_ALLOC; s = hier_decompress_flagged(t->n.nd->nname, &flagged); if(!flagged) s = strdup_2(s); } } } return(s); } static int determine_trace_flags(Trptr t, char *ch) { unsigned int flags = t->flags; int pos = 0; /* [0] */ if((flags & TR_SIGNED) != 0) { ch[pos++] = '+'; } /* [1] */ if((flags & TR_HEX) != 0) { ch[pos++] = 'X'; } else if ((flags & TR_ASCII) != 0) { ch[pos++] = 'A'; } else if ((flags & TR_DEC) != 0) { ch[pos++] = 'D'; } else if ((flags & TR_BIN) != 0) { ch[pos++] = 'B'; } else if ((flags & TR_OCT) != 0) { ch[pos++] = 'O'; } /* [2] */ if((flags & TR_RJUSTIFY) != 0) { ch[pos++] = 'J'; } /* [3] */ if((flags & TR_INVERT) != 0) { ch[pos++] = '~'; } /* [4] */ if((flags & TR_REVERSE) != 0) { ch[pos++] = 'V'; } /* [5] */ if((flags & (TR_ANALOG_STEP|TR_ANALOG_INTERPOLATED)) == (TR_ANALOG_STEP|TR_ANALOG_INTERPOLATED)) { ch[pos++] = '*'; } else if((flags & TR_ANALOG_STEP) != 0) { ch[pos++] = 'S'; } else if((flags & TR_ANALOG_INTERPOLATED) != 0) { ch[pos++] = 'I'; } /* [6] */ if((flags & TR_REAL) != 0) { ch[pos++] = 'R'; } /* [7] */ if((flags & TR_REAL2BITS) != 0) { ch[pos++] = 'r'; } /* [8] */ if((flags & TR_ZEROFILL) != 0) { ch[pos++] = '0'; } else if((flags & TR_ONEFILL) != 0) { ch[pos++] = '1'; } /* [9] */ if((flags & TR_BINGRAY) != 0) { ch[pos++] = 'G'; } /* [10] */ if((flags & TR_GRAYBIN) != 0) { ch[pos++] = 'g'; } /* [11] */ if((flags & TR_FTRANSLATED) != 0) { ch[pos++] = 'F'; } /* [12] */ if((flags & TR_PTRANSLATED) != 0) { ch[pos++] = 'P'; } /* [13] */ if((flags & TR_TTRANSLATED) != 0) { ch[pos++] = 'T'; } /* [14] */ if((flags & TR_POPCNT) != 0) { ch[pos++] = 'p'; } /* [15] (at worst case this needs 16 characters) */ ch[pos] = 0; if(!t->vector) { int vartype = t->n.nd->vartype; if((vartype < 0) || (vartype > ND_VARTYPE_MAX)) { vartype = 0; } if(vartype) { ch[pos++] = ':'; strcpy(ch + pos, vartype_strings[vartype]); pos += strlen(vartype_strings[vartype]); ch[++pos] = 0; } } return(pos); } /************************************************************************************************/ static void local_trace_asciival(Trptr t, char *tname, TimeType tim, int *nmaxlen, int *vmaxlen, char **asciivalue) { int len=0; int vlen=0; if(tname) { len=font_engine_string_measure(GLOBALS->wavefont, tname); if((tim!=-1)&&(!(t->flags&TR_EXCLUDE))) { GLOBALS->shift_timebase=t->shift; if(t->vector) { char *str; vptr v; v=bsearch_vector(t->n.vec,tim - t->shift); str=convert_ascii(t,v); if(str) { vlen=font_engine_string_measure(GLOBALS->wavefont,str); *asciivalue=str; } else { vlen=0; *asciivalue=NULL; } } else { char *str; hptr h_ptr; if((h_ptr=bsearch_node(t->n.nd,tim - t->shift))) { if(!t->n.nd->extvals) { unsigned char h_val = h_ptr->v.h_val; if(t->n.nd->vartype == ND_VCD_EVENT) { h_val = (h_ptr->time >= GLOBALS->tims.first) && ((GLOBALS->tims.marker-GLOBALS->shift_timebase) == h_ptr->time) ? AN_1 : AN_0; /* generate impulse */ } str=(char *)calloc_2(1,2*sizeof(char)); if(t->flags&TR_INVERT) { str[0]=AN_STR_INV[h_val]; } else { str[0]=AN_STR[h_val]; } *asciivalue=str; vlen=font_engine_string_measure(GLOBALS->wavefont,str); } else { if(h_ptr->flags&HIST_REAL) { if(!(h_ptr->flags&HIST_STRING)) { #ifdef WAVE_HAS_H_DOUBLE str=convert_ascii_real(t, &h_ptr->v.h_double); #else str=convert_ascii_real(t, (double *)h_ptr->v.h_vector); #endif } else { str=convert_ascii_string((char *)h_ptr->v.h_vector); } } else { str=convert_ascii_vec(t,h_ptr->v.h_vector); } if(str) { vlen=font_engine_string_measure(GLOBALS->wavefont,str); *asciivalue=str; } else { vlen=0; *asciivalue=NULL; } } } else { vlen=0; *asciivalue=NULL; } } } } *nmaxlen = len; *vmaxlen = vlen; } /************************************************************************************************/ static gint expose_event(GtkWidget *widget, GdkEventExpose *event) { gdk_draw_pixmap(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE(widget)], GLOBALS->mo_pixmap_mouseover_c_1, event->area.x, event->area.y, event->area.x, event->area.y, event->area.width, event->area.height); return(FALSE); } static void create_mouseover_sigs(gint x, gint y, gint width, gint height) { GLOBALS->mo_width_mouseover_c_1 = width; GLOBALS->mo_height_mouseover_c_1 = height; GLOBALS->mouseover_mouseover_c_1 = gtk_window_new(GTK_WINDOW_POPUP); gtk_window_set_default_size(GTK_WINDOW (GLOBALS->mouseover_mouseover_c_1), width, height); #ifdef WAVE_USE_GTK2 gtk_window_set_type_hint(GTK_WINDOW(GLOBALS->mouseover_mouseover_c_1), GDK_WINDOW_TYPE_HINT_SPLASHSCREEN); gtk_window_move(GTK_WINDOW(GLOBALS->mouseover_mouseover_c_1), x, y); #endif GLOBALS->mo_area_mouseover_c_1=gtk_drawing_area_new(); gtk_container_add(GTK_CONTAINER(GLOBALS->mouseover_mouseover_c_1), GLOBALS->mo_area_mouseover_c_1); gtk_widget_show(GLOBALS->mo_area_mouseover_c_1); gtk_widget_show(GLOBALS->mouseover_mouseover_c_1); #ifndef WAVE_USE_GTK2 gtk_window_reposition(GTK_WINDOW(GLOBALS->mouseover_mouseover_c_1), x, y); /* cuts down on GTK+-1.2 visual noise by moving it here */ #endif GLOBALS->mo_pixmap_mouseover_c_1 = gdk_pixmap_new(GLOBALS->mo_area_mouseover_c_1->window, GLOBALS->mouseover_mouseover_c_1->allocation.width, GLOBALS->mouseover_mouseover_c_1->allocation.height, -1); if(!GLOBALS->mo_dk_gray_mouseover_c_1) GLOBALS->mo_dk_gray_mouseover_c_1 = alloc_color(GLOBALS->mo_area_mouseover_c_1, 0x00cccccc, NULL); if(!GLOBALS->mo_black_mouseover_c_1) GLOBALS->mo_black_mouseover_c_1 = alloc_color(GLOBALS->mo_area_mouseover_c_1, 0x00000000, NULL); gdk_draw_rectangle(GLOBALS->mo_pixmap_mouseover_c_1, GLOBALS->mo_dk_gray_mouseover_c_1, TRUE, 0,0, GLOBALS->mo_width_mouseover_c_1, GLOBALS->mo_height_mouseover_c_1); gdk_draw_rectangle(GLOBALS->mo_pixmap_mouseover_c_1, GLOBALS->mo_black_mouseover_c_1, TRUE, 1,1, GLOBALS->mo_width_mouseover_c_1-2, GLOBALS->mo_height_mouseover_c_1-2); gtkwave_signal_connect(GTK_OBJECT(GLOBALS->mo_area_mouseover_c_1), "expose_event",GTK_SIGNAL_FUNC(expose_event), NULL); } #define MOUSEOVER_BREAKSIZE (100) void move_mouseover_sigs(Trptr t, gint xin, gint yin, TimeType tim) { gint xd = 0, yd = 0; char *asciivalue = NULL; int nmaxlen = 0, vmaxlen = 0; int totalmax = 0; int name_charlen = 0, value_charlen = 0; int num_info_rows = 2; char *flagged_name = NULL; char *alternate_name = NULL; int fh; char flag_string[65]; char *tname = NULL; if(GLOBALS->disable_mouseover) { if(GLOBALS->mouseover_mouseover_c_1) { gtk_widget_destroy(GLOBALS->mouseover_mouseover_c_1); GLOBALS->mouseover_mouseover_c_1 = NULL; gdk_pixmap_unref(GLOBALS->mo_pixmap_mouseover_c_1); GLOBALS->mo_pixmap_mouseover_c_1 = NULL; } goto bot; } fh = GLOBALS->wavefont->ascent+GLOBALS->wavefont->descent; if(t && (tname = get_fullname(t))) { local_trace_asciival(t, tname, tim, &nmaxlen, &vmaxlen, &asciivalue); value_charlen = asciivalue ? strlen(asciivalue) : 0; name_charlen = tname ? strlen(tname) : 0; if(name_charlen) { int len = determine_trace_flags(t, flag_string); flagged_name = malloc_2(name_charlen + 1 + len + 1); memcpy(flagged_name, tname, name_charlen); flagged_name[name_charlen] = ' '; strcpy(flagged_name+name_charlen+1, flag_string); name_charlen += (len + 1); } if(name_charlen > MOUSEOVER_BREAKSIZE) { alternate_name = malloc_2(MOUSEOVER_BREAKSIZE + 1); strcpy(alternate_name, "..."); strcpy(alternate_name + 3, flagged_name + name_charlen - (MOUSEOVER_BREAKSIZE - 3)); nmaxlen=font_engine_string_measure(GLOBALS->wavefont, alternate_name); } else { nmaxlen=font_engine_string_measure(GLOBALS->wavefont, flagged_name); } if(value_charlen > MOUSEOVER_BREAKSIZE) { char breakbuf[MOUSEOVER_BREAKSIZE+1]; int i, localmax; num_info_rows = (value_charlen + (MOUSEOVER_BREAKSIZE-1)) / MOUSEOVER_BREAKSIZE; vmaxlen = 0; for(i=0;iwavefont, breakbuf); vmaxlen = (localmax > vmaxlen) ? localmax : vmaxlen; } num_info_rows++; } totalmax = (nmaxlen > vmaxlen) ? nmaxlen : vmaxlen; totalmax += 8; totalmax = (totalmax + 1) & ~1; /* round up to next even pixel count */ if((GLOBALS->mouseover_mouseover_c_1)&&((totalmax != GLOBALS->mo_width_mouseover_c_1)||((num_info_rows * fh + 7) != GLOBALS->mo_height_mouseover_c_1))) { gtk_widget_destroy(GLOBALS->mouseover_mouseover_c_1); GLOBALS->mouseover_mouseover_c_1 = NULL; gdk_pixmap_unref(GLOBALS->mo_pixmap_mouseover_c_1); GLOBALS->mo_pixmap_mouseover_c_1 = NULL; } } if((!t)||(!tname)||(yin<0)||(yin>GLOBALS->waveheight)) { if(GLOBALS->mouseover_mouseover_c_1) { gtk_widget_destroy(GLOBALS->mouseover_mouseover_c_1); GLOBALS->mouseover_mouseover_c_1 = NULL; gdk_pixmap_unref(GLOBALS->mo_pixmap_mouseover_c_1); GLOBALS->mo_pixmap_mouseover_c_1 = NULL; } goto bot; } if(!GLOBALS->mouseover_mouseover_c_1) { #ifdef WAVE_USE_GTK2 gdk_window_get_origin(GLOBALS->signalarea->window, &xd, &yd); #else gdk_window_get_deskrelative_origin(GLOBALS->signalarea->window, &xd, &yd); #endif create_mouseover_sigs(xin + xd + 8, yin + yd + 20, totalmax, num_info_rows * fh + 7); } else { #ifdef WAVE_USE_GTK2 gdk_window_get_origin(GLOBALS->signalarea->window, &xd, &yd); gtk_window_move(GTK_WINDOW(GLOBALS->mouseover_mouseover_c_1), xin + xd + 8, yin + yd + 20); #else gdk_window_get_deskrelative_origin(GLOBALS->signalarea->window, &xd, &yd); gtk_window_reposition(GTK_WINDOW(GLOBALS->mouseover_mouseover_c_1), xin + xd + 8, yin + yd + 20); #endif } gdk_draw_rectangle(GLOBALS->mo_pixmap_mouseover_c_1, GLOBALS->mo_dk_gray_mouseover_c_1, TRUE, 0,0, GLOBALS->mo_width_mouseover_c_1, GLOBALS->mo_height_mouseover_c_1); gdk_draw_rectangle(GLOBALS->mo_pixmap_mouseover_c_1, GLOBALS->mo_black_mouseover_c_1, TRUE, 1,1, GLOBALS->mo_width_mouseover_c_1-2, GLOBALS->mo_height_mouseover_c_1-2); font_engine_draw_string(GLOBALS->mo_pixmap_mouseover_c_1, GLOBALS->wavefont, GLOBALS->mo_dk_gray_mouseover_c_1, 4, fh + 2, alternate_name ? alternate_name : flagged_name); if(num_info_rows == 2) { if(asciivalue) font_engine_draw_string(GLOBALS->mo_pixmap_mouseover_c_1, GLOBALS->wavefont, GLOBALS->mo_dk_gray_mouseover_c_1, 4, 2*fh+2, asciivalue); } else { char breakbuf[MOUSEOVER_BREAKSIZE+1]; int i; num_info_rows--; for(i=0;imo_pixmap_mouseover_c_1, GLOBALS->wavefont, GLOBALS->mo_dk_gray_mouseover_c_1, 4, ((2+i)*fh)+2, breakbuf); } } gdk_window_raise(GLOBALS->mouseover_mouseover_c_1->window); gdk_draw_pixmap(GLOBALS->mo_area_mouseover_c_1->window, GLOBALS->mo_area_mouseover_c_1->style->fg_gc[GTK_WIDGET_STATE(GLOBALS->mouseover_mouseover_c_1)],GLOBALS->mo_pixmap_mouseover_c_1,0,0,0,0,GLOBALS->mo_width_mouseover_c_1, GLOBALS->mo_height_mouseover_c_1); bot: if(asciivalue) { free_2(asciivalue); } if(alternate_name) { free_2(alternate_name); } if(flagged_name) { free_2(flagged_name); } if(tname) { free_2(tname); } } gtkwave-3.3.66/src/interp.c0000664000076400007640000002171712341266475015055 0ustar bybellbybell/********** Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group Spice is covered now covered by the BSD Copyright: Copyright (c) 1985-1991 The Regents of the University of California. All rights reserved. Permission is hereby granted, without written agreement and without license or royalty fees, to use, copy, modify, and distribute this software and its documentation for any purpose, provided that the above copyright notice and the following two paragraphs appear in all copies of this software. IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. **********/ /* * Polynomial interpolation code. */ #include #include #include #include #include #ifndef HAVE_BZERO #define bcopy(a,b,c) memcpy((b),(a),(c)) #define bzero(a,b) memset((a),0,(b)) #define bcmp(a,b,c) memcmp((a),(b),(c)) #endif #if 0 static void printmat (char *name, double *mat, int m, int n) { int i, j; printf ("\n\r=== Matrix: %s ===\n\r", name); for (i = 0; i < m; i++) { printf (" | "); for (j = 0; j < n; j++) printf ("%G ", mat[i * n + j]); printf ("|\n\r"); } printf ("===\n\r"); return; } #endif static double ft_peval (double x, double *coeffs, int degree) { double y; int i; if (!coeffs) return 0.0; /* XXX Should not happen */ y = coeffs[degree]; /* there are (degree+1) coeffs */ for (i = degree - 1; i >= 0; i--) { y *= x; y += coeffs[i]; } return y; } /* Returns the index of the last element that was calculated. oval is the * value of the old scale at the end of the interval that is being interpolated * from, and sign is 1 if the old scale was increasing, and -1 if it was * decreasing. */ static int putinterval (double *poly, int degree, double *nvec, int last, double *nscale, int nlen, double oval, int sign) { int end, i; /* See how far we have to go. */ for (end = last + 1; end < nlen; end++) if (nscale[end] * sign > oval * sign) break; end--; for (i = last + 1; i <= end; i++) nvec[i] = ft_peval (nscale[i], poly, degree); return (end); } /* Takes n = (degree+1) doubles, and fills in result with the n coefficients * of the polynomial that will fit them. It also takes a pointer to an * array of n ^ 2 + n doubles to use for scratch -- we want to make this * fast and avoid doing mallocs for each call. */ static int ft_polyfit (double *xdata, double *ydata, double *result, int degree, double *scratch) { double *mat1 = scratch; int l, k, j, i; int n = degree + 1; double *mat2 = scratch + n * n; /* XXX These guys are hacks! */ double d; bzero ((char *) result, n * sizeof (double)); bzero ((char *) mat1, n * n * sizeof (double)); bcopy ((char *) ydata, (char *) mat2, n * sizeof (double)); /* Fill in the matrix with x^k for 0 <= k <= degree for each point */ l = 0; for (i = 0; i < n; i++) { d = 1.0; for (j = 0; j < n; j++) { mat1[l] = d; d *= xdata[i]; l += 1; } } /* Do Gauss-Jordan elimination on mat1. */ for (i = 0; i < n; i++) { int lindex; double largest; /* choose largest pivot */ for (j = i, largest = mat1[i * n + i], lindex = i; j < n; j++) { if (fabs (mat1[j * n + i]) > largest) { largest = fabs (mat1[j * n + i]); lindex = j; } } if (lindex != i) { /* swap rows i and lindex */ for (k = 0; k < n; k++) { d = mat1[i * n + k]; mat1[i * n + k] = mat1[lindex * n + k]; mat1[lindex * n + k] = d; } d = mat2[i]; mat2[i] = mat2[lindex]; mat2[lindex] = d; } /* Make sure we have a non-zero pivot. */ if (mat1[i * n + i] == 0.0) { /* this should be rotated. */ return (0); } for (j = i + 1; j < n; j++) { d = mat1[j * n + i] / mat1[i * n + i]; for (k = 0; k < n; k++) mat1[j * n + k] -= d * mat1[i * n + k]; mat2[j] -= d * mat2[i]; } } for (i = n - 1; i > 0; i--) for (j = i - 1; j >= 0; j--) { d = mat1[j * n + i] / mat1[i * n + i]; for (k = 0; k < n; k++) mat1[j * n + k] -= d * mat1[i * n + k]; mat2[j] -= d * mat2[i]; } /* Now write the stuff into the result vector. */ for (i = 0; i < n; i++) { result[i] = mat2[i] / mat1[i * n + i]; /* printf(stderr, "result[%d] = %G\n", i, result[i]); */ } #define ABS_TOL 0.001 #define REL_TOL 0.001 /* Let's check and make sure the coefficients are ok. If they aren't, * just return false. This is not the best way to do it. */ for (i = 0; i < n; i++) { d = ft_peval (xdata[i], result, degree); if (fabs (d - ydata[i]) > ABS_TOL) { /* fprintf(stderr, "Error: polyfit: x = %le, y = %le, int = %le\n", xdata[i], ydata[i], d); printmat("mat1", mat1, n, n); printmat("mat2", mat2, n, 1); */ return (0); } else if (fabs (d - ydata[i]) / (fabs (d) > ABS_TOL ? fabs (d) : ABS_TOL) > REL_TOL) { /* fprintf(stderr, "Error: polyfit: x = %le, y = %le, int = %le\n", xdata[i], ydata[i], d); printmat("mat1", mat1, n, n); printmat("mat2", mat2, n, 1); */ return (0); } } return (1); } /* Interpolate data from oscale to nscale. data is assumed to be olen long, * ndata will be nlen long. Returns false if the scales are too strange * to deal with. Note that we are guaranteed that either both scales are * strictly increasing or both are strictly decreasing. * * Usage: return indicates success or failure * * data[] = old y * oscale[] = old x * olen = size of above array * * ndata[] = routine fills in with new y * nscale[] = user fills in with new x * nlen = user fills in with size of above array * * note that degree > 2 will result in bumpy curves if the derivatives * are not smooth */ int ft_interpolate (double *data, double *ndata, double *oscale, int olen, double *nscale, int nlen, int degree) { double *result, *scratch, *xdata, *ydata; int sign, lastone, i, l; int rc; if ((olen < 2) || (nlen < 2)) { /* fprintf(stderr, "Error: lengths too small to interpolate.\n"); */ return (0); } if ((degree < 1) || (degree > olen)) { /* fprintf(stderr, "Error: degree is %d, can't interpolate.\n", degree); */ return (0); } if (oscale[1] < oscale[0]) sign = -1; else sign = 1; scratch = (double *) malloc ((degree + 1) * (degree + 2) * sizeof (double)); result = (double *) malloc ((degree + 1) * sizeof (double)); xdata = (double *) malloc ((degree + 1) * sizeof (double)); ydata = (double *) malloc ((degree + 1) * sizeof (double)); /* Deal with the first degree pieces. */ bcopy ((char *) data, (char *) ydata, (degree + 1) * sizeof (double)); bcopy ((char *) oscale, (char *) xdata, (degree + 1) * sizeof (double)); while (!ft_polyfit (xdata, ydata, result, degree, scratch)) { /* If it doesn't work this time, bump the interpolation * degree down by one. */ if (--degree == 0) { /* fprintf(stderr, "ft_interpolate: Internal Error.\n"); */ rc = 0; goto bot; } } /* Add this part of the curve. What we do is evaluate the polynomial * at those points between the last one and the one that is greatest, * without being greater than the leftmost old scale point, or least * if the scale is decreasing at the end of the interval we are looking * at. */ lastone = -1; for (i = 0; i < degree; i++) { lastone = putinterval (result, degree, ndata, lastone, nscale, nlen, xdata[i], sign); } /* Now plot the rest, piece by piece. l is the * last element under consideration. */ for (l = degree + 1; l < olen; l++) { /* Shift the old stuff by one and get another value. */ for (i = 0; i < degree; i++) { xdata[i] = xdata[i + 1]; ydata[i] = ydata[i + 1]; } ydata[i] = data[l]; xdata[i] = oscale[l]; while (!ft_polyfit (xdata, ydata, result, degree, scratch)) { if (--degree == 0) { /* fprintf(stderr, "interpolate: Internal Error.\n"); */ rc = 0; goto bot; } } lastone = putinterval (result, degree, ndata, lastone, nscale, nlen, xdata[i], sign); } if (lastone < nlen - 1) /* ??? */ ndata[nlen - 1] = data[olen - 1]; rc = 1; bot: free (scratch); free (xdata); free (ydata); free (result); return (rc); } gtkwave-3.3.66/src/strace.h0000664000076400007640000000543412341266475015040 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2010. * * 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. */ #include "globals.h" #ifndef GTKWAVE_STRACE_H #define GTKWAVE_STRACE_H #include #include #include #include "debug.h" #include "analyzer.h" #include "currenttime.h" #include "bsearch.h" #if WAVE_USE_GTK2 #define WAVE_NUM_STRACE_WINDOWS (2) #else #define WAVE_NUM_STRACE_WINDOWS (1) #endif #define WAVE_STRACE_ITERATOR(x) for((x)=((WAVE_NUM_STRACE_WINDOWS)-1); (x)>=0 ; (x)--) #define WAVE_STRACE_ITERATOR_FWD(x) for((x)=0;(x)<(WAVE_NUM_STRACE_WINDOWS);(x)++) enum strace_directions { STRACE_BACKWARD, STRACE_FORWARD }; enum st_stype {ST_DC, ST_HIGH, ST_MID, ST_X, ST_LOW, ST_STRING, ST_RISE, ST_FALL, ST_ANY, WAVE_STYPE_COUNT}; struct strace_defer_free { struct strace_defer_free *next; Trptr defer; }; struct strace_back { struct strace *parent; int which; }; struct strace { struct strace *next; char *string; /* unmalloc this when all's done! */ Trptr trace; char value; char search_result; union { hptr h; /* what makes up this trace */ vptr v; } his; struct strace_back *back[WAVE_STYPE_COUNT]; /* dealloc these too! */ }; struct timechain { struct timechain *next; TimeType t; }; struct mprintf_buff_t { struct mprintf_buff_t *next; char *str; }; struct item_mark_string { char *str; unsigned char idx; }; /* for being able to handle multiple strace sessions at once, context is moved here */ struct strace_ctx_t { GtkWidget *ptr_mark_count_label_strace_c_1; struct strace *straces; struct strace *shadow_straces; struct strace_defer_free *strace_defer_free_head; GtkWidget *window_strace_c_10; void (*cleanup_strace_c_7)(void); struct mprintf_buff_t *mprintf_buff_head; struct mprintf_buff_t *mprintf_buff_current; char *shadow_string; TimeType *timearray; int timearray_size; char logical_mutex[6]; char shadow_logical_mutex[6]; char shadow_active; char shadow_encountered_parsewavline; char shadow_type; signed char mark_idx_start; signed char mark_idx_end; signed char shadow_mark_idx_start; signed char shadow_mark_idx_end; }; void strace_search(int direction); void strace_maketimetrace(int mode); /* 1=create, zero=delete */ TimeType strace_adjust(TimeType a, TimeType b); void swap_strace_contexts(void); void delete_strace_context(void); void cache_actual_pattern_mark_traces(void); void edge_search(int direction); /* from edgebuttons.c */ int mprintf(const char *fmt, ... ); void delete_mprintf(void); void tracesearchbox(const char *title, GtkSignalFunc func, gpointer data); #endif gtkwave-3.3.66/src/gnu-getopt.h0000664000076400007640000001436111572536221015641 0ustar bybellbybell/* Declarations for getopt. Copyright (C) 1989-1994, 1996-1999, 2001 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library 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 2.1 of the License, or (at your option) any later version. The GNU C Library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA */ #ifndef _GETOPT_H #ifndef __need_getopt # define _GETOPT_H 1 #endif /* If __GNU_LIBRARY__ is not already defined, either we are being used standalone, or this is the first header included in the source file. If we are being used with glibc, we need to include , but that does not exist if we are standalone. So: if __GNU_LIBRARY__ is not defined, include , which will pull in for us if it's from glibc. (Why ctype.h? It's guaranteed to exist and it doesn't flood the namespace with stuff the way some other headers do.) */ #if !defined __GNU_LIBRARY__ # include #endif #ifdef __cplusplus extern "C" { #endif /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns -1, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ /* Callers store zero here to inhibit the error message `getopt' prints for unrecognized options. */ /* Set to an option character which was unrecognized. */ #ifndef __need_getopt /* Describe the long-named options requested by the application. The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector of `struct option' terminated by an element containing a name which is zero. The field `has_arg' is: no_argument (or 0) if the option does not take an argument, required_argument (or 1) if the option requires an argument, optional_argument (or 2) if the option takes an optional argument. If the field `flag' is not NULL, it points to a variable that is set to the value given in the field `val' when the option is found, but left unchanged if the option is not found. To have a long-named option do something other than set an `int' to a compiled-in constant, such as set a value from `optarg', set the option's `flag' field to zero and its `val' field to a nonzero value (the equivalent single-letter option character, if there is one). For long options that have a zero `flag' field, `getopt' returns the contents of the `val' field. */ struct option { # if (defined __STDC__ && __STDC__) || defined __cplusplus const char *name; # else char *name; # endif /* has_arg can't be an enum because some compilers complain about type mismatches in all the code that assumes it is an int. */ int has_arg; int *flag; int val; }; /* Names for the values of the `has_arg' field of `struct option'. */ # define no_argument 0 # define required_argument 1 # define optional_argument 2 #endif /* need getopt */ /* Get definitions and prototypes for functions to process the arguments in ARGV (ARGC of them, minus the program name) for options given in OPTS. Return the option character from OPTS just read. Return -1 when there are no more options. For unrecognized options, or options missing arguments, `optopt' is set to the option letter, and '?' is returned. The OPTS string is a list of characters which are recognized option letters, optionally followed by colons, specifying that that letter takes an argument, to be placed in `optarg'. If a letter in OPTS is followed by two colons, its argument is optional. This behavior is specific to the GNU `getopt'. The argument `--' causes premature termination of argument scanning, explicitly telling `getopt' that there are no more options. If OPTS begins with `--', then non-option arguments are treated as arguments to the option '\0'. This behavior is specific to the GNU `getopt'. */ #if (defined __STDC__ && __STDC__) || defined __cplusplus # ifdef __GNU_LIBRARY__ /* Many other libraries have conflicting prototypes for getopt, with differences in the consts, in stdlib.h. To avoid compilation errors, only prototype getopt for the GNU C library. */ extern int getopt (int ___argc, char *const *___argv, const char *__shortopts); # else /* not __GNU_LIBRARY__ */ extern int getopt (); # endif /* __GNU_LIBRARY__ */ # ifndef __need_getopt extern int getopt_long (int ___argc, char *const *___argv, const char *__shortopts, const struct option *__longopts, int *__longind); extern int getopt_long_only (int ___argc, char *const *___argv, const char *__shortopts, const struct option *__longopts, int *__longind); /* Internal only. Users should not call this directly. */ extern int _getopt_internal (int ___argc, char *const *___argv, const char *__shortopts, const struct option *__longopts, int *__longind, int __long_only); # endif #else /* not __STDC__ */ extern int getopt (); # ifndef __need_getopt extern int getopt_long (); extern int getopt_long_only (); extern int _getopt_internal (); # endif #endif /* __STDC__ */ #ifdef __cplusplus } #endif /* Make sure we later can get all the definitions and declarations. */ #undef __need_getopt #endif /* getopt.h */ gtkwave-3.3.66/src/lxt.c0000664000076400007640000020221212360312657014345 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2001-2014. * * 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. */ #include #include #include "zlib.h" #include "bzlib.h" #if !defined __MINGW32__ && !defined _MSC_VER #include #include #else #include #include #endif #include"globals.h" #include #include #include #include #include #include "symbol.h" #include "vcd.h" #include "lxt.h" #include "bsearch.h" #include "debug.h" #include "hierpack.h" /****************************************************************************/ /* * functions which emit various big endian * data to a file */ static int lt_emit_u8(FILE *handle, int value) { unsigned char buf[1]; int nmemb; buf[0] = value & 0xff; nmemb=fwrite(buf, sizeof(char), 1, handle); GLOBALS->fpos_lxt_c_1+=nmemb; return(nmemb); } static int lt_emit_u16(FILE *handle, int value) { unsigned char buf[2]; int nmemb; buf[0] = (value>>8) & 0xff; buf[1] = value & 0xff; nmemb = fwrite(buf, sizeof(char), 2, handle); GLOBALS->fpos_lxt_c_1+=nmemb; return(nmemb); } static int lt_emit_u24(FILE *handle, int value) { unsigned char buf[3]; int nmemb; buf[0] = (value>>16) & 0xff; buf[1] = (value>>8) & 0xff; buf[2] = value & 0xff; nmemb=fwrite(buf, sizeof(char), 3, handle); GLOBALS->fpos_lxt_c_1+=nmemb; return(nmemb); } static int lt_emit_u32(FILE *handle, int value) { unsigned char buf[4]; int nmemb; buf[0] = (value>>24) & 0xff; buf[1] = (value>>16) & 0xff; buf[2] = (value>>8) & 0xff; buf[3] = value & 0xff; nmemb=fwrite(buf, sizeof(char), 4, handle); GLOBALS->fpos_lxt_c_1+=nmemb; return(nmemb); } /****************************************************************************/ #define LXTHDR "LXTLOAD | " /* its mmap() variant doesn't use file descriptors */ #if defined __MINGW32__ || defined _MSC_VER #define PROT_READ (0) #define MAP_SHARED (0) HANDLE hIn, hInMap; char *win_fname = NULL; void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) { close(fd); hIn = CreateFile(win_fname, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(hIn == INVALID_HANDLE_VALUE) { fprintf(stderr, "Could not open '%s' with CreateFile(), exiting.\n", win_fname); exit(255); } hInMap = CreateFileMapping(hIn, NULL, PAGE_READONLY, 0, 0, NULL); return(MapViewOfFile(hInMap, FILE_MAP_READ, 0, 0, 0)); } int munmap(void *start, size_t length) { UnmapViewOfFile(start); CloseHandle(hInMap); hInMap = NULL; CloseHandle(hIn); hIn = NULL; return(0); } #endif /****************************************************************************/ #ifdef _WAVE_BE32 /* * reconstruct 8/16/24/32 bits out of the lxt's representation * of a big-endian integer. this is for 32-bit PPC so no byte * swizzling needs to be done at all. for 24-bit ints, we have no danger of * running off the end of memory provided we do the "-1" trick * since we'll never read a 24-bit int at the very start of a file which * means that we'll have a 32-bit word that we can read. */ inline static unsigned int get_byte(offset) { return ((unsigned int)(*((unsigned char *)(GLOBALS->mm_lxt_c_1)+(offset)))); } inline static unsigned int get_16(offset) { return ((unsigned int)(*((unsigned short *)(((unsigned char *)(GLOBALS->mm_lxt_c_1)) +(offset))))); } inline static unsigned int get_32(offset) { return (*(unsigned int *)(((unsigned char *)(GLOBALS->mm_lxt_c_1))+(offset))); } inline static unsigned int get_24(offset) { return ((get_32((offset)-1)<<8)>>8); } inline static unsigned int get_64(offset) { return ((((UTimeType)get_32(offset))<<32)|((UTimeType)get_32((offset)+4))); } #else /* * reconstruct 8/16/24/32 bits out of the lxt's representation * of a big-endian integer. this should work on all architectures. */ #define get_byte(offset) ((unsigned int)(*((unsigned char *)GLOBALS->mm_lxt_c_1+offset))) static unsigned int get_16(off_t offset) { unsigned char *nn=(unsigned char *)GLOBALS->mm_lxt_c_1+offset; unsigned int m1=*((unsigned char *)(nn++)); unsigned int m2=*((unsigned char *)nn); return((m1<<8)|m2); } static unsigned int get_24(off_t offset) { unsigned char *nn=(unsigned char *)GLOBALS->mm_lxt_c_1+offset; unsigned int m1=*((unsigned char *)(nn++)); unsigned int m2=*((unsigned char *)(nn++)); unsigned int m3=*((unsigned char *)nn); return((m1<<16)|(m2<<8)|m3); } static unsigned int get_32(off_t offset) { unsigned char *nn=(unsigned char *)GLOBALS->mm_lxt_c_1+offset; unsigned int m1=*((unsigned char *)(nn++)); unsigned int m2=*((unsigned char *)(nn++)); unsigned int m3=*((unsigned char *)(nn++)); unsigned int m4=*((unsigned char *)nn); return((m1<<24)|(m2<<16)|(m3<<8)|m4); } static UTimeType get_64(off_t offset) { return( (((UTimeType)get_32(offset))<<32) |((UTimeType)get_32(offset+4)) ); } #endif /****************************************************************************/ static void create_double_endian_mask(int offset) { double d; int i, j; static double p = 3.14159; d= *((double *)((unsigned char *)GLOBALS->mm_lxt_c_1+offset)); if(p==d) { GLOBALS->double_is_native_lxt_c_1=1; } else { char *remote, *here; remote = (char *)&d; here = (char *)&p; for(i=0;i<8;i++) { for(j=0;j<8;j++) { if(here[i]==remote[j]) { GLOBALS->double_mask_lxt_c_1[i]=j; break; } } } } } static char *swab_double_via_mask(int offset) { char swapbuf[8]; char *pnt = malloc_2(8*sizeof(char)); int i; memcpy(swapbuf, ((unsigned char *)GLOBALS->mm_lxt_c_1+offset), 8); for(i=0;i<8;i++) { pnt[i]=swapbuf[GLOBALS->double_mask_lxt_c_1[i]]; } return(pnt); } /****************************************************************************/ /* * convert 0123 to an mvl character representation */ static unsigned char convert_mvl(int value) { return("01zxhuwl-xxxxxxx"[value&15]); } /* * given an offset into the aet, calculate the "time" of that * offset in simulation. this func similar to how gtkwave can * find the most recent valuechange that corresponds with * an arbitrary timevalue. */ static int compar_mvl_timechain(const void *s1, const void *s2) { int key, obj, delta; int rv; key=*((int *)s1); obj=*((int *)s2); if((obj<=key)&&(obj>GLOBALS->max_compare_time_tc_lxt_c_2)) { GLOBALS->max_compare_time_tc_lxt_c_2=obj; GLOBALS->max_compare_pos_tc_lxt_c_2=(int *)s2 - GLOBALS->positional_information_lxt_c_1; } delta=key-obj; if(delta<0) rv=-1; else if(delta>0) rv=1; else rv=0; return(rv); } static TimeType bsearch_mvl_timechain(int key) { GLOBALS->max_compare_time_tc_lxt_c_2=-1; GLOBALS->max_compare_pos_tc_lxt_c_2=-1; if(bsearch((void *)&key, (void *)GLOBALS->positional_information_lxt_c_1, GLOBALS->total_cycles_lxt_c_2, sizeof(int), compar_mvl_timechain)) { /* nothing, all side effects are in bsearch */ } if((GLOBALS->max_compare_pos_tc_lxt_c_2<=0)||(GLOBALS->max_compare_time_tc_lxt_c_2<0)) { GLOBALS->max_compare_pos_tc_lxt_c_2=0; /* aix bsearch fix */ } return(GLOBALS->time_information[GLOBALS->max_compare_pos_tc_lxt_c_2]); } /* * build up decompression dictionary for MVL2 facs >16 bits ... */ static void build_dict(void) { gzFile zhandle; off_t offs = GLOBALS->zdictionary_offset_lxt_c_1+24; int total_mem, rc; unsigned int i; char *decmem=NULL; char *pnt; #if defined __MINGW32__ || defined _MSC_VER FILE *tmp; #endif GLOBALS->dict_num_entries_lxt_c_1 = get_32(GLOBALS->zdictionary_offset_lxt_c_1+0); GLOBALS->dict_string_mem_required_lxt_c_1 = get_32(GLOBALS->zdictionary_offset_lxt_c_1+4); GLOBALS->dict_16_offset_lxt_c_1 = get_32(GLOBALS->zdictionary_offset_lxt_c_1+8); GLOBALS->dict_24_offset_lxt_c_1 = get_32(GLOBALS->zdictionary_offset_lxt_c_1+12); GLOBALS->dict_32_offset_lxt_c_1 = get_32(GLOBALS->zdictionary_offset_lxt_c_1+16); GLOBALS->dict_width_lxt_c_1 = get_32(GLOBALS->zdictionary_offset_lxt_c_1+20); DEBUG(fprintf(stderr, LXTHDR"zdictionary_offset = %08x\n", GLOBALS->zdictionary_offset_lxt_c_1)); DEBUG(fprintf(stderr, LXTHDR"zdictionary_predec_size = %08x\n\n", GLOBALS->zdictionary_predec_size_lxt_c_1)); DEBUG(fprintf(stderr, LXTHDR"dict_num_entries = %d\n", GLOBALS->dict_num_entries_lxt_c_1)); DEBUG(fprintf(stderr, LXTHDR"dict_string_mem_required = %d\n", GLOBALS->dict_string_mem_required_lxt_c_1)); DEBUG(fprintf(stderr, LXTHDR"dict_16_offset = %d\n", GLOBALS->dict_16_offset_lxt_c_1)); DEBUG(fprintf(stderr, LXTHDR"dict_24_offset = %d\n", GLOBALS->dict_24_offset_lxt_c_1)); DEBUG(fprintf(stderr, LXTHDR"dict_32_offset = %d\n", GLOBALS->dict_32_offset_lxt_c_1)); fprintf(stderr, LXTHDR"Dictionary compressed MVL2 change records detected...\n"); #if defined __MINGW32__ || defined _MSC_VER { unsigned char *t = (char *)GLOBALS->mm_lxt_c_1+offs; tmp = tmpfile(); if(!tmp) { fprintf(stderr, LXTHDR"could not open decompression tempfile, exiting.\n"); exit(255); } fwrite(t, GLOBALS->zdictionary_predec_size_lxt_c_1, 1, tmp); fseek(tmp, 0, SEEK_SET); zhandle = gzdopen(dup(fileno(tmp)), "rb"); } #else if(offs!=lseek(GLOBALS->fd_lxt_c_1, offs, SEEK_SET)) { fprintf(stderr, LXTHDR"dict lseek error at offset %08x\n", (unsigned int)offs); exit(255); } zhandle = gzdopen(dup(GLOBALS->fd_lxt_c_1), "rb"); #endif decmem = malloc_2(total_mem = GLOBALS->dict_string_mem_required_lxt_c_1); rc=gzread(zhandle, decmem, total_mem); DEBUG(printf(LXTHDR"section offs for name decompression = %08x of len %d\n", offs, GLOBALS->dict_num_entries_lxt_c_1)); DEBUG(printf(LXTHDR"Decompressed size is %d bytes (vs %d)\n", rc, total_mem)); if(rc!=total_mem) { fprintf(stderr, LXTHDR"decompression size disparity %d bytes (vs %d)\n", rc, total_mem); exit(255); } GLOBALS->dict_string_mem_array_lxt_c_1 = (char **)calloc_2(GLOBALS->dict_num_entries_lxt_c_1, sizeof(char *)); pnt = decmem; for(i=0;idict_num_entries_lxt_c_1;i++) { GLOBALS->dict_string_mem_array_lxt_c_1[i]=pnt; pnt+=(strlen(pnt)+1); DEBUG(printf(LXTHDR"Dict %d: '1%s'\n", i, GLOBALS->dict_string_mem_array_lxt_c_1[i])); } gzclose(zhandle); #if defined __MINGW32__ || defined _MSC_VER fclose(tmp); #endif fprintf(stderr, LXTHDR"...expanded %d entries from %08x into %08x bytes.\n", GLOBALS->dict_num_entries_lxt_c_1, GLOBALS->zdictionary_predec_size_lxt_c_1, GLOBALS->dict_string_mem_required_lxt_c_1); } /* * decompress facility names and build up fac geometry */ static void build_facs(char *fname, char **f_name, struct Node *node_block) { char *buf, *bufprev = NULL, *bufcurr; off_t offs=GLOBALS->facname_offset_lxt_c_1+8; int i, j, clone; char *pnt = NULL; int total_mem = get_32(GLOBALS->facname_offset_lxt_c_1+4); gzFile zhandle = NULL; char *decmem=NULL; #if defined __MINGW32__ || defined _MSC_VER FILE *tmp; #endif buf=malloc_2(total_mem); pnt=bufprev=buf; if(GLOBALS->zfacname_size_lxt_c_1) { int rc; #if defined __MINGW32__ || defined _MSC_VER unsigned char *t = (char *)GLOBALS->mm_lxt_c_1+offs; tmp = tmpfile(); if(!tmp) { fprintf(stderr, LXTHDR"could not open decompression tempfile, exiting.\n"); exit(255); } fwrite(t, GLOBALS->zfacname_size_lxt_c_1, 1, tmp); fseek(tmp, 0, SEEK_SET); zhandle = gzdopen(dup(fileno(tmp)), "rb"); #else if(offs!=lseek(GLOBALS->fd_lxt_c_1, offs, SEEK_SET)) { fprintf(stderr, LXTHDR"zfacname lseek error at offset %08x\n", (unsigned int)offs); exit(255); } zhandle = gzdopen(dup(GLOBALS->fd_lxt_c_1), "rb"); #endif GLOBALS->mmcache_lxt_c_1 = GLOBALS->mm_lxt_c_1; decmem = malloc_2(total_mem = GLOBALS->zfacname_predec_size_lxt_c_1); GLOBALS->mm_lxt_c_1 = decmem; rc=gzread(zhandle, decmem, total_mem); DEBUG(printf(LXTHDR"section offs for name decompression = %08x of len %d\n", offs, GLOBALS->zfacname_size_lxt_c_1)); DEBUG(printf(LXTHDR"Decompressed size is %d bytes (vs %d)\n", rc, total_mem)); if(rc!=total_mem) { fprintf(stderr, LXTHDR"decompression size disparity %d bytes (vs %d)\n", rc, total_mem); exit(255); } offs=0; /* we're in our new memory region now.. */ } fprintf(stderr, LXTHDR"Building %d facilities.\n", GLOBALS->numfacs); for(i=0;inumfacs;i++) { clone=get_16(offs); offs+=2; bufcurr=pnt; for(j=0;jzfacname_size_lxt_c_1) { GLOBALS->mm_lxt_c_1 = GLOBALS->mmcache_lxt_c_1; free_2(decmem); decmem = NULL; gzclose(zhandle); #if defined __MINGW32__ || defined _MSC_VER fclose(tmp); #endif } if(!GLOBALS->facgeometry_offset_lxt_c_1) { fprintf(stderr, "LXT '%s' is missing a facility geometry section, exiting.\n", fname); exit(255); } offs=GLOBALS->facgeometry_offset_lxt_c_1; if(GLOBALS->zfacgeometry_size_lxt_c_1) { int rc; #if defined __MINGW32__ || defined _MSC_VER unsigned char *t = (char *)GLOBALS->mm_lxt_c_1+offs; tmp = tmpfile(); if(!tmp) { fprintf(stderr, LXTHDR"could not open decompression tempfile, exiting.\n"); exit(255); } fwrite(t, GLOBALS->zfacgeometry_size_lxt_c_1, 1, tmp); fseek(tmp, 0, SEEK_SET); zhandle = gzdopen(dup(fileno(tmp)), "rb"); #else if(offs!=lseek(GLOBALS->fd_lxt_c_1, offs, SEEK_SET)) { fprintf(stderr, LXTHDR"zfacgeometry lseek error at offset %08x\n", (unsigned int)offs); exit(255); } zhandle = gzdopen(dup(GLOBALS->fd_lxt_c_1), "rb"); #endif GLOBALS->mmcache_lxt_c_1 = GLOBALS->mm_lxt_c_1; total_mem = GLOBALS->numfacs * 16; decmem = malloc_2(total_mem); GLOBALS->mm_lxt_c_1 = decmem; rc=gzread(zhandle, decmem, total_mem); DEBUG(printf(LXTHDR"section offs for facgeometry decompression = %08x of len %d\n", offs, GLOBALS->zfacgeometry_size_lxt_c_1)); DEBUG(printf(LXTHDR"Decompressed size is %d bytes (vs %d)\n", rc, total_mem)); if(rc!=total_mem) { fprintf(stderr, LXTHDR"decompression size disparity %d bytes (vs %d)\n", rc, total_mem); exit(255); } offs=0; /* we're in our new memory region now.. */ } for(i=0;inumfacs;i++) { GLOBALS->mvlfacs_lxt_c_2[i].node_alias=get_32(offs); node_block[i].msi=get_32(offs+4); node_block[i].lsi=get_32(offs+8); GLOBALS->mvlfacs_lxt_c_2[i].flags=get_32(offs+12); GLOBALS->mvlfacs_lxt_c_2[i].len=(node_block[i].lsi>node_block[i].msi)?(node_block[i].lsi-node_block[i].msi+1):(node_block[i].msi-node_block[i].lsi+1); if(GLOBALS->mvlfacs_lxt_c_2[i].len>GLOBALS->lt_len_lxt_c_1) GLOBALS->lt_len_lxt_c_1 = GLOBALS->mvlfacs_lxt_c_2[i].len; DEBUG(printf(LXTHDR"%s[%d:%d]\n", f_name[i], node_block[i].msi, node_block[i].lsi)); offs+=0x10; } GLOBALS->lt_buf_lxt_c_1 = malloc_2(GLOBALS->lt_len_lxt_c_1>255 ? GLOBALS->lt_len_lxt_c_1 : 256); /* in order to keep trivial LXT files from overflowing their buffer */ if(GLOBALS->zfacgeometry_size_lxt_c_1) { GLOBALS->mm_lxt_c_1 = GLOBALS->mmcache_lxt_c_1; free_2(decmem); decmem = NULL; gzclose(zhandle); #if defined __MINGW32__ || defined _MSC_VER fclose(tmp); #endif } } /* * build up the lastchange entries so we can start to walk * through the aet.. */ static void build_facs2(char *fname) { int i; off_t offs; int chg; int maxchg=0, maxindx=0; int last_position; TimeType last_time; char *decmem = NULL; int total_mem; gzFile zhandle = NULL; #if defined __MINGW32__ || defined _MSC_VER FILE *tmp; #endif if((!GLOBALS->time_table_offset_lxt_c_1)&&(!GLOBALS->time_table_offset64_lxt_c_1)) { fprintf(stderr, "LXT '%s' is missing a time table section, exiting.\n", fname); exit(255); } if((GLOBALS->time_table_offset_lxt_c_1)&&(GLOBALS->time_table_offset64_lxt_c_1)) { fprintf(stderr, "LXT '%s' has both 32 and 64-bit time table sections, exiting.\n", fname); exit(255); } if(GLOBALS->time_table_offset_lxt_c_1) { offs = GLOBALS->time_table_offset_lxt_c_1; DEBUG(printf(LXTHDR"Time table position: %08x\n", GLOBALS->time_table_offset_lxt_c_1 + 12)); GLOBALS->total_cycles_lxt_c_2=get_32(offs+0); DEBUG(printf(LXTHDR"Total cycles: %d\n", GLOBALS->total_cycles_lxt_c_2)); if(GLOBALS->ztime_table_size_lxt_c_1) { int rc; #if defined __MINGW32__ || defined _MSC_VER unsigned char *t = (char *)GLOBALS->mm_lxt_c_1+offs+4; tmp = tmpfile(); if(!tmp) { fprintf(stderr, LXTHDR"could not open decompression tempfile, exiting.\n"); exit(255); } fwrite(t, GLOBALS->ztime_table_size_lxt_c_1, 1, tmp); fseek(tmp, 0, SEEK_SET); zhandle = gzdopen(dup(fileno(tmp)), "rb"); #else if((offs+4)!=lseek(GLOBALS->fd_lxt_c_1, offs+4, SEEK_SET)) { fprintf(stderr, LXTHDR"ztime_table lseek error at offset %08x\n", (unsigned int)offs); exit(255); } zhandle = gzdopen(dup(GLOBALS->fd_lxt_c_1), "rb"); #endif GLOBALS->mmcache_lxt_c_1 = GLOBALS->mm_lxt_c_1; total_mem = 4 + 4 + (GLOBALS->total_cycles_lxt_c_2 * 4) + (GLOBALS->total_cycles_lxt_c_2 * 4); decmem = malloc_2(total_mem); GLOBALS->mm_lxt_c_1 = decmem; rc=gzread(zhandle, decmem, total_mem); DEBUG(printf(LXTHDR"section offs for timetable decompression = %08x of len %d\n", offs, GLOBALS->ztime_table_size_lxt_c_1)); DEBUG(printf(LXTHDR"Decompressed size is %d bytes (vs %d)\n", rc, total_mem)); if(rc!=total_mem) { fprintf(stderr, LXTHDR"decompression size disparity %d bytes (vs %d)\n", rc, total_mem); exit(255); } offs=0; /* we're in our new memory region now.. */ } else { offs+=4; /* skip past count to make consistent view between compressed/uncompressed */ } GLOBALS->first_cycle_lxt_c_2=get_32(offs); DEBUG(printf(LXTHDR"First cycle: %d\n", GLOBALS->first_cycle_lxt_c_2)); GLOBALS->last_cycle_lxt_c_2=get_32(offs+4); DEBUG(printf(LXTHDR"Last cycle: %d\n", GLOBALS->last_cycle_lxt_c_2)); DEBUG(printf(LXTHDR"Total cycles (actual): %d\n", GLOBALS->last_cycle_lxt_c_2-GLOBALS->first_cycle_lxt_c_2+1)); /* rebuild time table from its deltas... */ GLOBALS->positional_information_lxt_c_1 = (int *)malloc_2(GLOBALS->total_cycles_lxt_c_2 * sizeof(int)); last_position=0; offs+=8; for(i=0;itotal_cycles_lxt_c_2;i++) { last_position = GLOBALS->positional_information_lxt_c_1[i] = get_32(offs) + last_position; offs+=4; } GLOBALS->time_information = (TimeType *)malloc_2(GLOBALS->total_cycles_lxt_c_2 * sizeof(TimeType)); last_time=LLDescriptor(0); for(i=0;itotal_cycles_lxt_c_2;i++) { last_time = GLOBALS->time_information[i] = ((TimeType)get_32(offs)) + last_time; GLOBALS->time_information[i] *= (GLOBALS->time_scale); offs+=4; } if(GLOBALS->ztime_table_size_lxt_c_1) { GLOBALS->mm_lxt_c_1 = GLOBALS->mmcache_lxt_c_1; free_2(decmem); decmem = NULL; gzclose(zhandle); #if defined __MINGW32__ || defined _MSC_VER fclose(tmp); #endif } } else /* 64-bit read */ { offs = GLOBALS->time_table_offset64_lxt_c_1; DEBUG(printf(LXTHDR"Time table position: %08x\n", GLOBALS->time_table_offset64_lxt_c_1 + 20)); GLOBALS->total_cycles_lxt_c_2=(TimeType)((unsigned int)get_32(offs+0)); DEBUG(printf(LXTHDR"Total cycles: %d\n", GLOBALS->total_cycles_lxt_c_2)); if(GLOBALS->ztime_table_size_lxt_c_1) { int rc; #if defined __MINGW32__ || defined _MSC_VER unsigned char *t = (char *)GLOBALS->mm_lxt_c_1+offs+4; tmp = tmpfile(); if(!tmp) { fprintf(stderr, LXTHDR"could not open decompression tempfile, exiting.\n"); exit(255); } fwrite(t, GLOBALS->ztime_table_size_lxt_c_1, 1, tmp); fseek(tmp, 0, SEEK_SET); zhandle = gzdopen(dup(fileno(tmp)), "rb"); #else if((offs+4)!=lseek(GLOBALS->fd_lxt_c_1, offs+4, SEEK_SET)) { fprintf(stderr, LXTHDR"ztime_table lseek error at offset %08x\n", (unsigned int)offs); exit(255); } zhandle = gzdopen(dup(GLOBALS->fd_lxt_c_1), "rb"); #endif GLOBALS->mmcache_lxt_c_1 = GLOBALS->mm_lxt_c_1; total_mem = 8 + 8 + (GLOBALS->total_cycles_lxt_c_2 * 4) + (GLOBALS->total_cycles_lxt_c_2 * 8); decmem = malloc_2(total_mem); GLOBALS->mm_lxt_c_1 = decmem; rc=gzread(zhandle, decmem, total_mem); DEBUG(printf(LXTHDR"section offs for timetable decompression = %08x of len %d\n", offs, GLOBALS->ztime_table_size_lxt_c_1)); DEBUG(printf(LXTHDR"Decompressed size is %d bytes (vs %d)\n", rc, total_mem)); if(rc!=total_mem) { fprintf(stderr, LXTHDR"decompression size disparity %d bytes (vs %d)\n", rc, total_mem); exit(255); } offs=0; /* we're in our new memory region now.. */ } else { offs+=4; /* skip past count to make consistent view between compressed/uncompressed */ } GLOBALS->first_cycle_lxt_c_2=get_64(offs); DEBUG(printf(LXTHDR"First cycle: %d\n", GLOBALS->first_cycle_lxt_c_2)); GLOBALS->last_cycle_lxt_c_2=get_64(offs+8); DEBUG(printf(LXTHDR"Last cycle: %d\n", GLOBALS->last_cycle_lxt_c_2)); DEBUG(printf(LXTHDR"Total cycles (actual): %lld\n", GLOBALS->last_cycle_lxt_c_2-GLOBALS->first_cycle_lxt_c_2+1)); /* rebuild time table from its deltas... */ GLOBALS->positional_information_lxt_c_1 = (int *)malloc_2(GLOBALS->total_cycles_lxt_c_2 * sizeof(int)); last_position=0; offs+=16; for(i=0;itotal_cycles_lxt_c_2;i++) { last_position = GLOBALS->positional_information_lxt_c_1[i] = get_32(offs) + last_position; offs+=4; } GLOBALS->time_information = (TimeType *)malloc_2(GLOBALS->total_cycles_lxt_c_2 * sizeof(TimeType)); last_time=LLDescriptor(0); for(i=0;itotal_cycles_lxt_c_2;i++) { last_time = GLOBALS->time_information[i] = ((TimeType)get_64(offs)) + last_time; GLOBALS->time_information[i] *= (GLOBALS->time_scale); offs+=8; } if(GLOBALS->ztime_table_size_lxt_c_1) { GLOBALS->mm_lxt_c_1 = GLOBALS->mmcache_lxt_c_1; free_2(decmem); decmem = NULL; gzclose(zhandle); #if defined __MINGW32__ || defined _MSC_VER fclose(tmp); #endif } } if(GLOBALS->sync_table_offset_lxt_c_1) { offs = GLOBALS->sync_table_offset_lxt_c_1; if(GLOBALS->zsync_table_size_lxt_c_1) { int rc; #if defined __MINGW32__ || defined _MSC_VER unsigned char *t = (char *)GLOBALS->mm_lxt_c_1+offs; tmp = tmpfile(); if(!tmp) { fprintf(stderr, LXTHDR"could not open decompression tempfile, exiting.\n"); exit(255); } fwrite(t, GLOBALS->zsync_table_size_lxt_c_1, 1, tmp); fseek(tmp, 0, SEEK_SET); zhandle = gzdopen(dup(fileno(tmp)), "rb"); #else if(offs!=lseek(GLOBALS->fd_lxt_c_1, offs, SEEK_SET)) { fprintf(stderr, LXTHDR"zsync_table lseek error at offset %08x\n", (unsigned int)offs); exit(255); } zhandle = gzdopen(dup(GLOBALS->fd_lxt_c_1), "rb"); #endif GLOBALS->mmcache_lxt_c_1 = GLOBALS->mm_lxt_c_1; decmem = malloc_2(total_mem = GLOBALS->numfacs * 4); GLOBALS->mm_lxt_c_1 = decmem; rc=gzread(zhandle, decmem, total_mem); DEBUG(printf(LXTHDR"section offs for synctable decompression = %08x of len %d\n", offs, GLOBALS->zsync_table_size_lxt_c_1)); DEBUG(printf(LXTHDR"Decompressed size is %d bytes (vs %d)\n", rc, total_mem)); if(rc!=total_mem) { fprintf(stderr, LXTHDR"decompression size disparity %d bytes (vs %d)\n", rc, total_mem); exit(255); } offs=0; /* we're in our new memory region now.. */ } for(i=0;inumfacs;i++) { chg=get_32(offs); offs+=4; if(chg>maxchg) {maxchg=chg; maxindx=i; } GLOBALS->lastchange[i]=chg; } if(GLOBALS->zsync_table_size_lxt_c_1) { GLOBALS->mm_lxt_c_1 = GLOBALS->mmcache_lxt_c_1; free_2(decmem); decmem = NULL; gzclose(zhandle); #if defined __MINGW32__ || defined _MSC_VER fclose(tmp); #endif } GLOBALS->maxchange_lxt_c_1=maxchg; GLOBALS->maxindex_lxt_c_1=maxindx; } if(GLOBALS->zchg_size_lxt_c_1) { /* we don't implement the tempfile version for windows... */ #if !defined __MINGW32__ && !defined _MSC_VER if(GLOBALS->zchg_predec_size_lxt_c_1 > LXT_MMAP_MALLOC_BOUNDARY) { int fd_dummy; char *nam = tmpnam_2(NULL, &fd_dummy); FILE *tmp = fopen(nam, "wb"); unsigned int len=GLOBALS->zchg_predec_size_lxt_c_1; int rc; char buf[32768]; int fd2 = open(nam, O_RDONLY); char testbyte[2]={0,0}; char is_bz2; unlink(nam); if(fd_dummy >=0) close(fd_dummy); fprintf(stderr, LXTHDR"Compressed change records detected, making tempfile...\n"); if(GLOBALS->change_field_offset_lxt_c_1 != lseek(GLOBALS->fd_lxt_c_1, GLOBALS->change_field_offset_lxt_c_1, SEEK_SET)) { fprintf(stderr, LXTHDR"lseek error at offset %08x\n", (unsigned int)GLOBALS->change_field_offset_lxt_c_1); exit(255); } is_bz2 = (read(GLOBALS->fd_lxt_c_1, &testbyte, 2))&&(testbyte[0]=='B')&&(testbyte[1]=='Z'); if(GLOBALS->change_field_offset_lxt_c_1 != lseek(GLOBALS->fd_lxt_c_1, GLOBALS->change_field_offset_lxt_c_1, SEEK_SET)) { fprintf(stderr, LXTHDR"lseek error at offset %08x\n", (unsigned int)GLOBALS->change_field_offset_lxt_c_1); exit(255); } if(is_bz2) { zhandle = BZ2_bzdopen(dup(GLOBALS->fd_lxt_c_1), "rb"); while(len) { int siz = (len>32768) ? 32768 : len; rc = BZ2_bzread(zhandle, buf, siz); if(rc!=siz) { fprintf(stderr, LXTHDR"gzread error to tempfile %d (act) vs %d (exp), exiting.\n", rc, siz); exit(255); } if(1 != fwrite(buf, siz, 1, tmp)) { fprintf(stderr, LXTHDR"fwrite error to tempfile, exiting.\n"); exit(255); }; len -= siz; } fprintf(stderr, LXTHDR"...expanded %08x into %08x bytes.\n", GLOBALS->zchg_size_lxt_c_1, GLOBALS->zchg_predec_size_lxt_c_1); BZ2_bzclose(zhandle); } else { zhandle = gzdopen(dup(GLOBALS->fd_lxt_c_1), "rb"); while(len) { int siz = (len>32768) ? 32768 : len; rc = gzread(zhandle, buf, siz); if(rc!=siz) { fprintf(stderr, LXTHDR"gzread error to tempfile %d (act) vs %d (exp), exiting.\n", rc, siz); exit(255); } if(1 != fwrite(buf, siz, 1, tmp)) { fprintf(stderr, LXTHDR"fwrite error to tempfile, exiting.\n"); exit(255); }; len -= siz; } fprintf(stderr, LXTHDR"...expanded %08x into %08x bytes.\n", GLOBALS->zchg_size_lxt_c_1, GLOBALS->zchg_predec_size_lxt_c_1); gzclose(zhandle); } munmap(GLOBALS->mm_lxt_c_1, GLOBALS->f_len_lxt_c_1); close(GLOBALS->fd_lxt_c_1); fflush(tmp); fseeko(tmp, 0, SEEK_SET); fclose(tmp); GLOBALS->fd_lxt_c_1 = fd2; GLOBALS->mm_lxt_c_1=mmap(NULL, GLOBALS->zchg_predec_size_lxt_c_1, PROT_READ, MAP_SHARED, GLOBALS->fd_lxt_c_1, 0); GLOBALS->mm_lxt_mmap_addr = GLOBALS->mm_lxt_c_1; GLOBALS->mm_lxt_mmap_len = GLOBALS->zchg_predec_size_lxt_c_1; GLOBALS->mm_lxt_c_1=(void *)((char *)GLOBALS->mm_lxt_c_1-4); /* because header and version don't exist in packed change records */ } else #endif { unsigned int len=GLOBALS->zchg_predec_size_lxt_c_1; int rc; char *buf = malloc_2(GLOBALS->zchg_predec_size_lxt_c_1); char *pnt = buf; char testbyte[2]={0,0}; char is_bz2; fprintf(stderr, LXTHDR"Compressed change records detected...\n"); #if defined __MINGW32__ || defined _MSC_VER { unsigned char *t = (char *)GLOBALS->mm_lxt_c_1+GLOBALS->change_field_offset_lxt_c_1; tmp = tmpfile(); if(!tmp) { fprintf(stderr, LXTHDR"could not open decompression tempfile, exiting.\n"); exit(255); } fwrite(t, GLOBALS->zchg_size_lxt_c_1, 1, tmp); fseek(tmp, 0, SEEK_SET); is_bz2 = (get_byte(GLOBALS->change_field_offset_lxt_c_1)=='B') && (get_byte(GLOBALS->change_field_offset_lxt_c_1+1)=='Z'); } #else if(GLOBALS->change_field_offset_lxt_c_1 != lseek(GLOBALS->fd_lxt_c_1, GLOBALS->change_field_offset_lxt_c_1, SEEK_SET)) { fprintf(stderr, LXTHDR"lseek error at offset %08x\n", (unsigned int)GLOBALS->change_field_offset_lxt_c_1); exit(255); } is_bz2 = (read(GLOBALS->fd_lxt_c_1, &testbyte, 2))&&(testbyte[0]=='B')&&(testbyte[1]=='Z'); if(GLOBALS->change_field_offset_lxt_c_1 != lseek(GLOBALS->fd_lxt_c_1, GLOBALS->change_field_offset_lxt_c_1, SEEK_SET)) { fprintf(stderr, LXTHDR"lseek error at offset %08x\n", (unsigned int)GLOBALS->change_field_offset_lxt_c_1); exit(255); } #endif if(is_bz2) { #if defined __MINGW32__ || defined _MSC_VER zhandle = BZ2_bzdopen(dup(fileno(tmp)), "rb"); #else zhandle = BZ2_bzdopen(dup(GLOBALS->fd_lxt_c_1), "rb"); #endif while(len) { int siz = (len>32768) ? 32768 : len; rc = BZ2_bzread(zhandle, pnt, siz); if(rc!=siz) { fprintf(stderr, LXTHDR"BZ2_bzread error to buffer %d (act) vs %d (exp), exiting.\n", rc, siz); exit(255); } pnt += siz; len -= siz; } fprintf(stderr, LXTHDR"...expanded %08x into %08x bytes.\n", GLOBALS->zchg_size_lxt_c_1, GLOBALS->zchg_predec_size_lxt_c_1); BZ2_bzclose(zhandle); } else { #if defined __MINGW32__ || defined _MSC_VER zhandle = gzdopen(dup(fileno(tmp)), "rb"); #else zhandle = gzdopen(dup(GLOBALS->fd_lxt_c_1), "rb"); #endif while(len) { int siz = (len>32768) ? 32768 : len; rc = gzread(zhandle, pnt, siz); if(rc!=siz) { fprintf(stderr, LXTHDR"gzread error to buffer %d (act) vs %d (exp), exiting.\n", rc, siz); exit(255); } pnt += siz; len -= siz; } fprintf(stderr, LXTHDR"...expanded %08x into %08x bytes.\n", GLOBALS->zchg_size_lxt_c_1, GLOBALS->zchg_predec_size_lxt_c_1); gzclose(zhandle); #if defined __MINGW32__ || defined _MSC_VER fclose(tmp); #endif } munmap(GLOBALS->mm_lxt_c_1, GLOBALS->f_len_lxt_c_1); #if !defined __MINGW32__ && !defined _MSC_VER close(GLOBALS->fd_lxt_c_1); #endif GLOBALS->fd_lxt_c_1=-1; GLOBALS->mm_lxt_c_1=buf-4; /* because header and version don't exist in packed change records */ } } if(!GLOBALS->sync_table_offset_lxt_c_1) { off_t vlen = GLOBALS->zchg_predec_size_lxt_c_1 ? GLOBALS->zchg_predec_size_lxt_c_1+4 : 0; unsigned int numfacs_bytes; unsigned int num_records = 0; unsigned int last_change_delta, numbytes; int *positional_compar = GLOBALS->positional_information_lxt_c_1; int *positional_kill_pnt = GLOBALS->positional_information_lxt_c_1 + GLOBALS->total_cycles_lxt_c_2; char positional_kill = 0; unsigned int dict_16_offset_new = 0; unsigned int dict_24_offset_new = 0; unsigned int dict_32_offset_new = 0; char *nam; FILE *tmp; int recfd; int fd_dummy; offs = GLOBALS->zchg_predec_size_lxt_c_1 ? 4 : 0; fprintf(stderr, LXTHDR"Linear LXT encountered...\n"); if(!GLOBALS->zchg_predec_size_lxt_c_1) { fprintf(stderr, LXTHDR"Uncompressed linear LXT not supported, exiting.\n"); exit(255); } if(GLOBALS->numfacs >= 256*65536) { numfacs_bytes = 3; } else if(GLOBALS->numfacs >= 65536) { numfacs_bytes = 2; } else if(GLOBALS->numfacs >= 256) { numfacs_bytes = 1; } else { numfacs_bytes = 0; } nam = tmpnam_2(NULL, &fd_dummy); tmp = fopen(nam, "wb"); GLOBALS->fpos_lxt_c_1 = 4; /* fake 4 bytes padding */ recfd = open(nam, O_RDONLY); unlink(nam); if(fd_dummy >=0) close(fd_dummy); while(offs < vlen) { int facidx = 0; unsigned char cmd; off_t offscache2, offscache3; unsigned int height; unsigned char cmdkill; num_records++; /* remake time vs position table on the fly */ if(!positional_kill) { if(offs == *positional_compar) { *positional_compar = GLOBALS->fpos_lxt_c_1; positional_compar++; if(positional_compar == positional_kill_pnt) positional_kill = 1; } } switch(numfacs_bytes&3) { case 0: facidx = get_byte(offs); break; case 1: facidx = get_16(offs); break; case 2: facidx = get_24(offs); break; case 3: facidx = get_32(offs); break; } if(facidx>GLOBALS->numfacs) { fprintf(stderr, LXTHDR"Facidx %d out of range (vs %d) at offset %08x, exiting.\n", facidx, GLOBALS->numfacs, (unsigned int)offs); exit(255); } offs += (numfacs_bytes+1); cmdkill = GLOBALS->mvlfacs_lxt_c_2[facidx].flags & (LT_SYM_F_DOUBLE|LT_SYM_F_STRING); if(!cmdkill) { cmd = get_byte(offs); if(cmd>0xf) { fprintf(stderr, LXTHDR"Command byte %02x invalid at offset %08x, exiting.\n", cmd, (unsigned int)offs); exit(0); } offs++; } else { cmd=0; } offscache2 = offs; height = GLOBALS->mvlfacs_lxt_c_2[facidx].node_alias; if(height) { if(height >= 256*65536) { offs += 4; } else if(height >= 65536) { offs += 3; } else if(height >= 256) { offs += 2; } else { offs += 1; } } offscache3 = offs; if(!dict_16_offset_new) { if (offs == GLOBALS->dict_16_offset_lxt_c_1) { dict_16_offset_new = GLOBALS->fpos_lxt_c_1; } } else if(!dict_24_offset_new) { if (offs == GLOBALS->dict_24_offset_lxt_c_1) { dict_24_offset_new = GLOBALS->fpos_lxt_c_1; } } else if(!dict_32_offset_new) { if (offs == GLOBALS->dict_32_offset_lxt_c_1) { dict_32_offset_new = GLOBALS->fpos_lxt_c_1; } } /* printf("%08x : %04x %02x (%d) %s[%d:%d]\n", offscache, facidx, cmd, mvlfacs[facidx].len, mvlfacs[facidx].f_name, mvlfacs[facidx].msb, mvlfacs[facidx].lsb); */ if(!cmdkill) switch(cmd) { unsigned int modlen; case 0x0: modlen = (!(GLOBALS->mvlfacs_lxt_c_2[facidx].flags<_SYM_F_INTEGER)) ? GLOBALS->mvlfacs_lxt_c_2[facidx].len : 32; if((GLOBALS->dict_string_mem_array_lxt_c_1) && (modlen>GLOBALS->dict_width_lxt_c_1)) { if((!GLOBALS->dict_16_offset_lxt_c_1)||(offscache3dict_16_offset_lxt_c_1)) { offs += 1; } else if((!GLOBALS->dict_24_offset_lxt_c_1)||(offscache3dict_24_offset_lxt_c_1)) { offs += 2; } else if((!GLOBALS->dict_32_offset_lxt_c_1)||(offscache3dict_32_offset_lxt_c_1)) { offs += 3; } else { offs += 4; } } else { offs += (modlen + 7)/8; /* was offs += (GLOBALS->mvlfacs_lxt_c_2[facidx].len + 7)/8 which is wrong for integers! */ } break; case 0x1: offs += (GLOBALS->mvlfacs_lxt_c_2[facidx].len + 3)/4; break; case 0x2: offs += (GLOBALS->mvlfacs_lxt_c_2[facidx].len + 1)/2; break; case 0x3: case 0x4: case 0x5: case 0x6: case 0x7: case 0x8: case 0x9: case 0xa: case 0xb: break; /* single byte, no extra "skip" */ case 0xc: case 0xd: case 0xe: case 0xf: offs += ((cmd&3)+1); /* skip past numbytes_trans */ break; } else { /* cmdkill = 1 for strings + reals skip bytes */ if(GLOBALS->mvlfacs_lxt_c_2[facidx].flags & LT_SYM_F_DOUBLE) { offs += 8; } else /* strings */ { while(get_byte(offs)) offs++; offs++; } } last_change_delta = GLOBALS->fpos_lxt_c_1 - GLOBALS->lastchange[facidx] - 2; GLOBALS->lastchange[facidx] = GLOBALS->fpos_lxt_c_1; GLOBALS->maxchange_lxt_c_1=GLOBALS->fpos_lxt_c_1; GLOBALS->maxindex_lxt_c_1=facidx; if(last_change_delta >= 256*65536) { numbytes = 3; } else if(last_change_delta >= 65536) { numbytes = 2; } else if(last_change_delta >= 256) { numbytes = 1; } else { numbytes = 0; } lt_emit_u8(tmp, (numbytes<<4) | cmd); switch(numbytes&3) { case 0: lt_emit_u8(tmp, last_change_delta); break; case 1: lt_emit_u16(tmp, last_change_delta); break; case 2: lt_emit_u24(tmp, last_change_delta); break; case 3: lt_emit_u32(tmp, last_change_delta); break; } if(offs-offscache2) { GLOBALS->fpos_lxt_c_1 += fwrite((char *)GLOBALS->mm_lxt_c_1+offscache2, 1, offs-offscache2, tmp); /* copy rest of relevant info */ } } GLOBALS->dict_16_offset_lxt_c_1 = dict_16_offset_new; GLOBALS->dict_24_offset_lxt_c_1 = dict_24_offset_new; GLOBALS->dict_32_offset_lxt_c_1 = dict_32_offset_new; fflush(tmp); fseeko(tmp, 0, SEEK_SET); fclose(tmp); fprintf(stderr, LXTHDR"%d linear records converted into %08x bytes.\n", num_records, GLOBALS->fpos_lxt_c_1-4); #if !defined __MINGW32__ && !defined _MSC_VER if(GLOBALS->zchg_predec_size_lxt_c_1 > LXT_MMAP_MALLOC_BOUNDARY) { munmap((char *)GLOBALS->mm_lxt_c_1+4, GLOBALS->zchg_predec_size_lxt_c_1); close(GLOBALS->fd_lxt_c_1); GLOBALS->mm_lxt_mmap_addr = NULL; GLOBALS->mm_lxt_mmap_len = 0; } else #endif { free_2((char *)GLOBALS->mm_lxt_c_1+4); } GLOBALS->fd_lxt_c_1 = recfd; #if defined __MINGW32__ || defined _MSC_VER win_fname = nam; #endif GLOBALS->mm_lxt_c_1=mmap(NULL, GLOBALS->fpos_lxt_c_1-4, PROT_READ, MAP_SHARED, recfd, 0); GLOBALS->mm_lxt_mmap_addr = GLOBALS->mm_lxt_c_1; GLOBALS->mm_lxt_mmap_len = GLOBALS->fpos_lxt_c_1-4; GLOBALS->mm_lxt_c_1=(void *)((char *)GLOBALS->mm_lxt_c_1-4); /* because header and version don't exist in packed change records */ } } /* * given a fac+offset, return the binary data for it */ static char *parse_offset(struct fac *which, off_t offs) { int v, v2; unsigned int j; int k; unsigned int l; char *pnt; char repeat; l=which->len; pnt = GLOBALS->lt_buf_lxt_c_1; v=get_byte(offs); v2=v&0x0f; switch(v2) { case 0x00: /* MVL2 */ { unsigned int msk; unsigned int bitcnt=0; int ch; if((GLOBALS->dict_string_mem_array_lxt_c_1) && (l>GLOBALS->dict_width_lxt_c_1)) { unsigned int dictpos; unsigned int ld; offs += ((v>>4)&3)+2; /* skip value */ if((!GLOBALS->dict_16_offset_lxt_c_1)||(offsdict_16_offset_lxt_c_1)) { dictpos = get_byte(offs); } else if((!GLOBALS->dict_24_offset_lxt_c_1)||(offsdict_24_offset_lxt_c_1)) { dictpos = get_16(offs); } else if((!GLOBALS->dict_32_offset_lxt_c_1)||(offsdict_32_offset_lxt_c_1)) { dictpos = get_24(offs); } else { dictpos = get_32(offs); } if(dictpos <= GLOBALS->dict_num_entries_lxt_c_1) { ld = strlen(GLOBALS->dict_string_mem_array_lxt_c_1[dictpos]); for(j=0;j<(l-(ld+1));j++) { *(pnt++) = '0'; } *(pnt++) = '1'; memcpy(pnt, GLOBALS->dict_string_mem_array_lxt_c_1[dictpos], ld); } else { fprintf(stderr, LXTHDR"dict entry at offset %08x [%d] out of range, ignoring!\n", dictpos, (unsigned int)offs); for(j=0;j>4)&3)+2; /* skip value */ for(j=0;;j++) { ch=get_byte(offs+j); msk=0x80; for(k=0;k<8;k++) { *(pnt++)= (ch&msk) ? '1' : '0'; msk>>=1; bitcnt++; if(bitcnt==l) goto bail; } } } } break; case 0x01: /* MVL4 */ { unsigned int bitcnt=0; int ch; int rsh; offs += ((v>>4)&3)+2; /* skip value */ for(j=0;;j++) { ch=get_byte(offs+j); rsh=6; for(k=0;k<4;k++) { *(pnt++)=convert_mvl((ch>>rsh)&0x3); rsh-=2; bitcnt++; if(bitcnt==l) goto bail; } } } break; case 0x02: /* MVL9 */ { unsigned int bitcnt=0; int ch; int rsh; offs += ((v>>4)&3)+2; /* skip value */ for(j=0;;j++) { ch=get_byte(offs+j); rsh=4; for(k=0;k<2;k++) { *(pnt++)=convert_mvl(ch>>rsh); rsh-=4; bitcnt++; if(bitcnt==l) goto bail; } } } break; case 0x03: /* mvl repeat expansions */ case 0x04: case 0x05: case 0x06: case 0x07: case 0x08: case 0x09: case 0x0a: case 0x0b: repeat = convert_mvl(v2-3); for(j=0;jlt_buf_lxt_c_1); } /* * mainline */ TimeType lxt_main(char *fname) { int i; struct Node *n; struct symbol *s, *prevsymroot=NULL, *prevsym=NULL; off_t tagpnt; int tag; struct symbol *sym_block = NULL; struct Node *node_block = NULL; char **f_name = NULL; GLOBALS->fd_lxt_c_1=open(fname, O_RDONLY); if(GLOBALS->fd_lxt_c_1<0) { fprintf(stderr, "Could not open '%s', exiting.\n", fname); vcd_exit(255); } GLOBALS->f_len_lxt_c_1=lseek(GLOBALS->fd_lxt_c_1, (off_t)0, SEEK_END); #if defined __MINGW32__ || defined _MSC_VER win_fname = fname; #endif GLOBALS->mm_lxt_c_1=mmap(NULL, GLOBALS->f_len_lxt_c_1, PROT_READ, MAP_SHARED, GLOBALS->fd_lxt_c_1, 0); GLOBALS->mm_lxt_mmap_addr = GLOBALS->mm_lxt_c_1; GLOBALS->mm_lxt_mmap_len = GLOBALS->f_len_lxt_c_1; if(get_16((off_t)0)!=LT_HDRID) /* scan-build, assign to i= from get_16 removed */ { fprintf(stderr, "Not an LXT format AET, exiting.\n"); vcd_exit(255); } if((GLOBALS->version_lxt_c_1=get_16((off_t)2))>LT_VERSION) { fprintf(stderr, "Version %d of LXT format AETs not supported, exiting.\n", GLOBALS->version_lxt_c_1); vcd_exit(255); } if(get_byte(GLOBALS->f_len_lxt_c_1-1)!=LT_TRLID) { fprintf(stderr, "LXT '%s' is truncated, exiting.\n", fname); vcd_exit(255); } DEBUG(printf(LXTHDR"Loading LXT '%s'...\n", fname)); DEBUG(printf(LXTHDR"Len: %d\n", (unsigned int)GLOBALS->f_len_lxt_c_1)); /* SPLASH */ splash_create(); tagpnt = GLOBALS->f_len_lxt_c_1-2; while((tag=get_byte(tagpnt))!=LT_SECTION_END) { off_t offset = get_32(tagpnt-4); tagpnt-=5; switch(tag) { case LT_SECTION_CHG: GLOBALS->change_field_offset_lxt_c_1=offset; DEBUG(printf(LXTHDR"LT_SECTION_CHG at %08x\n", offset)); break; case LT_SECTION_SYNC_TABLE: GLOBALS->sync_table_offset_lxt_c_1=offset; DEBUG(printf(LXTHDR"LT_SECTION_SYNC_TABLE at %08x\n", offset)); break; case LT_SECTION_FACNAME: GLOBALS->facname_offset_lxt_c_1=offset; DEBUG(printf(LXTHDR"LT_SECTION_FACNAME at %08x\n", offset)); break; case LT_SECTION_FACNAME_GEOMETRY: GLOBALS->facgeometry_offset_lxt_c_1=offset; DEBUG(printf(LXTHDR"LT_SECTION_FACNAME_GEOMETRY at %08x\n", offset)); break; case LT_SECTION_TIMESCALE: GLOBALS->timescale_offset_lxt_c_1=offset; DEBUG(printf(LXTHDR"LT_SECTION_TIMESCALE at %08x\n", offset)); break; case LT_SECTION_TIME_TABLE: GLOBALS->time_table_offset_lxt_c_1=offset; DEBUG(printf(LXTHDR"LT_SECTION_TIME_TABLE at %08x\n", offset)); break; case LT_SECTION_TIME_TABLE64: GLOBALS->time_table_offset64_lxt_c_1=offset; DEBUG(printf(LXTHDR"LT_SECTION_TIME_TABLE64 at %08x\n", offset)); break; case LT_SECTION_INITIAL_VALUE: GLOBALS->initial_value_offset_lxt_c_1=offset; DEBUG(printf(LXTHDR"LT_SECTION_INITIAL_VALUE at %08x\n", offset)); break; case LT_SECTION_DOUBLE_TEST: GLOBALS->double_test_offset_lxt_c_1=offset; DEBUG(printf(LXTHDR"LT_SECTION_DOUBLE_TEST at %08x\n", offset)); break; case LT_SECTION_ZFACNAME_PREDEC_SIZE: GLOBALS->zfacname_predec_size_lxt_c_1=offset; DEBUG(printf(LXTHDR"LT_SECTION_ZFACNAME_PREDEC_SIZE = %08x\n", offset)); break; case LT_SECTION_ZFACNAME_SIZE: GLOBALS->zfacname_size_lxt_c_1=offset; DEBUG(printf(LXTHDR"LT_SECTION_ZFACNAME_SIZE = %08x\n", offset)); break; case LT_SECTION_ZFACNAME_GEOMETRY_SIZE: GLOBALS->zfacgeometry_size_lxt_c_1=offset; DEBUG(printf(LXTHDR"LT_SECTION_ZFACNAME_GEOMETRY_SIZE = %08x\n", offset)); break; case LT_SECTION_ZSYNC_SIZE: GLOBALS->zsync_table_size_lxt_c_1=offset; DEBUG(printf(LXTHDR"LT_SECTION_ZSYNC_SIZE = %08x\n", offset)); break; case LT_SECTION_ZTIME_TABLE_SIZE: GLOBALS->ztime_table_size_lxt_c_1=offset; DEBUG(printf(LXTHDR"LT_SECTION_ZTIME_TABLE_SIZE = %08x\n", offset)); break; case LT_SECTION_ZCHG_PREDEC_SIZE: GLOBALS->zchg_predec_size_lxt_c_1=offset; DEBUG(printf(LXTHDR"LT_SECTION_ZCHG_PREDEC_SIZE = %08x\n", offset)); break; case LT_SECTION_ZCHG_SIZE: GLOBALS->zchg_size_lxt_c_1=offset; DEBUG(printf(LXTHDR"LT_SECTION_ZCHG_SIZE = %08x\n", offset)); break; case LT_SECTION_ZDICTIONARY: GLOBALS->zdictionary_offset_lxt_c_1=offset; DEBUG(printf(LXTHDR"LT_SECTION_ZDICTIONARY = %08x\n", offset)); break; case LT_SECTION_ZDICTIONARY_SIZE: GLOBALS->zdictionary_predec_size_lxt_c_1=offset; DEBUG(printf(LXTHDR"LT_SECTION_ZDICTIONARY_SIZE = %08x\n", offset)); break; case LT_SECTION_EXCLUDE_TABLE: GLOBALS->exclude_offset_lxt_c_1=offset; DEBUG(printf(LXTHDR"LT_SECTION_EXCLUDE_TABLE = %08x\n", offset)); break; case LT_SECTION_TIMEZERO: GLOBALS->lxt_timezero_offset=offset; DEBUG(printf(LXTHDR"LT_SECTION_TIMEZERO = %08x\n", offset)); break; default: fprintf(stderr, "Skipping unknown section tag %02x.\n", tag); break; } } if(GLOBALS->lxt_timezero_offset) { GLOBALS->global_time_offset = get_64(GLOBALS->lxt_timezero_offset); } if(GLOBALS->exclude_offset_lxt_c_1) { off_t offset = GLOBALS->exclude_offset_lxt_c_1; int ix, num_blackouts = get_32(offset); TimeType bs, be; struct blackout_region_t *bt; offset+=4; for(ix=0;ixbstart = bs; bt->bend = be; bt->next = GLOBALS->blackout_regions; GLOBALS->blackout_regions = bt; } } if(GLOBALS->double_test_offset_lxt_c_1) { create_double_endian_mask(GLOBALS->double_test_offset_lxt_c_1); } if(GLOBALS->timescale_offset_lxt_c_1) { signed char scale; scale=(signed char)get_byte(GLOBALS->timescale_offset_lxt_c_1); exponent_to_time_scale(scale); } else { GLOBALS->time_dimension = 'n'; } if(!GLOBALS->facname_offset_lxt_c_1) { fprintf(stderr, "LXT '%s' is missing a facility name section, exiting.\n", fname); vcd_exit(255); } GLOBALS->numfacs=get_32(GLOBALS->facname_offset_lxt_c_1); DEBUG(printf(LXTHDR"Number of facs: %d\n", GLOBALS->numfacs)); GLOBALS->mvlfacs_lxt_c_2=(struct fac *)calloc_2(GLOBALS->numfacs,sizeof(struct fac)); GLOBALS->resolve_lxt_alias_to=(struct Node **)calloc_2(GLOBALS->numfacs,sizeof(struct Node *)); GLOBALS->lastchange=(unsigned int *)calloc_2(GLOBALS->numfacs,sizeof(unsigned int)); f_name = calloc_2(GLOBALS->numfacs,sizeof(char *)); if(GLOBALS->initial_value_offset_lxt_c_1) { switch(get_byte(GLOBALS->initial_value_offset_lxt_c_1)) { case 0: GLOBALS->initial_value_lxt_c_1 = AN_0; break; case 1: GLOBALS->initial_value_lxt_c_1 = AN_1; break; case 2: GLOBALS->initial_value_lxt_c_1 = AN_Z; break; case 4: GLOBALS->initial_value_lxt_c_1 = AN_H; break; case 5: GLOBALS->initial_value_lxt_c_1 = AN_U; break; case 6: GLOBALS->initial_value_lxt_c_1 = AN_W; break; case 7: GLOBALS->initial_value_lxt_c_1 = AN_L; break; case 8: GLOBALS->initial_value_lxt_c_1 = AN_DASH; break; default: GLOBALS->initial_value_lxt_c_1 = AN_X; break; } } else { GLOBALS->initial_value_lxt_c_1 = AN_X; } if(GLOBALS->zdictionary_offset_lxt_c_1) { if(GLOBALS->zdictionary_predec_size_lxt_c_1) { build_dict(); } else { fprintf(stderr, "LXT '%s' is missing a zdictionary_predec_size chunk, exiting.\n", fname); vcd_exit(255); } } sym_block = (struct symbol *)calloc_2(GLOBALS->numfacs, sizeof(struct symbol)); node_block = (struct Node *)calloc_2(GLOBALS->numfacs,sizeof(struct Node)); build_facs(fname, f_name, node_block); /* SPLASH */ splash_sync(1, 5); build_facs2(fname); /* SPLASH */ splash_sync(2, 5); /* do your stuff here..all useful info has been initialized by now */ if(!GLOBALS->hier_was_explicitly_set) /* set default hierarchy split char */ { GLOBALS->hier_delimeter='.'; } for(i=0;inumfacs;i++) { char buf[4096]; char *str; struct fac *f; if(GLOBALS->mvlfacs_lxt_c_2[i].flags<_SYM_F_ALIAS) { int alias = GLOBALS->mvlfacs_lxt_c_2[i].node_alias; f=GLOBALS->mvlfacs_lxt_c_2+alias; while(f->flags<_SYM_F_ALIAS) { f=GLOBALS->mvlfacs_lxt_c_2+f->node_alias; } } else { f=GLOBALS->mvlfacs_lxt_c_2+i; } if((f->len>1)&& (!(f->flags&(LT_SYM_F_INTEGER|LT_SYM_F_DOUBLE|LT_SYM_F_STRING))) ) { int len = sprintf(buf, "%s[%d:%d]", f_name[i],node_block[i].msi, node_block[i].lsi); str=malloc_2(len+1); if(!GLOBALS->alt_hier_delimeter) { strcpy(str, buf); } else { strcpy_vcdalt(str, buf, GLOBALS->alt_hier_delimeter); } s=&sym_block[i]; symadd_name_exists_sym_exists(s,str,0); prevsymroot = prevsym = NULL; } else { int gatecmp = (f->len==1) && (!(f->flags&(LT_SYM_F_INTEGER|LT_SYM_F_DOUBLE|LT_SYM_F_STRING))) && (node_block[i].msi!=-1) && (node_block[i].lsi!=-1); int revcmp = gatecmp && (i) && (!strcmp(f_name[i], f_name[i-1])); if(gatecmp) { int len = sprintf(buf, "%s[%d]", f_name[i],node_block[i].msi); str=malloc_2(len+1); if(!GLOBALS->alt_hier_delimeter) { strcpy(str, buf); } else { strcpy_vcdalt(str, buf, GLOBALS->alt_hier_delimeter); } s=&sym_block[i]; symadd_name_exists_sym_exists(s,str,0); if((prevsym)&&(revcmp)&&(!strchr(f_name[i], '\\'))) /* allow chaining for search functions.. */ { prevsym->vec_root = prevsymroot; prevsym->vec_chain = s; s->vec_root = prevsymroot; prevsym = s; } else { prevsymroot = prevsym = s; } } else { str=malloc_2(strlen(f_name[i])+1); if(!GLOBALS->alt_hier_delimeter) { strcpy(str, f_name[i]); } else { strcpy_vcdalt(str, f_name[i], GLOBALS->alt_hier_delimeter); } s=&sym_block[i]; symadd_name_exists_sym_exists(s,str,0); prevsymroot = prevsym = NULL; if(f->flags<_SYM_F_INTEGER) { node_block[i].msi=31; node_block[i].lsi=0; GLOBALS->mvlfacs_lxt_c_2[i].len=32; } } } n=&node_block[i]; n->nname=s->name; n->mv.mvlfac = GLOBALS->mvlfacs_lxt_c_2+i; if((f->len>1)||(f->flags&(LT_SYM_F_DOUBLE|LT_SYM_F_STRING))) { n->extvals = 1; } n->head.time=-1; /* mark 1st node as negative time */ n->head.v.h_val=AN_X; s->n=n; } free_2(f_name[0]); /* the start of the big decompression buffer */ for(i=0;inumfacs;i++) { f_name[i] = NULL; } free_2(f_name); f_name = NULL; /* SPLASH */ splash_sync(3, 5); GLOBALS->facs=(struct symbol **)malloc_2(GLOBALS->numfacs*sizeof(struct symbol *)); for(i=0;inumfacs;i++) { char *subst, ch; int len; int esc = 0; GLOBALS->facs[i]=&sym_block[i]; if((len=strlen(subst=GLOBALS->facs[i]->name))>GLOBALS->longestname) GLOBALS->longestname=len; while((ch=(*subst))) { #ifdef WAVE_HIERFIX if(ch==GLOBALS->hier_delimeter) { *subst=(!esc) ? VCDNAM_HIERSORT : VCDNAM_ESCAPE; } /* forces sort at hier boundaries */ #else if((ch==GLOBALS->hier_delimeter)&&(esc)) { *subst = VCDNAM_ESCAPE; } /* forces sort at hier boundaries */ #endif else if(ch=='\\') { esc = 1; GLOBALS->escaped_names_found_vcd_c_1 = 1; } subst++; } } fprintf(stderr, LXTHDR"Sorting facilities at hierarchy boundaries..."); wave_heapsort(GLOBALS->facs,GLOBALS->numfacs); fprintf(stderr, "sorted.\n"); #ifdef WAVE_HIERFIX for(i=0;inumfacs;i++) { char *subst, ch; subst=GLOBALS->facs[i]->name; while((ch=(*subst))) { if(ch==VCDNAM_HIERSORT) { *subst=GLOBALS->hier_delimeter; } /* restore back to normal */ subst++; } #ifdef DEBUG_FACILITIES printf("%-4d %s\n",i,facs[i]->name); #endif } #endif GLOBALS->facs_are_sorted=1; fprintf(stderr, LXTHDR"Building facility hierarchy tree..."); /* SPLASH */ splash_sync(4, 5); init_tree(); for(i=0;inumfacs;i++) { char *nf = GLOBALS->facs[i]->name; build_tree_from_name(nf, i); } /* SPLASH */ splash_sync(5, 5); if(GLOBALS->escaped_names_found_vcd_c_1) { for(i=0;inumfacs;i++) { char *subst, ch; subst=GLOBALS->facs[i]->name; while((ch=(*subst))) { if(ch==VCDNAM_ESCAPE) { *subst=GLOBALS->hier_delimeter; } /* restore back to normal */ subst++; } #ifdef DEBUG_FACILITIES printf("%-4d %s\n",i,facs[i]->name); #endif } } treegraft(&GLOBALS->treeroot); treesort(GLOBALS->treeroot, NULL); if(GLOBALS->escaped_names_found_vcd_c_1) { treenamefix(GLOBALS->treeroot); } fprintf(stderr, "built.\n\n"); #ifdef DEBUG_FACILITIES treedebug(GLOBALS->treeroot,""); #endif GLOBALS->min_time = GLOBALS->first_cycle_lxt_c_2*GLOBALS->time_scale; GLOBALS->max_time=GLOBALS->last_cycle_lxt_c_2*GLOBALS->time_scale; fprintf(stderr, "["TTFormat"] start time.\n["TTFormat"] end time.\n", GLOBALS->min_time, GLOBALS->max_time); GLOBALS->is_lxt = ~0; if(GLOBALS->blackout_regions) { struct blackout_region_t *bt = GLOBALS->blackout_regions; while(bt) { bt->bstart *= GLOBALS->time_scale; bt->bend *= GLOBALS->time_scale; bt = bt->next; } } /* SPLASH */ splash_finalize(); return(GLOBALS->max_time); } /* * this is the black magic that handles aliased signals... */ static void lxt_resolver(nptr np, nptr resolve) { np->extvals = resolve->extvals; np->msi = resolve->msi; np->lsi = resolve->lsi; memcpy(&np->head, &resolve->head, sizeof(struct HistEnt)); np->curr = resolve->curr; np->harray = resolve->harray; np->numhist = resolve->numhist; np->mv.mvlfac=NULL; } /* * actually import an lxt trace but don't do it if * 1) it's already been imported * 2) an alias of this trace has been imported--instead * copy over the relevant info and be done with it. */ void import_lxt_trace(nptr np) { off_t offs, offsdelta; int v, w; TimeType tmval; TimeType prevtmval; struct HistEnt *htemp; struct HistEnt *histent_head, *histent_tail; char *parsed; int len, i, j; struct fac *f; if(!(f=np->mv.mvlfac)) return; /* already imported */ if(np->mv.mvlfac->flags<_SYM_F_ALIAS) { int alias = np->mv.mvlfac->node_alias; f=GLOBALS->mvlfacs_lxt_c_2+alias; if(GLOBALS->resolve_lxt_alias_to[alias]) { if(!GLOBALS->resolve_lxt_alias_to[np->mv.mvlfac - GLOBALS->mvlfacs_lxt_c_2]) GLOBALS->resolve_lxt_alias_to[np->mv.mvlfac - GLOBALS->mvlfacs_lxt_c_2] = GLOBALS->resolve_lxt_alias_to[alias]; } else { GLOBALS->resolve_lxt_alias_to[alias] = np; } while(f->flags<_SYM_F_ALIAS) { f=GLOBALS->mvlfacs_lxt_c_2+f->node_alias; if(GLOBALS->resolve_lxt_alias_to[f->node_alias]) { if(!GLOBALS->resolve_lxt_alias_to[np->mv.mvlfac - GLOBALS->mvlfacs_lxt_c_2]) GLOBALS->resolve_lxt_alias_to[np->mv.mvlfac - GLOBALS->mvlfacs_lxt_c_2] = GLOBALS->resolve_lxt_alias_to[f->node_alias]; } else { GLOBALS->resolve_lxt_alias_to[f->node_alias] = np; } } } /* f is the head minus any aliases, np->mv.mvlfac is us... */ if(GLOBALS->resolve_lxt_alias_to[np->mv.mvlfac - GLOBALS->mvlfacs_lxt_c_2]) /* in case we're an alias head for later.. */ { lxt_resolver(np, GLOBALS->resolve_lxt_alias_to[np->mv.mvlfac - GLOBALS->mvlfacs_lxt_c_2]); return; } GLOBALS->resolve_lxt_alias_to[np->mv.mvlfac - GLOBALS->mvlfacs_lxt_c_2] = np; /* in case we're an alias head for later.. */ offs=GLOBALS->lastchange[f-GLOBALS->mvlfacs_lxt_c_2]; tmval=LLDescriptor(-1); prevtmval = LLDescriptor(-1); len = np->mv.mvlfac->len; histent_tail = htemp = histent_calloc(); if(len>1) { htemp->v.h_vector = (char *)malloc_2(len); for(i=0;iv.h_vector[i] = AN_Z; } else { htemp->v.h_val = AN_Z; /* z */ } htemp->time = MAX_HISTENT_TIME; histent_head = histent_calloc(); if(len>1) { histent_head->v.h_vector = (char *)malloc_2(len); for(i=0;iv.h_vector[i] = AN_X; } else { histent_head->v.h_val = AN_X; /* x */ } histent_head->time = MAX_HISTENT_TIME-1; histent_head->next = htemp; /* x */ np->numhist=2; if(f->node_alias < 1) /* sorry, arrays not supported */ while(offs) { unsigned char val = 0; if( (w=((v=get_byte(offs))&0xF)) >0xb) { off_t offsminus1, offsminus2, offsminus3; TimeType delta, time_offsminus1; int skip; switch(v&0xF0) { case 0x00: skip = 2; offsdelta=get_byte(offs+1); break; case 0x10: skip = 3; offsdelta=get_16(offs+1); break; case 0x20: skip = 4; offsdelta=get_24(offs+1); break; case 0x30: skip = 5; offsdelta=get_32(offs+1); break; default: fprintf(stderr, "Unknown %02x at offset: %08x\n", v, (unsigned int)offs); exit(0); } offsminus1 = offs-offsdelta-2; switch(get_byte(offsminus1)&0xF0) { case 0x00: offsdelta=get_byte(offsminus1+1); break; case 0x10: offsdelta=get_16(offsminus1+1); break; case 0x20: offsdelta=get_24(offsminus1+1); break; case 0x30: offsdelta=get_32(offsminus1+1); break; default: fprintf(stderr, "Unknown %02x at offset: %08x\n", get_byte(offsminus1), (unsigned int)offsminus1); exit(0); } offsminus2 = offsminus1-offsdelta-2; delta = (time_offsminus1=bsearch_mvl_timechain(offsminus1)) - bsearch_mvl_timechain(offsminus2); if(len>1) { DEBUG(fprintf(stderr, "!!! DELTA = %lld\n", delta)); DEBUG(fprintf(stderr, "!!! offsminus1 = %08x\n", offsminus1)); if(!GLOBALS->lxt_clock_compress_to_z) { int vval = get_byte(offsminus1)&0xF; int reps = 0; int rcnt; unsigned int reconstructm1 = 0; unsigned int reconstructm2 = 0; unsigned int reconstructm3 = 0; unsigned int rle_delta[2]; int ix; if((vval!=0)&&(vval!=3)&&(vval!=4)) { fprintf(stderr, "Unexpected clk compress byte %02x at offset: %08x\n", get_byte(offsminus1), (unsigned int)offsminus1); exit(0); } switch(w&3) { case 0: reps = get_byte(offs+skip); break; case 1: reps = get_16(offs+skip); break; case 2: reps = get_24(offs+skip); break; case 3: reps = get_32(offs+skip); break; } reps++; DEBUG(fprintf(stderr, "!!! reps = %d\n", reps)); parsed=parse_offset(f, offsminus1); for(ix=0;ix '%08x'\n", tmval, res)); for(k=0;kv.h_vector = (char *)malloc_2(len); memcpy(htemp->v.h_vector, parsed, len); htemp->time = tmval; htemp->next = histent_head; histent_head = htemp; np->numhist++; tmval-=delta; } } else /* compress to z on multibit */ { int ix; htemp = histent_calloc(); htemp->v.h_vector = (char *)malloc_2(len); for(ix=0;ixv.h_vector[ix] = 'z'; } tmval = time_offsminus1 + delta; htemp->time = tmval; htemp->next = histent_head; histent_head = htemp; np->numhist++; } offs = offsminus1; /* no need to recalc it again! */ continue; } else { if(!GLOBALS->lxt_clock_compress_to_z) { int vval = get_byte(offsminus1)&0xF; int reps = 0; int rcnt; if((vval<3)||(vval>4)) { fprintf(stderr, "Unexpected clk compress byte %02x at offset: %08x\n", get_byte(offsminus1), (unsigned int)offsminus1); exit(0); } switch(w&3) { case 0: reps = get_byte(offs+skip); break; case 1: reps = get_16(offs+skip); break; case 2: reps = get_24(offs+skip); break; case 3: reps = get_32(offs+skip); break; } reps++; vval = (reps & 1) ^ (vval==4); /* because x3='0', x4='1' */ vval = (vval==0) ? AN_0 : AN_1; tmval = time_offsminus1 + (delta * reps); for(rcnt=0;rcntv.h_val) { htemp = histent_calloc(); htemp->v.h_val = vval; htemp->time = tmval; htemp->next = histent_head; histent_head = htemp; np->numhist++; } else { histent_head->time = tmval; } tmval-=delta; vval= (vval==AN_0) ? AN_1: AN_0; } } else { int vval=AN_Z; if(vval!=histent_head->v.h_val) { htemp = histent_calloc(); htemp->v.h_val = vval; htemp->time = time_offsminus1 + delta; htemp->next = histent_head; histent_head = htemp; np->numhist++; } else { histent_head->time = time_offsminus1 + delta; } tmval = time_offsminus1 + delta; } } offs = offsminus1; /* no need to recalc it again! */ continue; } else if((tmval=bsearch_mvl_timechain(offs))!=prevtmval) /* get rid of glitches (if even possible) */ { DEBUG(printf(LXTHDR"offs: %08x is time %08x\n", offs, tmval)); if(!(f->flags&(LT_SYM_F_DOUBLE|LT_SYM_F_STRING))) { parsed=parse_offset(f, offs); if(len==1) { switch(parsed[0]) { case '0': val = AN_0; break; case 'x': val = AN_X; break; case 'z': val = AN_Z; break; case '1': val = AN_1; break; case 'h': val = AN_H; break; case 'u': val = AN_U; break; case 'w': val = AN_W; break; case 'l': val = AN_L; break; case '-': val = AN_DASH; break; } if(val!=histent_head->v.h_val) { htemp = histent_calloc(); htemp->v.h_val = val; htemp->time = tmval; htemp->next = histent_head; histent_head = htemp; np->numhist++; } else { histent_head->time = tmval; } } else { if(memcmp(parsed, histent_head->v.h_vector, len)) { htemp = histent_calloc(); htemp->v.h_vector = (char *)malloc_2(len); memcpy(htemp->v.h_vector, parsed, len); htemp->time = tmval; htemp->next = histent_head; histent_head = htemp; np->numhist++; } else { histent_head->time = tmval; } } } else if(f->flags<_SYM_F_DOUBLE) { int offs_dbl = offs + ((get_byte(offs)>>4)&3)+2; /* skip value */ htemp = histent_calloc(); htemp->flags = HIST_REAL; if(GLOBALS->double_is_native_lxt_c_1) { #ifdef WAVE_HAS_H_DOUBLE memcpy(&htemp->v.h_double, ((char *)GLOBALS->mm_lxt_c_1+offs_dbl), sizeof(double)); #else htemp->v.h_vector = ((char *)GLOBALS->mm_lxt_c_1+offs_dbl); DEBUG(printf(LXTHDR"Added double '%.16g'\n", *((double *)(GLOBALS->mm_lxt_c_1+offs_dbl)))); #endif } else { #ifdef WAVE_HAS_H_DOUBLE double *h_d = (double *)swab_double_via_mask(offs_dbl); htemp->v.h_double = *h_d; free_2(h_d); #else htemp->v.h_vector = swab_double_via_mask(offs_dbl); DEBUG(printf(LXTHDR"Added bytefixed double '%.16g'\n", *((double *)(htemp->v.h_vector)))); #endif } htemp->time = tmval; htemp->next = histent_head; histent_head = htemp; np->numhist++; } else { /* defaults to if(f->flags<_SYM_F_STRING) */ int offs_str = offs + ((get_byte(offs)>>4)&3)+2; /* skip value */ htemp = histent_calloc(); htemp->flags = HIST_REAL|HIST_STRING; htemp->v.h_vector = ((char *)GLOBALS->mm_lxt_c_1+offs_str); DEBUG(printf(LXTHDR"Added string '%s'\n", (unsigned char *)GLOBALS->mm_lxt_c_1+offs_str)); htemp->time = tmval; htemp->next = histent_head; histent_head = htemp; np->numhist++; } } prevtmval = tmval; /* v=get_byte(offs); */ switch(v&0xF0) { case 0x00: offsdelta=get_byte(offs+1); break; case 0x10: offsdelta=get_16(offs+1); break; case 0x20: offsdelta=get_24(offs+1); break; case 0x30: offsdelta=get_32(offs+1); break; default: fprintf(stderr, "Unknown %02x at offset: %08x\n", v, (unsigned int)offs); exit(0); } offs = offs-offsdelta-2; } np->mv.mvlfac = NULL; /* it's imported and cached so we can forget it's an mvlfac now */ for(j=0;j>-2;j--) { if(tmval!=GLOBALS->first_cycle_lxt_c_2) { char init; htemp = histent_calloc(); if(!(f->flags&(LT_SYM_F_DOUBLE|LT_SYM_F_STRING))) { if(GLOBALS->initial_value_offset_lxt_c_1) { init = GLOBALS->initial_value_lxt_c_1; } else { init = AN_X; /* x if unspecified */ } if(len>1) { char *pnt = htemp->v.h_vector = (char *)malloc_2(len); /* zeros */ int ix; for(ix=0;ixv.h_val = init; } } else { htemp->flags = HIST_REAL; if(f->flags<_SYM_F_STRING) htemp->flags |= HIST_STRING; } htemp->time = GLOBALS->first_cycle_lxt_c_2+j; htemp->next = histent_head; histent_head = htemp; np->numhist++; } tmval=GLOBALS->first_cycle_lxt_c_2+1; } if(!(f->flags&(LT_SYM_F_DOUBLE|LT_SYM_F_STRING))) { if(len>1) { np->head.v.h_vector = (char *)malloc_2(len); for(i=0;ihead.v.h_vector[i] = AN_X; } else { np->head.v.h_val = AN_X; /* 'x' */ } } else { np->head.flags = HIST_REAL; if(f->flags<_SYM_F_STRING) np->head.flags |= HIST_STRING; } np->head.time = -2; np->head.next = histent_head; np->curr = histent_tail; np->numhist++; } gtkwave-3.3.66/src/regex.c0000664000076400007640000000471212341266475014662 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2004. * * 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. */ #include "globals.h" #include #ifdef _AIX #ifndef _GNUC_ #include #include #define REGEX_MALLOC #ifndef STDC_HEADERS #define STDC_HEADERS #endif #endif #endif #ifdef __linux__ #include #include #include #else #if defined __CYGWIN__ || defined __MINGW32__ #include #include #ifndef HAVE_BZERO #define bcopy(a,b,c) memcpy((b),(a),(c)) #define bzero(a,b) memset((a),0,(b)) #define bcmp(a,b,c) memcmp((a),(b),(c)) #endif #define REGEX_MAY_COMPILE #include "gnu_regex.c" #else /* or for any other compiler that doesn't support POSIX.2 regexs properly like xlc or vc++ */ #ifdef _MSC_VER #include #define STDC_HEADERS #define alloca _alloca /* AIX doesn't like this */ #endif #define REGEX_MAY_COMPILE #include "gnu_regex.c" #endif #endif #include "regex_wave.h" #include "debug.h" /* * compile a regular expression into a regex_t and * dealloc any previously valid ones */ int wave_regex_compile(char *regex, int which) { int comp_rc; if(GLOBALS->regex_ok_regex_c_1[which]) { regfree(&GLOBALS->preg_regex_c_1[which]); } /* free previous regex_t ancillary data if valid */ comp_rc=regcomp(&GLOBALS->preg_regex_c_1[which], regex, REG_ICASE|REG_NOSUB); return(GLOBALS->regex_ok_regex_c_1[which]=(comp_rc)?0:1); } /* * do match */ int wave_regex_match(char *str, int which) { int rc; if(GLOBALS->regex_ok_regex_c_1[which]) { rc = regexec(&GLOBALS->preg_regex_c_1[which], str, 0, NULL, 0); } else { rc = 1; /* fail on malformed regex */ } return((rc)?0:1); } /* * compile a regular expression and return the pointer to * the regex_t if valid else return NULL */ void *wave_regex_alloc_compile(char *regex) { regex_t *mreg = (regex_t *)malloc_2(sizeof(regex_t)); int comp_rc=regcomp(mreg, regex, REG_ICASE|REG_NOSUB); if(comp_rc) { free_2(mreg); mreg=NULL; } return((void *)mreg); } /* * do match */ int wave_regex_alloc_match(void *mreg, char *str) { int rc=regexec((regex_t *)mreg, str, 0, NULL, 0); return((rc)?0:1); } /* * free it */ void wave_regex_alloc_free(void *pnt) { regex_t *mreg = (regex_t *)pnt; if(mreg) { regfree(mreg); free_2(mreg); } } gtkwave-3.3.66/src/treesearch_gtk2.c0000664000076400007640000022040612440263323016611 0ustar bybellbybell/* * Copyright (c) Tristan Gingold and Tony Bybell 2006-2014. * * 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. */ #include #include "globals.h" #include #include #include #include #include "gtk12compat.h" #include "analyzer.h" #include "tree.h" #include "symbol.h" #include "vcd.h" #include "lx2.h" #include "busy.h" #include "debug.h" #include "hierpack.h" #include "tcl_helper.h" WAVE_NODEVARTYPE_STR WAVE_NODEVARDIR_STR WAVE_NODEVARDATATYPE_STR enum { VIEW_DRAG_INACTIVE, TREE_TO_VIEW_DRAG_ACTIVE, SEARCH_TO_VIEW_DRAG_ACTIVE }; /* Treesearch is a pop-up window used to select signals. It is composed of two main areas: * A tree area to select the hierarchy [tree area] * The (filtered) list of signals contained in the hierarchy [signal area]. */ /* SIG_ROOT is the branch currently selected. Signals of SIG_ROOT are displayed in the signals window. */ /* Only signals which match the filter are displayed in the signal area. */ /* The signal area is based on a tree view which requires a store model. This store model contains the list of signals to be displayed. */ enum { NAME_COLUMN, TREE_COLUMN, TYPE_COLUMN, DIR_COLUMN, DTYPE_COLUMN, N_COLUMNS }; /* list of autocoalesced (synthesized) filter names that need to be freed at some point) */ void free_afl(void) { struct autocoalesce_free_list *at; while(GLOBALS->afl_treesearch_gtk2_c_1) { if(GLOBALS->afl_treesearch_gtk2_c_1->name) free_2(GLOBALS->afl_treesearch_gtk2_c_1->name); at = GLOBALS->afl_treesearch_gtk2_c_1->next; free_2(GLOBALS->afl_treesearch_gtk2_c_1); GLOBALS->afl_treesearch_gtk2_c_1 = at; } } /* point to pure signame (remove hierarchy) for fill_sig_store() */ static char *prune_hierarchy(char *nam) { char cmpchar = GLOBALS->alt_hier_delimeter ? GLOBALS->alt_hier_delimeter : '.'; char *t = nam; char *lastmatch = NULL; while(t && *t) { if(*t == cmpchar) { lastmatch = t+1; } t++; } return(lastmatch ? lastmatch : nam); } /* fix escaped signal names */ static void *fix_escaped_names(char *s, int do_free) { char *s2 = s; int found = 0; while(*s2) { if((*s2) == VCDNAM_ESCAPE) { found = 1; break; } s2++; } if(found) { s2 = strdup_2(s); if(do_free) free_2(s); s = s2; while(*s2) { if(*s2 == VCDNAM_ESCAPE) { *s2 = GLOBALS->hier_delimeter; } /* restore back to normal */ s2++; } } return(s); } /* truncate VHDL types to string directly after final '.' */ char *varxt_fix(char *s) { char *pnt = strrchr(s, '.'); return(pnt ? (pnt+1) : s); } /* Fill the store model using current SIG_ROOT and FILTER_STR. */ void fill_sig_store (void) { struct tree *t; struct tree *t_prev = NULL; GtkTreeIter iter; if(GLOBALS->selected_sig_name) { free_2(GLOBALS->selected_sig_name); GLOBALS->selected_sig_name = NULL; } free_afl(); gtk_list_store_clear (GLOBALS->sig_store_treesearch_gtk2_c_1); for (t = GLOBALS->sig_root_treesearch_gtk2_c_1; t != NULL; t = t->next) { int i = t->t_which; char *s, *tmp2; int vartype; int vardir; int is_tname = 0; int wrexm; int vardt; unsigned int varxt; char *varxt_pnt; if(i < 0) { t_prev = NULL; continue; } if(t_prev) /* duplicates removal for faulty dumpers */ { if(!strcmp(t_prev->name, t->name)) { continue; } } t_prev = t; varxt = GLOBALS->facs[i]->n->varxt; varxt_pnt = varxt ? varxt_fix(GLOBALS->subvar_pnt[varxt]) : NULL; vartype = GLOBALS->facs[i]->n->vartype; if((vartype < 0) || (vartype > ND_VARTYPE_MAX)) { vartype = 0; } vardir = GLOBALS->facs[i]->n->vardir; /* two bit already chops down to 0..3, but this doesn't hurt */ if((vardir < 0) || (vardir > ND_DIR_MAX)) { vardir = 0; } vardt = GLOBALS->facs[i]->n->vardt; if((vardt < 0) || (vardt > ND_VDT_MAX)) { vardt = 0; } if(!GLOBALS->facs[i]->vec_root) { is_tname = 1; s = t->name; s = fix_escaped_names(s, 0); } else { if(GLOBALS->autocoalesce) { char *p; if(GLOBALS->facs[i]->vec_root!=GLOBALS->facs[i]) continue; tmp2=makename_chain(GLOBALS->facs[i]); p = prune_hierarchy(tmp2); s=(char *)malloc_2(strlen(p)+4); strcpy(s,"[] "); strcpy(s+3, p); s = fix_escaped_names(s, 1); free_2(tmp2); } else { char *p = prune_hierarchy(GLOBALS->facs[i]->name); s=(char *)malloc_2(strlen(p)+4); strcpy(s,"[] "); strcpy(s+3, p); s = fix_escaped_names(s, 1); } } wrexm = 0; if ( (GLOBALS->filter_str_treesearch_gtk2_c_1 == NULL) || ((!GLOBALS->filter_noregex_treesearch_gtk2_c_1) && (wrexm = wave_regex_match(t->name, WAVE_REGEX_TREE)) && (!GLOBALS->filter_matlen_treesearch_gtk2_c_1)) || (GLOBALS->filter_matlen_treesearch_gtk2_c_1 && ((GLOBALS->filter_typ_treesearch_gtk2_c_1 == vardir) ^ GLOBALS->filter_typ_polarity_treesearch_gtk2_c_1) && (wrexm || (wrexm = wave_regex_match(t->name, WAVE_REGEX_TREE))) ) ) { gtk_list_store_prepend (GLOBALS->sig_store_treesearch_gtk2_c_1, &iter); if(is_tname) { gtk_list_store_set (GLOBALS->sig_store_treesearch_gtk2_c_1, &iter, NAME_COLUMN, s, TREE_COLUMN, t, TYPE_COLUMN, (((GLOBALS->supplemental_datatypes_encountered) && (!GLOBALS->supplemental_vartypes_encountered)) ? (varxt ? varxt_pnt : vardatatype_strings[vardt]) : vartype_strings[vartype]), DIR_COLUMN, vardir_strings[vardir], DTYPE_COLUMN, varxt ? varxt_pnt : vardatatype_strings[vardt], -1); if(s != t->name) { free_2(s); } } else { struct autocoalesce_free_list *a = calloc_2(1, sizeof(struct autocoalesce_free_list)); a->name = s; a->next = GLOBALS->afl_treesearch_gtk2_c_1; GLOBALS->afl_treesearch_gtk2_c_1 = a; gtk_list_store_set (GLOBALS->sig_store_treesearch_gtk2_c_1, &iter, NAME_COLUMN, s, TREE_COLUMN, t, TYPE_COLUMN, (((GLOBALS->supplemental_datatypes_encountered) && (!GLOBALS->supplemental_vartypes_encountered)) ? (varxt ? varxt_pnt : vardatatype_strings[vardt]) : vartype_strings[vartype]), DIR_COLUMN, vardir_strings[vardir], DTYPE_COLUMN, varxt ? varxt_pnt : vardatatype_strings[vardt], -1); } } else { if(s != t->name) { free_2(s); } } } } /* * tree open/close handling */ static void create_sst_nodes_if_necessary(GtkCTreeNode *node) { #ifndef WAVE_DISABLE_FAST_TREE if(node) { GtkCTreeRow *gctr = GTK_CTREE_ROW(node); struct tree *t = (struct tree *)(gctr->row.data); if(t->child) { GtkCTree *ctree = GLOBALS->ctree_main; GtkCTreeNode *n = gctr->children; gtk_clist_freeze(GTK_CLIST(ctree)); while(n) { GtkCTreeRow *g = GTK_CTREE_ROW(n); t = (struct tree *)(g->row.data); if(t->t_which < 0) { if(!t->children_in_gui) { t->children_in_gui = 1; maketree2(n, t, 0, n); } } n = GTK_CTREE_NODE_NEXT(n); } gtk_clist_thaw(GTK_CLIST(ctree)); } } #endif } int force_open_tree_node(char *name, int keep_path_nodes_open, struct tree **t_pnt) { GtkCTree *ctree = GLOBALS->ctree_main; int rv = 1 ; /* can possible open */ if(ctree) { int namlen = strlen(name); char *namecache = wave_alloca(namlen+1); char *name_end = name + namlen - 1; char *zap = name; GtkCTreeNode *node = GLOBALS->any_tree_node; GtkCTreeRow *gctr = GTK_CTREE_ROW(node); int depth = 1; strcpy(namecache, name); while(gctr->parent) { node = gctr->parent; gctr = GTK_CTREE_ROW(node); } for(;;) { struct tree *t = gctr->row.data; if(t_pnt) { *t_pnt = t; } while(*zap) { if(*zap != GLOBALS->hier_delimeter) { zap++; } else { *zap = 0; break; } } if(!strcmp(t->name, name)) { if(zap == name_end) { GtkCTreeNode **nodehist = wave_alloca(depth * sizeof(GtkCTreeNode *)); int *exp1 = wave_alloca(depth * sizeof(int)); int i = depth-1; nodehist[i] = node; exp1[i--] = 1; /* now work backwards up to parent getting the node open/close history*/ gctr = GTK_CTREE_ROW(node); while(gctr->parent) { node = gctr->parent; gctr = GTK_CTREE_ROW(node); nodehist[i] = node; exp1[i--] = gctr->expanded || (keep_path_nodes_open != 0); } gtk_clist_freeze(GTK_CLIST(ctree)); /* fully expand down */ for(i=0;i=0;i--) { if(exp1[i]) { gtk_ctree_expand(ctree, nodehist[i]); } else { gtk_ctree_collapse(ctree, nodehist[i]); } } gtk_clist_thaw(GTK_CLIST(ctree)); gtk_ctree_node_moveto(ctree, nodehist[depth-1], depth /*column*/, 0.5 /*row_align*/, 0.5 /*col_align*/); /* printf("[treeopennode] '%s' ok\n", name); */ rv = 0 ; /* opened */ GLOBALS->open_tree_nodes = xl_insert(namecache, GLOBALS->open_tree_nodes, NULL); return rv; } else { depth++; create_sst_nodes_if_necessary(node); node = gctr->children; if(!node) break; gctr = GTK_CTREE_ROW(node); if(!gctr) break; name = ++zap; continue; } } node = gctr->sibling; if(!node) break; gctr = GTK_CTREE_ROW(node); } /* printf("[treeopennode] '%s' failed\n", name); */ } else { rv = -1 ; /* tree does not exist */ } return rv ; } void dump_open_tree_nodes(FILE *wave, xl_Tree *t) { if(t->left) { dump_open_tree_nodes(wave, t->left); } fprintf(wave, "[treeopen] %s\n", t->item); if(t->right) { dump_open_tree_nodes(wave, t->right); } } static void generic_tree_expand_collapse_callback(int is_expand, GtkCTreeNode *node) { GtkCTreeRow **gctr; int depth, i; int len = 1; char *tstring; char hier_suffix[2]; int found; hier_suffix[0] = GLOBALS->hier_delimeter; hier_suffix[1] = 0; if(!node) return; depth = GTK_CTREE_ROW(node)->level; gctr = wave_alloca(depth * sizeof(GtkCTreeRow *)); for(i=depth-1;i>=0;i--) { struct tree *t; gctr[i] = GTK_CTREE_ROW(node); t = gctr[i]->row.data; len += (strlen(t->name) + 1); node = gctr[i]->parent; } tstring = wave_alloca(len); memset(tstring, 0, len); for(i=0;irow.data; strcat(tstring, t->name); strcat(tstring, hier_suffix); } if(GLOBALS->open_tree_nodes) /* cut down on chatter to Tcl clients */ { GLOBALS->open_tree_nodes = xl_splay(tstring, GLOBALS->open_tree_nodes); if(!strcmp(GLOBALS->open_tree_nodes->item, tstring)) { found = 1; } else { found = 0; } } else { found = 0; } if(is_expand) { GLOBALS->open_tree_nodes = xl_insert(tstring, GLOBALS->open_tree_nodes, NULL); if(!found) { gtkwavetcl_setvar(WAVE_TCLCB_TREE_EXPAND, tstring, WAVE_TCLCB_TREE_EXPAND_FLAGS); } } else { GLOBALS->open_tree_nodes = xl_delete(tstring, GLOBALS->open_tree_nodes); if(found) { gtkwavetcl_setvar(WAVE_TCLCB_TREE_COLLAPSE, tstring, WAVE_TCLCB_TREE_COLLAPSE_FLAGS); } } } static void tree_expand_callback(GtkCTree *ctree, GtkCTreeNode *node, gpointer user_data) { (void)ctree; (void)user_data; create_sst_nodes_if_necessary(node); generic_tree_expand_collapse_callback(1, node); #ifdef WAVE_ALLOW_QUARTZ_FLUSH_WORKAROUND #ifdef MAC_INTEGRATION /* workaround for ctree not rendering properly in OSX */ gtk_widget_hide(GTK_WIDGET(GLOBALS->tree_treesearch_gtk2_c_1)); gtk_widget_show(GTK_WIDGET(GLOBALS->tree_treesearch_gtk2_c_1)); #endif #endif } static void tree_collapse_callback(GtkCTree *ctree, GtkCTreeNode *node, gpointer user_data) { (void)ctree; (void)user_data; generic_tree_expand_collapse_callback(0, node); #ifdef WAVE_ALLOW_QUARTZ_FLUSH_WORKAROUND #ifdef MAC_INTEGRATION /* workaround for ctree not rendering properly in OSX */ gtk_widget_hide(GTK_WIDGET(GLOBALS->tree_treesearch_gtk2_c_1)); gtk_widget_show(GTK_WIDGET(GLOBALS->tree_treesearch_gtk2_c_1)); #endif #endif } void select_tree_node(char *name) { GtkCTree *ctree = GLOBALS->ctree_main; if(ctree) { int namlen = strlen(name); char *namecache = wave_alloca(namlen+1); char *name_end = name + namlen - 1; char *zap = name; GtkCTreeNode *node = GLOBALS->any_tree_node; GtkCTreeRow *gctr = GTK_CTREE_ROW(node); strcpy(namecache, name); while(gctr->parent) { node = gctr->parent; gctr = GTK_CTREE_ROW(node); } for(;;) { struct tree *t = gctr->row.data; while(*zap) { if(*zap != GLOBALS->hier_delimeter) { zap++; } else { *zap = 0; break; } } if(!strcmp(t->name, name)) { if(zap == name_end) { /* printf("[treeselectnode] '%s' ok\n", name); */ gtk_ctree_select(ctree, node); GLOBALS->sst_sig_root_treesearch_gtk2_c_1 = t; GLOBALS->sig_root_treesearch_gtk2_c_1 = t->child; fill_sig_store (); return; } else { node = gctr->children; gctr = GTK_CTREE_ROW(node); if(!gctr) break; name = ++zap; continue; } } node = gctr->sibling; if(!node) break; gctr = GTK_CTREE_ROW(node); } /* printf("[treeselectnode] '%s' failed\n", name); */ } } /* Callbacks for tree area when a row is selected/deselected. */ static void select_row_callback(GtkWidget *widget, gint row, gint column, GdkEventButton *event, gpointer data) { (void)widget; (void)column; (void)event; (void)data; struct tree *t; GtkCTreeNode* node = gtk_ctree_node_nth(GLOBALS->ctree_main, row); if(node) { GtkCTreeRow **gctr; int depth, i; int len = 1; char *tstring; char hier_suffix[2]; hier_suffix[0] = GLOBALS->hier_delimeter; hier_suffix[1] = 0; depth = GTK_CTREE_ROW(node)->level; gctr = wave_alloca(depth * sizeof(GtkCTreeRow *)); for(i=depth-1;i>=0;i--) { gctr[i] = GTK_CTREE_ROW(node); t = gctr[i]->row.data; len += (strlen(t->name) + 1); node = gctr[i]->parent; } tstring = wave_alloca(len); memset(tstring, 0, len); for(i=0;irow.data; strcat(tstring, t->name); strcat(tstring, hier_suffix); } if(GLOBALS->selected_hierarchy_name) { free_2(GLOBALS->selected_hierarchy_name); } GLOBALS->selected_hierarchy_name = strdup_2(tstring); } t=(struct tree *)gtk_clist_get_row_data(GTK_CLIST(GLOBALS->ctree_main), row); DEBUG(printf("TS: %08x %s\n",t,t->name)); GLOBALS->sst_sig_root_treesearch_gtk2_c_1 = t; GLOBALS->sig_root_treesearch_gtk2_c_1 = t->child; fill_sig_store (); gtkwavetcl_setvar(WAVE_TCLCB_TREE_SELECT, GLOBALS->selected_hierarchy_name, WAVE_TCLCB_TREE_SELECT_FLAGS); } static void unselect_row_callback(GtkWidget *widget, gint row, gint column, GdkEventButton *event, gpointer data) { (void)widget; (void)column; (void)event; (void)data; struct tree *t; if(GLOBALS->selected_hierarchy_name) { gtkwavetcl_setvar(WAVE_TCLCB_TREE_UNSELECT, GLOBALS->selected_hierarchy_name, WAVE_TCLCB_TREE_UNSELECT_FLAGS); free_2(GLOBALS->selected_hierarchy_name); GLOBALS->selected_hierarchy_name = NULL; } t=(struct tree *)gtk_clist_get_row_data(GTK_CLIST(GLOBALS->ctree_main), row); if(t) { /* unused */ } DEBUG(printf("TU: %08x %s\n",t,t->name)); GLOBALS->sst_sig_root_treesearch_gtk2_c_1 = NULL; GLOBALS->sig_root_treesearch_gtk2_c_1 = GLOBALS->treeroot; fill_sig_store (); } /* Signal callback for the filter widget. This catch the return key to update the signal area. */ static gboolean filter_edit_cb (GtkWidget *widget, GdkEventKey *ev, gpointer *data) { (void)data; /* Maybe this test is too strong ? */ if (ev->keyval == GDK_Return) { const char *t; /* Get the filter string, save it and change the store. */ if(GLOBALS->filter_str_treesearch_gtk2_c_1) { free_2((char *)GLOBALS->filter_str_treesearch_gtk2_c_1); GLOBALS->filter_str_treesearch_gtk2_c_1 = NULL; } t = gtk_entry_get_text (GTK_ENTRY (widget)); if (t == NULL || *t == 0) GLOBALS->filter_str_treesearch_gtk2_c_1 = NULL; else { int i; GLOBALS->filter_str_treesearch_gtk2_c_1 = malloc_2(strlen(t) + 1); strcpy(GLOBALS->filter_str_treesearch_gtk2_c_1, t); GLOBALS->filter_typ_treesearch_gtk2_c_1 = ND_DIR_UNSPECIFIED; GLOBALS->filter_typ_polarity_treesearch_gtk2_c_1 = 0; GLOBALS->filter_matlen_treesearch_gtk2_c_1 = 0; GLOBALS->filter_noregex_treesearch_gtk2_c_1 = 0; if(GLOBALS->filter_str_treesearch_gtk2_c_1[0] == '+') { for(i=0;i<=ND_DIR_MAX;i++) { int tlen = strlen(vardir_strings[i]); if(!strncasecmp(vardir_strings[i], GLOBALS->filter_str_treesearch_gtk2_c_1 + 1, tlen)) { if(GLOBALS->filter_str_treesearch_gtk2_c_1[tlen + 1] == '+') { GLOBALS->filter_matlen_treesearch_gtk2_c_1 = tlen + 2; GLOBALS->filter_typ_treesearch_gtk2_c_1 = i; if(GLOBALS->filter_str_treesearch_gtk2_c_1[tlen + 2] == 0) { GLOBALS->filter_noregex_treesearch_gtk2_c_1 = 1; } } } } } else if(GLOBALS->filter_str_treesearch_gtk2_c_1[0] == '-') { for(i=0;i<=ND_DIR_MAX;i++) { int tlen = strlen(vardir_strings[i]); if(!strncasecmp(vardir_strings[i], GLOBALS->filter_str_treesearch_gtk2_c_1 + 1, tlen)) { if(GLOBALS->filter_str_treesearch_gtk2_c_1[tlen + 1] == '-') { GLOBALS->filter_matlen_treesearch_gtk2_c_1 = tlen + 2; GLOBALS->filter_typ_treesearch_gtk2_c_1 = i; GLOBALS->filter_typ_polarity_treesearch_gtk2_c_1 = 1; /* invert via XOR with 1 */ if(GLOBALS->filter_str_treesearch_gtk2_c_1[tlen + 2] == 0) { GLOBALS->filter_noregex_treesearch_gtk2_c_1 = 1; } } } } } wave_regex_compile(GLOBALS->filter_str_treesearch_gtk2_c_1 + GLOBALS->filter_matlen_treesearch_gtk2_c_1, WAVE_REGEX_TREE); } fill_sig_store (); } return FALSE; } /* * for dynamic updates, simply fake the return key to the function above */ static void press_callback (GtkWidget *widget, gpointer *data) { GdkEventKey ev; ev.keyval = GDK_Return; filter_edit_cb (widget, &ev, data); } /* * select/unselect all in treeview */ void treeview_select_all_callback(void) { GtkTreeSelection* ts = gtk_tree_view_get_selection(GTK_TREE_VIEW(GLOBALS->dnd_sigview)); gtk_tree_selection_select_all(ts); } void treeview_unselect_all_callback(void) { GtkTreeSelection* ts = gtk_tree_view_get_selection(GTK_TREE_VIEW(GLOBALS->dnd_sigview)); gtk_tree_selection_unselect_all(ts); } int treebox_is_active(void) { return(GLOBALS->is_active_treesearch_gtk2_c_6); } static void enter_callback_e(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; G_CONST_RETURN gchar *entry_text; int len; entry_text = gtk_entry_get_text(GTK_ENTRY(GLOBALS->entry_a_treesearch_gtk2_c_2)); entry_text = entry_text ? entry_text : ""; DEBUG(printf("Entry contents: %s\n", entry_text)); if(!(len=strlen(entry_text))) GLOBALS->entrybox_text_local_treesearch_gtk2_c_3=NULL; else strcpy((GLOBALS->entrybox_text_local_treesearch_gtk2_c_3=(char *)malloc_2(len+1)),entry_text); wave_gtk_grab_remove(GLOBALS->window1_treesearch_gtk2_c_3); gtk_widget_destroy(GLOBALS->window1_treesearch_gtk2_c_3); GLOBALS->window1_treesearch_gtk2_c_3 = NULL; GLOBALS->cleanup_e_treesearch_gtk2_c_3(); } static void destroy_callback_e(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; DEBUG(printf("Entry Cancel\n")); GLOBALS->entrybox_text_local_treesearch_gtk2_c_3=NULL; wave_gtk_grab_remove(GLOBALS->window1_treesearch_gtk2_c_3); gtk_widget_destroy(GLOBALS->window1_treesearch_gtk2_c_3); GLOBALS->window1_treesearch_gtk2_c_3 = NULL; } static void entrybox_local(char *title, int width, char *default_text, int maxch, GtkSignalFunc func) { GtkWidget *vbox, *hbox; GtkWidget *button1, *button2; GLOBALS->cleanup_e_treesearch_gtk2_c_3=func; /* fix problem where ungrab doesn't occur if button pressed + simultaneous accelerator key occurs */ if(GLOBALS->in_button_press_wavewindow_c_1) { gdk_pointer_ungrab(GDK_CURRENT_TIME); } /* create a new modal window */ GLOBALS->window1_treesearch_gtk2_c_3 = gtk_window_new(GLOBALS->disable_window_manager ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL); install_focus_cb(GLOBALS->window1_treesearch_gtk2_c_3, ((char *)&GLOBALS->window1_treesearch_gtk2_c_3) - ((char *)GLOBALS)); gtk_widget_set_usize( GTK_WIDGET (GLOBALS->window1_treesearch_gtk2_c_3), width, 60); gtk_window_set_title(GTK_WINDOW (GLOBALS->window1_treesearch_gtk2_c_3), title); gtkwave_signal_connect(GTK_OBJECT (GLOBALS->window1_treesearch_gtk2_c_3), "delete_event",(GtkSignalFunc) destroy_callback_e, NULL); vbox = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (GLOBALS->window1_treesearch_gtk2_c_3), vbox); gtk_widget_show (vbox); GLOBALS->entry_a_treesearch_gtk2_c_2 = gtk_entry_new_with_max_length (maxch); gtkwave_signal_connect(GTK_OBJECT(GLOBALS->entry_a_treesearch_gtk2_c_2), "activate",GTK_SIGNAL_FUNC(enter_callback_e),GLOBALS->entry_a_treesearch_gtk2_c_2); gtk_entry_set_text (GTK_ENTRY (GLOBALS->entry_a_treesearch_gtk2_c_2), default_text); gtk_entry_select_region (GTK_ENTRY (GLOBALS->entry_a_treesearch_gtk2_c_2),0, GTK_ENTRY(GLOBALS->entry_a_treesearch_gtk2_c_2)->text_length); gtk_box_pack_start (GTK_BOX (vbox), GLOBALS->entry_a_treesearch_gtk2_c_2, TRUE, TRUE, 0); gtk_widget_show (GLOBALS->entry_a_treesearch_gtk2_c_2); hbox = gtk_hbox_new (FALSE, 1); gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0); gtk_widget_show (hbox); button1 = gtk_button_new_with_label ("OK"); gtk_widget_set_usize(button1, 100, -1); gtkwave_signal_connect(GTK_OBJECT (button1), "clicked", GTK_SIGNAL_FUNC(enter_callback_e), NULL); gtk_widget_show (button1); gtk_container_add (GTK_CONTAINER (hbox), button1); GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT); gtkwave_signal_connect_object (GTK_OBJECT (button1), "realize", (GtkSignalFunc) gtk_widget_grab_default, GTK_OBJECT (button1)); button2 = gtk_button_new_with_label ("Cancel"); gtk_widget_set_usize(button2, 100, -1); gtkwave_signal_connect(GTK_OBJECT (button2), "clicked", GTK_SIGNAL_FUNC(destroy_callback_e), NULL); GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT); gtk_widget_show (button2); gtk_container_add (GTK_CONTAINER (hbox), button2); gtk_widget_show(GLOBALS->window1_treesearch_gtk2_c_3); wave_gtk_grab_add(GLOBALS->window1_treesearch_gtk2_c_3); } /***************************************************************************/ /* Get the highest signal from T. */ struct tree *fetchhigh(struct tree *t) { while(t->child) t=t->child; return(t); } /* Get the lowest signal from T. */ struct tree *fetchlow(struct tree *t) { if(t->child) { t=t->child; for(;;) { while(t->next) t=t->next; if(t->child) t=t->child; else break; } } return(t); } static void fetchvex2(struct tree *t, char direction, char level) { while(t) { if(t->child) { if(t->child->child) { fetchvex2(t->child, direction, 1); } else { add_vector_range(NULL, fetchlow(t)->t_which, fetchhigh(t)->t_which, direction); } } if(level) { t=t->next; } else { break; } } } void fetchvex(struct tree *t, char direction) { if(t) { if(t->child) { fetchvex2(t, direction, 0); } else { add_vector_range(NULL, fetchlow(t)->t_which, fetchhigh(t)->t_which, direction); } } } /* call cleanup() on ok/insert functions */ static void bundle_cleanup_foreach (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) { (void)path; (void)data; struct tree *sel; /* Extract the tree. */ gtk_tree_model_get (model, iter, TREE_COLUMN, &sel, -1); if(!sel) return; if(GLOBALS->entrybox_text_local_treesearch_gtk2_c_3) { char *efix; if(!strlen(GLOBALS->entrybox_text_local_treesearch_gtk2_c_3)) { DEBUG(printf("Bundle name is not specified--recursing into hierarchy.\n")); fetchvex(sel, GLOBALS->bundle_direction_treesearch_gtk2_c_3); } else { efix=GLOBALS->entrybox_text_local_treesearch_gtk2_c_3; while(*efix) { if(*efix==' ') { *efix='_'; } efix++; } DEBUG(printf("Bundle name is: %s\n",GLOBALS->entrybox_text_local_treesearch_gtk2_c_3)); add_vector_range(GLOBALS->entrybox_text_local_treesearch_gtk2_c_3, fetchlow(sel)->t_which, fetchhigh(sel)->t_which, GLOBALS->bundle_direction_treesearch_gtk2_c_3); } free_2(GLOBALS->entrybox_text_local_treesearch_gtk2_c_3); } else { DEBUG(printf("Bundle name is not specified--recursing into hierarchy.\n")); fetchvex(sel, GLOBALS->bundle_direction_treesearch_gtk2_c_3); } } static void bundle_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; gtk_tree_selection_selected_foreach (GLOBALS->sig_selection_treesearch_gtk2_c_1, &bundle_cleanup_foreach, NULL); MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } static void bundle_callback_generic(void) { if(!GLOBALS->autoname_bundles) { if (gtk_tree_selection_count_selected_rows (GLOBALS->sig_selection_treesearch_gtk2_c_1) != 1) return; entrybox_local("Enter Bundle Name",300,"",128, GTK_SIGNAL_FUNC(bundle_cleanup)); } else { GLOBALS->entrybox_text_local_treesearch_gtk2_c_3=NULL; bundle_cleanup(NULL, NULL); } } static void bundle_callback_up(GtkWidget *widget, gpointer data) { (void)widget; (void)data; GLOBALS->bundle_direction_treesearch_gtk2_c_3=0; bundle_callback_generic(); } static void bundle_callback_down(GtkWidget *widget, gpointer data) { (void)widget; (void)data; GLOBALS->bundle_direction_treesearch_gtk2_c_3=1; bundle_callback_generic(); } /* Callback for insert/replace/append buttions. This call-back is called for every signal selected. */ enum cb_action { ACTION_INSERT, ACTION_REPLACE, ACTION_APPEND, ACTION_PREPEND }; static void sig_selection_foreach (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) { (void)path; (void)data; struct tree *sel; /* const enum cb_action action = (enum cb_action)data; */ int i; int low, high; /* Get the tree. */ gtk_tree_model_get (model, iter, TREE_COLUMN, &sel, -1); if(!sel) return; low = fetchlow(sel)->t_which; high = fetchhigh(sel)->t_which; /* Add signals and vectors. */ for(i=low;i<=high;i++) { int len; struct symbol *s, *t; s=GLOBALS->facs[i]; t=s->vec_root; if((t)&&(GLOBALS->autocoalesce)) { if(get_s_selected(t)) { set_s_selected(t,0); len=0; while(t) { len++; t=t->vec_chain; } if(len) add_vector_chain(s->vec_root, len); } } else { AddNodeUnroll(s->n, NULL); } } } static void sig_selection_foreach_finalize (gpointer data) { const enum cb_action action = (enum cb_action)data; if (action == ACTION_REPLACE || action == ACTION_INSERT || action == ACTION_PREPEND) { Trptr tfirst=NULL, tlast=NULL; Trptr t; Trptr *tp = NULL; int numhigh = 0; int it; if (action == ACTION_REPLACE) { tfirst=GLOBALS->traces.first; tlast=GLOBALS->traces.last; /* cache for highlighting */ } GLOBALS->traces.buffercount=GLOBALS->traces.total; GLOBALS->traces.buffer=GLOBALS->traces.first; GLOBALS->traces.bufferlast=GLOBALS->traces.last; GLOBALS->traces.first=GLOBALS->tcache_treesearch_gtk2_c_2.first; GLOBALS->traces.last=GLOBALS->tcache_treesearch_gtk2_c_2.last; GLOBALS->traces.total=GLOBALS->tcache_treesearch_gtk2_c_2.total; if (action == ACTION_REPLACE) { t = GLOBALS->traces.first; while(t) { if(t->flags & TR_HIGHLIGHT) { numhigh++; } t = t->t_next; } if(numhigh) { tp = calloc_2(numhigh, sizeof(Trptr)); t = GLOBALS->traces.first; it = 0; while(t) { if(t->flags & TR_HIGHLIGHT) { tp[it++] = t; } t = t->t_next; } } } if(action == ACTION_PREPEND) { PrependBuffer(); } else { PasteBuffer(); } GLOBALS->traces.buffercount=GLOBALS->tcache_treesearch_gtk2_c_2.buffercount; GLOBALS->traces.buffer=GLOBALS->tcache_treesearch_gtk2_c_2.buffer; GLOBALS->traces.bufferlast=GLOBALS->tcache_treesearch_gtk2_c_2.bufferlast; if (action == ACTION_REPLACE) { for(it=0;itflags |= TR_HIGHLIGHT; } t = tfirst; while(t) { t->flags &= ~TR_HIGHLIGHT; if(t==tlast) break; t=t->t_next; } CutBuffer(); while(tfirst) { tfirst->flags |= TR_HIGHLIGHT; if(tfirst==tlast) break; tfirst=tfirst->t_next; } if(tp) { free_2(tp); } } } } static void sig_selection_foreach_preload_lx2 (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) { (void)path; (void)data; struct tree *sel; /* const enum cb_action action = (enum cb_action)data; */ int i; int low, high; /* Get the tree. */ gtk_tree_model_get (model, iter, TREE_COLUMN, &sel, -1); if(!sel) return; low = fetchlow(sel)->t_which; high = fetchhigh(sel)->t_which; /* If signals are vectors, coalesces vectors if so. */ for(i=low;i<=high;i++) { struct symbol *s; s=GLOBALS->facs[i]; if(s->vec_root) { set_s_selected(s->vec_root, GLOBALS->autocoalesce); } } /* LX2 */ if(GLOBALS->is_lx2) { for(i=low;i<=high;i++) { struct symbol *s, *t; s=GLOBALS->facs[i]; t=s->vec_root; if((t)&&(GLOBALS->autocoalesce)) { if(get_s_selected(t)) { while(t) { if(t->n->mv.mvlfac) { lx2_set_fac_process_mask(t->n); GLOBALS->pre_import_treesearch_gtk2_c_1++; } t=t->vec_chain; } } } else { if(s->n->mv.mvlfac) { lx2_set_fac_process_mask(s->n); GLOBALS->pre_import_treesearch_gtk2_c_1++; } } } } /* LX2 */ } static void action_callback(enum cb_action action) { GLOBALS->pre_import_treesearch_gtk2_c_1 = 0; /* once through to mass gather lx2 traces... */ gtk_tree_selection_selected_foreach (GLOBALS->sig_selection_treesearch_gtk2_c_1, &sig_selection_foreach_preload_lx2, (void *)action); if(GLOBALS->pre_import_treesearch_gtk2_c_1) { lx2_import_masked(); } /* then do */ if (action == ACTION_INSERT || action == ACTION_REPLACE || action == ACTION_PREPEND) { /* Save and clear current traces. */ memcpy(&GLOBALS->tcache_treesearch_gtk2_c_2,&GLOBALS->traces,sizeof(Traces)); GLOBALS->traces.total=0; GLOBALS->traces.first=GLOBALS->traces.last=NULL; } gtk_tree_selection_selected_foreach (GLOBALS->sig_selection_treesearch_gtk2_c_1, &sig_selection_foreach, (void *)action); sig_selection_foreach_finalize((void *)action); if(action == ACTION_APPEND) { GLOBALS->traces.scroll_top = GLOBALS->traces.scroll_bottom = GLOBALS->traces.last; } MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } static void insert_callback(GtkWidget *widget, GtkWidget *nothing) { (void)nothing; set_window_busy(widget); action_callback (ACTION_INSERT); set_window_idle(widget); } static void replace_callback(GtkWidget *widget, GtkWidget *nothing) { (void)nothing; set_window_busy(widget); action_callback (ACTION_REPLACE); set_window_idle(widget); } static void ok_callback(GtkWidget *widget, GtkWidget *nothing) { (void)nothing; set_window_busy(widget); action_callback (ACTION_APPEND); set_window_idle(widget); } static void destroy_callback(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; GLOBALS->is_active_treesearch_gtk2_c_6=0; gtk_widget_destroy(GLOBALS->window_treesearch_gtk2_c_12); GLOBALS->window_treesearch_gtk2_c_12 = NULL; GLOBALS->dnd_sigview = NULL; GLOBALS->gtk2_tree_frame = NULL; GLOBALS->ctree_main = NULL; GLOBALS->filter_entry = NULL; /* when treebox() SST goes away after closed and rc hide_sst is true */ free_afl(); if(GLOBALS->selected_hierarchy_name) { free_2(GLOBALS->selected_hierarchy_name); GLOBALS->selected_hierarchy_name = NULL; } } /**********************************************************************/ static gboolean view_selection_func (GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean path_currently_selected, gpointer userdata) { (void)selection; (void)userdata; GtkTreeIter iter; if (gtk_tree_model_get_iter(model, &iter, path)) { gchar *name; gtk_tree_model_get(model, &iter, 0, &name, -1); if(GLOBALS->selected_sig_name) { free_2(GLOBALS->selected_sig_name); GLOBALS->selected_sig_name = NULL; } if (!path_currently_selected) { GLOBALS->selected_sig_name = strdup_2(name); gtkwavetcl_setvar(WAVE_TCLCB_TREE_SIG_SELECT, name, WAVE_TCLCB_TREE_SIG_SELECT_FLAGS); } else { gtkwavetcl_setvar(WAVE_TCLCB_TREE_SIG_UNSELECT, name, WAVE_TCLCB_TREE_SIG_UNSELECT_FLAGS); } g_free(name); } return TRUE; /* allow selection state to change */ } /**********************************************************************/ static gint button_press_event_std(GtkWidget *widget, GdkEventButton *event) { (void)widget; if(event->type == GDK_2BUTTON_PRESS) { if(GLOBALS->selected_hierarchy_name && GLOBALS->selected_sig_name) { char *sstr = wave_alloca(strlen(GLOBALS->selected_hierarchy_name) + strlen(GLOBALS->selected_sig_name) + 1); strcpy(sstr, GLOBALS->selected_hierarchy_name); strcat(sstr, GLOBALS->selected_sig_name); gtkwavetcl_setvar(WAVE_TCLCB_TREE_SIG_DOUBLE_CLICK, sstr, WAVE_TCLCB_TREE_SIG_DOUBLE_CLICK_FLAGS); } } return(FALSE); } static gint hier_top_button_press_event_std(GtkWidget *widget, GdkEventButton *event) { if((event->button == 3) && (event->type == GDK_BUTTON_PRESS)) { if(GLOBALS->sst_sig_root_treesearch_gtk2_c_1) { do_sst_popup_menu (widget, event); return(TRUE); } } return(FALSE); } /**********************************************************************/ /* * mainline.. */ void treebox(char *title, GtkSignalFunc func, GtkWidget *old_window) { GtkWidget *scrolled_win, *sig_scroll_win; GtkWidget *hbox; GtkWidget *button1, *button2, *button3, *button3a, *button4, *button5; GtkWidget *frameh, *sig_frame; GtkWidget *vbox, *vpan, *filter_hbox; GtkWidget *filter_label; GtkWidget *sig_view; GtkTooltips *tooltips; GtkCList *clist; /* fix problem where ungrab doesn't occur if button pressed + simultaneous accelerator key occurs */ if(GLOBALS->in_button_press_wavewindow_c_1) { gdk_pointer_ungrab(GDK_CURRENT_TIME); } if(old_window) { GLOBALS->is_active_treesearch_gtk2_c_6=1; GLOBALS->cleanup_treesearch_gtk2_c_8=func; goto do_tooltips; } if(GLOBALS->is_active_treesearch_gtk2_c_6) { if(GLOBALS->window_treesearch_gtk2_c_12) { gdk_window_raise(GLOBALS->window_treesearch_gtk2_c_12->window); } else { #if GTK_CHECK_VERSION(2,4,0) if(GLOBALS->expanderwindow) { gtk_expander_set_expanded(GTK_EXPANDER(GLOBALS->expanderwindow), TRUE); } #endif } return; } GLOBALS->is_active_treesearch_gtk2_c_6=1; GLOBALS->cleanup_treesearch_gtk2_c_8=func; /* create a new modal window */ GLOBALS->window_treesearch_gtk2_c_12 = gtk_window_new(GLOBALS->disable_window_manager ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL); install_focus_cb(GLOBALS->window_treesearch_gtk2_c_12, ((char *)&GLOBALS->window_treesearch_gtk2_c_12) - ((char *)GLOBALS)); gtk_window_set_title(GTK_WINDOW (GLOBALS->window_treesearch_gtk2_c_12), title); gtkwave_signal_connect(GTK_OBJECT (GLOBALS->window_treesearch_gtk2_c_12), "delete_event",(GtkSignalFunc) destroy_callback, NULL); do_tooltips: tooltips=gtk_tooltips_new_2(); GLOBALS->treesearch_gtk2_window_vbox = vbox = gtk_vbox_new (FALSE, 1); gtk_widget_show (vbox); gtkwave_signal_connect(GTK_OBJECT(vbox), "button_press_event",GTK_SIGNAL_FUNC(hier_top_button_press_event_std), NULL); vpan = gtk_vpaned_new (); gtk_widget_show (vpan); gtk_box_pack_start (GTK_BOX (vbox), vpan, TRUE, TRUE, 1); /* Hierarchy. */ GLOBALS->gtk2_tree_frame = gtk_frame_new (NULL); gtk_container_border_width (GTK_CONTAINER (GLOBALS->gtk2_tree_frame), 3); gtk_widget_show(GLOBALS->gtk2_tree_frame); gtk_paned_pack1 (GTK_PANED (vpan), GLOBALS->gtk2_tree_frame, TRUE, FALSE); GLOBALS->tree_treesearch_gtk2_c_1=gtk_ctree_new(1,0); GLOBALS->ctree_main=GTK_CTREE(GLOBALS->tree_treesearch_gtk2_c_1); gtk_clist_set_column_auto_resize (GTK_CLIST (GLOBALS->tree_treesearch_gtk2_c_1), 0, TRUE); gtk_widget_show(GLOBALS->tree_treesearch_gtk2_c_1); gtk_clist_set_use_drag_icons(GTK_CLIST (GLOBALS->tree_treesearch_gtk2_c_1), FALSE); clist=GTK_CLIST(GLOBALS->tree_treesearch_gtk2_c_1); gtkwave_signal_connect_object (GTK_OBJECT (clist), "select_row", GTK_SIGNAL_FUNC(select_row_callback), NULL); gtkwave_signal_connect_object (GTK_OBJECT (clist), "unselect_row", GTK_SIGNAL_FUNC(unselect_row_callback), NULL); gtkwave_signal_connect_object (GTK_OBJECT (clist), "tree_expand", GTK_SIGNAL_FUNC(tree_expand_callback), NULL); gtkwave_signal_connect_object (GTK_OBJECT (clist), "tree_collapse", GTK_SIGNAL_FUNC(tree_collapse_callback), NULL); gtk_clist_freeze(clist); gtk_clist_clear(clist); decorated_module_cleanup(); maketree(NULL, GLOBALS->treeroot); gtk_clist_thaw(clist); scrolled_win = gtk_scrolled_window_new (NULL, NULL); gtk_widget_set_usize( GTK_WIDGET (scrolled_win), -1, 50); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_widget_show(scrolled_win); gtk_container_add (GTK_CONTAINER (scrolled_win), GTK_WIDGET (GLOBALS->tree_treesearch_gtk2_c_1)); gtk_container_add (GTK_CONTAINER (GLOBALS->gtk2_tree_frame), scrolled_win); /* Signal names. */ GLOBALS->sig_store_treesearch_gtk2_c_1 = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); GLOBALS->sst_sig_root_treesearch_gtk2_c_1 = NULL; GLOBALS->sig_root_treesearch_gtk2_c_1 = GLOBALS->treeroot; fill_sig_store (); sig_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (GLOBALS->sig_store_treesearch_gtk2_c_1)); gtkwave_signal_connect(GTK_OBJECT(sig_view), "button_press_event",GTK_SIGNAL_FUNC(hier_top_button_press_event_std), NULL); /* The view now holds a reference. We can get rid of our own reference */ g_object_unref (G_OBJECT (GLOBALS->sig_store_treesearch_gtk2_c_1)); { GtkCellRenderer *renderer; GtkTreeViewColumn *column; renderer = gtk_cell_renderer_text_new (); switch(GLOBALS->loaded_file_type) { #ifdef EXTLOAD_SUFFIX case EXTLOAD_FILE: #endif case FST_FILE: /* fallthrough for Dir is deliberate for extload and FST */ if(GLOBALS->nonimplicit_direction_encountered) { column = gtk_tree_view_column_new_with_attributes ("Dir", renderer, "text", DIR_COLUMN, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (sig_view), column); } case AE2_FILE: case VCD_FILE: case VCD_RECODER_FILE: case DUMPLESS_FILE: column = gtk_tree_view_column_new_with_attributes (((GLOBALS->supplemental_datatypes_encountered) && (GLOBALS->supplemental_vartypes_encountered)) ? "VType" : "Type", renderer, "text", TYPE_COLUMN, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (sig_view), column); if((GLOBALS->supplemental_datatypes_encountered) && (GLOBALS->supplemental_vartypes_encountered)) { column = gtk_tree_view_column_new_with_attributes ("DType", renderer, "text", DTYPE_COLUMN, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (sig_view), column); } break; default: break; } column = gtk_tree_view_column_new_with_attributes ("Signals", renderer, "text", NAME_COLUMN, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (sig_view), column); /* Setup the selection handler */ GLOBALS->sig_selection_treesearch_gtk2_c_1 = gtk_tree_view_get_selection (GTK_TREE_VIEW (sig_view)); gtk_tree_selection_set_mode (GLOBALS->sig_selection_treesearch_gtk2_c_1, GTK_SELECTION_MULTIPLE); gtk_tree_selection_set_select_function (GLOBALS->sig_selection_treesearch_gtk2_c_1, view_selection_func, NULL, NULL); gtkwave_signal_connect(GTK_OBJECT(sig_view), "button_press_event",GTK_SIGNAL_FUNC(button_press_event_std), NULL); } GLOBALS->dnd_sigview = sig_view; dnd_setup(GLOBALS->dnd_sigview, GLOBALS->signalarea, 0); sig_frame = gtk_frame_new (NULL); gtk_container_border_width (GTK_CONTAINER (sig_frame), 3); gtk_widget_show(sig_frame); gtk_paned_pack2 (GTK_PANED (vpan), sig_frame, TRUE, FALSE); sig_scroll_win = gtk_scrolled_window_new (NULL, NULL); gtk_widget_set_usize (GTK_WIDGET (sig_scroll_win), 80, 100); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sig_scroll_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_widget_show(sig_scroll_win); gtk_container_add (GTK_CONTAINER (sig_frame), sig_scroll_win); gtk_container_add (GTK_CONTAINER (sig_scroll_win), sig_view); gtk_widget_show (sig_view); /* Filter. */ filter_hbox = gtk_hbox_new (FALSE, 1); gtk_widget_show (filter_hbox); filter_label = gtk_label_new ("Filter:"); gtk_widget_show (filter_label); gtk_box_pack_start (GTK_BOX (filter_hbox), filter_label, FALSE, FALSE, 1); GLOBALS->filter_entry = gtk_entry_new (); if(GLOBALS->filter_str_treesearch_gtk2_c_1) { gtk_entry_set_text(GTK_ENTRY(GLOBALS->filter_entry), GLOBALS->filter_str_treesearch_gtk2_c_1); } gtk_widget_show (GLOBALS->filter_entry); gtkwave_signal_connect(GTK_OBJECT(GLOBALS->filter_entry), "activate", GTK_SIGNAL_FUNC(press_callback), NULL); if(!GLOBALS->do_dynamic_treefilter) { gtkwave_signal_connect(GTK_OBJECT (GLOBALS->filter_entry), "key_press_event", (GtkSignalFunc) filter_edit_cb, NULL); } else { gtkwave_signal_connect(GTK_OBJECT(GLOBALS->filter_entry), "changed", GTK_SIGNAL_FUNC(press_callback), NULL); } gtk_tooltips_set_tip_2(tooltips, GLOBALS->filter_entry, "Add a POSIX filter. " "'.*' matches any number of characters," " '.' matches any character. Hit Return to apply." " The filter may be preceded with the port direction if it exists such as ++ (show only non-port), +I+, +O+, +IO+, etc." " Use -- to exclude all non-ports (i.e., show only all ports), -I- to exclude all input ports, etc.", NULL); gtk_box_pack_start (GTK_BOX (filter_hbox), GLOBALS->filter_entry, FALSE, FALSE, 1); gtk_box_pack_start (GTK_BOX (vbox), filter_hbox, FALSE, FALSE, 1); /* Buttons. */ frameh = gtk_frame_new (NULL); gtk_container_border_width (GTK_CONTAINER (frameh), 3); gtk_widget_show(frameh); gtk_box_pack_start (GTK_BOX (vbox), frameh, FALSE, FALSE, 1); hbox = gtk_hbox_new (FALSE, 1); gtk_widget_show (hbox); button1 = gtk_button_new_with_label ("Append"); gtk_container_border_width (GTK_CONTAINER (button1), 3); gtkwave_signal_connect_object (GTK_OBJECT (button1), "clicked",GTK_SIGNAL_FUNC(ok_callback),GTK_OBJECT (GLOBALS->window_treesearch_gtk2_c_12)); gtk_widget_show (button1); gtk_tooltips_set_tip_2(tooltips, button1, "Add selected signal hierarchy to end of the display on the main window.",NULL); gtk_box_pack_start (GTK_BOX (hbox), button1, TRUE, FALSE, 0); button2 = gtk_button_new_with_label (" Insert "); gtk_container_border_width (GTK_CONTAINER (button2), 3); gtkwave_signal_connect_object (GTK_OBJECT (button2), "clicked",GTK_SIGNAL_FUNC(insert_callback),GTK_OBJECT (GLOBALS->window_treesearch_gtk2_c_12)); gtk_widget_show (button2); gtk_tooltips_set_tip_2(tooltips, button2, "Add selected signal hierarchy after last highlighted signal on the main window.",NULL); gtk_box_pack_start (GTK_BOX (hbox), button2, TRUE, FALSE, 0); if(GLOBALS->vcd_explicit_zero_subscripts>=0) { button3 = gtk_button_new_with_label (" Bundle Up "); gtk_container_border_width (GTK_CONTAINER (button3), 3); gtkwave_signal_connect_object (GTK_OBJECT (button3), "clicked",GTK_SIGNAL_FUNC(bundle_callback_up),GTK_OBJECT (GLOBALS->window_treesearch_gtk2_c_12)); gtk_widget_show (button3); gtk_tooltips_set_tip_2(tooltips, button3, "Bundle selected signal hierarchy into a single bit " "vector with the topmost signal as the LSB and the " "lowest as the MSB. Entering a zero length bundle " "name will reconstruct the individual vectors " "in the hierarchy. Otherwise, all the bits in " "the hierarchy will be coalesced with the supplied " "name into a single vector.",NULL); gtk_box_pack_start (GTK_BOX (hbox), button3, TRUE, FALSE, 0); button3a = gtk_button_new_with_label (" Bundle Down "); gtk_container_border_width (GTK_CONTAINER (button3a), 3); gtkwave_signal_connect_object (GTK_OBJECT (button3a), "clicked",GTK_SIGNAL_FUNC(bundle_callback_down),GTK_OBJECT (GLOBALS->window_treesearch_gtk2_c_12)); gtk_widget_show (button3a); gtk_tooltips_set_tip_2(tooltips, button3a, "Bundle selected signal hierarchy into a single bit " "vector with the topmost signal as the MSB and the " "lowest as the LSB. Entering a zero length bundle " "name will reconstruct the individual vectors " "in the hierarchy. Otherwise, all the bits in " "the hierarchy will be coalesced with the supplied " "name into a single vector.",NULL); gtk_box_pack_start (GTK_BOX (hbox), button3a, TRUE, FALSE, 0); } button4 = gtk_button_new_with_label (" Replace "); gtk_container_border_width (GTK_CONTAINER (button4), 3); gtkwave_signal_connect_object (GTK_OBJECT (button4), "clicked",GTK_SIGNAL_FUNC(replace_callback),GTK_OBJECT (GLOBALS->window_treesearch_gtk2_c_12)); gtk_widget_show (button4); gtk_tooltips_set_tip_2(tooltips, button4, "Replace highlighted signals on the main window with signals selected above.",NULL); gtk_box_pack_start (GTK_BOX (hbox), button4, TRUE, FALSE, 0); button5 = gtk_button_new_with_label (" Exit "); gtk_container_border_width (GTK_CONTAINER (button5), 3); gtkwave_signal_connect_object (GTK_OBJECT (button5), "clicked",GTK_SIGNAL_FUNC(destroy_callback),GTK_OBJECT (GLOBALS->window_treesearch_gtk2_c_12)); gtk_tooltips_set_tip_2(tooltips, button5, "Do nothing and return to the main window.",NULL); gtk_widget_show (button5); gtk_box_pack_start (GTK_BOX (hbox), button5, TRUE, FALSE, 0); gtk_container_add (GTK_CONTAINER (frameh), hbox); gtk_container_add (GTK_CONTAINER (GLOBALS->window_treesearch_gtk2_c_12), vbox); gtk_window_set_default_size (GTK_WINDOW (GLOBALS->window_treesearch_gtk2_c_12), 200, 400); gtk_widget_show(GLOBALS->window_treesearch_gtk2_c_12); } /* * for use with expander in gtk2.4 and higher... */ GtkWidget* treeboxframe(char *title, GtkSignalFunc func) { (void)title; GtkWidget *scrolled_win, *sig_scroll_win; GtkWidget *hbox; GtkWidget *button1, *button2, *button3, *button3a, *button4; GtkWidget *frameh, *sig_frame; GtkWidget *vbox, *vpan, *filter_hbox; GtkWidget *filter_label; GtkWidget *sig_view; GtkTooltips *tooltips; GtkCList *clist; GLOBALS->is_active_treesearch_gtk2_c_6=1; GLOBALS->cleanup_treesearch_gtk2_c_8=func; /* create a new modal window */ tooltips=gtk_tooltips_new_2(); vbox = gtk_vbox_new (FALSE, 1); gtk_widget_show (vbox); gtkwave_signal_connect(GTK_OBJECT(vbox), "button_press_event",GTK_SIGNAL_FUNC(hier_top_button_press_event_std), NULL); vpan = gtk_vpaned_new (); /* GLOBALS->sst_vpaned is to be used to clone position over during reload */ GLOBALS->sst_vpaned = (GtkPaned *)vpan; if(GLOBALS->vpanedwindow_size_cache) { gtk_paned_set_position(GTK_PANED(GLOBALS->sst_vpaned), GLOBALS->vpanedwindow_size_cache); GLOBALS->vpanedwindow_size_cache = 0; } gtk_widget_show (vpan); gtk_box_pack_start (GTK_BOX (vbox), vpan, TRUE, TRUE, 1); /* Hierarchy. */ GLOBALS->gtk2_tree_frame = gtk_frame_new (NULL); gtk_container_border_width (GTK_CONTAINER (GLOBALS->gtk2_tree_frame), 3); gtk_widget_show(GLOBALS->gtk2_tree_frame); gtk_paned_pack1 (GTK_PANED (vpan), GLOBALS->gtk2_tree_frame, TRUE, FALSE); GLOBALS->tree_treesearch_gtk2_c_1=gtk_ctree_new(1,0); GLOBALS->ctree_main=GTK_CTREE(GLOBALS->tree_treesearch_gtk2_c_1); gtk_clist_set_column_auto_resize (GTK_CLIST (GLOBALS->tree_treesearch_gtk2_c_1), 0, TRUE); gtk_widget_show(GLOBALS->tree_treesearch_gtk2_c_1); clist=GTK_CLIST(GLOBALS->tree_treesearch_gtk2_c_1); gtkwave_signal_connect_object (GTK_OBJECT (clist), "select_row", GTK_SIGNAL_FUNC(select_row_callback), NULL); gtkwave_signal_connect_object (GTK_OBJECT (clist), "unselect_row", GTK_SIGNAL_FUNC(unselect_row_callback), NULL); gtkwave_signal_connect_object (GTK_OBJECT (clist), "tree_expand", GTK_SIGNAL_FUNC(tree_expand_callback), NULL); gtkwave_signal_connect_object (GTK_OBJECT (clist), "tree_collapse", GTK_SIGNAL_FUNC(tree_collapse_callback), NULL); gtk_clist_freeze(clist); gtk_clist_clear(clist); decorated_module_cleanup(); maketree(NULL, GLOBALS->treeroot); gtk_clist_thaw(clist); scrolled_win = gtk_scrolled_window_new (NULL, NULL); gtk_widget_set_usize( GTK_WIDGET (scrolled_win), -1, 50); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_widget_show(scrolled_win); gtk_container_add (GTK_CONTAINER (scrolled_win), GTK_WIDGET (GLOBALS->tree_treesearch_gtk2_c_1)); gtk_container_add (GTK_CONTAINER (GLOBALS->gtk2_tree_frame), scrolled_win); /* Signal names. */ GLOBALS->sig_store_treesearch_gtk2_c_1 = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); GLOBALS->sst_sig_root_treesearch_gtk2_c_1 = NULL; GLOBALS->sig_root_treesearch_gtk2_c_1 = GLOBALS->treeroot; fill_sig_store (); sig_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (GLOBALS->sig_store_treesearch_gtk2_c_1)); gtkwave_signal_connect(GTK_OBJECT(sig_view), "button_press_event",GTK_SIGNAL_FUNC(hier_top_button_press_event_std), NULL); /* The view now holds a reference. We can get rid of our own reference */ g_object_unref (G_OBJECT (GLOBALS->sig_store_treesearch_gtk2_c_1)); { GtkCellRenderer *renderer; GtkTreeViewColumn *column; renderer = gtk_cell_renderer_text_new (); switch(GLOBALS->loaded_file_type) { #ifdef EXTLOAD_SUFFIX case EXTLOAD_FILE: #endif case FST_FILE: /* fallthrough for Dir is deliberate for extload and FST */ if(GLOBALS->nonimplicit_direction_encountered) { column = gtk_tree_view_column_new_with_attributes ("Dir", renderer, "text", DIR_COLUMN, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (sig_view), column); } case AE2_FILE: case VCD_FILE: case VCD_RECODER_FILE: case DUMPLESS_FILE: column = gtk_tree_view_column_new_with_attributes (((GLOBALS->supplemental_datatypes_encountered) && (GLOBALS->supplemental_vartypes_encountered)) ? "VType" : "Type", renderer, "text", TYPE_COLUMN, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (sig_view), column); if((GLOBALS->supplemental_datatypes_encountered) && (GLOBALS->supplemental_vartypes_encountered)) { column = gtk_tree_view_column_new_with_attributes ("DType", renderer, "text", DTYPE_COLUMN, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (sig_view), column); } break; default: break; } column = gtk_tree_view_column_new_with_attributes ("Signals", renderer, "text", NAME_COLUMN, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (sig_view), column); /* Setup the selection handler */ GLOBALS->sig_selection_treesearch_gtk2_c_1 = gtk_tree_view_get_selection (GTK_TREE_VIEW (sig_view)); gtk_tree_selection_set_mode (GLOBALS->sig_selection_treesearch_gtk2_c_1, GTK_SELECTION_MULTIPLE); gtk_tree_selection_set_select_function (GLOBALS->sig_selection_treesearch_gtk2_c_1, view_selection_func, NULL, NULL); gtkwave_signal_connect(GTK_OBJECT(sig_view), "button_press_event",GTK_SIGNAL_FUNC(button_press_event_std), NULL); } GLOBALS->dnd_sigview = sig_view; sig_frame = gtk_frame_new (NULL); gtk_container_border_width (GTK_CONTAINER (sig_frame), 3); gtk_widget_show(sig_frame); gtk_paned_pack2 (GTK_PANED (vpan), sig_frame, TRUE, FALSE); sig_scroll_win = gtk_scrolled_window_new (NULL, NULL); gtk_widget_set_usize (GTK_WIDGET (sig_scroll_win), 80, 100); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sig_scroll_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_widget_show(sig_scroll_win); gtk_container_add (GTK_CONTAINER (sig_frame), sig_scroll_win); gtk_container_add (GTK_CONTAINER (sig_scroll_win), sig_view); gtk_widget_show (sig_view); /* Filter. */ filter_hbox = gtk_hbox_new (FALSE, 1); gtk_widget_show (filter_hbox); filter_label = gtk_label_new ("Filter:"); gtk_widget_show (filter_label); gtk_box_pack_start (GTK_BOX (filter_hbox), filter_label, FALSE, FALSE, 1); GLOBALS->filter_entry = gtk_entry_new (); if(GLOBALS->filter_str_treesearch_gtk2_c_1) { gtk_entry_set_text(GTK_ENTRY(GLOBALS->filter_entry), GLOBALS->filter_str_treesearch_gtk2_c_1); } gtk_widget_show (GLOBALS->filter_entry); gtkwave_signal_connect(GTK_OBJECT(GLOBALS->filter_entry), "activate", GTK_SIGNAL_FUNC(press_callback), NULL); if(!GLOBALS->do_dynamic_treefilter) { gtkwave_signal_connect(GTK_OBJECT (GLOBALS->filter_entry), "key_press_event", (GtkSignalFunc) filter_edit_cb, NULL); } else { gtkwave_signal_connect(GTK_OBJECT(GLOBALS->filter_entry), "changed", GTK_SIGNAL_FUNC(press_callback), NULL); } gtk_tooltips_set_tip_2(tooltips, GLOBALS->filter_entry, "Add a POSIX filter. " "'.*' matches any number of characters," " '.' matches any character. Hit Return to apply." " The filter may be preceded with the port direction if it exists such as ++ (show only non-port), +I+, +O+, +IO+, etc." " Use -- to exclude all non-ports (i.e., show only all ports), -I- to exclude all input ports, etc.", NULL); gtk_box_pack_start (GTK_BOX (filter_hbox), GLOBALS->filter_entry, FALSE, FALSE, 1); gtk_box_pack_start (GTK_BOX (vbox), filter_hbox, FALSE, FALSE, 1); /* Buttons. */ frameh = gtk_frame_new (NULL); gtk_container_border_width (GTK_CONTAINER (frameh), 3); gtk_widget_show(frameh); gtk_box_pack_start (GTK_BOX (vbox), frameh, FALSE, FALSE, 1); hbox = gtk_hbox_new (FALSE, 1); gtk_widget_show (hbox); button1 = gtk_button_new_with_label ("Append"); gtk_container_border_width (GTK_CONTAINER (button1), 3); gtkwave_signal_connect_object (GTK_OBJECT (button1), "clicked", GTK_SIGNAL_FUNC(ok_callback), GTK_OBJECT (GLOBALS->gtk2_tree_frame)); gtk_widget_show (button1); gtk_tooltips_set_tip_2(tooltips, button1, "Add selected signal hierarchy to end of the display on the main window.",NULL); gtk_box_pack_start (GTK_BOX (hbox), button1, TRUE, FALSE, 0); button2 = gtk_button_new_with_label (" Insert "); gtk_container_border_width (GTK_CONTAINER (button2), 3); gtkwave_signal_connect_object (GTK_OBJECT (button2), "clicked", GTK_SIGNAL_FUNC(insert_callback), GTK_OBJECT (GLOBALS->gtk2_tree_frame)); gtk_widget_show (button2); gtk_tooltips_set_tip_2(tooltips, button2, "Add selected signal hierarchy after last highlighted signal on the main window.",NULL); gtk_box_pack_start (GTK_BOX (hbox), button2, TRUE, FALSE, 0); if(GLOBALS->vcd_explicit_zero_subscripts>=0) { button3 = gtk_button_new_with_label (" Bundle Up "); gtk_container_border_width (GTK_CONTAINER (button3), 3); gtkwave_signal_connect_object (GTK_OBJECT (button3), "clicked", GTK_SIGNAL_FUNC(bundle_callback_up), GTK_OBJECT (GLOBALS->gtk2_tree_frame)); gtk_widget_show (button3); gtk_tooltips_set_tip_2(tooltips, button3, "Bundle selected signal hierarchy into a single bit " "vector with the topmost signal as the LSB and the " "lowest as the MSB. Entering a zero length bundle " "name will reconstruct the individual vectors " "in the hierarchy. Otherwise, all the bits in " "the hierarchy will be coalesced with the supplied " "name into a single vector.",NULL); gtk_box_pack_start (GTK_BOX (hbox), button3, TRUE, FALSE, 0); button3a = gtk_button_new_with_label (" Bundle Down "); gtk_container_border_width (GTK_CONTAINER (button3a), 3); gtkwave_signal_connect_object (GTK_OBJECT (button3a), "clicked", GTK_SIGNAL_FUNC(bundle_callback_down), GTK_OBJECT (GLOBALS->gtk2_tree_frame)); gtk_widget_show (button3a); gtk_tooltips_set_tip_2(tooltips, button3a, "Bundle selected signal hierarchy into a single bit " "vector with the topmost signal as the MSB and the " "lowest as the LSB. Entering a zero length bundle " "name will reconstruct the individual vectors " "in the hierarchy. Otherwise, all the bits in " "the hierarchy will be coalesced with the supplied " "name into a single vector.",NULL); gtk_box_pack_start (GTK_BOX (hbox), button3a, TRUE, FALSE, 0); } button4 = gtk_button_new_with_label (" Replace "); gtk_container_border_width (GTK_CONTAINER (button4), 3); gtkwave_signal_connect_object (GTK_OBJECT (button4), "clicked", GTK_SIGNAL_FUNC(replace_callback), GTK_OBJECT (GLOBALS->gtk2_tree_frame)); gtk_widget_show (button4); gtk_tooltips_set_tip_2(tooltips, button4, "Replace highlighted signals on the main window with signals selected above.",NULL); gtk_box_pack_start (GTK_BOX (hbox), button4, TRUE, FALSE, 0); gtk_container_add (GTK_CONTAINER (frameh), hbox); return vbox; } /**************************************************************** ** ** dnd ** ****************************************************************/ /* * DND "drag_begin" handler, this is called whenever a drag starts. */ static void DNDBeginCB( GtkWidget *widget, GdkDragContext *dc, gpointer data ) { (void)data; if((widget == NULL) || (dc == NULL)) return; /* Put any needed drag begin setup code here. */ if(!GLOBALS->dnd_state) { if(widget == GLOBALS->clist_search_c_3) { GLOBALS->tree_dnd_begin = SEARCH_TO_VIEW_DRAG_ACTIVE; } else { GLOBALS->tree_dnd_begin = TREE_TO_VIEW_DRAG_ACTIVE; } } } /* * DND "drag_end" handler, this is called when a drag and drop has * completed. So this function is the last one to be called in * any given DND operation. */ static void DNDEndCB_2( GtkWidget *widget, GdkDragContext *dc, gpointer data ) { (void)widget; (void)dc; (void)data; Trptr t; int trwhich, trtarget; GdkModifierType state; gdouble x, y; #ifdef WAVE_USE_GTK2 gint xi, yi; #endif /* Put any needed drag end cleanup code here. */ if(GLOBALS->dnd_tgt_on_signalarea_treesearch_gtk2_c_1) { WAVE_GDK_GET_POINTER(GLOBALS->signalarea->window, &x, &y, &xi, &yi, &state); WAVE_GDK_GET_POINTER_COPY; if((x<0)||(y<0)||(x>=GLOBALS->signalarea->allocation.width)||(y>=GLOBALS->signalarea->allocation.height)) return; } else if(GLOBALS->dnd_tgt_on_wavearea_treesearch_gtk2_c_1) { WAVE_GDK_GET_POINTER(GLOBALS->wavearea->window, &x, &y, &xi, &yi, &state); WAVE_GDK_GET_POINTER_COPY; if((x<0)||(y<0)||(x>=GLOBALS->wavearea->allocation.width)||(y>=GLOBALS->wavearea->allocation.height)) return; } else { return; } if((t=GLOBALS->traces.first)) { while(t) { t->flags&=~TR_HIGHLIGHT; t=t->t_next; } signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } trtarget = ((int)y / (int)GLOBALS->fontheight) - 2; if(trtarget < 0) { Trptr tp = GLOBALS->topmost_trace ? GivePrevTrace(GLOBALS->topmost_trace): NULL; trtarget = 0; if(tp) { t = tp; } else { if(GLOBALS->tree_dnd_begin == SEARCH_TO_VIEW_DRAG_ACTIVE) { if(GLOBALS->window_search_c_7) { search_insert_callback(GLOBALS->window_search_c_7, 1 /* is prepend */); } } else { action_callback(ACTION_PREPEND); /* prepend in this widget only ever used by this function call */ } goto dnd_import_fini; } } else { t=GLOBALS->topmost_trace; } trwhich=0; while(t) { if((trwhichflags |= TR_HIGHLIGHT; } if(GLOBALS->tree_dnd_begin == SEARCH_TO_VIEW_DRAG_ACTIVE) { if(GLOBALS->window_search_c_7) { search_insert_callback(GLOBALS->window_search_c_7, 0 /* is insert */); } } else { action_callback (ACTION_INSERT); } if(t) { t->flags &= ~TR_HIGHLIGHT; } dnd_import_fini: MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } static void DNDEndCB( GtkWidget *widget, GdkDragContext *dc, gpointer data ) { if((widget == NULL) || (dc == NULL)) { GLOBALS->tree_dnd_begin = VIEW_DRAG_INACTIVE; return; } if(GLOBALS->tree_dnd_begin == VIEW_DRAG_INACTIVE) { return; /* to keep cut and paste in signalwindow from conflicting */ } if(GLOBALS->tree_dnd_requested) { GLOBALS->tree_dnd_requested = 0; if(GLOBALS->is_lx2 == LXT2_IS_VLIST) { set_window_busy(NULL); } DNDEndCB_2(widget, dc, data); if(GLOBALS->is_lx2 == LXT2_IS_VLIST) { set_window_idle(NULL); } } GLOBALS->tree_dnd_begin = VIEW_DRAG_INACTIVE; } /* * DND "drag_motion" handler, this is called whenever the * pointer is dragging over the target widget. */ static gboolean DNDDragMotionCB( GtkWidget *widget, GdkDragContext *dc, gint x, gint y, guint t, gpointer data ) { (void)x; (void)y; (void)data; gboolean same_widget; GdkDragAction suggested_action; GtkWidget *src_widget, *tar_widget; if((widget == NULL) || (dc == NULL)) { gdk_drag_status(dc, 0, t); return(FALSE); } /* Get source widget and target widget. */ src_widget = gtk_drag_get_source_widget(dc); tar_widget = widget; /* Note if source widget is the same as the target. */ same_widget = (src_widget == tar_widget) ? TRUE : FALSE; GLOBALS->dnd_tgt_on_signalarea_treesearch_gtk2_c_1 = (tar_widget == GLOBALS->signalarea); GLOBALS->dnd_tgt_on_wavearea_treesearch_gtk2_c_1 = (tar_widget == GLOBALS->wavearea); /* If this is the same widget, our suggested action should be * move. For all other case we assume copy. */ if(same_widget) suggested_action = GDK_ACTION_MOVE; else suggested_action = GDK_ACTION_COPY; /* Respond with default drag action (status). First we check * the dc's list of actions. If the list only contains * move, copy, or link then we select just that, otherwise we * return with our default suggested action. * If no valid actions are listed then we respond with 0. */ /* Only move? */ if(dc->actions == GDK_ACTION_MOVE) gdk_drag_status(dc, GDK_ACTION_MOVE, t); /* Only copy? */ else if(dc->actions == GDK_ACTION_COPY) gdk_drag_status(dc, GDK_ACTION_COPY, t); /* Only link? */ else if(dc->actions == GDK_ACTION_LINK) gdk_drag_status(dc, GDK_ACTION_LINK, t); /* Other action, check if listed in our actions list? */ else if(dc->actions & suggested_action) gdk_drag_status(dc, suggested_action, t); /* All else respond with 0. */ else gdk_drag_status(dc, 0, t); return(FALSE); } /* * DND "drag_data_get" handler, for handling requests for DND * data on the specified widget. This function is called when * there is need for DND data on the source, so this function is * responsable for setting up the dynamic data exchange buffer * (DDE as sometimes it is called) and sending it out. */ static void DNDDataRequestCB( GtkWidget *widget, GdkDragContext *dc, GtkSelectionData *selection_data, guint info, guint t, gpointer data ) { (void)dc; (void)info; (void)t; (void)data; int upd = 0; GLOBALS->tree_dnd_requested = 1; /* indicate that a request for data occurred... */ if(widget == GLOBALS->clist_search_c_3) /* from search */ { char *text = add_dnd_from_searchbox(); if(text) { gtk_selection_data_set(selection_data,GDK_SELECTION_TYPE_STRING, 8, (guchar*)text, strlen(text)); free_2(text); } upd = 1; } else if(widget == GLOBALS->signalarea) { char *text = add_dnd_from_signal_window(); if(text) { char *text2 = emit_gtkwave_savefile_formatted_entries_in_tcl_list(GLOBALS->traces.first, TRUE); if(text2) { int textlen = strlen(text); int text2len = strlen(text2); char *pnt = calloc_2(1, textlen + text2len + 1); memcpy(pnt, text, textlen); memcpy(pnt + textlen, text2, text2len); free_2(text2); free_2(text); text = pnt; } gtk_selection_data_set(selection_data,GDK_SELECTION_TYPE_STRING, 8, (guchar*)text, strlen(text)); free_2(text); } upd = 1; } else if(widget == GLOBALS->dnd_sigview) { char *text = add_dnd_from_tree_window(); if(text) { gtk_selection_data_set(selection_data,GDK_SELECTION_TYPE_STRING, 8, (guchar*)text, strlen(text)); free_2(text); } upd = 1; } if(upd) { MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } /* * DND "drag_data_received" handler. When DNDDataRequestCB() * calls gtk_selection_data_set() to send out the data, this function * receives it and is responsible for handling it. * * This is also the only DND callback function where the given * inputs may reflect those of the drop target so we need to check * if this is the same structure or not. */ static void DNDDataReceivedCB( GtkWidget *widget, GdkDragContext *dc, gint x, gint y, GtkSelectionData *selection_data, guint info, guint t, gpointer data) { (void)x; (void)y; (void)t; gboolean same; GtkWidget *source_widget; if((widget == NULL) || (data == NULL) || (dc == NULL)) return; /* Important, check if we actually got data. Sometimes errors * occure and selection_data will be NULL. */ if(selection_data == NULL) return; if(selection_data->length < 0) return; /* Source and target widgets are the same? */ source_widget = gtk_drag_get_source_widget(dc); same = (source_widget == widget) ? TRUE : FALSE; if(same) { /* unused */ } if(source_widget) if((source_widget == GLOBALS->clist_search_c_3) || /* from search */ (source_widget == GLOBALS->signalarea) || (source_widget == GLOBALS->dnd_sigview)) { /* use internal mechanism instead of passing names around... */ return; } GLOBALS->dnd_state = 0; GLOBALS->tree_dnd_requested = 0; /* Now check if the data format type is one that we support * (remember, data format type, not data type). * * We check this by testing if info matches one of the info * values that we have defined. * * Note that we can also iterate through the atoms in: * GList *glist = dc->targets; * * while(glist != NULL) * { * gchar *name = gdk_atom_name((GdkAtom)glist->data); * * strcmp the name to see if it matches * * one that we support * * * glist = glist->next; * } */ if((info == WAVE_DRAG_TAR_INFO_0) || (info == WAVE_DRAG_TAR_INFO_1) || (info == WAVE_DRAG_TAR_INFO_2)) { /* printf("XXX %08x '%s'\n", selection_data->data, selection_data->data); */ #ifndef MAC_INTEGRATION DND_helper_quartz((char *)selection_data->data); #else if(!GLOBALS->dnd_helper_quartz) { GLOBALS->dnd_helper_quartz = strdup_2((const char *)selection_data->data); } #endif } } void DND_helper_quartz(char *data) { int num_found; if(!GLOBALS->splash_is_loading) { #if GTK_CHECK_VERSION(2,4,0) if(!GLOBALS->pFileChoose) #endif { if(!(num_found = process_url_list(data))) { num_found = process_tcl_list(data, TRUE); } if(num_found) { MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } #if GTK_CHECK_VERSION(2,4,0) else { MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } #endif } } /* * DND "drag_data_delete" handler, this function is called when * the data on the source `should' be deleted (ie if the DND was * a move). */ static void DNDDataDeleteCB( GtkWidget *widget, GdkDragContext *dc, gpointer data ) { (void)widget; (void)dc; (void)data; /* nothing */ } /***********************/ void dnd_setup(GtkWidget *src, GtkWidget *w, int enable_receive) { GtkWidget *win = w; GtkTargetEntry target_entry[3]; /* Realize the clist widget and make sure it has a window, * this will be for DND setup. */ if(!GTK_WIDGET_NO_WINDOW(w)) { /* DND: Set up the clist as a potential DND destination. * First we set up target_entry which is a sequence of of * structure which specify the kinds (which we define) of * drops accepted on this widget. */ /* Set up the list of data format types that our DND * callbacks will accept. */ target_entry[0].target = WAVE_DRAG_TAR_NAME_0; target_entry[0].flags = 0; target_entry[0].info = WAVE_DRAG_TAR_INFO_0; target_entry[1].target = WAVE_DRAG_TAR_NAME_1; target_entry[1].flags = 0; target_entry[1].info = WAVE_DRAG_TAR_INFO_1; target_entry[2].target = WAVE_DRAG_TAR_NAME_2; target_entry[2].flags = 0; target_entry[2].info = WAVE_DRAG_TAR_INFO_2; /* Set the drag destination for this widget, using the * above target entry types, accept move's and coppies'. */ gtk_drag_dest_set( w, GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP, target_entry, sizeof(target_entry) / sizeof(GtkTargetEntry), GDK_ACTION_MOVE | GDK_ACTION_COPY ); gtkwave_signal_connect(GTK_OBJECT(w), "drag_motion", GTK_SIGNAL_FUNC(DNDDragMotionCB), win); /* Set the drag source for this widget, allowing the user * to drag items off of this clist. */ if(src) { gtk_drag_source_set( src, GDK_BUTTON1_MASK | GDK_BUTTON2_MASK, target_entry, sizeof(target_entry) / sizeof(GtkTargetEntry), GDK_ACTION_MOVE | GDK_ACTION_COPY ); /* Set DND signals on clist. */ gtkwave_signal_connect(GTK_OBJECT(src), "drag_begin", GTK_SIGNAL_FUNC(DNDBeginCB), win); gtkwave_signal_connect(GTK_OBJECT(src), "drag_end", GTK_SIGNAL_FUNC(DNDEndCB), win); gtkwave_signal_connect(GTK_OBJECT(src), "drag_data_get", GTK_SIGNAL_FUNC(DNDDataRequestCB), win); gtkwave_signal_connect(GTK_OBJECT(src), "drag_data_delete", GTK_SIGNAL_FUNC(DNDDataDeleteCB), win); } if(enable_receive) gtkwave_signal_connect(GTK_OBJECT(w), "drag_data_received", GTK_SIGNAL_FUNC(DNDDataReceivedCB), win); } } gtkwave-3.3.66/src/mouseover_sigs.h0000664000076400007640000000066411523063250016613 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2010 * * 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. */ #ifndef WAVE_MOUSEOVER_SIGS_H #define WAVE_MOUSEOVER_SIGS_H void move_mouseover_sigs(Trptr t, gint xin, gint yin, TimeType tim); #endif gtkwave-3.3.66/src/tree.h0000664000076400007640000001050212341266475014506 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2011. * * 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. */ #include "globals.h" /* * tree.h 12/05/98ajb */ #ifndef WAVE_TREE_H #define WAVE_TREE_H #include #include #include #include #include "debug.h" #include "symbol.h" #include "vcd.h" #include "tree_component.h" #define FST_TREE_SEARCH_NEXT_LIMIT (40) /* Kind of the tree. */ enum tree_kind { /* Unknown. */ TREE_UNKNOWN, /* An internal signal. */ TREE_SIGNAL, /* An in/out/inout signal. */ TREE_IN, TREE_OUT, TREE_INOUT, /* An element of a vector. */ TREE_VECTOREL, /* An element of a record. */ TREE_RECORDEL, /* A Subinstance. */ TREE_INSTANCE, /* A package (somewhat VHDL specific ?). */ TREE_PACKAGE, /* A base (source file). Not yet implemented. */ TREE_BASE, /* Verilog/SV scope types */ TREE_VCD_ST_MODULE, TREE_VCD_ST_TASK, TREE_VCD_ST_FUNCTION, TREE_VCD_ST_BEGIN, TREE_VCD_ST_FORK, TREE_VCD_ST_GENERATE, TREE_VCD_ST_STRUCT, TREE_VCD_ST_UNION, TREE_VCD_ST_CLASS, TREE_VCD_ST_INTERFACE, TREE_VCD_ST_PACKAGE, TREE_VCD_ST_PROGRAM, /* GHW VHDL scope types */ TREE_VHDL_ST_DESIGN, TREE_VHDL_ST_BLOCK, TREE_VHDL_ST_GENIF, TREE_VHDL_ST_GENFOR, TREE_VHDL_ST_INSTANCE, TREE_VHDL_ST_PACKAGE, /* GHW VHDL signal types (still as part of scope in GHW) */ TREE_VHDL_ST_SIGNAL, TREE_VHDL_ST_PORTIN, TREE_VHDL_ST_PORTOUT, TREE_VHDL_ST_PORTINOUT, TREE_VHDL_ST_BUFFER, TREE_VHDL_ST_LINKAGE, /* FSDB VHDL scope types: FSDB also reuses/defines GHW's TREE_VHDL_ST_BLOCK, TREE_VHDL_ST_GENFOR, TREE_VHDL_ST_GENIF */ /* FST reuses TREE_VHDL_ST_PACKAGE */ TREE_VHDL_ST_ARCHITECTURE, TREE_VHDL_ST_FUNCTION, TREE_VHDL_ST_PROCEDURE, TREE_VHDL_ST_RECORD, TREE_VHDL_ST_PROCESS, TREE_VHDL_ST_GENERATE }; #define WAVE_T_WHICH_UNDEFINED_COMPNAME (-1) #define WAVE_T_WHICH_COMPNAME_START (-2) #ifdef WAVE_USE_STRUCT_PACKING #pragma pack(push) #pragma pack(1) #endif struct stem_struct_t { uint32_t stem_idx; /* in stem_path_string_table */ uint32_t stem_line_number; }; struct tree { struct tree *next; struct tree *child; int t_which; /* 'i' for facs[i] table, value of < 0 means not a full signame */ uint32_t t_stem; /* source stem (if >0) for Open Hierarchy Source Def, see stem_struct_t */ uint32_t t_istem; /* source stem (if >0) for Open Hierarchy Source Inst, see stem_struct_t */ unsigned kind : 7; /* Kind of the leaf: ghwlib reads this as val & 0x7f so only 7 bits needed */ unsigned children_in_gui : 1; /* indicates that the child nodes are in the gtk2 tree, but gets borrowed during tree creation for fast judy sort */ char name[]; /* C99 */ }; #ifdef WAVE_USE_STRUCT_PACKING #pragma pack(pop) #endif /* names at the end of the main hierarchy 010104ajb */ struct treechain { struct tree *tree; /* top of list of selected item in hierarchy */ struct tree *label; /* actual selected item in hierarchy */ struct treechain *next; }; struct autocoalesce_free_list { struct autocoalesce_free_list *next; /* list of coalesced names generated by treesearch gadget..only user of this struct */ char *name; /* free up next time filtering is performed */ }; void init_tree(void); void build_tree_from_name(const char *s, int which); int treegraft(struct tree **t); void treedebug(struct tree *t, char *s); void maketree(GtkCTreeNode *subtree, struct tree *t); #if WAVE_USE_GTK2 void maketree2(GtkCTreeNode *subtree, struct tree *t, int depth, GtkCTreeNode *graft); #endif char *leastsig_hiername(char *nam); void allocate_and_decorate_module_tree_node(unsigned char ttype, const char *scopename, const char *compname, uint32_t scopename_len, uint32_t compname_len, uint32_t t_stem, uint32_t t_istem); int decorated_module_cleanup(void); void treesort(struct tree *t, struct tree *p); void order_facs_from_treesort(struct tree *t, void *v); void treenamefix(struct tree *t); #ifdef WAVE_USE_STRUCT_PACKING #define WAVE_TALLOC_POOL_SIZE (64 * 1024) #define WAVE_TALLOC_ALTREQ_SIZE (4 * 1024) struct tree *talloc_2(size_t siz); #else #define talloc_2(x) calloc_2(1,(x)) #endif #endif gtkwave-3.3.66/src/vcd_recoder.c0000664000076400007640000025663012527430212016023 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2014. * * 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. */ /* * vcd.c 23jan99ajb * evcd parts 29jun99ajb * profiler optimizations 15jul99ajb * more profiler optimizations 25jan00ajb * finsim parameter fix 26jan00ajb * vector rechaining code 03apr00ajb * multiple var section code 06apr00ajb * fix for duplicate nets 19dec00ajb * support for alt hier seps 23dec00ajb * fix for rcs identifiers 16jan01ajb * coredump fix for bad VCD 04apr02ajb * min/maxid speedup 27feb03ajb * bugfix on min/maxid speedup 06jul03ajb * escaped hier modification 20feb06ajb * added real_parameter vartype 04aug06ajb * recoder using vlists 17aug06ajb * code cleanup 04sep06ajb * added in/out port vartype 31jan07ajb * use gperf for port vartypes 19feb07ajb * MTI SV implicit-var fix 05apr07ajb * MTI SV len=0 is real var 05apr07ajb * VCD fastloading 05mar09ajb */ #include #include "globals.h" #include "vcd.h" #include "vlist.h" #include "lx2.h" #include "hierpack.h" /**/ static void malform_eof_fix(void) { if(feof(GLOBALS->vcd_handle_vcd_recoder_c_2)) { memset(GLOBALS->vcdbuf_vcd_recoder_c_3, ' ', VCD_BSIZ); GLOBALS->vst_vcd_recoder_c_3=GLOBALS->vend_vcd_recoder_c_3; } } /**/ static void vlist_packer_emit_uv64(struct vlist_packer_t **vl, guint64 v) { guint64 nxt; while((nxt = v>>7)) { vlist_packer_alloc(*vl, v&0x7f); v = nxt; } vlist_packer_alloc(*vl, (v&0x7f) | 0x80); } static void vlist_packer_emit_utt(struct vlist_packer_t **vl, UTimeType v) { UTimeType nxt; while((nxt = v>>7)) { vlist_packer_alloc(*vl, v&0x7f); v = nxt; } vlist_packer_alloc(*vl, (v&0x7f) | 0x80); } static void vlist_packer_emit_uv32(struct vlist_packer_t **vl, unsigned int v) { unsigned int nxt; while((nxt = v>>7)) { vlist_packer_alloc(*vl, v&0x7f); v = nxt; } vlist_packer_alloc(*vl, (v&0x7f) | 0x80); } static void vlist_packer_emit_string(struct vlist_packer_t **vl, char *s) { while(*s) { vlist_packer_alloc(*vl, *s); s++; } vlist_packer_alloc(*vl, 0); } static void vlist_packer_emit_mvl9_string(struct vlist_packer_t **vl, char *s) { unsigned int recoded_bit; unsigned char which = 0; unsigned char accum = 0; while(*s) { switch(*s) { case '0': recoded_bit = AN_0; break; case '1': recoded_bit = AN_1; break; case 'x': case 'X': recoded_bit = AN_X; break; case 'z': case 'Z': recoded_bit = AN_Z; break; case 'h': case 'H': recoded_bit = AN_H; break; case 'u': case 'U': recoded_bit = AN_U; break; case 'w': case 'W': recoded_bit = AN_W; break; case 'l': case 'L': recoded_bit = AN_L; break; default: recoded_bit = AN_DASH; break; } if(!which) { accum = (recoded_bit << 4); which = 1; } else { accum |= recoded_bit; vlist_packer_alloc(*vl, accum); which = accum = 0; } s++; } recoded_bit = AN_MSK; /* XXX : this is assumed it is going to remain a 4 bit max quantity! */ if(!which) { accum = (recoded_bit << 4); } else { accum |= recoded_bit; } vlist_packer_alloc(*vl, accum); } /**/ static void vlist_emit_uv32(struct vlist_t **vl, unsigned int v) { unsigned int nxt; char *pnt; if(GLOBALS->vlist_prepack) { vlist_packer_emit_uv32((struct vlist_packer_t **)vl, v); return; } while((nxt = v>>7)) { pnt = vlist_alloc(vl, 1); *pnt = (v&0x7f); v = nxt; } pnt = vlist_alloc(vl, 1); *pnt = (v&0x7f) | 0x80; } static void vlist_emit_string(struct vlist_t **vl, char *s) { char *pnt; if(GLOBALS->vlist_prepack) { vlist_packer_emit_string((struct vlist_packer_t **)vl, s); return; } while(*s) { pnt = vlist_alloc(vl, 1); *pnt = *s; s++; } pnt = vlist_alloc(vl, 1); *pnt = 0; } static void vlist_emit_mvl9_string(struct vlist_t **vl, char *s) { char *pnt; unsigned int recoded_bit; unsigned char which; unsigned char accum; if(GLOBALS->vlist_prepack) { vlist_packer_emit_mvl9_string((struct vlist_packer_t **)vl, s); return; } which = accum = 0; while(*s) { switch(*s) { case '0': recoded_bit = AN_0; break; case '1': recoded_bit = AN_1; break; case 'x': case 'X': recoded_bit = AN_X; break; case 'z': case 'Z': recoded_bit = AN_Z; break; case 'h': case 'H': recoded_bit = AN_H; break; case 'u': case 'U': recoded_bit = AN_U; break; case 'w': case 'W': recoded_bit = AN_W; break; case 'l': case 'L': recoded_bit = AN_L; break; default: recoded_bit = AN_DASH; break; } if(!which) { accum = (recoded_bit << 4); which = 1; } else { accum |= recoded_bit; pnt = vlist_alloc(vl, 1); *pnt = accum; which = accum = 0; } s++; } recoded_bit = AN_MSK; /* XXX : this is assumed it is going to remain a 4 bit max quantity! */ if(!which) { accum = (recoded_bit << 4); } else { accum |= recoded_bit; } pnt = vlist_alloc(vl, 1); *pnt = accum; } /**/ static void write_fastload_time_section(void) { struct vlist_t *vlist; struct vlist_packer_t *vlist_p; /* emit blackout regions */ if(GLOBALS->blackout_regions) { struct blackout_region_t *bt = GLOBALS->blackout_regions; unsigned int bcnt = 0; while(bt) { bcnt++; bt = bt->next; } vlist_packer_emit_uv32((struct vlist_packer_t **)(void *)&GLOBALS->time_vlist_vcd_recoder_write, bcnt); bt = GLOBALS->blackout_regions; while(bt) { vlist_packer_emit_utt((struct vlist_packer_t **)(void *)&GLOBALS->time_vlist_vcd_recoder_write, bt->bstart); vlist_packer_emit_utt((struct vlist_packer_t **)(void *)&GLOBALS->time_vlist_vcd_recoder_write, bt->bend); bt = bt->next; } } else { vlist_packer_emit_uv32((struct vlist_packer_t **)(void *)&GLOBALS->time_vlist_vcd_recoder_write, 0); } vlist_p = (struct vlist_packer_t *)GLOBALS->time_vlist_vcd_recoder_write; vlist_packer_finalize(vlist_p); vlist = vlist_p->v; free_2(vlist_p); GLOBALS->time_vlist_vcd_recoder_write = vlist; vlist_freeze(&GLOBALS->time_vlist_vcd_recoder_write); } #ifdef HAVE_SYS_STAT_H static void write_fastload_header(struct stat *mystat, unsigned int finalize_cnt) #else static void write_fastload_header(unsigned int finalize_cnt) #endif { /* write out the trailer information for vcd fastload... vcd file size vcd last modification time number of finalize values number of variable-length integer values in the time table (GLOBALS->time_vlist_count_vcd_recoder_c_1) GLOBALS->time_vlist_vcd_recoder_write value deltas from GLOBALS->time_vlist_vcd_recoder_write and on though stepping through list generated by vlist_emit_finalize() */ struct vlist_packer_t *vlist_p; struct vlist_t * vlist_summary_index = ((struct vlist_t *)vlist_packer_create()); struct vcdsymbol *v = GLOBALS->vcdsymroot_vcd_recoder_c_3; guint64 val = (guint64)(unsigned long)GLOBALS->time_vlist_vcd_recoder_write; guint64 nval; char buf[33]; char *pnt; memset(buf, 0, sizeof(buf)); /* scan-build */ #ifdef HAVE_SYS_STAT_H vlist_packer_emit_uv64((struct vlist_packer_t **)(void *)&vlist_summary_index, (guint64)mystat->st_size); vlist_packer_emit_uv64((struct vlist_packer_t **)(void *)&vlist_summary_index, (guint64)mystat->st_mtime); #else vlist_packer_emit_uv64((struct vlist_packer_t **)(void *)&vlist_summary_index, (guint64)0); vlist_packer_emit_uv64((struct vlist_packer_t **)(void *)&vlist_summary_index, (guint64)0); #endif vlist_packer_emit_uv32((struct vlist_packer_t **)(void *)&vlist_summary_index, finalize_cnt); vlist_packer_emit_uv64((struct vlist_packer_t **)(void *)&vlist_summary_index, GLOBALS->time_vlist_count_vcd_recoder_c_1); vlist_packer_emit_uv64((struct vlist_packer_t **)(void *)&vlist_summary_index, val); val = 0; while(v) { nptr n = v->narray[0]; nval = (guint64)(unsigned long)n->mv.mvlfac_vlist; vlist_packer_emit_uv64((struct vlist_packer_t **)(void *)&vlist_summary_index, nval - val); val = nval; v = v->next; } vlist_p = (struct vlist_packer_t *)vlist_summary_index; vlist_packer_finalize(vlist_p); vlist_summary_index = vlist_p->v; free_2(vlist_p); GLOBALS->time_vlist_vcd_recoder_write = vlist_summary_index; vlist_freeze(&vlist_summary_index); pnt = buf; val = (guint64)(unsigned long)vlist_summary_index; while((nval = val>>7)) { *(pnt++) = (val&0x7f); val = nval; } *(pnt++) = ((val&0x7f) | 0x80); do { pnt--; fputc((unsigned char)*pnt, GLOBALS->vlist_handle); } while(pnt != buf); fflush(GLOBALS->vlist_handle); } static int read_fastload_body(void) { char *depacked = GLOBALS->fastload_depacked; char *pnt = GLOBALS->fastload_current; int rc = 0; guint64 v = 0, vprev = 0; int shamt = 0; /* unsigned int num_finalize; */ /* scan-build */ unsigned int num_in_time_table, num_blackout_regions; guint64 time_vlist_vcd_recoder_write; struct vcdsymbol *vs; struct vlist_t *vl; unsigned int list_size; unsigned int i; struct blackout_region_t *bt_head = NULL, *bt_curr = NULL; v = 0; shamt = 0; do { v |= ((guint64)(*pnt & 0x7f)) << shamt; shamt += 7; } while(!(*(pnt++) & 0x80)); /* num_finalize = v; */ /* scan-build */ v = 0; shamt = 0; do { v |= ((guint64)(*pnt & 0x7f)) << shamt; shamt += 7; } while(!(*(pnt++) & 0x80)); GLOBALS->time_vlist_count_vcd_recoder_c_1 = num_in_time_table = v; v = 0; shamt = 0; do { v |= ((guint64)(*pnt & 0x7f)) << shamt; shamt += 7; } while(!(*(pnt++) & 0x80)); time_vlist_vcd_recoder_write = v; vs=GLOBALS->vcdsymroot_vcd_recoder_c_3; while(vs) { nptr n = vs->narray[0]; v = 0; shamt = 0; do { v |= ((guint64)(*pnt & 0x7f)) << shamt; shamt += 7; } while(!(*(pnt++) & 0x80)); v += vprev; vprev = v; n->mv.mvlfac_vlist = (struct vlist_t *)(intptr_t)(v); vs = vs->next; } vlist_packer_decompress_destroy((char *)depacked); GLOBALS->fastload_depacked = NULL; GLOBALS->fastload_current = NULL; /* now create the time table */ vl = (struct vlist_t *)(intptr_t)time_vlist_vcd_recoder_write; vlist_uncompress(&vl); depacked = pnt = (char *)vlist_packer_decompress(vl, &list_size); vlist_destroy(vl); vprev = 0; for(i=0;itime_vlist_vcd_recoder_c_1, 0); *tt = tim = (TimeType)v; if(!i) { GLOBALS->start_time_vcd_recoder_c_3=tim; } GLOBALS->current_time_vcd_recoder_c_3=GLOBALS->end_time_vcd_recoder_c_3=tim; } /* now process blackout regions */ v = 0; shamt = 0; do { v |= ((guint64)(*pnt & 0x7f)) << shamt; shamt += 7; } while(!(*(pnt++) & 0x80)); num_blackout_regions = v; if(num_blackout_regions) { for(i=0;inext = bt; bt_curr = bt; } v = 0; shamt = 0; do { v |= ((guint64)(*pnt & 0x7f)) << shamt; shamt += 7; } while(!(*(pnt++) & 0x80)); tim = v; bt->bstart = tim; v = 0; shamt = 0; do { v |= ((guint64)(*pnt & 0x7f)) << shamt; shamt += 7; } while(!(*(pnt++) & 0x80)); tim = v; bt->bend = tim; } GLOBALS->blackout_regions = bt_head; } vlist_packer_decompress_destroy((char *)depacked); return(rc); } #ifdef HAVE_SYS_STAT_H static int read_fastload_header(struct stat *st) #else static int read_fastload_header(void) #endif { int rc = 0; int fs_rc = fseeko(GLOBALS->vlist_handle, 0, SEEK_END); off_t ftlen = ftello(GLOBALS->vlist_handle); guint64 v = 0; int ch; int shamt = 0; unsigned char *depacked = NULL; struct vlist_t *vl; unsigned int list_size; unsigned char *pnt; #ifdef HAVE_SYS_STAT_H struct stat mystat; int stat_rc = stat(GLOBALS->loaded_file_name, &mystat); #endif if((fs_rc<0)||(!ftlen)) { goto bail; } do { ftlen--; fseeko(GLOBALS->vlist_handle, ftlen, SEEK_SET); ch = fgetc(GLOBALS->vlist_handle); if(ch == EOF) { errno = 0; goto bail; } v |= ((guint64)(ch & 0x7f)) << shamt; shamt += 7; } while(!(ch & 0x80)); vl = (struct vlist_t *)(intptr_t)v; vlist_uncompress(&vl); depacked = vlist_packer_decompress(vl, &list_size); vlist_destroy(vl); pnt = depacked; v = 0; shamt = 0; do { v |= ((guint64)(*pnt & 0x7f)) << shamt; shamt += 7; } while(!(*(pnt++) & 0x80)); #ifdef HAVE_SYS_STAT_H if((stat_rc)||(v != (guint64)mystat.st_size)) { goto bail; } #endif v = 0; shamt = 0; do { v |= ((guint64)(*pnt & 0x7f)) << shamt; shamt += 7; } while(!(*(pnt++) & 0x80)); #ifdef HAVE_SYS_STAT_H if(v != (guint64)st->st_mtime) { goto bail; } #endif rc = 1; GLOBALS->fastload_depacked = (char *)depacked; GLOBALS->fastload_current = (char *)pnt; bail: if(!rc) vlist_packer_decompress_destroy((char *)depacked); return(rc); } /**/ #undef VCD_BSEARCH_IS_PERFECT /* bsearch is imperfect under linux, but OK under AIX */ static void add_histent(TimeType time, struct Node *n, char ch, int regadd, char *vector); static void vcd_build_symbols(void); static void vcd_cleanup(void); static void evcd_strcpy(char *dst, char *src); /******************************************************************/ enum Tokens { T_VAR, T_END, T_SCOPE, T_UPSCOPE, T_COMMENT, T_DATE, T_DUMPALL, T_DUMPOFF, T_DUMPON, T_DUMPVARS, T_ENDDEFINITIONS, T_DUMPPORTS, T_DUMPPORTSOFF, T_DUMPPORTSON, T_DUMPPORTSALL, T_TIMESCALE, T_VERSION, T_VCDCLOSE, T_TIMEZERO, T_EOF, T_STRING, T_UNKNOWN_KEY }; static char *tokens[]={ "var", "end", "scope", "upscope", "comment", "date", "dumpall", "dumpoff", "dumpon", "dumpvars", "enddefinitions", "dumpports", "dumpportsoff", "dumpportson", "dumpportsall", "timescale", "version", "vcdclose", "timezero", "", "", "" }; #define NUM_TOKENS 19 #define T_GET tok=get_token();if((tok==T_END)||(tok==T_EOF))break; /******************************************************************/ static unsigned int vcdid_hash(char *s, int len) { unsigned int val=0; int i; s+=(len-1); for(i=0;iid)); } /* * actual bsearch */ static struct vcdsymbol *bsearch_vcd(char *key, int len) { struct vcdsymbol **v; struct vcdsymbol *t; if(GLOBALS->indexed_vcd_recoder_c_3) { unsigned int hsh = vcdid_hash(key, len); if((hsh>=GLOBALS->vcd_minid_vcd_recoder_c_3)&&(hsh<=GLOBALS->vcd_maxid_vcd_recoder_c_3)) { return(GLOBALS->indexed_vcd_recoder_c_3[hsh-GLOBALS->vcd_minid_vcd_recoder_c_3]); } return(NULL); } if(GLOBALS->sorted_vcd_recoder_c_3) { v=(struct vcdsymbol **)bsearch(key, GLOBALS->sorted_vcd_recoder_c_3, GLOBALS->numsyms_vcd_recoder_c_3, sizeof(struct vcdsymbol *), vcdsymbsearchcompare); if(v) { #ifndef VCD_BSEARCH_IS_PERFECT for(;;) { t=*v; if((v==GLOBALS->sorted_vcd_recoder_c_3)||(strcmp((*(--v))->id, key))) { return(t); } } #else return(*v); #endif } else { return(NULL); } } else { if(!GLOBALS->err_vcd_recoder_c_3) { fprintf(stderr, "Near byte %d, VCD search table NULL..is this a VCD file?\n", (int)(GLOBALS->vcdbyteno_vcd_recoder_c_3+(GLOBALS->vst_vcd_recoder_c_3-GLOBALS->vcdbuf_vcd_recoder_c_3))); GLOBALS->err_vcd_recoder_c_3=1; } return(NULL); } } /* * sort on vcdsymbol pointers */ static int vcdsymcompare(const void *s1, const void *s2) { struct vcdsymbol *v1, *v2; v1=*((struct vcdsymbol **)s1); v2=*((struct vcdsymbol **)s2); return(strcmp(v1->id, v2->id)); } /* * create sorted (by id) table */ static void create_sorted_table(void) { struct vcdsymbol *v; struct vcdsymbol **pnt; unsigned int vcd_distance; if(GLOBALS->sorted_vcd_recoder_c_3) { free_2(GLOBALS->sorted_vcd_recoder_c_3); /* this means we saw a 2nd enddefinition chunk! */ GLOBALS->sorted_vcd_recoder_c_3=NULL; } if(GLOBALS->indexed_vcd_recoder_c_3) { free_2(GLOBALS->indexed_vcd_recoder_c_3); GLOBALS->indexed_vcd_recoder_c_3=NULL; } if(GLOBALS->numsyms_vcd_recoder_c_3) { vcd_distance = GLOBALS->vcd_maxid_vcd_recoder_c_3 - GLOBALS->vcd_minid_vcd_recoder_c_3 + 1; if((vcd_distance <= VCD_INDEXSIZ)||(!GLOBALS->vcd_hash_kill)) { GLOBALS->indexed_vcd_recoder_c_3 = (struct vcdsymbol **)calloc_2(vcd_distance, sizeof(struct vcdsymbol *)); /* printf("%d symbols span ID range of %d, using indexing... hash_kill = %d\n", GLOBALS->numsyms_vcd_recoder_c_3, vcd_distance, GLOBALS->vcd_hash_kill); */ v=GLOBALS->vcdsymroot_vcd_recoder_c_3; while(v) { if(!GLOBALS->indexed_vcd_recoder_c_3[v->nid - GLOBALS->vcd_minid_vcd_recoder_c_3]) GLOBALS->indexed_vcd_recoder_c_3[v->nid - GLOBALS->vcd_minid_vcd_recoder_c_3] = v; v=v->next; } } else { pnt=GLOBALS->sorted_vcd_recoder_c_3=(struct vcdsymbol **)calloc_2(GLOBALS->numsyms_vcd_recoder_c_3, sizeof(struct vcdsymbol *)); v=GLOBALS->vcdsymroot_vcd_recoder_c_3; while(v) { *(pnt++)=v; v=v->next; } qsort(GLOBALS->sorted_vcd_recoder_c_3, GLOBALS->numsyms_vcd_recoder_c_3, sizeof(struct vcdsymbol *), vcdsymcompare); } } } /******************************************************************/ static unsigned int vlist_emit_finalize(void) { struct vcdsymbol *v /* , *vprime */; /* scan-build */ struct vlist_t *vlist; char vlist_prepack = GLOBALS->vlist_prepack; int cnt = 0; v=GLOBALS->vcdsymroot_vcd_recoder_c_3; while(v) { nptr n = v->narray[0]; set_vcd_vartype(v, n); if(n->mv.mvlfac_vlist) { if(vlist_prepack) { vlist_packer_finalize(n->mv.mvlfac_packer_vlist); vlist = n->mv.mvlfac_packer_vlist->v; free_2(n->mv.mvlfac_packer_vlist); n->mv.mvlfac_vlist = vlist; vlist_freeze(&n->mv.mvlfac_vlist); } else { vlist_freeze(&n->mv.mvlfac_vlist); } } else { n->mv.mvlfac_vlist = vlist_prepack ? ((struct vlist_t *)vlist_packer_create()) : vlist_create(sizeof(char)); if((/* vprime= */ bsearch_vcd(v->id, strlen(v->id)))==v) /* hash mish means dup net */ /* scan-build */ { switch(v->vartype) { case V_REAL: vlist_emit_uv32(&n->mv.mvlfac_vlist, 'R'); vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)v->vartype); vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)v->size); vlist_emit_uv32(&n->mv.mvlfac_vlist, 0); vlist_emit_string(&n->mv.mvlfac_vlist, "NaN"); break; case V_STRINGTYPE: vlist_emit_uv32(&n->mv.mvlfac_vlist, 'S'); vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)v->vartype); vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)v->size); vlist_emit_uv32(&n->mv.mvlfac_vlist, 0); vlist_emit_string(&n->mv.mvlfac_vlist, "UNDEF"); break; default: if(v->size==1) { vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)'0'); vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)v->vartype); vlist_emit_uv32(&n->mv.mvlfac_vlist, RCV_X); } else { vlist_emit_uv32(&n->mv.mvlfac_vlist, 'B'); vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)v->vartype); vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)v->size); vlist_emit_uv32(&n->mv.mvlfac_vlist, 0); vlist_emit_mvl9_string(&n->mv.mvlfac_vlist, "x"); } break; } } if(vlist_prepack) { vlist_packer_finalize(n->mv.mvlfac_packer_vlist); vlist = n->mv.mvlfac_packer_vlist->v; free_2(n->mv.mvlfac_packer_vlist); n->mv.mvlfac_vlist = vlist; vlist_freeze(&n->mv.mvlfac_vlist); } else { vlist_freeze(&n->mv.mvlfac_vlist); } } v=v->next; cnt++; } return(cnt); } /******************************************************************/ /* * single char get inlined/optimized */ static void getch_alloc(void) { GLOBALS->vend_vcd_recoder_c_3=GLOBALS->vst_vcd_recoder_c_3=GLOBALS->vcdbuf_vcd_recoder_c_3=(char *)calloc_2(1,VCD_BSIZ); } static void getch_free(void) { free_2(GLOBALS->vcdbuf_vcd_recoder_c_3); GLOBALS->vcdbuf_vcd_recoder_c_3=GLOBALS->vst_vcd_recoder_c_3=GLOBALS->vend_vcd_recoder_c_3=NULL; } static int getch_fetch(void) { size_t rd; errno = 0; if(feof(GLOBALS->vcd_handle_vcd_recoder_c_2)) return(-1); GLOBALS->vcdbyteno_vcd_recoder_c_3+=(GLOBALS->vend_vcd_recoder_c_3-GLOBALS->vcdbuf_vcd_recoder_c_3); rd=fread(GLOBALS->vcdbuf_vcd_recoder_c_3, sizeof(char), VCD_BSIZ, GLOBALS->vcd_handle_vcd_recoder_c_2); GLOBALS->vend_vcd_recoder_c_3=(GLOBALS->vst_vcd_recoder_c_3=GLOBALS->vcdbuf_vcd_recoder_c_3)+rd; if((!rd)||(errno)) return(-1); if(GLOBALS->vcd_fsiz_vcd_recoder_c_2) { splash_sync(GLOBALS->vcdbyteno_vcd_recoder_c_3, GLOBALS->vcd_fsiz_vcd_recoder_c_2); /* gnome 2.18 seems to set errno so splash moved here... */ } return((int)(*GLOBALS->vst_vcd_recoder_c_3)); } static inline signed char getch(void) { signed char ch = (GLOBALS->vst_vcd_recoder_c_3!=GLOBALS->vend_vcd_recoder_c_3)?((int)(*GLOBALS->vst_vcd_recoder_c_3)):(getch_fetch()); GLOBALS->vst_vcd_recoder_c_3++; return(ch); } static inline signed char getch_peek(void) { signed char ch = (GLOBALS->vst_vcd_recoder_c_3!=GLOBALS->vend_vcd_recoder_c_3)?((int)(*GLOBALS->vst_vcd_recoder_c_3)):(getch_fetch()); /* no increment */ return(ch); } static int getch_patched(void) { char ch; ch=*GLOBALS->vsplitcurr_vcd_recoder_c_3; if(!ch) { return(-1); } else { GLOBALS->vsplitcurr_vcd_recoder_c_3++; return((int)ch); } } /* * simple tokenizer */ static int get_token(void) { int ch; int i, len=0; int is_string=0; char *yyshadow; for(;;) { ch=getch(); if(ch<0) return(T_EOF); if(ch<=' ') continue; /* val<=' ' is a quick whitespace check */ break; /* (take advantage of fact that vcd is text) */ } if(ch=='$') { GLOBALS->yytext_vcd_recoder_c_3[len++]=ch; for(;;) { ch=getch(); if(ch<0) return(T_EOF); if(ch<=' ') continue; break; } } else { is_string=1; } for(GLOBALS->yytext_vcd_recoder_c_3[len++]=ch;;GLOBALS->yytext_vcd_recoder_c_3[len++]=ch) { if(len==GLOBALS->T_MAX_STR_vcd_recoder_c_3) { GLOBALS->yytext_vcd_recoder_c_3=(char *)realloc_2(GLOBALS->yytext_vcd_recoder_c_3, (GLOBALS->T_MAX_STR_vcd_recoder_c_3=GLOBALS->T_MAX_STR_vcd_recoder_c_3*2)+1); } ch=getch(); if(ch<=' ') break; } GLOBALS->yytext_vcd_recoder_c_3[len]=0; /* terminator */ if(is_string) { GLOBALS->yylen_vcd_recoder_c_3=len; return(T_STRING); } yyshadow=GLOBALS->yytext_vcd_recoder_c_3; do { yyshadow++; for(i=0;ivar_prevch_vcd_recoder_c_3) { for(;;) { ch=getch_patched(); if(ch<0) { free_2(GLOBALS->varsplit_vcd_recoder_c_3); GLOBALS->varsplit_vcd_recoder_c_3=NULL; return(V_END); } if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')) continue; break; } } else { ch=GLOBALS->var_prevch_vcd_recoder_c_3; GLOBALS->var_prevch_vcd_recoder_c_3=0; } if(ch=='[') return(V_LB); if(ch==':') return(V_COLON); if(ch==']') return(V_RB); for(GLOBALS->yytext_vcd_recoder_c_3[len++]=ch;;GLOBALS->yytext_vcd_recoder_c_3[len++]=ch) { if(len==GLOBALS->T_MAX_STR_vcd_recoder_c_3) { GLOBALS->yytext_vcd_recoder_c_3=(char *)realloc_2(GLOBALS->yytext_vcd_recoder_c_3, (GLOBALS->T_MAX_STR_vcd_recoder_c_3=GLOBALS->T_MAX_STR_vcd_recoder_c_3*2)+1); } ch=getch_patched(); if(ch<0) { free_2(GLOBALS->varsplit_vcd_recoder_c_3); GLOBALS->varsplit_vcd_recoder_c_3=NULL; break; } if((ch==':')||(ch==']')) { GLOBALS->var_prevch_vcd_recoder_c_3=ch; break; } } GLOBALS->yytext_vcd_recoder_c_3[len]=0; /* terminator */ if(match_kw) { int vr = vcd_keyword_code(GLOBALS->yytext_vcd_recoder_c_3, len); if(vr != V_STRING) { if(ch<0) { free_2(GLOBALS->varsplit_vcd_recoder_c_3); GLOBALS->varsplit_vcd_recoder_c_3=NULL; } return(vr); } } GLOBALS->yylen_vcd_recoder_c_3=len; if(ch<0) { free_2(GLOBALS->varsplit_vcd_recoder_c_3); GLOBALS->varsplit_vcd_recoder_c_3=NULL; } return(V_STRING); } static int get_vartoken(int match_kw) { int ch; int len=0; if(GLOBALS->varsplit_vcd_recoder_c_3) { int rc=get_vartoken_patched(match_kw); if(rc!=V_END) return(rc); GLOBALS->var_prevch_vcd_recoder_c_3=0; } if(!GLOBALS->var_prevch_vcd_recoder_c_3) { for(;;) { ch=getch(); if(ch<0) return(V_END); if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')) continue; break; } } else { ch=GLOBALS->var_prevch_vcd_recoder_c_3; GLOBALS->var_prevch_vcd_recoder_c_3=0; } if(ch=='[') return(V_LB); if(ch==':') return(V_COLON); if(ch==']') return(V_RB); if(ch=='#') /* for MTI System Verilog '$var reg 64 >w #implicit-var###VarElem:ram_di[0.0] [63:0] $end' style declarations */ { /* debussy simply escapes until the space */ GLOBALS->yytext_vcd_recoder_c_3[len++]= '\\'; } for(GLOBALS->yytext_vcd_recoder_c_3[len++]=ch;;GLOBALS->yytext_vcd_recoder_c_3[len++]=ch) { if(len==GLOBALS->T_MAX_STR_vcd_recoder_c_3) { GLOBALS->yytext_vcd_recoder_c_3=(char *)realloc_2(GLOBALS->yytext_vcd_recoder_c_3, (GLOBALS->T_MAX_STR_vcd_recoder_c_3=GLOBALS->T_MAX_STR_vcd_recoder_c_3*2)+1); } ch=getch(); if(ch==' ') { if(match_kw) break; if(getch_peek() == '[') { ch = getch(); GLOBALS->varsplit_vcd_recoder_c_3=GLOBALS->yytext_vcd_recoder_c_3+len; /* keep looping so we get the *last* one */ continue; } } if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')||(ch<0)) break; if((ch=='[')&&(GLOBALS->yytext_vcd_recoder_c_3[0]!='\\')) { GLOBALS->varsplit_vcd_recoder_c_3=GLOBALS->yytext_vcd_recoder_c_3+len; /* keep looping so we get the *last* one */ } else if(((ch==':')||(ch==']'))&&(!GLOBALS->varsplit_vcd_recoder_c_3)&&(GLOBALS->yytext_vcd_recoder_c_3[0]!='\\')) { GLOBALS->var_prevch_vcd_recoder_c_3=ch; break; } } GLOBALS->yytext_vcd_recoder_c_3[len]=0; /* absolute terminator */ if((GLOBALS->varsplit_vcd_recoder_c_3)&&(GLOBALS->yytext_vcd_recoder_c_3[len-1]==']')) { char *vst; vst=malloc_2(strlen(GLOBALS->varsplit_vcd_recoder_c_3)+1); strcpy(vst, GLOBALS->varsplit_vcd_recoder_c_3); *GLOBALS->varsplit_vcd_recoder_c_3=0x00; /* zero out var name at the left bracket */ len=GLOBALS->varsplit_vcd_recoder_c_3-GLOBALS->yytext_vcd_recoder_c_3; GLOBALS->varsplit_vcd_recoder_c_3=GLOBALS->vsplitcurr_vcd_recoder_c_3=vst; GLOBALS->var_prevch_vcd_recoder_c_3=0; } else { GLOBALS->varsplit_vcd_recoder_c_3=NULL; } if(match_kw) { int vr = vcd_keyword_code(GLOBALS->yytext_vcd_recoder_c_3, len); if(vr != V_STRING) { return(vr); } } GLOBALS->yylen_vcd_recoder_c_3=len; return(V_STRING); } static int get_strtoken(void) { int ch; int len=0; if(!GLOBALS->var_prevch_vcd_recoder_c_3) { for(;;) { ch=getch(); if(ch<0) return(V_END); if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')) continue; break; } } else { ch=GLOBALS->var_prevch_vcd_recoder_c_3; GLOBALS->var_prevch_vcd_recoder_c_3=0; } for(GLOBALS->yytext_vcd_recoder_c_3[len++]=ch;;GLOBALS->yytext_vcd_recoder_c_3[len++]=ch) { if(len==GLOBALS->T_MAX_STR_vcd_recoder_c_3) { GLOBALS->yytext_vcd_recoder_c_3=(char *)realloc_2(GLOBALS->yytext_vcd_recoder_c_3, (GLOBALS->T_MAX_STR_vcd_recoder_c_3=GLOBALS->T_MAX_STR_vcd_recoder_c_3*2)+1); } ch=getch(); if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')||(ch<0)) break; } GLOBALS->yytext_vcd_recoder_c_3[len]=0; /* terminator */ GLOBALS->yylen_vcd_recoder_c_3=len; return(V_STRING); } static void sync_end(char *hdr) { int tok; if(hdr) { DEBUG(fprintf(stderr,"%s",hdr)); } for(;;) { tok=get_token(); if((tok==T_END)||(tok==T_EOF)) break; if(hdr) { DEBUG(fprintf(stderr," %s",GLOBALS->yytext_vcd_recoder_c_3)); } } if(hdr) { DEBUG(fprintf(stderr,"\n")); } } static int version_sync_end(char *hdr) { int tok; int rc = 0; if(hdr) { DEBUG(fprintf(stderr,"%s",hdr)); } for(;;) { tok=get_token(); if((tok==T_END)||(tok==T_EOF)) break; if(hdr) { DEBUG(fprintf(stderr," %s",GLOBALS->yytext_vcd_recoder_c_3)); } if(strstr(GLOBALS->yytext_vcd_recoder_c_3, "Icarus")) /* turn off autocoalesce for Icarus */ { GLOBALS->autocoalesce = 0; rc = 1; } } if(hdr) { DEBUG(fprintf(stderr,"\n")); } return(rc); } static void parse_valuechange(void) { struct vcdsymbol *v; char *vector; int vlen; unsigned char typ; switch((typ = GLOBALS->yytext_vcd_recoder_c_3[0])) { /* encode bits as (time delta<<4) + (enum AnalyzerBits value) */ case '0': case '1': case 'x': case 'X': case 'z': case 'Z': case 'h': case 'H': case 'u': case 'U': case 'w': case 'W': case 'l': case 'L': case '-': if(GLOBALS->yylen_vcd_recoder_c_3>1) { v=bsearch_vcd(GLOBALS->yytext_vcd_recoder_c_3+1, GLOBALS->yylen_vcd_recoder_c_3-1); if(!v) { fprintf(stderr,"Near byte %d, Unknown VCD identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_recoder_c_3+(GLOBALS->vst_vcd_recoder_c_3-GLOBALS->vcdbuf_vcd_recoder_c_3)),GLOBALS->yytext_vcd_recoder_c_3+1); malform_eof_fix(); } else { nptr n = v->narray[0]; unsigned int time_delta; unsigned int rcv; if(!n->mv.mvlfac_vlist) /* overloaded for vlist, numhist = last position used */ { n->mv.mvlfac_vlist = (GLOBALS->vlist_prepack) ? ((struct vlist_t *)vlist_packer_create()) : vlist_create(sizeof(char)); vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)'0'); /* represents single bit routine for decompression */ vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)v->vartype); } time_delta = GLOBALS->time_vlist_count_vcd_recoder_c_1 - (unsigned int)n->numhist; n->numhist = GLOBALS->time_vlist_count_vcd_recoder_c_1; switch(GLOBALS->yytext_vcd_recoder_c_3[0]) { case '0': case '1': rcv = ((GLOBALS->yytext_vcd_recoder_c_3[0]&1)<<1) | (time_delta<<2); break; /* pack more delta bits in for 0/1 vchs */ case 'x': case 'X': rcv = RCV_X | (time_delta<<4); break; case 'z': case 'Z': rcv = RCV_Z | (time_delta<<4); break; case 'h': case 'H': rcv = RCV_H | (time_delta<<4); break; case 'u': case 'U': rcv = RCV_U | (time_delta<<4); break; case 'w': case 'W': rcv = RCV_W | (time_delta<<4); break; case 'l': case 'L': rcv = RCV_L | (time_delta<<4); break; default: rcv = RCV_D | (time_delta<<4); break; } vlist_emit_uv32(&n->mv.mvlfac_vlist, rcv); } } else { fprintf(stderr,"Near byte %d, Malformed VCD identifier\n", (int)(GLOBALS->vcdbyteno_vcd_recoder_c_3+(GLOBALS->vst_vcd_recoder_c_3-GLOBALS->vcdbuf_vcd_recoder_c_3))); malform_eof_fix(); } break; /* encode everything else literally as a time delta + a string */ #ifndef STRICT_VCD_ONLY case 's': case 'S': vector=wave_alloca(GLOBALS->yylen_cache_vcd_recoder_c_3=GLOBALS->yylen_vcd_recoder_c_3); vlen = fstUtilityEscToBin((unsigned char *)vector, (unsigned char *)(GLOBALS->yytext_vcd_recoder_c_3+1), GLOBALS->yylen_vcd_recoder_c_3-1); vector[vlen] = 0; get_strtoken(); goto process_binary; #endif case 'b': case 'B': case 'r': case 'R': vector=wave_alloca(GLOBALS->yylen_cache_vcd_recoder_c_3=GLOBALS->yylen_vcd_recoder_c_3); strcpy(vector,GLOBALS->yytext_vcd_recoder_c_3+1); vlen=GLOBALS->yylen_vcd_recoder_c_3-1; get_strtoken(); process_binary: v=bsearch_vcd(GLOBALS->yytext_vcd_recoder_c_3, GLOBALS->yylen_vcd_recoder_c_3); if(!v) { fprintf(stderr,"Near byte %d, Unknown VCD identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_recoder_c_3+(GLOBALS->vst_vcd_recoder_c_3-GLOBALS->vcdbuf_vcd_recoder_c_3)),GLOBALS->yytext_vcd_recoder_c_3+1); malform_eof_fix(); } else { nptr n = v->narray[0]; unsigned int time_delta; if(!n->mv.mvlfac_vlist) /* overloaded for vlist, numhist = last position used */ { unsigned char typ2 = toupper(typ); n->mv.mvlfac_vlist = (GLOBALS->vlist_prepack) ? ((struct vlist_t *)vlist_packer_create()) : vlist_create(sizeof(char)); if((v->vartype!=V_REAL) && (v->vartype!=V_STRINGTYPE)) { if((typ2=='R')||(typ2=='S')) { typ2 = 'B'; /* ok, typical case...fix as 'r' on bits variable causes recoder crash during trace extraction */ } } else { if(typ2=='B') { typ2 = 'S'; /* should never be necessary...this is defensive */ } } vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)toupper(typ2)); /* B/R/P/S for decompress */ vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)v->vartype); vlist_emit_uv32(&n->mv.mvlfac_vlist, (unsigned int)v->size); } time_delta = GLOBALS->time_vlist_count_vcd_recoder_c_1 - (unsigned int)n->numhist; n->numhist = GLOBALS->time_vlist_count_vcd_recoder_c_1; vlist_emit_uv32(&n->mv.mvlfac_vlist, time_delta); if((typ=='b')||(typ=='B')) { if((v->vartype!=V_REAL)&&(v->vartype!=V_STRINGTYPE)) { vlist_emit_mvl9_string(&n->mv.mvlfac_vlist, vector); } else { vlist_emit_string(&n->mv.mvlfac_vlist, vector); } } else { if((v->vartype == V_REAL)||(v->vartype == V_STRINGTYPE)||(typ=='s')||(typ=='S')) { vlist_emit_string(&n->mv.mvlfac_vlist, vector); } else { char *bits = wave_alloca(v->size + 1); int i, j, k=0; memset(bits, 0x0, v->size + 1); for(i=0;i> (7-j)) & 1) | '0'; if(k >= v->size) goto bit_term; } } bit_term: vlist_emit_mvl9_string(&n->mv.mvlfac_vlist, bits); } } } break; case 'p': case 'P': /* extract port dump value.. */ vector=wave_alloca(GLOBALS->yylen_cache_vcd_recoder_c_3=GLOBALS->yylen_vcd_recoder_c_3); evcd_strcpy(vector,GLOBALS->yytext_vcd_recoder_c_3+1); /* convert to regular vcd */ vlen=GLOBALS->yylen_vcd_recoder_c_3-1; get_strtoken(); /* throw away 0_strength_component */ get_strtoken(); /* throw away 0_strength_component */ get_strtoken(); /* this is the id */ typ = 'b'; /* convert to regular vcd */ goto process_binary; /* store string literally */ default: break; } } static void evcd_strcpy(char *dst, char *src) { static const char *evcd="DUNZduLHXTlh01?FAaBbCcf"; static const char *vcd="01xz0101xz0101xzxxxxxxz"; char ch; int i; while((ch=*src)) { for(i=0;i<23;i++) { if(evcd[i]==ch) { *dst=vcd[i]; break; } } if(i==23) *dst='x'; src++; dst++; } *dst=0; /* null terminate destination */ } static void vcd_parse(void) { int tok; unsigned char ttype; int disable_autocoalesce = 0; for(;;) { switch(get_token()) { case T_COMMENT: sync_end("COMMENT:"); break; case T_DATE: sync_end("DATE:"); break; case T_VERSION: disable_autocoalesce = version_sync_end("VERSION:"); break; case T_TIMEZERO: { int vtok=get_token(); if((vtok==T_END)||(vtok==T_EOF)) break; GLOBALS->global_time_offset=atoi_64(GLOBALS->yytext_vcd_recoder_c_3); DEBUG(fprintf(stderr,"TIMEZERO: "TTFormat"\n",GLOBALS->global_time_offset)); sync_end(NULL); } break; case T_TIMESCALE: { int vtok; int i; char prefix=' '; vtok=get_token(); if((vtok==T_END)||(vtok==T_EOF)) break; fractional_timescale_fix(GLOBALS->yytext_vcd_recoder_c_3); GLOBALS->time_scale=atoi_64(GLOBALS->yytext_vcd_recoder_c_3); if(!GLOBALS->time_scale) GLOBALS->time_scale=1; for(i=0;iyylen_vcd_recoder_c_3;i++) { if((GLOBALS->yytext_vcd_recoder_c_3[i]<'0')||(GLOBALS->yytext_vcd_recoder_c_3[i]>'9')) { prefix=GLOBALS->yytext_vcd_recoder_c_3[i]; break; } } if(prefix==' ') { vtok=get_token(); if((vtok==T_END)||(vtok==T_EOF)) break; prefix=GLOBALS->yytext_vcd_recoder_c_3[0]; } switch(prefix) { case ' ': case 'm': case 'u': case 'n': case 'p': case 'f': case 'a': case 'z': GLOBALS->time_dimension=prefix; break; case 's': GLOBALS->time_dimension=' '; break; default: /* unknown */ GLOBALS->time_dimension='n'; break; } DEBUG(fprintf(stderr,"TIMESCALE: "TTFormat" %cs\n",GLOBALS->time_scale, GLOBALS->time_dimension)); sync_end(NULL); } break; case T_SCOPE: T_GET; { switch(GLOBALS->yytext_vcd_recoder_c_3[0]) { case 'm': ttype = TREE_VCD_ST_MODULE; break; case 't': ttype = TREE_VCD_ST_TASK; break; case 'f': ttype = (GLOBALS->yytext_vcd_recoder_c_3[1] == 'u') ? TREE_VCD_ST_FUNCTION : TREE_VCD_ST_FORK; break; case 'b': ttype = TREE_VCD_ST_BEGIN; break; case 'g': ttype = TREE_VCD_ST_GENERATE; break; case 's': ttype = TREE_VCD_ST_STRUCT; break; case 'u': ttype = TREE_VCD_ST_UNION; break; case 'c': ttype = TREE_VCD_ST_CLASS; break; case 'i': ttype = TREE_VCD_ST_INTERFACE; break; case 'p': ttype = (GLOBALS->yytext_vcd_recoder_c_3[1] == 'r') ? TREE_VCD_ST_PROGRAM : TREE_VCD_ST_PACKAGE; break; case 'v': { char *vht = GLOBALS->yytext_vcd_recoder_c_3; if(!strncmp(vht, "vhdl_", 5)) { switch(vht[5]) { case 'a': ttype = TREE_VHDL_ST_ARCHITECTURE; break; case 'r': ttype = TREE_VHDL_ST_RECORD; break; case 'b': ttype = TREE_VHDL_ST_BLOCK; break; case 'g': ttype = TREE_VHDL_ST_GENERATE; break; case 'i': ttype = TREE_VHDL_ST_GENIF; break; case 'f': ttype = (vht[6] == 'u') ? TREE_VHDL_ST_FUNCTION : TREE_VHDL_ST_GENFOR; break; case 'p': ttype = (!strncmp(vht+6, "roces", 5)) ? TREE_VHDL_ST_PROCESS: TREE_VHDL_ST_PROCEDURE; break; default: ttype = TREE_UNKNOWN; break; } } else { ttype = TREE_UNKNOWN; } } break; default: ttype = TREE_UNKNOWN; break; } } T_GET; if(tok==T_STRING) { struct slist *s; s=(struct slist *)calloc_2(1,sizeof(struct slist)); s->len=GLOBALS->yylen_vcd_recoder_c_3; s->str=(char *)malloc_2(GLOBALS->yylen_vcd_recoder_c_3+1); strcpy(s->str, GLOBALS->yytext_vcd_recoder_c_3); s->mod_tree_parent = GLOBALS->mod_tree_parent; allocate_and_decorate_module_tree_node(ttype, GLOBALS->yytext_vcd_recoder_c_3, NULL, GLOBALS->yylen_vcd_recoder_c_3, 0, 0, 0); if(GLOBALS->slistcurr) { GLOBALS->slistcurr->next=s; GLOBALS->slistcurr=s; } else { GLOBALS->slistcurr=GLOBALS->slistroot=s; } build_slisthier(); DEBUG(fprintf(stderr, "SCOPE: %s\n",GLOBALS->slisthier)); } sync_end(NULL); break; case T_UPSCOPE: if(GLOBALS->slistroot) { struct slist *s; GLOBALS->mod_tree_parent = GLOBALS->slistcurr->mod_tree_parent; s=GLOBALS->slistroot; if(!s->next) { free_2(s->str); free_2(s); GLOBALS->slistroot=GLOBALS->slistcurr=NULL; } else for(;;) { if(!s->next->next) { free_2(s->next->str); free_2(s->next); s->next=NULL; GLOBALS->slistcurr=s; break; } s=s->next; } build_slisthier(); DEBUG(fprintf(stderr, "SCOPE: %s\n",GLOBALS->slisthier)); } else { GLOBALS->mod_tree_parent = NULL; } sync_end(NULL); break; case T_VAR: if((GLOBALS->header_over_vcd_recoder_c_3)&&(0)) { fprintf(stderr,"$VAR encountered after $ENDDEFINITIONS near byte %d. VCD is malformed, exiting.\n", (int)(GLOBALS->vcdbyteno_vcd_recoder_c_3+(GLOBALS->vst_vcd_recoder_c_3-GLOBALS->vcdbuf_vcd_recoder_c_3))); vcd_exit(255); } else { int vtok; struct vcdsymbol *v=NULL; GLOBALS->var_prevch_vcd_recoder_c_3=0; if(GLOBALS->varsplit_vcd_recoder_c_3) { free_2(GLOBALS->varsplit_vcd_recoder_c_3); GLOBALS->varsplit_vcd_recoder_c_3=NULL; } vtok=get_vartoken(1); if(vtok>V_STRINGTYPE) goto bail; v=(struct vcdsymbol *)calloc_2(1,sizeof(struct vcdsymbol)); v->vartype=vtok; v->msi=v->lsi=GLOBALS->vcd_explicit_zero_subscripts; /* indicate [un]subscripted status */ if(vtok==V_PORT) { vtok=get_vartoken(1); if(vtok==V_STRING) { v->size=atoi_64(GLOBALS->yytext_vcd_recoder_c_3); if(!v->size) v->size=1; } else if(vtok==V_LB) { vtok=get_vartoken(1); if(vtok==V_END) goto err; if(vtok!=V_STRING) goto err; v->msi=atoi_64(GLOBALS->yytext_vcd_recoder_c_3); vtok=get_vartoken(0); if(vtok==V_RB) { v->lsi=v->msi; v->size=1; } else { if(vtok!=V_COLON) goto err; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; v->lsi=atoi_64(GLOBALS->yytext_vcd_recoder_c_3); vtok=get_vartoken(0); if(vtok!=V_RB) goto err; if(v->msi>v->lsi) { v->size=v->msi-v->lsi+1; } else { v->size=v->lsi-v->msi+1; } } } else goto err; vtok=get_strtoken(); if(vtok==V_END) goto err; v->id=(char *)malloc_2(GLOBALS->yylen_vcd_recoder_c_3+1); strcpy(v->id, GLOBALS->yytext_vcd_recoder_c_3); v->nid=vcdid_hash(GLOBALS->yytext_vcd_recoder_c_3,GLOBALS->yylen_vcd_recoder_c_3); if(v->nid == (GLOBALS->vcd_hash_max+1)) { GLOBALS->vcd_hash_max = v->nid; } else if((v->nid>0)&&(v->nid<=GLOBALS->vcd_hash_max)) { /* general case with aliases */ } else { GLOBALS->vcd_hash_kill = 1; } if(v->nid < GLOBALS->vcd_minid_vcd_recoder_c_3) GLOBALS->vcd_minid_vcd_recoder_c_3 = v->nid; if(v->nid > GLOBALS->vcd_maxid_vcd_recoder_c_3) GLOBALS->vcd_maxid_vcd_recoder_c_3 = v->nid; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; if(GLOBALS->slisthier_len) { v->name=(char *)malloc_2(GLOBALS->slisthier_len+1+GLOBALS->yylen_vcd_recoder_c_3+1); strcpy(v->name,GLOBALS->slisthier); strcpy(v->name+GLOBALS->slisthier_len,GLOBALS->vcd_hier_delimeter); if(GLOBALS->alt_hier_delimeter) { strcpy_vcdalt(v->name+GLOBALS->slisthier_len+1,GLOBALS->yytext_vcd_recoder_c_3,GLOBALS->alt_hier_delimeter); } else { if((strcpy_delimfix(v->name+GLOBALS->slisthier_len+1,GLOBALS->yytext_vcd_recoder_c_3)) && (GLOBALS->yytext_vcd_recoder_c_3[0] != '\\')) { char *sd=(char *)malloc_2(GLOBALS->slisthier_len+1+GLOBALS->yylen_vcd_recoder_c_3+2); strcpy(sd,GLOBALS->slisthier); strcpy(sd+GLOBALS->slisthier_len,GLOBALS->vcd_hier_delimeter); sd[GLOBALS->slisthier_len+1] = '\\'; strcpy(sd+GLOBALS->slisthier_len+2,v->name+GLOBALS->slisthier_len+1); free_2(v->name); v->name = sd; } } } else { v->name=(char *)malloc_2(GLOBALS->yylen_vcd_recoder_c_3+1); if(GLOBALS->alt_hier_delimeter) { strcpy_vcdalt(v->name,GLOBALS->yytext_vcd_recoder_c_3,GLOBALS->alt_hier_delimeter); } else { if((strcpy_delimfix(v->name,GLOBALS->yytext_vcd_recoder_c_3)) && (GLOBALS->yytext_vcd_recoder_c_3[0] != '\\')) { char *sd=(char *)malloc_2(GLOBALS->yylen_vcd_recoder_c_3+2); sd[0] = '\\'; strcpy(sd+1,v->name); free_2(v->name); v->name = sd; } } } if(GLOBALS->pv_vcd_recoder_c_3) { if(!strcmp(GLOBALS->prev_hier_uncompressed_name,v->name) && !disable_autocoalesce && (!strchr(v->name, '\\'))) { GLOBALS->pv_vcd_recoder_c_3->chain=v; v->root=GLOBALS->rootv_vcd_recoder_c_3; if(GLOBALS->pv_vcd_recoder_c_3==GLOBALS->rootv_vcd_recoder_c_3) GLOBALS->pv_vcd_recoder_c_3->root=GLOBALS->rootv_vcd_recoder_c_3; } else { GLOBALS->rootv_vcd_recoder_c_3=v; } free_2(GLOBALS->prev_hier_uncompressed_name); } else { GLOBALS->rootv_vcd_recoder_c_3=v; } GLOBALS->pv_vcd_recoder_c_3=v; GLOBALS->prev_hier_uncompressed_name = strdup_2(v->name); } else /* regular vcd var, not an evcd port var */ { vtok=get_vartoken(1); if(vtok==V_END) goto err; v->size=atoi_64(GLOBALS->yytext_vcd_recoder_c_3); vtok=get_strtoken(); if(vtok==V_END) goto err; v->id=(char *)malloc_2(GLOBALS->yylen_vcd_recoder_c_3+1); strcpy(v->id, GLOBALS->yytext_vcd_recoder_c_3); v->nid=vcdid_hash(GLOBALS->yytext_vcd_recoder_c_3,GLOBALS->yylen_vcd_recoder_c_3); if(v->nid == (GLOBALS->vcd_hash_max+1)) { GLOBALS->vcd_hash_max = v->nid; } else if((v->nid>0)&&(v->nid<=GLOBALS->vcd_hash_max)) { /* general case with aliases */ } else { GLOBALS->vcd_hash_kill = 1; } if(v->nid < GLOBALS->vcd_minid_vcd_recoder_c_3) GLOBALS->vcd_minid_vcd_recoder_c_3 = v->nid; if(v->nid > GLOBALS->vcd_maxid_vcd_recoder_c_3) GLOBALS->vcd_maxid_vcd_recoder_c_3 = v->nid; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; if(GLOBALS->slisthier_len) { v->name=(char *)malloc_2(GLOBALS->slisthier_len+1+GLOBALS->yylen_vcd_recoder_c_3+1); strcpy(v->name,GLOBALS->slisthier); strcpy(v->name+GLOBALS->slisthier_len,GLOBALS->vcd_hier_delimeter); if(GLOBALS->alt_hier_delimeter) { strcpy_vcdalt(v->name+GLOBALS->slisthier_len+1,GLOBALS->yytext_vcd_recoder_c_3,GLOBALS->alt_hier_delimeter); } else { if((strcpy_delimfix(v->name+GLOBALS->slisthier_len+1,GLOBALS->yytext_vcd_recoder_c_3)) && (GLOBALS->yytext_vcd_recoder_c_3[0] != '\\')) { char *sd=(char *)malloc_2(GLOBALS->slisthier_len+1+GLOBALS->yylen_vcd_recoder_c_3+2); strcpy(sd,GLOBALS->slisthier); strcpy(sd+GLOBALS->slisthier_len,GLOBALS->vcd_hier_delimeter); sd[GLOBALS->slisthier_len+1] = '\\'; strcpy(sd+GLOBALS->slisthier_len+2,v->name+GLOBALS->slisthier_len+1); free_2(v->name); v->name = sd; } } } else { v->name=(char *)malloc_2(GLOBALS->yylen_vcd_recoder_c_3+1); if(GLOBALS->alt_hier_delimeter) { strcpy_vcdalt(v->name,GLOBALS->yytext_vcd_recoder_c_3,GLOBALS->alt_hier_delimeter); } else { if((strcpy_delimfix(v->name,GLOBALS->yytext_vcd_recoder_c_3)) && (GLOBALS->yytext_vcd_recoder_c_3[0] != '\\')) { char *sd=(char *)malloc_2(GLOBALS->yylen_vcd_recoder_c_3+2); sd[0] = '\\'; strcpy(sd+1,v->name); free_2(v->name); v->name = sd; } } } if(GLOBALS->pv_vcd_recoder_c_3) { if(!strcmp(GLOBALS->prev_hier_uncompressed_name,v->name)) { GLOBALS->pv_vcd_recoder_c_3->chain=v; v->root=GLOBALS->rootv_vcd_recoder_c_3; if(GLOBALS->pv_vcd_recoder_c_3==GLOBALS->rootv_vcd_recoder_c_3) GLOBALS->pv_vcd_recoder_c_3->root=GLOBALS->rootv_vcd_recoder_c_3; } else { GLOBALS->rootv_vcd_recoder_c_3=v; } free_2(GLOBALS->prev_hier_uncompressed_name); } else { GLOBALS->rootv_vcd_recoder_c_3=v; } GLOBALS->pv_vcd_recoder_c_3=v; GLOBALS->prev_hier_uncompressed_name = strdup_2(v->name); vtok=get_vartoken(1); if(vtok==V_END) goto dumpv; if(vtok!=V_LB) goto err; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; v->msi=atoi_64(GLOBALS->yytext_vcd_recoder_c_3); vtok=get_vartoken(0); if(vtok==V_RB) { v->lsi=v->msi; goto dumpv; } if(vtok!=V_COLON) goto err; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; v->lsi=atoi_64(GLOBALS->yytext_vcd_recoder_c_3); vtok=get_vartoken(0); if(vtok!=V_RB) goto err; } dumpv: if(v->size == 0) { if(v->vartype != V_EVENT) { if(v->vartype != V_STRINGTYPE) { v->vartype = V_REAL; } } else { v->size = 1; } } /* MTI fix */ if((v->vartype==V_REAL)||(v->vartype==V_STRINGTYPE)) { v->size=1; /* override any data we parsed in */ v->msi=v->lsi=0; } else if((v->size>1)&&(v->msi<=0)&&(v->lsi<=0)) { if(v->vartype==V_EVENT) { v->size=1; } else { /* any criteria for the direction here? */ v->msi=v->size-1; v->lsi=0; } } else if((v->msi>v->lsi)&&((v->msi-v->lsi+1)!=v->size)) { if((v->vartype!=V_EVENT)&&(v->vartype!=V_PARAMETER)) { v->msi = v->size-1; v->lsi = 0; /* all this formerly was goto err; */ } else { v->size=v->msi-v->lsi+1; } } else if((v->lsi>=v->msi)&&((v->lsi-v->msi+1)!=v->size)) { if((v->vartype!=V_EVENT)&&(v->vartype!=V_PARAMETER)) { v->lsi = v->size-1; v->msi = 0; /* all this formerly was goto err; */ } else { v->size=v->lsi-v->msi+1; } } /* initial conditions */ v->narray=(struct Node **)calloc_2(1,sizeof(struct Node *)); v->narray[0]=(struct Node *)calloc_2(1,sizeof(struct Node)); v->narray[0]->head.time=-1; v->narray[0]->head.v.h_val=AN_X; if(!GLOBALS->vcdsymroot_vcd_recoder_c_3) { GLOBALS->vcdsymroot_vcd_recoder_c_3=GLOBALS->vcdsymcurr_vcd_recoder_c_3=v; } else { GLOBALS->vcdsymcurr_vcd_recoder_c_3->next=v; GLOBALS->vcdsymcurr_vcd_recoder_c_3=v; } GLOBALS->numsyms_vcd_recoder_c_3++; if(GLOBALS->vcd_save_handle) { if(v->msi==v->lsi) { if((v->vartype==V_REAL)||(v->vartype==V_STRINGTYPE)) { fprintf(GLOBALS->vcd_save_handle,"%s\n",v->name); } else { if(v->msi>=0) { if(!GLOBALS->vcd_explicit_zero_subscripts) fprintf(GLOBALS->vcd_save_handle,"%s%c%d\n",v->name,GLOBALS->hier_delimeter,v->msi); else fprintf(GLOBALS->vcd_save_handle,"%s[%d]\n",v->name,v->msi); } else { fprintf(GLOBALS->vcd_save_handle,"%s\n",v->name); } } } else { fprintf(GLOBALS->vcd_save_handle,"%s[%d:%d]\n",v->name,v->msi,v->lsi); } } goto bail; err: if(v) { GLOBALS->error_count_vcd_recoder_c_3++; if(v->name) { fprintf(stderr, "Near byte %d, $VAR parse error encountered with '%s'\n", (int)(GLOBALS->vcdbyteno_vcd_recoder_c_3+(GLOBALS->vst_vcd_recoder_c_3-GLOBALS->vcdbuf_vcd_recoder_c_3)), v->name); free_2(v->name); } else { fprintf(stderr, "Near byte %d, $VAR parse error encountered\n", (int)(GLOBALS->vcdbyteno_vcd_recoder_c_3+(GLOBALS->vst_vcd_recoder_c_3-GLOBALS->vcdbuf_vcd_recoder_c_3))); } if(v->id) free_2(v->id); free_2(v); v=NULL; GLOBALS->pv_vcd_recoder_c_3 = NULL; } bail: if(vtok!=V_END) sync_end(NULL); break; } case T_ENDDEFINITIONS: GLOBALS->header_over_vcd_recoder_c_3=1; /* do symbol table management here */ create_sorted_table(); if((!GLOBALS->sorted_vcd_recoder_c_3)&&(!GLOBALS->indexed_vcd_recoder_c_3)) { fprintf(stderr, "No symbols in VCD file..nothing to do!\n"); vcd_exit(255); } if(GLOBALS->error_count_vcd_recoder_c_3) { fprintf(stderr, "\n%d VCD parse errors encountered, exiting.\n", GLOBALS->error_count_vcd_recoder_c_3); vcd_exit(255); } if(GLOBALS->use_fastload == VCD_FSL_READ) { read_fastload_body(); fprintf(stderr, "VCDLOAD | Using fastload file.\n"); return; } break; case T_STRING: if(!GLOBALS->header_over_vcd_recoder_c_3) { GLOBALS->header_over_vcd_recoder_c_3=1; /* do symbol table management here */ create_sorted_table(); if((!GLOBALS->sorted_vcd_recoder_c_3)&&(!GLOBALS->indexed_vcd_recoder_c_3)) break; } { /* catchall for events when header over */ if(GLOBALS->yytext_vcd_recoder_c_3[0]=='#') { TimeType tim; TimeType *tt; tim=atoi_64(GLOBALS->yytext_vcd_recoder_c_3+1); if(GLOBALS->start_time_vcd_recoder_c_3<0) { GLOBALS->start_time_vcd_recoder_c_3=tim; if(GLOBALS->time_vlist_vcd_recoder_write) { vlist_packer_emit_utt((struct vlist_packer_t **)(void *)&GLOBALS->time_vlist_vcd_recoder_write, tim); } } else { if(tim < GLOBALS->current_time_vcd_recoder_c_3) /* avoid backtracking time counts which can happen on malformed files */ { tim = GLOBALS->current_time_vcd_recoder_c_3; } if(GLOBALS->time_vlist_vcd_recoder_write) { vlist_packer_emit_utt((struct vlist_packer_t **)(void *)&GLOBALS->time_vlist_vcd_recoder_write, tim - GLOBALS->current_time_vcd_recoder_c_3); } } GLOBALS->current_time_vcd_recoder_c_3=tim; if(GLOBALS->end_time_vcd_recoder_c_3end_time_vcd_recoder_c_3=tim; /* in case of malformed vcd files */ DEBUG(fprintf(stderr,"#"TTFormat"\n",tim)); tt = vlist_alloc(&GLOBALS->time_vlist_vcd_recoder_c_1, 0); *tt = tim; GLOBALS->time_vlist_count_vcd_recoder_c_1++; } else { if(GLOBALS->time_vlist_count_vcd_recoder_c_1) { /* OK, otherwise fix for System C which doesn't emit time zero... */ } else { TimeType tim = LLDescriptor(0); TimeType *tt; GLOBALS->start_time_vcd_recoder_c_3=GLOBALS->current_time_vcd_recoder_c_3=GLOBALS->end_time_vcd_recoder_c_3=tim; if(GLOBALS->time_vlist_vcd_recoder_write) { vlist_packer_emit_utt((struct vlist_packer_t **)(void *)&GLOBALS->time_vlist_vcd_recoder_write, tim); } tt = vlist_alloc(&GLOBALS->time_vlist_vcd_recoder_c_1, 0); *tt = tim; GLOBALS->time_vlist_count_vcd_recoder_c_1=1; } parse_valuechange(); } } break; case T_DUMPALL: /* dump commands modify vals anyway so */ case T_DUMPPORTSALL: break; /* just loop through.. */ case T_DUMPOFF: case T_DUMPPORTSOFF: GLOBALS->dumping_off_vcd_recoder_c_3=1; if((!GLOBALS->blackout_regions)||((GLOBALS->blackout_regions)&&(GLOBALS->blackout_regions->bstart<=GLOBALS->blackout_regions->bend))) { struct blackout_region_t *bt = calloc_2(1, sizeof(struct blackout_region_t)); bt->bstart = GLOBALS->current_time_vcd_recoder_c_3; bt->next = GLOBALS->blackout_regions; GLOBALS->blackout_regions = bt; } break; case T_DUMPON: case T_DUMPPORTSON: GLOBALS->dumping_off_vcd_recoder_c_3=0; if((GLOBALS->blackout_regions)&&(GLOBALS->blackout_regions->bstart>GLOBALS->blackout_regions->bend)) { GLOBALS->blackout_regions->bend = GLOBALS->current_time_vcd_recoder_c_3; } break; case T_DUMPVARS: case T_DUMPPORTS: if(GLOBALS->current_time_vcd_recoder_c_3<0) { GLOBALS->start_time_vcd_recoder_c_3=GLOBALS->current_time_vcd_recoder_c_3=GLOBALS->end_time_vcd_recoder_c_3=0; } break; case T_VCDCLOSE: sync_end("VCDCLOSE:"); break; /* next token will be '#' time related followed by $end */ case T_END: /* either closure for dump commands or */ break; /* it's spurious */ case T_UNKNOWN_KEY: sync_end(NULL); /* skip over unknown keywords */ break; case T_EOF: if((GLOBALS->blackout_regions)&&(GLOBALS->blackout_regions->bstart>GLOBALS->blackout_regions->bend)) { GLOBALS->blackout_regions->bend = GLOBALS->current_time_vcd_recoder_c_3; } GLOBALS->pv_vcd_recoder_c_3 = NULL; if(GLOBALS->prev_hier_uncompressed_name) { free_2(GLOBALS->prev_hier_uncompressed_name); GLOBALS->prev_hier_uncompressed_name = NULL; } return; default: DEBUG(fprintf(stderr,"UNKNOWN TOKEN\n")); } } } /*******************************************************************************/ void add_histent(TimeType tim, struct Node *n, char ch, int regadd, char *vector) { struct HistEnt *he; char heval; if(!vector) { if(!n->curr) { he=histent_calloc(); he->time=-1; he->v.h_val=AN_X; n->curr=he; n->head.next=he; add_histent(tim,n,ch,regadd, vector); } else { if(regadd) { tim*=(GLOBALS->time_scale); } if(ch=='0') heval=AN_0; else if(ch=='1') heval=AN_1; else if((ch=='x')||(ch=='X')) heval=AN_X; else if((ch=='z')||(ch=='Z')) heval=AN_Z; else if((ch=='h')||(ch=='H')) heval=AN_H; else if((ch=='u')||(ch=='U')) heval=AN_U; else if((ch=='w')||(ch=='W')) heval=AN_W; else if((ch=='l')||(ch=='L')) heval=AN_L; else /* if(ch=='-') */ heval=AN_DASH; /* default */ if((n->curr->v.h_val!=heval)||(tim==GLOBALS->start_time_vcd_recoder_c_3)||(n->vartype==ND_VCD_EVENT)||(GLOBALS->vcd_preserve_glitches)) /* same region == go skip */ { if(n->curr->time==tim) { DEBUG(printf("Warning: Glitch at time ["TTFormat"] Signal [%p], Value [%c->%c].\n", tim, n, AN_STR[n->curr->v.h_val], ch)); n->curr->v.h_val=heval; /* we have a glitch! */ GLOBALS->num_glitches_vcd_recoder_c_4++; if(!(n->curr->flags&HIST_GLITCH)) { n->curr->flags|=HIST_GLITCH; /* set the glitch flag */ GLOBALS->num_glitch_regions_vcd_recoder_c_4++; } } else { he=histent_calloc(); he->time=tim; he->v.h_val=heval; n->curr->next=he; n->curr=he; GLOBALS->regions+=regadd; } } } } else { switch(ch) { case 's': /* string */ { if(!n->curr) { he=histent_calloc(); he->flags=(HIST_STRING|HIST_REAL); he->time=-1; he->v.h_vector=NULL; n->curr=he; n->head.next=he; add_histent(tim,n,ch,regadd, vector); } else { if(regadd) { tim*=(GLOBALS->time_scale); } if(n->curr->time==tim) { DEBUG(printf("Warning: String Glitch at time ["TTFormat"] Signal [%p].\n", tim, n)); if(n->curr->v.h_vector) free_2(n->curr->v.h_vector); n->curr->v.h_vector=vector; /* we have a glitch! */ GLOBALS->num_glitches_vcd_recoder_c_4++; if(!(n->curr->flags&HIST_GLITCH)) { n->curr->flags|=HIST_GLITCH; /* set the glitch flag */ GLOBALS->num_glitch_regions_vcd_recoder_c_4++; } } else { he=histent_calloc(); he->flags=(HIST_STRING|HIST_REAL); he->time=tim; he->v.h_vector=vector; n->curr->next=he; n->curr=he; GLOBALS->regions+=regadd; } } break; } case 'g': /* real number */ { if(!n->curr) { he=histent_calloc(); he->flags=HIST_REAL; he->time=-1; #ifdef WAVE_HAS_H_DOUBLE he->v.h_double = strtod("NaN", NULL); #else he->v.h_vector=NULL; #endif n->curr=he; n->head.next=he; add_histent(tim,n,ch,regadd, vector); } else { if(regadd) { tim*=(GLOBALS->time_scale); } if( #ifdef WAVE_HAS_H_DOUBLE (vector&&(n->curr->v.h_double!=*(double *)vector)) #else (n->curr->v.h_vector&&vector&&(*(double *)n->curr->v.h_vector!=*(double *)vector)) #endif ||(tim==GLOBALS->start_time_vcd_recoder_c_3) #ifndef WAVE_HAS_H_DOUBLE ||(!n->curr->v.h_vector) #endif ||(GLOBALS->vcd_preserve_glitches)||(GLOBALS->vcd_preserve_glitches_real) ) /* same region == go skip */ { if(n->curr->time==tim) { DEBUG(printf("Warning: Real number Glitch at time ["TTFormat"] Signal [%p].\n", tim, n)); #ifdef WAVE_HAS_H_DOUBLE n->curr->v.h_double = *((double *)vector); #else if(n->curr->v.h_vector) free_2(n->curr->v.h_vector); n->curr->v.h_vector=vector; /* we have a glitch! */ #endif GLOBALS->num_glitches_vcd_recoder_c_4++; if(!(n->curr->flags&HIST_GLITCH)) { n->curr->flags|=HIST_GLITCH; /* set the glitch flag */ GLOBALS->num_glitch_regions_vcd_recoder_c_4++; } } else { he=histent_calloc(); he->flags=HIST_REAL; he->time=tim; #ifdef WAVE_HAS_H_DOUBLE he->v.h_double = *((double *)vector); #else he->v.h_vector=vector; #endif n->curr->next=he; n->curr=he; GLOBALS->regions+=regadd; } } else { #ifndef WAVE_HAS_H_DOUBLE free_2(vector); #endif } #ifdef WAVE_HAS_H_DOUBLE free_2(vector); #endif } break; } default: { if(!n->curr) { he=histent_calloc(); he->time=-1; he->v.h_vector=NULL; n->curr=he; n->head.next=he; add_histent(tim,n,ch,regadd, vector); } else { if(regadd) { tim*=(GLOBALS->time_scale); } if( (n->curr->v.h_vector&&vector&&(strcmp(n->curr->v.h_vector,vector))) ||(tim==GLOBALS->start_time_vcd_recoder_c_3) ||(!n->curr->v.h_vector) ||(GLOBALS->vcd_preserve_glitches) ) /* same region == go skip */ { if(n->curr->time==tim) { DEBUG(printf("Warning: Glitch at time ["TTFormat"] Signal [%p], Value [%c->%c].\n", tim, n, AN_STR[n->curr->v.h_val], ch)); if(n->curr->v.h_vector) free_2(n->curr->v.h_vector); n->curr->v.h_vector=vector; /* we have a glitch! */ GLOBALS->num_glitches_vcd_recoder_c_4++; if(!(n->curr->flags&HIST_GLITCH)) { n->curr->flags|=HIST_GLITCH; /* set the glitch flag */ GLOBALS->num_glitch_regions_vcd_recoder_c_4++; } } else { he=histent_calloc(); he->time=tim; he->v.h_vector=vector; n->curr->next=he; n->curr=he; GLOBALS->regions+=regadd; } } else { free_2(vector); } } break; } } } } /*******************************************************************************/ static void vcd_build_symbols(void) { int j; int max_slen=-1; struct sym_chain *sym_chain=NULL, *sym_curr=NULL; int duphier=0; char hashdirty; struct vcdsymbol *v, *vprime; char *str = wave_alloca(1); /* quiet scan-build null pointer warning below */ #ifdef _WAVE_HAVE_JUDY int ss_len, longest = 0; #endif v=GLOBALS->vcdsymroot_vcd_recoder_c_3; while(v) { int msi; int delta; { int slen; int substnode; msi=v->msi; delta=((v->lsi-v->msi)<0)?-1:1; substnode=0; slen=strlen(v->name); str=(slen>max_slen)?(wave_alloca((max_slen=slen)+32)):(str); /* more than enough */ strcpy(str,v->name); if(v->msi>=0) { strcpy(str+slen,GLOBALS->vcd_hier_delimeter); slen++; } if((vprime=bsearch_vcd(v->id, strlen(v->id)))!=v) /* hash mish means dup net */ { if(v->size!=vprime->size) { fprintf(stderr,"ERROR: Duplicate IDs with differing width: %s %s\n", v->name, vprime->name); } else { substnode=1; } } if((v->size==1)&&(v->vartype!=V_REAL)&&(v->vartype!=V_STRINGTYPE)) { struct symbol *s = NULL; for(j=0;jsize;j++) { if(v->msi>=0) { if(!GLOBALS->vcd_explicit_zero_subscripts) sprintf(str+slen,"%d",msi); else sprintf(str+slen-1,"[%d]",msi); } hashdirty=0; if(symfind(str, NULL)) { char *dupfix=(char *)malloc_2(max_slen+32); #ifndef _WAVE_HAVE_JUDY hashdirty=1; #endif DEBUG(fprintf(stderr,"Warning: %s is a duplicate net name.\n",str)); do sprintf(dupfix, "$DUP%d%s%s", duphier++, GLOBALS->vcd_hier_delimeter, str); while(symfind(dupfix, NULL)); strcpy(str, dupfix); free_2(dupfix); duphier=0; /* reset for next duplicate resolution */ } /* fallthrough */ { s=symadd(str,hashdirty?hash(str):GLOBALS->hashcache); #ifdef _WAVE_HAVE_JUDY ss_len = strlen(str); if(ss_len >= longest) { longest = ss_len + 1; } #endif s->n=v->narray[j]; if(substnode) { struct Node *n, *n2; n=s->n; n2=vprime->narray[j]; /* nname stays same */ /* n->head=n2->head; */ /* n->curr=n2->curr; */ n->curr=(hptr)n2; /* harray calculated later */ n->numhist=n2->numhist; } #ifndef _WAVE_HAVE_JUDY s->n->nname=s->name; #endif if(!GLOBALS->firstnode) { GLOBALS->firstnode= GLOBALS->curnode=calloc_2(1, sizeof(struct symchain)); } else { GLOBALS->curnode->next=calloc_2(1, sizeof(struct symchain)); GLOBALS->curnode=GLOBALS->curnode->next; } GLOBALS->curnode->symbol=s; GLOBALS->numfacs++; DEBUG(fprintf(stderr,"Added: %s\n",str)); } msi+=delta; } if((j==1)&&(v->root)) { s->vec_root=(struct symbol *)v->root; /* these will get patched over */ s->vec_chain=(struct symbol *)v->chain; /* these will get patched over */ v->sym_chain=s; if(!sym_chain) { sym_curr=(struct sym_chain *)calloc_2(1,sizeof(struct sym_chain)); sym_chain=sym_curr; } else { sym_curr->next=(struct sym_chain *)calloc_2(1,sizeof(struct sym_chain)); sym_curr=sym_curr->next; } sym_curr->val=s; } } else /* atomic vector */ { if((v->vartype!=V_REAL)&&(v->vartype!=V_STRINGTYPE)&&(v->vartype!=V_INTEGER)&&(v->vartype!=V_PARAMETER)) /* if((v->vartype!=V_REAL)&&(v->vartype!=V_STRINGTYPE)) */ { sprintf(str+slen-1,"[%d:%d]",v->msi,v->lsi); } else { *(str+slen-1)=0; } hashdirty=0; if(symfind(str, NULL)) { char *dupfix=(char *)malloc_2(max_slen+32); #ifndef _WAVE_HAVE_JUDY hashdirty=1; #endif DEBUG(fprintf(stderr,"Warning: %s is a duplicate net name.\n",str)); do sprintf(dupfix, "$DUP%d%s%s", duphier++, GLOBALS->vcd_hier_delimeter, str); while(symfind(dupfix, NULL)); strcpy(str, dupfix); free_2(dupfix); duphier=0; /* reset for next duplicate resolution */ } /* fallthrough */ { struct symbol *s; s=symadd(str,hashdirty?hash(str):GLOBALS->hashcache); /* cut down on double lookups.. */ #ifdef _WAVE_HAVE_JUDY ss_len = strlen(str); if(ss_len >= longest) { longest = ss_len + 1; } #endif s->n=v->narray[0]; if(substnode) { struct Node *n, *n2; n=s->n; n2=vprime->narray[0]; /* nname stays same */ /* n->head=n2->head; */ /* n->curr=n2->curr; */ n->curr=(hptr)n2; /* harray calculated later */ n->numhist=n2->numhist; n->extvals=n2->extvals; n->msi=n2->msi; n->lsi=n2->lsi; } else { s->n->msi=v->msi; s->n->lsi=v->lsi; s->n->extvals=1; } #ifndef _WAVE_HAVE_JUDY s->n->nname=s->name; #endif if(!GLOBALS->firstnode) { GLOBALS->firstnode= GLOBALS->curnode=calloc_2(1, sizeof(struct symchain)); } else { GLOBALS->curnode->next=calloc_2(1, sizeof(struct symchain)); GLOBALS->curnode=GLOBALS->curnode->next; } GLOBALS->curnode->symbol=s; GLOBALS->numfacs++; DEBUG(fprintf(stderr,"Added: %s\n",str)); } } } v=v->next; } #ifdef _WAVE_HAVE_JUDY { Pvoid_t PJArray = GLOBALS->sym_judy; PPvoid_t PPValue; char *Index = calloc_2(1, longest); for (PPValue = JudySLFirst (PJArray, (uint8_t *)Index, PJE0); PPValue != (PPvoid_t) NULL; PPValue = JudySLNext (PJArray, (uint8_t *)Index, PJE0)) { struct symbol *s = *(struct symbol **)PPValue; s->name = strdup_2(Index); s->n->nname = s->name; } free_2(Index); } #endif if(sym_chain) { sym_curr=sym_chain; while(sym_curr) { sym_curr->val->vec_root= ((struct vcdsymbol *)sym_curr->val->vec_root)->sym_chain; if ((struct vcdsymbol *)sym_curr->val->vec_chain) sym_curr->val->vec_chain=((struct vcdsymbol *)sym_curr->val->vec_chain)->sym_chain; DEBUG(printf("Link: ('%s') '%s' -> '%s'\n",sym_curr->val->vec_root->name, sym_curr->val->name, sym_curr->val->vec_chain?sym_curr->val->vec_chain->name:"(END)")); sym_chain=sym_curr; sym_curr=sym_curr->next; free_2(sym_chain); } } } /*******************************************************************************/ static void vcd_cleanup(void) { struct slist *s, *s2; struct vcdsymbol *v, *vt; if(GLOBALS->indexed_vcd_recoder_c_3) { free_2(GLOBALS->indexed_vcd_recoder_c_3); GLOBALS->indexed_vcd_recoder_c_3=NULL; } if(GLOBALS->sorted_vcd_recoder_c_3) { free_2(GLOBALS->sorted_vcd_recoder_c_3); GLOBALS->sorted_vcd_recoder_c_3=NULL; } v=GLOBALS->vcdsymroot_vcd_recoder_c_3; while(v) { if(v->name) free_2(v->name); if(v->id) free_2(v->id); if(v->narray) free_2(v->narray); vt=v; v=v->next; free_2(vt); } GLOBALS->vcdsymroot_vcd_recoder_c_3=GLOBALS->vcdsymcurr_vcd_recoder_c_3=NULL; if(GLOBALS->slisthier) { free_2(GLOBALS->slisthier); GLOBALS->slisthier=NULL; } s=GLOBALS->slistroot; while(s) { s2=s->next; if(s->str)free_2(s->str); free_2(s); s=s2; } GLOBALS->slistroot=GLOBALS->slistcurr=NULL; GLOBALS->slisthier_len=0; if(GLOBALS->vcd_is_compressed_vcd_recoder_c_2) { pclose(GLOBALS->vcd_handle_vcd_recoder_c_2); GLOBALS->vcd_handle_vcd_recoder_c_2 = NULL; } else { fclose(GLOBALS->vcd_handle_vcd_recoder_c_2); GLOBALS->vcd_handle_vcd_recoder_c_2 = NULL; } if(GLOBALS->yytext_vcd_recoder_c_3) { free_2(GLOBALS->yytext_vcd_recoder_c_3); GLOBALS->yytext_vcd_recoder_c_3=NULL; } } /*******************************************************************************/ TimeType vcd_recoder_main(char *fname) { unsigned int finalize_cnt = 0; #ifdef HAVE_SYS_STAT_H struct stat mystat; int stat_rc = stat(fname, &mystat); #endif GLOBALS->pv_vcd_recoder_c_3=GLOBALS->rootv_vcd_recoder_c_3=NULL; GLOBALS->vcd_hier_delimeter[0]=GLOBALS->hier_delimeter; if(GLOBALS->use_fastload) { char *ffname = malloc_2(strlen(fname) + 4 + 1); sprintf(ffname, "%s.idx", fname); GLOBALS->vlist_handle = fopen(ffname, "rb"); if(GLOBALS->vlist_handle) { GLOBALS->use_fastload = VCD_FSL_READ; /* need to do a sanity check looking for time of vcd file vs recoder file, etc. */ #ifdef HAVE_SYS_STAT_H if( (stat_rc) || (!read_fastload_header(&mystat)) ) #else if(!read_fastload_header()) #endif { GLOBALS->use_fastload = VCD_FSL_WRITE; fclose(GLOBALS->vlist_handle); GLOBALS->vlist_handle = NULL; } } else { GLOBALS->use_fastload = VCD_FSL_WRITE; } free_2(ffname); } errno=0; /* reset in case it's set for some reason */ GLOBALS->yytext_vcd_recoder_c_3=(char *)malloc_2(GLOBALS->T_MAX_STR_vcd_recoder_c_3+1); if(!GLOBALS->hier_was_explicitly_set) /* set default hierarchy split char */ { GLOBALS->hier_delimeter='.'; } if(suffix_check(fname, ".gz") || suffix_check(fname, ".zip")) { char *str; int dlen; dlen=strlen(WAVE_DECOMPRESSOR); str=wave_alloca(strlen(fname)+dlen+1); strcpy(str,WAVE_DECOMPRESSOR); strcpy(str+dlen,fname); GLOBALS->vcd_handle_vcd_recoder_c_2=popen(str,"r"); GLOBALS->vcd_is_compressed_vcd_recoder_c_2=~0; } else { if(strcmp("-vcd",fname)) { GLOBALS->vcd_handle_vcd_recoder_c_2=fopen(fname,"rb"); if(GLOBALS->vcd_handle_vcd_recoder_c_2) { fseeko(GLOBALS->vcd_handle_vcd_recoder_c_2, 0, SEEK_END); /* do status bar for vcd load */ GLOBALS->vcd_fsiz_vcd_recoder_c_2 = ftello(GLOBALS->vcd_handle_vcd_recoder_c_2); fseeko(GLOBALS->vcd_handle_vcd_recoder_c_2, 0, SEEK_SET); } if(GLOBALS->vcd_warning_filesize < 0) GLOBALS->vcd_warning_filesize = VCD_SIZE_WARN; if(GLOBALS->vcd_warning_filesize) if(GLOBALS->vcd_fsiz_vcd_recoder_c_2 > (GLOBALS->vcd_warning_filesize * (1024 * 1024))) { if(!GLOBALS->vlist_prepack) { fprintf(stderr, "Warning! File size is %d MB. This might fail in recoding.\n" "Consider converting it to the FST database format instead. (See the\n" "vcd2fst(1) manpage for more information.)\n" "To disable this warning, set rc variable vcd_warning_filesize to zero.\n" "Alternatively, use the -o, --optimize command line option to convert to FST\n" "or the -g, --giga command line option to use dynamically compressed memory.\n\n", (int)(GLOBALS->vcd_fsiz_vcd_recoder_c_2/(1024*1024))); } else { fprintf(stderr, "VCDLOAD | File size is %d MB, using vlist prepacking%s.\n\n", (int)(GLOBALS->vcd_fsiz_vcd_recoder_c_2/(1024*1024)), GLOBALS->vlist_spill_to_disk ? " and spill file" : ""); } } } else { GLOBALS->splash_disable = 1; GLOBALS->vcd_handle_vcd_recoder_c_2=stdin; } GLOBALS->vcd_is_compressed_vcd_recoder_c_2=0; } if(!GLOBALS->vcd_handle_vcd_recoder_c_2) { fprintf(stderr, "Error opening %s .vcd file '%s'.\n", GLOBALS->vcd_is_compressed_vcd_recoder_c_2?"compressed":"", fname); perror("Why"); vcd_exit(255); } /* SPLASH */ splash_create(); sym_hash_initialize(GLOBALS); getch_alloc(); /* alloc membuff for vcd getch buffer */ build_slisthier(); GLOBALS->time_vlist_vcd_recoder_c_1 = vlist_create(sizeof(TimeType)); if(GLOBALS->use_fastload == VCD_FSL_WRITE) { GLOBALS->time_vlist_vcd_recoder_write = ((struct vlist_t *)vlist_packer_create()); } if((GLOBALS->vlist_spill_to_disk) && (GLOBALS->use_fastload != VCD_FSL_READ)) { vlist_init_spillfile(); } vcd_parse(); if(GLOBALS->varsplit_vcd_recoder_c_3) { free_2(GLOBALS->varsplit_vcd_recoder_c_3); GLOBALS->varsplit_vcd_recoder_c_3=NULL; } if(GLOBALS->vlist_handle) { FILE *vh = GLOBALS->vlist_handle; GLOBALS->vlist_handle = NULL; vlist_freeze(&GLOBALS->time_vlist_vcd_recoder_c_1); GLOBALS->vlist_handle = vh; } else { vlist_freeze(&GLOBALS->time_vlist_vcd_recoder_c_1); } if(GLOBALS->time_vlist_vcd_recoder_write) { write_fastload_time_section(); } if(GLOBALS->use_fastload != VCD_FSL_READ) { finalize_cnt = vlist_emit_finalize(); } if(GLOBALS->time_vlist_vcd_recoder_write) { #ifdef HAVE_SYS_STAT_H write_fastload_header(&mystat, finalize_cnt); #else write_fastload_header(finalize_cnt); #endif } if((!GLOBALS->sorted_vcd_recoder_c_3)&&(!GLOBALS->indexed_vcd_recoder_c_3)) { fprintf(stderr, "No symbols in VCD file..is it malformed? Exiting!\n"); vcd_exit(255); } if(GLOBALS->vcd_save_handle) { fclose(GLOBALS->vcd_save_handle); GLOBALS->vcd_save_handle = NULL; } fprintf(stderr, "["TTFormat"] start time.\n["TTFormat"] end time.\n", GLOBALS->start_time_vcd_recoder_c_3*GLOBALS->time_scale, GLOBALS->end_time_vcd_recoder_c_3*GLOBALS->time_scale); if(GLOBALS->vcd_fsiz_vcd_recoder_c_2) { splash_sync(GLOBALS->vcd_fsiz_vcd_recoder_c_2, GLOBALS->vcd_fsiz_vcd_recoder_c_2); GLOBALS->vcd_fsiz_vcd_recoder_c_2 = 0; } else if(GLOBALS->vcd_is_compressed_vcd_recoder_c_2) { splash_sync(1,1); GLOBALS->vcd_fsiz_vcd_recoder_c_2 = 0; } GLOBALS->min_time=GLOBALS->start_time_vcd_recoder_c_3*GLOBALS->time_scale; GLOBALS->max_time=GLOBALS->end_time_vcd_recoder_c_3*GLOBALS->time_scale; GLOBALS->global_time_offset = GLOBALS->global_time_offset * GLOBALS->time_scale; if((GLOBALS->min_time==GLOBALS->max_time)&&(GLOBALS->max_time==LLDescriptor(-1))) { fprintf(stderr, "VCD times range is equal to zero. Exiting.\n"); vcd_exit(255); } vcd_build_symbols(); vcd_sortfacs(); vcd_cleanup(); getch_free(); /* free membuff for vcd getch buffer */ if(GLOBALS->blackout_regions) { struct blackout_region_t *bt = GLOBALS->blackout_regions; while(bt) { bt->bstart *= GLOBALS->time_scale; bt->bend *= GLOBALS->time_scale; bt = bt->next; } } /* is_vcd=~0; */ GLOBALS->is_lx2 = LXT2_IS_VLIST; /* SPLASH */ splash_finalize(); return(GLOBALS->max_time); } /*******************************************************************************/ void vcd_import_masked(void) { /* nothing */ } void vcd_set_fac_process_mask(nptr np) { if(np && np->mv.mvlfac_vlist) { import_vcd_trace(np); } } #define vlist_locate_import(x,y) ((GLOBALS->vlist_prepack) ? ((depacked) + (y)) : vlist_locate((x),(y))) void import_vcd_trace(nptr np) { struct vlist_t *v = np->mv.mvlfac_vlist; int len = 1; unsigned int list_size; unsigned char vlist_type; /* unsigned int vartype = 0; */ /* scan-build */ unsigned int vlist_pos = 0; unsigned char *chp; unsigned int time_idx = 0; TimeType *curtime_pnt; unsigned char arr[5]; int arr_pos; unsigned int accum; unsigned char ch; double *d; unsigned char *depacked = NULL; if(!v) return; vlist_uncompress(&v); if(GLOBALS->vlist_prepack) { depacked = vlist_packer_decompress(v, &list_size); vlist_destroy(v); } else { list_size=vlist_size(v); } if(!list_size) { len = 1; vlist_type = '!'; /* possible alias */ } else { chp = vlist_locate_import(v, vlist_pos++); if(chp) { switch((vlist_type = (*chp & 0x7f))) { case '0': len = 1; chp = vlist_locate_import(v, vlist_pos++); if(!chp) { fprintf(stderr, "Internal error file '%s' line %d, exiting.\n", __FILE__, __LINE__); exit(255); } /* vartype = (unsigned int)(*chp & 0x7f); */ /*scan-build */ break; case 'B': case 'R': case 'S': chp = vlist_locate_import(v, vlist_pos++); if(!chp) { fprintf(stderr, "Internal error file '%s' line %d, exiting.\n", __FILE__, __LINE__); exit(255); } /* vartype = (unsigned int)(*chp & 0x7f); */ /* scan-build */ arr_pos = accum = 0; do { chp = vlist_locate_import(v, vlist_pos++); if(!chp) break; ch = *chp; arr[arr_pos++] = ch; } while (!(ch & 0x80)); for(--arr_pos; arr_pos>=0; arr_pos--) { ch = arr[arr_pos]; accum <<= 7; accum |= (unsigned int)(ch & 0x7f); } len = accum; break; default: fprintf(stderr, "Unsupported vlist type '%c', exiting.", vlist_type); vcd_exit(255); break; } } else { len = 1; vlist_type = '!'; /* possible alias */ } } if(vlist_type == '0') /* single bit */ { while(vlist_pos < list_size) { unsigned int delta, bitval; char ascval; arr_pos = accum = 0; do { chp = vlist_locate_import(v, vlist_pos++); if(!chp) break; ch = *chp; arr[arr_pos++] = ch; } while (!(ch & 0x80)); for(--arr_pos; arr_pos>=0; arr_pos--) { ch = arr[arr_pos]; accum <<= 7; accum |= (unsigned int)(ch & 0x7f); } if(!(accum&1)) { delta = accum >> 2; bitval = (accum >> 1) & 1; ascval = '0' + bitval; } else { delta = accum >> 4; bitval = (accum >> 1) & 7; ascval = RCV_STR[bitval]; } time_idx += delta; curtime_pnt = vlist_locate(GLOBALS->time_vlist_vcd_recoder_c_1, time_idx ? time_idx-1 : 0); if(!curtime_pnt) { fprintf(stderr, "GTKWAVE | malformed bitwise signal data for '%s' after time_idx = %d\n", np->nname, time_idx - delta); exit(255); } add_histent(*curtime_pnt,np,ascval,1, NULL); } add_histent(MAX_HISTENT_TIME-1, np, 'x', 0, NULL); add_histent(MAX_HISTENT_TIME, np, 'z', 0, NULL); } else if(vlist_type == 'B') /* bit vector, port type was converted to bit vector already */ { char *sbuf = malloc_2(len+1); int dst_len; char *vector; while(vlist_pos < list_size) { unsigned int delta; arr_pos = accum = 0; do { chp = vlist_locate_import(v, vlist_pos++); if(!chp) break; ch = *chp; arr[arr_pos++] = ch; } while (!(ch & 0x80)); for(--arr_pos; arr_pos>=0; arr_pos--) { ch = arr[arr_pos]; accum <<= 7; accum |= (unsigned int)(ch & 0x7f); } delta = accum; time_idx += delta; curtime_pnt = vlist_locate(GLOBALS->time_vlist_vcd_recoder_c_1, time_idx ? time_idx-1 : 0); if(!curtime_pnt) { fprintf(stderr, "GTKWAVE | malformed 'b' signal data for '%s' after time_idx = %d\n", np->nname, time_idx - delta); exit(255); } dst_len = 0; for(;;) { chp = vlist_locate_import(v, vlist_pos++); if(!chp) break; ch = *chp; if((ch >> 4) == AN_MSK) break; if(dst_len == len) { if(len != 1) memmove(sbuf, sbuf+1, dst_len - 1); dst_len--; } sbuf[dst_len++] = AN_STR[ch >> 4]; if((ch & AN_MSK) == AN_MSK) break; if(dst_len == len) { if(len != 1) memmove(sbuf, sbuf+1, dst_len - 1); dst_len--; } sbuf[dst_len++] = AN_STR[ch & AN_MSK]; } if(len == 1) { add_histent(*curtime_pnt, np,sbuf[0],1, NULL); } else { vector = malloc_2(len+1); if(dst_len < len) { unsigned char extend=(sbuf[0]=='1')?'0':sbuf[0]; memset(vector, extend, len - dst_len); memcpy(vector + (len - dst_len), sbuf, dst_len); } else { memcpy(vector, sbuf, len); } vector[len] = 0; add_histent(*curtime_pnt, np,0,1,vector); } } if(len==1) { add_histent(MAX_HISTENT_TIME-1, np, 'x', 0, NULL); add_histent(MAX_HISTENT_TIME, np, 'z', 0, NULL); } else { add_histent(MAX_HISTENT_TIME-1, np, 'x', 0, (char *)calloc_2(1,sizeof(char))); add_histent(MAX_HISTENT_TIME, np, 'z', 0, (char *)calloc_2(1,sizeof(char))); } free_2(sbuf); } else if(vlist_type == 'R') /* real */ { char *sbuf = malloc_2(64); int dst_len; char *vector; while(vlist_pos < list_size) { unsigned int delta; arr_pos = accum = 0; do { chp = vlist_locate_import(v, vlist_pos++); if(!chp) break; ch = *chp; arr[arr_pos++] = ch; } while (!(ch & 0x80)); for(--arr_pos; arr_pos>=0; arr_pos--) { ch = arr[arr_pos]; accum <<= 7; accum |= (unsigned int)(ch & 0x7f); } delta = accum; time_idx += delta; curtime_pnt = vlist_locate(GLOBALS->time_vlist_vcd_recoder_c_1, time_idx ? time_idx-1 : 0); if(!curtime_pnt) { fprintf(stderr, "GTKWAVE | malformed 'r' signal data for '%s' after time_idx = %d\n", np->nname, time_idx - delta); exit(255); } dst_len = 0; do { chp = vlist_locate_import(v, vlist_pos++); if(!chp) break; ch = *chp; sbuf[dst_len++] = ch; } while(ch); vector=malloc_2(sizeof(double)); sscanf(sbuf,"%lg",(double *)vector); add_histent(*curtime_pnt, np,'g',1,(char *)vector); } d=malloc_2(sizeof(double)); *d=1.0; add_histent(MAX_HISTENT_TIME-1, np, 'g', 0, (char *)d); d=malloc_2(sizeof(double)); *d=0.0; add_histent(MAX_HISTENT_TIME, np, 'g', 0, (char *)d); free_2(sbuf); } else if(vlist_type == 'S') /* string */ { char *sbuf = malloc_2(list_size); /* being conservative */ int dst_len; char *vector; while(vlist_pos < list_size) { unsigned int delta; arr_pos = accum = 0; do { chp = vlist_locate_import(v, vlist_pos++); if(!chp) break; ch = *chp; arr[arr_pos++] = ch; } while (!(ch & 0x80)); for(--arr_pos; arr_pos>=0; arr_pos--) { ch = arr[arr_pos]; accum <<= 7; accum |= (unsigned int)(ch & 0x7f); } delta = accum; time_idx += delta; curtime_pnt = vlist_locate(GLOBALS->time_vlist_vcd_recoder_c_1, time_idx ? time_idx-1 : 0); if(!curtime_pnt) { fprintf(stderr, "GTKWAVE | malformed 's' signal data for '%s' after time_idx = %d\n", np->nname, time_idx - delta); exit(255); } dst_len = 0; do { chp = vlist_locate_import(v, vlist_pos++); if(!chp) break; ch = *chp; sbuf[dst_len++] = ch; } while(ch); vector=malloc_2(dst_len + 1); strcpy(vector, sbuf); add_histent(*curtime_pnt, np,'s',1,(char *)vector); } d=malloc_2(sizeof(double)); *d=1.0; add_histent(MAX_HISTENT_TIME-1, np, 'g', 0, (char *)d); d=malloc_2(sizeof(double)); *d=0.0; add_histent(MAX_HISTENT_TIME, np, 'g', 0, (char *)d); free_2(sbuf); } else if(vlist_type == '!') /* error in loading */ { nptr n2 = (nptr)np->curr; if((n2)&&(n2 != np)) /* keep out any possible infinite recursion from corrupt pointer bugs */ { import_vcd_trace(n2); if(GLOBALS->vlist_prepack) { vlist_packer_decompress_destroy((char *)depacked); } else { vlist_destroy(v); } np->mv.mvlfac_vlist = NULL; np->head = n2->head; np->curr = n2->curr; return; } fprintf(stderr, "Error in decompressing vlist for '%s', exiting.\n", np->nname); vcd_exit(255); } if(GLOBALS->vlist_prepack) { vlist_packer_decompress_destroy((char *)depacked); } else { vlist_destroy(v); } np->mv.mvlfac_vlist = NULL; } gtkwave-3.3.66/src/baseconvert.c0000664000076400007640000010357712341266475016074 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2014. * * 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. */ #include "globals.h" #include #include #include #include "gtk12compat.h" #include "currenttime.h" #include "pixmaps.h" #include "symbol.h" #include "bsearch.h" #include "color.h" #include "strace.h" #include "debug.h" #include "translate.h" #include "ptranslate.h" #include "ttranslate.h" #include "pipeio.h" #ifdef _MSC_VER #define strcasecmp _stricmp #endif /* * convert binary <=> gray/popcnt in place */ #define cvt_gray(f,p,n) \ do { \ if((f)&(TR_GRAYMASK|TR_POPCNT)) \ { \ if((f)&TR_BINGRAY) { convert_bingray((p),(n)); } \ if((f)&TR_GRAYBIN) { convert_graybin((p),(n)); } \ if((f)&TR_POPCNT) { convert_popcnt((p),(n)); } \ } \ } while(0) static void convert_graybin(char *pnt, int nbits) { char kill_state = 0; char pch = AN_0; int i; for(i=0;i=0;i--) /* always requires less number of bits */ { pnt[i] = (pop & 1) ? AN_1 : AN_0; pop >>= 1; } } /* * convert trptr+vptr into an ascii string */ static char *convert_ascii_2(Trptr t, vptr v) { Ulong flags; int nbits; unsigned char *bits; char *os, *pnt, *newbuff; int i, j, len; static const char xfwd[AN_COUNT]= AN_NORMAL ; static const char xrev[AN_COUNT]= AN_INVERSE ; const char *xtab; flags=t->flags; nbits=t->n.vec->nbits; bits=v->v; if(flags&TR_INVERT) { xtab = xrev; } else { xtab = xfwd; } if(flags&(TR_ZEROFILL|TR_ONEFILL)) { char whichfill = (flags&TR_ZEROFILL) ? AN_0 : AN_1; int msi = 0, lsi = 0, ok = 0; if((t->name)&&(nbits > 1)) { char *lbrack = strrchr(t->name, '['); if(lbrack) { int rc = sscanf(lbrack+1, "%d:%d", &msi, &lsi); if(rc == 2) { if(((msi - lsi + 1) == nbits) || ((lsi - msi + 1) == nbits)) { ok = 1; /* to ensure sanity... */ } } } } if(ok) { if(msi > lsi) { if(lsi > 0) { pnt=wave_alloca(msi + 1); memcpy(pnt, bits, nbits); for(i=nbits;i 0) { pnt=wave_alloca(lsi + 1); for(i=0;ishow_base) { *(pnt++)='"'; } parse=(flags&TR_RJUSTIFY)?(newbuff+((nbits+3)&3)):(newbuff+3); cvt_gray(flags,parse,nbits); for(i=0;i 0x7f || !isprint(val)) *pnt++ = '.'; else *pnt++ = val; found=1; } parse+=8; } if (!found && !GLOBALS->show_base) { *(pnt++)='"'; *(pnt++)='"'; } if(GLOBALS->show_base) { *(pnt++)='"'; } *(pnt)=0x00; /* scan build : remove dead increment */ } else if((flags&TR_HEX)||((flags&(TR_DEC|TR_SIGNED))&&(nbits>64)&&(!(flags&TR_POPCNT)))) { char *parse; len=(nbits/4)+2+1; /* $xxxxx */ os=pnt=(char *)calloc_2(1,len); if(GLOBALS->show_base) { *(pnt++)='$'; } parse=(flags&TR_RJUSTIFY)?(newbuff+((nbits+3)&3)):(newbuff+3); cvt_gray(flags,parse,nbits); for(i=0;i= 0) match = 0; break; } } val = (match) ? 16 : 21; break; } else if(parse[j]==AN_Z) { int xover = 0; int match = (j==0) || ((parse + i + j) == (newbuff + 3)); int k; for(k=j+1;k<4;k++) { if(parse[k]!=AN_Z) { if(parse[k]==AN_X) { xover = 1; } else { char *thisbyt = parse + i + k; char *lastbyt = newbuff + 3 + nbits - 1; if((lastbyt - thisbyt) >= 0) match = 0; } break; } } if(xover) val = 21; else val = (match) ? 17 : 22; break; } else if(parse[j]==AN_W) { int xover = 0; int match = (j==0) || ((parse + i + j) == (newbuff + 3)); int k; for(k=j+1;k<4;k++) { if(parse[k]!=AN_W) { if(parse[k]==AN_X) { xover = 1; } else { char *thisbyt = parse + i + k; char *lastbyt = newbuff + 3 + nbits - 1; if((lastbyt - thisbyt) >= 0) match = 0; } break; } } if(xover) val = 21; else val = (match) ? 18 : 23; break; } else if(parse[j]==AN_U) { int xover = 0; int match = (j==0) || ((parse + i + j) == (newbuff + 3)); int k; for(k=j+1;k<4;k++) { if(parse[k]!=AN_U) { if(parse[k]==AN_X) { xover = 1; } else { char *thisbyt = parse + i + k; char *lastbyt = newbuff + 3 + nbits - 1; if((lastbyt - thisbyt) >= 0) match = 0; } break; } } if(xover) val = 21; else val = (match) ? 19 : 24; break; } else if(parse[j]==AN_DASH) { int xover = 0; int k; for(k=j+1;k<4;k++) { if(parse[k]!=AN_DASH) { if(parse[k]==AN_X) { xover = 1; } break; } } if(xover) val = 21; else val = 20; break; } } *(pnt++)=AN_HEX_STR[val]; parse+=4; } *(pnt)=0x00; /* scan build : remove dead increment */ } else if(flags&TR_OCT) { char *parse; len=(nbits/3)+2+1; /* #xxxxx */ os=pnt=(char *)calloc_2(1,len); if(GLOBALS->show_base) { *(pnt++)='#'; } parse=(flags&TR_RJUSTIFY) ?(newbuff+((nbits%3)?(nbits%3):3)) :(newbuff+3); cvt_gray(flags,parse,nbits); for(i=0;ishow_base) { *(pnt++)='%'; } parse=newbuff+3; cvt_gray(flags,parse,nbits); for(i=0;ishow_base) { *(pnt++)='%'; } parse=newbuff+3; cvt_gray(flags,parse,nbits); for(i=0;iflags & TR_REAL2BITS) && d) /* "real2bits" also allows other filters such as "bits2real" on top of it */ { struct TraceEnt t2; char vec[64]; int i; guint64 swapmem; memcpy(&swapmem, d, sizeof(guint64)); for(i=0;i<64;i++) { if(swapmem & (ULLDescriptor(1)<<(63-i))) { vec[i] = AN_1; } else { vec[i] = AN_0; } } memcpy(&t2, t, sizeof(struct TraceEnt)); t2.n.nd->msi = 63; t2.n.nd->lsi = 0; t2.flags &= ~(TR_REAL2BITS); /* to avoid possible recursion in the future */ rv = convert_ascii_vec_2(&t2, vec); } else { rv=malloc_2(24); /* enough for .16e format */ if(d) { sprintf(rv,"%.16g",*d); } else { strcpy(rv,"UNDEF"); } } return(rv); } char *convert_ascii_string(char *s) { char *rv; if(s) { rv=(char *)malloc_2(strlen(s)+1); strcpy(rv, s); } else { rv=(char *)malloc_2(6); strcpy(rv, "UNDEF"); } return(rv); } int vtype(Trptr t, char *vec) { int i, nbits, res; int an_u_encountered = 0; if (vec == NULL) return(AN_X); nbits=t->n.nd->msi-t->n.nd->lsi; if(nbits<0)nbits=-nbits; nbits++; res = AN_1; for (i = 0; i < nbits; i++) { switch (*vec) { case AN_X: case 'x': case 'X': return(AN_X); case AN_U: case 'u': case 'U': an_u_encountered = 1; break; case AN_Z: case 'z': case 'Z': if (res == AN_0) return(AN_X); vec++; res = AN_Z; break; default: if (res == AN_Z) return(AN_X); vec++; res = AN_0; break; } } return(!an_u_encountered ? res : AN_U); } int vtype2(Trptr t, vptr v) { int i, nbits, res; int an_u_encountered = 0; char *vec=(char *)v->v; if(!t->t_filter_converted) { if (vec == NULL) return(AN_X); } else { return ( ((vec == NULL) || (vec[0] == 0)) ? AN_Z : AN_0 ); } nbits=t->n.vec->nbits; res = AN_1; for (i = 0; i < nbits; i++) { switch (*vec) { case AN_X: case 'x': case 'X': return(AN_X); case AN_U: case 'u': case 'U': an_u_encountered = 1; break; case AN_Z: case 'z': case 'Z': if (res == AN_0) return(AN_X); vec++; res = AN_Z; break; default: if (res == AN_Z) return(AN_X); vec++; res = AN_0; break; } } return(!an_u_encountered ? res : AN_U); } /* * convert trptr+hptr vectorstring into an ascii string */ char *convert_ascii_vec_2(Trptr t, char *vec) { Ulong flags; int nbits; char *bits; char *os, *pnt, *newbuff; int i, j, len; const char *xtab; static const char xfwd[AN_COUNT]= AN_NORMAL ; static const char xrev[AN_COUNT]= AN_INVERSE ; flags=t->flags; nbits=t->n.nd->msi-t->n.nd->lsi; if(nbits<0)nbits=-nbits; nbits++; if(vec) { bits=vec; if(*vec>AN_MSK) /* convert as needed */ for(i=0;i1)&&(t->n.nd->msi)&&(t->n.nd->lsi)) { char whichfill = (flags&TR_ZEROFILL) ? AN_0 : AN_1; if(t->n.nd->msi > t->n.nd->lsi) { if(t->n.nd->lsi > 0) { pnt=wave_alloca(t->n.nd->msi + 1); memcpy(pnt, bits, nbits); for(i=nbits;in.nd->msi+1;i++) { pnt[i]=whichfill; } bits = pnt; nbits = t->n.nd->msi + 1; } } else { if(t->n.nd->msi > 0) { pnt=wave_alloca(t->n.nd->lsi + 1); for(i=0;in.nd->msi;i++) { pnt[i]=whichfill; } memcpy(pnt+i, bits, nbits); bits = pnt; nbits = t->n.nd->lsi + 1; } } } if(flags&TR_INVERT) { xtab = xrev; } else { xtab = xfwd; } newbuff=(char *)malloc_2(nbits+6); /* for justify */ if(flags&TR_REVERSE) { char *fwdpnt, *revpnt; fwdpnt=bits; revpnt=newbuff+nbits+6; /* for(i=0;i<3;i++) *(--revpnt)=xtab[0]; */ for(i=0;i<3;i++) *(--revpnt)=xfwd[0]; for(i=0;ishow_base) { *(pnt++)='"'; } parse=(flags&TR_RJUSTIFY)?(newbuff+((nbits+3)&3)):(newbuff+3); cvt_gray(flags,parse,nbits); for(i=0;i 0x7f || !isprint(val)) *pnt++ = '.'; else *pnt++ = val; found=1; } parse+=8; } if (!found && !GLOBALS->show_base) { *(pnt++)='"'; *(pnt++)='"'; } if(GLOBALS->show_base) { *(pnt++)='"'; } *(pnt)=0x00; /* scan build : remove dead increment */ } else if((flags&TR_HEX)||((flags&(TR_DEC|TR_SIGNED))&&(nbits>64)&&(!(flags&TR_POPCNT)))) { char *parse; len=(nbits/4)+2+1; /* $xxxxx */ os=pnt=(char *)calloc_2(1,len); if(GLOBALS->show_base) { *(pnt++)='$'; } parse=(flags&TR_RJUSTIFY)?(newbuff+((nbits+3)&3)):(newbuff+3); cvt_gray(flags,parse,nbits); for(i=0;i= 0) match = 0; break; } } val = (match) ? 16 : 21; break; } else if(parse[j]==AN_Z) { int xover = 0; int match = (j==0) || ((parse + i + j) == (newbuff + 3)); int k; for(k=j+1;k<4;k++) { if(parse[k]!=AN_Z) { if(parse[k]==AN_X) { xover = 1; } else { char *thisbyt = parse + i + k; char *lastbyt = newbuff + 3 + nbits - 1; if((lastbyt - thisbyt) >= 0) match = 0; } break; } } if(xover) val = 21; else val = (match) ? 17 : 22; break; } else if(parse[j]==AN_W) { int xover = 0; int match = (j==0) || ((parse + i + j) == (newbuff + 3)); int k; for(k=j+1;k<4;k++) { if(parse[k]!=AN_W) { if(parse[k]==AN_X) { xover = 1; } else { char *thisbyt = parse + i + k; char *lastbyt = newbuff + 3 + nbits - 1; if((lastbyt - thisbyt) >= 0) match = 0; } break; } } if(xover) val = 21; else val = (match) ? 18 : 23; break; } else if(parse[j]==AN_U) { int xover = 0; int match = (j==0) || ((parse + i + j) == (newbuff + 3)); int k; for(k=j+1;k<4;k++) { if(parse[k]!=AN_U) { if(parse[k]==AN_X) { xover = 1; } else { char *thisbyt = parse + i + k; char *lastbyt = newbuff + 3 + nbits - 1; if((lastbyt - thisbyt) >= 0) match = 0; } break; } } if(xover) val = 21; else val = (match) ? 19 : 24; break; } else if(parse[j]==AN_DASH) { int xover = 0; int k; for(k=j+1;k<4;k++) { if(parse[k]!=AN_DASH) { if(parse[k]==AN_X) { xover = 1; } break; } } if(xover) val = 21; else val = 20; break; } } *(pnt++)=AN_HEX_STR[val]; parse+=4; } *(pnt)=0x00; /* scan build : remove dead increment */ } else if(flags&TR_OCT) { char *parse; len=(nbits/3)+2+1; /* #xxxxx */ os=pnt=(char *)calloc_2(1,len); if(GLOBALS->show_base) { *(pnt++)='#'; } parse=(flags&TR_RJUSTIFY) ?(newbuff+((nbits%3)?(nbits%3):3)) :(newbuff+3); cvt_gray(flags,parse,nbits); for(i=0;ishow_base) { *(pnt++)='%'; } parse=newbuff+3; cvt_gray(flags,parse,nbits); for(i=0;ishow_base) { *(pnt++)='%'; } parse=newbuff+3; cvt_gray(flags,parse,nbits); for(i=0;ixl_file_filter[t->f_filter] = xl_splay(s, GLOBALS->xl_file_filter[t->f_filter]); if(!strcasecmp(s, GLOBALS->xl_file_filter[t->f_filter]->item)) { free_2(s); s = malloc_2(strlen(GLOBALS->xl_file_filter[t->f_filter]->trans) + 1); strcpy(s, GLOBALS->xl_file_filter[t->f_filter]->trans); } if((*s == '?') && (!GLOBALS->color_active_in_filter)) { char *s2a; char *s2 = strchr(s+1, '?'); if(s2) { s2++; s2a = malloc_2(strlen(s2)+1); strcpy(s2a, s2); free_2(s); s = s2a; } } return(s); } static char *pdofilter(Trptr t, char *s) { struct pipe_ctx *p = GLOBALS->proc_filter[t->p_filter]; char buf[1025]; int n; if(p) { #if !defined _MSC_VER && !defined __MINGW32__ fputs(s, p->sout); fputc('\n', p->sout); fflush(p->sout); buf[0] = 0; n = fgets(buf, 1024, p->sin) ? strlen(buf) : 0; buf[n] = 0; #else { BOOL bSuccess; DWORD dwWritten, dwRead; WriteFile(p->g_hChildStd_IN_Wr, s, strlen(s), &dwWritten, NULL); WriteFile(p->g_hChildStd_IN_Wr, "\n", 1, &dwWritten, NULL); for(n=0;n<1024;n++) { do { bSuccess = ReadFile(p->g_hChildStd_OUT_Rd, buf+n, 1, &dwRead, NULL); if((!bSuccess)||(buf[n]=='\n')) { goto ex; } } while(buf[n]=='\r'); } ex: buf[n] = 0; } #endif if(n) { if(buf[n-1] == '\n') { buf[n-1] = 0; n--; } } if(buf[0]) { free_2(s); s = malloc_2(n + 1); strcpy(s, buf); } } if((*s == '?') && (!GLOBALS->color_active_in_filter)) { char *s2a; char *s2 = strchr(s+1, '?'); if(s2) { s2++; s2a = malloc_2(strlen(s2)+1); strcpy(s2a, s2); free_2(s); s = s2a; } } return(s); } char *convert_ascii_vec(Trptr t, char *vec) { char *s = convert_ascii_vec_2(t, vec); if(!(t->f_filter|t->p_filter)) { } else { if(t->f_filter) { s = dofilter(t, s); } else { s = pdofilter(t, s); } } return(s); } char *convert_ascii(Trptr t, vptr v) { char *s; if(!t->t_filter_converted) { s = convert_ascii_2(t, v); } else { s = strdup_2((char *)v->v); if((*s == '?') && (!GLOBALS->color_active_in_filter)) { char *s2a; char *s2 = strchr(s+1, '?'); if(s2) { s2++; s2a = malloc_2(strlen(s2)+1); strcpy(s2a, s2); free_2(s); s = s2a; } } } if(!(t->f_filter|t->p_filter)) { } else { if(t->f_filter) { s = dofilter(t, s); } else { s = pdofilter(t, s); } } return(s); } /* * convert trptr+hptr vectorstring into a real */ double convert_real_vec(Trptr t, char *vec) { Ulong flags; int nbits; char *bits; char *pnt, *newbuff; int i; const char *xtab; double mynan = strtod("NaN", NULL); double retval = mynan; static const char xfwd[AN_COUNT]= AN_NORMAL ; static const char xrev[AN_COUNT]= AN_INVERSE ; flags=t->flags; nbits=t->n.nd->msi-t->n.nd->lsi; if(nbits<0)nbits=-nbits; nbits++; if(vec) { bits=vec; if(*vec>AN_MSK) /* convert as needed */ for(i=0;iflags; nbits=t->n.vec->nbits; bits=v->v; if(flags&TR_INVERT) { xtab = xrev; } else { xtab = xfwd; } newbuff=(char *)malloc_2(nbits+6); /* for justify */ if(flags&TR_REVERSE) { char *fwdpnt, *revpnt; fwdpnt=(char *)bits; revpnt=newbuff+nbits+6; /* for(i=0;i<3;i++) *(--revpnt)=xtab[0]; */ for(i=0;i<3;i++) *(--revpnt)=xfwd[0]; for(i=0;i #include #else #include #include #endif struct Global *GLOBALS = NULL; /* make this const so if we try to write to it we coredump */ static const struct Global globals_base_values = { /* * ae2.c */ #ifdef AET2_IS_PRESENT #ifdef AET2_ALIASDB_IS_PRESENT NULL, /* adb_alias_stream_file */ 0, /* adb */ 0, /* adb_max_terms */ NULL, /* adb_terms */ NULL, /* adb_aliases */ NULL, /* adb_num_terms */ NULL, /* adb_idx_first */ NULL, /* adb_idx_last */ NULL, /* adb_alloc_pool_base */ 0, /* adb_alloc_idx */ #endif 0, /* ae2_num_facs */ 0, /* ae2_num_aliases */ 0, /* ae2_num_sections */ NULL, /* ae2_lx2_table */ NULL, /* ae2_f */ NULL, /* ae2 */ NULL, /* ae2_fr */ LLDescriptor(0), /* ae2_start_limit_cyc */ LLDescriptor(0), /* ae2_end_limit_cyc */ NULL, /* ae2_process_mask */ #endif LLDescriptor(0), /* ae2_start_cyc */ LLDescriptor(0), /* ae2_end_cyc */ NULL, /* ae2_time_xlate */ 0, /* disable_ae2_alias */ /* * analyzer.c */ TR_RJUSTIFY, /* default_flags 5 */ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0, 0.0}, /* tims 6 */ {0, 0, NULL, NULL, NULL, NULL, 0, NULL, NULL, 0}, /* traces 9 */ 0, /* hier_max_level 8 */ 0, /* hier_max_level_shadow */ 0, /* timestart_from_savefile */ 0, /* timestart_from_savefile_valid */ 0, /* group_depth */ /* * baseconvert.c */ 0, /* color_active_in_filter 9 */ /* * bsearch.c */ LLDescriptor(0), /* shift_timebase 10 */ LLDescriptor(0), /* shift_timebase_default_for_add 11 */ 0, /* max_compare_time_tc_bsearch_c_1 12 */ 0, /* max_compare_pos_tc_bsearch_c_1 13 */ 0, /* max_compare_time_bsearch_c_1 14 */ 0, /* max_compare_pos_bsearch_c_1 15 */ 0, /* max_compare_index 16 */ 0, /* vmax_compare_time_bsearch_c_1 17 */ 0, /* vmax_compare_pos_bsearch_c_1 18 */ 0, /* vmax_compare_index 19 */ 0, /* maxlen_trunc 20 */ 0, /* maxlen_trunc_pos_bsearch_c_1 21 */ 0, /* trunc_asciibase_bsearch_c_1 22 */ /* * busy.c */ NULL, /* busycursor_busy_c_1 23 */ 0, /* busy_busy_c_1 24 */ /* * color.c */ 0, /* keep_xz_colors */ NULL, /* wave_gcchain */ -1, /* color_back 25 */ -1, /* color_baseline 26 */ -1, /* color_grid 27 */ -1, /* color_grid2 27 */ -1, /* color_high 28 */ -1, /* color_low 29 */ -1, /* color_mark 30 */ -1, /* color_mid 31 */ -1, /* color_time 32 */ -1, /* color_timeb 33 */ -1, /* color_trans 34 */ -1, /* color_umark 35 */ -1, /* color_value 36 */ -1, /* color_vbox 37 */ -1, /* color_vtrans 38 */ -1, /* color_x 39 */ -1, /* color_xfill 40 */ -1, /* color_0 41 */ -1, /* color_1 42 */ -1, /* color_ufill 43 */ -1, /* color_u 44 */ -1, /* color_wfill 45 */ -1, /* color_w 46 */ -1, /* color_dashfill 47 */ -1, /* color_dash 48 */ -1, /* color_white 49 */ -1, /* color_black 50 */ -1, /* color_ltgray 51 */ -1, /* color_normal 52 */ -1, /* color_mdgray 53 */ -1, /* color_dkgray 54 */ -1, /* color_dkblue 55 */ -1, /* color_brkred */ -1, /* color_ltblue */ -1, /* color_gmstrd */ /* * currenttime.c */ LLDescriptor(0), /* global_time_offset */ 0, /* is_vcd 56 */ 0, /* partial_vcd */ 1, /* use_maxtime_display 57 */ 0, /* use_frequency_delta 58 */ NULL, /* max_or_marker_label_currenttime_c_1 59 */ NULL, /* base_or_curtime_label_currenttime_c_1 60 */ 0, /* cached_currenttimeval_currenttime_c_1 61 */ 0, /* currenttime 62 */ 0, /* max_time 63 */ -1, /* min_time 64 */ ~0, /* display_grid 65 */ 1, /* time_scale 66 */ 'n', /* time_dimension 67 */ 0, /* scale_to_time_dimension */ 0, /* maxtimewid_currenttime_c_1 69 */ 0, /* curtimewid_currenttime_c_1 70 */ 0, /* maxtext_currenttime_c_1 71 */ 0, /* curtext_currenttime_c_1 72 */ 1, /* time_trunc_val_currenttime_c_1 76 */ 0, /* use_full_precision 77 */ /* * debug.c */ NULL, /* alloc2_chain */ 0, /* outstanding */ NULL, /* atoi_cont_ptr 78 */ 0, /* disable_tooltips 79 */ /* * entry.c */ 0, /* window_entry_c_1 80 */ 0, /* entry_entry_c_1 81 */ NULL, /* entrybox_text 82 */ 0, /* cleanup_entry_c_1 83 */ 0, /* entry_raise_timer */ /* * extload.c */ 0, /* extload_ffr_import_count */ NULL, /* extload_ffr_ctx */ NULL, /* extload */ NULL, /* extload_idcodes */ NULL, /* extload_inv_idcodes */ #if !defined __MINGW32__ && !defined _MSC_VER 0, /* extload_lastmod */ 0, /* extload_already_errored */ #endif NULL, /* extload_namecache */ NULL, /* extload_namecache_max */ NULL, /* extload_namecache_lens */ NULL, /* extload_sym_block */ NULL, /* extload_node_block */ NULL, /* extload_xc */ NULL, /* extload_prevsymroot */ NULL, /* extload_prevsym */ 0, /* extload_i */ 0, /* extload_hlen */ 0, /* extload_vt_prev */ 0, /* extload_vd_prev */ 0, /* f_name_build_buf_len */ NULL, /* f_name_build_buf */ /* * fetchbuttons.c */ 100, /* fetchwindow 84 */ /* * fgetdynamic.c */ 0, /* fgetmalloc_len 85 */ /* * file.c */ #if GTK_CHECK_VERSION(2,4,0) NULL, /* pFileChoose */ NULL, /* pFileChooseFilterName */ NULL, /* pPatternSpec */ #endif 0, /* fs_file_c_1 86 */ NULL, /* fileselbox_text 87 */ 0, /* filesel_ok 88 */ 0, /* cleanup_file_c_2 89 */ 0, /* bad_cleanup_file_c1 */ /* * fonts.c */ NULL, /* fontname_signals 90 */ NULL, /* fontname_waves 91 */ #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) && GTK_CHECK_VERSION(2,8,0) NULL, /* fonts_renderer */ NULL, /* fonts_gc */ NULL, /* fonts_screen */ NULL, /* fonts_context */ NULL, /* fonts_layout */ #endif 1, /* use_pango_fonts */ /* * fst.c */ NULL, /* fst_fst_c_1 */ NULL, /* fst_scope_name */ 0, /* fst_scope_name_len */ 0, /* first_cycle_fst_c_3 */ 0, /* last_cycle_fst_c_3 */ 0, /* total_cycles_fst_c_3 */ NULL, /* fst_table_fst_c_1 */ NULL, /* mvlfacs_fst_c_3 */ NULL, /* mvlfacs_fst_alias */ NULL, /* mvlfacs_fst_rvs_alias */ 0, /* fst_maxhandle */ 0, /* busycnt_fst_c_2 */ NULL, /* double_curr_fst */ NULL, /* double_fini_fst */ 0, /* nonimplicit_direction_encountered */ 0, /* supplemental_datatypes_encountered */ 0, /* supplemental_vartypes_encountered */ 0, /* is_vhdl_component_format */ NULL, /* subvar_jrb */ 0, /* subvar_jrb_count */ NULL, /* subvar_pnt */ 0, /* fst_filetype */ 0, /* subvar_jrb_count_locked */ 0, /* stem_file_idx */ 0, /* stem_line_number */ NULL, /* stem_path_string_table */ NULL, /* stem_struct_base */ NULL, /* istem_struct_base */ 0, /* stem_path_string_table_siz */ 0, /* stem_path_string_table_alloc */ 0, /* stem_struct_base_siz */ 0, /* stem_struct_base_siz_alloc */ 0, /* istem_struct_base_siz */ 0, /* istem_struct_base_siz_alloc */ 0, /* stem_valid */ 0, /* istem_valid */ NULL, /* fst_synclock_str */ NULL, /* synclock_jrb */ /* * ghw.c */ 0, /* nxp_ghw_c_1 93 */ 0, /* sym_which_ghw_c_1 95 */ NULL, /* gwt_ghw_c_1 96 */ NULL, /* gwt_corr_ghw_c_1 97 */ 1, /* xlat_1164_ghw_c_1 98 */ 0, /* is_ghw 99 */ NULL, /* asbuf */ 0, /* nbr_sig_ref_ghw_c_1 101 */ 0, /* num_glitches_ghw_c_1 102 */ 0, /* num_glitch_regions_ghw_c_1 */ 0, /* fac_name_ghw_c_1 104 */ 0, /* fac_name_len_ghw_c_1 105 */ 0, /* fac_name_max_ghw_c_1 106 */ 0, /* last_fac_ghw_c_1 107 */ 0, /* warned_ghw_c_1 108 */ /* * globals.c */ NULL, /* dead_context */ NULL, /* gtk_context_bridge_ptr */ /* * help.c */ 0, /* helpbox_is_active 110 */ 0, /* text_help_c_1 111 */ 0, /* vscrollbar_help_c_1 112 */ #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) {NULL, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, NULL}, /* iter_help_c_1 113 */ 0, /* bold_tag_help_c_1 114 */ #endif 0, /* window_help_c_2 115 */ /* * hierpack.c */ NULL, /* hp_buf */ NULL, /* hp_offs */ 0, /* hp_prev */ 0, /* hp_buf_siz */ NULL, /* fmem_buf */ 0, /* fmem_buf_siz */ 0, /* fmem_buf_offs */ 0, /* fmem_uncompressed_siz */ /* * hiersearch.c */ 1, /* hier_grouping 116 */ 0, /* window_hiersearch_c_3 117 */ 0, /* entry_main_hiersearch_c_1 118 */ 0, /* clist_hiersearch_c_1 119 */ 0, /* bundle_direction_hiersearch_c_1 120 */ 0, /* cleanup_hiersearch_c_3 121 */ 0, /* num_rows_hiersearch_c_1 122 */ 0, /* selected_rows_hiersearch_c_1 123 */ 0, /* window1_hiersearch_c_1 124 */ 0, /* entry_hiersearch_c_2 125 */ NULL, /* entrybox_text_local_hiersearch_c_1 126 */ NULL, /* cleanup_e_hiersearch_c_1 127 */ NULL, /* h_selectedtree_hiersearch_c_1 128 */ NULL, /* current_tree_hiersearch_c_1 129 */ NULL, /* treechain_hiersearch_c_1 130 */ 0, /* is_active_hiersearch_c_1 131 */ /* * logfile.c */ NULL, /* logfiles */ NULL, /* fontname_logfile 133 */ NULL, /* font_logfile_c_1 134 */ #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) {NULL, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, NULL}, /* iter_logfile_c_2 135 */ NULL, /* bold_tag_logfile_c_2 136 */ NULL, /* mono_tag_logfile_c_1 137 */ NULL, /* size_tag_logfile_c_1 138 */ #endif /* * lx2.c */ LXT2_IS_INACTIVE, /* is_lx2 139 */ NULL, /* lx2_lx2_c_1 140 */ 0, /* first_cycle_lx2_c_1 141 */ 0, /* last_cycle */ 0, /* total_cycles */ NULL, /* lx2_table_lx2_c_1 142 */ NULL, /* mvlfacs_lx2_c_1 143 */ 0, /* busycnt_lx2_c_1 144 */ /* * lxt.c */ NULL, /* mm_lxt_mmap_addr */ 0, /* mm_lxt_mmap_len */ #if defined __MINGW32__ || defined _MSC_VER NULL, /* HANDLE hIn */ NULL, /* HANDLE hInMap */ NULL, /* char *win_fname = NULL; */ #endif 0, /* fpos_lxt_c_1 145 */ 0, /* is_lxt 146 */ 0, /* lxt_clock_compress_to_z 147 */ NULL, /* mm_lxt_c_1 148 */ NULL, /* mmcache_lxt_c_1 */ 0, /* version_lxt_c_1 149 */ NULL, /* mvlfacs_lxt_c_2 150 */ 0, /* first_cycle_lxt_c_2 151 */ 0, /* last_cycle */ 0, /* total_cycles */ 0, /* maxchange_lxt_c_1 152 */ 0, /* maxindex */ 0, /* f_len_lxt_c_1 153 */ NULL, /* positional_information_lxt_c_1 154 */ NULL, /* time_information 155 */ 0, /* change_field_offset_lxt_c_1 156 */ 0, /* facname_offset_lxt_c_1 157 */ 0, /* facgeometry_offset_lxt_c_1 158 */ 0, /* time_table_offset_lxt_c_1 159 */ 0, /* time_table_offset64_lxt_c_1 160 */ 0, /* sync_table_offset_lxt_c_1 161 */ 0, /* initial_value_offset_lxt_c_1 162 */ 0, /* timescale_offset_lxt_c_1 163 */ 0, /* double_test_offset_lxt_c_1 164 */ 0, /* zdictionary_offset_lxt_c_1 165 */ 0, /* zfacname_predec_size_lxt_c_1 166 */ 0, /* zfacname_size_lxt_c_1 167 */ 0, /* zfacgeometry_size_lxt_c_1 168 */ 0, /* zsync_table_size_lxt_c_1 169 */ 0, /* ztime_table_size_lxt_c_1 170 */ 0, /* zchg_predec_size_lxt_c_1 171 */ 0, /* zchg_size_lxt_c_1 172 */ 0, /* zdictionary_predec_size_lxt_c_1 173 */ AN_X, /* initial_value_lxt_c_1 174 */ 0, /* dict_num_entries_lxt_c_1 175 */ 0, /* dict_string_mem_required_lxt_c_1 176 */ 0, /* dict_16_offset_lxt_c_1 177 */ 0, /* dict_24_offset_lxt_c_1 178 */ 0, /* dict_32_offset_lxt_c_1 179 */ 0, /* dict_width_lxt_c_1 180 */ NULL, /* dict_string_mem_array_lxt_c_1 181 */ 0, /* exclude_offset_lxt_c_1 182 */ 0, /* lxt_timezero_offset */ NULL, /* lt_buf_lxt_c_1 183 */ 0, /* lt_len_lxt_c_1 184 */ -1, /* fd_lxt_c_1 185 */ {0,0,0,0,0,0,0,0}, /* double_mask_lxt_c_1 186 */ 0, /* double_is_native_lxt_c_1 187 */ 0, /* max_compare_time_tc_lxt_c_2 189 */ 0, /* max_compare_pos_tc_lxt_c_2 */ NULL, /* resolve_lxt_alias_to */ NULL, /* lastchange */ /* * main.c */ 1, /* is_gtkw_save_file */ 0, /* dumpfile_is_modified */ NULL, /* missing_file_toolbar */ NULL, /* argvlist */ #if defined(HAVE_LIBTCL) NULL, /* interp */ #endif NULL, /* repscript_name */ 500, /* repscript_period */ NULL, /* tcl_init_cmd */ 0, /* tcl_running */ 0, /* block_xy_update */ NULL, /* winname */ 0, /* num_notebook_pages */ 1, /* num_notebook_pages_cumulative */ 0, /* context_tabposition */ 0, /* this_context_page */ 0, /* second_page_created */ NULL, /* contexts */ NULL, /* notebook */ NULL, /* loaded_file_name */ NULL, /* unoptimized_vcd_file_name */ NULL, /* skip_start */ NULL, /* skip_end */ MISSING_FILE, /* loaded_file_type */ 0, /* is_optimized_stdin_vcd */ NULL, /* whoami 190 */ NULL, /* logfile 191 */ NULL, /* stems_name 192 */ WAVE_ANNO_NONE, /* stems_type 193 */ NULL, /* aet_name 194 */ NULL, /* anno_ctx 195 */ NULL, /* dual_ctx 196 */ 0, /* dual_id 197 */ 0, /* dual_attach_id_main_c_1 198 */ 0, /* dual_race_lock 199 */ NULL, /* mainwindow 200 */ NULL, /* signalwindow 201 */ NULL, /* wavewindow 202 */ NULL, /* toppanedwindow 203 */ NULL, /* panedwindow */ 0, /* toppanedwindow_size_cache */ 0, /* panedwindow_size_cache */ 0, /* vpanedwindow_size_cache */ NULL, /* sstpane 204 */ NULL, /* expanderwindow 205 */ 0, /* disable_window_manager 206 */ 0, /* disable_empty_gui */ 1, /* paned_pack_semantics 207 */ 0, /* zoom_was_explicitly_set 208 */ 1000, /* initial_window_x 209 */ 600, /* initial_window_y */ -1, /* initial_window_width */ -1, /* initial_window_height 210 */ 0, /* xy_ignore_main_c_1 211 */ 0, /* optimize_vcd 212 */ 1, /* num_cpus 213 */ -1, /* initial_window_xpos 214 */ -1, /* initial_window_ypos 214 */ 0, /* initial_window_set_valid 215 */ -1, /* initial_window_xpos_set 216 */ -1, /* initial_window_ypos_set */ 0, /* initial_window_get_valid 217 */ -1, /* initial_window_xpos_get 218 */ -1, /* initial_window_ypos_get 218 */ 0, /* xpos_delta 219 */ 0, /* ypos_delta 219 */ 0, /* use_scrollbar_only 220 */ 0, /* force_toolbars 221 */ 0, /* hide_sst 222 */ 1, /* sst_expanded 223 */ #ifdef WAVE_USE_GTK2 0, /* socket_xid 224 */ #endif 0, /* disable_menus 225 */ NULL, /* ftext_main_main_c_1 226 */ #ifdef WAVE_USE_GTK2 1, /* use_toolbutton_interface */ #else 0, /* use_toolbutton_interface */ #endif /* * markerbox.c */ NULL, /* window_markerbox_c_4 231 */ {0}, /* entries_markerbox_c_1 232 */ NULL, /* cleanup_markerbox_c_4 233 */ 0, /* dirty_markerbox_c_1 234 */ {0}, /* shadow_markers_markerbox_c_1 235 */ {NULL}, /* marker_names */ {NULL}, /* shadow_marker_names */ /* * menu.c */ NULL, /* cutcopylist */ 0, /* enable_fast_exit 236 */ 0, /* quiet_checkmenu */ NULL, /* wave_script_args 237 */ 0, /* ignore_savefile_pane_pos */ 0, /* ignore_savefile_pos 238 */ 0, /* ignore_savefile_size 239 */ #ifndef WAVE_USE_MLIST_T NULL, /* item_factory_menu_c_1 241 */ #endif NULL, /* regexp_string_menu_c_1 242 */ NULL, /* trace_to_alias_menu_c_1 243 */ NULL, /* showchangeall_menu_c_1 244 */ NULL, /* filesel_newviewer_menu_c_1 245 */ NULL, /* filesel_logfile_menu_c_1 246 */ NULL, /* filesel_scriptfile_menu */ NULL, /* filesel_writesave 247 */ NULL, /* filesel_imagegrab */ 0, /* save_success_menu_c_1 248 */ NULL, /* filesel_vcd_writesave 249 */ NULL, /* filesel_lxt_writesave 250 */ NULL, /* filesel_tim_writesave */ 0, /* lock_menu_c_1 251 */ 0, /* lock_menu_c_2 252 */ NULL, /* buf_menu_c_1 253 128 */ NULL, /* signal_popup_menu */ NULL, /* sst_signal_popup_menu */ /* * mouseover.c */ 1, /* disable_mouseover 254 */ NULL, /* mouseover_mouseover_c_1 255 */ NULL, /* mo_area_mouseover_c_1 256 */ NULL, /* mo_pixmap_mouseover_c_1 257 */ NULL, /* mo_dk_gray_mouseover_c_1 258 */ NULL, /* mo_black_mouseover_c_1 259 */ 0, /* mo_width_mouseover_c_1 260 */ 0, /* mo_height_mouseover_c_1 260 */ /* * pagebuttons.c */ 1.0, /* page_divisor 261 */ /* * pixmaps.c */ NULL, /* redo_pixmap */ NULL, /* redo_mask */ NULL, /* larrow_pixmap 263 */ NULL, /* larrow_mask 264 */ NULL, /* rarrow_pixmap 266 */ NULL, /* rarrow_mask 267 */ NULL, /* zoomin_pixmap 269 */ NULL, /* zoomin_mask 270 */ NULL, /* zoomout_pixmap 272 */ NULL, /* zoomout_mask 273 */ NULL, /* zoomfit_pixmap 275 */ NULL, /* zoomfit_mask 276 */ NULL, /* zoomundo_pixmap 278 */ NULL, /* zoomundo_mask 279 */ NULL, /* zoom_larrow_pixmap 281 */ NULL, /* zoom_larrow_mask 282 */ NULL, /* zoom_rarrow_pixmap 284 */ NULL, /* zoom_rarrow_mask 285 */ NULL, /* prev_page_pixmap 287 */ NULL, /* prev_page_mask 288 */ NULL, /* next_page_pixmap 290 */ NULL, /* next_page_mask 291 */ NULL, /* wave_info_pixmap 293 */ NULL, /* wave_info_mask 294 */ NULL, /* wave_alert_pixmap 296 */ NULL, /* wave_alert_mask 297 */ NULL, /* hiericon_module_pixmap */ NULL, /* hiericon_module_mask */ NULL, /* hiericon_task_pixmap */ NULL, /* hiericon_task_mask */ NULL, /* hiericon_function_pixmap */ NULL, /* hiericon_function_mask */ NULL, /* hiericon_begin_pixmap */ NULL, /* hiericon_begin_mask */ NULL, /* hiericon_fork_pixmap */ NULL, /* hiericon_fork_mask */ NULL, /* hiericon_interface_pixmap */ NULL, /* hiericon_interface_mask */ NULL, /* hiericon_svpackage_pixmap */ NULL, /* hiericon_svpackage_mask */ NULL, /* hiericon_program_pixmap */ NULL, /* hiericon_program_mask */ NULL, /* hiericon_class_pixmap */ NULL, /* hiericon_class_mask */ NULL, /* hiericon_record_pixmap */ NULL, /* hiericon_record_mask */ NULL, /* hiericon_generate_pixmap */ NULL, /* hiericon_generate_mask */ NULL, /* hiericon_design_pixmap */ NULL, /* hiericon_design_mask */ NULL, /* hiericon_block_pixmap */ NULL, /* hiericon_block_mask */ NULL, /* hiericon_generateif_pixmap */ NULL, /* hiericon_generateif_mask */ NULL, /* hiericon_generatefor_pixmap */ NULL, /* hiericon_generatefor_mask */ NULL, /* hiericon_instance_pixmap */ NULL, /* hiericon_instance_mask */ NULL, /* hiericon_package_pixmap */ NULL, /* hiericon_package_mask */ NULL, /* hiericon_signal_pixmap */ NULL, /* hiericon_signal_mask */ NULL, /* hiericon_portin_pixmap */ NULL, /* hiericon_portin_mask */ NULL, /* hiericon_portout_pixmap */ NULL, /* hiericon_portout_mask */ NULL, /* hiericon_portinout_pixmap */ NULL, /* hiericon_portinout_mask */ NULL, /* hiericon_buffer_pixmap */ NULL, /* hiericon_buffer_mask */ NULL, /* hiericon_linkage_pixmap */ NULL, /* hiericon_linkage_mask */ /* * print.c */ 72, /* inch_print_c_1 298 */ 1.0, /* ps_chwidth_print_c_1 299 */ 0, /* ybound_print_c_1 300 */ 0, /* pr_signal_fill_width_print_c_1 301 */ 0, /* ps_nummaxchars_print_c_1 302 */ 1, /* ps_fullpage 303 */ 66, /* ps_maxveclen 304 */ 0, /* liney_max 305 */ /* * ptranslate.c */ 0, /* current_translate_proc 308 */ 0, /* current_filter_ptranslate_c_1 309 */ 0, /* num_proc_filters 310 */ NULL, /* procsel_filter 311 */ NULL, /* proc_filter 312 */ 0, /* is_active_ptranslate_c_2 313 */ NULL, /* fcurr_ptranslate_c_1 314 */ NULL, /* window_ptranslate_c_5 315 */ NULL, /* clist_ptranslate_c_2 316 */ /* * rc.c */ 0, /* rc_line_no 318 */ 1, /* possibly_use_rc_defaults 319 */ NULL, /* editor_string */ /* * regex.c */ NULL, /* preg_regex_c_1 321 */ NULL, /* regex_ok_regex_c_1 322 */ /* * renderopt.c */ #ifdef WAVE_GTK_UNIX_PRINT NULL, /* gprs */ NULL, /* gps */ NULL, /* gp_tfn */ #endif 0, /* is_active_renderopt_c_3 323 */ 0, /* window_renderopt_c_6 324 */ NULL, /* filesel_print_pdf_renderopt_c_1 */ NULL, /* filesel_print_ps_renderopt_c_1 325 */ NULL, /* filesel_print_mif_renderopt_c_1 326 */ {0,0,0,0}, /* target_mutex_renderopt_c_1 328 */ {0,0,0,0,0}, /* page_mutex_renderopt_c_1 330 */ {0,0,0}, /* render_mutex_renderopt_c_1 332 */ 0, /* page_size_type_renderopt_c_1 333 */ /* * savefile.c */ NULL, /* sfn */ NULL, /* lcname */ /* * search.c */ {NULL,NULL,NULL,NULL,NULL}, /* menuitem_search */ NULL, /* window1_search_c_2 340 */ NULL, /* entry_a_search_c_1 341 */ NULL, /* entrybox_text_local_search_c_2 342 */ NULL, /* cleanup_e_search_c_2 343 */ NULL, /* pdata 344 */ 0, /* is_active_search_c_4 345 */ 0, /* is_insert_running_search_c_1 346 */ 0, /* is_replace_running_search_c_1 347 */ 0, /* is_append_running_search_c_1 348 */ 0, /* is_searching_running_search_c_1 349 */ {0,0,0,0,0}, /* regex_mutex_search_c_1 352 */ 0, /* regex_which_search_c_1 353 */ NULL, /* window_search_c_7 354 */ NULL, /* entry_search_c_3 355 */ NULL, /* clist_search_c_3 356 */ NULL, /* searchbox_text_search_c_1 358 */ 0, /* bundle_direction_search_c_2 359 */ NULL, /* cleanup_search_c_5 360 */ 0, /* num_rows_search_c_2 361 */ 0, /* selected_rows_search_c_2 362 */ /* * showchange.c */ NULL, /* button1_showchange_c_1 363 */ NULL, /* button1_showchange_c_2 363 */ NULL, /* button1_showchange_c_3 363 */ NULL, /* button1_showchange_c_4 363 */ NULL, /* button1_showchange_c_5 363 */ NULL, /* button1_showchange_c_6 363 */ NULL, /* toggle1_showchange_c_1 364 */ NULL, /* toggle2_showchange_c_1 364 */ NULL, /* toggle3_showchange_c_1 364 */ NULL, /* toggle4_showchange_c_1 364 */ NULL, /* window_showchange_c_8 365 */ NULL, /* cleanup_showchange_c_6 366 */ NULL, /* tcache_showchange_c_1 367 */ 0, /* flags_showchange_c_1 368 */ /* * signalwindow.c */ NULL, /* signalarea 369 */ NULL, /* signalfont 370 */ NULL, /* signalpixmap 371 */ #ifdef WAVE_ALLOW_QUARTZ_FLUSH_WORKAROUND 0, /* force_hide_show */ #endif 0, /* max_signal_name_pixel_width 372 */ 0, /* signal_pixmap_width 373 */ 0, /* signal_fill_width 374 */ 0, /* old_signal_fill_width 375 */ 0, /* old_signal_fill_height */ 1, /* right_align_active */ 1, /* fontheight 376 */ 0, /* dnd_state 377 */ 0, /* dnd_cursor_timer */ NULL, /* hscroll_signalwindow_c_1 378 */ NULL, /* signal_hslider 379 */ 0, /* cachedhiflag_signalwindow_c_1 380 */ -1, /* cachedwhich_signalwindow_c_1 381 */ NULL, /* cachedtrace 382 */ NULL, /* shift_click_trace 383 */ 0, /* trtarget_signalwindow_c_1 384 */ NULL, /* starting_unshifted_trace */ 0, /* standard_trace_dnd_degate */ 0, /* use_standard_trace_select */ 1, /* use_standard_clicking */ 0, /* std_collapse_pressed */ 0, /* std_dnd_tgt_on_signalarea */ 0, /* std_dnd_tgt_on_wavearea */ 0, /* signalarea_has_focus */ NULL, /* signalarea_event_box */ 0, /* keypress_handler_id */ 0, /* cached_mouseover_x */ 0, /* cached_mouseover_y */ 0, /* mouseover_counter */ 0, /* button2_debounce_flag */ /* * simplereq.c */ NULL, /* window_simplereq_c_9 385 */ NULL, /* cleanup 386 */ /* * splash.c */ 0, /* splash_is_loading */ 0, /* splash_fix_win_title */ 1, /* splash_disable 387 */ NULL, /* wave_splash_pixmap 389 */ NULL, /* wave_splash_mask 390 */ NULL, /* splash_splash_c_1 391 */ NULL, /* darea_splash_c_1 392 */ NULL, /* gt_splash_c_1 393 */ 0, /* timeout_tag 394 */ 0, /* load_complete_splash_c_1 395 */ 2, /* cnt_splash_c_1 396 */ 0, /* prev_bar_x_splash_c_1 397 */ /* * status.c */ NULL, /* text_status_c_2 398 */ NULL, /* vscrollbar_status_c_2 399 */ #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) {NULL, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 0, 0, 0, NULL}, /* iter_status_c_3 400 */ NULL, /* bold_tag_status_c_3 401 */ #endif /* * strace.c */ NULL, /* strace_ctx (defined in strace.h for multiple strace sessions) */ { {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,{0,0,0,0,0,0},{0,0,0,0,0,0},0,0,0,0,0,0,0}, /* strace_windows[0] */ #ifdef WAVE_USE_GTK2 {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,{0,0,0,0,0,0},{0,0,0,0,0,0},0,0,0,0,0,0,0} #endif }, /* strace_windows[1] */ #if WAVE_NUM_STRACE_WINDOWS != 2 #ifdef WAVE_USE_GTK2 #error the number of strace windows as defined in strace.h does not match globals.c! #else #if WAVE_NUM_STRACE_WINDOWS != 1 #error gtk1 only supports 1 strace window, sorry! #endif #endif #endif 0, /* strace_current_window */ 1, /* strace_repeat_count */ /* * symbol.c */ #ifdef _WAVE_HAVE_JUDY NULL, /* sym_judy */ NULL, /* s_selected */ #endif NULL, /* sym_hash 424 */ NULL, /* facs 425 */ 0, /* facs_are_sorted 426 */ 0, /* facs_have_symbols_state_machine */ 0, /* numfacs 427 */ 0, /* regions 428 */ 0, /* longestname 429 */ NULL, /* firstnode 430 */ NULL, /* curnode 431 */ 0, /* hashcache 432 */ /* * tcl_commands.c */ NULL, /* previous_braced_tcl_string */ /* * tcl_helper.c */ 0, /* in_tcl_callback */ /* * timeentry.c */ NULL, /* from_entry 433 */ NULL, /* to_entry */ /* * translate.c */ 0, /* current_translate_file 434 */ 0, /* current_filter_translate_c_2 435 */ 0, /* num_file_filters 436 */ NULL, /* filesel_filter 437 */ NULL, /* xl_file_filter 438 */ 0, /* is_active_translate_c_5 439 */ NULL, /* fcurr_translate_c_2 440 */ NULL, /* window_translate_c_11 441 */ NULL, /* clist_translate_c_4 442 */ /* * tree.c */ #ifdef _WAVE_HAVE_JUDY NULL, /* sym_tree */ NULL, /* sym_tree_addresses */ #endif NULL, /* treeroot 443 */ NULL, /* mod_tree_parent */ NULL, /* module_tree_c_1 444 */ 0, /* module_len_tree_c_1 445 */ NULL, /* terminals_tchain_tree_c_1 446 */ '.', /* hier_delimeter 447 */ 0, /* hier_was_explicitly_set 448 */ 0x00, /* alt_hier_delimeter 449 */ 1, /* fast_tree_sort 450 */ NULL, /* facs2_tree_c_1 451 */ 0, /* facs2_pos_tree_c_1 452 */ NULL, /* talloc_pool_base */ 0, /* talloc_idx */ /* * tree_component.c */ #ifdef _WAVE_HAVE_JUDY NULL, /* comp_name_judy */ #else NULL, /* comp_name_jrb */ #endif NULL, /* comp_name_idx */ 0, /* comp_name_serial */ 0, /* comp_name_total_stringmem */ 0, /* comp_name_longest */ /* * treesearch_gtk1.c */ NULL, /* GtkWidget *window1_treesearch_gtk1_c; */ NULL, /* GtkWidget *entry_a_treesearch_gtk1_c; */ NULL, /* char *entrybox_text_local_treesearch_gtk1_c; */ NULL, /* void (*cleanup_e_treesearch_gtk1_c)(); */ NULL, /* struct tree *selectedtree_treesearch_gtk1_c; */ 0, /* int is_active_treesearch_gtk1_c; */ NULL, /* GtkWidget *window_treesearch_gtk1_c; */ NULL, /* GtkWidget *tree_treesearch_gtk1_c; */ 0, /* char bundle_direction_treesearch_gtk1_c; */ NULL, /* void (*cleanup_treesearch_gtk1_c)(); */ /* * treesearch_gtk2.c */ #ifdef MAC_INTEGRATION NULL, /* dnd_helper_quartz */ #endif NULL, /* treeopen_chain_head */ NULL, /* treeopen_chain_curr */ 0, /* tree_dnd_begin */ 0, /* tree_dnd_requested */ 1, /* do_dynamic_treefilter */ NULL, /* treesearch_gtk2_window_vbox */ NULL, /* selected_hierarchy_name */ NULL, /* selected_sig_name */ NULL, /* gtk2_tree_frame */ NULL, /* filter_entry */ NULL, /* any_tree_node */ NULL, /* open_tree_nodes */ 0, /* autoname_bundles 453 */ NULL, /* window1_treesearch_gtk2_c_3 454 */ NULL, /* entry_a_treesearch_gtk2_c_2 455 */ NULL, /* entrybox_text_local_treesearch_gtk2_c_3 456 */ NULL, /* cleanup_e_treesearch_gtk2_c_3 457 */ NULL, /* sig_root_treesearch_gtk2_c_1 458 */ NULL, /* sst_sig_root_treesearch_gtk2_c_1 */ NULL, /* filter_str_treesearch_gtk2_c_1 459 */ ND_DIR_UNSPECIFIED, /* filter_typ_treesearch_gtk2_c_1 */ 0, /* filter_typ_polarity_treesearch_gtk2_c_1 */ 0, /* filter_matlen_treesearch_gtk2_c_1 */ 0, /* filter_noregex_treesearch_gtk2_c_1 */ #if defined(WAVE_USE_GTK2) NULL, /* sig_store_treesearch_gtk2_c_1 460 */ NULL, /* sig_selection_treesearch_gtk2_c_1 461 */ #endif 0, /* is_active_treesearch_gtk2_c_6 462 */ NULL, /* ctree_main 463 */ NULL, /* afl_treesearch_gtk2_c_1 464 */ NULL, /* window_treesearch_gtk2_c_12 465 */ NULL, /* tree_treesearch_gtk2_c_1 466 */ 0, /* bundle_direction_treesearch_gtk2_c_3 467 */ NULL, /* cleanup_treesearch_gtk2_c_8 468 */ 0, /* pre_import_treesearch_gtk2_c_1 469 */ {0,0,NULL,NULL,NULL,NULL,0,NULL,NULL,0}, /* tcache_treesearch_gtk2_c_2 470 */ 0, /* dnd_tgt_on_signalarea_treesearch_gtk2_c_1 471 */ 0, /* dnd_tgt_on_wavearea_treesearch_gtk2_c_1 */ NULL, /* dnd_sigview */ NULL, /* sst_vpaned */ /* * ttranslate.c */ 0, /* current_translate_ttrans */ 0, /* current_filter_ttranslate_c_1 */ 0, /* num_ttrans_filters */ NULL, /* ttranssel_filter */ NULL, /* ttrans_filter */ 0, /* is_active_ttranslate_c_2 */ NULL, /* fcurr_ttranslate_c_1 */ NULL, /* window_ttranslate_c_5 */ NULL, /* clist_ttranslate_c_2 */ NULL, /* ttranslate_args */ /* * vcd.c */ 0, /* do_hier_compress */ NULL, /* prev_hier_uncompressed_name */ NULL, /* vcd_jmp_buf */ -1, /* vcd_warning_filesize 472 */ 1, /* autocoalesce 473 */ 0, /* autocoalesce_reversal */ -1, /* vcd_explicit_zero_subscripts 474 */ 0, /* convert_to_reals 475 */ 1, /* atomic_vectors 476 */ 0, /* make_vcd_save_file 477 */ 0, /* vcd_preserve_glitches 478 */ 0, /* vcd_preserve_glitches_real */ NULL, /* vcd_save_handle 479 */ NULL, /* vcd_handle_vcd_c_1 480 */ 0, /* vcd_is_compressed_vcd_c_1 481 */ 0, /* vcdbyteno_vcd_c_1 482 */ 0, /* error_count_vcd_c_1 483 */ 0, /* header_over_vcd_c_1 484 */ 0, /* dumping_off_vcd_c_1 485 */ -1, /* start_time_vcd_c_1 486 */ -1, /* end_time_vcd_c_1 487 */ -1, /* current_time_vcd_c_1 488 */ 0, /* num_glitches_vcd_c_2 489 */ 0, /* num_glitch_regions_vcd_c_2 490 */ {0, 0}, /* vcd_hier_delimeter 491 */ NULL, /* pv_vcd_c_1 492 */ NULL, /* rootv_vcd_c_1 */ NULL, /* vcdbuf_vcd_c_1 493 */ NULL, /* vst */ NULL, /* vend */ 0, /* escaped_names_found_vcd_c_1 494 */ NULL, /* slistroot 495 */ NULL, /* slistcurr */ NULL, /* slisthier 496 */ 0, /* slisthier_len 497x */ 1024, /* T_MAX_STR_vcd_c_1 499 */ NULL, /* yytext_vcd_c_1 500 */ 0, /* yylen_vcd_c_1 501 */ 0, /* yylen_cache */ NULL, /* vcdsymroot_vcd_c_1 502 */ NULL, /* vcdsymcurr */ NULL, /* sorted_vcd_c_1 503 */ NULL, /* indexed_vcd_c_1 504 */ 0, /* numsyms_vcd_c_1 505 */ NULL, /* he_curr_vcd_c_1 506 */ NULL, /* he_fini */ ~0, /* vcd_minid_vcd_c_1 508 */ 0, /* vcd_maxid_vcd_c_1 509 */ 0, /* err_vcd_c_1 510 */ 0, /* vcd_fsiz_vcd_c_1 511 */ NULL, /* varsplit_vcd_c_1 512 */ NULL, /* varsplitcurr */ 0, /* var_prevch_vcd_c_1 513 */ /* * vcd_partial.c */ 0, /* vcdbyteno_vcd_partial_c_2 516 */ 0, /* error_count_vcd_partial_c_2 517 */ 0, /* header_over_vcd_partial_c_2 518 */ 0, /* dumping_off_vcd_partial_c_2 519 */ -1, /* start_time_vcd_partial_c_2 520 */ -1, /* end_time_vcd_partial_c_2 521 */ -1, /* current_time_vcd_partial_c_2 522 */ 0, /* num_glitches_vcd_partial_c_3 523 */ 0, /* num_glitch_regions_vcd_partial_c_3 524 */ NULL, /* pv_vcd_partial_c_2 525 */ NULL, /* rootv */ NULL, /* vcdbuf_vcd_partial_c_2 526 */ NULL, /* vst */ NULL, /* vend */ NULL, /* consume_ptr_vcd_partial_c_1 527 */ NULL, /* buf_vcd_partial_c_2 528 */ 100000, /* consume_countdown_vcd_partial_c_1 529 */ 1024, /* T_MAX_STR_vcd_partial_c_2 531 */ NULL, /* yytext_vcd_partial_c_2 532 */ 0, /* yylen_vcd_partial_c_2 533 */ 0, /* yylen_cache */ NULL, /* vcdsymroot_vcd_partial_c_2 534 */ NULL, /* vcdsymcurr */ NULL, /* sorted_vcd_partial_c_2 535 */ NULL, /* indexed_vcd_partial_c_2 536 */ 0, /* numsyms_vcd_partial_c_2 538 */ ~0, /* vcd_minid_vcd_partial_c_2 540 */ 0, /* vcd_maxid_vcd_partial_c_2 541 */ 0, /* err_vcd_partial_c_2 542 */ NULL, /* varsplit_vcd_partial_c_2 543 */ NULL, /* vsplitcurr */ 0, /* var_prevch_vcd_partial_c_2 544 */ 0, /* timeset_vcd_partial_c_1 547 */ /* * vcd_recoder.c */ NULL, /* time_vlist_vcd_recoder_c_1 548 */ NULL, /* time_vlist_vcd_recoder_write */ NULL, /* fastload_depacked */ NULL, /* fastload_current */ 0, /* time_vlist_count_vcd_recoder_c_1 549 */ NULL, /* vcd_handle_vcd_recoder_c_2 550 */ 0, /* vcd_is_compressed_vcd_recoder_c_2 551 */ VCD_FSL_NONE, /* use_fastload */ 0, /* vcdbyteno_vcd_recoder_c_3 552 */ 0, /* error_count_vcd_recoder_c_3 553 */ 0, /* header_over_vcd_recoder_c_3 554 */ 0, /* dumping_off_vcd_recoder_c_3 555 */ -1, /* start_time_vcd_recoder_c_3 556 */ -1, /* end_time_vcd_recoder_c_3 557 */ -1, /* current_time_vcd_recoder_c_3 558 */ 0, /* num_glitches_vcd_recoder_c_4 559 */ 0, /* num_glitch_regions_vcd_recoder_c_4 560 */ NULL, /* pv_vcd_recoder_c_3 561 */ NULL, /* rootv */ NULL, /* vcdbuf_vcd_recoder_c_3 562 */ NULL, /* vst */ NULL, /* vend */ 1024, /* T_MAX_STR_vcd_recoder_c_3 564 */ NULL, /* yytext_vcd_recoder_c_3 565 */ 0, /* yylen_vcd_recoder_c_3 566 */ 0, /* yylen_cache */ NULL, /* vcdsymroot_vcd_recoder_c_3 567 */ NULL, /* vcdsymcurr */ NULL, /* sorted_vcd_recoder_c_3 568 */ NULL, /* indexed_vcd_recoder_c_3 569 */ 0, /* numsyms_vcd_recoder_c_3 570 */ ~0, /* vcd_minid_vcd_recoder_c_3 571 */ 0, /* vcd_maxid_vcd_recoder_c_3 572 */ 0, /* err_vcd_recoder_c_3 573 */ 0, /* vcd_fsiz_vcd_recoder_c_2 574 */ NULL, /* varsplit_vcd_recoder_c_3 575 */ NULL, /* vsplitcurr */ 0, /* var_prevch_vcd_recoder_c_3 576 */ 0, /* vcd_hash_max */ 0, /* vcd_hash_kill */ /* * vcd_saver.c */ NULL, /* f_vcd_saver_c_1 579 */ {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0}, /* buf_vcd_saver_c_3 580 */ NULL, /* hp_vcd_saver_c_1 581 */ NULL, /* nhold_vcd_saver_c_1 582 */ /* * vlist.c */ 0, /* vlist_spill_to_disk */ 0, /* vlist_prepack */ NULL, /* vlist_handle */ 0, /* vlist_bytes_written */ 4, /* vlist_compression_depth 583 */ /* * vzt.c */ NULL, /* vzt_vzt_c_1 584 */ 0, /* first_cycle_vzt_c_3 585 */ 0, /* last_cycle */ 0, /* total_cycles */ NULL, /* vzt_table_vzt_c_1 586 */ NULL, /* mvlfacs_vzt_c_3 587 */ 0, /* busycnt_vzt_c_2 588 */ /* * wavewindow.c */ 0, /* highlight_wavewindow */ 1, /* alt_wheel_mode */ 0, /* use_scrollwheel_as_y */ 0, /* enable_slider_zoom */ 0, /* m1x_wavewindow_c_1 589 */ 0, /* m2x_wavewindow_c_1 */ 0, /* black_and_white */ 1, /* signalwindow_width_dirty 590 */ 1, /* enable_ghost_marker 591 */ 1, /* enable_horiz_grid 592 */ 1, /* enable_vert_grid 593 */ 0, /* use_big_fonts 594 */ 0, /* use_nonprop_fonts */ ~0, /* do_resize_signals 595 */ ~0, /* first_unsized_signals */ 0, /* initial_signal_window_width */ 0, /* constant_marker_update 596 */ 0, /* use_roundcaps 597 */ ~0, /* show_base 598 */ ~0, /* wave_scrolling 599 */ 4, /* vector_padding 600 */ 0, /* in_button_press_wavewindow_c_1 601 */ 0, /* left_justify_sigs 602 */ 0, /* zoom_pow10_snap 603 */ 0, /* zoom_dyn */ 0, /* zoom_dyne */ 0, /* cursor_snap 604 */ -1.0, /* old_wvalue 605 */ NULL, /* blackout_regions 606 */ 0, /* zoom 607 */ 1, /* scale */ 1, /* nsperframe */ 1, /* pixelsperframe 608 */ 1.0, /* hashstep 609 */ -1, /* prevtim_wavewindow_c_1 610 */ 1.0, /* pxns 611 */ 1.0, /* nspx */ 2.0, /* zoombase 612 */ NULL, /* topmost_trace 613 */ 1, /* waveheight 614 */ 0, /* wavecrosspiece */ 1, /* wavewidth 615 */ NULL, /* wavefont 616 */ NULL, /* wavefont_smaller 617 */ NULL, /* wavearea 618 */ NULL, /* vscroll_wavewindow_c_1 619 */ NULL, /* hscroll_wavewindow_c_2 620 */ NULL, /* wavepixmap_wavewindow_c_1 621 */ NULL, /* wave_vslider 622 */ NULL, /* wave_hslider */ {0}, /* named_markers 623 */ -1, /* named_marker_lock_idx */ 0, /* made_gc_contexts_wavewindow_c_1 624 */ 0, /* which_t_color */ NULL, /* gc_white 650 */ NULL, /* gc_black 651 */ {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, /* gc */ WAVE_RAINBOW_INITIALIZER, /* gc_rainbow */ 0, /* made_sgc_contexts_wavewindow_c_1 649 */ 0, /* fill_in_smaller_rgb_areas_wavewindow_c_1 659 */ -1, /* prev_markertime */ {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, /* gccache */ 20, /* analog_redraw_skip_count */ 0, /* str_wid_x */ 0, /* str_wid_width */ 0, /* str_wid_bigw */ 0, /* str_wid_state */ 0, /* str_wid_slider */ 0, /* str_wid_height */ 0, /* ruler_origin */ 0, /* ruler_step */ /* * zoombuttons.c */ 1, /* do_zoom_center 660 */ 0, /* do_initial_zoom_fit 661 */ 0, /* do_initial_zoom_fit_used */ }; /* * prototypes (because of struct Global header recursion issues */ void *calloc_2_into_context(struct Global *g, size_t nmemb, size_t size); /* * context manipulation functions */ struct Global *initialize_globals(void) { struct Global *g = calloc(1,sizeof(struct Global)); /* allocate viewer context */ memcpy(g, &globals_base_values, sizeof(struct Global)); /* fill in the blanks */ g->gtk_context_bridge_ptr = calloc(1, sizeof(struct Global *)); *(g->gtk_context_bridge_ptr) = g; g->buf_menu_c_1 = calloc_2_into_context(g, 1, 65537); /* do remaining mallocs into new ctx */ g->regexp_string_menu_c_1 = calloc_2_into_context(g, 1, 129); g->regex_ok_regex_c_1 = calloc_2_into_context(g, WAVE_REGEX_TOTAL, sizeof(int)); g->preg_regex_c_1 = calloc_2_into_context(g, WAVE_REGEX_TOTAL, sizeof(regex_t)); g->strace_ctx = &g->strace_windows[0]; /* arbitrarily point to first one */ return(g); /* what to do with ctx is at discretion of caller */ } void strcpy2_into_new_context(struct Global *g, char **newstrref, char **oldstrref) { char *o = *oldstrref; char *n; if(o) /* only allocate + copy string if nonnull pointer */ { n = calloc_2_into_context(g, 1, strlen(o) + 1); strcpy(n, o); *newstrref = n; } } /* * widget destruction functions */ static void widget_ungrab_destroy(GtkWidget **wp) { if(*wp) { wave_gtk_grab_remove(*wp); gtk_widget_destroy(*wp); *wp = NULL; } } static void widget_only_destroy(GtkWidget **wp) { if(*wp) { gtk_widget_destroy(*wp); *wp = NULL; } } /* * setjump to avoid -Wclobbered issues */ static int handle_setjmp(void) { struct Global *setjmp_globals; int load_was_success = 0; GLOBALS->vcd_jmp_buf = calloc(1, sizeof(jmp_buf)); setjmp_globals = calloc(1,sizeof(struct Global)); /* allocate yet another copy of viewer context */ memcpy(setjmp_globals, GLOBALS, sizeof(struct Global)); /* clone */ GLOBALS->alloc2_chain = NULL; /* will merge this in after load if successful */ GLOBALS->outstanding = 0; /* zero out count of chunks in this ctx */ if(!setjmp(*(GLOBALS->vcd_jmp_buf))) /* loader exception handling */ { switch(GLOBALS->loaded_file_type) /* on fail, longjmp called in these loaders */ { case LXT_FILE: lxt_main(GLOBALS->loaded_file_name); break; case VCD_FILE: vcd_main(GLOBALS->loaded_file_name); break; case VCD_RECODER_FILE: vcd_recoder_main(GLOBALS->loaded_file_name); break; default: break; } #ifdef _WAVE_HAVE_JUDY { Pvoid_t PJArray = (Pvoid_t)setjmp_globals->alloc2_chain; int rcValue; Word_t Index; Index = 0; for (rcValue = Judy1First(PJArray, &Index, PJE0); rcValue != 0; rcValue = Judy1Next(PJArray, &Index, PJE0)) { Judy1Set ((Pvoid_t)&GLOBALS->alloc2_chain, Index, PJE0); } GLOBALS->outstanding += setjmp_globals->outstanding; Judy1FreeArray(&PJArray, PJE0); } #else { void **t, **t2; t = (void **)setjmp_globals->alloc2_chain; while(t) { t2 = (void **) *(t+1); if(t2) { t = t2; } else { *(t+1) = GLOBALS->alloc2_chain; if(GLOBALS->alloc2_chain) { t2 = (void **)GLOBALS->alloc2_chain; *(t2+0) = t; } GLOBALS->alloc2_chain = setjmp_globals->alloc2_chain; GLOBALS->outstanding += setjmp_globals->outstanding; break; } } } #endif free(GLOBALS->vcd_jmp_buf); GLOBALS->vcd_jmp_buf = NULL; free(setjmp_globals); setjmp_globals = NULL; load_was_success = 1; } else { free(GLOBALS->vcd_jmp_buf); GLOBALS->vcd_jmp_buf = NULL; if(GLOBALS->vcd_handle_vcd_c_1) { if(GLOBALS->vcd_is_compressed_vcd_c_1) { pclose(GLOBALS->vcd_handle_vcd_c_1); GLOBALS->vcd_handle_vcd_c_1 = NULL; } else { fclose(GLOBALS->vcd_handle_vcd_c_1); GLOBALS->vcd_handle_vcd_c_1 = NULL; } } if(GLOBALS->vcd_handle_vcd_recoder_c_2) { if(GLOBALS->vcd_is_compressed_vcd_recoder_c_2) { pclose(GLOBALS->vcd_handle_vcd_recoder_c_2); GLOBALS->vcd_handle_vcd_recoder_c_2 = NULL; } else { fclose(GLOBALS->vcd_handle_vcd_recoder_c_2); GLOBALS->vcd_handle_vcd_recoder_c_2 = NULL; } } if(GLOBALS->vlist_handle) { fclose(GLOBALS->vlist_handle); GLOBALS->vlist_handle = NULL; } if(GLOBALS->mm_lxt_mmap_addr) { munmap(GLOBALS->mm_lxt_mmap_addr, GLOBALS->mm_lxt_mmap_len); GLOBALS->mm_lxt_mmap_addr = NULL; } free_outstanding(); /* free anything allocated in loader ctx */ memcpy(GLOBALS, setjmp_globals, sizeof(struct Global)); /* copy over old ctx */ free(setjmp_globals); /* remove cached old ctx */ /* now try again, jump through recovery sequence below */ } return(load_was_success); } /* * reload from old into the new context */ void reload_into_new_context_2(void) { FILE *statefile; struct Global *new_globals; /* gint tree_frame_x = -1; */ /* scan-build */ #if WAVE_USE_GTK2 gint tree_frame_y = -1; gdouble tree_vadj_value = 0.0; gdouble tree_hadj_value = 0.0; gdouble treeview_vadj_value = 0.0; gdouble treeview_hadj_value = 0.0; #endif int fix_from_time = 0, fix_to_time = 0; TimeType from_time = LLDescriptor(0), to_time = LLDescriptor(0); char timestr[32]; struct stringchain_t *hier_head = NULL, *hier_curr = NULL; int load_was_success = 0; int reload_fail_delay = 1; char *save_tmpfilename = NULL; char *reload_tmpfilename = NULL; int fd_dummy = -1; int s_ctx_iter; /* save these in case we decide to write out the rc file later as a user option */ char cached_ignore_savefile_pane_pos = GLOBALS->ignore_savefile_pane_pos; char cached_ignore_savefile_pos = GLOBALS->ignore_savefile_pos; char cached_ignore_savefile_size = GLOBALS->ignore_savefile_size; char cached_splash_disable = GLOBALS->splash_disable; if((GLOBALS->loaded_file_type == MISSING_FILE)||(GLOBALS->is_optimized_stdin_vcd)) { fprintf(stderr, "GTKWAVE | Nothing to reload!\n"); return; } logbox_reload(); /* kill any pending splash screens (e.g., from Tcl "wish") */ splash_button_press_event(NULL, NULL); /* fix problem where ungrab doesn't occur if button pressed + simultaneous reload accelerator key occurs */ if(GLOBALS->in_button_press_wavewindow_c_1) { gdk_pointer_ungrab(GDK_CURRENT_TIME); } /* let all GTK/X events spin through in order to keep menus from freezing open during reload */ #ifndef MAC_INTEGRATION if(GLOBALS->text_status_c_2) { wave_gtk_grab_add(GLOBALS->text_status_c_2); /* grab focus to a known widget with no real side effects */ gtkwave_main_iteration(); /* spin on GTK event loop */ wave_gtk_grab_remove(GLOBALS->text_status_c_2); /* ungrab focus */ } #endif printf("GTKWAVE | Reloading waveform...\n"); gtkwavetcl_setvar(WAVE_TCLCB_RELOAD_BEGIN, GLOBALS->loaded_file_name, WAVE_TCLCB_RELOAD_BEGIN_FLAGS); /* Save state to file */ save_tmpfilename = tmpnam_2(NULL, &fd_dummy); statefile = save_tmpfilename ? fopen(save_tmpfilename,"wb") : NULL; if(statefile == NULL) { fprintf(stderr, "Failed to create temp file required for file reload.\n"); if(save_tmpfilename) { perror("Why"); free_2(save_tmpfilename); } gtkwavetcl_setvar_nonblocking(WAVE_TCLCB_ERROR,"reload failed",WAVE_TCLCB_ERROR_FLAGS); return; } if(fd_dummy >=0) close(fd_dummy); write_save_helper(save_tmpfilename, statefile); fclose(statefile); reload_tmpfilename = strdup(save_tmpfilename); free_2(save_tmpfilename); /* save off size of tree frame if active */ #if WAVE_USE_GTK2 if(GLOBALS->gtk2_tree_frame) { /* upper tree */ GtkCList *cl = GTK_CLIST(GLOBALS->ctree_main); GtkAdjustment *vadj = gtk_clist_get_vadjustment(cl); GtkAdjustment *hadj = gtk_clist_get_hadjustment(cl); if(vadj) tree_vadj_value = vadj->value; if(hadj) tree_hadj_value = hadj->value; /* tree_frame_x = (GLOBALS->gtk2_tree_frame)->allocation.width; */ /* scan-build */ tree_frame_y = (GLOBALS->gtk2_tree_frame)->allocation.height; /* lower signal set */ vadj = gtk_tree_view_get_vadjustment((GtkTreeView *)GLOBALS->dnd_sigview); hadj = gtk_tree_view_get_hadjustment((GtkTreeView *)GLOBALS->dnd_sigview); if(vadj) treeview_vadj_value = vadj->value; if(hadj) treeview_hadj_value = hadj->value; } #endif /* Kill any open processes */ remove_all_proc_filters(); remove_all_ttrans_filters(); /* Instantiate new global status */ new_globals = initialize_globals(); free(new_globals->gtk_context_bridge_ptr); /* don't need this one as we're copying over the old one... */ new_globals->gtk_context_bridge_ptr = GLOBALS->gtk_context_bridge_ptr; /* SMP */ new_globals->num_cpus = GLOBALS->num_cpus; /* tcl interpreter */ #if defined(HAVE_LIBTCL) new_globals->interp = GLOBALS->interp; #endif /* lxt.c */ if(GLOBALS->fd_lxt_c_1 >= 0) { close(GLOBALS->fd_lxt_c_1); GLOBALS->fd_lxt_c_1 = -1; } /* Marker positions */ memcpy(new_globals->named_markers, GLOBALS->named_markers, sizeof(GLOBALS->named_markers)); new_globals->named_marker_lock_idx = GLOBALS->named_marker_lock_idx; /* notebook page flipping */ new_globals->num_notebook_pages = GLOBALS->num_notebook_pages; new_globals->num_notebook_pages_cumulative = GLOBALS->num_notebook_pages_cumulative; new_globals->this_context_page = GLOBALS->this_context_page; new_globals->contexts = GLOBALS->contexts; /* this value is a *** chameleon! malloc'd region is outside debug.c control! */ new_globals->notebook = GLOBALS->notebook; new_globals->second_page_created = GLOBALS->second_page_created; (*new_globals->contexts)[new_globals->this_context_page] = new_globals; new_globals->dead_context = GLOBALS->dead_context; /* this value is a ** chameleon! malloc'd region is outside debug.c control! */ /* to cut down on temporary visual noise from incorrect zoom factor on reload */ new_globals->pixelsperframe = GLOBALS->pixelsperframe; new_globals->nsperframe = GLOBALS->nsperframe; new_globals->pxns = GLOBALS->pxns; new_globals->nspx = GLOBALS->nspx; new_globals->nspx = GLOBALS->nspx; new_globals->zoom = GLOBALS->zoom; /* Default colors, X contexts, pixmaps, drawables, etc from signalwindow.c and wavewindow.c */ new_globals->possibly_use_rc_defaults = GLOBALS->possibly_use_rc_defaults; new_globals->signalarea_event_box = GLOBALS->signalarea_event_box; new_globals->keypress_handler_id = GLOBALS->keypress_handler_id; new_globals->signalarea = GLOBALS->signalarea; new_globals->wavearea = GLOBALS->wavearea; new_globals->wavepixmap_wavewindow_c_1 = GLOBALS->wavepixmap_wavewindow_c_1; new_globals->signalpixmap = GLOBALS->signalpixmap; new_globals->wave_splash_pixmap = GLOBALS->wave_splash_pixmap; new_globals->wave_splash_mask = GLOBALS->wave_splash_mask; new_globals->black_and_white = GLOBALS->black_and_white; new_globals->gc_white = GLOBALS->gc_white; new_globals->gc_black = GLOBALS->gc_black; memcpy(&new_globals->gc, &GLOBALS->gc, sizeof(struct wave_gcmaster_t)); new_globals->made_sgc_contexts_wavewindow_c_1 = GLOBALS->made_sgc_contexts_wavewindow_c_1; new_globals->made_gc_contexts_wavewindow_c_1 = GLOBALS->made_gc_contexts_wavewindow_c_1; memcpy(&new_globals->gccache, &GLOBALS->gccache, sizeof(struct wave_gcmaster_t)); memcpy(&new_globals->gc_rainbow, &GLOBALS->gc_rainbow, 2 * WAVE_NUM_RAINBOW * sizeof(GdkGC *)); new_globals->mainwindow = GLOBALS->mainwindow; new_globals->signalwindow = GLOBALS->signalwindow; new_globals->wavewindow = GLOBALS->wavewindow; new_globals->toppanedwindow = GLOBALS->toppanedwindow; new_globals->panedwindow = GLOBALS->panedwindow; new_globals->sstpane = GLOBALS->sstpane; new_globals->sst_vpaned = GLOBALS->sst_vpaned; new_globals->expanderwindow = GLOBALS->expanderwindow; new_globals->signal_hslider = GLOBALS->signal_hslider; new_globals->wave_vslider = GLOBALS->wave_vslider; new_globals->wave_hslider = GLOBALS->wave_hslider; new_globals->hscroll_wavewindow_c_2 = GLOBALS->hscroll_wavewindow_c_2; new_globals->max_or_marker_label_currenttime_c_1 = GLOBALS->max_or_marker_label_currenttime_c_1; new_globals->maxtext_currenttime_c_1 = (char *) calloc_2_into_context(new_globals,1,40); memcpy(new_globals->maxtext_currenttime_c_1, GLOBALS->maxtext_currenttime_c_1,40); new_globals->maxtimewid_currenttime_c_1 = GLOBALS->maxtimewid_currenttime_c_1; new_globals->curtext_currenttime_c_1 = (char *) calloc_2_into_context(new_globals,1,40); memcpy(new_globals->curtext_currenttime_c_1, GLOBALS->curtext_currenttime_c_1, 40); new_globals->base_or_curtime_label_currenttime_c_1 = GLOBALS->base_or_curtime_label_currenttime_c_1; new_globals->curtimewid_currenttime_c_1 = GLOBALS->curtimewid_currenttime_c_1; new_globals->from_entry = GLOBALS->from_entry; new_globals->to_entry = GLOBALS->to_entry; new_globals->fontheight = GLOBALS->fontheight; new_globals->wavecrosspiece = GLOBALS->wavecrosspiece; new_globals->signalfont = calloc_2_into_context(new_globals, 1, sizeof(struct font_engine_font_t)); memcpy(new_globals->signalfont, GLOBALS->signalfont, sizeof(struct font_engine_font_t)); new_globals->wavefont = calloc_2_into_context(new_globals, 1, sizeof(struct font_engine_font_t)); memcpy(new_globals->wavefont, GLOBALS->wavefont, sizeof(struct font_engine_font_t)); new_globals->wavefont_smaller = calloc_2_into_context(new_globals, 1, sizeof(struct font_engine_font_t)); memcpy(new_globals->wavefont_smaller, GLOBALS->wavefont_smaller, sizeof(struct font_engine_font_t)); #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) && GTK_CHECK_VERSION(2,8,0) new_globals->fonts_renderer = GLOBALS->fonts_renderer; new_globals->fonts_gc = GLOBALS->fonts_gc; new_globals->fonts_screen = GLOBALS->fonts_screen; new_globals->fonts_context = GLOBALS->fonts_context; new_globals->fonts_layout = GLOBALS->fonts_layout; #endif new_globals->use_pango_fonts = GLOBALS->use_pango_fonts; new_globals->ruler_origin = GLOBALS->ruler_origin; new_globals->ruler_step = GLOBALS->ruler_step; /* busy.c */ new_globals->busycursor_busy_c_1 = GLOBALS->busycursor_busy_c_1; new_globals->busy_busy_c_1 = GLOBALS->busy_busy_c_1; /* pixmaps.c */ new_globals->redo_pixmap = GLOBALS->redo_pixmap; new_globals->larrow_pixmap = GLOBALS->larrow_pixmap; new_globals->rarrow_pixmap = GLOBALS->rarrow_pixmap; new_globals->zoomout_pixmap = GLOBALS->zoomout_pixmap; new_globals->zoomin_pixmap = GLOBALS->zoomin_pixmap; new_globals->zoomfit_pixmap = GLOBALS->zoomfit_pixmap; new_globals->zoomundo_pixmap = GLOBALS->zoomundo_pixmap; new_globals->zoom_larrow_pixmap = GLOBALS->zoom_larrow_pixmap; new_globals->zoom_rarrow_pixmap = GLOBALS->zoom_rarrow_pixmap; new_globals->prev_page_pixmap = GLOBALS->prev_page_pixmap; new_globals->next_page_pixmap = GLOBALS->next_page_pixmap; new_globals->wave_info_pixmap = GLOBALS->wave_info_pixmap; new_globals->wave_alert_pixmap = GLOBALS->wave_alert_pixmap; clone_icon_pointers_across_contexts(new_globals, GLOBALS); /* rc.c */ new_globals->scale_to_time_dimension = GLOBALS->scale_to_time_dimension; new_globals->zoom_dyn = GLOBALS->zoom_dyn; new_globals->zoom_dyne = GLOBALS->zoom_dyne; new_globals->use_scrollwheel_as_y = GLOBALS->use_scrollwheel_as_y; new_globals->enable_slider_zoom = GLOBALS->enable_slider_zoom; new_globals->context_tabposition = GLOBALS->context_tabposition; new_globals->use_standard_clicking = GLOBALS->use_standard_clicking; new_globals->ignore_savefile_pane_pos = 1; /* to keep window from resizing/jumping */ new_globals->ignore_savefile_pos = 1; /* to keep window from resizing/jumping */ new_globals->ignore_savefile_size = 1; /* to keep window from resizing/jumping */ new_globals->color_back = GLOBALS->color_back; new_globals->color_baseline = GLOBALS->color_baseline; new_globals->color_grid = GLOBALS->color_grid; new_globals->color_grid2 = GLOBALS->color_grid2; new_globals->color_high = GLOBALS->color_high; new_globals->color_low = GLOBALS->color_low; new_globals->color_1 = GLOBALS->color_1; new_globals->color_0 = GLOBALS->color_0; new_globals->color_mark = GLOBALS->color_mark; new_globals->color_mid = GLOBALS->color_mid; new_globals->color_time = GLOBALS->color_time; new_globals->color_timeb = GLOBALS->color_timeb; new_globals->color_trans = GLOBALS->color_trans; new_globals->color_umark = GLOBALS->color_umark; new_globals->color_value = GLOBALS->color_value; new_globals->color_vbox = GLOBALS->color_vbox; new_globals->color_vtrans = GLOBALS->color_vtrans; new_globals->color_x = GLOBALS->color_x; new_globals->color_xfill = GLOBALS->color_xfill; new_globals->color_u = GLOBALS->color_u; new_globals->color_ufill = GLOBALS->color_ufill; new_globals->color_w = GLOBALS->color_w; new_globals->color_wfill = GLOBALS->color_wfill; new_globals->color_dash = GLOBALS->color_dash; new_globals->color_dashfill = GLOBALS->color_dashfill; new_globals->color_white = GLOBALS->color_white; new_globals->color_black = GLOBALS->color_black; new_globals->color_ltgray = GLOBALS->color_ltgray; new_globals->color_normal = GLOBALS->color_normal; new_globals->color_mdgray = GLOBALS->color_mdgray; new_globals->color_dkgray = GLOBALS->color_dkgray; new_globals->color_dkblue = GLOBALS->color_dkblue; new_globals->color_brkred = GLOBALS->color_brkred; new_globals->color_ltblue = GLOBALS->color_ltblue; new_globals->color_gmstrd = GLOBALS->color_gmstrd; new_globals->atomic_vectors = GLOBALS->atomic_vectors; new_globals->autoname_bundles = GLOBALS->autoname_bundles; new_globals->autocoalesce = GLOBALS->autocoalesce; new_globals->autocoalesce_reversal = GLOBALS->autocoalesce_reversal; new_globals->constant_marker_update = GLOBALS->constant_marker_update; new_globals->convert_to_reals = GLOBALS->convert_to_reals; new_globals->disable_mouseover = GLOBALS->disable_mouseover; new_globals->keep_xz_colors = GLOBALS->keep_xz_colors; new_globals->disable_tooltips = GLOBALS->disable_tooltips; new_globals->do_hier_compress = GLOBALS->do_hier_compress; new_globals->do_initial_zoom_fit = GLOBALS->do_initial_zoom_fit; new_globals->do_initial_zoom_fit_used = GLOBALS->do_initial_zoom_fit_used; new_globals->do_resize_signals = GLOBALS->do_resize_signals; new_globals->alt_wheel_mode = GLOBALS->alt_wheel_mode; new_globals->initial_signal_window_width = GLOBALS->initial_signal_window_width; new_globals->enable_fast_exit = GLOBALS->enable_fast_exit; new_globals->enable_ghost_marker = GLOBALS->enable_ghost_marker; new_globals->enable_horiz_grid = GLOBALS->enable_horiz_grid; new_globals->make_vcd_save_file = GLOBALS->make_vcd_save_file; new_globals->enable_vert_grid = GLOBALS->enable_vert_grid; new_globals->force_toolbars = GLOBALS->force_toolbars; new_globals->hide_sst = GLOBALS->hide_sst; new_globals->sst_expanded = GLOBALS->sst_expanded; new_globals->hier_grouping = GLOBALS->hier_grouping; new_globals->hier_max_level = GLOBALS->hier_max_level; new_globals->hier_max_level_shadow = GLOBALS->hier_max_level_shadow; new_globals->paned_pack_semantics = GLOBALS->paned_pack_semantics; new_globals->left_justify_sigs = GLOBALS->left_justify_sigs; new_globals->lxt_clock_compress_to_z = GLOBALS->lxt_clock_compress_to_z; new_globals->ps_maxveclen = GLOBALS->ps_maxveclen; new_globals->show_base = GLOBALS->show_base; new_globals->display_grid = GLOBALS->display_grid; new_globals->highlight_wavewindow = GLOBALS->highlight_wavewindow; new_globals->use_standard_trace_select = GLOBALS->use_standard_trace_select; new_globals->use_big_fonts = GLOBALS->use_big_fonts; new_globals->use_full_precision = GLOBALS->use_full_precision; new_globals->use_frequency_delta = GLOBALS->use_frequency_delta; new_globals->use_maxtime_display = GLOBALS->use_maxtime_display; new_globals->use_nonprop_fonts = GLOBALS->use_nonprop_fonts; new_globals->use_roundcaps = GLOBALS->use_roundcaps; new_globals->use_scrollbar_only = GLOBALS->use_scrollbar_only; new_globals->vcd_explicit_zero_subscripts = GLOBALS->vcd_explicit_zero_subscripts; new_globals->vcd_preserve_glitches = GLOBALS->vcd_preserve_glitches; new_globals->vcd_preserve_glitches_real = GLOBALS->vcd_preserve_glitches_real; new_globals->vcd_warning_filesize = GLOBALS->vcd_warning_filesize; new_globals->vector_padding = GLOBALS->vector_padding; new_globals->vlist_prepack = GLOBALS->vlist_prepack; new_globals->vlist_spill_to_disk = GLOBALS->vlist_spill_to_disk; new_globals->vlist_compression_depth = GLOBALS->vlist_compression_depth; new_globals->wave_scrolling = GLOBALS->wave_scrolling; new_globals->do_zoom_center = GLOBALS->do_zoom_center; new_globals->zoom_pow10_snap = GLOBALS->zoom_pow10_snap; new_globals->alt_hier_delimeter = GLOBALS->alt_hier_delimeter; new_globals->cursor_snap = GLOBALS->cursor_snap; new_globals->hier_delimeter = GLOBALS->hier_delimeter; new_globals->hier_was_explicitly_set = GLOBALS->hier_was_explicitly_set; new_globals->page_divisor = GLOBALS->page_divisor; new_globals->ps_maxveclen = GLOBALS->ps_maxveclen; new_globals->vector_padding = GLOBALS->vector_padding; new_globals->zoombase = GLOBALS->zoombase; new_globals->disable_ae2_alias = GLOBALS->disable_ae2_alias; new_globals->splash_disable = 1; /* to disable splash for reload */ new_globals->strace_repeat_count = GLOBALS->strace_repeat_count; /* for edgebuttons and also strace */ new_globals->logfiles = GLOBALS->logfiles; /* this value is a ** chameleon! malloc'd region is outside debug.c control! */ strcpy2_into_new_context(new_globals, &new_globals->argvlist, &GLOBALS->argvlist); strcpy2_into_new_context(new_globals, &new_globals->editor_name, &GLOBALS->editor_name); strcpy2_into_new_context(new_globals, &new_globals->fontname_logfile, &GLOBALS->fontname_logfile); strcpy2_into_new_context(new_globals, &new_globals->fontname_signals, &GLOBALS->fontname_signals); strcpy2_into_new_context(new_globals, &new_globals->fontname_waves, &GLOBALS->fontname_waves); strcpy2_into_new_context(new_globals, &new_globals->cutcopylist, &GLOBALS->cutcopylist); strcpy2_into_new_context(new_globals, &new_globals->tcl_init_cmd, &GLOBALS->tcl_init_cmd); strcpy2_into_new_context(new_globals, &new_globals->repscript_name, &GLOBALS->repscript_name); new_globals->repscript_period = GLOBALS->repscript_period; #if GTK_CHECK_VERSION(2,4,0) strcpy2_into_new_context(new_globals, &new_globals->pFileChooseFilterName, &GLOBALS->pFileChooseFilterName); #endif /* ttranslate.c */ strcpy2_into_new_context(new_globals, &new_globals->ttranslate_args, &GLOBALS->ttranslate_args); /* vlist.c */ if(GLOBALS->vlist_handle) { vlist_kill_spillfile(); new_globals->use_fastload = (GLOBALS->use_fastload != VCD_FSL_NONE) ? VCD_FSL_WRITE : VCD_FSL_NONE; } /* lxt2.c / vzt.c / ae2.c */ strcpy2_into_new_context(new_globals, &new_globals->skip_start, &GLOBALS->skip_start); strcpy2_into_new_context(new_globals, &new_globals->skip_end, &GLOBALS->skip_end); /* main.c */ new_globals->missing_file_toolbar = GLOBALS->missing_file_toolbar; new_globals->is_gtkw_save_file = GLOBALS->is_gtkw_save_file; new_globals->use_toolbutton_interface = GLOBALS->use_toolbutton_interface; new_globals->optimize_vcd = GLOBALS->optimize_vcd; strcpy2_into_new_context(new_globals, &new_globals->winname, &GLOBALS->winname); /* for page swapping */ /* menu.c */ new_globals->wave_script_args = GLOBALS->wave_script_args; #ifndef WAVE_USE_MLIST_T new_globals->item_factory_menu_c_1 = GLOBALS->item_factory_menu_c_1; #endif strcpy2_into_new_context(new_globals, &new_globals->filesel_writesave, &GLOBALS->filesel_writesave); new_globals->save_success_menu_c_1 = GLOBALS->save_success_menu_c_1; new_globals->signal_popup_menu = GLOBALS->signal_popup_menu; new_globals->sst_signal_popup_menu = GLOBALS->sst_signal_popup_menu; strcpy2_into_new_context(new_globals, &new_globals->filesel_vcd_writesave, &GLOBALS->filesel_vcd_writesave); strcpy2_into_new_context(new_globals, &new_globals->filesel_lxt_writesave, &GLOBALS->filesel_lxt_writesave); strcpy2_into_new_context(new_globals, &new_globals->filesel_tim_writesave, &GLOBALS->filesel_tim_writesave); strcpy2_into_new_context(new_globals, &new_globals->stems_name, &GLOBALS->stems_name); /* remaining fileselbox() vars not handled elsewhere */ strcpy2_into_new_context(new_globals, &new_globals->filesel_logfile_menu_c_1, &GLOBALS->filesel_logfile_menu_c_1); strcpy2_into_new_context(new_globals, &new_globals->filesel_scriptfile_menu, &GLOBALS->filesel_scriptfile_menu); strcpy2_into_new_context(new_globals, &new_globals->fcurr_ttranslate_c_1, &GLOBALS->fcurr_ttranslate_c_1); strcpy2_into_new_context(new_globals, &new_globals->fcurr_ptranslate_c_1, &GLOBALS->fcurr_ptranslate_c_1); strcpy2_into_new_context(new_globals, &new_globals->fcurr_translate_c_2, &GLOBALS->fcurr_translate_c_2); strcpy2_into_new_context(new_globals, &new_globals->filesel_imagegrab, &GLOBALS->filesel_imagegrab); /* renderopt.c */ #ifdef WAVE_GTK_UNIX_PRINT new_globals->gprs = GLOBALS->gprs; new_globals->gps = GLOBALS->gps; #endif /* status.c */ new_globals->text_status_c_2 = GLOBALS->text_status_c_2; #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) memcpy(&new_globals->iter_status_c_3, &GLOBALS->iter_status_c_3, sizeof(GtkTextIter)); #endif /* treesearch_gtk2.c */ new_globals->do_dynamic_treefilter = GLOBALS->do_dynamic_treefilter; new_globals->treesearch_gtk2_window_vbox = GLOBALS->treesearch_gtk2_window_vbox; new_globals->window_treesearch_gtk2_c_12 = GLOBALS->window_treesearch_gtk2_c_12; new_globals->dnd_sigview = GLOBALS->dnd_sigview; strcpy2_into_new_context(new_globals, &new_globals->filter_str_treesearch_gtk2_c_1, &GLOBALS->filter_str_treesearch_gtk2_c_1); strcpy2_into_new_context(new_globals, &new_globals->selected_hierarchy_name, &GLOBALS->selected_hierarchy_name); new_globals->filter_typ_treesearch_gtk2_c_1 = GLOBALS->filter_typ_treesearch_gtk2_c_1; new_globals->filter_matlen_treesearch_gtk2_c_1 = GLOBALS->filter_matlen_treesearch_gtk2_c_1; new_globals->filter_noregex_treesearch_gtk2_c_1 = GLOBALS->filter_noregex_treesearch_gtk2_c_1; /* timeentry.c */ new_globals->from_entry = GLOBALS->from_entry; new_globals->to_entry = GLOBALS->to_entry; if(GLOBALS->tims.first != GLOBALS->min_time) { fix_from_time = 1; from_time = GLOBALS->tims.first; } if(GLOBALS->tims.last != GLOBALS->max_time) { fix_to_time = 1; to_time = GLOBALS->tims.last; } /* twinwave stuff */ new_globals->dual_attach_id_main_c_1 = GLOBALS->dual_attach_id_main_c_1; new_globals->dual_id = GLOBALS->dual_id; #ifdef WAVE_USE_GTK2 new_globals->socket_xid = GLOBALS->socket_xid; #endif new_globals->dual_ctx = GLOBALS->dual_ctx; /* Times struct */ memcpy(&(new_globals->tims), &(GLOBALS->tims), sizeof(Times)); /* File name and type */ new_globals->loaded_file_type = GLOBALS->loaded_file_type; strcpy2_into_new_context(new_globals, &new_globals->loaded_file_name, &GLOBALS->loaded_file_name); if(new_globals->optimize_vcd) { strcpy2_into_new_context(new_globals, &new_globals->unoptimized_vcd_file_name, &GLOBALS->unoptimized_vcd_file_name); } /* fst.c, though might be others later */ if(GLOBALS->subvar_jrb) { jrb_free_tree(GLOBALS->subvar_jrb); GLOBALS->subvar_jrb = NULL; GLOBALS->subvar_jrb_count = 0; } if(GLOBALS->synclock_jrb) { jrb_free_tree(GLOBALS->synclock_jrb); GLOBALS->synclock_jrb = NULL; } /* deallocate any loader-related stuff */ switch(GLOBALS->loaded_file_type) { case LXT_FILE: if(GLOBALS->mm_lxt_mmap_addr) { munmap(GLOBALS->mm_lxt_mmap_addr, GLOBALS->mm_lxt_mmap_len); } break; case LX2_FILE: lxt2_rd_close(GLOBALS->lx2_lx2_c_1); break; case VZT_FILE: vzt_rd_close(GLOBALS->vzt_vzt_c_1); break; case FST_FILE: fstReaderClose(GLOBALS->fst_fst_c_1); GLOBALS->fst_fst_c_1 = NULL; break; case AE2_FILE: #ifdef AET2_IS_PRESENT #ifdef AET2_ALIASDB_IS_PRESENT if(GLOBALS->adb) { adb_close_db(GLOBALS->adb); GLOBALS->adb = 0; } /* if(GLOBALS->m_alias_stream_file) { fclose(GLOBALS->m_alias_stream_file); GLOBALS->m_alias_stream_file = NULL; } */ ae2_read_end(GLOBALS->ae2); fclose(GLOBALS->ae2_f); #endif #endif break; #ifdef EXTLOAD_SUFFIX case EXTLOAD_FILE: if(GLOBALS->extload_ffr_ctx) { #ifdef WAVE_FSDB_READER_IS_PRESENT fsdbReaderClose(GLOBALS->extload_ffr_ctx); #endif GLOBALS->extload_ffr_ctx = NULL; } break; #endif case MISSING_FILE: case DUMPLESS_FILE: case GHW_FILE: case VCD_FILE: case VCD_RECODER_FILE: default: /* do nothing */ break; } /* window destruction (of windows that aren't the parent window) */ #if !defined _MSC_VER kill_stems_browser(); /* for now, need to rework the stems browser dumpfile access routines to support this properly */ new_globals->stems_type = GLOBALS->stems_type; strcpy2_into_new_context(new_globals, &new_globals->aet_name, &GLOBALS->aet_name); #endif /* remaining windows which are completely destroyed and haven't migrated over */ widget_only_destroy(&GLOBALS->window_ptranslate_c_5); /* ptranslate.c */ WAVE_STRACE_ITERATOR(s_ctx_iter) { GLOBALS->strace_ctx = &GLOBALS->strace_windows[GLOBALS->strace_current_window = s_ctx_iter]; widget_only_destroy(&GLOBALS->strace_ctx->window_strace_c_10); /* strace.c */ } widget_only_destroy(&GLOBALS->window_translate_c_11); /* translate.c */ widget_only_destroy(&GLOBALS->window_treesearch_gtk1_c); /* treesearch_gtk1.c */ widget_only_destroy(&GLOBALS->window_help_c_2); /* help.c : reload is gated off during help so this should never execute */ /* windows which in theory should never destroy as they will have grab focus which means reload will not be called */ widget_ungrab_destroy(&GLOBALS->window_entry_c_1); /* entry.c */ widget_ungrab_destroy(&GLOBALS->window1_hiersearch_c_1); /* hiersearch.c */ widget_ungrab_destroy(&GLOBALS->window_markerbox_c_4); /* markerbox.c */ widget_ungrab_destroy(&GLOBALS->window1_search_c_2); /* search.c */ widget_ungrab_destroy(&GLOBALS->window_showchange_c_8); /* showchange.c */ widget_ungrab_destroy(&GLOBALS->window_simplereq_c_9); /* simplereq.c */ widget_ungrab_destroy(&GLOBALS->window1_treesearch_gtk1_c); /* treesearch_gtk1.c */ widget_ungrab_destroy(&GLOBALS->window1_treesearch_gtk2_c_3); /* treesearch_gtk2.c */ /* supported migration of window contexts... */ if(GLOBALS->window_hiersearch_c_3) { struct treechain *tc = GLOBALS->treechain_hiersearch_c_1; while(tc) { char *tclname; if(!hier_curr) { hier_head = hier_curr = calloc_2_into_context(new_globals,1,sizeof(struct stringchain_t)); } else { hier_curr->next = calloc_2_into_context(new_globals,1,sizeof(struct stringchain_t)); hier_curr = hier_curr->next; } tclname = &tc->label->name[0]; strcpy2_into_new_context(new_globals, &hier_curr->name, &tclname); tc = tc->next; } new_globals->window_hiersearch_c_3 = GLOBALS->window_hiersearch_c_3; new_globals->entry_main_hiersearch_c_1 = GLOBALS->entry_main_hiersearch_c_1; new_globals->clist_hiersearch_c_1 = GLOBALS->clist_hiersearch_c_1; new_globals->bundle_direction_hiersearch_c_1 = GLOBALS->bundle_direction_hiersearch_c_1; new_globals->cleanup_hiersearch_c_3 = GLOBALS->cleanup_hiersearch_c_3; new_globals->is_active_hiersearch_c_1 = GLOBALS->is_active_hiersearch_c_1; } if(GLOBALS->mouseover_mouseover_c_1) /* mouseover regenerates as the pointer moves so no real context lost */ { gtk_widget_destroy(GLOBALS->mouseover_mouseover_c_1); GLOBALS->mouseover_mouseover_c_1 = NULL; gdk_pixmap_unref(GLOBALS->mo_pixmap_mouseover_c_1); GLOBALS->mo_pixmap_mouseover_c_1 = NULL; } if(GLOBALS->window_renderopt_c_6) { new_globals->is_active_renderopt_c_3 = GLOBALS->is_active_renderopt_c_3; new_globals->window_renderopt_c_6 = GLOBALS->window_renderopt_c_6; memcpy(new_globals->target_mutex_renderopt_c_1, GLOBALS->target_mutex_renderopt_c_1, sizeof(GLOBALS->target_mutex_renderopt_c_1)); memcpy(new_globals->page_mutex_renderopt_c_1, GLOBALS->page_mutex_renderopt_c_1, sizeof(GLOBALS->page_mutex_renderopt_c_1)); memcpy(new_globals->render_mutex_renderopt_c_1, GLOBALS->render_mutex_renderopt_c_1, sizeof(GLOBALS->render_mutex_renderopt_c_1)); strcpy2_into_new_context(new_globals, &new_globals->filesel_print_pdf_renderopt_c_1, &GLOBALS->filesel_print_pdf_renderopt_c_1); strcpy2_into_new_context(new_globals, &new_globals->filesel_print_ps_renderopt_c_1, &GLOBALS->filesel_print_ps_renderopt_c_1); strcpy2_into_new_context(new_globals, &new_globals->filesel_print_mif_renderopt_c_1, &GLOBALS->filesel_print_mif_renderopt_c_1); new_globals->page_size_type_renderopt_c_1 = GLOBALS->page_size_type_renderopt_c_1; } if(GLOBALS->window_search_c_7) { int i; new_globals->pdata = calloc_2_into_context(new_globals, 1, sizeof(SearchProgressData)); memcpy(new_globals->pdata, GLOBALS->pdata, sizeof(SearchProgressData)); new_globals->is_active_search_c_4 = GLOBALS->is_active_search_c_4; new_globals->regex_which_search_c_1 = GLOBALS->regex_which_search_c_1; new_globals->window_search_c_7 = GLOBALS->window_search_c_7; new_globals->entry_search_c_3 = GLOBALS->entry_search_c_3; new_globals->clist_search_c_3 = GLOBALS->clist_search_c_3; strcpy2_into_new_context(new_globals, &new_globals->searchbox_text_search_c_1, &GLOBALS->searchbox_text_search_c_1); for(i=0;i<5;i++) { new_globals->menuitem_search[i] = GLOBALS->menuitem_search[i]; new_globals->regex_mutex_search_c_1[i] = GLOBALS->regex_mutex_search_c_1[i]; } } /* erase any old tabbed contexts if they exist... */ dead_context_sweep(); /* let any destructors finalize on GLOBALS dereferences... (commented out for now) */ /* gtkwave_main_iteration(); */ /* Free the old context */ free_outstanding(); /* Free the old globals struct, memsetting it to zero in the hope of forcing crashes. */ memset(GLOBALS, 0, sizeof(struct Global)); free(GLOBALS); GLOBALS = NULL; /* valgrind fix */ /* Set the GLOBALS pointer to the newly allocated struct. */ set_GLOBALS(new_globals); *(GLOBALS->gtk_context_bridge_ptr) = GLOBALS; init_filetrans_data(); init_proctrans_data(); init_ttrans_data(); /* load_all_fonts(); */ /* attempt to reload file and recover on loader errors until successful */ for(;;) { set_window_busy(NULL); /* Check to see if we need to reload a vcd file */ #if !defined _MSC_VER && !defined __MINGW32__ if(GLOBALS->optimize_vcd) { optimize_vcd_file(); } #endif /* Load new file from disk, no reload on partial vcd or vcd from stdin. */ switch(GLOBALS->loaded_file_type) { #ifdef EXTLOAD_SUFFIX case EXTLOAD_FILE: extload_main(GLOBALS->loaded_file_name, GLOBALS->skip_start, GLOBALS->skip_end); load_was_success = (GLOBALS->extload != NULL) && (!GLOBALS->extload_already_errored); GLOBALS->extload_already_errored = 0; GLOBALS->extload_lastmod = 0; break; #endif case LX2_FILE: lx2_main(GLOBALS->loaded_file_name,GLOBALS->skip_start,GLOBALS->skip_end); load_was_success = (GLOBALS->lx2_lx2_c_1 != NULL); break; case VZT_FILE: vzt_main(GLOBALS->loaded_file_name,GLOBALS->skip_start,GLOBALS->skip_end); load_was_success = (GLOBALS->vzt_vzt_c_1 != NULL); break; case FST_FILE: fst_main(GLOBALS->loaded_file_name,GLOBALS->skip_start,GLOBALS->skip_end); load_was_success = (GLOBALS->fst_fst_c_1 != NULL); break; case AE2_FILE: #ifdef AET2_IS_PRESENT ae2_main(GLOBALS->loaded_file_name,GLOBALS->skip_start,GLOBALS->skip_end); load_was_success = (GLOBALS->ae2 != NULL); #else load_was_success = 0; /* never executes as AE2_FILE won't be set */ #endif break; case GHW_FILE: load_was_success = (ghw_main(GLOBALS->loaded_file_name) != 0); break; case LXT_FILE: case VCD_FILE: case VCD_RECODER_FILE: load_was_success = handle_setjmp(); break; default: break; } set_window_idle(NULL); if(load_was_success) { break; } else { /* recovery sequence */ printf("GTKWAVE | Reload failure, reattempt in %d second%s...\n", reload_fail_delay, (reload_fail_delay==1) ? "" : "s"); fflush(stdout); sleep(reload_fail_delay); switch(reload_fail_delay) { case 1: reload_fail_delay = 2; break; case 2: reload_fail_delay = 5; break; case 5: reload_fail_delay = 10; break; case 10: reload_fail_delay = 30; break; case 30: reload_fail_delay = 60; break; default: break; } } } /* deallocate the symbol hash table */ sym_hash_destroy(GLOBALS); /* Setup timings we probably need to redraw here */ GLOBALS->tims.last=GLOBALS->max_time; GLOBALS->tims.first=GLOBALS->min_time; if(fix_from_time) { if((from_time >= GLOBALS->min_time) && (from_time <= GLOBALS->max_time)) { GLOBALS->tims.first = from_time; } } if(fix_to_time) { if((to_time >= GLOBALS->min_time) && (to_time <= GLOBALS->max_time) && (to_time > GLOBALS->tims.first)) { GLOBALS->tims.last = to_time; } } if(GLOBALS->tims.start < GLOBALS->tims.first) { GLOBALS->tims.start = GLOBALS->tims.first; } if(GLOBALS->tims.end > GLOBALS->tims.last) { GLOBALS->tims.end = GLOBALS->tims.last; } if(GLOBALS->tims.marker < GLOBALS->tims.first) { GLOBALS->tims.marker = GLOBALS->tims.first; } if(GLOBALS->tims.marker > GLOBALS->tims.last) { GLOBALS->tims.marker = GLOBALS->tims.last; } if(GLOBALS->tims.prevmarker < GLOBALS->tims.first) { GLOBALS->tims.prevmarker = GLOBALS->tims.first; } if(GLOBALS->tims.prevmarker > GLOBALS->tims.last) { GLOBALS->tims.prevmarker = GLOBALS->tims.last; } if(GLOBALS->tims.laststart < GLOBALS->tims.first) { GLOBALS->tims.laststart = GLOBALS->tims.first; } if(GLOBALS->tims.laststart > GLOBALS->tims.last) { GLOBALS->tims.laststart = GLOBALS->tims.last; } reformat_time(timestr, GLOBALS->tims.first + GLOBALS->global_time_offset, GLOBALS->time_dimension); gtk_entry_set_text(GTK_ENTRY(GLOBALS->from_entry),timestr); reformat_time(timestr, GLOBALS->tims.last + GLOBALS->global_time_offset, GLOBALS->time_dimension); gtk_entry_set_text(GTK_ENTRY(GLOBALS->to_entry),timestr); /* Change SST - if it exists */ /* XXX need to destroy/free the old tree widgets. */ #if GTK_CHECK_VERSION(2,4,0) if(!GLOBALS->hide_sst) { gint pane_pos = gtk_paned_get_position(GLOBALS->sst_vpaned); gtk_widget_hide(GLOBALS->expanderwindow); gtk_container_remove(GTK_CONTAINER(GLOBALS->expanderwindow), GLOBALS->sstpane); GLOBALS->sstpane = treeboxframe("SST", GTK_SIGNAL_FUNC(mkmenu_treesearch_cleanup)); gtk_container_add(GTK_CONTAINER(GLOBALS->expanderwindow), GLOBALS->sstpane); gtk_paned_set_position(GLOBALS->sst_vpaned, pane_pos); gtk_widget_show(GLOBALS->expanderwindow); if(GLOBALS->dnd_sigview) { dnd_setup(GLOBALS->dnd_sigview, GLOBALS->signalarea, 0); } if(GLOBALS->clist_search_c_3) { dnd_setup(GLOBALS->clist_search_c_3, GLOBALS->signalarea, 0); } } #endif #if WAVE_USE_GTK2 if(GLOBALS->window_treesearch_gtk2_c_12) { gtk_container_remove(GTK_CONTAINER(GLOBALS->window_treesearch_gtk2_c_12), GLOBALS->treesearch_gtk2_window_vbox); treebox(NULL, GTK_SIGNAL_FUNC(mkmenu_treesearch_cleanup), GLOBALS->window_treesearch_gtk2_c_12); } if((GLOBALS->filter_str_treesearch_gtk2_c_1) && (GLOBALS->filter_entry)) { gtk_entry_set_text(GTK_ENTRY(GLOBALS->filter_entry), GLOBALS->filter_str_treesearch_gtk2_c_1); wave_regex_compile(GLOBALS->filter_str_treesearch_gtk2_c_1 + GLOBALS->filter_matlen_treesearch_gtk2_c_1, WAVE_REGEX_TREE); } #endif /* Reload state from file */ { char is_gtkw_save_file_cached = GLOBALS->is_gtkw_save_file; read_save_helper(reload_tmpfilename, NULL, NULL, NULL, NULL, NULL); GLOBALS->is_gtkw_save_file = is_gtkw_save_file_cached; } /* again doing this here (read_save_helper does it) seems to be necessary in order to keep display in sync */ GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); /* unlink temp */ unlink(reload_tmpfilename); free(reload_tmpfilename); /* intentional use of free(), of strdup'd string from earlier */ /* part 2 of SST (which needs to be done after the tree is expanded from loading the savefile...) */ #if WAVE_USE_GTK2 if((!GLOBALS->hide_sst)||(GLOBALS->window_treesearch_gtk2_c_12)) { GtkCList *cl = GTK_CLIST(GLOBALS->ctree_main); char *hiername_cache = NULL; /* some strange race condition side effect in gtk selecting/deselecting blows this out so cache it */ if(GLOBALS->selected_hierarchy_name) { hiername_cache = strdup_2(GLOBALS->selected_hierarchy_name); select_tree_node(GLOBALS->selected_hierarchy_name); } if(tree_vadj_value != 0.0) { GtkAdjustment *vadj = gtk_clist_get_vadjustment(cl); if((vadj) && (tree_vadj_value >= vadj->lower) && (tree_vadj_value <= vadj->upper)) { vadj->value = tree_vadj_value; gtk_clist_set_vadjustment(cl, vadj); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(vadj)), "changed"); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(vadj)), "value_changed"); } } if(tree_hadj_value != 0.0) { GtkAdjustment *hadj = gtk_clist_get_hadjustment(cl); if((hadj) && (tree_hadj_value >= hadj->lower) && (tree_hadj_value <= hadj->upper)) { hadj->value = tree_hadj_value; gtk_clist_set_hadjustment(cl, hadj); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(hadj)), "changed"); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(hadj)), "value_changed"); } } if(hiername_cache) { if(GLOBALS->selected_hierarchy_name) { free_2(GLOBALS->selected_hierarchy_name); } GLOBALS->selected_hierarchy_name = hiername_cache; } if(tree_frame_y != -1) { /* this doesn't work...this sets the *minimum* size */ /* gtk_widget_set_size_request(GLOBALS->gtk2_tree_frame, -1, tree_frame_y); */ } if(GLOBALS->filter_entry) { gtk_signal_emit_by_name (GTK_OBJECT (GLOBALS->filter_entry), "activate"); } } #endif /* part 2 of search (which needs to be done after the new dumpfile is loaded) */ if(GLOBALS->window_search_c_7) { search_enter_callback(GLOBALS->entry_search_c_3, NULL); } /* part 2 of hier search (which needs to be done after the new dumpfile is loaded) */ if(GLOBALS->window_hiersearch_c_3) { if(!hier_curr) { GLOBALS->current_tree_hiersearch_c_1=GLOBALS->treeroot; GLOBALS->h_selectedtree_hiersearch_c_1=NULL; } else { struct tree *t = GLOBALS->treeroot; hier_curr = hier_head; while((hier_curr)&&(t)) { if(!strcmp(hier_curr->name, t->name)) { if(t->child) { struct treechain *tc, *tc2; tc=GLOBALS->treechain_hiersearch_c_1; if(tc) { while(tc->next) tc=tc->next; tc2=calloc_2(1,sizeof(struct treechain)); tc2->label=t; tc2->tree=GLOBALS->current_tree_hiersearch_c_1; tc->next=tc2; } else { GLOBALS->treechain_hiersearch_c_1=calloc_2(1,sizeof(struct treechain)); GLOBALS->treechain_hiersearch_c_1->tree=GLOBALS->current_tree_hiersearch_c_1; GLOBALS->treechain_hiersearch_c_1->label=t; } GLOBALS->current_tree_hiersearch_c_1=t->child; } t = t->child; hier_curr = hier_curr->next; continue; } t = t->next; } hier_curr = hier_head; while(hier_head) { hier_head = hier_curr->next; free_2(hier_curr->name); free_2(hier_curr); hier_curr = hier_head; } } refresh_hier_tree(GLOBALS->current_tree_hiersearch_c_1); } /* restore these in case we decide to write out the rc file later as a user option */ GLOBALS->ignore_savefile_pane_pos = cached_ignore_savefile_pane_pos; GLOBALS->ignore_savefile_pos = cached_ignore_savefile_pos; GLOBALS->ignore_savefile_size = cached_ignore_savefile_size; GLOBALS->splash_disable = cached_splash_disable; printf("GTKWAVE | ...waveform reloaded\n"); gtkwavetcl_setvar(WAVE_TCLCB_RELOAD_END, GLOBALS->loaded_file_name, WAVE_TCLCB_RELOAD_END_FLAGS); /* update lower signal set in SST to correct position */ #if WAVE_USE_GTK2 if((GLOBALS->dnd_sigview) && ((treeview_vadj_value != 0.0) || (treeview_hadj_value != 0.0))) { struct Global *G2 = GLOBALS; gtk_events_pending_gtk_main_iteration(); if((G2 == GLOBALS)&&(GLOBALS->dnd_sigview)) { if(treeview_vadj_value != 0.0) { GtkAdjustment *vadj = gtk_tree_view_get_vadjustment((GtkTreeView *)GLOBALS->dnd_sigview); if((vadj) && (treeview_vadj_value >= vadj->lower) && (treeview_vadj_value <= vadj->upper)) { vadj->value = treeview_vadj_value; gtk_tree_view_set_vadjustment((GtkTreeView *)GLOBALS->dnd_sigview, vadj); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(vadj)), "changed"); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(vadj)), "value_changed"); } } if(treeview_hadj_value != 0.0) { GtkAdjustment *hadj = gtk_tree_view_get_hadjustment((GtkTreeView *)GLOBALS->dnd_sigview); if((hadj) && (treeview_hadj_value >= hadj->lower) && (treeview_hadj_value <= hadj->upper)) { hadj->value = treeview_hadj_value; gtk_tree_view_set_hadjustment((GtkTreeView *)GLOBALS->dnd_sigview, hadj); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(hadj)), "changed"); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(hadj)), "value_changed"); } } } } #endif } void reload_into_new_context(void) { static int reloading = 0; if(!reloading) { #ifdef MAC_INTEGRATION osx_menu_sensitivity(FALSE); #endif reload_into_new_context_2(); reloading = 0; #ifdef MAC_INTEGRATION if(GLOBALS->loaded_file_type != MISSING_FILE) { osx_menu_sensitivity(TRUE); } #endif } } /* * for notebook page closing */ void free_and_destroy_page_context(void) { int s_ctx_iter; /* deallocate any loader-related stuff */ switch(GLOBALS->loaded_file_type) { case LXT_FILE: if(GLOBALS->mm_lxt_mmap_addr) { munmap(GLOBALS->mm_lxt_mmap_addr, GLOBALS->mm_lxt_mmap_len); } break; case LX2_FILE: lxt2_rd_close(GLOBALS->lx2_lx2_c_1); break; case VZT_FILE: vzt_rd_close(GLOBALS->vzt_vzt_c_1); break; case FST_FILE: fstReaderClose(GLOBALS->fst_fst_c_1); GLOBALS->fst_fst_c_1 = NULL; break; case AE2_FILE: #ifdef AET2_IS_PRESENT #ifdef AET2_ALIASDB_IS_PRESENT if(GLOBALS->adb) { adb_close_db(GLOBALS->adb); GLOBALS->adb = 0; } /* if(GLOBALS->adb_alias_stream_file) { fclose(GLOBALS->adb_alias_stream_file); GLOBALS->adb_alias_stream_file = NULL; } */ ae2_read_end(GLOBALS->ae2); fclose(GLOBALS->ae2_f); #endif #endif break; #ifdef EXTLOAD_SUFFIX case EXTLOAD_FILE: if(GLOBALS->extload_ffr_ctx) { #ifdef WAVE_FSDB_READER_IS_PRESENT fsdbReaderClose(GLOBALS->extload_ffr_ctx); #endif GLOBALS->extload_ffr_ctx = NULL; } break; #endif case MISSING_FILE: case DUMPLESS_FILE: case GHW_FILE: case VCD_FILE: case VCD_RECODER_FILE: default: /* do nothing */ break; } /* window destruction (of windows that aren't the parent window) */ widget_only_destroy(&GLOBALS->window_ptranslate_c_5); /* ptranslate.c */ WAVE_STRACE_ITERATOR(s_ctx_iter) { GLOBALS->strace_ctx = &GLOBALS->strace_windows[GLOBALS->strace_current_window = s_ctx_iter]; widget_only_destroy(&GLOBALS->strace_ctx->window_strace_c_10); /* strace.c */ } widget_only_destroy(&GLOBALS->window_translate_c_11); /* translate.c */ widget_only_destroy(&GLOBALS->window_treesearch_gtk1_c); /* treesearch_gtk1.c */ widget_only_destroy(&GLOBALS->window_treesearch_gtk2_c_12); /* treesearch_gtk2.c */ widget_only_destroy(&GLOBALS->window_help_c_2); /* help.c : reload is gated off during help so this should never execute */ /* windows which in theory should never destroy as they will have grab focus which means reload will not be called */ widget_ungrab_destroy(&GLOBALS->window_entry_c_1); /* entry.c */ widget_ungrab_destroy(&GLOBALS->window1_hiersearch_c_1); /* hiersearch.c */ widget_ungrab_destroy(&GLOBALS->window_markerbox_c_4); /* markerbox.c */ widget_ungrab_destroy(&GLOBALS->window1_search_c_2); /* search.c */ widget_ungrab_destroy(&GLOBALS->window_showchange_c_8); /* showchange.c */ widget_ungrab_destroy(&GLOBALS->window_simplereq_c_9); /* simplereq.c */ widget_ungrab_destroy(&GLOBALS->window1_treesearch_gtk1_c); /* treesearch_gtk1.c */ widget_ungrab_destroy(&GLOBALS->window1_treesearch_gtk2_c_3); /* treesearch_gtk2.c */ /* supported migration of window contexts... */ widget_only_destroy(&GLOBALS->window_hiersearch_c_3); if(GLOBALS->mouseover_mouseover_c_1) /* mouseover regenerates as the pointer moves so no real context lost */ { gtk_widget_destroy(GLOBALS->mouseover_mouseover_c_1); GLOBALS->mouseover_mouseover_c_1 = NULL; gdk_pixmap_unref(GLOBALS->mo_pixmap_mouseover_c_1); GLOBALS->mo_pixmap_mouseover_c_1 = NULL; } widget_only_destroy(&GLOBALS->window_renderopt_c_6); widget_only_destroy(&GLOBALS->window_search_c_7); (*GLOBALS->dead_context)[0] = GLOBALS; /* let any destructors finalize on GLOBALS dereferences... */ gtkwave_main_iteration(); } /* * part 2 of free_and_destroy_page_context() as some context data seems to be used later by * gtk (i.e., the destroys might be deferred slightly causing corruption) */ void dead_context_sweep(void) { struct Global *gp = (*GLOBALS->dead_context)[0]; struct Global *g_curr; if(gp) { g_curr = GLOBALS; set_GLOBALS(gp); (*GLOBALS->dead_context)[0] = NULL; /* remove the bridge pointer */ if(GLOBALS->gtk_context_bridge_ptr) { free(GLOBALS->gtk_context_bridge_ptr); GLOBALS->gtk_context_bridge_ptr = NULL; } /* Free all gcs */ dealloc_all_gcs(); /* Free the context */ free_outstanding(); /* Free the old globals struct, memsetting it to zero in the hope of forcing crashes. */ memset(GLOBALS, 0, sizeof(struct Global)); free(GLOBALS); GLOBALS = NULL; /* valgrind fix */ set_GLOBALS(g_curr); } } /* * focus directed context switching of GLOBALS in multiple tabs mode */ static gint context_swapper(GtkWindow *w, GdkEvent *event, void *data) { GdkEventType type; if(ignore_context_swap()) /* block context swap if explicitly directed (e.g., during loading) */ { return(FALSE); } type = event->type; /* printf("Window: %08x GtkEvent: %08x gpointer: %08x, type: %d\n", w, event, data, type); */ switch(type) { case GDK_ENTER_NOTIFY: case GDK_FOCUS_CHANGE: if(GLOBALS->num_notebook_pages >= 2) { unsigned int i; void **vp; GtkWindow *wcmp; for(i=0;inum_notebook_pages;i++) { struct Global *test_g = (*GLOBALS->contexts)[i]; vp = (void **)(((char *)test_g) + (long)data); wcmp = (GtkWindow *)(*vp); if(wcmp != NULL) { if(wcmp == w) { if(i!=GLOBALS->this_context_page) { struct Global *g_old = GLOBALS; /* printf("Switching to: %d %08x\n", i, GTK_WINDOW(wcmp)); */ set_GLOBALS((*GLOBALS->contexts)[i]); GLOBALS->lxt_clock_compress_to_z = g_old->lxt_clock_compress_to_z; GLOBALS->autoname_bundles = g_old->autoname_bundles; GLOBALS->autocoalesce_reversal = g_old->autocoalesce_reversal; GLOBALS->autocoalesce = g_old->autocoalesce; GLOBALS->hier_grouping = g_old->hier_grouping; GLOBALS->wave_scrolling = g_old->wave_scrolling; GLOBALS->constant_marker_update = g_old->constant_marker_update; GLOBALS->do_zoom_center = g_old->do_zoom_center; GLOBALS->use_roundcaps = g_old->use_roundcaps; GLOBALS->do_resize_signals = g_old->do_resize_signals; GLOBALS->alt_wheel_mode = g_old->alt_wheel_mode; GLOBALS->initial_signal_window_width = g_old->initial_signal_window_width; GLOBALS->use_full_precision = g_old->use_full_precision; GLOBALS->show_base = g_old->show_base; GLOBALS->display_grid = g_old->display_grid; GLOBALS->highlight_wavewindow = g_old->highlight_wavewindow; GLOBALS->use_standard_trace_select = g_old->use_standard_trace_select; GLOBALS->disable_mouseover = g_old->disable_mouseover; GLOBALS->keep_xz_colors = g_old->keep_xz_colors; GLOBALS->zoom_pow10_snap = g_old->zoom_pow10_snap; GLOBALS->scale_to_time_dimension = g_old->scale_to_time_dimension; GLOBALS->zoom_dyn = g_old->zoom_dyn; GLOBALS->zoom_dyne = g_old->zoom_dyne; GLOBALS->ignore_savefile_pane_pos = g_old->ignore_savefile_pane_pos; GLOBALS->ignore_savefile_pos = g_old->ignore_savefile_pos; GLOBALS->ignore_savefile_size = g_old->ignore_savefile_size; gtk_notebook_set_current_page(GTK_NOTEBOOK(GLOBALS->notebook), GLOBALS->this_context_page); } return(FALSE); } } } } break; default: break; } return(FALSE); } void install_focus_cb(GtkWidget *w, unsigned long ptr_offset) { gtk_signal_connect (GTK_OBJECT(w), "enter_notify_event", GTK_SIGNAL_FUNC(context_swapper), (void *)ptr_offset); gtk_signal_connect (GTK_OBJECT(w), "focus_in_event", GTK_SIGNAL_FUNC(context_swapper), (void *)ptr_offset); } /* * wrapped gtk_signal_connect/gtk_signal_connect_object functions for context watchdog monitoring... * note that this false triggers on configure_event as gtk sends events to multiple tabs and not * just the visible one! */ static gint ctx_swap_watchdog(struct Global **w) { struct Global *watch = *w; if(GLOBALS->gtk_context_bridge_ptr != w) { #ifdef GTKWAVE_SIGNAL_CONNECT_DEBUG fprintf(stderr, "GTKWAVE | WARNING: globals change caught by ctx_swap_watchdog()! %p vs %p, session %d vs %d\n", (void *)GLOBALS->gtk_context_bridge_ptr,(void *)w, (*GLOBALS->gtk_context_bridge_ptr)->this_context_page, watch->this_context_page); #endif set_GLOBALS(watch); } return(0); } static gint ctx_prints(char *s) { printf(">>> %s\n", s); return(0); } static gint ctx_printd(int d) { printf(">>>\t%d\n", d); return(0); } gulong gtkwave_signal_connect_x(GtkObject *object, const gchar *name, GtkSignalFunc func, gpointer data, char *f, unsigned long line) { gulong rc; if(f) { gtk_signal_connect_object(object, name, (GtkSignalFunc)ctx_prints, (GtkObject *)f); gtk_signal_connect_object(object, name, (GtkSignalFunc)ctx_printd, (GtkObject *)line); } gtk_signal_connect_object(object, name, (GtkSignalFunc)ctx_swap_watchdog, (GtkObject *)GLOBALS->gtk_context_bridge_ptr); rc = gtk_signal_connect(object, name, func, data); return(rc); } gulong gtkwave_signal_connect_object_x(GtkObject *object, const gchar *name, GtkSignalFunc func, gpointer data, char *f, unsigned long line) { gulong rc; if(f) { gtk_signal_connect_object(object, name, (GtkSignalFunc)ctx_prints, (GtkObject *)f); gtk_signal_connect_object(object, name, (GtkSignalFunc)ctx_printd, (GtkObject *)line); } gtk_signal_connect_object(object, name, (GtkSignalFunc)ctx_swap_watchdog, (GtkObject *)GLOBALS->gtk_context_bridge_ptr); rc = gtk_signal_connect_object(object, name, func, data); return(rc); } void set_GLOBALS_x(struct Global *g, const char *file, int line) { char sstr[32]; if(line) { printf("Globals old %p -> new %p (%s: %d)\n", (void *)GLOBALS, (void *)g, file, line); } if(GLOBALS != g) { /* fix problem where ungrab doesn't occur if button pressed + simultaneous context swap occurs */ if(GLOBALS && GLOBALS->in_button_press_wavewindow_c_1) { gdk_pointer_ungrab(GDK_CURRENT_TIME); } GLOBALS = g; sprintf(sstr, "%d", GLOBALS->this_context_page); gtkwavetcl_setvar(WAVE_TCLCB_CURRENT_ACTIVE_TAB, sstr, WAVE_TCLCB_CURRENT_ACTIVE_TAB_FLAGS); } } /* * for ensuring continuity of pixmap/mask pointers */ void clone_icon_pointers_across_contexts(struct Global *a, struct Global *b) { if(!a || !b) return; a->hiericon_module_pixmap = b->hiericon_module_pixmap; a->hiericon_module_mask = b->hiericon_module_mask; a->hiericon_task_pixmap = b->hiericon_task_pixmap; a->hiericon_task_mask = b->hiericon_task_mask; a->hiericon_function_pixmap = b->hiericon_function_pixmap; a->hiericon_function_mask = b->hiericon_function_mask; a->hiericon_begin_pixmap = b->hiericon_begin_pixmap; a->hiericon_begin_mask = b->hiericon_begin_mask; a->hiericon_fork_pixmap = b->hiericon_fork_pixmap; a->hiericon_fork_mask = b->hiericon_fork_mask; a->hiericon_interface_pixmap = b->hiericon_interface_pixmap; a->hiericon_interface_mask = b->hiericon_interface_mask; a->hiericon_svpackage_pixmap = b->hiericon_svpackage_pixmap; a->hiericon_svpackage_mask = b->hiericon_svpackage_mask; a->hiericon_program_pixmap = b->hiericon_program_pixmap; a->hiericon_program_mask = b->hiericon_program_mask; a->hiericon_class_pixmap = b->hiericon_class_pixmap; a->hiericon_class_mask = b->hiericon_class_mask; a->hiericon_record_pixmap = b->hiericon_record_pixmap; a->hiericon_record_mask = b->hiericon_record_mask; a->hiericon_generate_pixmap = b->hiericon_generate_pixmap; a->hiericon_generate_mask = b->hiericon_generate_mask; a->hiericon_design_pixmap = b->hiericon_design_pixmap; a->hiericon_design_mask = b->hiericon_design_mask; a->hiericon_block_pixmap = b->hiericon_block_pixmap; a->hiericon_block_mask = b->hiericon_block_mask; a->hiericon_generateif_pixmap = b->hiericon_generateif_pixmap; a->hiericon_generateif_mask = b->hiericon_generateif_mask; a->hiericon_generatefor_pixmap = b->hiericon_generatefor_pixmap; a->hiericon_generatefor_mask = b->hiericon_generatefor_mask; a->hiericon_instance_pixmap = b->hiericon_instance_pixmap; a->hiericon_instance_mask = b->hiericon_instance_mask; a->hiericon_package_pixmap = b->hiericon_package_pixmap; a->hiericon_package_mask = b->hiericon_package_mask; a->hiericon_signal_pixmap = b->hiericon_signal_pixmap; a->hiericon_signal_mask = b->hiericon_signal_mask; a->hiericon_portin_pixmap = b->hiericon_portin_pixmap; a->hiericon_portin_mask = b->hiericon_portin_mask; a->hiericon_portout_pixmap = b->hiericon_portout_pixmap; a->hiericon_portout_mask = b->hiericon_portout_mask; a->hiericon_portinout_pixmap = b->hiericon_portinout_pixmap; a->hiericon_portinout_mask = b->hiericon_portinout_mask; a->hiericon_buffer_pixmap = b->hiericon_buffer_pixmap; a->hiericon_buffer_mask = b->hiericon_buffer_mask; a->hiericon_linkage_pixmap = b->hiericon_linkage_pixmap; a->hiericon_linkage_mask = b->hiericon_linkage_mask; } gtkwave-3.3.66/src/tcl_support_commands.h0000664000076400007640000000216212341266475020011 0ustar bybellbybell/* * Copyright (c) Yiftach Tzori 2009. * * 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. */ #ifndef WAVE_TCL_SUPPORT_CMDS_H #define WAVE_TCL_SUPPORT_CMDS_H #include #include "debug.h" GtkCTreeNode *SST_find_node_by_path(GtkCTreeRow *root, char *path); int SST_open_path(GtkCTree *ctree, GtkCTreeNode *node); void fill_sig_store (void); int SST_open_node(char *name); llist_p *llist_new(llist_u v, ll_elem_type type, int arg); llist_p *llist_append(llist_p *head, llist_p *elem, llist_p **tail); llist_p *llist_remove_last(llist_p *head, llist_p **tail, ll_elem_type type, void *f(void *) ); void llist_free(llist_p *head, ll_elem_type type, void *f(void *)); llist_p *signal_change_list(char *sig_name, int dir, TimeType start_time, TimeType end_time, int max_elements); #define SST_NODE_FOUND 0 #define SST_NODE_CURRENT 2 #define SST_NODE_NOT_EXIST 1 #define SST_TREE_NOT_EXIST -1 #endif gtkwave-3.3.66/src/busy.h0000664000076400007640000000160312341266475014533 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2006. * * 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. */ #include "globals.h" #ifndef WAVE_BUSYWIN_H #define WAVE_BUSYWIN_H #include #include #include #include "main.h" /* number of histents to create before kicking off gtk_main_iteration() checking */ #define WAVE_BUSY_ITER (1000) void init_busy(void); void set_window_busy_no_refresh(GtkWidget *w); void set_window_busy(GtkWidget *w); void set_window_idle(GtkWidget *w); void busy_window_refresh(void); void gtkwave_main_iteration(void); void gtk_events_pending_gtk_main_iteration(void); gboolean in_main_iteration(void); gboolean ignore_context_swap(void); #endif gtkwave-3.3.66/src/hiersearch.c0000664000076400007640000007044412360623564015667 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2011. * * 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. */ /* AIX may need this for alloca to work */ #if defined _AIX #pragma alloca #endif #include "globals.h" #include #include #include "gtk12compat.h" #include "analyzer.h" #include "symbol.h" #include "lx2.h" #include "vcd.h" #include "busy.h" #include "debug.h" int hier_searchbox_is_active(void) { return(GLOBALS->is_active_hiersearch_c_1); } void refresh_hier_tree(struct tree *t) { struct tree *t2; GtkCList *cl; int len; int row; int pixlen=0, maxpixlen=0; static char *dotdot=".."; struct treechain *tc; gtk_clist_freeze(cl=GTK_CLIST(GLOBALS->clist_hiersearch_c_1)); gtk_clist_clear(cl); GLOBALS->num_rows_hiersearch_c_1=0; if(t!=GLOBALS->treeroot) { maxpixlen=font_engine_string_measure(GLOBALS->signalfont,(gchar *)(dotdot)); } if(!GLOBALS->hier_grouping) { char *tmp, *tmp2, *tmp3; t2=t; while(t2) { { if(t2->child) { tmp=wave_alloca(strlen(t2->name)+5); strcpy(tmp, "(+) "); strcpy(tmp+4, t2->name); } else if(t2->t_which >= 0) { if(GLOBALS->facs[t2->t_which]->vec_root) { if(GLOBALS->autocoalesce) { if(GLOBALS->facs[t2->t_which]->vec_root!=GLOBALS->facs[t2->t_which]) { t2=t2->next; continue; } tmp2=makename_chain(GLOBALS->facs[t2->t_which]); tmp3=leastsig_hiername(tmp2); tmp=wave_alloca(strlen(tmp3)+4); strcpy(tmp, "[] "); strcpy(tmp+3, tmp3); free_2(tmp2); } else { tmp=wave_alloca(strlen(t2->name)+4); strcpy(tmp, "[] "); strcpy(tmp+3, t2->name); } } else { tmp=t2->name; } } else { /* tmp=t2->name; */ goto skip_node; /* GHW */ } row=gtk_clist_prepend(cl,(gchar **)&tmp); pixlen=font_engine_string_measure(GLOBALS->signalfont,(gchar *)(tmp)); } maxpixlen=(pixlen>maxpixlen)?pixlen:maxpixlen; gtk_clist_set_row_data(cl, row,t2); GLOBALS->num_rows_hiersearch_c_1++; skip_node: t2=t2->next; } } else { char *tmp, *tmp2, *tmp3; t2=t; while(t2) { if(!t2->child) { if(t2->t_which >= 0) { if(GLOBALS->facs[t2->t_which]->vec_root) { if(GLOBALS->autocoalesce) { if(GLOBALS->facs[t2->t_which]->vec_root!=GLOBALS->facs[t2->t_which]) { t2=t2->next; continue; } tmp2=makename_chain(GLOBALS->facs[t2->t_which]); tmp3=leastsig_hiername(tmp2); tmp=wave_alloca(strlen(tmp3)+4); strcpy(tmp, "[] "); strcpy(tmp+3, tmp3); free_2(tmp2); } else { tmp=wave_alloca(strlen(t2->name)+4); strcpy(tmp, "[] "); strcpy(tmp+3, t2->name); } } else { tmp=t2->name; } } else { /* tmp=t2->name; */ goto skip_node_2; /* GHW */ } row=gtk_clist_prepend(cl,(gchar **)&tmp); pixlen=font_engine_string_measure(GLOBALS->signalfont,(gchar *)(tmp)); maxpixlen=(pixlen>maxpixlen)?pixlen:maxpixlen; gtk_clist_set_row_data(cl, row,t2); GLOBALS->num_rows_hiersearch_c_1++; } skip_node_2: t2=t2->next; } t2=t; while(t2) { if(t2->child) { tmp=wave_alloca(strlen(t2->name)+5); strcpy(tmp, "(+) "); strcpy(tmp+4, t2->name); row=gtk_clist_prepend(cl,(gchar **)&tmp); pixlen=font_engine_string_measure(GLOBALS->signalfont,(gchar *)(tmp)); maxpixlen=(pixlen>maxpixlen)?pixlen:maxpixlen; gtk_clist_set_row_data(cl, row,t2); GLOBALS->num_rows_hiersearch_c_1++; } t2=t2->next; } } if(t!=GLOBALS->treeroot) { row=gtk_clist_prepend(cl,(gchar **)&dotdot); gtk_clist_set_row_data(cl, row,NULL); GLOBALS->num_rows_hiersearch_c_1++; } if(maxpixlen)gtk_clist_set_column_width(GTK_CLIST(GLOBALS->clist_hiersearch_c_1),0,maxpixlen); gtk_clist_thaw(cl); if((tc=GLOBALS->treechain_hiersearch_c_1)) { char *buf; char hier_str[2]; len=1; while(tc) { len+=strlen(tc->label->name); if(tc->next) len++; tc=tc->next; } buf=calloc_2(1,len); hier_str[0]=GLOBALS->hier_delimeter; hier_str[1]=0; tc=GLOBALS->treechain_hiersearch_c_1; while(tc) { strcat(buf,tc->label->name); if(tc->next) strcat(buf,hier_str); tc=tc->next; } gtk_entry_set_text(GTK_ENTRY(GLOBALS->entry_main_hiersearch_c_1), buf); free_2(buf); } else { gtk_entry_set_text(GTK_ENTRY(GLOBALS->entry_main_hiersearch_c_1),""); } } static void enter_callback_e(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; G_CONST_RETURN gchar *entry_text; int len; entry_text = gtk_entry_get_text(GTK_ENTRY(GLOBALS->entry_hiersearch_c_2)); entry_text = entry_text ? entry_text : ""; DEBUG(printf("Entry contents: %s\n", entry_text)); if(!(len=strlen(entry_text))) GLOBALS->entrybox_text_local_hiersearch_c_1=NULL; else strcpy((GLOBALS->entrybox_text_local_hiersearch_c_1=(char *)malloc_2(len+1)),entry_text); wave_gtk_grab_remove(GLOBALS->window1_hiersearch_c_1); gtk_widget_destroy(GLOBALS->window1_hiersearch_c_1); GLOBALS->window1_hiersearch_c_1 = NULL; GLOBALS->cleanup_e_hiersearch_c_1(); } static void destroy_callback_e(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; DEBUG(printf("Entry Cancel\n")); GLOBALS->entrybox_text_local_hiersearch_c_1=NULL; wave_gtk_grab_remove(GLOBALS->window1_hiersearch_c_1); gtk_widget_destroy(GLOBALS->window1_hiersearch_c_1); GLOBALS->window1_hiersearch_c_1 = NULL; } static void entrybox_local(char *title, int width, char *default_text, int maxch, GtkSignalFunc func) { GtkWidget *vbox, *hbox; GtkWidget *button1, *button2; GLOBALS->cleanup_e_hiersearch_c_1=func; /* fix problem where ungrab doesn't occur if button pressed + simultaneous accelerator key occurs */ if(GLOBALS->in_button_press_wavewindow_c_1) { gdk_pointer_ungrab(GDK_CURRENT_TIME); } /* create a new modal window */ GLOBALS->window1_hiersearch_c_1 = gtk_window_new(GLOBALS->disable_window_manager ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL); install_focus_cb(GLOBALS->window1_hiersearch_c_1, ((char *)&GLOBALS->window1_hiersearch_c_1) - ((char *)GLOBALS)); gtk_widget_set_usize( GTK_WIDGET (GLOBALS->window1_hiersearch_c_1), width, 60); gtk_window_set_title(GTK_WINDOW (GLOBALS->window1_hiersearch_c_1), title); gtkwave_signal_connect(GTK_OBJECT (GLOBALS->window1_hiersearch_c_1), "delete_event",(GtkSignalFunc) destroy_callback_e, NULL); vbox = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (GLOBALS->window1_hiersearch_c_1), vbox); gtk_widget_show (vbox); GLOBALS->entry_hiersearch_c_2 = gtk_entry_new_with_max_length (maxch); gtkwave_signal_connect(GTK_OBJECT(GLOBALS->entry_hiersearch_c_2), "activate",GTK_SIGNAL_FUNC(enter_callback_e),GLOBALS->entry_hiersearch_c_2); gtk_entry_set_text (GTK_ENTRY (GLOBALS->entry_hiersearch_c_2), default_text); gtk_entry_select_region (GTK_ENTRY (GLOBALS->entry_hiersearch_c_2),0, GTK_ENTRY(GLOBALS->entry_hiersearch_c_2)->text_length); gtk_box_pack_start (GTK_BOX (vbox), GLOBALS->entry_hiersearch_c_2, TRUE, TRUE, 0); gtk_widget_show (GLOBALS->entry_hiersearch_c_2); hbox = gtk_hbox_new (FALSE, 1); gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0); gtk_widget_show (hbox); button1 = gtk_button_new_with_label ("OK"); gtk_widget_set_usize(button1, 100, -1); gtkwave_signal_connect(GTK_OBJECT (button1), "clicked", GTK_SIGNAL_FUNC(enter_callback_e), NULL); gtk_widget_show (button1); gtk_container_add (GTK_CONTAINER (hbox), button1); GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT); gtkwave_signal_connect_object (GTK_OBJECT (button1), "realize", (GtkSignalFunc) gtk_widget_grab_default, GTK_OBJECT (button1)); button2 = gtk_button_new_with_label ("Cancel"); gtk_widget_set_usize(button2, 100, -1); gtkwave_signal_connect(GTK_OBJECT (button2), "clicked", GTK_SIGNAL_FUNC(destroy_callback_e), NULL); GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT); gtk_widget_show (button2); gtk_container_add (GTK_CONTAINER (hbox), button2); gtk_widget_show(GLOBALS->window1_hiersearch_c_1); wave_gtk_grab_add(GLOBALS->window1_hiersearch_c_1); } /***************************************************************************/ static void ok_callback(GtkWidget *widget, GtkWidget *nothing) { (void)nothing; int i; if(!GLOBALS->h_selectedtree_hiersearch_c_1) return; set_window_busy(widget); for(i=fetchlow(GLOBALS->h_selectedtree_hiersearch_c_1)->t_which;i<=fetchhigh(GLOBALS->h_selectedtree_hiersearch_c_1)->t_which;i++) { struct symbol *s; if(i<0) break; /* GHW */ s=GLOBALS->facs[i]; if(s->vec_root) { set_s_selected(s->vec_root, GLOBALS->autocoalesce); } } /* LX2 */ if(GLOBALS->is_lx2) { int pre_import = 0; for(i=fetchlow(GLOBALS->h_selectedtree_hiersearch_c_1)->t_which;i<=fetchhigh(GLOBALS->h_selectedtree_hiersearch_c_1)->t_which;i++) { struct symbol *s, *t; if(i<0) break; /* GHW */ s=GLOBALS->facs[i]; t=s->vec_root; if((t)&&(GLOBALS->autocoalesce)) { if(get_s_selected(t)) { while(t) { if(t->n->mv.mvlfac) { lx2_set_fac_process_mask(t->n); pre_import++; } t=t->vec_chain; } } } else { if(s->n->mv.mvlfac) { lx2_set_fac_process_mask(s->n); pre_import++; } } } if(pre_import) { lx2_import_masked(); } } /* LX2 */ for(i=fetchlow(GLOBALS->h_selectedtree_hiersearch_c_1)->t_which;i<=fetchhigh(GLOBALS->h_selectedtree_hiersearch_c_1)->t_which;i++) { int len; struct symbol *s, *t; if(i<0) break; /* GHW */ s=GLOBALS->facs[i]; t=s->vec_root; if((t)&&(GLOBALS->autocoalesce)) { if(get_s_selected(t)) { set_s_selected(t, 0); len=0; while(t) { len++; t=t->vec_chain; } if(len) add_vector_chain(s->vec_root, len); } } else { AddNodeUnroll(s->n, NULL); } } set_window_idle(widget); GLOBALS->traces.scroll_top = GLOBALS->traces.scroll_bottom = GLOBALS->traces.last; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } static void insert_callback(GtkWidget *widget, GtkWidget *nothing) { (void)nothing; Traces tcache; int i; if(!GLOBALS->h_selectedtree_hiersearch_c_1) return; memcpy(&tcache,&GLOBALS->traces,sizeof(Traces)); GLOBALS->traces.total=0; GLOBALS->traces.first=GLOBALS->traces.last=NULL; set_window_busy(widget); for(i=fetchlow(GLOBALS->h_selectedtree_hiersearch_c_1)->t_which;i<=fetchhigh(GLOBALS->h_selectedtree_hiersearch_c_1)->t_which;i++) { struct symbol *s; if(i<0) break; /* GHW */ s=GLOBALS->facs[i]; if(s->vec_root) { set_s_selected(s->vec_root, GLOBALS->autocoalesce); } } /* LX2 */ if(GLOBALS->is_lx2) { int pre_import = 0; for(i=fetchlow(GLOBALS->h_selectedtree_hiersearch_c_1)->t_which;i<=fetchhigh(GLOBALS->h_selectedtree_hiersearch_c_1)->t_which;i++) { struct symbol *s, *t; if(i<0) break; /* GHW */ s=GLOBALS->facs[i]; t=s->vec_root; if((t)&&(GLOBALS->autocoalesce)) { if(get_s_selected(t)) { while(t) { if(t->n->mv.mvlfac) { lx2_set_fac_process_mask(t->n); pre_import++; } t=t->vec_chain; } } } else { if(s->n->mv.mvlfac) { lx2_set_fac_process_mask(s->n); pre_import++; } } } if(pre_import) { lx2_import_masked(); } } /* LX2 */ for(i=fetchlow(GLOBALS->h_selectedtree_hiersearch_c_1)->t_which;i<=fetchhigh(GLOBALS->h_selectedtree_hiersearch_c_1)->t_which;i++) { int len; struct symbol *s, *t; if(i<0) break; /* GHW */ s=GLOBALS->facs[i]; t=s->vec_root; if((t)&&(GLOBALS->autocoalesce)) { if(get_s_selected(t)) { set_s_selected(t, 0); len=0; while(t) { len++; t=t->vec_chain; } if(len) add_vector_chain(s->vec_root, len); } } else { AddNodeUnroll(s->n, NULL); } } set_window_idle(widget); GLOBALS->traces.buffercount=GLOBALS->traces.total; GLOBALS->traces.buffer=GLOBALS->traces.first; GLOBALS->traces.bufferlast=GLOBALS->traces.last; GLOBALS->traces.first=tcache.first; GLOBALS->traces.last=tcache.last; GLOBALS->traces.total=tcache.total; PasteBuffer(); GLOBALS->traces.buffercount=tcache.buffercount; GLOBALS->traces.buffer=tcache.buffer; GLOBALS->traces.bufferlast=tcache.bufferlast; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } static void replace_callback(GtkWidget *widget, GtkWidget *nothing) { (void)nothing; Traces tcache; int i; Trptr tfirst=NULL, tlast=NULL; if(!GLOBALS->h_selectedtree_hiersearch_c_1) return; memcpy(&tcache,&GLOBALS->traces,sizeof(Traces)); GLOBALS->traces.total=0; GLOBALS->traces.first=GLOBALS->traces.last=NULL; set_window_busy(widget); for(i=fetchlow(GLOBALS->h_selectedtree_hiersearch_c_1)->t_which;i<=fetchhigh(GLOBALS->h_selectedtree_hiersearch_c_1)->t_which;i++) { struct symbol *s; if(i<0) break; /* GHW */ s=GLOBALS->facs[i]; if(s->vec_root) { set_s_selected(s->vec_root, GLOBALS->autocoalesce); } } /* LX2 */ if(GLOBALS->is_lx2) { int pre_import = 0; for(i=fetchlow(GLOBALS->h_selectedtree_hiersearch_c_1)->t_which;i<=fetchhigh(GLOBALS->h_selectedtree_hiersearch_c_1)->t_which;i++) { struct symbol *s, *t; if(i<0) break; /* GHW */ s=GLOBALS->facs[i]; t=s->vec_root; if((t)&&(GLOBALS->autocoalesce)) { if(get_s_selected(t)) { while(t) { if(t->n->mv.mvlfac) { lx2_set_fac_process_mask(t->n); pre_import++; } t=t->vec_chain; } } } else { if(s->n->mv.mvlfac) { lx2_set_fac_process_mask(s->n); pre_import++; } } } if(pre_import) { lx2_import_masked(); } } /* LX2 */ for(i=fetchlow(GLOBALS->h_selectedtree_hiersearch_c_1)->t_which;i<=fetchhigh(GLOBALS->h_selectedtree_hiersearch_c_1)->t_which;i++) { int len; struct symbol *s, *t; if(i<0) break; /* GHW */ s=GLOBALS->facs[i]; t=s->vec_root; if((t)&&(GLOBALS->autocoalesce)) { if(get_s_selected(t)) { set_s_selected(t, 0); len=0; while(t) { len++; t=t->vec_chain; } if(len) add_vector_chain(s->vec_root, len); } } else { AddNodeUnroll(s->n, NULL); } } set_window_idle(widget); tfirst=GLOBALS->traces.first; tlast=GLOBALS->traces.last; /* cache for highlighting */ GLOBALS->traces.buffercount=GLOBALS->traces.total; GLOBALS->traces.buffer=GLOBALS->traces.first; GLOBALS->traces.bufferlast=GLOBALS->traces.last; GLOBALS->traces.first=tcache.first; GLOBALS->traces.last=tcache.last; GLOBALS->traces.total=tcache.total; { Trptr t = GLOBALS->traces.first; Trptr *tp = NULL; int numhigh = 0; int it; while(t) { if(t->flags & TR_HIGHLIGHT) { numhigh++; } t = t->t_next; } if(numhigh) { tp = calloc_2(numhigh, sizeof(Trptr)); t = GLOBALS->traces.first; it = 0; while(t) { if(t->flags & TR_HIGHLIGHT) { tp[it++] = t; } t = t->t_next; } } PasteBuffer(); GLOBALS->traces.buffercount=tcache.buffercount; GLOBALS->traces.buffer=tcache.buffer; GLOBALS->traces.bufferlast=tcache.bufferlast; for(i=0;iflags |= TR_HIGHLIGHT; } t = tfirst; while(t) { t->flags &= ~TR_HIGHLIGHT; if(t==tlast) break; t=t->t_next; } CutBuffer(); while(tfirst) { tfirst->flags |= TR_HIGHLIGHT; if(tfirst==tlast) break; tfirst=tfirst->t_next; } if(tp) { free_2(tp); } } MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } static void bundle_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; if(GLOBALS->entrybox_text_local_hiersearch_c_1) { char *efix; if(!strlen(GLOBALS->entrybox_text_local_hiersearch_c_1)) { DEBUG(printf("Bundle name is not specified--recursing into hierarchy.\n")); fetchvex(GLOBALS->h_selectedtree_hiersearch_c_1, GLOBALS->bundle_direction_hiersearch_c_1); } else { efix=GLOBALS->entrybox_text_local_hiersearch_c_1; while(*efix) { if(*efix==' ') { *efix='_'; } efix++; } DEBUG(printf("Bundle name is: %s\n",GLOBALS->entrybox_text_local_hiersearch_c_1)); add_vector_range(GLOBALS->entrybox_text_local_hiersearch_c_1, fetchlow(GLOBALS->h_selectedtree_hiersearch_c_1)->t_which, fetchhigh(GLOBALS->h_selectedtree_hiersearch_c_1)->t_which, GLOBALS->bundle_direction_hiersearch_c_1); } free_2(GLOBALS->entrybox_text_local_hiersearch_c_1); } else { DEBUG(printf("Bundle name is not specified--recursing into hierarchy.\n")); fetchvex(GLOBALS->h_selectedtree_hiersearch_c_1, GLOBALS->bundle_direction_hiersearch_c_1); } MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } static void bundle_callback_generic(void) { if(!GLOBALS->autoname_bundles) { entrybox_local("Enter Bundle Name",300,"",128,GTK_SIGNAL_FUNC(bundle_cleanup)); } else { GLOBALS->entrybox_text_local_hiersearch_c_1=NULL; bundle_cleanup(NULL, NULL); } } static void bundle_callback_up(GtkWidget *widget, gpointer data) { (void)widget; (void)data; GLOBALS->bundle_direction_hiersearch_c_1=0; bundle_callback_generic(); } static void bundle_callback_down(GtkWidget *widget, gpointer data) { (void)widget; (void)data; GLOBALS->bundle_direction_hiersearch_c_1=1; bundle_callback_generic(); } /****************************************************************************/ static void select_row_callback(GtkWidget *widget, gint row, gint column, GdkEventButton *event, gpointer data) { (void)widget; (void)column; (void)event; (void)data; struct tree *t; t=(struct tree *)gtk_clist_get_row_data(GTK_CLIST(GLOBALS->clist_hiersearch_c_1), row); if(t) { GLOBALS->h_selectedtree_hiersearch_c_1=t; DEBUG(printf("Selected: %s\n",t->name)); if(t->child) { struct treechain *tc, *tc2; tc=GLOBALS->treechain_hiersearch_c_1; if(tc) { while(tc->next) tc=tc->next; tc2=calloc_2(1,sizeof(struct treechain)); tc2->label=t; tc2->tree=GLOBALS->current_tree_hiersearch_c_1; tc->next=tc2; } else { GLOBALS->treechain_hiersearch_c_1=calloc_2(1,sizeof(struct treechain)); GLOBALS->treechain_hiersearch_c_1->tree=GLOBALS->current_tree_hiersearch_c_1; GLOBALS->treechain_hiersearch_c_1->label=t; } GLOBALS->current_tree_hiersearch_c_1=t->child; refresh_hier_tree(GLOBALS->current_tree_hiersearch_c_1); } } else { struct treechain *tc; GLOBALS->h_selectedtree_hiersearch_c_1=NULL; tc=GLOBALS->treechain_hiersearch_c_1; if(tc) { for(;;) { if(tc->next) { if(tc->next->next) { tc=tc->next; continue; } else { GLOBALS->current_tree_hiersearch_c_1=tc->next->tree; free_2(tc->next); tc->next=NULL; break; } } else { free_2(tc); GLOBALS->treechain_hiersearch_c_1=NULL; GLOBALS->current_tree_hiersearch_c_1=GLOBALS->treeroot; break; } } refresh_hier_tree(GLOBALS->current_tree_hiersearch_c_1); } } } static void unselect_row_callback(GtkWidget *widget, gint row, gint column, GdkEventButton *event, gpointer data) { (void)widget; (void)column; (void)event; (void)data; struct tree *t; t=(struct tree *)gtk_clist_get_row_data(GTK_CLIST(GLOBALS->clist_hiersearch_c_1), row); GLOBALS->h_selectedtree_hiersearch_c_1=NULL; if(t) { DEBUG(printf("Unselected: %s\n",t->name)); } else { /* just ignore */ } } static void destroy_callback(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; GLOBALS->is_active_hiersearch_c_1=0; gtk_widget_destroy(GLOBALS->window_hiersearch_c_3); GLOBALS->window_hiersearch_c_3 = NULL; } /* * mainline.. */ void hier_searchbox(char *title, GtkSignalFunc func) { GtkWidget *scrolled_win; GtkWidget *vbox1, *hbox; GtkWidget *button1, *button2, *button3, *button3a, *button4, *button5; GtkWidget *label; gchar *titles[]={"Children"}; GtkWidget *frame1, *frame2, *frameh; GtkWidget *table; GtkTooltips *tooltips; /* fix problem where ungrab doesn't occur if button pressed + simultaneous accelerator key occurs */ if(GLOBALS->in_button_press_wavewindow_c_1) { gdk_pointer_ungrab(GDK_CURRENT_TIME); } if(GLOBALS->is_active_hiersearch_c_1) { gdk_window_raise(GLOBALS->window_hiersearch_c_3->window); return; } GLOBALS->is_active_hiersearch_c_1=1; GLOBALS->cleanup_hiersearch_c_3=func; GLOBALS->num_rows_hiersearch_c_1=GLOBALS->selected_rows_hiersearch_c_1=0; /* create a new modal window */ GLOBALS->window_hiersearch_c_3 = gtk_window_new(GLOBALS->disable_window_manager ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL); install_focus_cb(GLOBALS->window_hiersearch_c_3, ((char *)&GLOBALS->window_hiersearch_c_3) - ((char *)GLOBALS)); gtk_window_set_title(GTK_WINDOW (GLOBALS->window_hiersearch_c_3), title); gtkwave_signal_connect(GTK_OBJECT (GLOBALS->window_hiersearch_c_3), "delete_event",(GtkSignalFunc) destroy_callback, NULL); tooltips=gtk_tooltips_new_2(); table = gtk_table_new (256, 1, FALSE); gtk_widget_show (table); vbox1 = gtk_vbox_new (FALSE, 0); gtk_container_border_width (GTK_CONTAINER (vbox1), 3); gtk_widget_show (vbox1); frame1 = gtk_frame_new (NULL); gtk_container_border_width (GTK_CONTAINER (frame1), 3); gtk_widget_show(frame1); gtk_table_attach (GTK_TABLE (table), frame1, 0, 1, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); label=gtk_label_new("Signal Hierarchy"); gtk_widget_show(label); gtk_box_pack_start (GTK_BOX (vbox1), label, TRUE, TRUE, 0); GLOBALS->entry_main_hiersearch_c_1 = gtk_entry_new(); gtk_entry_set_editable(GTK_ENTRY(GLOBALS->entry_main_hiersearch_c_1), FALSE); gtk_widget_show (GLOBALS->entry_main_hiersearch_c_1); gtk_tooltips_set_tip_2(tooltips, GLOBALS->entry_main_hiersearch_c_1, "The hierarchy is built here by clicking on the appropriate " "items below in the scrollable window. Click on \"..\" to " "go up a level." ,NULL); gtk_box_pack_start (GTK_BOX (vbox1), GLOBALS->entry_main_hiersearch_c_1, TRUE, TRUE, 0); gtk_container_add (GTK_CONTAINER (frame1), vbox1); frame2 = gtk_frame_new (NULL); gtk_container_border_width (GTK_CONTAINER (frame2), 3); gtk_widget_show(frame2); gtk_table_attach (GTK_TABLE (table), frame2, 0, 1, 1, 254, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); GLOBALS->clist_hiersearch_c_1=gtk_clist_new_with_titles(1,titles); gtk_clist_column_titles_passive(GTK_CLIST(GLOBALS->clist_hiersearch_c_1)); gtk_clist_set_selection_mode(GTK_CLIST(GLOBALS->clist_hiersearch_c_1), GTK_SELECTION_SINGLE); gtkwave_signal_connect_object (GTK_OBJECT (GLOBALS->clist_hiersearch_c_1), "select_row",GTK_SIGNAL_FUNC(select_row_callback),NULL); gtkwave_signal_connect_object (GTK_OBJECT (GLOBALS->clist_hiersearch_c_1), "unselect_row",GTK_SIGNAL_FUNC(unselect_row_callback),NULL); gtk_widget_show (GLOBALS->clist_hiersearch_c_1); scrolled_win = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_widget_set_usize( GTK_WIDGET (scrolled_win), -1, 300); gtk_widget_show(scrolled_win); /* gtk_scrolled_window_add_with_viewport doesn't seen to work right here.. */ gtk_container_add (GTK_CONTAINER (scrolled_win), GLOBALS->clist_hiersearch_c_1); gtk_container_add (GTK_CONTAINER (frame2), scrolled_win); frameh = gtk_frame_new (NULL); gtk_container_border_width (GTK_CONTAINER (frameh), 3); gtk_widget_show(frameh); gtk_table_attach (GTK_TABLE (table), frameh, 0, 1, 255, 256, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); hbox = gtk_hbox_new (FALSE, 1); gtk_widget_show (hbox); button1 = gtk_button_new_with_label ("Append"); gtk_container_border_width (GTK_CONTAINER (button1), 3); gtkwave_signal_connect_object (GTK_OBJECT (button1), "clicked",GTK_SIGNAL_FUNC(ok_callback),GTK_OBJECT (GLOBALS->window_hiersearch_c_3)); gtk_widget_show (button1); gtk_tooltips_set_tip_2(tooltips, button1, "Add selected signals to end of the display on the main window.",NULL); gtk_box_pack_start (GTK_BOX (hbox), button1, TRUE, FALSE, 0); button2 = gtk_button_new_with_label (" Insert "); gtk_container_border_width (GTK_CONTAINER (button2), 3); gtkwave_signal_connect_object (GTK_OBJECT (button2), "clicked",GTK_SIGNAL_FUNC(insert_callback),GTK_OBJECT (GLOBALS->window_hiersearch_c_3)); gtk_widget_show (button2); gtk_tooltips_set_tip_2(tooltips, button2, "Add children after last highlighted signal on the main window.",NULL); gtk_box_pack_start (GTK_BOX (hbox), button2, TRUE, FALSE, 0); if(GLOBALS->vcd_explicit_zero_subscripts>=0) { button3 = gtk_button_new_with_label (" Bundle Up "); gtk_container_border_width (GTK_CONTAINER (button3), 3); gtkwave_signal_connect_object (GTK_OBJECT (button3), "clicked",GTK_SIGNAL_FUNC(bundle_callback_up),GTK_OBJECT (GLOBALS->window_hiersearch_c_3)); gtk_widget_show (button3); gtk_tooltips_set_tip_2(tooltips, button3, "Bundle children into a single bit vector with the topmost signal as the LSB and the lowest as the MSB.",NULL); gtk_box_pack_start (GTK_BOX (hbox), button3, TRUE, FALSE, 0); button3a = gtk_button_new_with_label (" Bundle Down "); gtk_container_border_width (GTK_CONTAINER (button3a), 3); gtkwave_signal_connect_object (GTK_OBJECT (button3a), "clicked",GTK_SIGNAL_FUNC(bundle_callback_down),GTK_OBJECT (GLOBALS->window_hiersearch_c_3)); gtk_widget_show (button3a); gtk_tooltips_set_tip_2(tooltips, button3a, "Bundle children into a single bit vector with the topmost signal as the MSB and the lowest as the LSB.",NULL); gtk_box_pack_start (GTK_BOX (hbox), button3a, TRUE, FALSE, 0); } button4 = gtk_button_new_with_label (" Replace "); gtk_container_border_width (GTK_CONTAINER (button4), 3); gtkwave_signal_connect_object (GTK_OBJECT (button4), "clicked",GTK_SIGNAL_FUNC(replace_callback),GTK_OBJECT (GLOBALS->window_hiersearch_c_3)); gtk_widget_show (button4); gtk_tooltips_set_tip_2(tooltips, button4, "Replace highlighted signals on the main window with children shown above.",NULL); gtk_box_pack_start (GTK_BOX (hbox), button4, TRUE, FALSE, 0); button5 = gtk_button_new_with_label (" Exit "); gtk_container_border_width (GTK_CONTAINER (button5), 3); gtkwave_signal_connect_object (GTK_OBJECT (button5), "clicked",GTK_SIGNAL_FUNC(destroy_callback),GTK_OBJECT (GLOBALS->window_hiersearch_c_3)); gtk_tooltips_set_tip_2(tooltips, button5, "Do nothing and return to the main window.",NULL); gtk_widget_show (button5); gtk_box_pack_start (GTK_BOX (hbox), button5, TRUE, FALSE, 0); gtk_container_add (GTK_CONTAINER (frameh), hbox); gtk_container_add (GTK_CONTAINER (GLOBALS->window_hiersearch_c_3), table); gtk_widget_show(GLOBALS->window_hiersearch_c_3); if(!GLOBALS->current_tree_hiersearch_c_1) { GLOBALS->current_tree_hiersearch_c_1=GLOBALS->treeroot; GLOBALS->h_selectedtree_hiersearch_c_1=NULL; } refresh_hier_tree(GLOBALS->current_tree_hiersearch_c_1); } gtkwave-3.3.66/src/savefile.c0000664000076400007640000016427512542115425015350 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2012-2013. * * 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. */ #include "globals.h" #include #include "savefile.h" #include "hierpack.h" #ifdef HAVE_SYS_STAT_H #include #endif #ifdef __linux__ #ifndef _XOPEN_SOURCE char *strptime(const char *s, const char *format, struct tm *tm); #endif #endif char *extract_dumpname_from_save_file(char *lcname, gboolean *modified, int *opt_vcd) { char *dfn = NULL; char *sfn = NULL; char *rp = NULL; FILE *f; off_t dumpsiz = -1; time_t dumptim = -1; if ((suffix_check(lcname, ".sav")) || (suffix_check(lcname, ".gtkw"))) { read_save_helper(lcname, &dfn, &sfn, &dumpsiz, &dumptim, opt_vcd); #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED || defined __CYGWIN__ || defined HAVE_REALPATH || defined __MINGW32__ if(sfn && dfn) { char *can = realpath_2(lcname, NULL); char *fdf = find_dumpfile(sfn, dfn, can); free(can); f = fopen(fdf, "rb"); if(f) { rp = fdf; fclose(f); goto bot; } } #endif if(dfn) { f = fopen(dfn, "rb"); if(f) { fclose(f); rp = strdup_2(dfn); goto bot; } } } bot: if(dfn) free_2(dfn); if(sfn) free_2(sfn); if(modified) *modified = 0; #ifdef HAVE_SYS_STAT_H if(modified && rp && (dumpsiz != -1) && (dumptim != -1)) { struct stat sbuf; if(!stat(rp, &sbuf)) { *modified = (dumpsiz != sbuf.st_size) || (dumptim != sbuf.st_mtime); } } #endif return(rp); } char *append_array_row(nptr n) { int was_packed = HIER_DEPACK_ALLOC; char *hname = hier_decompress_flagged(n->nname, &was_packed); #ifdef WAVE_ARRAY_SUPPORT if(!n->array_height) #endif { strcpy(GLOBALS->buf_menu_c_1, hname); } #ifdef WAVE_ARRAY_SUPPORT else { sprintf(GLOBALS->buf_menu_c_1, "%s{%d}", hname, n->this_row); } #endif if(was_packed) free_2(hname); return(GLOBALS->buf_menu_c_1); } void write_save_helper(const char *savnam, FILE *wave) { Trptr t; int i; unsigned int def=0; int sz_x, sz_y; TimeType prevshift=LLDescriptor(0); int root_x, root_y; struct strace *st; int s_ctx_iter; time_t walltime; DEBUG(printf("Write Save Fini: %s\n", savnam)); GLOBALS->dumpfile_is_modified = 0; /* writing a save file removes modification */ wave_gtk_window_set_title(GTK_WINDOW(GLOBALS->mainwindow), GLOBALS->winname, GLOBALS->dumpfile_is_modified ? WAVE_SET_TITLE_MODIFIED: WAVE_SET_TITLE_NONE, 0); time(&walltime); fprintf(wave, "[*]\n"); fprintf(wave, "[*] "WAVE_VERSION_INFO"\n"); fprintf(wave, "[*] %s",asctime(gmtime(&walltime))); fprintf(wave, "[*]\n"); if(GLOBALS->loaded_file_name) { if((GLOBALS->loaded_file_type == MISSING_FILE)||(GLOBALS->is_optimized_stdin_vcd)) { /* don't emit dumpfile tag */ } else { #ifdef HAVE_SYS_STAT_H struct stat sbuf; #endif char *unopt = GLOBALS->unoptimized_vcd_file_name ? GLOBALS->unoptimized_vcd_file_name: GLOBALS->loaded_file_name; #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED || defined __CYGWIN__ || defined HAVE_REALPATH || defined __MINGW32__ char *can = realpath_2(GLOBALS->optimize_vcd ? unopt : GLOBALS->loaded_file_name, NULL); const char *cansav = realpath_2(savnam, NULL); const int do_free = 1; #else char *can = GLOBALS->optimize_vcd ? unopt : GLOBALS->loaded_file_name; const char *cansav = savnam; const int do_free = 0; #endif fprintf(wave, "[dumpfile] \"%s\"\n", can); #ifdef HAVE_SYS_STAT_H if(!stat(can, &sbuf)) { char *asct = asctime(gmtime(&sbuf.st_mtime)); if(asct) { char *asct2 = strdup_2(asct); char *nl = strchr(asct2, '\n'); if(nl) *nl = 0; fprintf(wave, "[dumpfile_mtime] \"%s\"\n", asct2); free_2(asct2); fprintf(wave, "[dumpfile_size] %"PRIu64"\n", sbuf.st_size); } } #endif if(GLOBALS->optimize_vcd && GLOBALS->unoptimized_vcd_file_name) { fprintf(wave, "[optimize_vcd]\n"); } fprintf(wave, "[savefile] \"%s\"\n", cansav); /* emit also in order to do relative path matching in future... */ if(do_free) { free(can); } } } fprintf(wave, "[timestart] "TTFormat"\n", GLOBALS->tims.start); get_window_size (&sz_x, &sz_y); if(!GLOBALS->ignore_savefile_size) fprintf(wave,"[size] %d %d\n", sz_x, sz_y); get_window_xypos(&root_x, &root_y); if(!GLOBALS->ignore_savefile_pos) fprintf(wave,"[pos] %d %d\n", root_x + GLOBALS->xpos_delta, root_y + GLOBALS->ypos_delta); fprintf(wave,"*%f "TTFormat, (float)(GLOBALS->tims.zoom),GLOBALS->tims.marker); for(i=0;inamed_markers[i]; /* gcc compiler problem...thinks this is a 'long int' in printf format warning reporting */ fprintf(wave," "TTFormat,nm); } fprintf(wave,"\n"); for(i=0;imarker_names[i]) { char mbuf[16]; make_bijective_marker_id_string(mbuf, i); if(strlen(mbuf)<2) { fprintf(wave, "[markername] %s%s\n", mbuf, GLOBALS->marker_names[i]); } else { fprintf(wave, "[markername_long] %s %s\n", mbuf, GLOBALS->marker_names[i]); } } } if(GLOBALS->ruler_step) { fprintf(wave, "[ruler] "TTFormat" "TTFormat"\n", GLOBALS->ruler_origin, GLOBALS->ruler_step); } #if WAVE_USE_GTK2 if(GLOBALS->open_tree_nodes) { dump_open_tree_nodes(wave, GLOBALS->open_tree_nodes); } #endif #if GTK_CHECK_VERSION(2,4,0) if(!GLOBALS->ignore_savefile_pane_pos) { if(GLOBALS->toppanedwindow) { fprintf(wave, "[sst_width] %d\n", gtk_paned_get_position(GTK_PANED(GLOBALS->toppanedwindow))); } if(GLOBALS->panedwindow) { fprintf(wave, "[signals_width] %d\n", gtk_paned_get_position(GTK_PANED(GLOBALS->panedwindow))); } if(GLOBALS->expanderwindow) { GLOBALS->sst_expanded = gtk_expander_get_expanded(GTK_EXPANDER(GLOBALS->expanderwindow)); fprintf(wave, "[sst_expanded] %d\n", GLOBALS->sst_expanded); } if(GLOBALS->sst_vpaned) { fprintf(wave, "[sst_vpaned_height] %d\n", gtk_paned_get_position(GTK_PANED(GLOBALS->sst_vpaned))); } } #endif t=GLOBALS->traces.first; while(t) { if((t->flags!=def)||(t==GLOBALS->traces.first)) { if((t->flags & TR_PTRANSLATED) && (!t->p_filter)) t->flags &= (~TR_PTRANSLATED); if((t->flags & TR_FTRANSLATED) && (!t->f_filter)) t->flags &= (~TR_FTRANSLATED); if((t->flags & TR_TTRANSLATED) && (!t->t_filter)) t->flags &= (~TR_TTRANSLATED); fprintf(wave,"@%x\n",def=t->flags); } if((t->shift)||((prevshift)&&(!t->shift))) { fprintf(wave,">"TTFormat"\n", t->shift); } prevshift=t->shift; if(!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH))) { if(t->t_color) { fprintf(wave, "[color] %d\n", t->t_color); } if(t->flags & TR_FTRANSLATED) { if(t->f_filter && GLOBALS->filesel_filter[t->f_filter]) { fprintf(wave, "^%d %s\n", t->f_filter, GLOBALS->filesel_filter[t->f_filter]); } else { fprintf(wave, "^%d %s\n", 0, "disabled"); } } else if(t->flags & TR_PTRANSLATED) { if(t->p_filter && GLOBALS->procsel_filter[t->p_filter]) { fprintf(wave, "^>%d %s\n", t->p_filter, GLOBALS->procsel_filter[t->p_filter]); } else { fprintf(wave, "^>%d %s\n", 0, "disabled"); } } /* NOT an else! */ if(t->flags & TR_TTRANSLATED) { if(t->transaction_args) { fprintf(wave, "[transaction_args] \"%s\"\n", t->transaction_args); } else { fprintf(wave, "[transaction_args] \"%s\"\n", ""); } if(t->t_filter && GLOBALS->ttranssel_filter[t->t_filter]) { #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED || defined __CYGWIN__ || defined HAVE_REALPATH || defined __MINGW32__ char *can = realpath_2(GLOBALS->ttranssel_filter[t->t_filter], NULL); fprintf(wave, "^<%d %s\n", t->t_filter, can); free(can); #else fprintf(wave, "^<%d %s\n", t->t_filter, GLOBALS->ttranssel_filter[t->t_filter]); #endif } else { fprintf(wave, "^<%d %s\n", 0, "disabled"); } } if(t->vector && !(t->n.vec->transaction_cache && t->n.vec->transaction_cache->transaction_nd)) { int ix; nptr *nodes; bptr bits; baptr ba; if (HasAlias(t)) { fprintf(wave,"+{%s} ", t->name_full); } bits = t->n.vec->bits; ba = bits ? bits->attribs : NULL; fprintf(wave,"%c{%s}", ba ? ':' : '#', t->n.vec->transaction_cache ? t->n.vec->transaction_cache->bvname : t->n.vec->bvname); nodes=t->n.vec->bits->nodes; for(ix=0;ixn.vec->bits->nnbits;ix++) { if(nodes[ix]->expansion) { fprintf(wave," (%d)%s",nodes[ix]->expansion->parentbit, append_array_row(nodes[ix]->expansion->parent)); } else { fprintf(wave," %s",append_array_row(nodes[ix])); } if(ba) { fprintf(wave, " "TTFormat" %x", ba[ix].shift, ba[ix].flags); } } fprintf(wave,"\n"); } else { nptr nd = (t->vector && t->n.vec->transaction_cache && t->n.vec->transaction_cache->transaction_nd) ? t->n.vec->transaction_cache->transaction_nd : t->n.nd; if(HasAlias(t)) { if(nd->expansion) { fprintf(wave,"+{%s} (%d)%s\n",t->name_full,nd->expansion->parentbit, append_array_row(nd->expansion->parent)); } else { fprintf(wave,"+{%s} %s\n",t->name_full,append_array_row(nd)); } } else { if(nd->expansion) { fprintf(wave,"(%d)%s\n",nd->expansion->parentbit, append_array_row(nd->expansion->parent)); } else { fprintf(wave,"%s\n",append_array_row(nd)); } } } } else { if(!t->name) fprintf(wave,"-\n"); else fprintf(wave,"-%s\n",t->name); } t=t->t_next; } WAVE_STRACE_ITERATOR(s_ctx_iter) { GLOBALS->strace_ctx = &GLOBALS->strace_windows[GLOBALS->strace_current_window = s_ctx_iter]; fprintf(wave, "[pattern_trace] %d\n", s_ctx_iter); if(GLOBALS->strace_ctx->timearray) { if(GLOBALS->strace_ctx->shadow_straces) { swap_strace_contexts(); st=GLOBALS->strace_ctx->straces; if(GLOBALS->strace_ctx->straces) { fprintf(wave, "!%d%d%d%d%d%d%c%c\n", GLOBALS->strace_ctx->logical_mutex[0], GLOBALS->strace_ctx->logical_mutex[1], GLOBALS->strace_ctx->logical_mutex[2], GLOBALS->strace_ctx->logical_mutex[3], GLOBALS->strace_ctx->logical_mutex[4], GLOBALS->strace_ctx->logical_mutex[5], '@'+GLOBALS->strace_ctx->mark_idx_start, '@'+GLOBALS->strace_ctx->mark_idx_end); } while(st) { if(st->value==ST_STRING) { fprintf(wave, "?\"%s\n", st->string ? st->string : ""); /* search type for this trace is string.. */ } else { fprintf(wave, "?%02x\n", (unsigned char)st->value); /* else search type for this trace.. */ } t=st->trace; if(t->flags!=def) { if((t->flags & TR_FTRANSLATED) && (!t->f_filter)) t->flags &= (~TR_FTRANSLATED); if((t->flags & TR_PTRANSLATED) && (!t->p_filter)) t->flags &= (~TR_PTRANSLATED); if((t->flags & TR_TTRANSLATED) && (!t->t_filter)) t->flags &= (~TR_TTRANSLATED); fprintf(wave,"@%x\n",def=t->flags); } if((t->shift)||((prevshift)&&(!t->shift))) { fprintf(wave,">"TTFormat"\n", t->shift); } prevshift=t->shift; if(!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH))) { if(t->flags & TR_FTRANSLATED) { if(t->f_filter && GLOBALS->filesel_filter[t->f_filter]) { fprintf(wave, "^%d %s\n", t->f_filter, GLOBALS->filesel_filter[t->f_filter]); } else { fprintf(wave, "^%d %s\n", 0, "disabled"); } } else if(t->flags & TR_PTRANSLATED) { if(t->p_filter && GLOBALS->procsel_filter[t->p_filter]) { fprintf(wave, "^>%d %s\n", t->p_filter, GLOBALS->procsel_filter[t->p_filter]); } else { fprintf(wave, "^>%d %s\n", 0, "disabled"); } } /* NOT an else! */ if(t->flags & TR_TTRANSLATED) { if(t->transaction_args) { fprintf(wave, "[transaction_args] \"%s\"\n", t->transaction_args); } else { fprintf(wave, "[transaction_args] \"%s\"\n", ""); } if(t->t_filter && GLOBALS->ttranssel_filter[t->t_filter]) { #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED || defined __CYGWIN__ || defined HAVE_REALPATH || defined __MINGW32__ char *can = realpath_2(GLOBALS->ttranssel_filter[t->t_filter], NULL); fprintf(wave, "^<%d %s\n", t->t_filter, can); free(can); #else fprintf(wave, "^<%d %s\n", t->t_filter, GLOBALS->ttranssel_filter[t->t_filter]); #endif } else { fprintf(wave, "^<%d %s\n", 0, "disabled"); } } if(t->vector && !(t->n.vec->transaction_cache && t->n.vec->transaction_cache->transaction_nd)) { int ix; nptr *nodes; bptr bits; baptr ba; if (HasAlias(t)) { fprintf(wave,"+{%s} ", t->name_full); } bits = t->n.vec->bits; ba = bits ? bits->attribs : NULL; fprintf(wave,"%c{%s}", ba ? ':' : '#', t->n.vec->transaction_cache ? t->n.vec->transaction_cache->bvname : t->n.vec->bvname); nodes=t->n.vec->bits->nodes; for(ix=0;ixn.vec->bits->nnbits;ix++) { if(nodes[ix]->expansion) { fprintf(wave," (%d)%s",nodes[ix]->expansion->parentbit, append_array_row(nodes[ix]->expansion->parent)); } else { fprintf(wave," %s",append_array_row(nodes[ix])); } if(ba) { fprintf(wave, " "TTFormat" %x", ba[ix].shift, ba[ix].flags); } } fprintf(wave,"\n"); } else { nptr nd = (t->vector && t->n.vec->transaction_cache && t->n.vec->transaction_cache->transaction_nd) ? t->n.vec->transaction_cache->transaction_nd : t->n.nd; if(HasAlias(t)) { if(nd->expansion) { fprintf(wave,"+{%s} (%d)%s\n",t->name_full,nd->expansion->parentbit, append_array_row(nd->expansion->parent)); } else { fprintf(wave,"+{%s} %s\n",t->name_full,append_array_row(nd)); } } else { if(nd->expansion) { fprintf(wave,"(%d)%s\n",nd->expansion->parentbit, append_array_row(nd->expansion->parent)); } else { fprintf(wave,"%s\n",append_array_row(nd)); } } } } st=st->next; } /* while(st)... */ if(GLOBALS->strace_ctx->straces) { fprintf(wave, "!!\n"); /* mark end of strace region */ } swap_strace_contexts(); } else { struct mprintf_buff_t *mt = GLOBALS->strace_ctx->mprintf_buff_head; while(mt) { fprintf(wave, "%s", mt->str); mt=mt->next; } } } /* if(timearray)... */ } } void read_save_helper_relative_init(char *wname) { /* for relative files in parsewavline() */ if(GLOBALS->lcname) { free_2(GLOBALS->lcname); } GLOBALS->lcname = wname ? strdup_2(wname) : NULL; if(GLOBALS->sfn) { free_2(GLOBALS->sfn); GLOBALS->sfn = NULL; } } char *get_relative_adjusted_name(char *sfn, char *dfn, char *lcname) { char *rp = NULL; FILE *f; #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED || defined __CYGWIN__ || defined HAVE_REALPATH if(sfn && dfn) { char *can = realpath_2(lcname, NULL); char *fdf = find_dumpfile(sfn, dfn, can); free(can); if(fdf) { f = fopen(fdf, "rb"); if(f) { rp = fdf; fclose(f); goto bot; } } } #endif if(dfn) { f = fopen(dfn, "rb"); if(f) { fclose(f); rp = strdup_2(dfn); goto bot; } } bot: return(rp); } int read_save_helper(char *wname, char **dumpfile, char **savefile, off_t *dumpsiz, time_t *dumptim, int *opt_vcd) { FILE *wave; char *str = NULL; int wave_is_compressed; char traces_already_exist = (GLOBALS->traces.first != NULL); int rc = -1; int extract_dumpfile_savefile_only = (dumpfile != NULL) && (savefile != NULL); GLOBALS->is_gtkw_save_file = suffix_check(wname, ".gtkw") || suffix_check(wname, ".gtkw.gz") || suffix_check(wname, ".gtkw.zip"); if(suffix_check(wname, ".gz") || suffix_check(wname, ".zip")) { str=wave_alloca(strlen(wname)+5+1); strcpy(str,"zcat "); strcpy(str+5,wname); wave=popen(str,"r"); wave_is_compressed=~0; } else { wave=fopen(wname,"rb"); wave_is_compressed=0; } if(!wave) { fprintf(stderr, "Error opening save file '%s' for reading.\n", wname); perror("Why"); errno=0; } else { char *iline; int s_ctx_iter; if(extract_dumpfile_savefile_only) { while((iline=fgetmalloc(wave))) { if(!strncmp(iline, "[dumpfile]", 10)) { char *lhq = strchr(iline+10, '"'); char *rhq = strrchr(iline+10, '"'); if((lhq) && (rhq) && (lhq != rhq)) /* no real need to check rhq != NULL*/ { *rhq = 0; if(*dumpfile) free_2(*dumpfile); *dumpfile = strdup_2(lhq + 1); } } else if(!strncmp(iline, "[dumpfile_mtime]", 16)) { if(dumptim) { struct tm tm; time_t t; char *lhq = strchr(iline+16, '"'); char *rhq = strrchr(iline+16, '"'); memset(&tm, 0, sizeof(struct tm)); *dumptim = -1; #if !defined _MSC_VER && !defined __MINGW32__ /* format is: "Fri Feb 4 15:50:48 2011" */ if(lhq && rhq && (lhq != rhq)) { int slen; char *strp_buf; *rhq = 0; slen = strlen(lhq+1); strp_buf = calloc_2(1, slen + 32); /* workaround: linux strptime seems to overshoot its buffer */ strcpy(strp_buf, lhq+1); if(strptime(strp_buf, "%a %b %d %H:%M:%S %Y", &tm) != NULL) { t = timegm(&tm); if(t != -1) { *dumptim = t; } } free_2(strp_buf); } #endif } } else if(!strncmp(iline, "[dumpfile_size]", 15)) { if(dumpsiz) { *dumpsiz = atoi_64(iline+15); } } else if(!strncmp(iline, "[savefile]", 10)) { char *lhq = strchr(iline+10, '"'); char *rhq = strrchr(iline+10, '"'); if((lhq) && (rhq) && (lhq != rhq)) /* no real need to check rhq != NULL*/ { *rhq = 0; if(*savefile) free_2(*savefile); *savefile = strdup_2(lhq + 1); } } else if(!strncmp(iline, "[optimize_vcd]", 14)) { if(opt_vcd) { *opt_vcd = 1; } } free_2(iline); rc++; } if(wave_is_compressed) pclose(wave); else fclose(wave); return(rc); } read_save_helper_relative_init(wname); WAVE_STRACE_ITERATOR(s_ctx_iter) { GLOBALS->strace_ctx = &GLOBALS->strace_windows[GLOBALS->strace_current_window = s_ctx_iter]; GLOBALS->strace_ctx->shadow_encountered_parsewavline = 0; } if(GLOBALS->traces.total) { GLOBALS->group_depth=0; /* AddBlankTrace(NULL); in order to terminate any possible collapsed groups */ } if(GLOBALS->is_lx2) { while((iline=fgetmalloc(wave))) { parsewavline_lx2(iline, NULL, 0); free_2(iline); } lx2_import_masked(); if(wave_is_compressed) { pclose(wave); wave=popen(str,"r"); } else { fclose(wave); wave=fopen(wname,"rb"); } if(!wave) { fprintf(stderr, "Error opening save file '%s' for reading.\n", wname); perror("Why"); errno=0; return(rc); } } GLOBALS->default_flags=TR_RJUSTIFY; GLOBALS->shift_timebase_default_for_add=LLDescriptor(0); GLOBALS->strace_current_window = 0; /* in case there are shadow traces */ rc = 0; GLOBALS->which_t_color = 0; while((iline=fgetmalloc(wave))) { parsewavline(iline, NULL, 0); GLOBALS->strace_ctx->shadow_encountered_parsewavline |= GLOBALS->strace_ctx->shadow_active; free_2(iline); rc++; } GLOBALS->which_t_color = 0; WAVE_STRACE_ITERATOR(s_ctx_iter) { GLOBALS->strace_ctx = &GLOBALS->strace_windows[GLOBALS->strace_current_window = s_ctx_iter]; if(GLOBALS->strace_ctx->shadow_encountered_parsewavline) { GLOBALS->strace_ctx->shadow_encountered_parsewavline = 0; if(GLOBALS->strace_ctx->shadow_straces) { GLOBALS->strace_ctx->shadow_active = 1; swap_strace_contexts(); strace_maketimetrace(1); swap_strace_contexts(); GLOBALS->strace_ctx->shadow_active = 0; } } } GLOBALS->default_flags=TR_RJUSTIFY; GLOBALS->shift_timebase_default_for_add=LLDescriptor(0); update_markertime(GLOBALS->tims.marker); if(wave_is_compressed) pclose(wave); else fclose(wave); if(traces_already_exist) GLOBALS->timestart_from_savefile_valid = 0; EnsureGroupsMatch(); GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); #ifdef MAC_INTEGRATION if(GLOBALS->num_notebook_pages > 1) #endif { if(!GLOBALS->block_xy_update) { int x, y; get_window_size(&x, &y); set_window_size(x, y); } } } GLOBALS->current_translate_file = 0; return(rc); } /******************************************************************/ /* * attempt to synthesize bitwise on loader fail...caller must free return pnt */ static char *synth_blastvec(char *w) { char *mem = NULL; char *t; char *lbrack, *colon, *rbrack, *rname, *msbs, *lsbs; int wlen, bitlen, msb, lsb; int msbslen, lsbslen, maxnumlen; int i, siz; if(w) { if((lbrack = strrchr(w, '['))) if((colon = strchr(lbrack+1, ':'))) if((rbrack = strchr(colon+1, ']'))) { *lbrack = *colon = *rbrack = 0; msbs = lbrack + 1; lsbs = colon + 1; rname = hier_extract(w, GLOBALS->hier_max_level); msb = atoi(msbs); lsb = atoi(lsbs); bitlen = (msb > lsb) ? (msb - lsb + 1) : (lsb - msb + 1); if(bitlen > 1) { wlen = strlen(w); msbslen = strlen(msbs); lsbslen = strlen(lsbs); maxnumlen = (msbslen > lsbslen) ? msbslen : lsbslen; siz = 1 + /* # */ strlen(rname) + /* vector alias name */ 1+ /* */ 1+ /* [ */ msbslen+ /* msb */ 1+ /* : */ lsbslen+ /* lsb */ 1+ /* ] */ 1; /* */ siz += bitlen * ( wlen + /* full bitname */ 1+ /* [ */ maxnumlen+ /* individual bit */ 1+ /* ] */ 1 /* */ ); mem = calloc_2(1, siz); t = mem + sprintf(mem, "#%s[%d:%d] ", rname, msb, lsb); if(msb > lsb) { for(i = msb; i >= lsb; i--) { t += sprintf(t, "%s[%d]", w, i); if(i!=lsb) t += sprintf(t, " "); } } else { for(i = msb; i <= lsb; i++) { t += sprintf(t, "%s[%d]", w, i); if(i!=lsb) t += sprintf(t, " "); } } /* fprintf(stderr, "%d,%d: %s\n", siz, strlen(mem), mem); */ } } } return(mem); } /******************************************************************/ /* * Parse a line of the wave file and act accordingly.. * Returns nonzero if trace(s) added. */ int parsewavline(char *w, char *alias, int depth) { int i; int len; char *w2; nptr nexp; unsigned int rows = 0; char *prefix, *suffix, *new; char *prefix_init, *w2_init; unsigned int mode; if(!(len=strlen(w))) return(0); if(*(w+len-1)=='\n') { *(w+len-1)=0x00; /* strip newline if present */ len--; if(!len) return(0); } while(1) { if(isspace((int)(unsigned char)*w)) { w++; continue; } if(!(*w)) return(0); /* no args */ break; /* start grabbing chars from here */ } w2=w; /* sscanf(w2,"%s",prefix); */ prefix=(char *)wave_alloca(len+1); suffix=(char *)wave_alloca(len+1); new=(char *)wave_alloca(len+1); memset(new, 0, len+1); /* scan-build */ prefix_init = prefix; w2_init = new; mode = 0; /* 0 = before "{", 1 = after "{", 2 = after "}" or " " */ while(*w2) { if((mode == 0) && (*w2 == '{')) { mode = 1; w2++; } else if((mode == 1) && (*w2 == '}')) { /* strcpy(prefix, ""); */ *(prefix) = '\0'; mode = 2; w2++; } else if((mode == 0) && (*w2 == ' ')) { /* strcpy(prefix, ""); */ *(prefix) = '\0'; strcpy(new, w2); mode = 2; w2++; new++; } else { strcpy(new, w2); if (mode != 2) { strcpy(prefix, w2); prefix++; } w2++; new++; } } prefix = prefix_init; w2 = w2_init; /* printf("HHHHH |%s| %s\n", prefix, w2); */ if(*w2=='*') { float f; TimeType ttlocal; int which=0; GLOBALS->zoom_was_explicitly_set=~0; w2++; for(;;) { while(*w2==' ') w2++; if(*w2==0) return(~0); if(!which) { sscanf(w2,"%f",&f); if((!GLOBALS->do_initial_zoom_fit)||(!GLOBALS->do_initial_zoom_fit_used)) { GLOBALS->tims.zoom=(gdouble)f; } } else { sscanf(w2,TTFormat,&ttlocal); switch(which) { case 1: GLOBALS->tims.marker=ttlocal; break; default: if((which-2)named_markers[which-2]=ttlocal; break; } } which++; w2++; for(;;) { if(*w2==0) return(~0); if(*w2=='\n') return(~0); if(*w2!=' ') w2++; else break; } } } else if(*w2=='-') { AddBlankTrace((*(w2+1)!=0)?(w2+1):NULL); } else if(*w2=='>') { char *wnptr=(*(w2+1)!=0)?(w2+1):NULL; GLOBALS->shift_timebase_default_for_add=wnptr?atoi_64(wnptr):LLDescriptor(0); } else if(*w2=='@') { /* handle trace flags */ sscanf(w2+1, "%x", &GLOBALS->default_flags); if( (GLOBALS->default_flags & (TR_FTRANSLATED|TR_PTRANSLATED)) == (TR_FTRANSLATED|TR_PTRANSLATED) ) { GLOBALS->default_flags &= ~TR_PTRANSLATED; /* safest bet though this is a cfg file error */ } return(~0); } else if(*w2=='+') { /* handle aliasing */ struct symbol *s; sscanf(w2+strlen(prefix),"%s",suffix); if(suffix[0]=='(') { for(i=1;;i++) { if(suffix[i]==0) return(0); if((suffix[i]==')')&&(suffix[i+1])) {i++; break; } } s=symfind(suffix+i, &rows); if (s) { nexp = ExtractNodeSingleBit(&s->n[rows], atoi(suffix+1)); if(nexp) { AddNode(nexp, prefix+1); return(~0); } else { return(0); } } else { char *lp = strrchr(suffix+i, '['); if(lp) { char *ns = malloc_2(strlen(suffix+i) + 32); char *colon = strchr(lp+1, ':'); int msi, lsi, bval, actual; *lp = 0; bval = atoi(suffix+1); if(colon) { msi = atoi(lp+1); lsi = atoi(colon+1); if(lsi > msi) { actual = msi + bval; } else { actual = msi - bval; } } else { actual = bval; /* punt */ } sprintf(ns, "%s[%d]", suffix+i, actual); *lp = '['; s=symfind(ns, &rows); free_2(ns); if(s) { AddNode(&s->n[rows], prefix+1); return(~0); } } return(0); } } else { int rc; char *newl = strdup_2(w2+strlen(prefix)); char *nalias = strdup_2(prefix+1); rc = parsewavline(newl, nalias, depth); if (newl) free_2(newl); if (nalias) free_2(nalias); return rc; } /* { */ /* if((s=symfind(suffix, &rows))) */ /* { */ /* AddNode(&s->n[rows],prefix+1); */ /* return(~0); */ /* } */ /* else */ /* { */ /* return(0); */ /* } */ /* } */ } else if((*w2=='#')||(*w2==':')) { /* handle bitvec */ bvptr v=NULL; bptr b=NULL; int maketyp = (*w2=='#'); w2=w2+strlen(prefix); while(1) { if(isspace((int)(unsigned char)*w2)) { w2++; continue; } if(!(*w2)) return(0); /* no more args */ break; /* start grabbing chars from here */ } b = maketyp ? makevec(prefix+1,w2) : makevec_annotated(prefix+1,w2); /* '#' vs ':' cases... */ if(b) { if((v=bits2vector(b))) { v->bits=b; /* only needed for savefile function */ AddVector(v, alias); free_2(b->name); b->name=NULL; return(v!=NULL); } else { free_2(b->name); if(b->attribs) free_2(b->attribs); free_2(b); } } else if(!depth) /* don't try vectorized if we're re-entrant */ { char *sp = strchr(w2, ' '); char *lbrack; if(sp) { *sp = 0; lbrack = strrchr(w2, '['); if(lbrack) { /* int made = 0; */ /* scan-build */ char *w3; char *rbrack = strrchr(w2, ']'); char *rightmost_lbrack = strrchr(sp+1, '['); if(rbrack && rightmost_lbrack) { *rbrack = 0; w3 = malloc_2(strlen(w2) + 1 + strlen(rightmost_lbrack+1) + 1); sprintf(w3, "%s:%s", w2, rightmost_lbrack+1); /* made = */ maketraces(w3, alias, 1); /* scan-build */ free_2(w3); } #if 0 /* this is overkill for now with possible delay implications so commented out */ if(!made) { *lbrack = 0; fprintf(stderr, "GTKWAVE | Attempting regex '%s' on missing stranded vector\n", w2); w3 = malloc_2(1 + strlen(w2) + 5); sprintf(w3, "^%s\\[.*", w2); maketraces(w3, alias, 1); free_2(w3); } #endif } } } return(v!=NULL); } else if(*w2=='!') { /* fill logical_mutex */ char ch; for(i=0;i<6;i++) { ch = *(w2+i+1); if(ch != 0) { if(ch=='!') { GLOBALS->strace_ctx->shadow_active = 0; return(~0); } if((!i)&&(GLOBALS->strace_ctx->shadow_straces)) { delete_strace_context(); } GLOBALS->strace_ctx->shadow_logical_mutex[i] = (ch & 1); } else /* in case of short read */ { GLOBALS->strace_ctx->shadow_logical_mutex[i] = 0; } } GLOBALS->strace_ctx->shadow_mark_idx_start = 0; GLOBALS->strace_ctx->shadow_mark_idx_end = 0; if(i==6) { ch = *(w2+7); if(ch != 0) { if (isupper((int)(unsigned char)ch) || ch=='@') GLOBALS->strace_ctx->shadow_mark_idx_start = ch - '@'; ch = *(w2+8); if(ch != 0) { if (isupper((int)(unsigned char)ch) || ch=='@') GLOBALS->strace_ctx->shadow_mark_idx_end = ch - '@'; } } } GLOBALS->strace_ctx->shadow_active = 1; return(~0); } else if(*w2=='?') { /* fill st->type */ if(*(w2+1)=='\"') { int lens = strlen(w2+2); if(GLOBALS->strace_ctx->shadow_string) free_2(GLOBALS->strace_ctx->shadow_string); GLOBALS->strace_ctx->shadow_string=NULL; if(lens) { GLOBALS->strace_ctx->shadow_string = malloc_2(lens+1); strcpy(GLOBALS->strace_ctx->shadow_string, w2+2); } GLOBALS->strace_ctx->shadow_type = ST_STRING; } else { unsigned int hex; sscanf(w2+1, "%x", &hex); GLOBALS->strace_ctx->shadow_type = hex; } return(~0); } else if(*w2=='^') { if(*(w2+1) == '>') { GLOBALS->current_translate_proc = 0; /* will overwrite if loadable/translatable */ if(*(w2+2) != '0') { /* char *fn = strstr(w2+3, " "); */ char *fn = w2+2; while(*fn && !isspace((int)(unsigned char)*fn)) fn++; if(fn) { while(*fn && isspace((int)(unsigned char)*fn)) fn++; if(*fn && !isspace((int)(unsigned char)*fn)) { char *rp = get_relative_adjusted_name(GLOBALS->sfn, fn, GLOBALS->lcname); set_current_translate_proc(rp ? rp : fn); if(rp) free_2(rp); } } } } else if(*(w2+1) == '<') { GLOBALS->current_translate_ttrans = 0; /* will overwrite if loadable/translatable */ if(*(w2+2) != '0') { /* char *fn = strstr(w2+3, " "); */ char *fn = w2+3; if(fn) { while(*fn && isspace((int)(unsigned char)*fn)) fn++; if(*fn && !isspace((int)(unsigned char)*fn)) { char *rp = get_relative_adjusted_name(GLOBALS->sfn, fn, GLOBALS->lcname); set_current_translate_ttrans(rp ? rp : fn); if(rp) free_2(rp); } } } } else { GLOBALS->current_translate_file = 0; /* will overwrite if loadable/translatable */ if(*(w2+1) != '0') { char *fn = strstr(w2+2, " "); if(fn) { while(*fn && isspace((int)(unsigned char)*fn)) fn++; if(*fn && !isspace((int)(unsigned char)*fn)) { char *rp = get_relative_adjusted_name(GLOBALS->sfn, fn, GLOBALS->lcname); set_current_translate_file(rp ? rp : fn); if(rp) free_2(rp); } } } } } else if (*w2 == '[') { /* Search for matching ']'. */ w2++; for (w = w2; *w; w++) if (*w == ']') break; if (!*w) return 0; *w++ = 0; if (strcmp (w2, "size") == 0) { if(!GLOBALS->ignore_savefile_size) { /* Main window size. */ int x, y; sscanf (w, "%d %d", &x, &y); if(!GLOBALS->block_xy_update) set_window_size (x, y); } } else if (strcmp (w2, "pos") == 0) { if(!GLOBALS->ignore_savefile_pos) { /* Main window position. */ int x, y; sscanf (w, "%d %d", &x, &y); if(!GLOBALS->block_xy_update) set_window_xypos (x, y); } } else if (strcmp (w2, "sst_width") == 0) { if(!GLOBALS->ignore_savefile_pane_pos) { /* sst vs rhs of window position. */ int x; sscanf (w, "%d", &x); if(!GLOBALS->block_xy_update) { if(GLOBALS->toppanedwindow) { #if GTK_CHECK_VERSION(2,4,0) gtk_paned_set_position(GTK_PANED(GLOBALS->toppanedwindow), x); #endif } else { GLOBALS->toppanedwindow_size_cache = x; } } } } else if (strcmp (w2, "signals_width") == 0) { if(!GLOBALS->ignore_savefile_pane_pos) { /* signals vs waves panes position. */ int x; sscanf (w, "%d", &x); if(!GLOBALS->block_xy_update) { if(GLOBALS->panedwindow) { #if GTK_CHECK_VERSION(2,4,0) gtk_paned_set_position(GTK_PANED(GLOBALS->panedwindow), x); #endif } else { GLOBALS->panedwindow_size_cache = x; } } } } else if (strcmp (w2, "sst_expanded") == 0) { if(!GLOBALS->ignore_savefile_pane_pos) { /* sst is expanded? */ int x; sscanf (w, "%d", &x); GLOBALS->sst_expanded = (x != 0); #if GTK_CHECK_VERSION(2,4,0) if(!GLOBALS->block_xy_update) { if(GLOBALS->expanderwindow) { gtk_expander_set_expanded(GTK_EXPANDER(GLOBALS->expanderwindow), GLOBALS->sst_expanded); } } #endif } } else if (strcmp (w2, "sst_vpaned_height") == 0) { if(!GLOBALS->ignore_savefile_pane_pos) { /* signals vs waves panes position. */ int x; sscanf (w, "%d", &x); if(!GLOBALS->block_xy_update) { if(GLOBALS->sst_vpaned) { #if GTK_CHECK_VERSION(2,4,0) gtk_paned_set_position(GTK_PANED(GLOBALS->sst_vpaned), x); #endif } else { GLOBALS->vpanedwindow_size_cache = x; } } } } else if (strcmp (w2, "color") == 0) { int which_col = 0; sscanf (w, "%d", &which_col); if((which_col>=0)&&(which_col<=WAVE_NUM_RAINBOW)) { GLOBALS->which_t_color = which_col; } else { GLOBALS->which_t_color = 0; } } else if (strcmp (w2, "pattern_trace") == 0) { int which_ctx = 0; sscanf (w, "%d", &which_ctx); if((which_ctx>=0)&&(which_ctxstrace_ctx = &GLOBALS->strace_windows[GLOBALS->strace_current_window = which_ctx]; } } else if (strcmp (w2, "ruler") == 0) { GLOBALS->ruler_origin = GLOBALS->ruler_step = LLDescriptor(0); sscanf(w, TTFormat" "TTFormat, &GLOBALS->ruler_origin, &GLOBALS->ruler_step); } else if (strcmp (w2, "timestart") == 0) { sscanf(w, TTFormat, &GLOBALS->timestart_from_savefile); GLOBALS->timestart_from_savefile_valid = 1; } #if WAVE_USE_GTK2 else if (strcmp (w2, "treeopen") == 0) { while(*w) { if(!isspace((int)(unsigned char)*w)) { break; } w++; } if(GLOBALS->ctree_main) { force_open_tree_node(w, 0, NULL); } else { /* cache values until ctree_main is created */ struct string_chain_t *t = calloc_2(1, sizeof(struct string_chain_t)); t->str = strdup_2(w); if(!GLOBALS->treeopen_chain_curr) { GLOBALS->treeopen_chain_head = GLOBALS->treeopen_chain_curr = t; } else { GLOBALS->treeopen_chain_curr->next = t; GLOBALS->treeopen_chain_curr = t; } } } #endif else if (strcmp (w2, "markername") == 0) { char *pnt = w; int which; if((*pnt) && (isspace((int)(unsigned char)*pnt))) pnt++; if(*pnt) { which = (*pnt) - 'A'; if((which >=0) && (which < WAVE_NUM_NAMED_MARKERS)) { pnt++; if(*pnt) { if(GLOBALS->marker_names[which]) free_2(GLOBALS->marker_names[which]); GLOBALS->marker_names[which] = strdup_2(pnt); } } } } else if (strcmp (w2, "markername_long") == 0) { char *pnt = w; int which; if((*pnt) && (isspace((int)(unsigned char)*pnt))) pnt++; if(*pnt) { char *pnt2 = strchr(pnt, ' '); if(pnt2) { *pnt2 = 0; which = bijective_marker_id_string_hash(pnt); if((which >=0) && (which < WAVE_NUM_NAMED_MARKERS)) { pnt = pnt2 + 1; if((*pnt) && (isspace((int)(unsigned char)*pnt))) pnt++; if(*pnt) { if(GLOBALS->marker_names[which]) free_2(GLOBALS->marker_names[which]); GLOBALS->marker_names[which] = strdup_2(pnt); } } } } } else if (strcmp (w2, "dumpfile") == 0) { /* nothing here currently...only finder/DnD processes these externally */ } else if (strcmp (w2, "savefile") == 0) { /* store name for relative name processing of filters */ char *lhq = strchr(w, '"'); char *rhq = strrchr(w, '"'); if(GLOBALS->sfn) { free_2(GLOBALS->sfn); GLOBALS->sfn = NULL; } if((lhq) && (rhq) && (lhq != rhq)) /* no real need to check rhq != NULL*/ { *rhq = 0; GLOBALS->sfn = strdup_2(lhq + 1); } } else if (strcmp (w2, "transaction_args") == 0) { char *lhq = strchr(w, '"'); char *rhq = strrchr(w, '"'); if(GLOBALS->ttranslate_args) { free_2(GLOBALS->ttranslate_args); GLOBALS->ttranslate_args = NULL; } if((lhq) && (rhq) && (lhq != rhq)) /* no real need to check rhq != NULL*/ { *rhq = 0; GLOBALS->ttranslate_args = strdup_2(lhq + 1); } } else if (strcmp (w2, "*") == 0) { /* reserved for [*] comment lines */ } else { /* Unknown attribute. Forget it. */ return 0; } } else { int rc = maketraces(w, alias, 0); if(rc) { return(rc); } else { char *newl = synth_blastvec(w); if(newl) { rc = parsewavline(newl, alias, depth+1); free_2(newl); } /* prevent malformed group openings [missing group opening] from keeping other signals from displaying */ if((!rc)&&(GLOBALS->default_flags&TR_GRP_BEGIN)) { AddBlankTrace(w); rc = ~0; } return(rc); } } return(0); } /******************************************************************/ /****************/ /* LX2 variants */ /****************/ /* * Make solitary traces from wildcarded signals... */ int maketraces_lx2(char *str, char *alias, int quick_return) { (void)alias; char *pnt, *wild; char ch, wild_active=0; int len; int i; int made = 0; pnt=str; while((ch=*pnt)) { if(ch=='*') { wild_active=1; break; } pnt++; } if(!wild_active) /* short circuit wildcard evaluation with bsearch */ { struct symbol *s; if(str[0]=='(') { for(i=1;;i++) { if(str[i]==0) return(0); if((str[i]==')')&&(str[i+1])) {i++; break; } } if((s=symfind(str+i, NULL))) { lx2_set_fac_process_mask(s->n); made = ~0; } return(made); } else { if((s=symfind(str, NULL))) { lx2_set_fac_process_mask(s->n); made = ~0; } return(made); } } while(1) { pnt=str; len=0; while(1) { ch=*pnt++; if(isspace((int)(unsigned char)ch)||(!ch)) break; len++; } if(len) { wild=(char *)calloc_2(1,len+1); memcpy(wild,str,len); wave_regex_compile(wild, WAVE_REGEX_WILD); for(i=0;inumfacs;i++) { if(wave_regex_match(GLOBALS->facs[i]->name, WAVE_REGEX_WILD)) { lx2_set_fac_process_mask(GLOBALS->facs[i]->n); made = ~0; if(quick_return) break; } } free_2(wild); } if(!ch) break; str=pnt; } return(made); } /* * Create a vector from wildcarded signals... */ int makevec_lx2(char *str) { char *pnt, *pnt2, *wild=NULL; char ch, ch2, wild_active; int len; int i; int rc = 0; while(1) { pnt=str; len=0; while(1) { ch=*pnt++; if(isspace((int)(unsigned char)ch)||(!ch)) break; len++; } if(len) { wild=(char *)calloc_2(1,len+1); memcpy(wild,str,len); DEBUG(printf("WILD: %s\n",wild)); wild_active=0; pnt2=wild; while((ch2=*pnt2)) { if(ch2=='*') { wild_active=1; break; } pnt2++; } if(!wild_active) /* short circuit wildcard evaluation with bsearch */ { struct symbol *s; if(wild[0]=='(') { for(i=1;;i++) { if(wild[i]==0) break; if((wild[i]==')')&&(wild[i+1])) { i++; s=symfind(wild+i, NULL); if(s) { lx2_set_fac_process_mask(s->n); rc = 1; } break; } } } else { if((s=symfind(wild, NULL))) { lx2_set_fac_process_mask(s->n); rc = 1; } } } else { wave_regex_compile(wild, WAVE_REGEX_WILD); for(i=GLOBALS->numfacs-1;i>=0;i--) /* to keep vectors in little endian hi..lo order */ { if(wave_regex_match(GLOBALS->facs[i]->name, WAVE_REGEX_WILD)) { lx2_set_fac_process_mask(GLOBALS->facs[i]->n); rc = 1; } } } free_2(wild); } if(!ch) break; str=pnt; } return(rc); } /* * Parse a line of the wave file and act accordingly.. * Returns nonzero if trace(s) added. */ int parsewavline_lx2(char *w, char *alias, int depth) { int made = 0; int i; int len; char *w2; char *prefix, *suffix, *new; char *prefix_init, *w2_init; unsigned int mode; if(!(len=strlen(w))) return(0); if(*(w+len-1)=='\n') { *(w+len-1)=0x00; /* strip newline if present */ len--; if(!len) return(0); } while(1) { if(isspace((int)(unsigned char)*w)) { w++; continue; } if(!(*w)) return(0); /* no args */ break; /* start grabbing chars from here */ } w2=w; /* sscanf(w2,"%s",prefix); */ prefix=(char *)wave_alloca(len+1); suffix=(char *)wave_alloca(len+1); new=(char *)wave_alloca(len+1); new[0] = 0; /* scan-build : in case there are weird mode problems */ prefix_init = prefix; w2_init = new; mode = 0; /* 0 = before "{", 1 = after "{", 2 = after "}" or " " */ while(*w2) { if((mode == 0) && (*w2 == '{')) { mode = 1; w2++; } else if((mode == 1) && (*w2 == '}')) { *(prefix) = '\0'; mode = 2; w2++; } else if((mode == 0) && (*w2 == ' ')) { *(prefix) = '\0'; strcpy(new, w2); mode = 2; w2++; new++; } else { strcpy(new, w2); if (mode != 2) { strcpy(prefix, w2); prefix++; } w2++; new++; } } prefix = prefix_init; w2 = w2_init; /* printf("IIIII |%s| %s\n", prefix, w2); */ if(*w2=='[') { } else if(*w2=='*') { } else if(*w2=='-') { } else if(*w2=='>') { } else if(*w2=='@') { } else if(*w2=='+') { /* handle aliasing */ struct symbol *s; sscanf(w2+strlen(prefix),"%s",suffix); if(suffix[0]=='(') { for(i=1;;i++) { if(suffix[i]==0) return(0); if((suffix[i]==')')&&(suffix[i+1])) {i++; break; } } s=symfind(suffix+i, NULL); if(s) { lx2_set_fac_process_mask(s->n); made = ~0; } else { char *lp = strrchr(suffix+i, '['); if(lp) { char *ns = malloc_2(strlen(suffix+i) + 32); char *colon = strchr(lp+1, ':'); int msi, lsi, bval, actual; *lp = 0; bval = atoi(suffix+1); if(colon) { msi = atoi(lp+1); lsi = atoi(colon+1); if(lsi > msi) { actual = msi + bval; } else { actual = msi - bval; } } else { actual = bval; /* punt */ } sprintf(ns, "%s[%d]", suffix+i, actual); *lp = '['; s=symfind(ns, NULL); free_2(ns); if(s) { lx2_set_fac_process_mask(s->n); made = ~0; } } } return(made); } else { int rc; char *newl = strdup_2(w2+strlen(prefix)); char *nalias = strdup_2(prefix+1); rc = parsewavline_lx2(newl, nalias, depth); if (newl) free_2(newl); if (nalias) free_2(nalias); return rc; } /* { */ /* if((s=symfind(suffix, NULL))) */ /* { */ /* lx2_set_fac_process_mask(s->n); */ /* made = ~0; */ /* } */ /* return(made); */ /* } */ } else if((*w2=='#')||(*w2==':')) { int rc; /* handle bitvec, parsing extra time info and such is inefficient but ok for ":" case */ w2=w2+strlen(prefix); while(1) { if(isspace((int)(unsigned char)*w2)) { w2++; continue; } if(!(*w2)) return(0); /* no more args */ break; /* start grabbing chars from here */ } rc = makevec_lx2(w2); if((!rc)&&(!depth)) /* don't try vectorized if we're re-entrant */ { char *sp = strchr(w2, ' '); char *lbrack; if(sp) { *sp = 0; lbrack = strrchr(w2, '['); if(lbrack) { char *w3; char *rbrack = strrchr(w2, ']'); char *rightmost_lbrack = strrchr(sp+1, '['); if(rbrack && rightmost_lbrack) { *rbrack = 0; w3 = malloc_2(strlen(w2) + 1 + strlen(rightmost_lbrack+1) + 1); sprintf(w3, "%s:%s", w2, rightmost_lbrack+1); made = maketraces_lx2(w3, alias, 1); free_2(w3); } if(0) /* this is overkill for now with possible delay implications so commented out */ if(!made) { *lbrack = 0; w3 = malloc_2(1 + strlen(w2) + 5); sprintf(w3, "^%s\\[.*", w2); maketraces_lx2(w3, alias, 1); free_2(w3); } } } } return(made); } else if(*w2=='!') { } else if(*w2=='?') { } else if(*w2=='^') { } else { made = maketraces_lx2(w, alias, 0); if(!made) { char *newl = synth_blastvec(w); if(newl) { made = parsewavline_lx2(newl, alias, depth+1); free_2(newl); } } } return(made); } /******************************************************************/ /* GetRelativeFilename(), by Rob Fisher. * rfisher@iee.org * http://come.to/robfisher */ #define MAX_FILENAME_LEN PATH_MAX /* The number of characters at the start of an absolute filename. e.g. in DOS, * absolute filenames start with "X:\" so this value should be 3, in UNIX they start * with "\" so this value should be 1. */ #if defined _MSC_VER || defined __MINGW32__ #define ABSOLUTE_NAME_START 3 #else #define ABSOLUTE_NAME_START 1 #endif /* set this to '\\' for DOS or '/' for UNIX */ #if defined _MSC_VER || defined __MINGW32__ #define SLASH '\\' #else #define SLASH '/' #endif /* Given the absolute current directory and an absolute file name, returns a relative file name. * For example, if the current directory is C:\foo\bar and the filename C:\foo\whee\text.txt is given, * GetRelativeFilename will return ..\whee\text.txt. */ char* GetRelativeFilename(char *currentDirectory, char *absoluteFilename, int *dotdot_levels) { int afMarker = 0, rfMarker = 0; int cdLen = 0, afLen = 0; int i = 0; int levels = 0; static char relativeFilename[MAX_FILENAME_LEN+1]; *dotdot_levels = 0; cdLen = strlen(currentDirectory); afLen = strlen(absoluteFilename); /* make sure the names are not too long or too short */ if(cdLen > MAX_FILENAME_LEN || cdLen < ABSOLUTE_NAME_START+1 || afLen > MAX_FILENAME_LEN || afLen < ABSOLUTE_NAME_START+1) { return(NULL); } /* Handle DOS names that are on different drives: */ if(currentDirectory[0] != absoluteFilename[0]) { /* not on the same drive, so only absolute filename will do */ strcpy(relativeFilename, absoluteFilename); return(relativeFilename); } /* they are on the same drive, find out how much of the current directory * is in the absolute filename */ i = ABSOLUTE_NAME_START; while(i < afLen && i < cdLen && currentDirectory[i] == absoluteFilename[i]) { i++; } if(i == cdLen && (absoluteFilename[i] == SLASH || absoluteFilename[i-1] == SLASH)) { /* the whole current directory name is in the file name, * so we just trim off the current directory name to get the * current file name. */ if(absoluteFilename[i] == SLASH) { /* a directory name might have a trailing slash but a relative * file name should not have a leading one... */ i++; } strcpy(relativeFilename, &absoluteFilename[i]); return(relativeFilename); } /* The file is not in a child directory of the current directory, so we * need to step back the appropriate number of parent directories by * using "..\"s. First find out how many levels deeper we are than the * common directory */ afMarker = i; levels = 1; /* count the number of directory levels we have to go up to get to the * common directory */ while(i < cdLen) { i++; if(currentDirectory[i] == SLASH) { /* make sure it's not a trailing slash */ i++; if(currentDirectory[i] != '\0') { levels++; } } } /* move the absolute filename marker back to the start of the directory name * that it has stopped in. */ while(afMarker > 0 && absoluteFilename[afMarker-1] != SLASH) { afMarker--; } /* check that the result will not be too long */ if(levels * 3 + afLen - afMarker > MAX_FILENAME_LEN) { return(NULL); } /* add the appropriate number of "..\"s. */ rfMarker = 0; *dotdot_levels = levels; for(i = 0; i < levels; i++) { relativeFilename[rfMarker++] = '.'; relativeFilename[rfMarker++] = '.'; relativeFilename[rfMarker++] = SLASH; } /* copy the rest of the filename into the result string */ strcpy(&relativeFilename[rfMarker], &absoluteFilename[afMarker]); return(relativeFilename); } /******************************************************************/ #ifdef __MINGW32__ static void find_dumpfile_scrub_slashes(char *s) { if(s) { while(*s) { if(*s == '/') *s = '\\'; s++; } } } #else static void find_dumpfile_scrub_slashes(char *s) { if(s) { if(s[0] && s[1] && s[2] && (s[1] == ':') && (s[2] == '\\')) { while(*s) { if(*s == '\\') *s = '/'; s++; } } } } #endif char *find_dumpfile(char *orig_save, char *orig_dump, char *this_save) { char *synth_nam = NULL; if(orig_save && orig_dump && this_save) { char *dup_orig_save; char *rhs_orig_save_slash; char *grf = NULL; int dotdot_levels = 0; find_dumpfile_scrub_slashes(orig_save); find_dumpfile_scrub_slashes(orig_dump); find_dumpfile_scrub_slashes(this_save); dup_orig_save = strdup_2(orig_save); rhs_orig_save_slash = strrchr(dup_orig_save, SLASH); if(rhs_orig_save_slash) { *rhs_orig_save_slash = 0; grf =GetRelativeFilename(dup_orig_save, orig_dump, &dotdot_levels); if(grf) { char *dup_this_save = strdup_2(this_save); char *rhs_this_save_slash = strrchr(dup_this_save, SLASH); char *p = dup_this_save; int levels = 0; if(rhs_this_save_slash) { *(rhs_this_save_slash+1) = 0; while(*p) { if(*p == SLASH) levels++; p++; } if(levels > dotdot_levels) /* > because we left the ending slash on dup_this_save */ { synth_nam = malloc_2(strlen(dup_this_save) + strlen(grf) + 1); strcpy(synth_nam, dup_this_save); strcat(synth_nam, grf); } } free_2(dup_this_save); } } free_2(dup_orig_save); } return(synth_nam); } /******************************************************************/ /* * deliberately kept outside of GLOBALS control */ struct finder_file_chain { struct finder_file_chain *next; unsigned queue_warning_presented : 1; unsigned save_file_only : 1; char *name; }; static struct finder_file_chain *finder_name_integration = NULL; /* * called in timer routine */ gboolean process_finder_names_queued(void) { return(finder_name_integration != NULL); } char *process_finder_extract_queued_name(void) { struct finder_file_chain *lc = finder_name_integration; while(lc) { if(!lc->queue_warning_presented) { lc->queue_warning_presented = 1; return(lc->name); } lc = lc->next; } return(NULL); } gboolean process_finder_name_integration(void) { static int is_working = 0; struct finder_file_chain *lc = finder_name_integration; struct finder_file_chain *lc_next; if(lc && !is_working) { is_working = 1; finder_name_integration = NULL; /* placed here to avoid race conditions with GLOBALS */ while(lc) { char *lcname = lc->name; int try_to_load_file = 1; int reload_save_file = 0; char *dfn = NULL; char *sfn = NULL; char *fdf = NULL; FILE *f; off_t dumpsiz = -1; time_t dumptim = -1; int optimize_vcd = 0; if ((suffix_check(lcname, ".sav")) || (suffix_check(lcname, ".gtkw"))) { reload_save_file = 1; try_to_load_file = 0; if(!lc->save_file_only) { read_save_helper(lcname, &dfn, &sfn, &dumpsiz, &dumptim, &optimize_vcd); if(dfn) { char *old_dfn = dfn; dfn = wave_alloca(strlen(dfn)+1); /* as context can change on file load */ strcpy(dfn, old_dfn); free_2(old_dfn); } if(sfn) { char *old_sfn = sfn; sfn = wave_alloca(strlen(sfn)+1); /* as context can change on file load */ strcpy(sfn, old_sfn); free_2(old_sfn); } #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED || defined __CYGWIN__ || defined HAVE_REALPATH if(dfn && sfn) { char *can = realpath_2(lcname, NULL); char *old_fdf = find_dumpfile(sfn, dfn, can); free(can); fdf = wave_alloca(strlen(old_fdf)+1); strcpy(fdf, old_fdf); free_2(old_fdf); f = fopen(fdf, "rb"); if(f) { fclose(f); lcname = fdf; try_to_load_file = 1; } } #endif if(dfn && !try_to_load_file) { f = fopen(dfn, "rb"); if(f) { fclose(f); lcname = dfn; try_to_load_file = 1; } } } } if(try_to_load_file) { int plen = strlen(lcname); char *fni = wave_alloca(plen + 32); /* extra space for message */ sprintf(fni, "Loading %s...", lcname); wave_gtk_window_set_title(GTK_WINDOW(GLOBALS->mainwindow), fni, GLOBALS->dumpfile_is_modified ? WAVE_SET_TITLE_MODIFIED: WAVE_SET_TITLE_NONE, 0); strcpy(fni, lcname); if(!menu_new_viewer_tab_cleanup_2(fni, optimize_vcd)) { } else { GLOBALS->dumpfile_is_modified = 0; #ifdef HAVE_SYS_STAT_H if((dumpsiz != -1) && (dumptim != -1)) { struct stat sbuf; if(!stat(fni, &sbuf)) { GLOBALS->dumpfile_is_modified = (dumpsiz != sbuf.st_size) || (dumptim != sbuf.st_mtime); } } #endif } wave_gtk_window_set_title(GTK_WINDOW(GLOBALS->mainwindow), GLOBALS->winname, GLOBALS->dumpfile_is_modified ? WAVE_SET_TITLE_MODIFIED: WAVE_SET_TITLE_NONE, 0); } /* now do save file... */ if(reload_save_file) { /* let any possible dealloc get taken up by free_outstanding() */ GLOBALS->filesel_writesave = strdup_2(lc->name); read_save_helper(GLOBALS->filesel_writesave, NULL, NULL, NULL, NULL, NULL); wave_gconf_client_set_string("/current/savefile", GLOBALS->filesel_writesave); } lc_next = lc->next; g_free(lc->name); g_free(lc); lc = lc_next; } is_working = 0; return(TRUE); } return(FALSE); } /******************************************************************/ /* * Integration with Finder... * cache name and load in later off a timer (similar to caching DnD for quartz...) */ gboolean deal_with_rpc_open_2(const gchar *path, gpointer user_data, gboolean is_save_file_only) { (void)user_data; const char *suffixes[] = { ".vcd", ".evcd", ".dump", ".lxt", ".lxt2", ".lx2", ".vzt", ".fst", ".ghw", #ifdef EXTLOAD_SUFFIX EXTLOAD_SUFFIX, #endif #ifdef AET2_IS_PRESENT ".aet", ".ae2", #endif ".gtkw", ".sav" }; const int num_suffixes = sizeof(suffixes) / sizeof(const char *); int i, mat = 0; for(i=0;iname = g_strdup(path); p->queue_warning_presented = 0; p->save_file_only = 1; p->next = finder_name_integration; finder_name_integration = p; } else { if(!finder_name_integration) { finder_name_integration = g_malloc(sizeof(struct finder_file_chain)); finder_name_integration->name = g_strdup(path); finder_name_integration->queue_warning_presented = 0; finder_name_integration->save_file_only = 0; finder_name_integration->next = NULL; } else { struct finder_file_chain *p = finder_name_integration; while(p->next) p = p->next; p->next = g_malloc(sizeof(struct finder_file_chain)); p->next->queue_warning_presented = 0; p->next->save_file_only = 0; p->next->name = g_strdup(path); p->next->next = NULL; } } return(TRUE); } gboolean deal_with_rpc_open(const gchar *path, gpointer user_data) { return(deal_with_rpc_open_2(path, user_data, FALSE)); } #ifdef MAC_INTEGRATION /* * block termination if in the middle of something important */ gboolean deal_with_termination(GtkosxApplication *app, gpointer user_data) { (void)app; (void)user_data; gboolean do_not_terminate = FALSE; /* future expansion */ if(do_not_terminate) { status_text("GTKWAVE | Busy, quit signal blocked.\n"); } return(do_not_terminate); } /* * Integration with Finder... * cache name and load in later off a timer (similar to caching DnD for quartz...) */ gboolean deal_with_finder_open(GtkosxApplication *app, gchar *path, gpointer user_data) { (void)app; return(deal_with_rpc_open(path, user_data)); } #endif int suffix_check(const char *s, const char *sfx) { unsigned int sfxlen = strlen(sfx); return((strlen(s)>=sfxlen)&&(!strcasecmp(s+strlen(s)-sfxlen,sfx))); } gtkwave-3.3.66/src/file.c0000664000076400007640000004055112431472626014465 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2013. * * 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. */ #include "globals.h" #include #include #include "gtk12compat.h" #include "menu.h" #include "debug.h" #include "wavealloca.h" #include #include /* #include */ #ifdef MAC_INTEGRATION #include #endif #if defined __MINGW32__ #include #endif #if GTK_CHECK_VERSION(2,4,0) #ifndef MAC_INTEGRATION static gboolean ffunc (const GtkFileFilterInfo *filter_info, gpointer data) { (void)data; const char *rms = strrchr(filter_info->filename, '\\'); const char *rms2; if(!rms) rms = filter_info->filename; else rms++; rms2 = strrchr(rms, '/'); if(!rms2) rms2 = rms; else rms2++; if(!GLOBALS->pFileChooseFilterName || !GLOBALS->pPatternSpec) { return(TRUE); } if(!strchr(GLOBALS->pFileChooseFilterName, '*') && !strchr(GLOBALS->pFileChooseFilterName, '?')) { char *fpos = strstr(rms2, GLOBALS->pFileChooseFilterName); return(fpos != NULL); } else { return(g_pattern_match_string(GLOBALS->pPatternSpec, rms2)); } } static void filter_edit_cb (GtkWidget *widget, GdkEventKey *ev, gpointer *data) { (void)ev; const char *t; gchar *folder_filename; if(GLOBALS->pFileChooseFilterName) { free_2((char *)GLOBALS->pFileChooseFilterName); GLOBALS->pFileChooseFilterName = NULL; } t = gtk_entry_get_text (GTK_ENTRY (widget)); if (t == NULL || *t == 0) { GLOBALS->pFileChooseFilterName = NULL; } else { GLOBALS->pFileChooseFilterName = malloc_2(strlen(t) + 1); strcpy(GLOBALS->pFileChooseFilterName, t); if(GLOBALS->pPatternSpec) g_pattern_spec_free(GLOBALS->pPatternSpec); GLOBALS->pPatternSpec = g_pattern_spec_new(t); } /* now force refresh with new filter */ folder_filename = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER(data)); if(folder_filename) { gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(data), folder_filename); g_free(folder_filename); } } static void press_callback (GtkWidget *widget, gpointer *data) { GdkEventKey ev; filter_edit_cb (widget, &ev, data); } #endif #endif static void enter_callback(GtkWidget *widget, GtkFileSelection *fw) { (void)widget; (void)fw; G_CONST_RETURN char *allocbuf; int alloclen; allocbuf=gtk_file_selection_get_filename(GTK_FILE_SELECTION(GLOBALS->fs_file_c_1)); if((alloclen=strlen(allocbuf))) { GLOBALS->filesel_ok=1; if(*GLOBALS->fileselbox_text) free_2(*GLOBALS->fileselbox_text); *GLOBALS->fileselbox_text=(char *)malloc_2(alloclen+1); strcpy(*GLOBALS->fileselbox_text, allocbuf); } DEBUG(printf("Filesel OK %s\n",allocbuf)); wave_gtk_grab_remove(GLOBALS->fs_file_c_1); gtk_widget_destroy(GLOBALS->fs_file_c_1); gtkwave_main_iteration(); GLOBALS->cleanup_file_c_2(); } static void cancel_callback(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; DEBUG(printf("Filesel Entry Cancel\n")); wave_gtk_grab_remove(GLOBALS->fs_file_c_1); gtk_widget_destroy(GLOBALS->fs_file_c_1); gtkwave_main_iteration(); if(GLOBALS->bad_cleanup_file_c_1) GLOBALS->bad_cleanup_file_c_1(); } static void destroy_callback(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; DEBUG(printf("Filesel Destroy\n")); gtkwave_main_iteration(); if(GLOBALS->bad_cleanup_file_c_1) GLOBALS->bad_cleanup_file_c_1(); } void fileselbox_old(char *title, char **filesel_path, GtkSignalFunc ok_func, GtkSignalFunc notok_func, char *pattn, int is_writemode) { #if defined __MINGW32__ OPENFILENAME ofn; char szFile[260]; /* buffer for file name */ char szPath[260]; /* buffer for path name */ char lpstrFilter[260]; /* more than enough room for some patterns */ BOOL rc; #else (void)pattn; (void)is_writemode; #endif GLOBALS->fileselbox_text=filesel_path; GLOBALS->filesel_ok=0; GLOBALS->cleanup_file_c_2=ok_func; GLOBALS->bad_cleanup_file_c_1=notok_func; #if defined __MINGW32__ ZeroMemory(&ofn, sizeof(ofn)); ofn.lStructSize = sizeof(ofn); ofn.lpstrFile = szFile; ofn.lpstrFile[0] = '\0'; ofn.lpstrFilter = lpstrFilter; ofn.nMaxFile = sizeof(szFile); ofn.lpstrFileTitle = NULL; ofn.nMaxFileTitle = 0; ofn.lpstrInitialDir = NULL; ofn.Flags = is_writemode ? (OFN_CREATEPROMPT | OFN_OVERWRITEPROMPT) : (OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST); if((!pattn)||(!strcmp(pattn, "*"))) { sprintf(lpstrFilter, "%s%c%s%c", "All", 0, "*.*", 0); ofn.nFilterIndex = 0; } else { sprintf(lpstrFilter, "%s%c%s%c%s%c%s%c", pattn, 0, pattn, 0, "All", 0, "*.*", 0); /* cppcheck */ ofn.nFilterIndex = 0; } if(*filesel_path) { char *fsp = *filesel_path; int ch_idx = 0; char ch = 0; while(*fsp) { ch = *fsp; szFile[ch_idx++] = (ch != '/') ? ch : '\\'; fsp++; } szFile[ch_idx] = 0; if((ch == '/') || (ch == '\\')) { strcpy(szPath, szFile); szFile[0] = 0; ofn.lpstrInitialDir = szPath; } } rc = is_writemode ? GetSaveFileName(&ofn) : GetOpenFileName(&ofn); if (rc==TRUE) { GLOBALS->filesel_ok=1; if(*GLOBALS->fileselbox_text) free_2(*GLOBALS->fileselbox_text); if(!is_writemode) { *GLOBALS->fileselbox_text=(char *)strdup_2(szFile); } else { char *suf_str = NULL; int suf_add = 0; int szlen = 0; int suflen = 0; if(pattn) { suf_str = strstr(pattn, "*."); if(suf_str) suf_str++; } if(suf_str) { szlen = strlen(szFile); suflen = strlen(suf_str); if(suflen > szlen) { suf_add = 1; } else { if(strcasecmp(szFile + (szlen - suflen), suf_str)) { suf_add = 1; } } } if(suf_str && suf_add) { *GLOBALS->fileselbox_text=(char *)malloc_2(szlen + suflen + 1); strcpy(*GLOBALS->fileselbox_text, szFile); strcpy(*GLOBALS->fileselbox_text + szlen, suf_str); } else { *GLOBALS->fileselbox_text=(char *)strdup_2(szFile); } } GLOBALS->cleanup_file_c_2(); } else { if(GLOBALS->bad_cleanup_file_c_1) GLOBALS->bad_cleanup_file_c_1(); } #else GLOBALS->fs_file_c_1=gtk_file_selection_new(title); gtkwave_signal_connect(GTK_OBJECT(GLOBALS->fs_file_c_1), "destroy", (GtkSignalFunc) destroy_callback, NULL); gtkwave_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(GLOBALS->fs_file_c_1)->ok_button), "clicked", (GtkSignalFunc) enter_callback, GTK_OBJECT(GLOBALS->fs_file_c_1)); gtkwave_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(GLOBALS->fs_file_c_1)->cancel_button),"clicked", (GtkSignalFunc) cancel_callback, GTK_OBJECT(GLOBALS->fs_file_c_1)); gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(GLOBALS->fs_file_c_1)); if(*GLOBALS->fileselbox_text) gtk_file_selection_set_filename(GTK_FILE_SELECTION(GLOBALS->fs_file_c_1), *GLOBALS->fileselbox_text); /* * XXX: filter on patterns when this feature eventually works (or for a later version of GTK)! * if((pattn)&&(pattn[0])) gtk_file_selection_complete(GTK_FILE_SELECTION(fs), pattn); */ gtk_widget_show(GLOBALS->fs_file_c_1); wave_gtk_grab_add(GLOBALS->fs_file_c_1); #endif } void fileselbox(char *title, char **filesel_path, GtkSignalFunc ok_func, GtkSignalFunc notok_func, char *pattn, int is_writemode) { #ifndef MAC_INTEGRATION #if GTK_CHECK_VERSION(2,4,0) int can_set_filename = 0; GtkWidget *pFileChoose; GtkWidget *pWindowMain; GtkFileFilter *filter; GtkWidget *label; GtkWidget *label_ent; GtkWidget *box; GtkTooltips *tooltips; struct Global *old_globals = GLOBALS; #endif #endif /* fix problem where ungrab doesn't occur if button pressed + simultaneous accelerator key occurs */ if(GLOBALS->in_button_press_wavewindow_c_1) { gdk_pointer_ungrab(GDK_CURRENT_TIME); } if(!*filesel_path) /* if no name specified, hijack loaded file name path */ { if(GLOBALS->loaded_file_name) { char *can = realpath_2(GLOBALS->loaded_file_name, NULL); /* prevents filechooser from blocking/asking where to save file */ char *tname = strdup_2(can ? can : GLOBALS->loaded_file_name); char *delim = strrchr(tname, '/'); if(!delim) delim = strrchr(tname, '\\'); if(delim) { *(delim+1) = 0; /* keep slash for gtk_file_chooser_set_filename vs gtk_file_chooser_set_current_folder test below */ *filesel_path = tname; } else { free_2(tname); } free(can); } } if(GLOBALS->wave_script_args) { char *s = NULL; GLOBALS->fileselbox_text=filesel_path; GLOBALS->filesel_ok=1; while((!s)&&(GLOBALS->wave_script_args->curr)) s = wave_script_args_fgetmalloc_stripspaces(GLOBALS->wave_script_args); if(*GLOBALS->fileselbox_text) free_2(*GLOBALS->fileselbox_text); if(!s) { fprintf(stderr, "Null filename passed to fileselbox in script, exiting.\n"); exit(255); } *GLOBALS->fileselbox_text = s; fprintf(stderr, "GTKWAVE | Filename '%s'\n", s); ok_func(); return; } #ifdef MAC_INTEGRATION GLOBALS->fileselbox_text=filesel_path; GLOBALS->filesel_ok=0; char *rc = gtk_file_req_bridge(title, *filesel_path, pattn, is_writemode); if(rc) { GLOBALS->filesel_ok=1; if(*GLOBALS->fileselbox_text) free_2(*GLOBALS->fileselbox_text); *GLOBALS->fileselbox_text=strdup_2(rc); g_free(rc); if(ok_func) ok_func(); } else { if(notok_func) notok_func(); } return; #else #if defined __MINGW32__ || !GTK_CHECK_VERSION(2,4,0) fileselbox_old(title, filesel_path, ok_func, notok_func, pattn, is_writemode); return; #else pWindowMain = GLOBALS->mainwindow; GLOBALS->fileselbox_text=filesel_path; GLOBALS->filesel_ok=0; if(*GLOBALS->fileselbox_text && (!g_path_is_absolute(*GLOBALS->fileselbox_text))) { #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED || defined __CYGWIN__ || defined HAVE_REALPATH char *can = realpath_2(*GLOBALS->fileselbox_text, NULL); if(can) { if(*GLOBALS->fileselbox_text) free_2(*GLOBALS->fileselbox_text); *GLOBALS->fileselbox_text=(char *)malloc_2(strlen(can)+1); strcpy(*GLOBALS->fileselbox_text, can); free(can); can_set_filename = 1; } #else #if __GNUC__ #warning Absolute file path warnings might be issued by the file chooser dialogue on this system! #endif #endif } else { if(*GLOBALS->fileselbox_text) { can_set_filename = 1; } } if(is_writemode) { pFileChoose = gtk_file_chooser_dialog_new( title, NULL, GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); #if GTK_CHECK_VERSION(2,8,0) gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER (pFileChoose), TRUE); #endif } else { pFileChoose = gtk_file_chooser_dialog_new( title, NULL, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); } GLOBALS->pFileChoose = pFileChoose; if((can_set_filename) && (*filesel_path)) { int flen = strlen(*filesel_path); if(((*filesel_path)[flen-1]=='/') || ((*filesel_path)[flen-1]=='\\')) { gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(pFileChoose), *filesel_path); } else { gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(pFileChoose), *filesel_path); } } label=gtk_label_new("Custom Filter:"); label_ent=gtk_entry_new_with_max_length(40); tooltips=gtk_tooltips_new_2(); gtk_tooltips_set_delay_2(tooltips,1500); gtk_entry_set_text(GTK_ENTRY(label_ent), GLOBALS->pFileChooseFilterName ? GLOBALS->pFileChooseFilterName : "*"); gtk_signal_connect (GTK_OBJECT (label_ent), "changed",GTK_SIGNAL_FUNC (press_callback), pFileChoose); box=gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0); gtk_widget_show(label); gtk_box_pack_start(GTK_BOX(box), label_ent, FALSE, FALSE, 0); gtk_widget_set_usize(GTK_WIDGET(label_ent), 300, 22); gtk_tooltips_set_tip_2(tooltips, label_ent, "Enter custom pattern match filter here. Note that \"string\" without * or ? achieves a match on \"*string*\".", NULL); gtk_widget_show(label_ent); gtk_widget_show(box); gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(pFileChoose), box); if(pattn) { int is_gtkw = suffix_check(pattn, ".gtkw"); int is_sav = suffix_check(pattn, ".sav"); filter = gtk_file_filter_new(); gtk_file_filter_add_pattern(filter, pattn); gtk_file_filter_set_name(filter, pattn); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(pFileChoose), filter); if(is_gtkw || is_sav) { const char *pattn2 = is_sav ? "*.gtkw" : "*.sav"; filter = gtk_file_filter_new(); gtk_file_filter_add_pattern(filter, pattn2); gtk_file_filter_set_name(filter, pattn2); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(pFileChoose), filter); } } if((!pattn) || (strcmp(pattn, "*"))) { filter = gtk_file_filter_new(); gtk_file_filter_add_pattern(filter, "*"); gtk_file_filter_set_name(filter, "*"); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(pFileChoose), filter); } filter = gtk_file_filter_new(); gtk_file_filter_add_custom(filter, GTK_FILE_FILTER_FILENAME, ffunc, NULL, NULL); gtk_file_filter_set_name(filter, "Custom"); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(pFileChoose), filter); if(GLOBALS->pFileChooseFilterName) { GLOBALS->pPatternSpec = g_pattern_spec_new(GLOBALS->pFileChooseFilterName); } gtk_dialog_set_default_response(GTK_DIALOG(pFileChoose), GTK_RESPONSE_ACCEPT); gtk_object_set_data(GTK_OBJECT(pFileChoose), "FileChooseWindow", pFileChoose); gtk_container_set_border_width(GTK_CONTAINER(pFileChoose), 10); gtk_window_set_position(GTK_WINDOW(pFileChoose), GTK_WIN_POS_CENTER); gtk_window_set_modal(GTK_WINDOW(pFileChoose), TRUE); gtk_window_set_policy(GTK_WINDOW(pFileChoose), FALSE, FALSE, FALSE); gtk_window_set_resizable(GTK_WINDOW(pFileChoose), TRUE); /* some distros need this */ if(pWindowMain) { gtk_window_set_transient_for(GTK_WINDOW(pFileChoose), GTK_WINDOW(pWindowMain)); } gtk_widget_show(pFileChoose); wave_gtk_grab_add(pFileChoose); /* check against old_globals is because of DnD context swapping so make response fail */ if((gtk_dialog_run(GTK_DIALOG (pFileChoose)) == GTK_RESPONSE_ACCEPT) && (GLOBALS == old_globals) && (GLOBALS->fileselbox_text)) { G_CONST_RETURN char *allocbuf; int alloclen; allocbuf = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (pFileChoose)); if((alloclen=strlen(allocbuf))) { int gtkw_test = 0; GLOBALS->filesel_ok=1; if(*GLOBALS->fileselbox_text) free_2(*GLOBALS->fileselbox_text); *GLOBALS->fileselbox_text=(char *)malloc_2(alloclen+1); strcpy(*GLOBALS->fileselbox_text, allocbuf); /* add missing suffix to write files */ if(pattn && is_writemode) { char *s = *GLOBALS->fileselbox_text; char *s2; char *suffix = wave_alloca(strlen(pattn) + 1); char *term; int attempt_suffix = 1; strcpy(suffix, pattn); while((*suffix) && (*suffix != '.')) suffix++; term = *suffix ? suffix+1 : suffix; while((*term) && (isalnum((int)(unsigned char)*term))) term++; *term = 0; gtkw_test = suffix_check(pattn, ".gtkw") || suffix_check(pattn, ".sav"); if(gtkw_test) { attempt_suffix = (!suffix_check(s, ".gtkw")) && (!suffix_check(s, ".sav")); } if(attempt_suffix) { if(strlen(s) > strlen(suffix)) { if(strcmp(s + strlen(s) - strlen(suffix), suffix)) { goto fix_suffix; } } else { fix_suffix: s2 = malloc_2(strlen(s) + strlen(suffix) + 1); strcpy(s2, s); strcat(s2, suffix); free_2(s); *GLOBALS->fileselbox_text = s2; } } } if((gtkw_test) && (*GLOBALS->fileselbox_text)) { GLOBALS->is_gtkw_save_file = suffix_check(*GLOBALS->fileselbox_text, ".gtkw"); } } DEBUG(printf("Filesel OK %s\n",allocbuf)); wave_gtk_grab_remove(pFileChoose); gtk_widget_destroy(pFileChoose); GLOBALS->pFileChoose = NULL; /* keeps DND from firing */ gtkwave_main_iteration(); ok_func(); } else { DEBUG(printf("Filesel Entry Cancel\n")); wave_gtk_grab_remove(pFileChoose); gtk_widget_destroy(pFileChoose); GLOBALS->pFileChoose = NULL; /* keeps DND from firing */ gtkwave_main_iteration(); if(GLOBALS->bad_cleanup_file_c_1) notok_func(); } if(GLOBALS->pPatternSpec) { g_pattern_spec_free(GLOBALS->pPatternSpec); GLOBALS->pPatternSpec = NULL; } #endif #endif } gtkwave-3.3.66/src/translate.h0000664000076400007640000000204312341266475015545 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2005. * * 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. */ #include "globals.h" #ifndef WAVE_TRANSLATE_H #define WAVE_TRANSLATE_H #include #include #include #include "fgetdynamic.h" #include "debug.h" /* * char splay */ typedef struct xl_tree_node xl_Tree; struct xl_tree_node { xl_Tree *left, *right; char *item; char *trans; }; #define FILE_FILTER_MAX (128) #define WAVE_TCL_INSTALLED_FILTER "\"TCL_Installed_Filter\"" xl_Tree * xl_splay (char *i, xl_Tree * t); xl_Tree * xl_insert(char *i, xl_Tree * t, char *trans); xl_Tree * xl_delete(char *i, xl_Tree * t); void trans_searchbox(char *title); void init_filetrans_data(void); int install_file_filter(int which); void set_current_translate_enums(char *lst); void set_current_translate_file(char *name); #endif gtkwave-3.3.66/src/getopt.c0000664000076400007640000010346611572536221015052 0ustar bybellbybell/* Getopt for GNU. NOTE: getopt is now part of the C library, so if you don't know what "Keep this file name-space clean" means, talk to drepper@gnu.org before changing it! Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001,2002 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library 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 2.1 of the License, or (at your option) any later version. The GNU C Library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA */ /* This tells Alpha OSF/1 not to define a getopt prototype in . Ditto for AIX 3.2 and . */ #ifndef _NO_PROTO # define _NO_PROTO #endif #if 0 #define HAVE_CONFIG_H /* needed for Wine */ #endif #ifdef HAVE_CONFIG_H # include #endif #ifdef HAVE_GETOPT_LONG #define ELIDE_CODE #endif #if !defined __STDC__ || !__STDC__ /* This is a separate conditional since some stdc systems reject `defined (const)'. */ # ifndef const # define const # endif #endif #include /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #define GETOPT_INTERFACE_VERSION 2 #if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 # include # if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION # define ELIDE_CODE # endif #endif #ifndef ELIDE_CODE /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ /* Don't include stdlib.h for non-GNU C libraries because some of them contain conflicting prototypes for getopt. */ # include # include #endif /* GNU C library. */ #ifdef VMS # include # if HAVE_STRING_H - 0 # include # endif #endif #ifndef _ /* This is for other GNU distributions with internationalized messages. */ # if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC # include # ifndef _ # define _(msgid) gettext (msgid) # endif # else # define _(msgid) (msgid) # endif # if defined _LIBC && defined USE_IN_LIBIO # include # endif #endif #ifndef attribute_hidden # define attribute_hidden #endif /* This version of `getopt' appears to the caller like standard Unix `getopt' but it behaves differently for the user, since it allows the user to intersperse the options with the other arguments. As `getopt' works, it permutes the elements of ARGV so that, when it is done, all the options precede everything else. Thus all application programs are extended to handle flexible argument order. Setting the environment variable POSIXLY_CORRECT disables permutation. Then the behavior is completely standard. GNU application programs can use a third alternative mode in which they can distinguish the relative order of options and other arguments. */ #include "gnu-getopt.h" /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ char *optarg; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns -1, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ /* 1003.2 says this must be 1 before any call. */ int optind = 1; /* Formerly, initialization of getopt depended on optind==0, which causes problems with re-calling getopt as programs generally don't know that. */ int __getopt_initialized attribute_hidden; /* The next char to be scanned in the option-element in which the last option character we returned was found. This allows us to pick up the scan where we left off. If this is zero, or a null string, it means resume the scan by advancing to the next ARGV-element. */ static char *nextchar; /* Callers store zero here to inhibit the error message for unrecognized options. */ int opterr = 1; /* Set to an option character which was unrecognized. This must be initialized on some systems to avoid linking in the system's own getopt implementation. */ int optopt = '?'; /* Describe how to deal with options that follow non-option ARGV-elements. If the caller did not specify anything, the default is REQUIRE_ORDER if the environment variable POSIXLY_CORRECT is defined, PERMUTE otherwise. REQUIRE_ORDER means don't recognize them as options; stop option processing when the first non-option is seen. This is what Unix does. This mode of operation is selected by either setting the environment variable POSIXLY_CORRECT, or using `+' as the first character of the list of option characters. PERMUTE is the default. We permute the contents of ARGV as we scan, so that eventually all the non-options are at the end. This allows options to be given in any order, even with programs that were not written to expect this. RETURN_IN_ORDER is an option available to programs that were written to expect options and other ARGV-elements in any order and that care about the ordering of the two. We describe each non-option ARGV-element as if it were the argument of an option with character code 1. Using `-' as the first character of the list of option characters selects this mode of operation. The special argument `--' forces an end of option-scanning regardless of the value of `ordering'. In the case of RETURN_IN_ORDER, only `--' can cause `getopt' to return -1 with `optind' != ARGC. */ static enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering; /* Value of POSIXLY_CORRECT environment variable. */ static char *posixly_correct; #ifdef __GNU_LIBRARY__ /* We want to avoid inclusion of string.h with non-GNU libraries because there are many ways it can cause trouble. On some systems, it contains special magic macros that don't work in GCC. */ # include # define my_index strchr #else # if HAVE_STRING_H # include # else # include # endif /* Avoid depending on library functions or files whose names are inconsistent. */ #ifndef getenv extern char *getenv (); #endif static char * my_index (str, chr) const char *str; int chr; { while (*str) { if (*str == chr) return (char *) str; str++; } return 0; } /* If using GCC, we can safely declare strlen this way. If not using GCC, it is ok not to declare it. */ #ifdef __GNUC__ /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. That was relevant to code that was here before. */ # if (!defined __STDC__ || !__STDC__) && !defined strlen /* gcc with -traditional declares the built-in strlen to return int, and has done so at least since version 2.4.5. -- rms. */ extern int strlen (const char *); # endif /* not __STDC__ */ #endif /* __GNUC__ */ #endif /* not __GNU_LIBRARY__ */ /* Handle permutation of arguments. */ /* Describe the part of ARGV that contains non-options that have been skipped. `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is the index after the last of them. */ static int first_nonopt; static int last_nonopt; #ifdef _LIBC /* Stored original parameters. XXX This is no good solution. We should rather copy the args so that we can compare them later. But we must not use malloc(3). */ extern int __libc_argc; extern char **__libc_argv; /* Bash 2.0 gives us an environment variable containing flags indicating ARGV elements that should not be considered arguments. */ # ifdef USE_NONOPTION_FLAGS /* Defined in getopt_init.c */ extern char *__getopt_nonoption_flags; static int nonoption_flags_max_len; static int nonoption_flags_len; # endif # ifdef USE_NONOPTION_FLAGS # define SWAP_FLAGS(ch1, ch2) \ if (nonoption_flags_len > 0) \ { \ char __tmp = __getopt_nonoption_flags[ch1]; \ __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ __getopt_nonoption_flags[ch2] = __tmp; \ } # else # define SWAP_FLAGS(ch1, ch2) # endif #else /* !_LIBC */ # define SWAP_FLAGS(ch1, ch2) #endif /* _LIBC */ /* Exchange two adjacent subsequences of ARGV. One subsequence is elements [first_nonopt,last_nonopt) which contains all the non-options that have been skipped so far. The other is elements [last_nonopt,optind), which contains all the options processed since those non-options were skipped. `first_nonopt' and `last_nonopt' are relocated so that they describe the new indices of the non-options in ARGV after they are moved. */ #if defined __STDC__ && __STDC__ static void exchange (char **); #endif static void exchange (argv) char **argv; { int bottom = first_nonopt; int middle = last_nonopt; int top = optind; char *tem; /* Exchange the shorter segment with the far end of the longer segment. That puts the shorter segment into the right place. It leaves the longer segment in the right place overall, but it consists of two parts that need to be swapped next. */ #if defined _LIBC && defined USE_NONOPTION_FLAGS /* First make sure the handling of the `__getopt_nonoption_flags' string can work normally. Our top argument must be in the range of the string. */ if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) { /* We must extend the array. The user plays games with us and presents new arguments. */ char *new_str = malloc (top + 1); if (new_str == NULL) nonoption_flags_len = nonoption_flags_max_len = 0; else { memset (__mempcpy (new_str, __getopt_nonoption_flags, nonoption_flags_max_len), '\0', top + 1 - nonoption_flags_max_len); nonoption_flags_max_len = top + 1; __getopt_nonoption_flags = new_str; } } #endif while (top > middle && middle > bottom) { if (top - middle > middle - bottom) { /* Bottom segment is the short one. */ int len = middle - bottom; register int i; /* Swap it with the top part of the top segment. */ for (i = 0; i < len; i++) { tem = argv[bottom + i]; argv[bottom + i] = argv[top - (middle - bottom) + i]; argv[top - (middle - bottom) + i] = tem; SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); } /* Exclude the moved bottom segment from further swapping. */ top -= len; } else { /* Top segment is the short one. */ int len = top - middle; register int i; /* Swap it with the bottom part of the bottom segment. */ for (i = 0; i < len; i++) { tem = argv[bottom + i]; argv[bottom + i] = argv[middle + i]; argv[middle + i] = tem; SWAP_FLAGS (bottom + i, middle + i); } /* Exclude the moved top segment from further swapping. */ bottom += len; } } /* Update records for the slots the non-options now occupy. */ first_nonopt += (optind - last_nonopt); last_nonopt = optind; } /* Initialize the internal data when the first call is made. */ #if defined __STDC__ && __STDC__ static const char *_getopt_initialize (int, char *const *, const char *); #endif static const char * _getopt_initialize (argc, argv, optstring) int argc; char *const *argv; const char *optstring; { /* Start processing options with ARGV-element 1 (since ARGV-element 0 is the program name); the sequence of previously skipped non-option ARGV-elements is empty. */ first_nonopt = last_nonopt = optind; nextchar = NULL; posixly_correct = getenv ("POSIXLY_CORRECT"); /* Determine how to handle the ordering of options and nonoptions. */ if (optstring[0] == '-') { ordering = RETURN_IN_ORDER; ++optstring; } else if (optstring[0] == '+') { ordering = REQUIRE_ORDER; ++optstring; } else if (posixly_correct != NULL) ordering = REQUIRE_ORDER; else ordering = PERMUTE; #if defined _LIBC && defined USE_NONOPTION_FLAGS if (posixly_correct == NULL && argc == __libc_argc && argv == __libc_argv) { if (nonoption_flags_max_len == 0) { if (__getopt_nonoption_flags == NULL || __getopt_nonoption_flags[0] == '\0') nonoption_flags_max_len = -1; else { const char *orig_str = __getopt_nonoption_flags; int len = nonoption_flags_max_len = strlen (orig_str); if (nonoption_flags_max_len < argc) nonoption_flags_max_len = argc; __getopt_nonoption_flags = (char *) malloc (nonoption_flags_max_len); if (__getopt_nonoption_flags == NULL) nonoption_flags_max_len = -1; else memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), '\0', nonoption_flags_max_len - len); } } nonoption_flags_len = nonoption_flags_max_len; } else nonoption_flags_len = 0; #endif return optstring; } /* Scan elements of ARGV (whose length is ARGC) for option characters given in OPTSTRING. If an element of ARGV starts with '-', and is not exactly "-" or "--", then it is an option element. The characters of this element (aside from the initial '-') are option characters. If `getopt' is called repeatedly, it returns successively each of the option characters from each of the option elements. If `getopt' finds another option character, it returns that character, updating `optind' and `nextchar' so that the next call to `getopt' can resume the scan with the following option character or ARGV-element. If there are no more option characters, `getopt' returns -1. Then `optind' is the index in ARGV of the first ARGV-element that is not an option. (The ARGV-elements have been permuted so that those that are not options now come last.) OPTSTRING is a string containing the legitimate option characters. If an option character is seen that is not listed in OPTSTRING, return '?' after printing an error message. If you set `opterr' to zero, the error message is suppressed but we still return '?'. If a char in OPTSTRING is followed by a colon, that means it wants an arg, so the following text in the same ARGV-element, or the text of the following ARGV-element, is returned in `optarg'. Two colons mean an option that wants an optional arg; if there is text in the current ARGV-element, it is returned in `optarg', otherwise `optarg' is set to zero. If OPTSTRING starts with `-' or `+', it requests different methods of handling the non-option ARGV-elements. See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. Long-named options begin with `--' instead of `-'. Their names may be abbreviated as long as the abbreviation is unique or is an exact match for some defined option. If they have an argument, it follows the option name in the same ARGV-element, separated from the option name by a `=', or else the in next ARGV-element. When `getopt' finds a long-named option, it returns 0 if that option's `flag' field is nonzero, the value of the option's `val' field if the `flag' field is zero. The elements of ARGV aren't really const, because we permute them. But we pretend they're const in the prototype to be compatible with other systems. LONGOPTS is a vector of `struct option' terminated by an element containing a name which is zero. LONGIND returns the index in LONGOPT of the long-named option found. It is only valid when a long-named option has been found by the most recent call. If LONG_ONLY is nonzero, '-' as well as '--' can introduce long-named options. */ int _getopt_internal (argc, argv, optstring, longopts, longind, long_only) int argc; char *const *argv; const char *optstring; const struct option *longopts; int *longind; int long_only; { int print_errors = opterr; if (optstring[0] == ':') print_errors = 0; if (argc < 1) return -1; optarg = NULL; if (optind == 0 || !__getopt_initialized) { if (optind == 0) optind = 1; /* Don't scan ARGV[0], the program name. */ optstring = _getopt_initialize (argc, argv, optstring); __getopt_initialized = 1; } /* Test whether ARGV[optind] points to a non-option argument. Either it does not have option syntax, or there is an environment flag from the shell indicating it is not an option. The later information is only used when the used in the GNU libc. */ #if defined _LIBC && defined USE_NONOPTION_FLAGS # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ || (optind < nonoption_flags_len \ && __getopt_nonoption_flags[optind] == '1')) #else # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') #endif if (nextchar == NULL || *nextchar == '\0') { /* Advance to the next ARGV-element. */ /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been moved back by the user (who may also have changed the arguments). */ if (last_nonopt > optind) last_nonopt = optind; if (first_nonopt > optind) first_nonopt = optind; if (ordering == PERMUTE) { /* If we have just processed some options following some non-options, exchange them so that the options come first. */ if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (last_nonopt != optind) first_nonopt = optind; /* Skip any additional non-options and extend the range of non-options previously skipped. */ while (optind < argc && NONOPTION_P) optind++; last_nonopt = optind; } /* The special ARGV-element `--' means premature end of options. Skip it like a null option, then exchange with previous non-options as if it were an option, then skip everything else like a non-option. */ if (optind != argc && !strcmp (argv[optind], "--")) { optind++; if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (first_nonopt == last_nonopt) first_nonopt = optind; last_nonopt = argc; optind = argc; } /* If we have done all the ARGV-elements, stop the scan and back over any non-options that we skipped and permuted. */ if (optind == argc) { /* Set the next-arg-index to point at the non-options that we previously skipped, so the caller will digest them. */ if (first_nonopt != last_nonopt) optind = first_nonopt; return -1; } /* If we have come to a non-option and did not permute it, either stop the scan or describe it to the caller and pass it by. */ if (NONOPTION_P) { if (ordering == REQUIRE_ORDER) return -1; optarg = argv[optind++]; return 1; } /* We have found another option-ARGV-element. Skip the initial punctuation. */ nextchar = (argv[optind] + 1 + (longopts != NULL && argv[optind][1] == '-')); } /* Decode the current option-ARGV-element. */ /* Check whether the ARGV-element is a long option. If long_only and the ARGV-element has the form "-f", where f is a valid short option, don't consider it an abbreviated form of a long option that starts with f. Otherwise there would be no way to give the -f short option. On the other hand, if there's a long option "fubar" and the ARGV-element is "-fu", do consider that an abbreviation of the long option, just like "--fu", and not "-f" with arg "u". This distinction seems to be the most useful approach. */ if (longopts != NULL && (argv[optind][1] == '-' || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) { char *nameend; const struct option *p; const struct option *pfound = NULL; int exact = 0; int ambig = 0; int indfound = -1; int option_index; for (nameend = nextchar; *nameend && *nameend != '='; nameend++) /* Do nothing. */ ; /* Test all long options for either exact match or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) if (!strncmp (p->name, nextchar, nameend - nextchar)) { if ((unsigned int) (nameend - nextchar) == (unsigned int) strlen (p->name)) { /* Exact match found. */ pfound = p; indfound = option_index; exact = 1; break; } else if (pfound == NULL) { /* First nonexact match found. */ pfound = p; indfound = option_index; } else if (long_only || pfound->has_arg != p->has_arg || pfound->flag != p->flag || pfound->val != p->val) /* Second or later nonexact match found. */ ambig = 1; } if (ambig && !exact) { if (print_errors) { #if defined _LIBC && defined USE_IN_LIBIO char *buf; if (__asprintf (&buf, _("%s: option `%s' is ambiguous\n"), argv[0], argv[optind]) >= 0) { if (_IO_fwide (stderr, 0) > 0) __fwprintf (stderr, L"%s", buf); else fputs (buf, stderr); free (buf); } #else fprintf (stderr, _("%s: option `%s' is ambiguous\n"), argv[0], argv[optind]); #endif } nextchar += strlen (nextchar); optind++; optopt = 0; return '?'; } if (pfound != NULL) { option_index = indfound; optind++; if (*nameend) { /* Don't test has_arg with >, because some C compilers don't allow it to be used on enums. */ if (pfound->has_arg) optarg = nameend + 1; else { if (print_errors) { #if defined _LIBC && defined USE_IN_LIBIO char *buf; int n; #endif if (argv[optind - 1][1] == '-') { /* --option */ #if defined _LIBC && defined USE_IN_LIBIO n = __asprintf (&buf, _("\ %s: option `--%s' doesn't allow an argument\n"), argv[0], pfound->name); #else fprintf (stderr, _("\ %s: option `--%s' doesn't allow an argument\n"), argv[0], pfound->name); #endif } else { /* +option or -option */ #if defined _LIBC && defined USE_IN_LIBIO n = __asprintf (&buf, _("\ %s: option `%c%s' doesn't allow an argument\n"), argv[0], argv[optind - 1][0], pfound->name); #else fprintf (stderr, _("\ %s: option `%c%s' doesn't allow an argument\n"), argv[0], argv[optind - 1][0], pfound->name); #endif } #if defined _LIBC && defined USE_IN_LIBIO if (n >= 0) { if (_IO_fwide (stderr, 0) > 0) __fwprintf (stderr, L"%s", buf); else fputs (buf, stderr); free (buf); } #endif } nextchar += strlen (nextchar); optopt = pfound->val; return '?'; } } else if (pfound->has_arg == 1) { if (optind < argc) optarg = argv[optind++]; else { if (print_errors) { #if defined _LIBC && defined USE_IN_LIBIO char *buf; if (__asprintf (&buf, _("\ %s: option `%s' requires an argument\n"), argv[0], argv[optind - 1]) >= 0) { if (_IO_fwide (stderr, 0) > 0) __fwprintf (stderr, L"%s", buf); else fputs (buf, stderr); free (buf); } #else fprintf (stderr, _("%s: option `%s' requires an argument\n"), argv[0], argv[optind - 1]); #endif } nextchar += strlen (nextchar); optopt = pfound->val; return optstring[0] == ':' ? ':' : '?'; } } nextchar += strlen (nextchar); if (longind != NULL) *longind = option_index; if (pfound->flag) { *(pfound->flag) = pfound->val; return 0; } return pfound->val; } /* Can't find it as a long option. If this is not getopt_long_only, or the option starts with '--' or is not a valid short option, then it's an error. Otherwise interpret it as a short option. */ if (!long_only || argv[optind][1] == '-' || my_index (optstring, *nextchar) == NULL) { if (print_errors) { #if defined _LIBC && defined USE_IN_LIBIO char *buf; int n; #endif if (argv[optind][1] == '-') { /* --option */ #if defined _LIBC && defined USE_IN_LIBIO n = __asprintf (&buf, _("%s: unrecognized option `--%s'\n"), argv[0], nextchar); #else fprintf (stderr, _("%s: unrecognized option `--%s'\n"), argv[0], nextchar); #endif } else { /* +option or -option */ #if defined _LIBC && defined USE_IN_LIBIO n = __asprintf (&buf, _("%s: unrecognized option `%c%s'\n"), argv[0], argv[optind][0], nextchar); #else fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), argv[0], argv[optind][0], nextchar); #endif } #if defined _LIBC && defined USE_IN_LIBIO if (n >= 0) { if (_IO_fwide (stderr, 0) > 0) __fwprintf (stderr, L"%s", buf); else fputs (buf, stderr); free (buf); } #endif } nextchar = (char *) ""; optind++; optopt = 0; return '?'; } } /* Look at and handle the next short option-character. */ { char c = *nextchar++; char *temp = my_index (optstring, c); /* Increment `optind' when we start to process its last character. */ if (*nextchar == '\0') ++optind; if (temp == NULL || c == ':') { if (print_errors) { #if defined _LIBC && defined USE_IN_LIBIO char *buf; int n; #endif if (posixly_correct) { /* 1003.2 specifies the format of this message. */ #if defined _LIBC && defined USE_IN_LIBIO n = __asprintf (&buf, _("%s: illegal option -- %c\n"), argv[0], c); #else fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c); #endif } else { #if defined _LIBC && defined USE_IN_LIBIO n = __asprintf (&buf, _("%s: invalid option -- %c\n"), argv[0], c); #else fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c); #endif } #if defined _LIBC && defined USE_IN_LIBIO if (n >= 0) { if (_IO_fwide (stderr, 0) > 0) __fwprintf (stderr, L"%s", buf); else fputs (buf, stderr); free (buf); } #endif } optopt = c; return '?'; } /* Convenience. Treat POSIX -W foo same as long option --foo */ if (temp[0] == 'W' && temp[1] == ';') { char *nameend; const struct option *p; const struct option *pfound = NULL; int exact = 0; int ambig = 0; int indfound = 0; int option_index; /* This is an option that requires an argument. */ if (*nextchar != '\0') { optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg, we must advance to the next element now. */ optind++; } else if (optind == argc) { if (print_errors) { /* 1003.2 specifies the format of this message. */ #if defined _LIBC && defined USE_IN_LIBIO char *buf; if (__asprintf (&buf, _("%s: option requires an argument -- %c\n"), argv[0], c) >= 0) { if (_IO_fwide (stderr, 0) > 0) __fwprintf (stderr, L"%s", buf); else fputs (buf, stderr); free (buf); } #else fprintf (stderr, _("%s: option requires an argument -- %c\n"), argv[0], c); #endif } optopt = c; if (optstring[0] == ':') c = ':'; else c = '?'; return c; } else /* We already incremented `optind' once; increment it again when taking next ARGV-elt as argument. */ optarg = argv[optind++]; /* optarg is now the argument, see if it's in the table of longopts. */ for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) /* Do nothing. */ ; /* Test all long options for either exact match or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) if (!strncmp (p->name, nextchar, nameend - nextchar)) { if ((unsigned int) (nameend - nextchar) == strlen (p->name)) { /* Exact match found. */ pfound = p; indfound = option_index; exact = 1; break; } else if (pfound == NULL) { /* First nonexact match found. */ pfound = p; indfound = option_index; } else /* Second or later nonexact match found. */ ambig = 1; } if (ambig && !exact) { if (print_errors) { #if defined _LIBC && defined USE_IN_LIBIO char *buf; if (__asprintf (&buf, _("%s: option `-W %s' is ambiguous\n"), argv[0], argv[optind]) >= 0) { if (_IO_fwide (stderr, 0) > 0) __fwprintf (stderr, L"%s", buf); else fputs (buf, stderr); free (buf); } #else fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), argv[0], argv[optind]); #endif } nextchar += strlen (nextchar); optind++; return '?'; } if (pfound != NULL) { option_index = indfound; if (*nameend) { /* Don't test has_arg with >, because some C compilers don't allow it to be used on enums. */ if (pfound->has_arg) optarg = nameend + 1; else { if (print_errors) { #if defined _LIBC && defined USE_IN_LIBIO char *buf; if (__asprintf (&buf, _("\ %s: option `-W %s' doesn't allow an argument\n"), argv[0], pfound->name) >= 0) { if (_IO_fwide (stderr, 0) > 0) __fwprintf (stderr, L"%s", buf); else fputs (buf, stderr); free (buf); } #else fprintf (stderr, _("\ %s: option `-W %s' doesn't allow an argument\n"), argv[0], pfound->name); #endif } nextchar += strlen (nextchar); return '?'; } } else if (pfound->has_arg == 1) { if (optind < argc) optarg = argv[optind++]; else { if (print_errors) { #if defined _LIBC && defined USE_IN_LIBIO char *buf; if (__asprintf (&buf, _("\ %s: option `%s' requires an argument\n"), argv[0], argv[optind - 1]) >= 0) { if (_IO_fwide (stderr, 0) > 0) __fwprintf (stderr, L"%s", buf); else fputs (buf, stderr); free (buf); } #else fprintf (stderr, _("%s: option `%s' requires an argument\n"), argv[0], argv[optind - 1]); #endif } nextchar += strlen (nextchar); return optstring[0] == ':' ? ':' : '?'; } } nextchar += strlen (nextchar); if (longind != NULL) *longind = option_index; if (pfound->flag) { *(pfound->flag) = pfound->val; return 0; } return pfound->val; } nextchar = NULL; return 'W'; /* Let the application handle it. */ } if (temp[1] == ':') { if (temp[2] == ':') { /* This is an option that accepts an argument optionally. */ if (*nextchar != '\0') { optarg = nextchar; optind++; } else optarg = NULL; nextchar = NULL; } else { /* This is an option that requires an argument. */ if (*nextchar != '\0') { optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg, we must advance to the next element now. */ optind++; } else if (optind == argc) { if (print_errors) { /* 1003.2 specifies the format of this message. */ #if defined _LIBC && defined USE_IN_LIBIO char *buf; if (__asprintf (&buf, _("\ %s: option requires an argument -- %c\n"), argv[0], c) >= 0) { if (_IO_fwide (stderr, 0) > 0) __fwprintf (stderr, L"%s", buf); else fputs (buf, stderr); free (buf); } #else fprintf (stderr, _("%s: option requires an argument -- %c\n"), argv[0], c); #endif } optopt = c; if (optstring[0] == ':') c = ':'; else c = '?'; } else /* We already incremented `optind' once; increment it again when taking next ARGV-elt as argument. */ optarg = argv[optind++]; nextchar = NULL; } } return c; } } int getopt (argc, argv, optstring) int argc; char *const *argv; const char *optstring; { return _getopt_internal (argc, argv, optstring, (const struct option *) 0, (int *) 0, 0); } #endif /* Not ELIDE_CODE. */ #ifdef TEST /* Compile with -DTEST to make an executable for use in testing the above definition of `getopt'. */ int main (argc, argv) int argc; char **argv; { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; c = getopt (argc, argv, "abc:d:0123456789"); if (c == -1) break; switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); break; case 'a': printf ("option a\n"); break; case 'b': printf ("option b\n"); break; case 'c': printf ("option c with value `%s'\n", optarg); break; case '?': break; default: printf ("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit (0); } #endif /* TEST */ gtkwave-3.3.66/src/rc.h0000664000076400007640000000727612341266475014171 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2009. * * 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. */ #include "globals.h" #ifndef WAVE_RC_H #define WAVE_RC_H struct rc_entry { char *name; int (*func)(char *); }; void read_rc_file(char *override_rc); int get_rgb_from_name(char *str); GdkGC *get_gc_from_name(char *str); int f_accel (char *str); int f_alt_hier_delimeter (char *str); int f_append_vcd_hier (char *str); int f_atomic_vectors (char *str); int f_autocoalesce (char *str); int f_autocoalesce_reversal (char *str); int f_autoname_bundles (char *str); int f_color_0 (char *str); int f_color_1 (char *str); int f_color_back (char *str); int f_color_baseline (char *str); int f_color_black (char *str); int f_color_dash (char *str); int f_color_dashfill (char *str); int f_color_dkblue (char *str); int f_color_brkred (char *str); int f_color_ltblue (char *str); int f_color_gmstrd (char *str); int f_color_dkgray (char *str); int f_color_grid (char *str); int f_color_grid2 (char *str); int f_color_high (char *str); int f_color_low (char *str); int f_color_ltgray (char *str); int f_color_mark (char *str); int f_color_mdgray (char *str); int f_color_mid (char *str); int f_color_normal (char *str); int f_color_time (char *str); int f_color_timeb (char *str); int f_color_trans (char *str); int f_color_u (char *str); int f_color_ufill (char *str); int f_color_umark (char *str); int f_color_value (char *str); int f_color_vbox (char *str); int f_color_vtrans (char *str); int f_color_w (char *str); int f_color_wfill (char *str); int f_color_white (char *str); int f_color_x (char *str); int f_color_xfill (char *str); int f_constant_marker_update (char *str); int f_convert_to_reals (char *str); int f_cursor_snap (char *str); int f_disable_mouseover (char *str); int f_disable_tooltips (char *str); int f_do_initial_zoom_fit (char *str); int f_dynamic_resizing (char *str); int f_enable_fast_exit (char *str); int f_enable_ghost_marker (char *str); int f_enable_horiz_grid (char *str); int f_enable_vcd_autosave (char *str); int f_enable_vert_grid (char *str); int f_fontname_logfile (char *str); int f_fontname_signals (char *str); int f_fontname_waves (char *str); int f_force_toolbars (char *str); int f_hide_sst (char *str); int f_hier_delimeter (char *str); int f_hier_grouping (char *str); int f_hier_max_level (char *str); int f_hpane_pack (char *str); int f_ignore_savefile_pos (char *str); int f_ignore_savefile_size (char *str); int f_initial_window_x (char *str); int f_initial_window_xpos (char *str); int f_initial_window_y (char *str); int f_initial_window_ypos (char *str); int f_left_justify_sigs (char *str); int f_lxt_clock_compress_to_z (char *str); int f_page_divisor (char *str); int f_ps_maxveclen (char *str); int f_show_base_symbols (char *str); int f_show_grid (char *str); int f_splash_disable (char *str); int f_sst_expanded (char *str); int f_use_big_fonts (char *str); int f_use_frequency_display (char *str); int f_use_full_precision (char *str); int f_use_maxtime_display (char *str); int f_use_nonprop_fonts (char *str); int f_use_roundcaps (char *str); int f_use_scrollbar_only (char *str); int f_vcd_explicit_zero_subscripts (char *str); int f_vcd_preserve_glitches (char *str); int f_vcd_warning_filesize (char *str); int f_vector_padding (char *str); int f_vlist_compression (char *str); int f_wave_scrolling (char *str); int f_zoom_base (char *str); int f_zoom_center (char *str); int f_zoom_pow10_snap (char *str); #endif gtkwave-3.3.66/src/Makefile.am0000664000076400007640000000744012473716613015441 0ustar bybellbybell## -*- makefile -*- ## SUBDIRS= $(LIBZ_DIR) $(LIBBZ2_DIR) liblzma helpers helpers/fst cocoa DIST_SUBDIRS= libz libbz2 liblzma helpers helpers/fst cocoa LIBFST_CFLAGS = -I$(srcdir)/helpers/fst LIBFST_LDADD = ./helpers/fst/libfst.a LIBLZMA_CFLAGS = -I$(srcdir)/liblzma $(LIBXZ_CFLAGS) LIBLZMA_LDADD = ./liblzma/libgwlzma.a $(LIBXZ_LDADD) LIBCOCOA_CFLAGS = -I$(srcdir)/cocoa LIBCOCOA_LDADD = ./cocoa/libgtkwmacintegration.a $(COCOA_GTK_LDADD) #DEBUGS = -DDEBUG_FACILITIES -DDEBUG_PRINTF -DDEBUG_MALLOC -DSTRICT_VCD_ONLY -DDEBUG_MALLOC_LINES bin_PROGRAMS= gtkwave twinwave AM_CFLAGS= -I$(srcdir)/.. -I$(srcdir)/helpers $(FASTTREE_CFLAGS) $(GTK_CFLAGS) $(LIBLZMA_CFLAGS) \ $(LIBZ_CFLAGS) $(LIBBZ2_CFLAGS) $(LIBFST_CFLAGS) $(AET2_CFLAGS) $(FSDB_CFLAGS) $(TCL_INCLUDE_SPEC) \ $(TCL_DEFADD) $(TK_INCLUDE_SPEC) $(EXTLOAD_CFLAGS) $(GEDIT_CFLAGS) $(LIBJUDY_CFLAGS) \ $(GTK_MAC_CFLAGS) $(GCONF_CFLAGS) $(LIBCOCOA_CFLAGS) $(GTK_UNIX_PRINT_CFLAGS) AM_CXXFLAGS= $(AM_CFLAGS) ./liblzma/libgwlzma.a: $(srcdir)/liblzma/LzmaLib.c $(srcdir)/liblzma/LzmaLib.h ./helpers/fst/libfst.a: $(srcdir)/helpers/fst/fastlz.c $(srcdir)/helpers/fst/fastlz.h $(srcdir)/helpers/fst/fstapi.c $(srcdir)/helpers/fst/fstapi.h ./cocoa/libgtkwmacintegration.a: $(srcdir)/cocoa/cocoa_misc.c $(srcdir)/cocoa/cocoa_misc.h gtkwave_SOURCES= \ fsdb_wrapper_api.cc fsdb_wrapper_api.h \ baseconvert.h wavewindow.h zoombuttons.h fetchbuttons.h timeentry.h shiftbuttons.h pagebuttons.h edgebuttons.h \ signalwindow.h entry.h file.h status.h search.h showchange.h treesearch.h hiersearch.h renderopt.h markerbox.h \ simplereq.h help.h logfile.h vcd_partial.h mouseover.h mouseover_sigs.h interp.h \ globals.c globals.h ae2.c ae2.h analyzer.c analyzer.h baseconvert.c bitvec.c \ bsearch.c bsearch.h busy.c busy.h \ clipping.c clipping.h color.c color.h currenttime.c currenttime.h \ debug.c debug.h discardbuttons.c edgebuttons.c \ entry.c extload.c extload.h fetchbuttons.c fgetdynamic.c fgetdynamic.h file.c fonts.c fonts.h fst.c fst.h \ gconf.c gconf.h getopt.c \ getopt1.c ghw.c ghw.h ghwlib.c ghwlib.h gnu-getopt.h gnu_regex.h gtk12compat.h \ hierpack.c hierpack.h jrb.c jrb.h help.c helpers/lxt2_read.c \ helpers/lxt_write.c helpers/vzt_read.c hiersearch.c interp.c \ logfile.c lx2.c lx2.h lxt.c lxt.h main.c main.h markerbox.c menu.c menu.h mouseover.c \ mouseover_sigs.c pagebuttons.c pipeio.c pipeio.h pixmaps.c pixmaps.h print.c print.h \ ptranslate.c ptranslate.h rc.c rc.h \ regex.c regex_wave.h renderopt.c rgb.c savefile.c savefile.h search.c shiftbuttons.c showchange.c \ signalwindow.c simplereq.c splash.c status.c strace.c strace.h symbol.c symbol.h tcl_callbacks.h \ tcl_commands.c tcl_helper.c tcl_helper.h tcl_np.c tcl_np.h tcl_support_commands.c tcl_support_commands.h \ timeentry.c translate.c translate.h tree.c tree.h treesearch.c tree_component.c tree_component.h \ ttranslate.c ttranslate.h vcd.c vcd.h vcd_keywords.c \ vcd_partial.c vcd_recoder.c vcd_saver.c vcd_saver.h version.h vlist.c vlist.h vzt.c vzt.h wavealloca.h \ wavewindow.c zoombuttons.c gtkwave_LDADD= $(LIBCOCOA_LDADD) $(GTK_LIBS) $(LIBLZMA_LDADD) $(LIBZ_LDADD) $(LIBBZ2_LDADD) $(LIBFST_LDADD) $(AET2_LDADD) $(TCL_LDADD) $(TK_LDADD) $(FSDB_LDADD) $(LIBJUDY_LDADD) $(GTK_MAC_LIBS) $(GCONF_LIBS) $(GTK_UNIX_PRINT_LIBS) $(MINGW_LDADD) gtkwave_LDFLAGS = $(COCOA_GTK_LDFLAGS) twinwave_SOURCES= twinwave.c twinwave_LDADD= $(GTK_LIBS) $(GTK_MAC_LIBS) $(GCONF_LIBS) vcd_keywords.c: vcd_keywords.gperf printf "$(GPERF) -o -i 1 -C -k 1,\044 -L C -H keyword_hash -N check_identifier -tT $(srcdir)/vcd_keywords.gperf >vcd_keywords.c" | sh BUILT_SOURCES= vcd_keywords.c # I'm listing treesearch_gtk2.c here instead of in SOURCES because we don't directly # compile it. Rather it is #include'd by treesearch.c. EXTRA_DIST= treesearch_gtk1.c treesearch_gtk2.c vcd_keywords.gperf gnu_regex.c gtkwave-3.3.66/src/getopt1.c0000664000076400007640000001124411572536221015123 0ustar bybellbybell/* getopt_long and getopt_long_only entry points for GNU getopt. Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library 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 2.1 of the License, or (at your option) any later version. The GNU C Library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA */ #if 0 #define HAVE_CONFIG_H /* needed for Wine */ #endif #ifdef HAVE_CONFIG_H #include #endif #ifdef HAVE_GETOPT_LONG #define ELIDE_CODE #endif #ifdef _LIBC # include #else # include "gnu-getopt.h" #endif #if !defined __STDC__ || !__STDC__ /* This is a separate conditional since some stdc systems reject `defined (const)'. */ #ifndef const #define const #endif #endif #include /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #define GETOPT_INTERFACE_VERSION 2 #if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 #include #if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION #define ELIDE_CODE #endif #endif #ifndef ELIDE_CODE /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ #include #endif #ifndef NULL #define NULL 0 #endif int getopt_long (argc, argv, options, long_options, opt_index) int argc; char *const *argv; const char *options; const struct option *long_options; int *opt_index; { return _getopt_internal (argc, argv, options, long_options, opt_index, 0); } /* Like getopt_long, but '-' as well as '--' can indicate a long option. If an option that starts with '-' (not '--') doesn't match a long option, but does match a short option, it is parsed as a short option instead. */ int getopt_long_only (argc, argv, options, long_options, opt_index) int argc; char *const *argv; const char *options; const struct option *long_options; int *opt_index; { return _getopt_internal (argc, argv, options, long_options, opt_index, 1); } # ifdef _LIBC libc_hidden_def (getopt_long) libc_hidden_def (getopt_long_only) # endif #endif /* Not ELIDE_CODE. */ #ifdef TEST #include int main (argc, argv) int argc; char **argv; { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; int option_index = 0; static struct option long_options[] = { {"add", 1, 0, 0}, {"append", 0, 0, 0}, {"delete", 1, 0, 0}, {"verbose", 0, 0, 0}, {"create", 0, 0, 0}, {"file", 1, 0, 0}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "abc:d:0123456789", long_options, &option_index); if (c == -1) break; switch (c) { case 0: printf ("option %s", long_options[option_index].name); if (optarg) printf (" with arg %s", optarg); printf ("\n"); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); break; case 'a': printf ("option a\n"); break; case 'b': printf ("option b\n"); break; case 'c': printf ("option c with value `%s'\n", optarg); break; case 'd': printf ("option d with value `%s'\n", optarg); break; case '?': break; default: printf ("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit (0); } #endif /* TEST */ gtkwave-3.3.66/src/shiftbuttons.c0000664000076400007640000001051412360623564016276 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999. * * 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. */ #include "globals.h" #include #include "currenttime.h" #include "pixmaps.h" #include "debug.h" void service_left_shift(GtkWidget *text, gpointer data) { (void)text; (void)data; GtkAdjustment *hadj; gfloat inc; TimeType ntinc; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nShift Left"); help_text( " scrolls the display window left one tick worth of data." " The net action is that the data scrolls right a tick." #ifdef WAVE_USE_GTK2 " Ctrl + Scrollwheel Up also does this in non-alternative wheel mode." #endif ); return; } if(GLOBALS->nspx>1.0) inc=GLOBALS->nspx; else inc=1.0; hadj=GTK_ADJUSTMENT(GLOBALS->wave_hslider); if((hadj->value-inc)>GLOBALS->tims.first) hadj->value=hadj->value-inc; else hadj->value=GLOBALS->tims.first; ntinc=(TimeType)inc; if((GLOBALS->tims.start-ntinc)>GLOBALS->tims.first) GLOBALS->tims.timecache=GLOBALS->tims.start-ntinc; else GLOBALS->tims.timecache=GLOBALS->tims.first; time_update(); DEBUG(printf("Left Shift\n")); } void service_right_shift(GtkWidget *text, gpointer data) { (void)text; (void)data; GtkAdjustment *hadj; gfloat inc; TimeType ntinc, pageinc; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nShift Right"); help_text( " scrolls the display window right one tick worth of data." " The net action is that the data scrolls left a tick." #ifdef WAVE_USE_GTK2 " Ctrl + Scrollwheel Down also does this in non-alternative wheel mode." #endif ); return; } if(GLOBALS->nspx>1.0) inc=GLOBALS->nspx; else inc=1.0; ntinc=(TimeType)inc; hadj=GTK_ADJUSTMENT(GLOBALS->wave_hslider); if((hadj->value+inc)tims.last) hadj->value=hadj->value+inc; else hadj->value=GLOBALS->tims.last-inc; pageinc=(TimeType)(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx); if((GLOBALS->tims.start+ntinc)<(GLOBALS->tims.last-pageinc+1)) GLOBALS->tims.timecache=GLOBALS->tims.start+ntinc; else { GLOBALS->tims.timecache=GLOBALS->tims.last-pageinc+1; if(GLOBALS->tims.timecachetims.first) GLOBALS->tims.timecache=GLOBALS->tims.first; } time_update(); DEBUG(printf("Right Shift\n")); } /* Create shift buttons */ GtkWidget * create_shift_buttons (void) { GtkWidget *table; GtkWidget *table2; GtkWidget *frame; GtkWidget *main_vbox; GtkWidget *b1; GtkWidget *b2; GtkWidget *pixmapwid1, *pixmapwid2; GtkTooltips *tooltips; tooltips=gtk_tooltips_new_2(); gtk_tooltips_set_delay_2(tooltips,1500); pixmapwid1=gtk_pixmap_new(GLOBALS->larrow_pixmap, GLOBALS->larrow_mask); gtk_widget_show(pixmapwid1); pixmapwid2=gtk_pixmap_new(GLOBALS->rarrow_pixmap, GLOBALS->rarrow_mask); gtk_widget_show(pixmapwid2); /* Create a table to hold the text widget and scrollbars */ table = gtk_table_new (1, 1, FALSE); main_vbox = gtk_vbox_new (FALSE, 1); gtk_container_border_width (GTK_CONTAINER (main_vbox), 1); gtk_container_add (GTK_CONTAINER (table), main_vbox); frame = gtk_frame_new ("Shift "); gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0); gtk_widget_show (frame); gtk_widget_show (main_vbox); table2 = gtk_table_new (2, 1, FALSE); b1 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b1), pixmapwid1); gtk_table_attach (GTK_TABLE (table2), b1, 0, 1, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); gtk_signal_connect_object (GTK_OBJECT (b1), "clicked", GTK_SIGNAL_FUNC(service_left_shift), GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(tooltips, b1, "Shift Left 1 Tick", NULL); gtk_widget_show(b1); b2 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b2), pixmapwid2); gtk_table_attach (GTK_TABLE (table2), b2, 0, 1, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); gtk_signal_connect_object (GTK_OBJECT (b2), "clicked", GTK_SIGNAL_FUNC(service_right_shift), GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(tooltips, b2, "Shift Right 1 Tick", NULL); gtk_widget_show(b2); gtk_container_add (GTK_CONTAINER (frame), table2); gtk_widget_show(table2); return(table); } gtkwave-3.3.66/src/main.h0000664000076400007640000000347612341266475014507 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2012. * * 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. */ #include "globals.h" #ifndef __MFMAIN_H__ #define __MFMAIN_H__ #include "busy.h" #define HAVE_PANED_PACK /* undefine this if you have an older GTK */ struct logfile_chain { struct logfile_chain *next; char *name; }; int main_2(int opt_vcd, int argc, char *argv[]); GtkWidget *create_text(void); GtkWidget *create_zoom_buttons(void); GtkWidget *create_page_buttons(void); GtkWidget *create_fetch_buttons(void); GtkWidget *create_discard_buttons(void); GtkWidget *create_edge_buttons(void); GtkWidget *create_shift_buttons(void); GtkWidget *create_entry_box(void); GtkWidget *create_time_box(void); GtkWidget *create_wavewindow(void); GtkWidget *create_signalwindow(void); /* Get/set the current size of the window. */ extern void get_window_size (int *x, int *y); extern void set_window_size (int x, int y); /* Get/set the x/y pos of the window */ void get_window_xypos(int *root_x, int *root_y); void set_window_xypos(int root_x, int root_y); /* stems helper activation */ int stems_are_active(void); void activate_stems_reader(char *stems_name); #if !defined _MSC_VER void kill_stems_browser(void); #endif void kill_stems_browser_single(void *G); /* prototype only used in main.c */ void menu_reload_waveform_marshal(GtkWidget *widget, gpointer data); /* function for spawning vcd conversions */ void optimize_vcd_file(void); enum FileType { MISSING_FILE, LXT_FILE, LX2_FILE, VZT_FILE, AE2_FILE, GHW_FILE, VCD_FILE, VCD_RECODER_FILE, #ifdef EXTLOAD_SUFFIX EXTLOAD_FILE, #endif FST_FILE, DUMPLESS_FILE }; #endif gtkwave-3.3.66/src/bsearch.c0000664000076400007640000001721312341266475015157 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2013. * * 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. */ #include "globals.h" #include #include "analyzer.h" #include "currenttime.h" #include "symbol.h" #include "bsearch.h" #include "strace.h" #include "hierpack.h" #include static int compar_timechain(const void *s1, const void *s2) { TimeType key, obj, delta; TimeType *cpos; int rv; key=*((TimeType *)s1); obj=*(cpos=(TimeType *)s2); if((obj<=key)&&(obj>GLOBALS->max_compare_time_tc_bsearch_c_1)) { GLOBALS->max_compare_time_tc_bsearch_c_1=obj; GLOBALS->max_compare_pos_tc_bsearch_c_1=cpos; } delta=key-obj; if(delta<0) rv=-1; else if(delta>0) rv=1; else rv=0; return(rv); } int bsearch_timechain(TimeType key) { GLOBALS->max_compare_time_tc_bsearch_c_1=-2; GLOBALS->max_compare_pos_tc_bsearch_c_1=NULL; if(!GLOBALS->strace_ctx->timearray) return(-1); if(bsearch(&key, GLOBALS->strace_ctx->timearray, GLOBALS->strace_ctx->timearray_size, sizeof(TimeType), compar_timechain)) { /* nothing, all side effects are in bsearch */ } if((!GLOBALS->max_compare_pos_tc_bsearch_c_1)||(GLOBALS->max_compare_time_tc_bsearch_c_1shift_timebase)) { GLOBALS->max_compare_pos_tc_bsearch_c_1=GLOBALS->strace_ctx->timearray; /* aix bsearch fix */ } return(GLOBALS->max_compare_pos_tc_bsearch_c_1-GLOBALS->strace_ctx->timearray); } /*****************************************************************************************/ int bsearch_aetinfo_timechain(TimeType key) { GLOBALS->max_compare_time_tc_bsearch_c_1=-2; GLOBALS->max_compare_pos_tc_bsearch_c_1=NULL; if(!GLOBALS->ae2_time_xlate) return(-1); if(bsearch(&key, GLOBALS->ae2_time_xlate, GLOBALS->ae2_end_cyc - GLOBALS->ae2_start_cyc + 1, sizeof(TimeType), compar_timechain)) { /* nothing, all side effects are in bsearch */ } if(!GLOBALS->max_compare_pos_tc_bsearch_c_1) { GLOBALS->max_compare_pos_tc_bsearch_c_1=GLOBALS->ae2_time_xlate; /* aix bsearch fix */ } return(GLOBALS->max_compare_pos_tc_bsearch_c_1-GLOBALS->ae2_time_xlate); } /*****************************************************************************************/ static int compar_histent(const void *s1, const void *s2) { TimeType key, obj, delta; hptr cpos; int rv; key=*((TimeType *)s1); obj=(cpos=(*((hptr *)s2)))->time; if((obj<=key)&&(obj>GLOBALS->max_compare_time_bsearch_c_1)) { GLOBALS->max_compare_time_bsearch_c_1=obj; GLOBALS->max_compare_pos_bsearch_c_1=cpos; GLOBALS->max_compare_index=(hptr *)s2; } delta=key-obj; if(delta<0) rv=-1; else if(delta>0) rv=1; else rv=0; return(rv); } hptr bsearch_node(nptr n, TimeType key) { GLOBALS->max_compare_time_bsearch_c_1=-2; GLOBALS->max_compare_pos_bsearch_c_1=NULL; GLOBALS->max_compare_index=NULL; if(bsearch(&key, n->harray, n->numhist, sizeof(hptr), compar_histent)) { /* nothing, all side effects are in bsearch */ } if((!GLOBALS->max_compare_pos_bsearch_c_1)||(GLOBALS->max_compare_time_bsearch_c_1max_compare_pos_bsearch_c_1=n->harray[1]; /* aix bsearch fix */ GLOBALS->max_compare_index=&(n->harray[1]); } while(GLOBALS->max_compare_pos_bsearch_c_1->next) /* non-RoSync dumper deglitching fix */ { if(GLOBALS->max_compare_pos_bsearch_c_1->time != GLOBALS->max_compare_pos_bsearch_c_1->next->time) break; GLOBALS->max_compare_pos_bsearch_c_1 = GLOBALS->max_compare_pos_bsearch_c_1->next; } return(GLOBALS->max_compare_pos_bsearch_c_1); } /*****************************************************************************************/ static int compar_vectorent(const void *s1, const void *s2) { TimeType key, obj, delta; vptr cpos; int rv; key=*((TimeType *)s1); /* obj=(cpos=(*((vptr *)s2)))->time+GLOBALS->shift_timebase; */ obj=(cpos=(*((vptr *)s2)))->time; if((obj<=key)&&(obj>GLOBALS->vmax_compare_time_bsearch_c_1)) { GLOBALS->vmax_compare_time_bsearch_c_1=obj; GLOBALS->vmax_compare_pos_bsearch_c_1=cpos; GLOBALS->vmax_compare_index=(vptr *)s2; } delta=key-obj; if(delta<0) rv=-1; else if(delta>0) rv=1; else rv=0; return(rv); } vptr bsearch_vector(bvptr b, TimeType key) { GLOBALS->vmax_compare_time_bsearch_c_1=-2; GLOBALS->vmax_compare_pos_bsearch_c_1=NULL; GLOBALS->vmax_compare_index=NULL; if(bsearch(&key, b->vectors, b->numregions, sizeof(vptr), compar_vectorent)) { /* nothing, all side effects are in bsearch */ } if((!GLOBALS->vmax_compare_pos_bsearch_c_1)||(GLOBALS->vmax_compare_time_bsearch_c_1 that declared in the structure definition via end of structure malloc padding */ GLOBALS->vmax_compare_pos_bsearch_c_1=b->vectors[1]; /* aix bsearch fix */ GLOBALS->vmax_compare_index=&(b->vectors[1]); } while(GLOBALS->vmax_compare_pos_bsearch_c_1->next) /* non-RoSync dumper deglitching fix */ { if(GLOBALS->vmax_compare_pos_bsearch_c_1->time != GLOBALS->vmax_compare_pos_bsearch_c_1->next->time) break; GLOBALS->vmax_compare_pos_bsearch_c_1 = GLOBALS->vmax_compare_pos_bsearch_c_1->next; } return(GLOBALS->vmax_compare_pos_bsearch_c_1); } /*****************************************************************************************/ static int compar_trunc(const void *s1, const void *s2) { char *str; char vcache[2]; int key, obj; str=(char *)s2; key=*((int*)s1); vcache[0]=*str; vcache[1]=*(str+1); *str='+'; *(str+1)=0; obj=font_engine_string_measure(GLOBALS->wavefont,GLOBALS->trunc_asciibase_bsearch_c_1); *str=vcache[0]; *(str+1)=vcache[1]; if((obj<=key)&&(obj>GLOBALS->maxlen_trunc)) { GLOBALS->maxlen_trunc=obj; GLOBALS->maxlen_trunc_pos_bsearch_c_1=str; } return(key-obj); } char *bsearch_trunc(char *ascii, int maxlen) { int len; if((maxlen<=0)||(!ascii)||(!(len=strlen(ascii)))) return(NULL); GLOBALS->maxlen_trunc=0; GLOBALS->maxlen_trunc_pos_bsearch_c_1=NULL; if(bsearch(&maxlen, GLOBALS->trunc_asciibase_bsearch_c_1=ascii, len, sizeof(char), compar_trunc)) { /* nothing, all side effects are in bsearch */ } return(GLOBALS->maxlen_trunc_pos_bsearch_c_1); } /*****************************************************************************************/ static int compar_facs(const void *key, const void *v2) { struct symbol *s2; int rc; int was_packed = HIER_DEPACK_STATIC; char *s3; s2=*((struct symbol **)v2); s3 = hier_decompress_flagged(s2->name, &was_packed); rc=sigcmp((char *)key,s3); /* if(was_packed) free_2(s3); ...not needed with HIER_DEPACK_STATIC */ return(rc); } struct symbol *bsearch_facs(char *ascii, unsigned int *rows_return) { struct symbol **rc; int len; if ((!ascii)||(!(len=strlen(ascii)))) return(NULL); if(rows_return) { *rows_return = 0; } if(ascii[len-1]=='}') { int i; for(i=len-2;i>=2;i--) { if(isdigit((int)(unsigned char)ascii[i])) continue; if(ascii[i]=='{') { char *tsc = wave_alloca(i+1); memcpy(tsc, ascii, i+1); tsc[i] = 0; rc=(struct symbol **)bsearch(tsc, GLOBALS->facs, GLOBALS->numfacs, sizeof(struct symbol *), compar_facs); if(rc) { unsigned int whichrow = atoi(&ascii[i+1]); if(rows_return) *rows_return = whichrow; #ifdef WAVE_ARRAY_SUPPORT if(whichrow <= (*rc)->n->array_height) #endif { return(*rc); } } } break; /* fallthrough to normal handler */ } } rc=(struct symbol **)bsearch(ascii, GLOBALS->facs, GLOBALS->numfacs, sizeof(struct symbol *), compar_facs); if(rc) return(*rc); else return(NULL); } gtkwave-3.3.66/src/hiersearch.h0000664000076400007640000000075111523063250015654 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2010 * * 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. */ #ifndef WAVE_HIERSEARCH_H #define WAVE_HIERSEARCH_H void hier_searchbox(char *title, GtkSignalFunc func); void refresh_hier_tree(struct tree *t); int hier_searchbox_is_active(void); #endif gtkwave-3.3.66/src/edgebuttons.c0000664000076400007640000003243512360623564016073 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2008-2012. * * 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. */ #include "globals.h" #include #include "currenttime.h" #include "pixmaps.h" #include "strace.h" #include "debug.h" static Trptr find_first_highlighted_trace(void) { Trptr t = NULL; for(t=GLOBALS->traces.first;t;t=t->t_next) { if ((t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH))||(!(t->flags&TR_HIGHLIGHT))||(!(t->name))) { continue; } else { break; } } return(t); } static Trptr find_next_highlighted_trace(Trptr t) { if(t) { t = t->t_next; for(;t;t=t->t_next) { if ((t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH))||(!(t->flags&TR_HIGHLIGHT))||(!(t->name))) { continue; } else { break; } } } return(t); } /************************************************/ /* * strace backward or forward..this was cut and * pasted from strace.c and special cased to handle * just a single trace. this might be relaxed later. */ static void edge_search_2(int direction, int is_last_iteration) { struct strace s_tmp; struct strace *s_head, *s; TimeType basetime, maxbase, sttim, fintim; Trptr t = find_first_highlighted_trace(); int totaltraces; #ifdef DEBUG_PRINTF int passcount; #endif int whichpass; TimeType middle=0, width; if(!t) return; memset(s_head = &s_tmp, 0, sizeof(struct strace)); s_head->trace = t; s_head->value = ST_ANY; s = s_head; while(t) { t = find_next_highlighted_trace(t); if(t) { s->next = wave_alloca(sizeof(struct strace)); memset(s = s->next, 0, sizeof(struct strace)); s->trace = t; s->value = ST_ANY; } } if(direction==STRACE_BACKWARD) /* backwards */ { if(GLOBALS->tims.marker<0) { basetime=MAX_HISTENT_TIME; } else { basetime=GLOBALS->tims.marker; } } else /* go forwards */ { if(GLOBALS->tims.marker<0) { basetime=GLOBALS->tims.first; } else { basetime=GLOBALS->tims.marker; } } sttim=GLOBALS->tims.first; fintim=GLOBALS->tims.last; for(whichpass=0;;whichpass++) { if(direction==STRACE_BACKWARD) /* backwards */ { maxbase=-1; s=s_head; while(s) { t=s->trace; GLOBALS->shift_timebase=t->shift; if(!(t->vector)) { hptr h; hptr *hp; UTimeType utt; TimeType tt; /* h= */ bsearch_node(t->n.nd, basetime - t->shift); /* scan-build */ hp=GLOBALS->max_compare_index; if((hp==&(t->n.nd->harray[1]))||(hp==&(t->n.nd->harray[0]))) return; if(basetime == ((*hp)->time+GLOBALS->shift_timebase)) hp--; h=*hp; s->his.h=h; utt=strace_adjust(h->time,GLOBALS->shift_timebase); tt=utt; if(tt > maxbase) maxbase=tt; } else { vptr v; vptr *vp; UTimeType utt; TimeType tt; /* v= */ bsearch_vector(t->n.vec, basetime - t->shift); /* scan-build */ vp=GLOBALS->vmax_compare_index; if((vp==&(t->n.vec->vectors[1]))||(vp==&(t->n.vec->vectors[0]))) return; if(basetime == ((*vp)->time+GLOBALS->shift_timebase)) vp--; v=*vp; s->his.v=v; utt=strace_adjust(v->time,GLOBALS->shift_timebase); tt=utt; if(tt > maxbase) maxbase=tt; } s=s->next; } } else /* go forward */ { maxbase=MAX_HISTENT_TIME; s=s_head; while(s) { t=s->trace; GLOBALS->shift_timebase=t->shift; if(!(t->vector)) { hptr h; UTimeType utt; TimeType tt; h=bsearch_node(t->n.nd, basetime - t->shift); while(h->next && h->time==h->next->time) h=h->next; if((whichpass)||(GLOBALS->tims.marker>=0)) h=h->next; if(!h) return; s->his.h=h; utt=strace_adjust(h->time,GLOBALS->shift_timebase); tt=utt; if(tt < maxbase) maxbase=tt; } else { vptr v; UTimeType utt; TimeType tt; v=bsearch_vector(t->n.vec, basetime - t->shift); while(v->next && v->time==v->next->time) v=v->next; if((whichpass)||(GLOBALS->tims.marker>=0)) v=v->next; if(!v) return; s->his.v=v; utt=strace_adjust(v->time,GLOBALS->shift_timebase); tt=utt; if(tt < maxbase) maxbase=tt; } s=s->next; } } s=s_head; totaltraces=0; /* increment when not don't care */ while(s) { /* commented out, maybe will have possible future expansion later, * this was cut and pasted from strace.c */ #if 0 char str[2]; #endif t=s->trace; s->search_result=0; /* explicitly must set this */ GLOBALS->shift_timebase=t->shift; if((!t->vector)&&(!(t->n.nd->extvals))) { if(strace_adjust(s->his.h->time,GLOBALS->shift_timebase)!=maxbase) { s->his.h=bsearch_node(t->n.nd, maxbase - t->shift); while(s->his.h->next && s->his.h->time==s->his.h->next->time) s->his.h=s->his.h->next; } /* commented out, maybe will have possible future expansion later, * this was cut and pasted from strace.c */ #if 0 if(t->flags&TR_INVERT) { str[0]=AN_STR_INV[s->his.h->v.h_val]; } else { str[0]=AN_STR[s->his.h->v.h_val]; } str[1]=0x00; #endif switch(s->value) { case ST_ANY: totaltraces++; s->search_result=1; break; /* commented out, maybe will have possible future expansion later, * this was cut and pasted from strace.c */ #if 0 case ST_DC: break; case ST_HIGH: totaltraces++; if((str[0]=='1')||(str[0]=='H')) s->search_result=1; break; case ST_RISE: if((str[0]=='1')||(str[0]=='H')) s->search_result=1; totaltraces++; break; case ST_LOW: totaltraces++; if((str[0]=='0')||(str[0]=='L')) s->search_result=1; break; case ST_FALL: totaltraces++; if((str[0]=='0')||(str[0]=='L')) s->search_result=1; break; case ST_MID: totaltraces++; if(str[0]=='Z') s->search_result=1; break; case ST_X: totaltraces++; if(str[0]=='X') s->search_result=1; break; case ST_STRING: totaltraces++; if(s->string) if(strstr_i(s->string,str)) s->search_result=1; break; #endif default: fprintf(stderr, "Internal error: st_type of %d\n",s->value); exit(255); } } else { char *chval, *chval2; char ch; if(t->vector) { if(strace_adjust(s->his.v->time,GLOBALS->shift_timebase)!=maxbase) { s->his.v=bsearch_vector(t->n.vec, maxbase - t->shift); while(s->his.v->next && s->his.v->time==s->his.v->next->time) s->his.v=s->his.v->next; } chval=convert_ascii(t,s->his.v); } else { if(strace_adjust(s->his.h->time,GLOBALS->shift_timebase)!=maxbase) { s->his.h=bsearch_node(t->n.nd, maxbase - t->shift); while(s->his.h->next && s->his.h->time==s->his.h->next->time) s->his.h=s->his.h->next; } if(s->his.h->flags&HIST_REAL) { if(!(s->his.h->flags&HIST_STRING)) { #ifdef WAVE_HAS_H_DOUBLE chval=convert_ascii_real(t, &s->his.h->v.h_double); #else chval=convert_ascii_real(t, (double *)s->his.h->v.h_vector); #endif } else { chval=convert_ascii_string((char *)s->his.h->v.h_vector); chval2=chval; while((ch=*chval2)) /* toupper() the string */ { if((ch>='a')&&(ch<='z')) { *chval2= ch-('a'-'A'); } chval2++; } } } else { chval=convert_ascii_vec(t,s->his.h->v.h_vector); } } switch(s->value) { case ST_ANY: totaltraces++; s->search_result=1; break; /* commented out, maybe will have possible future expansion later, * this was cut and pasted from strace.c */ #if 0 case ST_DC: break; case ST_RISE: case ST_FALL: totaltraces++; break; case ST_HIGH: totaltraces++; if((chval2=chval)) while((ch=*(chval2++))) { if(((ch>='1')&&(ch<='9'))||(ch=='h')||(ch=='H')||((ch>='A')&&(ch<='F'))) { s->search_result=1; break; } } break; case ST_LOW: totaltraces++; if((chval2=chval)) { s->search_result=1; while((ch=*(chval2++))) { if((ch!='0')&&(ch!='l')&&(ch!='L')) { s->search_result=0; break; } } } break; case ST_MID: totaltraces++; if((chval2=chval)) { s->search_result=1; while((ch=*(chval2++))) { if((ch!='z')&&(ch!='Z')) { s->search_result=0; break; } } } break; case ST_X: totaltraces++; if((chval2=chval)) { s->search_result=1; while((ch=*(chval2++))) { if((ch!='X')&&(ch!='W')&&(ch!='x')&&(ch!='w')) { s->search_result=0; break; } } } break; case ST_STRING: totaltraces++; if(s->string) if(strstr_i(chval, s->string)) s->search_result=1; break; #endif default: fprintf(stderr, "Internal error: st_type of %d\n",s->value); exit(255); } free_2(chval); } s=s->next; } if((maxbasefintim)) return; #ifdef DEBUG_PRINTF DEBUG(printf("Maxbase: "TTFormat", total traces: %d\n",maxbase, totaltraces)); s=s_head; passcount=0; while(s) { DEBUG(printf("\tPass: %d, Name: %s\n",s->search_result, s->trace->name)); if(s->search_result) passcount++; s=s->next; } #endif if(totaltraces) { break; } basetime=maxbase; } GLOBALS->tims.marker=maxbase; if(is_last_iteration) { update_markertime(GLOBALS->tims.marker); width=(TimeType)(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx); if((GLOBALS->tims.markertims.start)||(GLOBALS->tims.marker>=GLOBALS->tims.start+width)) { if((GLOBALS->tims.marker<0)||(GLOBALS->tims.markertims.first)||(GLOBALS->tims.marker>GLOBALS->tims.last)) { if(GLOBALS->tims.end>GLOBALS->tims.last) GLOBALS->tims.end=GLOBALS->tims.last; middle=(GLOBALS->tims.start/2)+(GLOBALS->tims.end/2); if((GLOBALS->tims.start&1)&&(GLOBALS->tims.end&1)) middle++; } else { middle=GLOBALS->tims.marker; } GLOBALS->tims.start=time_trunc(middle-(width/2)); if(GLOBALS->tims.start+width>GLOBALS->tims.last) GLOBALS->tims.start=GLOBALS->tims.last-width; if(GLOBALS->tims.starttims.first) GLOBALS->tims.start=GLOBALS->tims.first; GTK_ADJUSTMENT(GLOBALS->wave_hslider)->value=GLOBALS->tims.timecache=GLOBALS->tims.start; } MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } void edge_search(int direction) { int i; int i_high_cnt = ((GLOBALS->strace_repeat_count > 0) ? GLOBALS->strace_repeat_count : 1) - 1; for(i=0;i<=i_high_cnt;i++) { edge_search_2(direction, (i == i_high_cnt)); } } /************************************************/ void service_left_edge(GtkWidget *text, gpointer data) { (void)text; (void)data; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nFind Previous Edge"); help_text( " moves the marker to the closest transition to the left of the marker" " of the first highlighted trace. If the marker is not nailed down, it starts from max time." ); return; } edge_search(STRACE_BACKWARD); DEBUG(printf("Edge Left\n")); } void service_right_edge(GtkWidget *text, gpointer data) { (void)text; (void)data; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nFind Next Edge"); help_text( " moves the marker to the closest transition to the right of the marker" " of the first highlighted trace. If the marker is not nailed down, it starts from min time." ); return; } edge_search(STRACE_FORWARD); DEBUG(printf("Edge Right\n")); } /* Create shift buttons */ GtkWidget * create_edge_buttons (void) { GtkWidget *table; GtkWidget *table2; GtkWidget *frame; GtkWidget *main_vbox; GtkWidget *b1; GtkWidget *b2; GtkWidget *pixmapwid1, *pixmapwid2; GtkTooltips *tooltips; tooltips=gtk_tooltips_new_2(); gtk_tooltips_set_delay_2(tooltips,1500); pixmapwid1=gtk_pixmap_new(GLOBALS->larrow_pixmap, GLOBALS->larrow_mask); gtk_widget_show(pixmapwid1); pixmapwid2=gtk_pixmap_new(GLOBALS->rarrow_pixmap, GLOBALS->rarrow_mask); gtk_widget_show(pixmapwid2); /* Create a table to hold the text widget and scrollbars */ table = gtk_table_new (1, 1, FALSE); main_vbox = gtk_vbox_new (FALSE, 1); gtk_container_border_width (GTK_CONTAINER (main_vbox), 1); gtk_container_add (GTK_CONTAINER (table), main_vbox); frame = gtk_frame_new ("Edge "); gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0); gtk_widget_show (frame); gtk_widget_show (main_vbox); table2 = gtk_table_new (2, 1, FALSE); b1 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b1), pixmapwid1); gtk_table_attach (GTK_TABLE (table2), b1, 0, 1, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); gtk_signal_connect_object (GTK_OBJECT (b1), "clicked", GTK_SIGNAL_FUNC(service_left_edge), GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(tooltips, b1, "Find next transition of highlighted trace scanning left", NULL); gtk_widget_show(b1); b2 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b2), pixmapwid2); gtk_table_attach (GTK_TABLE (table2), b2, 0, 1, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); gtk_signal_connect_object (GTK_OBJECT (b2), "clicked", GTK_SIGNAL_FUNC(service_right_edge), GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(tooltips, b2, "Find next transition of highlighted trace scanning right", NULL); gtk_widget_show(b2); gtk_container_add (GTK_CONTAINER (frame), table2); gtk_widget_show(table2); return(table); } gtkwave-3.3.66/src/lx2.h0000664000076400007640000000200112341266475014247 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2003-2010. * * 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. */ #include "globals.h" #ifndef WAVE_LX2RDR_H #define WAVE_LX2RDR_H #ifdef HAVE_INTTYPES_H #include #endif #include "vcd.h" #include "ae2.h" #define F_NAME_MODULUS (3) enum LXT2_Loader_Type_Encodings { LXT2_IS_INACTIVE, LXT2_IS_LXT2, LXT2_IS_VZT, LXT2_IS_AET2, LXT2_IS_VLIST, LXT2_IS_FST, LXT2_IS_FSDB }; #ifdef WAVE_USE_STRUCT_PACKING #pragma pack(push) #pragma pack(1) #endif struct lx2_entry { struct HistEnt *histent_head, *histent_curr; int numtrans; nptr np; }; #ifdef WAVE_USE_STRUCT_PACKING #pragma pack(pop) #endif TimeType lx2_main(char *fname, char *skip_start, char *skip_end); void import_lx2_trace(nptr np); void lx2_set_fac_process_mask(nptr np); void lx2_import_masked(void); #endif gtkwave-3.3.66/src/analyzer.h0000664000076400007640000004350712360312657015402 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2014. * * 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. */ #include "globals.h" #ifndef ANALYZER_H #define ANALYZER_H #include #include #include "wavealloca.h" #include "vlist.h" #include "debug.h" #ifdef AET2_IS_PRESENT #define WAVE_ARRAY_SUPPORT #endif /* struct Node bitfield widths */ #define WAVE_VARXT_WIDTH (16) #define WAVE_VARXT_MAX_ID ((1 << WAVE_VARXT_WIDTH) - 1) #define WAVE_VARDT_WIDTH (6) #define WAVE_VARDIR_WIDTH (3) #define WAVE_VARTYPE_WIDTH (6) typedef struct _SearchProgressData { GtkWidget *window; GtkWidget *pbar; GtkAdjustment *adj; int timer; /* might be used later.. */ gfloat value, oldvalue; } SearchProgressData; #define BITATTRIBUTES_MAX 32768 typedef struct ExpandInfo *eptr; typedef struct ExpandReferences *exptr; typedef struct Node *nptr; typedef struct HistEnt *hptr; typedef struct Bits *bptr; typedef struct VectorEnt *vptr; typedef struct BitVector *bvptr; typedef struct BitAttributes *baptr; typedef unsigned long Ulong; typedef unsigned int Uint; enum TraceReorderMode { TR_SORT_INS, TR_SORT_NORM, TR_SORT_LEX, TR_SORT_RVS }; /* vvv Bit representation vvv */ enum AnalyzerBits { AN_0, AN_X, AN_Z, AN_1, AN_H, AN_U, AN_W, AN_L, AN_DASH, AN_RSV9, AN_RSVA, AN_RSVB, AN_RSVC, AN_RSVD, AN_RSVE, AN_RSVF, AN_COUNT }; #define AN_NORMAL { AN_0, AN_X, AN_Z, AN_1, AN_H, AN_U, AN_W, AN_L, AN_DASH, AN_DASH, AN_DASH, AN_DASH, AN_DASH, AN_DASH, AN_DASH, AN_DASH } #define AN_INVERSE { AN_1, AN_X, AN_Z, AN_0, AN_L, AN_U, AN_W, AN_H, AN_DASH, AN_DASH, AN_DASH, AN_DASH, AN_DASH, AN_DASH, AN_DASH, AN_DASH } #define AN_MSK (AN_COUNT-1) /* max index into AN_STR, AN_COUNT *must* be a power of two unless logic AND with AN_MSK is changed */ /* positional ascii 0123456789ABCDEF, question marks should not happen unless something slips through the cracks as AN_RSVA to AN_RSVF are reserved */ #define AN_STR "0xz1huwl-???????" #define AN_STR_INV "1xz0luwh-???????" #define AN_USTR "0XZ1HUWL-???????" #define AN_USTR_INV "1XZ0LUWH-???????" /* for writing out 4 state formats (read GHW, write LXT) */ #define AN_STR4ST "0xz11xz0xxxxxxxx" #define AN_USTR4ST "0XZ11XZ0XXXXXXXX" /* for hex/oct conversion in baseconvert.c */ #define AN_HEX_STR "0123456789ABCDEFxzwu-XZWU" #define AN_OCT_STR "01234567xzwu-" /* now the recoded "extra" values... */ #define RCV_X (1 | (0<<1)) #define RCV_Z (1 | (1<<1)) #define RCV_H (1 | (2<<1)) #define RCV_U (1 | (3<<1)) #define RCV_W (1 | (4<<1)) #define RCV_L (1 | (5<<1)) #define RCV_D (1 | (6<<1)) #define RCV_STR "xzhuwl-?" /* 01234567 */ /* ^^^ Bit representation ^^^ */ #if (SIZEOF_VOID_P == SIZEOF_DOUBLE) #define WAVE_HAS_H_DOUBLE #endif #ifdef WAVE_USE_STRUCT_PACKING #pragma pack(push) #pragma pack(1) #endif typedef struct HistEnt { hptr next; /* next transition in history */ union { unsigned char h_val; /* value: AN_STR[val] or AnalyzerBits which correspond */ char *h_vector; /* pointer to a whole vector of h_val type bits */ #ifdef WAVE_HAS_H_DOUBLE double h_double; #endif } v; TimeType time; /* time of transition */ unsigned char flags; /* so far only set on glitch/real condition */ } HistEnt; #ifdef WAVE_USE_STRUCT_PACKING #pragma pack(pop) #endif enum HistEntFlagBits { HIST_GLITCH_B, HIST_REAL_B, HIST_STRING_B }; #define HIST_GLITCH (1<name then) */ unsigned is_depacked : 1; /* set when it's been depacked from a compressed entry (safe to free t->name then) */ unsigned vector : 1; /* 1 if bit vector, 0 if node */ unsigned shift_drag_valid : 1; /* qualifies shift_drag above */ unsigned interactive_vector_needs_regeneration : 1; /* for interactive VCDs */ unsigned minmax_valid : 1; /* for d_minval, d_maxval */ unsigned is_sort_group : 1; /* only used for sorting purposes */ unsigned t_filter_converted : 1; /* used to mark that data conversion already occurred if t_filter != 0*/ } TraceEnt; enum TraceEntFlagBits { TR_HIGHLIGHT_B, TR_HEX_B, TR_DEC_B, TR_BIN_B, TR_OCT_B, TR_RJUSTIFY_B, TR_INVERT_B, TR_REVERSE_B, TR_EXCLUDE_B, TR_BLANK_B, TR_SIGNED_B, TR_ASCII_B, TR_COLLAPSED_B, TR_FTRANSLATED_B, TR_PTRANSLATED_B, TR_ANALOG_STEP_B, TR_ANALOG_INTERPOLATED_B, TR_ANALOG_BLANK_STRETCH_B, TR_REAL_B, TR_ANALOG_FULLSCALE_B, TR_ZEROFILL_B, TR_ONEFILL_B, TR_CLOSED_B, TR_GRP_BEGIN_B, TR_GRP_END_B, TR_BINGRAY_B, TR_GRAYBIN_B, TR_REAL2BITS_B, TR_TTRANSLATED_B, TR_POPCNT_B }; #define TR_HIGHLIGHT (1<flags&TR_HIGHLIGHT) #define IsGroupBegin(t) (t->flags&TR_GRP_BEGIN) #define IsGroupEnd(t) (t->flags&TR_GRP_END) #define IsClosed(t) (t->flags&TR_CLOSED) #define HasWave(t) (!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH))) #define CanAlias(t) HasWave(t) #define HasAlias(t) (t->name_full&&HasWave(t)) #define IsCollapsed(t) (t->flags&TR_COLLAPSED) unsigned IsShadowed(Trptr t); char* GetFullName(Trptr t, int *was_packed); void OpenTrace(Trptr t); void CloseTrace(Trptr t); void ClearTraces(void); void ClearGroupTraces(Trptr t); #endif gtkwave-3.3.66/src/tcl_helper.h0000664000076400007640000000522312341266475015674 0ustar bybellbybell/* * Copyright (c) Tony Bybell and Concept Engineering GmbH 2008-2009. * * 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. */ #ifndef WAVE_TCLHELPER_H #define WAVE_TCLHELPER_H #include #include "tcl_callbacks.h" #ifdef HAVE_LIBTCL #include #include #include "debug.h" #define WAVE_TCL_CHECK_VERSION(major,minor,micro) \ (TCL_MAJOR_VERSION > (major) || \ (TCL_MAJOR_VERSION == (major) && TCL_MINOR_VERSION > (minor)) || \ (TCL_MAJOR_VERSION == (major) && TCL_MINOR_VERSION == (minor) && \ TCL_RELEASE_SERIAL >= (micro))) typedef struct { const char *cmdstr; int (*func)(); } tcl_cmdstruct; extern tcl_cmdstruct gtkwave_commands[]; #endif #define WAVE_OE_ME \ if(one_entry) \ { \ if(!mult_entry) \ { \ mult_entry = one_entry; \ mult_len = strlen(mult_entry); \ } \ else \ { \ int sing_len = strlen(one_entry); \ mult_entry = realloc_2(mult_entry, mult_len + sing_len + 1); \ strcpy(mult_entry + mult_len, one_entry); \ mult_len += sing_len; \ } \ } struct iter_dnd_strings { char *one_entry; char *mult_entry; int mult_len; }; typedef enum {LL_NONE, LL_INT, LL_UINT, LL_CHAR, LL_SHORT, LL_STR, LL_VOID_P, LL_TIMETYPE} ll_elem_type; typedef union llist_payload { int i ; unsigned int u ; char c ; short s ; char *str ; void *p ; TimeType tt ; } llist_u; typedef struct llist_s { llist_u u; struct llist_s *prev ; struct llist_s *next ; } llist_p ; int process_url_file(char *s); int process_url_list(char *s); int process_tcl_list(char *s, gboolean track_mouse_y); char *add_dnd_from_searchbox(void); char *add_dnd_from_signal_window(void); char *add_traces_from_signal_window(gboolean is_from_tcl_command); char *add_dnd_from_tree_window(void); char *emit_gtkwave_savefile_formatted_entries_in_tcl_list(Trptr trhead, gboolean use_tcl_mode); char* zMergeTclList(int argc, const char** argv); char** zSplitTclList(const char* list, int* argcPtr); char *make_single_tcl_list_name(char *s, char *opt_value, int promote_to_bus, int preserve_range); void make_tcl_interpreter(char *argv[]); const char *gtkwavetcl_setvar(const char *name1, const char *val, int flags); const char *gtkwavetcl_setvar_nonblocking(const char *name1, const char *val, int flags); char *rpc_script_execute(const char *nam); #ifdef HAVE_LIBTCL int gtkwaveInterpreterInit (Tcl_Interp *interp); void set_globals_interp(char *me, int install_tk); #endif #endif gtkwave-3.3.66/src/menu.c0000664000076400007640000071421412542115425014510 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2014. * * 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. */ /* * note: any functions which add/remove traces must first look at * the global "straces". if it's active, complain to the status * window and don't do the op. same for "dnd_state". */ #include "globals.h" #include #include #include "gtk12compat.h" #include "main.h" #include "menu.h" #include "vcd.h" #include "vcd_saver.h" #include "translate.h" #include "ptranslate.h" #include "ttranslate.h" #include "lx2.h" #include "hierpack.h" #include "tcl_helper.h" #include #include #if !defined __MINGW32__ && !defined _MSC_VER #include #include #else #include #include #endif #ifdef _MSC_VER #define strcasecmp _stricmp #endif #undef WAVE_USE_MENU_BLACKOUTS static gtkwave_mlist_t menu_items[WV_MENU_NUMITEMS]; #ifdef WAVE_USE_MLIST_T static GtkWidget **menu_wlist=NULL; #endif extern char *gtkwave_argv0_cached; /* for new window */ /* marshals for handling menu items vs button pressed items */ static void service_left_edge_marshal(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)callback_action; service_left_edge(widget, null_data); } static void service_right_edge_marshal(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)callback_action; service_right_edge(widget, null_data); } static void service_zoom_in_marshal(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)callback_action; service_zoom_in(widget, null_data); } static void service_zoom_out_marshal(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)callback_action; service_zoom_out(widget, null_data); } static void service_zoom_full_marshal(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)callback_action; service_zoom_full(widget, null_data); } static void service_zoom_fit_marshal(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)callback_action; service_zoom_fit(widget, null_data); } static void service_zoom_left_marshal(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)callback_action; service_zoom_left(widget, null_data); } static void service_zoom_right_marshal(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)callback_action; service_zoom_right(widget, null_data); } static void service_zoom_undo_marshal(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)callback_action; service_zoom_undo(widget, null_data); } static void fetch_right_marshal(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)callback_action; fetch_right(widget, null_data); } static void fetch_left_marshal(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)callback_action; fetch_left(widget, null_data); } static void discard_right_marshal(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)callback_action; discard_right(widget, null_data); } static void discard_left_marshal(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)callback_action; discard_left(widget, null_data); } static void service_right_shift_marshal(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)callback_action; service_right_shift(widget, null_data); } static void service_left_shift_marshal(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)callback_action; service_left_shift(widget, null_data); } static void service_right_page_marshal(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)callback_action; service_right_page(widget, null_data); } static void service_left_page_marshal(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)callback_action; service_left_page(widget, null_data); } /* ruler */ static void menu_def_ruler(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nDefine Time Ruler Marks"); help_text( " changes the ruler markings such that the Baseline marker" " defines the origin and the Primary marker distance from" " the Baseline marker defines the period. If either the" " Baseline marker or Primary marker are not present, the" " default ruler markers are used. If the Baseline marker" " and Primary marker have the same value, the default ruler" " markers are used." ); return; } if((GLOBALS->tims.baseline>=0) && (GLOBALS->tims.marker>=0)) { GLOBALS->ruler_origin = GLOBALS->tims.baseline; GLOBALS->ruler_step = GLOBALS->tims.baseline - GLOBALS->tims.marker; if(GLOBALS->ruler_step < 0) GLOBALS->ruler_step = -GLOBALS->ruler_step; } else { GLOBALS->ruler_origin = GLOBALS->ruler_step = LLDescriptor(0); } GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } /* marker locking */ static void lock_marker_left(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; int ent_idx = GLOBALS->named_marker_lock_idx; int i; int success = 0; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nLock to Lesser Named Marker"); help_text( " locks the primary marker to a named marker." " If no named marker is currently selected, the last defined one is used," " otherwise the marker selected will be one lower in the alphabet, scrolling" " through to the end of the alphabet on wrap." " If no named marker exists, one is dropped down for 'A' and the primary" " marker is locked to it." ); return; } if(ent_idx < 0) ent_idx = WAVE_NUM_NAMED_MARKERS; ent_idx--; if(ent_idx < 0) ent_idx = WAVE_NUM_NAMED_MARKERS-1; for(i=0;inamed_markers[ent_idx] >= 0) { success = 1; break; } ent_idx--; if(ent_idx < 0) ent_idx = WAVE_NUM_NAMED_MARKERS-1; } if(!success) { ent_idx = 0; GLOBALS->named_markers[ent_idx] = GLOBALS->tims.marker; } GLOBALS->named_marker_lock_idx = ent_idx; GLOBALS->tims.marker = GLOBALS->named_markers[ent_idx]; update_markertime(GLOBALS->tims.marker); GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } static void lock_marker_right(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; int ent_idx = GLOBALS->named_marker_lock_idx; int i; int success = 0; if(ent_idx < 0) ent_idx = -1; /* not really necessary */ ent_idx++; if(ent_idx > (WAVE_NUM_NAMED_MARKERS-1)) ent_idx = 0; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nLock to Greater Named Marker"); help_text( " locks the primary marker to a named marker." " If no named marker is currently selected, the first defined one is used," " otherwise the marker selected will be one higher in the alphabet, scrolling" " through to the beginning of the alphabet on wrap." " If no named marker exists, one is dropped down for 'A' and the primary" " marker is locked to it." ); return; } for(i=0;inamed_markers[ent_idx] >= 0) { success = 1; break; } ent_idx++; if(ent_idx > (WAVE_NUM_NAMED_MARKERS-1)) ent_idx = 0; } if(!success) { ent_idx = 0; GLOBALS->named_markers[ent_idx] = GLOBALS->tims.marker; } GLOBALS->named_marker_lock_idx = ent_idx; GLOBALS->tims.marker = GLOBALS->named_markers[ent_idx]; update_markertime(GLOBALS->tims.marker); GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } static void unlock_marker(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nUnlock from Named Marker"); help_text( " unlocks the primary marker from the currently selected named marker." ); return; } GLOBALS->named_marker_lock_idx = -1; GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } /* toggles for time dimension conversion */ #ifdef WAVE_USE_MLIST_T void menu_scale_to_td_x(GtkWidget *widget, gpointer data) { (void)widget; (void)data; #else void menu_scale_to_td_x(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; #endif if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nScale To Time Dimension: None"); help_text( " turns off time dimension conversion." ); } else { #ifdef WAVE_USE_MLIST_T if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) #endif { GLOBALS->scale_to_time_dimension = 0; set_scale_to_time_dimension_toggles(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } } #ifdef WAVE_USE_MLIST_T void menu_scale_to_td_s(GtkWidget *widget, gpointer data) { (void)widget; (void)data; #else void menu_scale_to_td_s(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; #endif if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nScale To Time Dimension: sec"); help_text( " changes the time dimension conversion value to seconds." ); } else { #ifdef WAVE_USE_MLIST_T if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) #endif { GLOBALS->scale_to_time_dimension = 's'; set_scale_to_time_dimension_toggles(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } } #ifdef WAVE_USE_MLIST_T void menu_scale_to_td_m(GtkWidget *widget, gpointer data) { (void)widget; (void)data; #else void menu_scale_to_td_m(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; #endif if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nScale To Time Dimension: ms"); help_text( " changes the time dimension conversion value to milliseconds." ); } else { #ifdef WAVE_USE_MLIST_T if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) #endif { GLOBALS->scale_to_time_dimension = 'm'; set_scale_to_time_dimension_toggles(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } } #ifdef WAVE_USE_MLIST_T void menu_scale_to_td_u(GtkWidget *widget, gpointer data) { (void)widget; (void)data; #else void menu_scale_to_td_u(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; #endif if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nScale To Time Dimension: us"); help_text( " changes the time dimension conversion value to microseconds." ); } else { #ifdef WAVE_USE_MLIST_T if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) #endif { GLOBALS->scale_to_time_dimension = 'u'; set_scale_to_time_dimension_toggles(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } } #ifdef WAVE_USE_MLIST_T void menu_scale_to_td_n(GtkWidget *widget, gpointer data) { (void)widget; (void)data; #else void menu_scale_to_td_n(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; #endif if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nScale To Time Dimension: ns"); help_text( " changes the time dimension conversion value to nanoseconds." ); } else { #ifdef WAVE_USE_MLIST_T if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) #endif { GLOBALS->scale_to_time_dimension = 'n'; set_scale_to_time_dimension_toggles(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } } #ifdef WAVE_USE_MLIST_T void menu_scale_to_td_p(GtkWidget *widget, gpointer data) { (void)widget; (void)data; #else void menu_scale_to_td_p(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; #endif if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nScale To Time Dimension: ps"); help_text( " changes the time dimension conversion value to picoseconds." ); } else { #ifdef WAVE_USE_MLIST_T if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) #endif { GLOBALS->scale_to_time_dimension = 'p'; set_scale_to_time_dimension_toggles(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } } #ifdef WAVE_USE_MLIST_T void menu_scale_to_td_f(GtkWidget *widget, gpointer data) { (void)widget; (void)data; #else void menu_scale_to_td_f(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; #endif if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nScale To Time Dimension: fs"); help_text( " changes the time dimension conversion value to femtoseconds." ); } else { #ifdef WAVE_USE_MLIST_T if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) #endif { GLOBALS->scale_to_time_dimension = 'f'; set_scale_to_time_dimension_toggles(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } } /********** transaction procsel filter install ********/ void menu_dataformat_xlate_ttrans_1(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nTransaction Filter Process"); help_text( " will enable transaction filtering on marked traces using a filter process. A requester will appear to get the filter filename." ); return; } ttrans_searchbox("Select Transaction Filter Process"); } void menu_dataformat_xlate_ttrans_0(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nTransaction Filter Process Disable"); help_text( " will remove transaction filtering." ); return; } install_ttrans_filter(0); /* disable, 0 is always NULL */ } /********** procsel filter install ********/ void menu_dataformat_xlate_proc_1(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nTranslate Filter Process"); help_text( " will enable translation on marked traces using a filter process. A requester will appear to get the filter filename." ); return; } ptrans_searchbox("Select Signal Filter Process"); } void menu_dataformat_xlate_proc_0(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nTranslate Filter Process Disable"); help_text( " will remove translation filtering used to reconstruct" " enums for marked traces." ); return; } install_proc_filter(0); /* disable, 0 is always NULL */ } /********** filesel filter install ********/ void menu_dataformat_xlate_file_1(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nTranslate Filter File"); help_text( " will enable translation on marked traces using a filter file. A requester will appear to get the filter filename." ); return; } trans_searchbox("Select Signal Filter"); } void menu_dataformat_xlate_file_0(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nTranslate Filter File Disable"); help_text( " will remove translation filtering used to reconstruct" " enums for marked traces." ); return; } install_file_filter(0); /* disable, 0 is always NULL */ } /******************************************************************/ void menu_write_lxt_file_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; int rc; if(!GLOBALS->filesel_ok) { return; } if(GLOBALS->lock_menu_c_1 == 1) return; /* avoid recursion */ GLOBALS->lock_menu_c_1 = 1; status_text("Saving LXT...\n"); gtkwave_main_iteration(); /* make requester disappear requester */ rc = save_nodes_to_export(*GLOBALS->fileselbox_text, WAVE_EXPORT_LXT); GLOBALS->lock_menu_c_1 = 0; switch(rc) { case VCDSAV_EMPTY: status_text("No traces onscreen to save!\n"); break; case VCDSAV_FILE_ERROR: status_text("Problem writing LXT: "); status_text(strerror(errno)); break; case VCDSAV_OK: status_text("LXT written successfully.\n"); default: break; } } void menu_write_lxt_file(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nWrite LXT File As"); help_text( " will open a file requester that will ask for the name" " of an LXT dumpfile. The contents of the dumpfile" " generated will be the vcd representation of the traces onscreen" " that can be seen by manipulating the signal and wavewindow scrollbars." " The data saved corresponds to the trace information needed" " to allow viewing when used in tandem with the corresponding GTKWave save file." ); return; } if(GLOBALS->traces.first) { if((GLOBALS->is_ghw)&&(0)) { status_text("LXT export not supported for GHW.\n"); } else { fileselbox("Write LXT File As",&GLOBALS->filesel_lxt_writesave,GTK_SIGNAL_FUNC(menu_write_lxt_file_cleanup), GTK_SIGNAL_FUNC(NULL),"*.lxt", 1); } } else { status_text("No traces onscreen to save!\n"); } } /******************************************************************/ void menu_write_vcd_file_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; int rc; if(!GLOBALS->filesel_ok) { return; } if(GLOBALS->lock_menu_c_2 == 1) return; /* avoid recursion */ GLOBALS->lock_menu_c_2 = 1; status_text("Saving VCD...\n"); gtkwave_main_iteration(); /* make requester disappear requester */ rc = save_nodes_to_export(*GLOBALS->fileselbox_text, WAVE_EXPORT_VCD); GLOBALS->lock_menu_c_2 = 0; switch(rc) { case VCDSAV_EMPTY: status_text("No traces onscreen to save!\n"); break; case VCDSAV_FILE_ERROR: status_text("Problem writing VCD: "); status_text(strerror(errno)); break; case VCDSAV_OK: status_text("VCD written successfully.\n"); default: break; } } void menu_write_vcd_file(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nWrite VCD File As"); help_text( " will open a file requester that will ask for the name" " of a VCD dumpfile. The contents of the dumpfile" " generated will be the vcd representation of the traces onscreen" " that can be seen by manipulating the signal and wavewindow scrollbars." " The data saved corresponds to the trace information needed" " to allow viewing when used in tandem with the corresponding GTKWave save file." ); return; } if(GLOBALS->traces.first) { fileselbox("Write VCD File As",&GLOBALS->filesel_vcd_writesave,GTK_SIGNAL_FUNC(menu_write_vcd_file_cleanup), GTK_SIGNAL_FUNC(NULL),"*.vcd", 1); } else { status_text("No traces onscreen to save!\n"); } } /******************************************************************/ void menu_write_tim_file_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; int rc; if(!GLOBALS->filesel_ok) { return; } if(GLOBALS->lock_menu_c_2 == 1) return; /* avoid recursion */ GLOBALS->lock_menu_c_2 = 1; status_text("Saving TIM...\n"); gtkwave_main_iteration(); /* make requester disappear requester */ rc = save_nodes_to_export(*GLOBALS->fileselbox_text, WAVE_EXPORT_TIM); GLOBALS->lock_menu_c_2 = 0; switch(rc) { case VCDSAV_EMPTY: status_text("No traces onscreen to save!\n"); break; case VCDSAV_FILE_ERROR: status_text("Problem writing TIM: "); status_text(strerror(errno)); break; case VCDSAV_OK: status_text("TIM written successfully.\n"); default: break; } } void menu_write_tim_file(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nWrite TIM File As"); help_text( " will open a file requester that will ask for the name" " of a TimingAnalyzer .tim file. The contents of the file" " generated will be the representation of the traces onscreen." " If the baseline and primary marker are set, the time range" " written to the file will be between the two markers, otherwise" " it will be the entire time range." ); return; } if(GLOBALS->traces.first) { fileselbox("Write TIM File As",&GLOBALS->filesel_tim_writesave,GTK_SIGNAL_FUNC(menu_write_tim_file_cleanup), GTK_SIGNAL_FUNC(NULL),"*.tim", 1); } else { status_text("No traces onscreen to save!\n"); } } /******************************************************************/ void menu_unwarp_traces_all(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; Trptr t; int found=0; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nUnwarp All"); help_text( " unconditionally removes all offsets on all traces." ); return; } t=GLOBALS->traces.first; while(t) { if(t->shift) { t->shift=LLDescriptor(0); found++; } t=t->t_next; } if(found) { GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } void menu_unwarp_traces(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; Trptr t; int found=0; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nUnwarp Marked"); help_text( " removes all offsets on all highlighted traces." ); return; } t=GLOBALS->traces.first; while(t) { if(t->flags&TR_HIGHLIGHT) { t->shift=LLDescriptor(0); t->flags&=(~TR_HIGHLIGHT); found++; } t=t->t_next; } if(found) { GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } void warp_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; if(GLOBALS->entrybox_text) { TimeType gt, delta; Trptr t; gt=unformat_time(GLOBALS->entrybox_text, GLOBALS->time_dimension); free_2(GLOBALS->entrybox_text); GLOBALS->entrybox_text=NULL; if(gt<0) { delta=GLOBALS->tims.first-GLOBALS->tims.last; if(gt0) { delta=GLOBALS->tims.last-GLOBALS->tims.first; if(gt>delta) gt=delta; } t=GLOBALS->traces.first; while(t) { if(t->flags&TR_HIGHLIGHT) { if(HasWave(t)) /* though note if a user specifies comment warping in a .sav file we will honor it.. */ { t->shift=gt; } else { t->shift=LLDescriptor(0); } t->flags&=(~TR_HIGHLIGHT); } t=t->t_next; } } GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } void menu_warp_traces(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; char gt[32]; Trptr t; int found=0; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nWarp Marked"); help_text( " offsets all highlighted traces by the amount of" " time entered in the requester. (Positive values" " will shift traces to the right.)" " Attempting to shift greater than the absolute value of total simulation" " time will cap the shift magnitude at the length of simulation." " Note that you can also warp traces dynamically by holding" " down CTRL and dragging a group of highlighted traces to" " the left or right with the left mouse button pressed. When you release" " the mouse button, if CTRL is pressed, the drag warp commits, else" " it reverts to its pre-drag condition." ); return; } t=GLOBALS->traces.first; while(t) { if(t->flags&TR_HIGHLIGHT) { found++; break; } t=t->t_next; } if(found) { reformat_time(gt, LLDescriptor(0), GLOBALS->time_dimension); entrybox("Warp Traces",200,gt,NULL,20,GTK_SIGNAL_FUNC(warp_cleanup)); } } void menu_altwheel(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nAlternate Wheel Mode"); help_text( " makes the mouse wheel act how TomB expects it to." " Wheel alone will pan part of a page (so you can still" " see where you were). Ctrl+Wheel will zoom around the" " cursor (not where the marker is), and Alt+Wheel will" " edge left or right on the selected signal."); } else { #ifndef WAVE_USE_MLIST_T if(!GLOBALS->alt_wheel_mode) { status_text("Alternate Wheel Mode On.\n"); GLOBALS->alt_wheel_mode=1; } else { status_text("Alternate Wheel Mode Off.\n"); GLOBALS->alt_wheel_mode=0; } #else GLOBALS->alt_wheel_mode = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_HSWM])); if(GLOBALS->alt_wheel_mode) { status_text("Alternate Wheel Mode On.\n"); } else { status_text("Alternate Wheel Mode Off.\n"); } #endif } #ifndef WAVE_USE_MLIST_T GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_HSWM].path))->active=(GLOBALS->alt_wheel_mode)?TRUE:FALSE; #endif } void wave_scrolling_on(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nWave Scrolling"); help_text( " allows movement of the primary marker beyond screen boundaries" " which causes the wave window to scroll when enabled." " When disabled, it" " disallows movement of the primary marker beyond screen boundaries." ); } else { #ifndef WAVE_USE_MLIST_T if(!GLOBALS->wave_scrolling) { status_text("Wave Scrolling On.\n"); GLOBALS->wave_scrolling=1; } else { status_text("Wave Scrolling Off.\n"); GLOBALS->wave_scrolling=0; } #else GLOBALS->wave_scrolling = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_MWSON])); if(GLOBALS->wave_scrolling) { status_text("Wave Scrolling On.\n"); } else { status_text("Wave Scrolling Off.\n"); } #endif } #ifndef WAVE_USE_MLIST_T GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_MWSON].path))->active=(GLOBALS->wave_scrolling)?TRUE:FALSE; #endif } /**/ void menu_keep_xz_colors(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nKeep xz Colors"); help_text( " when enabled" " keeps the old non 0/1 signal value colors when a user specifies a color override" " by using Edit/Color Format." ); } else { #ifndef WAVE_USE_MLIST_T if(!GLOBALS->keep_xz_colors) { GLOBALS->keep_xz_colors=1; } else { GLOBALS->keep_xz_colors=0; } #else GLOBALS->keep_xz_colors = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_KEEPXZ])); #endif } #ifndef WAVE_USE_MLIST_T GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_KEEPXZ].path))->active=(GLOBALS->keep_xz_colors)?TRUE:FALSE; #endif GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } /**/ void menu_autocoalesce(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nAutocoalesce"); help_text( " when enabled" " allows the wave viewer to reconstruct split vectors." " Split vectors will be indicated by a \"[]\"" " prefix in the search requesters." ); } else { #ifndef WAVE_USE_MLIST_T if(!GLOBALS->autocoalesce) { status_text("Autocoalesce On.\n"); GLOBALS->autocoalesce=1; } else { status_text("Autocoalesce Off.\n"); GLOBALS->autocoalesce=0; } #else GLOBALS->autocoalesce = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_ACOL])); if(GLOBALS->autocoalesce) { status_text("Autocoalesce On.\n"); } else { status_text("Autocoalesce Off.\n"); } #endif } #ifndef WAVE_USE_MLIST_T GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_ACOL].path))->active=(GLOBALS->autocoalesce)?TRUE:FALSE; #endif } void menu_autocoalesce_reversal(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nAutocoalesce Reversal"); help_text( " causes split vectors to be reconstructed in reverse order (only if autocoalesce is also active). This is necessary with some simulators." " Split vectors will be indicated by a \"[]\"" " prefix in the search requesters." ); } else { #ifndef WAVE_USE_MLIST_T if(!GLOBALS->autocoalesce_reversal) { status_text("Autocoalesce Rvs On.\n"); GLOBALS->autocoalesce_reversal=1; } else { status_text("Autocoalesce Rvs Off.\n"); GLOBALS->autocoalesce_reversal=0; } #else GLOBALS->autocoalesce_reversal = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_ACOLR])); if(GLOBALS->autocoalesce_reversal) { status_text("Autocoalesce Rvs On.\n"); } else { status_text("Autocoalesce Rvs Off.\n"); } #endif } #ifndef WAVE_USE_MLIST_T GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_ACOLR].path))->active=(GLOBALS->autocoalesce_reversal)?TRUE:FALSE; #endif } void menu_autoname_bundles_on(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nAutoname Bundles"); help_text( " when enabled" " modifies the bundle up/down operations in the hierarchy" " and tree searches such that a NULL bundle name is" " implicitly created which informs GTKWave to create bundle" " and signal names based on the position in the hierarchy." " When disabled, it" " modifies the bundle up/down operations in the hierarchy" " and tree searches such that a NULL bundle name is" " not implicitly created. This informs GTKWave to create bundle" " and signal names based on the position in the hierarchy" " only if the user enters a zero-length bundle name. This" " behavior is the default." ); } else { #ifndef WAVE_USE_MLIST_T if(!GLOBALS->autoname_bundles) { status_text("Autoname On.\n"); GLOBALS->autoname_bundles=1; } else { status_text("Autoname Off.\n"); GLOBALS->autoname_bundles=0; } #else GLOBALS->autoname_bundles = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_ABON])); if(GLOBALS->autoname_bundles) { status_text("Autoname On.\n"); } else { status_text("Autoname Off.\n"); } #endif } #ifndef WAVE_USE_MLIST_T GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_ABON].path))->active=(GLOBALS->autoname_bundles)?TRUE:FALSE; #endif } void menu_hgrouping(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nSearch Hierarchy Grouping"); help_text( " when enabled ensures that new members added to the ``Tree Search'' and" " ``Hierarchy Search'' widgets are added alphanumerically: first hierarchy names as a group followed by signal names as a group." " This is the default and is recommended. When disabled, hierarchy names and signal names are interleaved together in" " strict alphanumerical ordering." " Note that due to the caching mechanism in ``Tree Search'', dynamically changing this flag when the widget is active" " may not produce immediately obvious results. Closing the widget then opening it up again will ensure that it follows the" " behavior of this flag." ); } else { #ifndef WAVE_USE_MLIST_T if(!GLOBALS->hier_grouping) { status_text("Hier Grouping On.\n"); GLOBALS->hier_grouping=1; } else { status_text("Hier Grouping Off.\n"); GLOBALS->hier_grouping=0; } #else GLOBALS->hier_grouping = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_HTGP])); if(GLOBALS->hier_grouping) { status_text("Hier Grouping On.\n"); } else { status_text("Hier Grouping Off.\n"); } #endif } #ifndef WAVE_USE_MLIST_T GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_HTGP].path))->active=(GLOBALS->hier_grouping)?TRUE:FALSE; #endif } void set_hier_cleanup(GtkWidget *widget, gpointer data, int level) { (void)widget; (void)data; char update_string[128]; Trptr t; int i; GLOBALS->hier_max_level=level; if(GLOBALS->hier_max_level<0) GLOBALS->hier_max_level=0; for(i=0;i<2;i++) { if(i==0) t=GLOBALS->traces.first; else t=GLOBALS->traces.buffer; while(t) { if(!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH))) { if (HasAlias(t)) { t->name = t->name_full; if(GLOBALS->hier_max_level) t->name = hier_extract(t->name, GLOBALS->hier_max_level); } else if(t->vector==TRUE) { t->name = t->n.vec->bvname; if(GLOBALS->hier_max_level) t->name = hier_extract(t->name, GLOBALS->hier_max_level); } else { if(!GLOBALS->hier_max_level) { int flagged = HIER_DEPACK_ALLOC; if(t->name&&t->is_depacked) { free_2(t->name); } t->name = hier_decompress_flagged(t->n.nd->nname, &flagged); t->is_depacked = (flagged != 0); } else { int flagged = HIER_DEPACK_ALLOC; char *tbuff; if(t->name&&t->is_depacked) { free_2(t->name); } tbuff = hier_decompress_flagged(t->n.nd->nname, &flagged); t->is_depacked = (flagged != 0); if(!flagged) { t->name = hier_extract(t->n.nd->nname, GLOBALS->hier_max_level); } else { t->name = strdup_2(hier_extract(tbuff, GLOBALS->hier_max_level)); free_2(tbuff); } } } } t=t->t_next; } } GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); sprintf(update_string, "Trace Hier Max Depth is now: %d\n", GLOBALS->hier_max_level); status_text(update_string); } void max_hier_cleanup(GtkWidget *widget, gpointer data) { if(GLOBALS->entrybox_text) { int i; i = atoi_64(GLOBALS->entrybox_text); set_hier_cleanup(widget, data, i); GLOBALS->hier_max_level_shadow = GLOBALS->hier_max_level; /* used for the toggle function */ free_2(GLOBALS->entrybox_text); GLOBALS->entrybox_text=NULL; } } void menu_set_max_hier(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; char za[32]; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nSet Max Hier"); help_text( " sets the maximum hierarchy depth (counting from the right" " with bit numbers or ranges ignored) that is displayable" " for trace names. Zero indicates that no truncation will" " be performed (default). Note that any aliased signals" " (prefix of a \"+\") will not have truncated names." ); return; } sprintf(za,"%d",GLOBALS->hier_max_level); entrybox("Max Hier Depth",200,za,NULL,20,GTK_SIGNAL_FUNC(max_hier_cleanup)); } void menu_toggle_hier(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)callback_action; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nToggle Trace Hier"); help_text( " toggles the maximum hierarchy depth from zero to whatever was previously set." ); return; } if (GLOBALS->hier_max_level) set_hier_cleanup(widget, null_data, 0); else set_hier_cleanup(widget, null_data, GLOBALS->hier_max_level_shadow); /* instead of just '1' */ } /**/ void menu_use_roundcaps(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nDraw Roundcapped Vectors"); help_text( " draws vector transitions that have sloping edges when enabled." " Draws vector transitions that have sharp edges when disabled;" " this is the default." ); } else { #ifndef WAVE_USE_MLIST_T if(!GLOBALS->use_roundcaps) { status_text("Using roundcaps.\n"); GLOBALS->use_roundcaps=1; } else { status_text("Using flatcaps.\n"); GLOBALS->use_roundcaps=0; } MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); #else GLOBALS->use_roundcaps = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VDRV])); if(GLOBALS->use_roundcaps) { status_text("Using roundcaps.\n"); } else { status_text("Using flatcaps.\n"); } if(GLOBALS->signalarea && GLOBALS->wavearea) { MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } #endif } #ifndef WAVE_USE_MLIST_T GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VDRV].path))->active=(GLOBALS->use_roundcaps)?TRUE:FALSE; #endif } /**/ void menu_lxt_clk_compress(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nLXT Clock Compress to Z"); help_text( " reduces memory usage when active as clocks compressed in LXT format are" " kept at Z in order to save memory. Traces imported with this are permanently" " kept at Z." ); } else { #ifndef WAVE_USE_MLIST_T if(GLOBALS->lxt_clock_compress_to_z) { GLOBALS->lxt_clock_compress_to_z=0; status_text("LXT CC2Z Off.\n"); } else { GLOBALS->lxt_clock_compress_to_z=1; status_text("LXT CC2Z On.\n"); } #else GLOBALS->lxt_clock_compress_to_z = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_LXTCC2Z])); if(!GLOBALS->lxt_clock_compress_to_z) { status_text("LXT CC2Z Off.\n"); } else { status_text("LXT CC2Z On.\n"); } #endif } #ifndef WAVE_USE_MLIST_T if(GLOBALS->loaded_file_type == LXT_FILE) { GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_LXTCC2Z].path))->active=(GLOBALS->lxt_clock_compress_to_z)?TRUE:FALSE; } #endif } /**/ void menu_use_full_precision(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nFull Precision"); help_text( " does not round time values when the number of ticks per pixel onscreen is greater than" " 10 when active. The default is that this feature is disabled." ); } else { #ifndef WAVE_USE_MLIST_T if(GLOBALS->use_full_precision) { GLOBALS->use_full_precision=0; status_text("Full Prec Off.\n"); } else { GLOBALS->use_full_precision=1; status_text("Full Prec On.\n"); } #else GLOBALS->use_full_precision = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VFTP])); if(!GLOBALS->use_full_precision) { status_text("Full Prec Off.\n"); } else { status_text("Full Prec On.\n"); } #endif calczoom(GLOBALS->tims.zoom); fix_wavehadj(); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */ gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed"); /* force zoom update */ update_maxmarker_labels(); } #ifndef WAVE_USE_MLIST_T GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VFTP].path))->active=(GLOBALS->use_full_precision)?TRUE:FALSE; #endif } /**/ void menu_remove_marked(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nRemove Pattern Marks"); help_text( " removes any vertical traces on the display caused by the Mark" " feature in pattern search and reverts to the normal format." ); } else { int i; WAVE_STRACE_ITERATOR(i) { GLOBALS->strace_ctx = &GLOBALS->strace_windows[GLOBALS->strace_current_window = i]; if(GLOBALS->strace_ctx->shadow_straces) { delete_strace_context(); } strace_maketimetrace(0); } MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } /**/ void menu_use_color(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nUse Color"); help_text( " draws signal names and trace data in color. This is normal operation." ); } else { force_normal_gcs(); MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } /**/ void menu_use_bw(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nUse Black and White"); help_text( " draws signal names and trace data in black and white. This is intended for use in" " black and white screen dumps." ); } else { force_screengrab_gcs(); MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } /**/ void menu_zoom10_snap(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nZoom Pow10 Snap"); help_text( " snaps time values to a power of ten boundary when active. Fractional zooms are" " internally stored, but what is actually displayed will be rounded up/down to the" " nearest power of 10. This only works when the ticks per frame is greater than 100" " units." ); } else { #ifndef WAVE_USE_MLIST_T if(GLOBALS->zoom_pow10_snap) { GLOBALS->zoom_pow10_snap=0; status_text("Pow10 Snap Off.\n"); } else { GLOBALS->zoom_pow10_snap=1; status_text("Pow10 Snap On.\n"); } #else GLOBALS->zoom_pow10_snap = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VZPS])); if(!GLOBALS->zoom_pow10_snap) { status_text("Pow10 Snap Off.\n"); } else { status_text("Pow10 Snap On.\n"); } #endif if(GLOBALS->wave_hslider) { calczoom(GLOBALS->tims.zoom); fix_wavehadj(); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */ gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed"); /* force zoom update */ } } #ifndef WAVE_USE_MLIST_T GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VZPS].path))->active=(GLOBALS->zoom_pow10_snap)?TRUE:FALSE; #endif } /**/ void menu_zoom_dynf(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nPartial VCD Dynamic Zoom Full"); help_text( " causes the screen to be in full zoom mode while a VCD file is loading" " incrementally." ); } else { #ifndef WAVE_USE_MLIST_T if(GLOBALS->zoom_dyn) { GLOBALS->zoom_dyn=0; status_text("Dynamic Zoom Full Off.\n"); } else { GLOBALS->zoom_dyn=1; status_text("Dynamic Zoom Full On.\n"); } #else GLOBALS->zoom_dyn = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VZDYN])); if(!GLOBALS->zoom_dyn) { status_text("Dynamic Zoom Full Off.\n"); } else { status_text("Dynamic Zoom Full On.\n"); } #endif } #ifndef WAVE_USE_MLIST_T GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VZDYN].path))->active=(GLOBALS->zoom_dyn)?TRUE:FALSE; #endif } /**/ void menu_zoom_dyne(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nPartial VCD Dynamic Zoom To End"); help_text( " causes the screen to zoom to the end while a VCD file is loading" " incrementally." ); } else { #ifndef WAVE_USE_MLIST_T if(GLOBALS->zoom_dyne) { GLOBALS->zoom_dyne=0; status_text("Dynamic Zoom To End Off.\n"); } else { GLOBALS->zoom_dyne=1; status_text("Dynamic Zoom To End On.\n"); } #else GLOBALS->zoom_dyne = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VZDYNE])); if(!GLOBALS->zoom_dyne) { status_text("Dynamic Zoom To End Off.\n"); } else { status_text("Dynamic Zoom To End On.\n"); } #endif } #ifndef WAVE_USE_MLIST_T GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VZDYNE].path))->active=(GLOBALS->zoom_dyne)?TRUE:FALSE; #endif } /**/ void menu_left_justify(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nLeft Justify Signals"); help_text( " draws signal names flushed to the left border of the signal window." ); } else { status_text("Left Justification.\n"); GLOBALS->left_justify_sigs=~0; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); } } /**/ void menu_right_justify(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nRight Justify Signals"); help_text( " draws signal names flushed to the right (\"equals\") side of the signal window." ); } else { status_text("Right Justification.\n"); GLOBALS->left_justify_sigs=0; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); } } /**/ void menu_enable_constant_marker_update(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nConstant Marker Update"); help_text( " when enabled," " allows GTKWave to dynamically show the changing values of the" " traces under the primary marker while it is being dragged" " across the screen. This works best with dynamic resizing disabled." " When disabled, it" " restricts GTKWave to only update the trace values when the" " left mouse button is initially pressed then again when it is released." " This is the default behavior." ); } else { #ifndef WAVE_USE_MLIST_T if(!GLOBALS->constant_marker_update) { status_text("Constant marker update enabled.\n"); GLOBALS->constant_marker_update=~0; } else { status_text("Constant marker update disabled.\n"); GLOBALS->constant_marker_update=0; } #else GLOBALS->constant_marker_update = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VCMU])); if(GLOBALS->constant_marker_update) { status_text("Constant marker update enabled.\n"); } else { status_text("Constant marker update disabled.\n"); } #endif } #ifndef WAVE_USE_MLIST_T GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VCMU].path))->active=(GLOBALS->constant_marker_update)?TRUE:FALSE; #endif } /**/ void menu_enable_standard_trace_select(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nStandard Trace Select"); help_text( " when enabled," " keeps the currently selected traces from deselecting on mouse button press." " This allows drag and drop to function more smoothly. As this behavior is not" " how GTK normally functions, it is by default disabled." ); } else { #ifndef WAVE_USE_MLIST_T if(!GLOBALS->use_standard_trace_select) { status_text("Standard Trace Select enabled.\n"); GLOBALS->use_standard_trace_select=~0; } else { status_text("Standard Trace Select disabled.\n"); GLOBALS->use_standard_trace_select=0; } #else GLOBALS->use_standard_trace_select = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_ESTS])); if(GLOBALS->use_standard_trace_select) { status_text("Standard Trace Select enabled.\n"); } else { status_text("Standard Trace Select disabled.\n"); } #endif } #ifndef WAVE_USE_MLIST_T GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_ESTS].path))->active=(GLOBALS->use_standard_trace_select)?TRUE:FALSE; #endif } /**/ void menu_enable_dynamic_resize(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nDynamic Resize"); help_text( " allows GTKWave to dynamically resize the signal" " window for you when toggled active. This can be helpful during numerous" " signal additions and/or deletions. This is the default" " behavior." ); } else { #ifndef WAVE_USE_MLIST_T if(!GLOBALS->do_resize_signals) { status_text("Resizing enabled.\n"); GLOBALS->do_resize_signals=~0; } else { status_text("Resizing disabled.\n"); GLOBALS->do_resize_signals=0; } GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); #else GLOBALS->do_resize_signals = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VDR])); if(GLOBALS->do_resize_signals) { status_text("Resizing enabled.\n"); } else { status_text("Resizing disabled.\n"); } if(GLOBALS->signalarea && GLOBALS->wavearea) { GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } #endif } #ifndef WAVE_USE_MLIST_T GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VDR].path))->active=(GLOBALS->do_resize_signals)?TRUE:FALSE; #endif } /**/ void menu_toggle_delta_or_frequency(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nToggle Delta-Frequency"); help_text( " allows you to switch between the delta time and" " frequency display in the upper right corner" " of the main window when measuring distances between markers. Default behavior is that the" " delta time is displayed." ); } else { GLOBALS->use_frequency_delta=(GLOBALS->use_frequency_delta)?0:1; update_maxmarker_labels(); } } /**/ void menu_toggle_max_or_marker(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nToggle Max-Marker"); help_text( " allows you to switch between the maximum time and" " marker time for display in the upper right corner" " of the main window. Default behavior is that the" " maximum time is displayed." ); } else { GLOBALS->use_maxtime_display=(GLOBALS->use_maxtime_display)?0:1; update_maxmarker_labels(); } } /**/ #ifdef MAC_INTEGRATION void menu_help_manual(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nWave User's Guide"); help_text( " opens the PDF file of the GTKWave User's Guide for viewing." ); return; } else { const gchar *bundle_id = gtkosx_application_get_bundle_id(); if(bundle_id) { const gchar *rpath = gtkosx_application_get_resource_path(); const char *suf = "/doc/gtkwave.pdf"; char *pdfpath = NULL; FILE *handle; if(rpath) { pdfpath = (char *)alloca(strlen(rpath) + strlen(suf) + 1); strcpy(pdfpath, rpath); strcat(pdfpath, suf); } if(!pdfpath || !(handle=fopen(pdfpath,"rb"))) { } else { fclose(handle); gtk_open_external_file(pdfpath); return; } } simplereqbox("Wave User's Guide",400,"Could not open PDF!","OK", NULL, NULL, 1); } } #endif /**/ void menu_help(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nWave Help"); help_text( " is already active. It's this window." ); return; } helpbox("Wave Help",480,"Select any main window menu item"); } /**/ void menu_version(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nWave Version"); help_text( " merely brings up a requester which indicates the current" " version of this program." ); return; } simplereqbox("Wave Version",480,WAVE_VERSION_INFO,"OK", NULL, NULL, 0); } /**/ void menu_quit_callback(GtkWidget *widget, gpointer data) { (void)widget; char sstr[32]; if(data) { #ifdef __CYGWIN__ kill_stems_browser(); #endif g_print("Exiting.\n"); sprintf(sstr, "%d", GLOBALS->this_context_page); gtkwavetcl_setvar(WAVE_TCLCB_QUIT_PROGRAM, sstr, WAVE_TCLCB_QUIT_PROGRAM_FLAGS); gtk_exit(0); } } void menu_quit(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nQuit"); help_text( " closes GTKWave and exits immediately." ); return; } if(!GLOBALS->enable_fast_exit) { simplereqbox("Quit Program",300,"Do you really want to quit?","Yes", "No", GTK_SIGNAL_FUNC(menu_quit_callback), 1); } else { menu_quit_callback(NULL, &GLOBALS->enable_fast_exit); /* nonzero dummy arg */ } } /**/ void menu_quit_close_callback(GtkWidget *widget, gpointer dummy_data) { (void)widget; (void)dummy_data; unsigned int i, j=0; unsigned int this_page = GLOBALS->this_context_page; unsigned np = GLOBALS->num_notebook_pages; unsigned int new_page = (this_page != np-1) ? this_page : (this_page-1); GtkWidget *n = GLOBALS->notebook; struct Global *old_g = NULL, *saved_g; char sstr[32]; gboolean is_mf = (GLOBALS->loaded_file_type == MISSING_FILE); sprintf(sstr, "%d", this_page); gtkwavetcl_setvar(WAVE_TCLCB_CLOSE_TAB_NUMBER, sstr, WAVE_TCLCB_CLOSE_TAB_NUMBER_FLAGS); kill_stems_browser_single(GLOBALS); dead_context_sweep(); for(i=0;icontexts)[j] = (*GLOBALS->contexts)[i]; (*GLOBALS->contexts)[j]->this_context_page = j; (*GLOBALS->contexts)[j]->num_notebook_pages--; j++; } else { old_g = (*GLOBALS->contexts)[j]; } } (*GLOBALS->contexts)[j] = old_g; gtk_notebook_set_show_tabs(GTK_NOTEBOOK(n), (np>2)); gtk_notebook_set_show_border(GTK_NOTEBOOK(n), (np>2)); gtk_notebook_remove_page(GTK_NOTEBOOK(n), this_page); gtk_notebook_set_current_page(GTK_NOTEBOOK(n), new_page); set_GLOBALS((*GLOBALS->contexts)[new_page]); saved_g = GLOBALS; gtkwave_main_iteration(); set_GLOBALS(old_g); if(!is_mf) { free_and_destroy_page_context(); } set_GLOBALS(saved_g); /* need to do this if 2 pages -> 1 */ reformat_time(sstr, GLOBALS->tims.first, GLOBALS->time_dimension); gtk_entry_set_text(GTK_ENTRY(GLOBALS->from_entry),sstr); reformat_time(sstr, GLOBALS->tims.last, GLOBALS->time_dimension); gtk_entry_set_text(GTK_ENTRY(GLOBALS->to_entry),sstr); update_maxmarker_labels(); update_basetime(GLOBALS->tims.baseline); gtk_window_set_title(GTK_WINDOW(GLOBALS->mainwindow), GLOBALS->winname); MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } void menu_quit_close(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nClose"); help_text( " immediately closes the current tab if multiple tabs exist or" " exits GTKWave after an additional confirmation" " requester is given the OK to quit." ); return; } if((GLOBALS->num_notebook_pages < 2) && (!GLOBALS->enable_fast_exit)) { simplereqbox("Quit Program",300,"Do you really want to quit?","Yes", "No", GTK_SIGNAL_FUNC(menu_quit_callback), 1); } else { if(GLOBALS->num_notebook_pages < 2) { menu_quit_callback(NULL, &GLOBALS->num_notebook_pages); /* nonzero dummy arg */ } else { menu_quit_close_callback(NULL, NULL); /* dummy arg, not needed to be nonzero */ } } } /**/ void must_sel(void) { status_text("Select one or more traces.\n"); } static void must_sel_nb(void) { status_text("Select one or more nonblank traces.\n"); } static void must_sel_bg(void) { status_text("Select a bundle or group.\n"); } /**/ static void menu_open_group(GtkWidget *widget, gpointer data) { (void)widget; (void)data; Trptr t; unsigned dirty = 0; /* currently only called by toggle menu option, so no help menu text */ if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */ t=GLOBALS->traces.first; while(t) { if((t->flags&TR_HIGHLIGHT)&&(IsGroupBegin(t) || IsGroupEnd(t))) { dirty=1; break; } t=t->t_next; } if(dirty) { OpenTrace(t); GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } else { must_sel_bg(); } } static void menu_close_group(GtkWidget *widget, gpointer data) { (void)widget; (void)data; Trptr t; unsigned dirty = 0; /* currently only called by toggle menu option, so no help menu text */ if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */ t=GLOBALS->traces.first; while(t) { if((t->flags&TR_HIGHLIGHT)&&(IsGroupBegin(t) || IsGroupEnd(t))) { dirty=1; break; } t=t->t_next; } if(dirty) { CloseTrace(t); GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } else { must_sel_bg(); } } static unsigned create_group (char* name, Trptr t_composite) { Trptr t, t_prev, t_begin, t_end; unsigned dirty = 0; if(!name) name = "Group"; /* generate anonymous name */ t=GLOBALS->traces.first; while(t) { if(t->flags&TR_HIGHLIGHT) { dirty=1; break; } t=t->t_next; } if(dirty) { t_prev = t->t_prev; CutBuffer(); if (t_composite) { t_begin = t_composite; t_begin->flags |=TR_GRP_BEGIN; } else { if( (t_begin = (Trptr) calloc_2( 1, sizeof( TraceEnt ))) == NULL ) { fprintf( stderr, "Out of memory, can't add trace.\n"); return(0); } t_begin->flags = (TR_BLANK|TR_GRP_BEGIN); t_begin->name = (char *)malloc_2(1+strlen(name)); strcpy(t_begin->name, name); } GLOBALS->traces.buffer->t_prev = t_begin; t_begin->t_next = GLOBALS->traces.buffer; GLOBALS->traces.buffer = t_begin; GLOBALS->traces.buffercount++; if( (t_end = (Trptr) calloc_2( 1, sizeof( TraceEnt ))) == NULL ) { fprintf( stderr, "Out of memory, can't add trace.\n"); return(0); } t_end->flags = (TR_BLANK|TR_GRP_END); if (t_composite) { /* make the group end trace invisible */ t_end->flags |= TR_COLLAPSED; t_end->name = (char *)malloc_2(1+strlen("group_end")); strcpy(t_end->name, "group_end"); } else { t_end->name = (char *)malloc_2(1+strlen(name)); strcpy(t_end->name, name); } GLOBALS->traces.bufferlast->t_next = t_end; t_end->t_prev = GLOBALS->traces.bufferlast; GLOBALS->traces.bufferlast = t_end; GLOBALS->traces.buffercount++; t_begin->t_match = t_end; t_end->t_match = t_begin; if (t_prev) { t_prev->flags |= TR_HIGHLIGHT; PasteBuffer(); } else { PrependBuffer(); } } return dirty; } static void create_group_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; unsigned dirty = 0; dirty = create_group(GLOBALS->entrybox_text, NULL); if (!dirty) { must_sel_bg(); } else { GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } void menu_create_group(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; Trptr t; unsigned dirty = 0; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nCreate Group"); help_text( " creates a group of traces which may be opened or closed." " It is permitted for groups to be nested." ); return; } t=GLOBALS->traces.first; while(t) { if(t->flags&TR_HIGHLIGHT) { dirty=1; break; } t=t->t_next; } if(dirty) { /* don't mess with sigs when dnd active */ if(GLOBALS->dnd_state) { dnd_error(); return; } entrybox("Create Group",300,"","Enter group name:",128,GTK_SIGNAL_FUNC(create_group_cleanup)); } else { must_sel_bg(); } } static unsigned expand_trace(Trptr t_top) { Trptr t, tmp; int tmpi; unsigned dirty = 0; int color; t = t_top; if(HasWave(t) && !IsGroupBegin(t) && !IsGroupEnd(t)) { FreeCutBuffer(); GLOBALS->traces.buffer=GLOBALS->traces.first; GLOBALS->traces.bufferlast=GLOBALS->traces.last; GLOBALS->traces.buffercount=GLOBALS->traces.total; GLOBALS->traces.first=GLOBALS->traces.last=NULL; GLOBALS->traces.total=0; color = t->t_color; if(t->vector) { bptr bits; int i; Trptr tfix; TimeType otime = t->shift; bits=t->n.vec->bits; if(!(t->flags&TR_REVERSE)) { for(i=0;innbits;i++) { if(bits->nodes[i]->expansion) bits->nodes[i]->expansion->refcnt++; GLOBALS->which_t_color = color; AddNodeTraceReturn(bits->nodes[i],NULL, &tfix); if(bits->attribs) { tfix->shift = otime + bits->attribs[i].shift; } } } else { for(i=(bits->nnbits-1);i>-1;i--) { if(bits->nodes[i]->expansion) bits->nodes[i]->expansion->refcnt++; GLOBALS->which_t_color = color; AddNodeTraceReturn(bits->nodes[i],NULL, &tfix); if(bits->attribs) { tfix->shift = otime + bits->attribs[i].shift; } } } } else { eptr e=ExpandNode(t->n.nd); int i; if(!e) { /* if(t->n.nd->expansion) t->n.nd->expansion->refcnt++; */ /* AddNode(t->n.nd,NULL); */ } else { int dhc_sav = GLOBALS->do_hier_compress; GLOBALS->do_hier_compress = 0; for(i=0;iwidth;i++) { GLOBALS->which_t_color = color; AddNode(e->narray[i], NULL); } GLOBALS->do_hier_compress = dhc_sav; free_2(e->narray); free_2(e); } } tmp=GLOBALS->traces.buffer; GLOBALS->traces.buffer=GLOBALS->traces.first; GLOBALS->traces.first=tmp; tmp=GLOBALS->traces.bufferlast; GLOBALS->traces.bufferlast=GLOBALS->traces.last; GLOBALS->traces.last=tmp; tmpi=GLOBALS->traces.buffercount; GLOBALS->traces.buffercount=GLOBALS->traces.total; GLOBALS->traces.total=tmpi; if (GLOBALS->traces.buffercount > 0) { /* buffer now contains the created signals */ ClearTraces(); if (t_top->t_prev) { t_top->t_prev->flags |= TR_HIGHLIGHT; RemoveTrace(t_top, 0); PasteBuffer(); t_top->t_prev->flags &= ~TR_HIGHLIGHT; } else { RemoveTrace(t_top, 0); PrependBuffer(); } dirty = create_group("unused_2", t_top); } } GLOBALS->which_t_color = 0; return dirty; } void menu_expand(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; Trptr t, t_next; int dirty=0; int j; GtkAdjustment *wadj; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nExpand"); help_text( " decomposes the highlighted signals into their individual bits." " The resulting bits are converted to traces and inserted after the" " last highlighted trace. The original unexpanded traces will" " be placed in the cut buffer." " It will function seemingly randomly" " when used upon real valued single-bit traces." " When used upon multi-bit vectors that contain" " real valued traces, those traces will expand to their normal \"correct\" values," " not individual bits." ); return; } if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */ DEBUG(printf("Expand Traces\n")); t=GLOBALS->traces.first; while(t) { if(IsSelected(t) && HasWave(t)) { t->flags |= TR_COLLAPSED; dirty=1; } t=t->t_next; } if(dirty) { ClearTraces(); t=GLOBALS->traces.first; while(t) { t_next = t->t_next; if(HasWave(t) && (t->flags&TR_COLLAPSED)) { if (!IsGroupBegin(t) && !IsGroupEnd(t)) { expand_trace(t); } else { OpenTrace(t); } } t=t_next; } t=GLOBALS->traces.first; if(t) { t->t_grp = NULL; } /* scan-build */ while(t) { if(HasWave(t) && (t->flags&TR_COLLAPSED)) { t->flags &= ~TR_COLLAPSED; t->flags |= TR_HIGHLIGHT; } updateTraceGroup(t); t=t->t_next; } t=GLOBALS->traces.first; while(t) { if (IsSelected(t)) { break; } t=t->t_next; } j = GetTraceNumber(t); wadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider); if (j < wadj->value) { SetTraceScrollbarRowValue(j, 0); } GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } else { must_sel_nb(); } } void menu_toggle_group(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; Trptr t; unsigned dirty_group = 0; unsigned dirty_signal = 0; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nToggle Group"); help_text( " toggles a group opened or closed." ); return; } if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */ t=GLOBALS->traces.first; while(t) { if((t->flags&TR_HIGHLIGHT)&&(IsGroupBegin(t) || IsGroupEnd(t))) { dirty_group=1; break; } if((t->flags&TR_HIGHLIGHT)&&HasWave(t)) { dirty_signal=1; break; } t=t->t_next; } if(dirty_group) { if(IsClosed(t)) { menu_open_group(widget, null_data); gtkwavetcl_setvar(WAVE_TCLCB_OPEN_TRACE_GROUP, t->name, WAVE_TCLCB_OPEN_TRACE_GROUP_FLAGS); } else { menu_close_group(widget, null_data); gtkwavetcl_setvar(WAVE_TCLCB_CLOSE_TRACE_GROUP, t->name, WAVE_TCLCB_CLOSE_TRACE_GROUP_FLAGS); } return; } if(dirty_signal) { ClearTraces(); t->flags |= TR_HIGHLIGHT; menu_expand(null_data, 0, widget); gtkwavetcl_setvar(WAVE_TCLCB_OPEN_TRACE_GROUP, t->name, WAVE_TCLCB_OPEN_TRACE_GROUP_FLAGS); return; } must_sel_bg(); } static void rename_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; Trptr t = GLOBALS->trace_to_alias_menu_c_1; if(GLOBALS->entrybox_text) { char *efix; /* code to turn '{' and '}' into '[' and ']' */ if(!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH))) { efix=GLOBALS->entrybox_text; while(*efix) { if(*efix=='{') { *efix='['; } if(*efix=='}') { *efix=']'; } efix++; } } if(t->vector) { if(t->name_full) { free_2(t->name_full); t->name_full = NULL; } if (t->n.vec->bvname) { free_2(t->n.vec->bvname); } t->n.vec->bvname = (char *)malloc_2(1+strlen(GLOBALS->entrybox_text)); strcpy(t->n.vec->bvname, GLOBALS->entrybox_text); t->name = t->n.vec->bvname; if(GLOBALS->hier_max_level) t->name = hier_extract(t->name, GLOBALS->hier_max_level); t->flags&= ~TR_HIGHLIGHT; } GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } static void menu_rename(GtkWidget *widget, gpointer data) { (void)widget; (void)data; Trptr t; /* currently only called by various combine menu options, so no help menu text */ GLOBALS->trace_to_alias_menu_c_1=NULL; /* don't mess with sigs when dnd active */ if(GLOBALS->dnd_state) { dnd_error(); return; } t = GLOBALS->traces.first; while(t) { if(IsSelected(t)&&(t->vector==TRUE)) { GLOBALS->trace_to_alias_menu_c_1 = t; break; } t=t->t_next; } if(GLOBALS->trace_to_alias_menu_c_1) { int was_packed = HIER_DEPACK_ALLOC; char* current = GetFullName(GLOBALS->trace_to_alias_menu_c_1, &was_packed); ClearTraces(); GLOBALS->trace_to_alias_menu_c_1->flags |= TR_HIGHLIGHT; entrybox("Trace Name",300,current,NULL,128,GTK_SIGNAL_FUNC(rename_cleanup)); if(was_packed) { free_2(current); } } else { must_sel(); } } bvptr combine_traces(int direction, Trptr single_trace_only) { Trptr t, tmp; int tmpi,dirty=0, attrib_reqd=0; nptr bitblast_parent; int bitblast_delta=0; DEBUG(printf("Combine Traces\n")); t=single_trace_only ? single_trace_only : GLOBALS->traces.first; while(t) { if((t->flags&TR_HIGHLIGHT)&&(!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH)))) { if(t->vector) { dirty+=t->n.vec->nbits; } else { if(t->n.nd->extvals) { int msb, lsb, width; msb = t->n.nd->msi; lsb = t->n.nd->lsi; if(msb>lsb) width = msb-lsb+1; else width = lsb-msb+1; dirty += width; } else { dirty++; } } } if(t == single_trace_only) break; t=t->t_next; } if(!dirty) { if(!single_trace_only) must_sel_nb(); return NULL; } if(dirty>BITATTRIBUTES_MAX) { char buf[128]; if(!single_trace_only) { sprintf(buf, "%d bits selected, please use <= %d.\n", dirty, BITATTRIBUTES_MAX); status_text(buf); } return NULL; } else { int i,nodepnt=0; struct Node *n[BITATTRIBUTES_MAX]; struct BitAttributes ba[BITATTRIBUTES_MAX]; struct Bits *b=NULL; bvptr v=NULL; memset(n, 0, sizeof(n)); /* scan-build */ if(!single_trace_only) { FreeCutBuffer(); GLOBALS->traces.buffer=GLOBALS->traces.first; GLOBALS->traces.bufferlast=GLOBALS->traces.last; GLOBALS->traces.buffercount=GLOBALS->traces.total; GLOBALS->traces.first=GLOBALS->traces.last=NULL; GLOBALS->traces.total=0; t=GLOBALS->traces.buffer; } else { t = single_trace_only; } while(t) { if(t->flags&TR_HIGHLIGHT) { if(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH)) { /* nothing */ } else { if(t->vector) { int ix; bptr bits = t->n.vec->bits; baptr oldba = bits ? bits->attribs : NULL; bits=t->n.vec->bits; if(!(t->flags&TR_REVERSE)) { for(ix=0;ixnnbits;ix++) { if(bits->nodes[ix]->expansion) bits->nodes[ix]->expansion->refcnt++; ba[nodepnt].shift = t->shift + (oldba ? oldba[ix].shift : 0); ba[nodepnt].flags = t->flags ^ (oldba ? oldba[ix].flags&TR_INVERT : 0); n[nodepnt++]=bits->nodes[ix]; } } else { for(ix=(bits->nnbits-1);ix>-1;ix--) { if(bits->nodes[ix]->expansion) bits->nodes[ix]->expansion->refcnt++; ba[nodepnt].shift = t->shift + (oldba ? oldba[ix].shift : 0); ba[nodepnt].flags = t->flags ^ (oldba ? oldba[ix].flags&TR_INVERT : 0); n[nodepnt++]=bits->nodes[ix]; } } } else { eptr e=ExpandNode(t->n.nd); int ix; if(!e) { if(t->n.nd->expansion) t->n.nd->expansion->refcnt++; ba[nodepnt].shift = t->shift; ba[nodepnt].flags = t->flags; n[nodepnt++]=t->n.nd; } else { for(ix=0;ixwidth;ix++) { ba[nodepnt].shift = t->shift; ba[nodepnt].flags = t->flags; n[nodepnt++]=e->narray[ix]; e->narray[ix]->expansion->refcnt++; } free_2(e->narray); free_2(e); } } } } if(nodepnt==dirty) break; if(t == single_trace_only) break; t=t->t_next; } b=(struct Bits *)calloc_2(1,sizeof(struct Bits)+(nodepnt)*sizeof(struct Node *)); b->attribs = malloc_2(nodepnt * sizeof(struct BitAttributes)); for(i=0;iattribs+i, ba+i, sizeof(struct BitAttributes)); } else { memcpy(b->attribs+i, ba+(nodepnt-1-i), sizeof(struct BitAttributes)); } if((ba[i].shift)||(ba[i].flags&TR_INVERT)) /* timeshift/invert are only relevant flags */ { attrib_reqd = 1; } } if(!attrib_reqd) { free_2(b->attribs); b->attribs = NULL; } if(nodepnt && n[0] && n[0]->expansion) /* scan-build */ { bitblast_parent = n[0]->expansion->parent; } else { bitblast_parent = NULL; } if(direction) { for(i=0;inodes[i]=n[i]; if(n[i] && n[i]->expansion) /* scan-build */ { if(bitblast_parent != n[i]->expansion->parent) { bitblast_parent=NULL; } else { if(i==1) { if(n[0] && n[0]->expansion) /* scan-build */ { bitblast_delta = n[1]->expansion->actual - n[0]->expansion->actual; if(bitblast_delta<-1) bitblast_delta=0; else if(bitblast_delta>1) bitblast_delta=0; } else { bitblast_delta = 0; } } else if((bitblast_delta)&&(i>1)) { if((n[i]->expansion->actual - n[i-1]->expansion->actual) != bitblast_delta) bitblast_delta=0; } } } else { bitblast_parent = NULL; } } } else { int rev; rev=nodepnt-1; for(i=0;inodes[i]=n[rev--]; if(n[i] && n[i]->expansion) /* scan-build */ { if(bitblast_parent != n[i]->expansion->parent) { bitblast_parent=NULL; } else { if(i==1) { if(n[0] && n[0]->expansion) /* scan-build */ { bitblast_delta = n[1]->expansion->actual - n[0]->expansion->actual; if(bitblast_delta<-1) bitblast_delta=0; else if(bitblast_delta>1) bitblast_delta=0; } else { bitblast_delta=0; } } else if((bitblast_delta)&&(i>1)) { if((n[i]->expansion->actual - n[i-1]->expansion->actual) != bitblast_delta) bitblast_delta=0; } } } else { bitblast_parent = NULL; } } } b->nnbits=nodepnt; if(!bitblast_parent) { char *aname; int match_iter = 1; if(direction) { aname = (nodepnt && n[0]) ? attempt_vecmatch(n[0]->nname, n[nodepnt-1]->nname) : NULL; /* scan-build */ } else { aname = (nodepnt && n[0]) ? attempt_vecmatch(n[nodepnt-1]->nname, n[0]->nname) : NULL; /* scan-build */ } if(aname) { int ix; for(ix=0;ixnname, n[ix]->nname); if(!mat) { match_iter = 0; break; } else { free_2(mat); } } } if(!match_iter) { free_2(aname); aname = NULL; } if(!b->attribs) { if(aname) { b->name = aname; } else { strcpy(b->name=(char *)malloc_2(strlen("")+1),""); } } else { if(aname) { b->name = aname; } else { strcpy(b->name=(char *)malloc_2(strlen("")+1),""); } } } else { int ix, offset; char *nam; char *namex; int was_packed = HIER_DEPACK_ALLOC; namex = hier_decompress_flagged(n[0]->nname, &was_packed); offset = strlen(namex); for(ix=offset-1;ix>=0;ix--) { if(namex[ix]=='[') break; } if(ix>-1) offset=ix; nam=(char *)wave_alloca(offset+40); memcpy(nam, namex, offset); if(was_packed) { free_2(namex); } if(direction) { sprintf(nam+offset, "[%d%s%d]", n[0]->expansion->actual, (bitblast_delta!=0) ? ":" : "|", n[nodepnt-1]->expansion->actual); } else { sprintf(nam+offset, "[%d%s%d]", n[nodepnt-1]->expansion->actual, (bitblast_delta!=0) ? ":" : "|", n[0]->expansion->actual); } strcpy(b->name=(char *)malloc_2(offset + strlen(nam+offset)+1), nam); DEBUG(printf("Name is: '%s'\n", nam)); } if((v=bits2vector(b))) { v->bits=b; /* only needed for savefile function */ } else { free_2(b->name); if(b->attribs) free_2(b->attribs); free_2(b); return NULL; } if(!single_trace_only) { tmp=GLOBALS->traces.buffer; GLOBALS->traces.buffer=GLOBALS->traces.first; GLOBALS->traces.first=tmp; tmp=GLOBALS->traces.bufferlast; GLOBALS->traces.bufferlast=GLOBALS->traces.last; GLOBALS->traces.last=tmp; tmpi=GLOBALS->traces.buffercount; GLOBALS->traces.buffercount=GLOBALS->traces.total; GLOBALS->traces.total=tmpi; PasteBuffer(); } return v; } } void menu_combine_down(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; bvptr v; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nCombine Down"); help_text( " coalesces the highlighted signals into a single vector named" " \"\" in a top to bottom fashion" " placed after the last highlighted trace. The original traces will" " be placed in the cut buffer." " It will function seemingly randomly" " when used upon real valued single-bit traces." ); return; } if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */ v = combine_traces(1, NULL); /* down */ if (v) { Trptr t; AddVector(v, NULL); free_2(v->bits->name); v->bits->name=NULL; t = GLOBALS->traces.last; RemoveTrace(t, 0); /* t is now the composite signal trace */ create_group("unused_0", t); GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); menu_rename(widget, null_data); } else { } } void menu_combine_up(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; bvptr v; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nCombine Up"); help_text( " coalesces the highlighted signals into a single vector named" " \"\" in a bottom to top fashion" " placed after the last highlighted trace. The original traces will" " be placed in the cut buffer." " It will function seemingly randomly" " when used upon real valued single-bit traces." ); return; } if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */ v = combine_traces(0, NULL); /* up */ if (v) { Trptr t; AddVector(v, NULL); free_2(v->bits->name); v->bits->name=NULL; t = GLOBALS->traces.last; RemoveTrace(t, 0); /* t is now the composite signal trace */ create_group("unused_1", t); GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); menu_rename(widget, null_data); } else { } } /**/ void menu_tracesearchbox_callback(GtkWidget *widget, gpointer data) { (void)widget; (void)data; } void menu_tracesearchbox(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; Trptr t; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nPattern Search"); help_text( " only works when at least one trace is highlighted. " " A requester will appear that lists all the selected" " traces (maximum of 500) and allows various criteria" " to be specified for each trace. Searches can go forward" " or backward from the primary (unnamed) marker. If the" " primary marker has not been set, the search starts at the" " beginning of the displayed data (\"From\") for a forwards" " search and starts at the end of the displayed data (\"To\")" " for a backwards search." " \"Mark\" and \"Clear\" are used to modify the normal time" " vertical markings such that they can be used to indicate" " all the times that a specific pattern search condition is" " true (e.g., every upclock of a specific signal). The" " \"Mark Count\" field indicates how many times the specific" " pattern search condition was encountered." " The \"Marking Begins at\" and \"Marking Stops at\" fields are" " used to limit the time over which marking is applied" " (but they have no effect on searching)." ); return; } for(t=GLOBALS->traces.first;t;t=t->t_next) { if ((t->flags&TR_HIGHLIGHT)&&HasWave(t)) { /* at least one good trace, so do it */ /* data contains WV_MENU_SPS or WV_MENU_SPS2 or ... but the base is WV_MENU_SPS*/ char buf[128]; long which = ((long)callback_action) - WV_MENU_SPS; if((which < 0) || (which >= WAVE_NUM_STRACE_WINDOWS)) { /* should never happen unless menus are defined wrong */ sprintf(buf, "Pattern search ID %d out of range of 1-%d available, ignoring.", (int)(which+1), WAVE_NUM_STRACE_WINDOWS); status_text(buf); } else { sprintf(buf, "Waveform Display Search (%d)", (int)(which+1)); tracesearchbox(buf, GTK_SIGNAL_FUNC(menu_tracesearchbox_callback), (gpointer)which); } return; } } must_sel(); } /**/ void menu_new_viewer_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; pid_t pid; if(GLOBALS->filesel_ok) { /* fix problem where ungrab doesn't occur if button pressed + simultaneous accelerator key occurs */ if(GLOBALS->in_button_press_wavewindow_c_1) { gdk_pointer_ungrab(GDK_CURRENT_TIME); } #if !defined __MINGW32__ && !defined _MSC_VER /* * for some reason, X won't let us double-fork in order to cleanup zombies.. *shrug* */ pid=fork(); if(((int)pid) < 0) { return; /* not much we can do about this.. */ } if(pid) /* parent==original server_pid */ { return; } #ifdef MAC_INTEGRATION /* from : @pfx = split(' ', "open -n -W -a gtkwave --args --chdir dummy"); */ if(GLOBALS->optimize_vcd) { execlp("open", "open", "-n", "-W", "-a", "gtkwave", "--args", "--optimize", "--dump", *GLOBALS->fileselbox_text, NULL); } else { execlp("open", "open", "-n", "-W", "-a", "gtkwave", "--args", "--dump", *GLOBALS->fileselbox_text, NULL); } #else if(GLOBALS->optimize_vcd) { execlp(GLOBALS->whoami, GLOBALS->whoami, "-o", *GLOBALS->fileselbox_text, NULL); } else { execlp(GLOBALS->whoami, GLOBALS->whoami, *GLOBALS->fileselbox_text, NULL); } #endif exit(0); /* control never gets here if successful */ #else BOOL bSuccess = FALSE; PROCESS_INFORMATION piProcInfo; TCHAR *szCmdline; STARTUPINFO si; memset(&piProcInfo, 0, sizeof(PROCESS_INFORMATION)); memset(&si, 0, sizeof(STARTUPINFO)); szCmdline = malloc_2(strlen(GLOBALS->whoami) + 1 + strlen(*GLOBALS->fileselbox_text) + 1); sprintf(szCmdline, "%s %s", GLOBALS->whoami, *GLOBALS->fileselbox_text); bSuccess = CreateProcess(NULL, szCmdline, /* command line */ NULL, /* process security attributes */ NULL, /* primary thread security attributes */ TRUE, /* handles are inherited */ 0, /* creation flags */ NULL, /* use parent's environment */ NULL, /* use parent's current directory */ &si, /* STARTUPINFO pointer */ &piProcInfo); /* receives PROCESS_INFORMATION */ free_2(szCmdline); if(!bSuccess) { /* failed */ } #endif } } void menu_new_viewer(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; static int mnv = 0; if(!mnv && !GLOBALS->busy_busy_c_1) { mnv = 1; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nOpen New Window"); help_text( " will open a file requester that will ask for the name" " of a VCD or AET file to view. This will fork off a" " new viewer process." ); } else { if(in_main_iteration()) { mnv = 0; return; } fileselbox("Select a trace to view...",&GLOBALS->filesel_newviewer_menu_c_1,GTK_SIGNAL_FUNC(menu_new_viewer_cleanup), GTK_SIGNAL_FUNC(NULL), NULL, 0); } mnv = 0; } } /**/ int menu_new_viewer_tab_cleanup_2(char *fname, int optimize_vcd) { int rc = 0; char *argv[2]; struct Global *g_old = GLOBALS; struct Global *g_now; argv[0] = gtkwave_argv0_cached ? gtkwave_argv0_cached : "gtkwave"; argv[1] = fname; /* fix problem where ungrab doesn't occur if button pressed + simultaneous accelerator key occurs */ if(GLOBALS->in_button_press_wavewindow_c_1) { gdk_pointer_ungrab(GDK_CURRENT_TIME); } GLOBALS->vcd_jmp_buf = calloc(1, sizeof(jmp_buf)); splash_button_press_event(NULL, NULL); /* kill any possible splash screens (e.g., if automated) */ set_window_busy(NULL); gtkwave_main_iteration(); if(!setjmp(*(GLOBALS->vcd_jmp_buf))) { main_2(optimize_vcd, 2, argv); g_now = GLOBALS; set_GLOBALS(g_old); clone_icon_pointers_across_contexts(g_now, GLOBALS); free(GLOBALS->vcd_jmp_buf); GLOBALS->vcd_jmp_buf = NULL; set_window_idle(NULL); set_GLOBALS(g_now); g_now->vcd_jmp_buf = NULL; /* copy old file req strings into new context */ strcpy2_into_new_context(GLOBALS, &GLOBALS->fcurr_ttranslate_c_1, &g_old->fcurr_ttranslate_c_1); strcpy2_into_new_context(GLOBALS, &GLOBALS->fcurr_ptranslate_c_1, &g_old->fcurr_ptranslate_c_1); strcpy2_into_new_context(GLOBALS, &GLOBALS->fcurr_translate_c_2, &g_old->fcurr_translate_c_2); #if 0 /* disabled for now...these probably would be disruptive */ strcpy2_into_new_context(GLOBALS, &GLOBALS->filesel_lxt_writesave, &g_old->filesel_lxt_writesave); strcpy2_into_new_context(GLOBALS, &GLOBALS->filesel_vcd_writesave, &g_old->filesel_vcd_writesave); strcpy2_into_new_context(GLOBALS, &GLOBALS->filesel_tim_writesave, &g_old->filesel_tim_writesave); strcpy2_into_new_context(GLOBALS, &GLOBALS->filesel_writesave, &g_old->filesel_writesave); strcpy2_into_new_context(GLOBALS, &GLOBALS->stems_name, &g_old->stems_name); strcpy2_into_new_context(GLOBALS, &GLOBALS->filesel_logfile_menu_c_1, &g_old->filesel_logfile_menu_c_1); strcpy2_into_new_context(GLOBALS, &GLOBALS->filesel_scriptfile_menu, &g_old->filesel_scriptfile_menu); strcpy2_into_new_context(GLOBALS, &GLOBALS->filesel_print_pdf_renderopt_c_1, &g_old->filesel_print_pdf_renderopt_c_1); strcpy2_into_new_context(GLOBALS, &GLOBALS->filesel_print_ps_renderopt_c_1, &g_old->filesel_print_ps_renderopt_c_1); strcpy2_into_new_context(GLOBALS, &GLOBALS->filesel_print_mif_renderopt_c_1, &g_old->filesel_print_mif_renderopt_c_1); #endif /* not sure what's really needed here */ /* for now, add back in repscript_name */ GLOBALS->repscript_period = g_old->repscript_period; strcpy2_into_new_context(GLOBALS, &GLOBALS->repscript_name, &g_old->repscript_name); GLOBALS->strace_repeat_count = g_old->strace_repeat_count; if(g_old->loaded_file_type == MISSING_FILE) /* remove original "blank" page */ { if(g_old->missing_file_toolbar) gtk_widget_set_sensitive(g_old->missing_file_toolbar, TRUE); menu_set_sensitive(); gtk_notebook_set_current_page(GTK_NOTEBOOK(g_old->notebook), g_old->this_context_page); set_GLOBALS(g_old); menu_quit_close_callback(NULL, NULL); } wave_gconf_client_set_string("/current/pwd", getenv("PWD")); wave_gconf_client_set_string("/current/dumpfile", GLOBALS->optimize_vcd ? GLOBALS->unoptimized_vcd_file_name : GLOBALS->loaded_file_name); wave_gconf_client_set_string("/current/optimized_vcd", GLOBALS->optimize_vcd ? "1" : "0"); wave_gconf_client_set_string("/current/savefile", GLOBALS->filesel_writesave); rc = 1; } else { if(GLOBALS->vcd_handle_vcd_c_1) { fclose(GLOBALS->vcd_handle_vcd_c_1); GLOBALS->vcd_handle_vcd_c_1 = NULL; } if(GLOBALS->vcd_handle_vcd_recoder_c_2) { fclose(GLOBALS->vcd_handle_vcd_recoder_c_2); GLOBALS->vcd_handle_vcd_recoder_c_2 =NULL; } if(GLOBALS->mm_lxt_mmap_addr) { munmap(GLOBALS->mm_lxt_mmap_addr, GLOBALS->mm_lxt_mmap_len); GLOBALS->mm_lxt_mmap_addr = NULL; } free_outstanding(); /* free anything allocated in loader ctx */ free(GLOBALS); GLOBALS = NULL; /* valgrind fix */ set_GLOBALS(g_old); free(GLOBALS->vcd_jmp_buf); GLOBALS->vcd_jmp_buf = NULL; set_window_idle(NULL); /* load failed */ wave_gtk_window_set_title(GTK_WINDOW(GLOBALS->mainwindow), GLOBALS->winname, GLOBALS->dumpfile_is_modified ? WAVE_SET_TITLE_MODIFIED: WAVE_SET_TITLE_NONE, 0); printf("GTKWAVE | File load failure, new tab not created.\n"); rc = 0; } return(rc); } void menu_new_viewer_tab_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; if(GLOBALS->filesel_ok) { menu_new_viewer_tab_cleanup_2(*GLOBALS->fileselbox_text, GLOBALS->optimize_vcd); } } void menu_new_viewer_tab(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nOpen New Tab"); help_text( " will open a file requester that will ask for the name" " of a VCD or AET file to view. This will create a tabbed page." ); return; } if(in_main_iteration()) return; #ifdef WAVE_USE_GTK2 if((!GLOBALS->socket_xid)&&(!GLOBALS->partial_vcd)) #else if(!GLOBALS->partial_vcd) #endif { fileselbox("Select a trace to view...",&GLOBALS->filesel_newviewer_menu_c_1,GTK_SIGNAL_FUNC(menu_new_viewer_tab_cleanup), GTK_SIGNAL_FUNC(NULL), NULL, 0); } } /**/ void menu_reload_waveform(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nReload Current Waveform"); help_text( " will reload the currently displayed waveform" " from a potentially updated file." ); return; } if(in_main_iteration()) return; if(GLOBALS->gt_splash_c_1 || GLOBALS->splash_is_loading) { return; /* don't attempt reload if splash screen is still active...that's pointless anyway */ } /* XXX if there's no file (for some reason), this function shouldn't occur we should probably gray it out. */ if(GLOBALS->loaded_file_type == DUMPLESS_FILE) { printf("GTKWAVE | DUMPLESS_FILE type cannot be reloaded\n"); return; } reload_into_new_context(); } void menu_reload_waveform_marshal(GtkWidget *widget, gpointer data) { menu_reload_waveform(data, 0, widget); } /**/ void menu_print(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nPrint To File"); help_text( " will open up a requester that will allow you to select" " print options (PS or MIF; Letter, A4, or Legal; Full or Minimal)." " After selecting the options you want," " a file requester will ask for the name of the" " output file to generate" " that reflects the current main window display's contents." ); return; } renderbox("Print Formatting Options"); } /**/ void menu_markerbox_callback(GtkWidget *widget, gpointer data) { (void)widget; (void)data; } void menu_markerbox(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nShow-Change Marker Data"); help_text( " displays and allows the modification of the times for" " all named markers by filling in the leftmost entry boxes. In addition, optional marker text" " rather than a generic single letter name may be specified by filling in the rightmost entry boxes." " Note that the time for each marker must be unique." ); return; } markerbox("Markers", GTK_SIGNAL_FUNC(menu_markerbox_callback)); } void copy_pri_b_marker(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nCopy Primary -> B Marker"); help_text( " copies the primary marker position to the B marker (handy for measuring deltas)." ); return; } DEBUG(printf("copy_pri_b_marker()\n")); if(GLOBALS->tims.marker!=-1) { GLOBALS->tims.baseline = GLOBALS->tims.marker; update_basetime(GLOBALS->tims.baseline); GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } /**/ void delete_unnamed_marker(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nDelete Primary Marker"); help_text( " removes the primary marker from the display if present." ); return; } DEBUG(printf("delete_unnamed marker()\n")); if(GLOBALS->tims.marker!=-1) { Trptr t; for(t=GLOBALS->traces.first;t;t=t->t_next) { if(t->asciivalue) { free_2(t->asciivalue); t->asciivalue=NULL; } } for(t=GLOBALS->traces.buffer;t;t=t->t_next) { if(t->asciivalue) { free_2(t->asciivalue); t->asciivalue=NULL; } } update_markertime(GLOBALS->tims.marker=-1); GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } /**/ void collect_all_named_markers(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; int i; int dirty=0; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nCollect All Named Markers"); help_text( " simply collects any and all named markers which have" " been dropped." ); return; } DEBUG(printf("collect_all_unnamed_markers()\n")); for(i=0;inamed_markers[i]!=-1) { GLOBALS->named_markers[i]=-1; dirty=1; } if(GLOBALS->marker_names[i]) { free_2(GLOBALS->marker_names[i]); GLOBALS->marker_names[i] = NULL; } } if(dirty) { signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } /**/ void collect_named_marker(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; int i; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nCollect Named Marker"); help_text( " collects a named marker where the current primary (unnamed)" " marker is placed if there is a named marker at its position." ); return; } DEBUG(printf("collect_named_marker()\n")); if(GLOBALS->tims.marker!=-1) { for(i=0;inamed_markers[i]==GLOBALS->tims.marker) { GLOBALS->named_markers[i]=-1; signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); if(GLOBALS->marker_names[i]) { free_2(GLOBALS->marker_names[i]); GLOBALS->marker_names[i] = NULL; } /* return; */ } } } } /**/ void drop_named_marker(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; int i; if(GLOBALS->helpbox_is_active) { char nm_s[32]; sprintf(nm_s, "%d", WAVE_NUM_NAMED_MARKERS); help_text_bold("\n\nDrop Named Marker"); help_text( " drops a named marker where the current primary (unnamed)" " marker is placed. A maximum of " ); help_text( nm_s ); help_text( " named markers are allowed" " and the times for all must be different." ); return; } DEBUG(printf("drop_named_marker()\n")); if(GLOBALS->tims.marker!=-1) { /* only one per slot requirement removed... #if 0 for(i=0;inamed_markers[i]==GLOBALS->tims.marker) return; } #endif ...only one per slot requirement removed */ for(i=0;inamed_markers[i]==-1) { GLOBALS->named_markers[i]=GLOBALS->tims.marker; signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); return; } } } } /**/ void menu_treesearch_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); DEBUG(printf("menu_treesearch_cleanup()\n")); } void menu_treesearch(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nSignal Search Tree"); help_text( " provides an easy means of adding traces to the display." " Various functions are provided in the Signal Search Tree requester" " which allow searching a treelike hierarchy and bundling" " (coalescing individual bits into a single vector)." ); return; } if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */ treebox("Signal Search Tree",GTK_SIGNAL_FUNC(menu_treesearch_cleanup), NULL); } /**/ void menu_showchangeall_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; Trptr t; Ulong flags; t=GLOBALS->showchangeall_menu_c_1; if(t) { flags=t->flags; while(t) { if((t->flags&TR_HIGHLIGHT)&&(!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH)))&&(t->name)) { t->flags=flags; } t=t->t_next; } } GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); DEBUG(printf("menu_showchangeall_cleanup()\n")); } void menu_showchangeall(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; Trptr t; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nShow-Change All Highlighted"); help_text( " provides an easy means of changing trace attributes en masse." " Various functions are provided in a Show-Change requester." ); return; } DEBUG(printf("menu_showchangeall()\n")); GLOBALS->showchangeall_menu_c_1=NULL; t=GLOBALS->traces.first; while(t) { if((t->flags&TR_HIGHLIGHT)&&(!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH)))&&(t->name)) { showchange("Show-Change All", GLOBALS->showchangeall_menu_c_1=t, GTK_SIGNAL_FUNC(menu_showchangeall_cleanup)); return; } t=t->t_next; } must_sel(); } /**/ void menu_showchange_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); DEBUG(printf("menu_showchange_cleanup()\n")); } void menu_showchange(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; Trptr t; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nShow-Change First Highlighted"); help_text( " provides a means of changing trace attributes for the" " first highlighted trace. " " Various functions are provided in a Show-Change requester. " " When a function is applied, the trace will be unhighlighted." ); return; } DEBUG(printf("menu_showchange()\n")); t=GLOBALS->traces.first; while(t) { if((t->flags&TR_HIGHLIGHT)&&(!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH)))&&(t->name)) { showchange("Show-Change", t, GTK_SIGNAL_FUNC(menu_showchange_cleanup)); return; } t=t->t_next; } must_sel(); } /**/ void menu_remove_aliases(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; Trptr t; int dirty=0, none_selected = 1; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nRemove Highlighted Aliases"); help_text( " only works when at least one trace has been highlighted. " " Any aliased traces will have their names restored to their" " original names. As vectors get their names from aliases," " vector aliases will not be removed." ); return; } if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */ t=GLOBALS->traces.first; while(t) { if(HasAlias(t) && IsSelected(t)) { char *name_full; int was_packed = HIER_DEPACK_ALLOC; free_2(t->name_full); t->name_full = NULL; if(t->vector) { name_full = t->n.vec->bvname; } else { name_full = hier_decompress_flagged(t->n.nd->nname, &was_packed); } t->name = name_full; if (GLOBALS->hier_max_level) { if(!was_packed) { t->name = hier_extract(t->name, GLOBALS->hier_max_level); } else { t->name = strdup_2(hier_extract(name_full, GLOBALS->hier_max_level)); free_2(name_full); } } if(was_packed) t->is_depacked = 1; dirty = 1; } if (IsSelected(t)) none_selected = 0; t=t->t_next; } if(dirty) { GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); DEBUG(printf("menu_remove_aliases()\n")); } if (none_selected) { must_sel(); } } static void alias_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; Trptr t = GLOBALS->trace_to_alias_menu_c_1; if(GLOBALS->entrybox_text) { char *efix; /* code to turn '{' and '}' into '[' and ']' */ if(!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH))) { efix=GLOBALS->entrybox_text; while(*efix) { if(*efix=='{') { *efix='['; } if(*efix=='}') { *efix=']'; } efix++; } } if (CanAlias(t)) { if(HasAlias(t)) free_2(t->name_full); t->name_full = (char *)malloc_2(1+strlen(GLOBALS->entrybox_text)); strcpy(t->name_full, GLOBALS->entrybox_text); t->name = t->name_full; if(GLOBALS->hier_max_level) t->name = hier_extract(t->name, GLOBALS->hier_max_level); t->flags&= ~TR_HIGHLIGHT; } GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } void menu_alias(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; Trptr t; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nAlias Highlighted Trace"); help_text( " only works when at least one trace has been highlighted. " " With this function, you will be prompted for an alias" " name for the first highlighted trace. After successfully" " aliasing a trace, the aliased trace will be unhighlighted." " Single bits will be marked with a leading \"+\" and vectors" " will have no such designation. The purpose of this is to" " provide a fast method of determining which trace names are" " real and which ones are aliases." ); return; } GLOBALS->trace_to_alias_menu_c_1=NULL; /* don't mess with sigs when dnd active */ if(GLOBALS->dnd_state) { dnd_error(); return; } t = GLOBALS->traces.first; while(t) { if(IsSelected(t)&&CanAlias(t)) { GLOBALS->trace_to_alias_menu_c_1=t; break; } t=t->t_next; } if(GLOBALS->trace_to_alias_menu_c_1) { int was_packed = HIER_DEPACK_ALLOC; char* current = GetFullName(GLOBALS->trace_to_alias_menu_c_1, &was_packed); ClearTraces(); GLOBALS->trace_to_alias_menu_c_1->flags |= TR_HIGHLIGHT; entrybox("Alias Highlighted Trace",300,current,NULL,128,GTK_SIGNAL_FUNC(alias_cleanup)); if(was_packed) { free_2(current); } } else { must_sel(); } } /**/ void menu_hiersearch_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); DEBUG(printf("menu_hiersearch_cleanup()\n")); } void menu_hiersearch(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nHierarchy Search"); help_text( " provides an easy means of adding traces to the display in a text based" " treelike fashion." ); return; } if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */ hier_searchbox("Hierarchy Search",GTK_SIGNAL_FUNC(menu_hiersearch_cleanup)); } /**/ void menu_signalsearch_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); DEBUG(printf("menu_signalsearch_cleanup()\n")); } void menu_signalsearch(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nSignal Search Regexp"); help_text( " provides an easy means of adding traces to the display. " " Various functions are provided in the Signal Search requester" " which allow searching using POSIX regular expressions and bundling" " (coalescing individual bits into a single vector). " ); return; } if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */ searchbox("Signal Search",GTK_SIGNAL_FUNC(menu_signalsearch_cleanup)); } /**/ static void regexp_highlight_generic(int mode) { if(GLOBALS->entrybox_text) { Trptr t; Ulong modebits; char dirty=0; modebits=(mode)?TR_HIGHLIGHT:0; strcpy(GLOBALS->regexp_string_menu_c_1, GLOBALS->entrybox_text); wave_regex_compile(GLOBALS->regexp_string_menu_c_1, WAVE_REGEX_SEARCH); free_2(GLOBALS->entrybox_text); t=GLOBALS->traces.first; while(t) { char *pnt; pnt=(t->name)?t->name:""; /* handle (really) blank lines */ if(*pnt=='+') /* skip alias prefix if present */ { pnt++; if(*pnt==' ') { pnt++; } } if(wave_regex_match(pnt, WAVE_REGEX_SEARCH)) { t->flags=((t->flags&(~TR_HIGHLIGHT))|modebits); dirty=1; } t=t->t_next; } if(dirty) { signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } } static void regexp_unhighlight_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; regexp_highlight_generic(0); } void menu_regexp_unhighlight(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nUnHighlight Regexp"); help_text( " brings up a text requester that will ask for a" " regular expression that may contain text with POSIX regular expressions." " All traces meeting this criterion / these criteria will be" " unhighlighted if they are currently highlighted." ); return; } entrybox("Regexp UnHighlight",300,GLOBALS->regexp_string_menu_c_1,NULL,128,GTK_SIGNAL_FUNC(regexp_unhighlight_cleanup)); } /**/ static void regexp_highlight_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; regexp_highlight_generic(1); } void menu_regexp_highlight(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nHighlight Regexp"); help_text( " brings up a text requester that will ask for a" " regular expression that may contain text with POSIX regular expressions." " All traces meeting this criterion / these criteria will be" " highlighted." ); return; } entrybox("Regexp Highlight",300,GLOBALS->regexp_string_menu_c_1,NULL,128,GTK_SIGNAL_FUNC(regexp_highlight_cleanup)); } /**/ #if GTK_CHECK_VERSION(2,14,0) void menu_write_screengrab_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; GdkWindow *gw; gint w, h; GdkColormap *cm; GdkPixbuf *dest = NULL; GdkPixbuf *dest2; GError *err = NULL; gboolean succ = FALSE; if(!GLOBALS->filesel_ok) { return; } gw = gtk_widget_get_window(GTK_WIDGET(GLOBALS->mainwindow)); if(gw) { gdk_drawable_get_size(gw, &w, &h); cm = gdk_drawable_get_colormap(gw); if(cm) { dest = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, w, h); if(dest) { dest2 = gdk_pixbuf_get_from_drawable(dest, gw, cm, 0, 0, 0, 0, w, h); if(dest2) { succ = gdk_pixbuf_save (dest2, *GLOBALS->fileselbox_text, "png", &err, NULL); } } } } if(dest) { g_object_unref(dest); } if(!succ) { fprintf(stderr, "Error opening imagegrab file '%s' for writing.\n",*GLOBALS->fileselbox_text); perror("Why"); errno=0; } else { wave_gconf_client_set_string("/current/imagegrab", GLOBALS->filesel_imagegrab); } } void menu_write_screengrab_as(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nGrab To File"); help_text( " will open a file requester that will ask for the name" " to be used for a PNG format image grab of the main GTKWave window." " Note that if the main window is covered by other windows or" " is partially offscreen, the grabbed image might not appear properly." ); return; } errno = 0; fileselbox("Grab To File",&GLOBALS->filesel_imagegrab,GTK_SIGNAL_FUNC(menu_write_screengrab_cleanup), GTK_SIGNAL_FUNC(NULL), "*.png", 1); } #endif /**/ void menu_write_save_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; FILE *wave; if(!GLOBALS->filesel_ok) { return; } if(!(wave=fopen(*GLOBALS->fileselbox_text,"wb"))) { fprintf(stderr, "Error opening save file '%s' for writing.\n",*GLOBALS->fileselbox_text); perror("Why"); errno=0; } else { write_save_helper(*GLOBALS->fileselbox_text, wave); wave_gconf_client_set_string("/current/savefile", GLOBALS->filesel_writesave); GLOBALS->save_success_menu_c_1 = 1; fclose(wave); } } void menu_write_save_file_as(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nWrite Save File As"); help_text( " will open a file requester that will ask for the name" " of a GTKWave save file. The contents of the save file" " generated will be the traces as well as their" " format (binary, decimal, hex, reverse, etc.) which" " are currently a part of the display. Marker positional" " data and the zoom factor are also a part of the save file." ); return; } fileselbox("Write Save File",&GLOBALS->filesel_writesave,GTK_SIGNAL_FUNC(menu_write_save_cleanup), GTK_SIGNAL_FUNC(NULL), GLOBALS->is_gtkw_save_file ? "*.gtkw" : "*.sav", 1); } void menu_write_save_file(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nWrite Save File"); help_text( " will invoke Write Save File As if no save file name has been specified previously." " Otherwise it will write the save file data without prompting." ); return; } if(!GLOBALS->filesel_writesave) { fileselbox("Write Save File",&GLOBALS->filesel_writesave,GTK_SIGNAL_FUNC(menu_write_save_cleanup), GTK_SIGNAL_FUNC(NULL), GLOBALS->is_gtkw_save_file ? "*.gtkw" : "*.sav", 1); } else { GLOBALS->filesel_ok = 1; GLOBALS->save_success_menu_c_1 = 0; GLOBALS->fileselbox_text = &GLOBALS->filesel_writesave; menu_write_save_cleanup(NULL, NULL); if(GLOBALS->save_success_menu_c_1) { status_text("Wrote save file OK.\n"); } else { status_text("Problem writing save file.\n"); } } } /**/ void menu_read_save_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; if(GLOBALS->filesel_ok) { char *wname; DEBUG(printf("Read Save Fini: %s\n", *GLOBALS->fileselbox_text)); wname=*GLOBALS->fileselbox_text; wave_gconf_client_set_string("/current/savefile", wname); read_save_helper(wname, NULL, NULL, NULL, NULL, NULL); } } void menu_read_save_file(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nRead Save File"); help_text( " will open a file requester that will ask for the name" " of a GTKWave save file. The contents of the save file" " will determine which traces and vectors as well as their" " format (binary, decimal, hex, reverse, etc.) are to be" " appended to the display. Note that the marker positional" " data and zoom factor present in the save file will" " replace any current settings." ); return; } if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */ fileselbox("Read Save File",&GLOBALS->filesel_writesave,GTK_SIGNAL_FUNC(menu_read_save_cleanup), GTK_SIGNAL_FUNC(NULL), GLOBALS->is_gtkw_save_file ? "*.gtkw" : "*.sav", 0); } #if !defined _MSC_VER /**/ void menu_read_stems_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; char *fname; if(GLOBALS->filesel_ok) { DEBUG(printf("Read Stems Fini: %s\n", *GLOBALS->fileselbox_text)); fname=*GLOBALS->fileselbox_text; if((fname)&&strlen(fname)) { activate_stems_reader(fname); } } } /**/ void menu_read_stems_file(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nRead Verilog Stemsfile"); help_text( " will open a file requester that will ask for the name" " of a Verilog stemsfile. This will then launch an RTL browser and allow source code annotation based on" " the primary marker position." " Stems files are generated by Vermin. Please see its manpage" " for syntax and more information on stems file generation." ); return; } if(!stems_are_active()) { if(GLOBALS->stems_type != WAVE_ANNO_NONE) { fileselbox("Read Verilog Stemsfile",&GLOBALS->stems_name, GTK_SIGNAL_FUNC(menu_read_stems_cleanup), GTK_SIGNAL_FUNC(NULL), NULL, 0); } else { status_text("Unsupported dumpfile type for rtlbrowse.\n"); } } } #endif /**/ void menu_read_log_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; char *fname ; if(GLOBALS->filesel_ok) { DEBUG(printf("Read Log Fini: %s\n", *GLOBALS->fileselbox_text)); fname=*GLOBALS->fileselbox_text; if((fname)&&strlen(fname)) { logbox("Logfile viewer", 480, fname); } } } /**/ void menu_read_log_file(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nRead Logfile"); help_text( " will open a file requester that will ask for the name" " of a plaintext simulation log. By clicking on the numbers in the logfile," " the marker will jump to the appropriate time value in the wave window." ); return; } fileselbox("Read Logfile",&GLOBALS->filesel_logfile_menu_c_1,GTK_SIGNAL_FUNC(menu_read_log_cleanup), GTK_SIGNAL_FUNC(NULL), NULL, 0); } /**/ void menu_read_script_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; char *fname; if(GLOBALS->filesel_ok) { DEBUG(printf("Read Script Fini: %s\n", *GLOBALS->fileselbox_text)); fname=*GLOBALS->fileselbox_text; if((fname)&&strlen(fname)) { execute_script(fname, 0); } } } /**/ void menu_read_script_file(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nRead Script File"); help_text( " will open a file requester that will ask for the name" " of a TCL script to run. This menu option itself is not callable" " by TCL scripts." ); return; } fileselbox("Read Script File",&GLOBALS->filesel_scriptfile_menu,GTK_SIGNAL_FUNC(menu_read_script_cleanup), GTK_SIGNAL_FUNC(NULL), "*.tcl", 0); } /**/ void menu_insert_blank_traces(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nInsert Blank"); help_text( " inserts a blank trace after the last highlighted trace." " If no traces are highlighted, the blank is inserted after" " the last trace." ); return; } if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */ DEBUG(printf("Insert Blank Trace\n")); InsertBlankTrace(NULL, 0); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } void menu_insert_analog_height_extension(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nInsert Analog Height Extension"); help_text( " inserts a blank analog extension trace after the last highlighted trace." " If no traces are highlighted, the blank is inserted after" " the last trace. This type of trace is used to increase the height of analog traces." ); return; } if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */ DEBUG(printf("Insert Analog Blank Trace\n")); InsertBlankTrace(NULL, TR_ANALOG_BLANK_STRETCH); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } /**/ static void comment_trace_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; InsertBlankTrace(GLOBALS->entrybox_text, 0); if(GLOBALS->entrybox_text) { free_2(GLOBALS->entrybox_text); GLOBALS->entrybox_text=NULL; } GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } void menu_insert_comment_traces(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nInsert Comment"); help_text( " inserts a comment trace after the last highlighted trace." " If no traces are highlighted, the comment is inserted after" " the last trace." ); return; } if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */ DEBUG(printf("Insert Comment Trace\n")); entrybox("Insert Comment Trace",300,"",NULL,128,GTK_SIGNAL_FUNC(comment_trace_cleanup)); } /**/ static void strace_repcnt_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; if(GLOBALS->entrybox_text) { GLOBALS->strace_repeat_count = atoi_64(GLOBALS->entrybox_text); free_2(GLOBALS->entrybox_text); GLOBALS->entrybox_text=NULL; } } void menu_strace_repcnt(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; char gt[32]; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nSet Pattern Search Repeat Count"); help_text( " sets the number of times that both edge and pattern searches iterate forward or backward when marker forward/backward is selected." " Default value is one. This can be used, for example, to skip forward 10 clock edges at a time rather than a single edge." ); return; } sprintf(gt, "%d", GLOBALS->strace_repeat_count); entrybox("Repeat Count",300,gt,NULL,20,GTK_SIGNAL_FUNC(strace_repcnt_cleanup)); } /**/ void movetotime_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; if(GLOBALS->entrybox_text) { TimeType gt = GLOBALS->tims.first; char update_string[128]; char timval[40]; GtkAdjustment *hadj; TimeType pageinc; if((GLOBALS->entrybox_text[0] >= 'A' && GLOBALS->entrybox_text[0] <= 'Z')||(GLOBALS->entrybox_text[0] >= 'a' && GLOBALS->entrybox_text[0] <= 'z')) { char *su = GLOBALS->entrybox_text; int uch; while(*su) { uch = toupper((int)(unsigned char)*su); *su = uch; su++; } uch = bijective_marker_id_string_hash(GLOBALS->entrybox_text); if((uch >= 0)&&(uch < WAVE_NUM_NAMED_MARKERS)) { gt=GLOBALS->named_markers[uch]; } } else { gt=unformat_time(GLOBALS->entrybox_text, GLOBALS->time_dimension); gt -= GLOBALS->global_time_offset; } free_2(GLOBALS->entrybox_text); GLOBALS->entrybox_text=NULL; if(gttims.first) gt=GLOBALS->tims.first; else if(gt>GLOBALS->tims.last) gt=GLOBALS->tims.last; hadj=GTK_ADJUSTMENT(GLOBALS->wave_hslider); hadj->value=gt; pageinc=(TimeType)(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx); if(gt<(GLOBALS->tims.last-pageinc+1)) GLOBALS->tims.timecache=gt; else { GLOBALS->tims.timecache=GLOBALS->tims.last-pageinc+1; if(GLOBALS->tims.timecachetims.first) GLOBALS->tims.timecache=GLOBALS->tims.first; } reformat_time(timval,GLOBALS->tims.timecache + GLOBALS->global_time_offset,GLOBALS->time_dimension); sprintf(update_string, "Moved to time: %s\n", timval); status_text(update_string); time_update(); } } void menu_movetotime(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; char gt[32]; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nMove To Time"); help_text( " scrolls the waveform display such that the left border" " is the time entered in the requester." " Use one of the letters A-Z to move to a named marker." ); return; } reformat_time(gt, GLOBALS->tims.start + GLOBALS->global_time_offset, GLOBALS->time_dimension); entrybox("Move To Time",200,gt,NULL,20,GTK_SIGNAL_FUNC(movetotime_cleanup)); } /**/ static void fetchsize_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; if(GLOBALS->entrybox_text) { TimeType fw; char update_string[128]; fw=unformat_time(GLOBALS->entrybox_text, GLOBALS->time_dimension); if(fw<1) { fw=GLOBALS->fetchwindow; /* in case they try to pull 0 or <0 */ } else { GLOBALS->fetchwindow=fw; } free_2(GLOBALS->entrybox_text); GLOBALS->entrybox_text=NULL; sprintf(update_string, "Fetch Size is now: "TTFormat"\n", fw); status_text(update_string); } } void menu_fetchsize(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; char fw[32]; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nFetch Size"); help_text( " brings up a requester which allows input of the" " number of ticks used for fetch/discard operations." " Default is 100." ); return; } reformat_time(fw, GLOBALS->fetchwindow, GLOBALS->time_dimension); entrybox("New Fetch Size",200,fw,NULL,20,GTK_SIGNAL_FUNC(fetchsize_cleanup)); } /**/ void zoomsize_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; if(GLOBALS->entrybox_text) { float f; char update_string[128]; sscanf(GLOBALS->entrybox_text, "%f", &f); if(f>0.0) { f=0.0; /* in case they try to go out of range */ } else if(f<-62.0) { f=-62.0; /* in case they try to go out of range */ } GLOBALS->tims.prevzoom=GLOBALS->tims.zoom; GLOBALS->tims.zoom=(gdouble)f; calczoom(GLOBALS->tims.zoom); fix_wavehadj(); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed"); free_2(GLOBALS->entrybox_text); GLOBALS->entrybox_text=NULL; sprintf(update_string, "Zoom Amount is now: %g\n", f); status_text(update_string); } } void menu_zoomsize(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; char za[32]; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nZoom Amount"); help_text( " allows entry of zero or a negative value for the display" " zoom. Zero is no magnification." ); return; } sprintf(za,"%g",(float)(GLOBALS->tims.zoom)); entrybox("New Zoom Amount",200,za,NULL,20,GTK_SIGNAL_FUNC(zoomsize_cleanup)); } /**/ static void zoombase_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; if(GLOBALS->entrybox_text) { float za; char update_string[128]; sscanf(GLOBALS->entrybox_text, "%f", &za); if(za>10.0) { za=10.0; } else if(za<1.5) { za=1.5; } GLOBALS->zoombase=(gdouble)za; calczoom(GLOBALS->tims.zoom); fix_wavehadj(); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed"); free_2(GLOBALS->entrybox_text); GLOBALS->entrybox_text=NULL; sprintf(update_string, "Zoom Base is now: %g\n", za); status_text(update_string); } } void menu_zoombase(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; char za[32]; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nZoom Base"); help_text( " allows entry of a zoom base for the zoom (magnification per integer step)" " Allowable values are 1.5 to 10.0. Default is 2.0." ); return; } sprintf(za,"%g",GLOBALS->zoombase); entrybox("New Zoom Base Amount",200,za,NULL,20,GTK_SIGNAL_FUNC(zoombase_cleanup)); } /**/ static void colorformat(int color) { Trptr t; int fix=0; int color_prev = WAVE_COLOR_NORMAL; int is_first = 0; if((t=GLOBALS->traces.first)) { while(t) { if(IsSelected(t)&&!IsShadowed(t)) { if(color != WAVE_COLOR_CYCLE) { t->t_color = color; } else { if(!is_first) { is_first = 1; if(t->t_color == WAVE_COLOR_NORMAL) { color_prev = WAVE_COLOR_RED; } else { color_prev = t->t_color; } } else { color_prev++; } if(color_prev > WAVE_COLOR_VIOLET) color_prev = WAVE_COLOR_RED; t->t_color = color_prev; } fix=1; } t=t->t_next; } if(fix) { GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } } void menu_colorformat_0(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nColor Format Normal"); help_text( " uses normal waveform colorings for all selected traces." ); return; } colorformat(WAVE_COLOR_NORMAL); } void menu_colorformat_1(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nColor Format Red"); help_text( " uses red waveform colorings for all selected traces." ); return; } colorformat(WAVE_COLOR_RED); } void menu_colorformat_2(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nColor Format Orange"); help_text( " uses orange waveform colorings for all selected traces." ); return; } colorformat(WAVE_COLOR_ORANGE); } void menu_colorformat_3(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nColor Format Yellow"); help_text( " uses yellow waveform colorings for all selected traces." ); return; } colorformat(WAVE_COLOR_YELLOW); } void menu_colorformat_4(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nColor Format Green"); help_text( " uses green waveform colorings for all selected traces." ); return; } colorformat(WAVE_COLOR_GREEN); } void menu_colorformat_5(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nColor Format Blue"); help_text( " uses blue waveform colorings for all selected traces." ); return; } colorformat(WAVE_COLOR_BLUE); } void menu_colorformat_6(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nColor Format Indigo"); help_text( " uses indigo waveform colorings for all selected traces." ); return; } colorformat(WAVE_COLOR_INDIGO); } void menu_colorformat_7(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nColor Format Violet"); help_text( " uses violet waveform colorings for all selected traces." ); return; } colorformat(WAVE_COLOR_VIOLET); } void menu_colorformat_cyc(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nColor Format Cycle"); help_text( " uses cycling waveform colorings for all selected traces." ); return; } colorformat(WAVE_COLOR_CYCLE); } /**/ char **grow_array(char ***src, int *siz, char *str) { if(!*src) { *src = malloc_2(sizeof(char *)); (*src)[0] = str; *siz = 1; } else { *src = realloc_2(*src, (*siz + 1) * sizeof(char *)); (*src)[*siz] = str; *siz = *siz + 1; } return(*src); } #if WAVE_USE_GTK2 static void open_index_in_forked_editor(uint32_t idx, int typ) { if(idx) { int lineno = 1; char *edname = getenv("GTKWAVE_EDITOR"); char *fname = NULL; FILE *ftest = NULL; if(GLOBALS->editor_name) { edname = GLOBALS->editor_name; /* rcfile "editor" variable first */ } else { if(edname) { /* ok, env var GTKWAVE_EDITOR second */ } #ifdef GEDIT_PATH else { /* fallback */ edname = GEDIT_PATH; } #endif } #ifdef MAC_INTEGRATION if(!edname) { edname = "open -t"; /* Use OSX TextEdit as editor of last resort */ } #endif idx--; if(typ == FST_MT_SOURCESTEM) { lineno = GLOBALS->stem_struct_base[idx].stem_line_number; fname = GLOBALS->stem_path_string_table[GLOBALS->stem_struct_base[idx].stem_idx]; } else { lineno = GLOBALS->istem_struct_base[idx].stem_line_number; fname = GLOBALS->stem_path_string_table[GLOBALS->istem_struct_base[idx].stem_idx]; } #ifdef __MINGW32__ { fprintf(stderr, "GTKWAVE | Not supported in Windows!\n"); } #else if(!(ftest = fopen(fname, "rb"))) { char *rp = get_relative_adjusted_name(GLOBALS->loaded_file_name, fname, GLOBALS->loaded_file_name); if(!rp) { int clen = strlen(fname); int wid = clen * 10; if(wid < 400) wid = 400; simplereqbox("Could not open file!", wid, fname, "OK", NULL, NULL, 1); return; } fname = wave_alloca(strlen(rp) + 1); strcpy(fname, rp); free_2(rp); } else { fclose(ftest); ftest = NULL; } { pid_t pid=fork(); if(((int)pid) < 0) { /* can't do anything about this */ } else { if(pid) /* parent==original server_pid */ { } else { char *str = strdup_2(edname); char nbuf[32]; char *saveptr1 = NULL; char *str1, *token, *sd_token; const char *delim = " \t"; int num_seen = 0; int fn_seen = 0; char **ar = NULL; int siz = 0; for(str1 = str;;str1 = NULL) { token = strtok_r(str1, delim, &saveptr1); if(!token) break; if(strstr(token, "%d")) { sprintf(nbuf, token, lineno); sd_token = strdup_2(nbuf); num_seen = 1; } else if(!strcmp(token, "%s")) { sd_token = strdup_2(fname); fn_seen = 1; } else { sd_token = strdup_2(token); } grow_array(&ar, &siz, sd_token); } if(ar && edname) { if(!num_seen) { if((strstr(ar[0], "vi")) || (strstr(ar[0], "emacs")) || (strstr(ar[0], "gedit"))) { sprintf(nbuf, "+%d", lineno); sd_token = strdup_2(nbuf); grow_array(&ar, &siz, sd_token); } } if(!fn_seen) { sd_token = strdup_2(fname); grow_array(&ar, &siz, sd_token); } grow_array(&ar, &siz, NULL); execvp(ar[0], ar); } fprintf(stderr, "GTKWAVE | Could not find editor executable!\n"); exit(255); /* control never gets here if successful */ } } } #endif } else { simplereqbox("Open Source", 400, "Source stem not present!", "OK", NULL, NULL, 1); } } #endif static void menu_open_hierarchy_2(gpointer null_data, guint callback_action, GtkWidget *widget, int typ) { (void)null_data; (void)callback_action; (void)widget; #if WAVE_USE_GTK2 Trptr t; int fix=0; struct tree *t_forced = NULL; #endif if(GLOBALS->helpbox_is_active) { if((typ == FST_MT_SOURCESTEM) || (typ == FST_MT_SOURCEISTEM)) { if(typ == FST_MT_SOURCESTEM) { help_text_bold("\n\nOpen Source Definition"); } else { help_text_bold("\n\nOpen Source Instantiation"); } help_text( #if WAVE_USE_GTK2 " opens and selects the appropriate level of hierarchy in the SST" " for the first selected signal and also invokes the editor specified by the" " \"editor\" gtkwaverc variable, that specified by the environment variable $GTKWAVE_EDITOR," #ifndef MAC_INTEGRATION " or gedit (if found during ./configure)" #else " gedit (if found during ./configure), or lastly open -t" #endif " on the appropriate source unit. This is currently only supported by FST." #else " is not available with this build. Please build against GTK 2." #endif ); } else { help_text_bold("\n\nOpen Scope"); help_text( #if WAVE_USE_GTK2 " opens and selects the appropriate level of hierarchy in the SST" " for the first selected signal." #else " is not available with this build. Please build against GTK 2." #endif ); } return; } #if WAVE_USE_GTK2 if((t=GLOBALS->traces.first)) { while(t) { if(IsSelected(t)&&!IsShadowed(t)) { char *tname = NULL; if(!HasWave(t)) { break; } if (HasAlias(t)) { tname = strdup_2(t->name_full); } else if(t->vector==TRUE) { tname = strdup_2(t->n.vec->bvname); } else { int flagged = HIER_DEPACK_ALLOC; if(!t->n.nd) { break; /* additional guard on top of !HasWave(t) */ } tname = hier_decompress_flagged(t->n.nd->nname, &flagged); if(!flagged) { tname = strdup_2(tname); } } if(tname) { char *lasthier = strrchr(tname, GLOBALS->hier_delimeter); if(lasthier) { char *tname_copy; lasthier++; /* zero out character after hierarchy */ *lasthier = 0; tname_copy = strdup_2(tname); /* force_open_tree_node() is destructive */ if(force_open_tree_node(tname_copy, 1, &t_forced) >= 0) { if(GLOBALS->selected_hierarchy_name) { free_2(GLOBALS->selected_hierarchy_name); GLOBALS->selected_hierarchy_name = strdup_2(tname); } select_tree_node(tname); } free_2(tname_copy); } free_2(tname); fix=1; break; } } t=t->t_next; } if(fix) { GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } if(((typ == FST_MT_SOURCESTEM) || (typ == FST_MT_SOURCEISTEM)) && t_forced) { uint32_t idx = (typ == FST_MT_SOURCESTEM) ? t_forced->t_stem : t_forced->t_istem; if(!GLOBALS->stem_path_string_table) { fprintf(stderr, "GTKWAVE | Could not find stems information in this file!\n"); } else { if(!idx && (typ == FST_MT_SOURCEISTEM) && GLOBALS->istem_struct_base) { /* handle top level where istem == stem and istem is deliberately not specified */ typ = FST_MT_SOURCESTEM; idx = t_forced->t_stem; } open_index_in_forked_editor(idx, typ); } } #endif } static void menu_open_hierarchy_2a(gpointer null_data, guint callback_action, GtkWidget *widget, int typ) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { if((typ == FST_MT_SOURCESTEM) || (typ == FST_MT_SOURCEISTEM)) { if(typ == FST_MT_SOURCESTEM) { help_text_bold("\n\nOpen Source Definition"); } else { help_text_bold("\n\nOpen Source Instantiation"); } help_text( #if WAVE_USE_GTK2 " invokes $GTKWAVE_EDITOR or gedit (if found) on the appropriate source unit." #else " is not available with this build. Please build against GTK 2." #endif ); } else { help_text_bold("\n\nOpen Scope"); help_text( #if WAVE_USE_GTK2 " opens and selects the appropriate level of hierarchy in the SST" " for the first selected signal." #else " is not available with this build. Please build against GTK 2." #endif ); } return; } #if WAVE_USE_GTK2 if((typ == FST_MT_SOURCESTEM) || (typ == FST_MT_SOURCEISTEM)) { struct tree *t_forced = GLOBALS->sst_sig_root_treesearch_gtk2_c_1; if(t_forced) { uint32_t idx = (typ == FST_MT_SOURCESTEM) ? t_forced->t_stem : t_forced->t_istem; if(!GLOBALS->stem_path_string_table) { fprintf(stderr, "GTKWAVE | Could not find stems information in this file!\n"); } else { if(!idx && (typ == FST_MT_SOURCEISTEM) && GLOBALS->istem_struct_base) { /* handle top level where istem == stem and istem is deliberately not specified */ typ = FST_MT_SOURCESTEM; idx = t_forced->t_stem; } open_index_in_forked_editor(idx, typ); } } } #endif } void menu_open_hierarchy(gpointer null_data, guint callback_action, GtkWidget *widget) { menu_open_hierarchy_2(null_data, callback_action, widget, FST_MT_MIN); /* zero for regular open */ } void menu_open_hierarchy_source(gpointer null_data, guint callback_action, GtkWidget *widget) { menu_open_hierarchy_2(null_data, callback_action, widget, FST_MT_SOURCESTEM); /* for definition source */ } void menu_open_hierarchy_isource(gpointer null_data, guint callback_action, GtkWidget *widget) { menu_open_hierarchy_2(null_data, callback_action, widget, FST_MT_SOURCEISTEM); /* for instantiation source */ } void menu_open_sst_hierarchy_source(gpointer null_data, guint callback_action, GtkWidget *widget) { menu_open_hierarchy_2a(null_data, callback_action, widget, FST_MT_SOURCESTEM); /* for definition source */ } void menu_open_sst_hierarchy_isource(gpointer null_data, guint callback_action, GtkWidget *widget) { menu_open_hierarchy_2a(null_data, callback_action, widget, FST_MT_SOURCEISTEM); /* for instantiation source */ } /**/ static void dataformat(int mask, int patch) { Trptr t; int fix=0; if((t=GLOBALS->traces.first)) { while(t) { if(IsSelected(t)&&!IsShadowed(t)) { t->minmax_valid = 0; /* force analog traces to regenerate if necessary */ t->flags=((t->flags)&mask)|patch; fix=1; } t=t->t_next; } if(fix) { GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } } void menu_dataformat_ascii(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nData Format-ASCII"); help_text( " will step through all highlighted traces and ensure that" " vectors with this qualifier will be displayed with ASCII" " values." ); return; } dataformat( ~(TR_NUMMASK|TR_ANALOGMASK), TR_ASCII ); } void menu_dataformat_real(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nData Format-BitsToReal"); help_text( " will step through all highlighted traces and ensure that" " vectors with this qualifier will be displayed with Real" " values. Note that this only works for 64-bit quantities" " and that ones of other sizes will display as binary." ); return; } dataformat( ~(TR_NUMMASK|TR_ANALOGMASK), TR_REAL ); } void menu_dataformat_real2bon(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nData Format-RealToBits On"); help_text( " will step through all highlighted traces and ensure that" " Real vectors with this qualifier will be displayed as Hex" " values. Note that this only works for Real quantities" " and other ones will remain to display as binary. This is a pre-filter" " so it is possible to invert, reverse, apply Decimal, etc. It will not be" " possible however to expand those values into their constituent bits." ); return; } dataformat( ~(TR_REAL2BITS|TR_NUMMASK|TR_ANALOGMASK), TR_REAL2BITS|TR_HEX ); } void menu_dataformat_real2boff(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nData Format-RealToBits Off"); help_text( " will step through all highlighted traces and ensure that" " the Real To Bits qualifier is removed from those traces." ); return; } dataformat( ~(TR_REAL2BITS|TR_ANALOGMASK), 0 ); } void menu_dataformat_hex(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nData Format-Hex"); help_text( " will step through all highlighted traces and ensure that" " vectors with this qualifier will be displayed with hexadecimal" " values." ); return; } dataformat( ~(TR_NUMMASK|TR_ANALOGMASK), TR_HEX ); } void menu_dataformat_dec(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nData Format-Decimal"); help_text( " will step through all highlighted traces and ensure that" " vectors with this qualifier will be displayed with decimal" " values." ); return; } dataformat( ~(TR_NUMMASK|TR_ANALOGMASK), TR_DEC ); } void menu_dataformat_signed(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nData Format-Signed"); help_text( " will step through all highlighted traces and ensure that" " vectors with this qualifier will be displayed as sign extended decimal" " values." ); return; } dataformat( ~(TR_NUMMASK|TR_ANALOGMASK), TR_SIGNED ); } void menu_dataformat_bin(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nData Format-Binary"); help_text( " will step through all highlighted traces and ensure that" " vectors with this qualifier will be displayed with binary" " values." ); return; } dataformat( ~(TR_NUMMASK|TR_ANALOGMASK), TR_BIN ); } void menu_dataformat_oct(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nData Format-Octal"); help_text( " will step through all highlighted traces and ensure that" " vectors with this qualifier will be displayed with octal" " values." ); return; } dataformat( ~(TR_NUMMASK|TR_ANALOGMASK), TR_OCT ); } void menu_dataformat_rjustify_on(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nData Format-Right Justify-On"); help_text( " will step through all highlighted traces and ensure that" " vectors with this qualifier will be displayed right" " justified." ); return; } dataformat( ~(TR_RJUSTIFY), TR_RJUSTIFY ); } void menu_dataformat_rjustify_off(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nData Format-Right Justify-Off"); help_text( " will step through all highlighted traces and ensure that" " vectors with this qualifier will not be displayed right" " justified." ); return; } dataformat( ~(TR_RJUSTIFY), 0 ); } void menu_dataformat_bingray_on(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nData Format-Gray Filters-To Gray"); help_text( " will step through all highlighted traces and ensure that" " bits and vectors with this qualifier will be displayed after" " going through normal to gray conversion. This is a filter" " which sits before other Data Format options such as hex, etc." ); return; } dataformat( ~(TR_GRAYMASK|TR_ANALOGMASK), TR_BINGRAY ); } void menu_dataformat_graybin_on(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nData Format-Gray Filters-From Gray"); help_text( " will step through all highlighted traces and ensure that" " bits and vectors with this qualifier will be displayed after" " going through gray to normal conversion. This is a filter" " which sits before other Data Format options such as hex, etc." ); return; } dataformat( ~(TR_GRAYMASK|TR_ANALOGMASK), TR_GRAYBIN ); } void menu_dataformat_nogray(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nData Format-Gray Filters-None"); help_text( " will step through all highlighted traces and ensure that" " bits and vectors with this qualifier will be displayed with" " normal encoding." ); return; } dataformat( ~(TR_GRAYMASK|TR_ANALOGMASK), 0 ); } void menu_dataformat_popcnt_on(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nData Format-Popcnt-On"); help_text( " will step through all highlighted traces and ensure that" " bits and vectors with this qualifier will be displayed after" " going through a population (one's) count conversion. This is a filter" " which sits before other Data Format options such as hex, etc." ); return; } dataformat( ~(TR_POPCNT), TR_POPCNT ); } void menu_dataformat_popcnt_off(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nData Format-Popcnt-Off"); help_text( " will step through all highlighted traces and ensure that" " bits and vectors with this qualifier will be displayed with" " normal encoding." ); return; } dataformat( ~(TR_POPCNT), 0 ); } void menu_dataformat_invert_on(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nData Format-Invert-On"); help_text( " will step through all highlighted traces and ensure that" " bits and vectors with this qualifier will be displayed with" " 1's and 0's inverted." ); return; } dataformat( ~(TR_INVERT), TR_INVERT ); } void menu_dataformat_invert_off(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nData Format-Invert-Off"); help_text( " will step through all highlighted traces and ensure that" " bits and vectors with this qualifier will not be displayed with" " 1's and 0's inverted." ); return; } dataformat( ~(TR_INVERT), 0 ); } void menu_dataformat_reverse_on(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nData Format-Reverse Bits-On"); help_text( " will step through all highlighted traces and ensure that" " vectors with this qualifier will be displayed in" " reversed bit order." ); return; } dataformat( ~(TR_REVERSE), TR_REVERSE ); } void menu_dataformat_reverse_off(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nData Format-Reverse Bits-Off"); help_text( " will step through all highlighted traces and ensure that" " vectors with this qualifier will not be displayed in" " reversed bit order." ); return; } dataformat( ~(TR_REVERSE), 0 ); } void menu_dataformat_exclude_on(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nExclude"); help_text( " causes the waveform data for all currently highlighted traces" " to be blanked out." ); return; } dataformat( ~(TR_EXCLUDE), TR_EXCLUDE ); } void menu_dataformat_exclude_off(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nShow"); help_text( " causes the waveform data for all currently highlighted traces" " to be displayed as normal if the exclude attribute is currently" " set on the highlighted traces." ); return; } dataformat( ~(TR_EXCLUDE), 0 ); } /**/ void menu_dataformat_rangefill_zero(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nData Format-Range Fill With 0s"); help_text( " will step through all highlighted traces and ensure that" " vectors with this qualifier will be displayed as if" " the bitrange of the MSB or LSB as appropriate goes to zero." " Zero bits will be filled in for the missing bits." ); return; } dataformat( ~(TR_ZEROFILL|TR_ONEFILL|TR_ANALOGMASK), TR_ZEROFILL ); } void menu_dataformat_rangefill_one(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nData Format-Range Fill With 1s"); help_text( " will step through all highlighted traces and ensure that" " vectors with this qualifier will be displayed as if" " the bitrange of the MSB or LSB as appropriate goes to zero." " One bits will be filled in for the missing bits; this is mostly intended" " to be used when viewing values which are inverted in the logic and need" " to be inverted in the viewer." ); return; } dataformat( ~(TR_ZEROFILL|TR_ONEFILL|TR_ANALOGMASK), TR_ONEFILL ); } void menu_dataformat_rangefill_off(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nData Format-Zero Range Fill Off"); help_text( " will step through all highlighted traces and ensure that" " normal bitrange displays are used." ); return; } dataformat( ~(TR_ZEROFILL|TR_ONEFILL|TR_ANALOGMASK), 0 ); } /**/ void menu_dataformat_analog_off(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nAnalog Off"); help_text( " causes the waveform data for all currently highlighted traces" " to be displayed as normal." ); return; } dataformat( ~(TR_ANALOGMASK), 0 ); } void menu_dataformat_analog_step(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nAnalog Step"); help_text( " causes the waveform data for all currently highlighted traces" " to be displayed as stepwise analog waveform." ); return; } dataformat( ~(TR_ANALOGMASK), TR_ANALOG_STEP ); } void menu_dataformat_analog_interpol(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nAnalog Interpolate"); help_text( " causes the waveform data for all currently highlighted traces" " to be displayed as interpolated analog waveform." ); return; } dataformat( ~(TR_ANALOGMASK), TR_ANALOG_INTERPOLATED ); } void menu_dataformat_analog_interpol_step(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nAnalog Interpolate Annotated"); help_text( " causes the waveform data for all currently highlighted traces" " to be displayed as an interpolated analog waveform annotated" " with the non-interpolated data sampling points that the cursor snaps to." ); return; } dataformat( ~(TR_ANALOGMASK), (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP) ); } void menu_dataformat_analog_resize_screen(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nAnalog Resizing Screen Data"); help_text( " causes the waveform data for all currently highlighted traces" " to be displayed such that the y-value scaling maximizes the on-screen trace" " data so if fills the whole trace width at all times." ); return; } dataformat( ~(TR_ANALOG_FULLSCALE), 0 ); } void menu_dataformat_analog_resize_all(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nAnalog Resizing All Data"); help_text( " causes the waveform data for all currently highlighted traces" " to be displayed such that the y-value scaling maximizes the on-screen trace" " data so if fills the whole trace width only when fully zoomed out." " (i.e., the scale used goes across all trace data)" ); return; } dataformat( ~(TR_ANALOG_FULLSCALE), (TR_ANALOG_FULLSCALE) ); } /**/ void menu_dataformat_highlight_all(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; Trptr t; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nHighlight All"); help_text( " simply highlights all displayed traces." ); return; } if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */ if((t=GLOBALS->traces.first)) { while(t) { t->flags|=TR_HIGHLIGHT; t=t->t_next; } signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } void menu_dataformat_unhighlight_all(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; Trptr t; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nUnHighlight All"); help_text( " simply unhighlights all displayed traces." ); return; } if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */ if((t=GLOBALS->traces.first)) { while(t) { t->flags&=(~TR_HIGHLIGHT); t=t->t_next; } signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } void menu_lexize(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nSigsort All"); help_text( " sorts all displayed traces with the numeric parts being taken into account. Blank traces are sorted to the bottom." ); return; } if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */ if(GLOBALS->traces.first) { if(TracesReorder(TR_SORT_LEX)) { signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } } /**/ void menu_alphabetize(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nAlphabetize All"); help_text( " alphabetizes all displayed traces. Blank traces are sorted to the bottom." ); return; } if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */ if(GLOBALS->traces.first) { if(TracesReorder(TR_SORT_NORM)) { signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } } /**/ void menu_alphabetize2(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nAlphabetize All (CaseIns)"); help_text( " alphabetizes all displayed traces without regard to case. Blank traces are sorted to the bottom." ); return; } if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */ if(GLOBALS->traces.first) { if(TracesReorder(TR_SORT_INS)) { signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } } /**/ void menu_reverse(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nReverse All"); help_text( " reverses all displayed traces unconditionally." ); return; } if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */ if(GLOBALS->traces.first) { if(TracesReorder(TR_SORT_RVS)) { signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } } /**/ void menu_cut_traces(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; Trptr cutbuffer = NULL; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nCut"); help_text( " removes highlighted signals from the display and places them" " in an offscreen cut/copy buffer for later Paste operations. " " Cut implicitly destroys the previous contents of the cut/copy buffer." ); return; } if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */ DEBUG(printf("Cut Traces\n")); cutbuffer = CutBuffer(); if(cutbuffer) { if(GLOBALS->cutcopylist) { free_2(GLOBALS->cutcopylist); } GLOBALS->cutcopylist = emit_gtkwave_savefile_formatted_entries_in_tcl_list(cutbuffer, FALSE); /* printf("Cutlist: '%s'\n", GLOBALS->cutcopylist); */ MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } else { must_sel(); } } void menu_copy_traces(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; Trptr t = GLOBALS->traces.first; gboolean highlighted = FALSE; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nCopy"); help_text( " copies highlighted signals from the display and places them" " in an offscreen cut/copy buffer for later Paste operations. " " Copy implicitly destroys the previous contents of the cut/copy buffer." ); return; } if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */ DEBUG(printf("Copy Traces\n")); while(t) { if(t->flags & TR_HIGHLIGHT) { highlighted = TRUE; break; } t = t->t_next; } if(!highlighted) { must_sel(); } else { if(GLOBALS->cutcopylist) { free_2(GLOBALS->cutcopylist); } GLOBALS->cutcopylist = emit_gtkwave_savefile_formatted_entries_in_tcl_list(GLOBALS->traces.first, TRUE); /* printf("Copylist: '%s'\n", GLOBALS->cutcopylist); */ FreeCutBuffer(); } } void menu_paste_traces(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nPaste"); help_text( " pastes signals from" " an offscreen cut/copy buffer and places them in a group after" " the last highlighted signal, or at the end of the display" " if no signal is highlighted." ); return; } if(GLOBALS->dnd_state) { dnd_error(); return; } /* don't mess with sigs when dnd active */ DEBUG(printf("Paste Traces\n")); if(PasteBuffer()) { GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } else { if(GLOBALS->cutcopylist) { /*int num_traces =*/ process_tcl_list(GLOBALS->cutcopylist, FALSE); /* printf("Pastelist: %d '%s'\n", num_traces, GLOBALS->cutcopylist); */ GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } } /**/ void menu_center_zooms(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nCenter Zooms"); help_text( " when enabled" " configures zoom in/out operations such that all zooms use the center of the" " display as the fixed zoom origin if the primary (unnamed) marker is" " not present, otherwise, the primary marker is used as the center origin." " When disabled, it" " configures zoom in/out operations such that all zooms use the" " left margin of the display as the fixed zoom origin." ); } else { #ifndef WAVE_USE_MLIST_T GLOBALS->do_zoom_center=(GLOBALS->do_zoom_center)?0:1; #else GLOBALS->do_zoom_center = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VCZ])); #endif DEBUG(printf("Center Zooms\n")); } #ifndef WAVE_USE_MLIST_T GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VCZ].path))->active=(GLOBALS->do_zoom_center)?TRUE:FALSE; #endif } void menu_show_base(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nShow Base Symbols"); help_text( " enables the display of leading base symbols ('$' for hex," " '%' for binary, '#' for octal if they are turned off and" " disables the drawing of leading base symbols if" " they are turned on." " Base symbols are displayed by default." ); } else { #ifndef WAVE_USE_MLIST_T GLOBALS->show_base=(GLOBALS->show_base)?0:~0; #else GLOBALS->show_base = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VSBS])); #endif GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); DEBUG(printf("Show Base Symbols\n")); } #ifndef WAVE_USE_MLIST_T GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VSBS].path))->active=(GLOBALS->show_base)?TRUE:FALSE; #endif } /**/ void menu_show_grid(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nShow Grid"); help_text( " toggles the drawing of gridlines in the waveform display." ); } else { #ifndef WAVE_USE_MLIST_T GLOBALS->display_grid=(GLOBALS->display_grid)?0:~0; #else GLOBALS->display_grid = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VSG])); #endif if(GLOBALS->wave_hslider) { gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)),"changed"); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)),"value_changed"); } DEBUG(printf("Show Grid\n")); } #ifndef WAVE_USE_MLIST_T GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VSG].path))->active=(GLOBALS->display_grid)?TRUE:FALSE; #endif } /**/ void menu_show_wave_highlight(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nShow Wave Highlight"); help_text( " toggles the drawing of highlighted waveforms (instead of gridlines) in the waveform display." ); } else { #ifndef WAVE_USE_MLIST_T GLOBALS->highlight_wavewindow=(GLOBALS->highlight_wavewindow)?0:~0; #else GLOBALS->highlight_wavewindow = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_SHW])); #endif if(GLOBALS->wave_hslider) { gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)),"changed"); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)),"value_changed"); } DEBUG(printf("Show Wave Highlight\n")); } #ifndef WAVE_USE_MLIST_T GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_SHW].path))->active=(GLOBALS->highlight_wavewindow)?TRUE:FALSE; #endif } /**/ void menu_show_mouseover(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nShow Mouseover"); help_text( " toggles the dynamic tooltip for signal names and values which follow the marker on mouse button presses in the waveform display." " This is useful for examining the values of closely packed value changes without having to zoom outward and without having to" " refer to the signal name pane to the left. Note that an encoded string will be displayed next to the signal name that" " indicates what data format flags are currently active for that signal. Flags are as follows:\n" " + = Signed Decimal\n" " X = Hexadecimal\n" " A = ASCII\n" " D = Decimal\n" " B = Binary\n" " O = Octal\n" " J = Right Justify\n" " ~ = Invert\n" " V = Reverse\n" " * = Analog Step+Interpolated\n" " S = Analog Step\n" " I = Analog Interpolated\n" " R = Real\n" " r = Real to Bits\n" " 0 = Range Fill with 0s\n" " 1 = Range Fill with 1s\n" " G = Binary to Gray\n" " g = Gray to Binary\n" " F = File Filter\n" " P = Process Filter\n" " T = Transaction Filter\n" " p = Population Count\n" ); } else { GLOBALS->disable_mouseover=(GLOBALS->disable_mouseover)?0:~0; DEBUG(printf("Show Mouseover\n")); } #ifndef WAVE_USE_MLIST_T GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VSMO].path))->active=(GLOBALS->disable_mouseover)?FALSE:TRUE; #else GLOBALS->disable_mouseover = !gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VSMO])); #endif } /**/ /* this is the GtkMenuEntry structure used to create new menus. The * first member is the menu definition string. The second, the * default accelerator key used to access this menu function with * the keyboard. The third is the callback function to call when * this menu item is selected (by the accelerator key, or with the * mouse.) The last member is the data to pass to your callback function. * * ...This has all been changed to use itemfactory stuff which is more * powerful. The only real difference is the final item which tells * the itemfactory just what the item "is". */ #ifdef WAVE_USE_MENU_BLACKOUTS static const char *menu_blackouts[] = { "/Edit", "/Search", "/Time", "/Markers", "/View" }; #endif static gtkwave_mlist_t menu_items[] = { WAVE_GTKIFE("/File/Open New Window", "N", menu_new_viewer, WV_MENU_FONV, ""), WAVE_GTKIFE("/File/Open New Tab", "T", menu_new_viewer_tab, WV_MENU_FONVT, ""), WAVE_GTKIFE("/File/Reload Waveform", "R", menu_reload_waveform, WV_MENU_FRW, ""), WAVE_GTKIFE("/File/Export/Write VCD File As", NULL, menu_write_vcd_file, WV_MENU_WRVCD, ""), WAVE_GTKIFE("/File/Export/Write LXT File As", NULL, menu_write_lxt_file, WV_MENU_WRLXT, ""), WAVE_GTKIFE("/File/Export/Write TIM File As", NULL, menu_write_tim_file, WV_MENU_WRTIM, ""), WAVE_GTKIFE("/File/Close", "W", menu_quit_close, WV_MENU_WCLOSE, ""), WAVE_GTKIFE("/File/", NULL, NULL, WV_MENU_SEP2VCD, ""), WAVE_GTKIFE("/File/Print To File", "P", menu_print, WV_MENU_FPTF, ""), #if GTK_CHECK_VERSION(2,14,0) WAVE_GTKIFE("/File/Grab To File", NULL, menu_write_screengrab_as, WV_MENU_SGRAB, ""), #endif WAVE_GTKIFE("/File/", NULL, NULL, WV_MENU_SEP1, ""), WAVE_GTKIFE("/File/Read Save File", "O", menu_read_save_file, WV_MENU_FRSF, ""), WAVE_GTKIFE("/File/Write Save File", "S", menu_write_save_file, WV_MENU_FWSF, ""), WAVE_GTKIFE("/File/Write Save File As", "S", menu_write_save_file_as, WV_MENU_FWSFAS, ""), WAVE_GTKIFE("/File/", NULL, NULL, WV_MENU_SEP2, ""), WAVE_GTKIFE("/File/Read Sim Logfile", "L", menu_read_log_file, WV_MENU_FRLF, ""), /* 10 */ WAVE_GTKIFE("/File/", NULL, NULL, WV_MENU_SEP2LF, ""), #if !defined _MSC_VER WAVE_GTKIFE("/File/Read Verilog Stemsfile", NULL, menu_read_stems_file, WV_MENU_FRSTMF, ""), WAVE_GTKIFE("/File/", NULL, NULL, WV_MENU_SEP2STMF, ""), #endif #if defined(HAVE_LIBTCL) WAVE_GTKIFE("/File/Read Tcl Script File", NULL, menu_read_script_file, WV_MENU_TCLSCR, ""), WAVE_GTKIFE("/File/", NULL, NULL, WV_MENU_TCLSEP, ""), #endif WAVE_GTKIFE("/File/Quit", "Q", menu_quit, WV_MENU_FQY, ""), WAVE_GTKIFE("/Edit/Set Trace Max Hier", NULL, menu_set_max_hier, WV_MENU_ESTMH, ""), WAVE_GTKIFE("/Edit/Toggle Trace Hier", "H", menu_toggle_hier, WV_MENU_ETH, ""), WAVE_GTKIFE("/Edit/", NULL, NULL, WV_MENU_SEP3, ""), WAVE_GTKIFE("/Edit/Insert Blank", "B", menu_insert_blank_traces, WV_MENU_EIB, ""), WAVE_GTKIFE("/Edit/Insert Comment", NULL, menu_insert_comment_traces, WV_MENU_EIC, ""), WAVE_GTKIFE("/Edit/Insert Analog Height Extension", NULL, menu_insert_analog_height_extension, WV_MENU_EIA, ""), #ifdef MAC_INTEGRATION WAVE_GTKIFE("/Edit/Cut", NULL, menu_cut_traces, WV_MENU_EC, ""), WAVE_GTKIFE("/Edit/Copy", NULL, menu_copy_traces, WV_MENU_ECY, ""), WAVE_GTKIFE("/Edit/Paste", NULL, menu_paste_traces, WV_MENU_EP, ""), #else WAVE_GTKIFE("/Edit/Cut", "X", menu_cut_traces, WV_MENU_EC, ""), WAVE_GTKIFE("/Edit/Copy", "C", menu_copy_traces, WV_MENU_ECY, ""), WAVE_GTKIFE("/Edit/Paste", "V", menu_paste_traces, WV_MENU_EP, ""), #endif WAVE_GTKIFE("/Edit/", NULL, NULL, WV_MENU_SEP3A, ""), WAVE_GTKIFE("/Edit/Alias Highlighted Trace", "A", menu_alias, WV_MENU_EAHT, ""), WAVE_GTKIFE("/Edit/Remove Highlighted Aliases", "A", menu_remove_aliases, WV_MENU_ERHA, ""), /* 20 */ WAVE_GTKIFE("/Edit/", NULL, NULL, WV_MENU_SEP4, ""), WAVE_GTKIFE("/Edit/Expand", "F3", menu_expand, WV_MENU_EE, ""), WAVE_GTKIFE("/Edit/Combine Down", "F4", menu_combine_down, WV_MENU_ECD, ""), WAVE_GTKIFE("/Edit/Combine Up", "F5", menu_combine_up, WV_MENU_ECU, ""), WAVE_GTKIFE("/Edit/", NULL, NULL, WV_MENU_SEP5, ""), WAVE_GTKIFE("/Edit/Data Format/Hex", "X", menu_dataformat_hex, WV_MENU_EDFH, ""), WAVE_GTKIFE("/Edit/Data Format/Decimal", "D", menu_dataformat_dec, WV_MENU_EDFD, ""), /* 30 */ WAVE_GTKIFE("/Edit/Data Format/Signed Decimal", NULL, menu_dataformat_signed, WV_MENU_EDFSD, ""), WAVE_GTKIFE("/Edit/Data Format/Binary", "B", menu_dataformat_bin, WV_MENU_EDFB, ""), WAVE_GTKIFE("/Edit/Data Format/Octal", "O", menu_dataformat_oct, WV_MENU_EDFO, ""), WAVE_GTKIFE("/Edit/Data Format/ASCII", NULL, menu_dataformat_ascii, WV_MENU_EDFA, ""), WAVE_GTKIFE("/Edit/Data Format/BitsToReal", NULL, menu_dataformat_real, WV_MENU_EDRL, ""), WAVE_GTKIFE("/Edit/Data Format/RealToBits/On", NULL, menu_dataformat_real2bon, WV_MENU_EDR2BON, ""), WAVE_GTKIFE("/Edit/Data Format/RealToBits/Off", NULL, menu_dataformat_real2boff, WV_MENU_EDR2BOFF, ""), WAVE_GTKIFE("/Edit/Data Format/Right Justify/On", "J", menu_dataformat_rjustify_on, WV_MENU_EDFRJON, ""), WAVE_GTKIFE("/Edit/Data Format/Right Justify/Off", "J", menu_dataformat_rjustify_off, WV_MENU_EDFRJOFF, ""), WAVE_GTKIFE("/Edit/Data Format/Invert/On", "I", menu_dataformat_invert_on, WV_MENU_EDFION, ""), WAVE_GTKIFE("/Edit/Data Format/Invert/Off", "I", menu_dataformat_invert_off, WV_MENU_EDFIOFF, ""), WAVE_GTKIFE("/Edit/Data Format/Reverse Bits/On", "V", menu_dataformat_reverse_on, WV_MENU_EDFRON, ""), /* 40 */ WAVE_GTKIFE("/Edit/Data Format/Reverse Bits/Off", "V", menu_dataformat_reverse_off, WV_MENU_EDFROFF, ""), WAVE_GTKIFE("/Edit/Data Format/Translate Filter File/Disable", NULL, menu_dataformat_xlate_file_0, WV_MENU_XLF_0, ""), WAVE_GTKIFE("/Edit/Data Format/Translate Filter File/Enable and Select", NULL, menu_dataformat_xlate_file_1, WV_MENU_XLF_1, ""), WAVE_GTKIFE("/Edit/Data Format/Translate Filter Process/Disable", NULL, menu_dataformat_xlate_proc_0, WV_MENU_XLP_0, ""), WAVE_GTKIFE("/Edit/Data Format/Translate Filter Process/Enable and Select", NULL, menu_dataformat_xlate_proc_1, WV_MENU_XLP_1, ""), WAVE_GTKIFE("/Edit/Data Format/Transaction Filter Process/Disable", NULL, menu_dataformat_xlate_ttrans_0, WV_MENU_TTXLP_0, ""), WAVE_GTKIFE("/Edit/Data Format/Transaction Filter Process/Enable and Select", NULL, menu_dataformat_xlate_ttrans_1, WV_MENU_TTXLP_1, ""), WAVE_GTKIFE("/Edit/Data Format/Analog/Off", NULL, menu_dataformat_analog_off, WV_MENU_EDFAOFF, ""), WAVE_GTKIFE("/Edit/Data Format/Analog/Step", NULL, menu_dataformat_analog_step, WV_MENU_EDFASTEP, ""), WAVE_GTKIFE("/Edit/Data Format/Analog/Interpolated", NULL, menu_dataformat_analog_interpol, WV_MENU_EDFAINTERPOL, ""), WAVE_GTKIFE("/Edit/Data Format/Analog/Interpolated Annotated", NULL, menu_dataformat_analog_interpol_step, WV_MENU_EDFAINTERPOL2, ""), WAVE_GTKIFE("/Edit/Data Format/Analog/Resizing/Screen Data", NULL, menu_dataformat_analog_resize_screen, WV_MENU_EDFARSD, ""), WAVE_GTKIFE("/Edit/Data Format/Analog/Resizing/All Data", NULL, menu_dataformat_analog_resize_all, WV_MENU_EDFARAD, ""), WAVE_GTKIFE("/Edit/Data Format/Range Fill/With 0s", NULL, menu_dataformat_rangefill_zero, WV_MENU_RFILL0, ""), WAVE_GTKIFE("/Edit/Data Format/Range Fill/With 1s", NULL, menu_dataformat_rangefill_one, WV_MENU_RFILL1, ""), WAVE_GTKIFE("/Edit/Data Format/Range Fill/Off", NULL, menu_dataformat_rangefill_off, WV_MENU_RFILLOFF, ""), WAVE_GTKIFE("/Edit/Data Format/Gray Filters/To Gray", NULL, menu_dataformat_bingray_on, WV_MENU_B2G, ""), WAVE_GTKIFE("/Edit/Data Format/Gray Filters/From Gray", NULL, menu_dataformat_graybin_on, WV_MENU_G2B, ""), WAVE_GTKIFE("/Edit/Data Format/Gray Filters/None", NULL, menu_dataformat_nogray, WV_MENU_GBNONE, ""), WAVE_GTKIFE("/Edit/Data Format/Popcnt/On", NULL, menu_dataformat_popcnt_on, WV_MENU_POPON, ""), WAVE_GTKIFE("/Edit/Data Format/Popcnt/Off", NULL, menu_dataformat_popcnt_off, WV_MENU_POPOFF, ""), WAVE_GTKIFE("/Edit/Color Format/Normal", NULL, menu_colorformat_0, WV_MENU_CLRFMT0, ""), WAVE_GTKIFE("/Edit/Color Format/Red", NULL, menu_colorformat_1, WV_MENU_CLRFMT1, ""), WAVE_GTKIFE("/Edit/Color Format/Orange", NULL, menu_colorformat_2, WV_MENU_CLRFMT2, ""), WAVE_GTKIFE("/Edit/Color Format/Yellow", NULL, menu_colorformat_3, WV_MENU_CLRFMT3, ""), WAVE_GTKIFE("/Edit/Color Format/Green", NULL, menu_colorformat_4, WV_MENU_CLRFMT4, ""), WAVE_GTKIFE("/Edit/Color Format/Blue", NULL, menu_colorformat_5, WV_MENU_CLRFMT5, ""), WAVE_GTKIFE("/Edit/Color Format/Indigo", NULL, menu_colorformat_6, WV_MENU_CLRFMT6, ""), WAVE_GTKIFE("/Edit/Color Format/Violet", NULL, menu_colorformat_7, WV_MENU_CLRFMT7, ""), WAVE_GTKIFE("/Edit/Color Format/Cycle", NULL, menu_colorformat_cyc, WV_MENU_CLRFMTC, ""), WAVE_GTKIFE("/Edit/Color Format/", NULL, NULL, WV_MENU_SEP5A, ""), WAVE_GTKIFE("/Edit/Color Format/Keep xz Colors", NULL, menu_keep_xz_colors, WV_MENU_KEEPXZ, ""), WAVE_GTKIFE("/Edit/Show-Change All Highlighted", NULL, menu_showchangeall, WV_MENU_ESCAH, ""), WAVE_GTKIFE("/Edit/Show-Change First Highlighted", "F", menu_showchange, WV_MENU_ESCFH, ""), /* 50 */ WAVE_GTKIFE("/Edit/", NULL, NULL, WV_MENU_SEP6, ""), WAVE_GTKIFE("/Edit/Time Warp/Warp Marked", NULL, menu_warp_traces, WV_MENU_WARP, ""), WAVE_GTKIFE("/Edit/Time Warp/Unwarp Marked", NULL, menu_unwarp_traces, WV_MENU_UNWARP, ""), WAVE_GTKIFE("/Edit/Time Warp/Unwarp All", NULL, menu_unwarp_traces_all, WV_MENU_UNWARPA, ""), WAVE_GTKIFE("/Edit/", NULL, NULL, WV_MENU_SEP7A, ""), WAVE_GTKIFE("/Edit/Exclude", "E", menu_dataformat_exclude_on, WV_MENU_EEX, ""), WAVE_GTKIFE("/Edit/Show", "S", menu_dataformat_exclude_off, WV_MENU_ESH, ""), WAVE_GTKIFE("/Edit/", NULL, NULL, WV_MENU_SEP6A, ""), /* WAVE_GTKIFE("/Edit/Expand All Groups", "F12", menu_expand_all, WV_MENU_EXA, ""), */ /* WAVE_GTKIFE("/Edit/Collapse All Groups", "F12", menu_collapse_all, WV_MENU_CPA, ""), */ /* 60 */ WAVE_GTKIFE("/Edit/Toggle Group Open|Close", "T", menu_toggle_group, WV_MENU_TG, ""), WAVE_GTKIFE("/Edit/Create Group", "G", menu_create_group, WV_MENU_AG, ""), WAVE_GTKIFE("/Edit/", NULL, NULL, WV_MENU_SEP6A1, ""), WAVE_GTKIFE("/Edit/Highlight Regexp", "R", menu_regexp_highlight, WV_MENU_EHR, ""), WAVE_GTKIFE("/Edit/UnHighlight Regexp", "R", menu_regexp_unhighlight, WV_MENU_EUHR, ""), #ifdef MAC_INTEGRATION WAVE_GTKIFE("/Edit/Highlight All", NULL, menu_dataformat_highlight_all, WV_MENU_EHA, ""), WAVE_GTKIFE("/Edit/UnHighlight All", NULL, menu_dataformat_unhighlight_all, WV_MENU_EUHA, ""), #else WAVE_GTKIFE("/Edit/Highlight All", "A", menu_dataformat_highlight_all, WV_MENU_EHA, ""), WAVE_GTKIFE("/Edit/UnHighlight All", "A", menu_dataformat_unhighlight_all, WV_MENU_EUHA, ""), #endif WAVE_GTKIFE("/Edit/", NULL, NULL, WV_MENU_SEP6B, ""), WAVE_GTKIFE("/Edit/Sort/Alphabetize All", NULL, menu_alphabetize, WV_MENU_ALPHA, ""), WAVE_GTKIFE("/Edit/Sort/Alphabetize All (CaseIns)", NULL, menu_alphabetize2, WV_MENU_ALPHA2, ""), WAVE_GTKIFE("/Edit/Sort/Sigsort All", NULL, menu_lexize, WV_MENU_LEX, ""), WAVE_GTKIFE("/Edit/Sort/Reverse All", NULL, menu_reverse, WV_MENU_RVS, ""), /* 70 */ WAVE_GTKIFE("/Search/Pattern Search 1", NULL, menu_tracesearchbox, WV_MENU_SPS, ""), #ifdef WAVE_USE_GTK2 WAVE_GTKIFE("/Search/Pattern Search 2", NULL, menu_tracesearchbox, WV_MENU_SPS2, ""), #endif WAVE_GTKIFE("/Search/", NULL, NULL, WV_MENU_SEP7B, ""), WAVE_GTKIFE("/Search/Signal Search Regexp", "S", menu_signalsearch, WV_MENU_SSR, ""), WAVE_GTKIFE("/Search/Signal Search Hierarchy", "T", menu_hiersearch, WV_MENU_SSH, ""), WAVE_GTKIFE("/Search/Signal Search Tree", "T", menu_treesearch, WV_MENU_SST, ""), WAVE_GTKIFE("/Search/", NULL, NULL, WV_MENU_SEP7, ""), #if !defined __MINGW32__ && !defined _MSC_VER WAVE_GTKIFE("/Search/Open Source Definition", NULL, menu_open_hierarchy_source, WV_MENU_OPENHS, ""), WAVE_GTKIFE("/Search/Open Source Instantiation", NULL, menu_open_hierarchy_isource, WV_MENU_OPENIHS, ""), #endif WAVE_GTKIFE("/Search/Open Scope", NULL, menu_open_hierarchy, WV_MENU_OPENH, ""), WAVE_GTKIFE("/Search/", NULL, NULL, WV_MENU_SEP7D, ""), WAVE_GTKIFE("/Search/Autocoalesce", NULL, menu_autocoalesce, WV_MENU_ACOL, ""), WAVE_GTKIFE("/Search/Autocoalesce Reversal", NULL, menu_autocoalesce_reversal, WV_MENU_ACOLR, ""), WAVE_GTKIFE("/Search/Autoname Bundles", NULL, menu_autoname_bundles_on, WV_MENU_ABON, ""), WAVE_GTKIFE("/Search/Search Hierarchy Grouping", NULL, menu_hgrouping, WV_MENU_HTGP, ""), /* 80 */ WAVE_GTKIFE("/Search/", NULL, NULL, WV_MENU_SEP7C, ""), WAVE_GTKIFE("/Search/Set Pattern Search Repeat Count", NULL, menu_strace_repcnt, WV_MENU_STRSE, ""), WAVE_GTKIFE("/Time/Move To Time", "F1", menu_movetotime, WV_MENU_TMTT, ""), WAVE_GTKIFE("/Time/Zoom/Zoom Amount", "F2", menu_zoomsize, WV_MENU_TZZA, ""), WAVE_GTKIFE("/Time/Zoom/Zoom Base", "F2", menu_zoombase, WV_MENU_TZZB, ""), WAVE_GTKIFE("/Time/Zoom/Zoom In", "Z", service_zoom_in_marshal, WV_MENU_TZZI, ""), WAVE_GTKIFE("/Time/Zoom/Zoom Out", "Z", service_zoom_out_marshal, WV_MENU_TZZO, ""), WAVE_GTKIFE("/Time/Zoom/Zoom Full", "F", service_zoom_full_marshal, WV_MENU_TZZBFL, ""), WAVE_GTKIFE("/Time/Zoom/Zoom Best Fit", "F", service_zoom_fit_marshal, WV_MENU_TZZBF, ""), WAVE_GTKIFE("/Time/Zoom/Zoom To Start", "Home", service_zoom_left_marshal, WV_MENU_TZZTS, ""), WAVE_GTKIFE("/Time/Zoom/Zoom To End", "End", service_zoom_right_marshal, WV_MENU_TZZTE, ""), WAVE_GTKIFE("/Time/Zoom/Undo Zoom", "U", service_zoom_undo_marshal, WV_MENU_TZUZ, ""), /* 90 */ WAVE_GTKIFE("/Time/Fetch/Fetch Size", "F7", menu_fetchsize, WV_MENU_TFFS, ""), WAVE_GTKIFE("/Time/Fetch/Fetch ->", "2", fetch_right_marshal, WV_MENU_TFFR, ""), WAVE_GTKIFE("/Time/Fetch/Fetch <-", "1", fetch_left_marshal, WV_MENU_TFFL, ""), WAVE_GTKIFE("/Time/Discard/Discard ->", "4", discard_right_marshal, WV_MENU_TDDR, ""), WAVE_GTKIFE("/Time/Discard/Discard <-", "3", discard_left_marshal, WV_MENU_TDDL, ""), WAVE_GTKIFE("/Time/Shift/Shift ->", "6", service_right_shift_marshal, WV_MENU_TSSR, ""), WAVE_GTKIFE("/Time/Shift/Shift <-", "5", service_left_shift_marshal, WV_MENU_TSSL, ""), WAVE_GTKIFE("/Time/Page/Page ->", "8", service_right_page_marshal, WV_MENU_TPPR, ""), WAVE_GTKIFE("/Time/Page/Page <-", "7", service_left_page_marshal, WV_MENU_TPPL, ""), WAVE_GTKIFE("/Markers/Show-Change Marker Data", "M", menu_markerbox, WV_MENU_MSCMD, ""), /* 100 */ WAVE_GTKIFE("/Markers/Drop Named Marker", "N", drop_named_marker, WV_MENU_MDNM, ""), WAVE_GTKIFE("/Markers/Collect Named Marker", "N", collect_named_marker, WV_MENU_MCNM, ""), WAVE_GTKIFE("/Markers/Collect All Named Markers", "N", collect_all_named_markers, WV_MENU_MCANM, ""), #ifdef MAC_INTEGRATION WAVE_GTKIFE("/Markers/Copy Primary->B Marker", NULL, copy_pri_b_marker, WV_MENU_MCAB, ""), #else WAVE_GTKIFE("/Markers/Copy Primary->B Marker", "B", copy_pri_b_marker, WV_MENU_MCAB, ""), #endif WAVE_GTKIFE("/Markers/Delete Primary Marker", "M", delete_unnamed_marker, WV_MENU_MDPM, ""), WAVE_GTKIFE("/Markers/", NULL, NULL, WV_MENU_SEP8, ""), WAVE_GTKIFE("/Markers/Find Previous Edge", NULL, service_left_edge_marshal, WV_MENU_SLE, ""), WAVE_GTKIFE("/Markers/Find Next Edge", NULL, service_right_edge_marshal, WV_MENU_SRE, ""), WAVE_GTKIFE("/Markers/", NULL, NULL, WV_MENU_SEP8B, ""), WAVE_GTKIFE("/Markers/Alternate Wheel Mode", NULL, menu_altwheel, WV_MENU_HSWM, ""), WAVE_GTKIFE("/Markers/Wave Scrolling", "F9", wave_scrolling_on, WV_MENU_MWSON, ""), WAVE_GTKIFE("/Markers/Locking/Lock to Lesser Named Marker", "Q", lock_marker_left, WV_MENU_MLKLT, ""), WAVE_GTKIFE("/Markers/Locking/Lock to Greater Named Marker", "W", lock_marker_right, WV_MENU_MLKRT, ""), WAVE_GTKIFE("/Markers/Locking/Unlock from Named Marker", "O", unlock_marker, WV_MENU_MLKOFF, ""), WAVE_GTKIFE("/View/Show Grid", "G", menu_show_grid, WV_MENU_VSG, ""), WAVE_GTKIFE("/View/", NULL, NULL, WV_MENU_SEP9, ""), WAVE_GTKIFE("/View/Show Wave Highlight", NULL, menu_show_wave_highlight, WV_MENU_SHW, ""), WAVE_GTKIFE("/View/", NULL, NULL, WV_MENU_SEP9B, ""), WAVE_GTKIFE("/View/Show Mouseover", NULL, menu_show_mouseover, WV_MENU_VSMO, ""), WAVE_GTKIFE("/View/", NULL, NULL, WV_MENU_SEP9A, ""), WAVE_GTKIFE("/View/Show Base Symbols", "F1", menu_show_base, WV_MENU_VSBS, ""), WAVE_GTKIFE("/View/", NULL, NULL, WV_MENU_SEP10, ""), /* 110 */ WAVE_GTKIFE("/View/Standard Trace Select", NULL, menu_enable_standard_trace_select, WV_MENU_ESTS, ""), WAVE_GTKIFE("/View/", NULL, NULL, WV_MENU_SEP10A, ""), WAVE_GTKIFE("/View/Dynamic Resize", "9", menu_enable_dynamic_resize, WV_MENU_VDR, ""), WAVE_GTKIFE("/View/", NULL, NULL, WV_MENU_SEP11, ""), WAVE_GTKIFE("/View/Center Zooms", "F8", menu_center_zooms, WV_MENU_VCZ, ""), WAVE_GTKIFE("/View/", NULL, NULL, WV_MENU_SEP12, ""), WAVE_GTKIFE("/View/Toggle Delta-Frequency", NULL, menu_toggle_delta_or_frequency, WV_MENU_VTDF, ""), WAVE_GTKIFE("/View/Toggle Max-Marker", "F10", menu_toggle_max_or_marker, WV_MENU_VTMM, ""), WAVE_GTKIFE("/View/", NULL, NULL, WV_MENU_SEP13, ""), WAVE_GTKIFE("/View/Constant Marker Update", "F11", menu_enable_constant_marker_update, WV_MENU_VCMU, ""), WAVE_GTKIFE("/View/", NULL, NULL, WV_MENU_SEP14, ""), WAVE_GTKIFE("/View/Draw Roundcapped Vectors", "F2", menu_use_roundcaps, WV_MENU_VDRV, ""), /* 120 */ WAVE_GTKIFE("/View/", NULL, NULL, WV_MENU_SEP15, ""), WAVE_GTKIFE("/View/Left Justified Signals", "Home", menu_left_justify, WV_MENU_VLJS, ""), WAVE_GTKIFE("/View/Right Justified Signals", "End", menu_right_justify, WV_MENU_VRJS, ""), WAVE_GTKIFE("/View/", NULL, NULL, WV_MENU_SEP16, ""), WAVE_GTKIFE("/View/Zoom Pow10 Snap", "Pause", menu_zoom10_snap, WV_MENU_VZPS, ""), WAVE_GTKIFE("/View/Partial VCD Dynamic Zoom Full", NULL, menu_zoom_dynf, WV_MENU_VZDYN, ""), WAVE_GTKIFE("/View/Partial VCD Dynamic Zoom To End", NULL, menu_zoom_dyne, WV_MENU_VZDYNE, ""), WAVE_GTKIFE("/View/Full Precision", "Pause", menu_use_full_precision, WV_MENU_VFTP, ""), WAVE_GTKIFE("/View/", NULL, NULL, WV_MENU_SEP17, ""), WAVE_GTKIFE("/View/Define Time Ruler Marks", NULL, menu_def_ruler, WV_MENU_RULER, ""), WAVE_GTKIFE("/View/Remove Pattern Marks", NULL, menu_remove_marked, WV_MENU_RMRKS, ""), WAVE_GTKIFE("/View/", NULL, NULL, WV_MENU_SEP17A, ""), WAVE_GTKIFE("/View/Use Color", NULL, menu_use_color, WV_MENU_USECOLOR, ""), WAVE_GTKIFE("/View/Use Black and White", NULL, menu_use_bw, WV_MENU_USEBW, ""), WAVE_GTKIFE("/View/", NULL, NULL, WV_MENU_SEP18, ""), WAVE_GTKIFE("/View/LXT Clock Compress to Z", NULL, menu_lxt_clk_compress, WV_MENU_LXTCC2Z, ""), WAVE_GTKIFE("/View/", NULL, NULL, WV_MENU_SEP19, ""), WAVE_GTKIFE("/View/Scale To Time Dimension/None", NULL, menu_scale_to_td_x, WV_MENU_TDSCALEX, ""), WAVE_GTKIFE("/View/Scale To Time Dimension/sec", NULL, menu_scale_to_td_s, WV_MENU_TDSCALES, ""), WAVE_GTKIFE("/View/Scale To Time Dimension/ms", NULL, menu_scale_to_td_m, WV_MENU_TDSCALEM, ""), WAVE_GTKIFE("/View/Scale To Time Dimension/us", NULL, menu_scale_to_td_u, WV_MENU_TDSCALEU, ""), WAVE_GTKIFE("/View/Scale To Time Dimension/ns", NULL, menu_scale_to_td_n, WV_MENU_TDSCALEN, ""), WAVE_GTKIFE("/View/Scale To Time Dimension/ps", NULL, menu_scale_to_td_p, WV_MENU_TDSCALEP, ""), WAVE_GTKIFE("/View/Scale To Time Dimension/fs", NULL, menu_scale_to_td_f, WV_MENU_TDSCALEF, ""), /* 130 */ WAVE_GTKIFE("/Help/WAVE Help", "H", menu_help, WV_MENU_HWH, ""), #ifdef MAC_INTEGRATION WAVE_GTKIFE("/Help/WAVE User Manual", NULL, menu_help_manual, WV_MENU_HWM, ""), #endif WAVE_GTKIFE("/Help/Wave Version", NULL, menu_version, WV_MENU_HWV, ""), }; #ifndef WAVE_USE_MLIST_T void set_scale_to_time_dimension_toggles(void) { int i; for(i = WV_MENU_TDSCALEX; i<= WV_MENU_TDSCALEF; i++) { GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[i].path))->active=FALSE; } switch(GLOBALS->scale_to_time_dimension) { case 's': i = WV_MENU_TDSCALES; break; case 'm': i = WV_MENU_TDSCALEM; break; case 'u': i = WV_MENU_TDSCALEU; break; case 'n': i = WV_MENU_TDSCALEN; break; case 'p': i = WV_MENU_TDSCALEP; break; case 'f': i = WV_MENU_TDSCALEF; break; default: i = WV_MENU_TDSCALEX; break; } GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[i].path))->active=TRUE; } #else void set_scale_to_time_dimension_toggles(void) { int i, ii; switch(GLOBALS->scale_to_time_dimension) { case 's': ii = WV_MENU_TDSCALES; break; case 'm': ii = WV_MENU_TDSCALEM; break; case 'u': ii = WV_MENU_TDSCALEU; break; case 'n': ii = WV_MENU_TDSCALEN; break; case 'p': ii = WV_MENU_TDSCALEP; break; case 'f': ii = WV_MENU_TDSCALEF; break; default: ii = WV_MENU_TDSCALEX; break; } for(i = WV_MENU_TDSCALEX; i<= WV_MENU_TDSCALEF; i++) { gboolean is_active = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[i])); if(i!=ii) { if(is_active) { gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[i]), FALSE); } } else { if(!is_active) { gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[i]), TRUE); } } } } #endif /* * set toggleitems to their initial states */ #ifndef WAVE_USE_MLIST_T static void set_menu_toggles(void) { GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VZPS].path))->active=(GLOBALS->zoom_pow10_snap)?TRUE:FALSE; GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VSG].path))->active=(GLOBALS->display_grid)?TRUE:FALSE; GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_SHW].path))->active=(GLOBALS->highlight_wavewindow)?TRUE:FALSE; GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_HSWM].path))->active=(GLOBALS->alt_wheel_mode)?TRUE:FALSE; GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1,menu_items[WV_MENU_VSMO].path))->active=(GLOBALS->disable_mouseover)?FALSE:TRUE; GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VSBS].path))->active=(GLOBALS->show_base)?TRUE:FALSE; GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VDR].path))->active=(GLOBALS->do_resize_signals)?TRUE:FALSE; GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_ESTS].path))->active=(GLOBALS->use_standard_trace_select)?TRUE:FALSE; GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VCMU].path))->active=(GLOBALS->constant_marker_update)?TRUE:FALSE; GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VCZ].path))->active=(GLOBALS->do_zoom_center)?TRUE:FALSE; GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VDRV].path))->active=(GLOBALS->use_roundcaps)?TRUE:FALSE; GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_MWSON].path))->active=(GLOBALS->wave_scrolling)?TRUE:FALSE; GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_ABON].path))->active=(GLOBALS->autoname_bundles)?TRUE:FALSE; GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_HTGP].path))->active=(GLOBALS->hier_grouping)?TRUE:FALSE; GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VFTP].path))->active=(GLOBALS->use_full_precision)?TRUE:FALSE; GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_ACOL].path))->active=(GLOBALS->autocoalesce)?TRUE:FALSE; GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_ACOLR].path))->active=(GLOBALS->autocoalesce_reversal)?TRUE:FALSE; GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_KEEPXZ].path))->active=(GLOBALS->keep_xz_colors)?TRUE:FALSE; if(GLOBALS->partial_vcd) { GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VZDYN].path))->active=(GLOBALS->zoom_dyn)?TRUE:FALSE; GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VZDYNE].path))->active=(GLOBALS->zoom_dyne)?TRUE:FALSE; } if(GLOBALS->loaded_file_type == LXT_FILE) { GTK_CHECK_MENU_ITEM(gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_LXTCC2Z].path))->active=(GLOBALS->lxt_clock_compress_to_z)?TRUE:FALSE; } set_scale_to_time_dimension_toggles(); } #else void set_menu_toggles(void) { GLOBALS->quiet_checkmenu = 1; gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VZPS]), GLOBALS->zoom_pow10_snap); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VSG]), GLOBALS->display_grid); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_SHW]), GLOBALS->highlight_wavewindow); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_HSWM]), GLOBALS->alt_wheel_mode); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VSMO]), !GLOBALS->disable_mouseover); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VSBS]), GLOBALS->show_base); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VDR]), GLOBALS->do_resize_signals); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_ESTS]), GLOBALS->use_standard_trace_select); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VCMU]), GLOBALS->constant_marker_update); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VCZ]), GLOBALS->do_zoom_center); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VDRV]), GLOBALS->use_roundcaps); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_MWSON]), GLOBALS->wave_scrolling); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_ABON]), GLOBALS->autoname_bundles); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_HTGP]), GLOBALS->hier_grouping); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VFTP]), GLOBALS->use_full_precision); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_ACOL]), GLOBALS->autocoalesce); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_ACOLR]), GLOBALS->autocoalesce_reversal); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_KEEPXZ]), GLOBALS->keep_xz_colors); if(GLOBALS->partial_vcd) { gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VZDYN]), GLOBALS->zoom_dyn); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VZDYNE]), GLOBALS->zoom_dyne); } if(GLOBALS->loaded_file_type == LXT_FILE) { gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_LXTCC2Z]), GLOBALS->lxt_clock_compress_to_z); } set_scale_to_time_dimension_toggles(); GLOBALS->quiet_checkmenu = 0; } #endif /* * create the menu through an itemfactory instance */ #ifndef WAVE_USE_MLIST_T void get_main_menu(GtkWidget *window, GtkWidget ** menubar) { int nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]); GtkAccelGroup *global_accel; int i; GtkWidget *mw; GLOBALS->regexp_string_menu_c_1 = calloc_2(1, 129); global_accel = gtk_accel_group_new(); GLOBALS->item_factory_menu_c_1 = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "
", global_accel); gtk_item_factory_create_items(GLOBALS->item_factory_menu_c_1, nmenu_items, menu_items, NULL); if(GLOBALS->loaded_file_type == MISSING_FILE) { for(i=0;iitem_factory_menu_c_1, menu_items[i].path); if(mw) gtk_widget_set_sensitive(mw, FALSE); break; } } #ifdef WAVE_USE_MENU_BLACKOUTS for(i=0;i<(sizeof(menu_blackouts)/sizeof(char *));i++) { mw = gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_blackouts[i]); if(mw) gtk_widget_set_sensitive(mw, FALSE); } #endif } if( #ifdef WAVE_USE_GTK2 (GLOBALS->socket_xid)|| #endif (GLOBALS->partial_vcd)) { gtk_item_factory_delete_item(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_FONVT].path); } if(!GLOBALS->partial_vcd) { gtk_item_factory_delete_item(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VZDYN].path); gtk_item_factory_delete_item(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_VZDYNE].path); } if(GLOBALS->loaded_file_type == DUMPLESS_FILE) { gtk_item_factory_delete_item(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_FRW].path); } if(GLOBALS->loaded_file_type != LXT_FILE) { gtk_item_factory_delete_item(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_SEP18].path); gtk_item_factory_delete_item(GLOBALS->item_factory_menu_c_1, menu_items[WV_MENU_LXTCC2Z].path); } gtk_window_add_accel_group(GTK_WINDOW(window), global_accel); if(menubar) { *menubar = gtk_item_factory_get_widget (GLOBALS->item_factory_menu_c_1, "
"); set_menu_toggles(); } } #endif void menu_set_sensitive(void) { int nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]); int i; GtkWidget *mw; #ifdef WAVE_USE_MENU_BLACKOUTS for(i=0;i<(sizeof(menu_blackouts)/sizeof(char *));i++) { mw = gtk_item_factory_get_widget(GLOBALS->item_factory_menu_c_1, menu_blackouts[i]); if(mw) gtk_widget_set_sensitive(mw, TRUE); } #endif for(i=0;iitem_factory_menu_c_1, menu_items[i].path); #endif if(mw) { #ifdef MAC_INTEGRATION if(menu_items[i].callback) #endif { gtk_widget_set_sensitive(mw, TRUE); } } break; } } } /* * bail out */ int file_quit_cmd_callback (GtkWidget *widget, gpointer data) { (void)widget; (void)data; if(!GLOBALS->enable_fast_exit) { simplereqbox("Quit Program",300,"Do you really want to quit?","Yes", "No", GTK_SIGNAL_FUNC(menu_quit_callback), 1); } else { #ifdef __CYGWIN__ kill_stems_browser(); #endif g_print ("WM Destroy\n"); gtk_exit(0); } return(TRUE); /* keeps "delete_event" from happening...we'll manually destory later if need be */ } /* * RPC */ int execute_script(char *name, int dealloc_name) { unsigned int i; int nlen = strlen(name); if(GLOBALS->tcl_running) { fprintf(stderr, "Could not run script file '%s', as one is already running.\n", name); if(dealloc_name) { free_2(name); } return(0); } GLOBALS->tcl_running = 1; if(1) /* all scripts are Tcl now */ { #if defined(HAVE_LIBTCL) int tclrc; char *tcl_cmd = wave_alloca(7 + nlen + 1); /* originally a malloc, but the script can change the context! */ strcpy(tcl_cmd, "source "); strcpy(tcl_cmd+7, name); fprintf(stderr, "GTKWAVE | Executing Tcl script '%s'\n", name); if(dealloc_name) { free_2(name); } #ifdef WIN32 { char *slashfix = tcl_cmd; while(*slashfix) { if(*slashfix=='\\') *slashfix='/'; slashfix++; } } #endif tclrc = Tcl_Eval (GLOBALS->interp, tcl_cmd); if(tclrc != TCL_OK) { fprintf (stderr, "GTKWAVE | %s\n", Tcl_GetStringResult (GLOBALS->interp)); } #else fprintf(stderr, "GTKWAVE | Tcl support not compiled into gtkwave, exiting.\n"); gtk_exit(255); #endif } for(i=0;inum_notebook_pages;i++) { (*GLOBALS->contexts)[i]->wave_script_args = NULL; /* just in case there was a CTX swap */ } GLOBALS->tcl_running = 0; return(0); } gtkwave_mlist_t *retrieve_menu_items_array(int *num_items) { *num_items = sizeof(menu_items) / sizeof(menu_items[0]); return(menu_items); } /* * support for menu accelerator modifications... */ int set_wave_menu_accelerator(char *str) { char *path, *pathend; char *accel; int i; path = strchr(str, '\"'); if(!path) return(1); path++; if(!*path) return(1); pathend = strchr(path, '\"'); if(!pathend) return(1); *pathend = 0; accel = pathend + 1; while(*accel) { if(!isspace((int)(unsigned char)*accel)) break; accel++; } if(!*accel) return(1); if(strstr(path, "")) return(1); if(!strcmp(accel, "(null)")) { accel = NULL; } else { for(i=0;i"), WAVE_GTKIFE("/Data Format/Decimal", NULL, menu_dataformat_dec, WV_MENU_EDFD, ""), WAVE_GTKIFE("/Data Format/Signed Decimal", NULL, menu_dataformat_signed, WV_MENU_EDFSD, ""), WAVE_GTKIFE("/Data Format/Binary", NULL, menu_dataformat_bin, WV_MENU_EDFB, ""), WAVE_GTKIFE("/Data Format/Octal", NULL, menu_dataformat_oct, WV_MENU_EDFO, ""), WAVE_GTKIFE("/Data Format/ASCII", NULL, menu_dataformat_ascii, WV_MENU_EDFA, ""), WAVE_GTKIFE("/Data Format/BitsToReal", NULL, menu_dataformat_real, WV_MENU_EDRL, ""), WAVE_GTKIFE("/Data Format/RealToBits/On", NULL, menu_dataformat_real2bon, WV_MENU_EDR2BON, ""), WAVE_GTKIFE("/Data Format/RealToBits/Off", NULL, menu_dataformat_real2boff, WV_MENU_EDR2BOFF, ""), WAVE_GTKIFE("/Data Format/Right Justify/On", NULL, menu_dataformat_rjustify_on, WV_MENU_EDFRJON, ""), WAVE_GTKIFE("/Data Format/Right Justify/Off", NULL, menu_dataformat_rjustify_off, WV_MENU_EDFRJOFF, ""), WAVE_GTKIFE("/Data Format/Invert/On", NULL, menu_dataformat_invert_on, WV_MENU_EDFION, ""), WAVE_GTKIFE("/Data Format/Invert/Off", NULL, menu_dataformat_invert_off, WV_MENU_EDFIOFF, ""), WAVE_GTKIFE("/Data Format/Reverse Bits/On", NULL, menu_dataformat_reverse_on, WV_MENU_EDFRON, ""), WAVE_GTKIFE("/Data Format/Reverse Bits/Off", NULL, menu_dataformat_reverse_off, WV_MENU_EDFROFF, ""), WAVE_GTKIFE("/Data Format/Translate Filter File/Disable", NULL, menu_dataformat_xlate_file_0, WV_MENU_XLF_0, ""), WAVE_GTKIFE("/Data Format/Translate Filter File/Enable and Select", NULL, menu_dataformat_xlate_file_1, WV_MENU_XLF_1, ""), WAVE_GTKIFE("/Data Format/Translate Filter Process/Disable", NULL, menu_dataformat_xlate_proc_0, WV_MENU_XLP_0, ""), WAVE_GTKIFE("/Data Format/Translate Filter Process/Enable and Select", NULL, menu_dataformat_xlate_proc_1, WV_MENU_XLP_1, ""), WAVE_GTKIFE("/Data Format/Transaction Filter Process/Disable", NULL, menu_dataformat_xlate_ttrans_0, WV_MENU_TTXLP_0, ""), WAVE_GTKIFE("/Data Format/Transaction Filter Process/Enable and Select", NULL, menu_dataformat_xlate_ttrans_1, WV_MENU_TTXLP_1, ""), WAVE_GTKIFE("/Data Format/Analog/Off", NULL, menu_dataformat_analog_off, WV_MENU_EDFAOFF, ""), WAVE_GTKIFE("/Data Format/Analog/Step", NULL, menu_dataformat_analog_step, WV_MENU_EDFASTEP, ""), WAVE_GTKIFE("/Data Format/Analog/Interpolated", NULL, menu_dataformat_analog_interpol, WV_MENU_EDFAINTERPOL, ""), WAVE_GTKIFE("/Data Format/Analog/Interpolated Annotated", NULL, menu_dataformat_analog_interpol_step, WV_MENU_EDFAINTERPOL2, ""), WAVE_GTKIFE("/Data Format/Analog/Resizing/Screen Data", NULL, menu_dataformat_analog_resize_screen, WV_MENU_EDFARSD, ""), WAVE_GTKIFE("/Data Format/Analog/Resizing/All Data", NULL, menu_dataformat_analog_resize_all, WV_MENU_EDFARAD, ""), WAVE_GTKIFE("/Data Format/Range Fill/With 0s", NULL, menu_dataformat_rangefill_zero, WV_MENU_RFILL0, ""), WAVE_GTKIFE("/Data Format/Range Fill/With 1s", NULL, menu_dataformat_rangefill_one, WV_MENU_RFILL1, ""), WAVE_GTKIFE("/Data Format/Range Fill/Off", NULL, menu_dataformat_rangefill_off, WV_MENU_RFILLOFF, ""), WAVE_GTKIFE("/Data Format/Gray Filters/To Gray", NULL, menu_dataformat_bingray_on, WV_MENU_B2G, ""), WAVE_GTKIFE("/Data Format/Gray Filters/From Gray", NULL, menu_dataformat_graybin_on, WV_MENU_G2B, ""), WAVE_GTKIFE("/Data Format/Gray Filters/None", NULL, menu_dataformat_nogray, WV_MENU_GBNONE, ""), WAVE_GTKIFE("/Data Format/Popcnt/On", NULL, menu_dataformat_popcnt_on, WV_MENU_POPON, ""), WAVE_GTKIFE("/Data Format/Popcnt/Off", NULL, menu_dataformat_popcnt_off, WV_MENU_POPOFF, ""), WAVE_GTKIFE("/Color Format/Normal", NULL, menu_colorformat_0, WV_MENU_CLRFMT0, ""), WAVE_GTKIFE("/Color Format/Red", NULL, menu_colorformat_1, WV_MENU_CLRFMT1, ""), WAVE_GTKIFE("/Color Format/Orange", NULL, menu_colorformat_2, WV_MENU_CLRFMT2, ""), WAVE_GTKIFE("/Color Format/Yellow", NULL, menu_colorformat_3, WV_MENU_CLRFMT3, ""), WAVE_GTKIFE("/Color Format/Green", NULL, menu_colorformat_4, WV_MENU_CLRFMT4, ""), WAVE_GTKIFE("/Color Format/Blue", NULL, menu_colorformat_5, WV_MENU_CLRFMT5, ""), WAVE_GTKIFE("/Color Format/Indigo", NULL, menu_colorformat_6, WV_MENU_CLRFMT6, ""), WAVE_GTKIFE("/Color Format/Violet", NULL, menu_colorformat_7, WV_MENU_CLRFMT7, ""), WAVE_GTKIFE("/Color Format/Cycle", NULL, menu_colorformat_cyc, WV_MENU_CLRFMTC, ""), WAVE_GTKIFE("/", NULL, NULL, WV_MENU_SEP1, ""), WAVE_GTKIFE("/Insert Analog Height Extension", NULL, menu_insert_analog_height_extension, WV_MENU_EIA, ""), WAVE_GTKIFE("/", NULL, NULL, WV_MENU_SEP2, ""), WAVE_GTKIFE("/Insert Blank", NULL, menu_insert_blank_traces, WV_MENU_EIB, ""), WAVE_GTKIFE("/Insert Comment", NULL, menu_insert_comment_traces, WV_MENU_EIC, ""), WAVE_GTKIFE("/Alias Highlighted Trace", NULL, menu_alias, WV_MENU_EAHT, ""), WAVE_GTKIFE("/Remove Highlighted Aliases", NULL, menu_remove_aliases, WV_MENU_ERHA, ""), WAVE_GTKIFE("/", NULL, NULL, WV_MENU_SEP3, ""), WAVE_GTKIFE("/Cut", NULL, menu_cut_traces, WV_MENU_EC, ""), WAVE_GTKIFE("/Copy", NULL, menu_copy_traces, WV_MENU_ECY, ""), WAVE_GTKIFE("/Paste", NULL, menu_paste_traces, WV_MENU_EP, ""), WAVE_GTKIFE("/", NULL, NULL, WV_MENU_SEP4, ""), WAVE_GTKIFE("/Open Scope", NULL, menu_open_hierarchy, WV_MENU_OPENH, "") #if !defined __MINGW32__ && !defined _MSC_VER , /* see do_popup_menu() for specific patch for this for if(!GLOBALS->stem_path_string_table) ... */ WAVE_GTKIFE("/Open Source Definition", NULL, menu_open_hierarchy_source, WV_MENU_OPENHS, ""), WAVE_GTKIFE("/Open Source Instantiation", NULL, menu_open_hierarchy_isource, WV_MENU_OPENIHS, "") #endif }; void do_popup_menu (GtkWidget *my_widget, GdkEventButton *event) { (void)my_widget; GtkWidget *menu; int button, event_time; if(!GLOBALS->signal_popup_menu) { int nmenu_items = sizeof(popmenu_items) / sizeof(popmenu_items[0]); #if !defined __MINGW32__ && !defined _MSC_VER if(!GLOBALS->stem_path_string_table) { nmenu_items = nmenu_items - 2; /* to remove WV_MENU_OPENHS, WV_MENU_OPENIHS -> keep at end of list! */ } else { if(!GLOBALS->istem_struct_base) { nmenu_items--; /* remove "/Open Source Instantiation" if not present */ } } #endif #ifdef WAVE_USE_MLIST_T GLOBALS->signal_popup_menu = menu = alt_menu(popmenu_items, nmenu_items, NULL, NULL, FALSE); #else GtkItemFactory *item_factory = gtk_item_factory_new (GTK_TYPE_MENU, "
", NULL); gtk_item_factory_create_items (item_factory, nmenu_items, popmenu_items, NULL); GLOBALS->signal_popup_menu = menu = gtk_item_factory_get_widget (item_factory, "
"); #endif } else { menu = GLOBALS->signal_popup_menu; } if (event) { button = event->button; event_time = event->time; } else { button = 0; #if WAVE_USE_GTK2 event_time = gtk_get_current_event_time (); #else return; /* disabled in GTK1.2 */ #endif } gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, button, event_time); } /***************************/ /*** sst popup menu code ***/ /***************************/ #if !defined __MINGW32__ && !defined _MSC_VER static gtkwave_mlist_t sst_popmenu_items[] = { WAVE_GTKIFE("/Open Source Definition", NULL, menu_open_sst_hierarchy_source, WV_MENU_OPENHS, ""), WAVE_GTKIFE("/Open Source Instantiation", NULL, menu_open_sst_hierarchy_isource, WV_MENU_OPENIHS, "") }; void do_sst_popup_menu (GtkWidget *my_widget, GdkEventButton *event) { (void)my_widget; GtkWidget *menu; int button, event_time; if(!GLOBALS->stem_path_string_table) { return; /* no stems so no popup */ } if(!GLOBALS->sst_signal_popup_menu) { int nmenu_items = sizeof(sst_popmenu_items) / sizeof(sst_popmenu_items[0]); if(!GLOBALS->istem_struct_base) { nmenu_items--; /* remove "/Open Source Instantiation" if not present */ } #ifdef WAVE_USE_MLIST_T GLOBALS->sst_signal_popup_menu = menu = alt_menu(sst_popmenu_items, nmenu_items, NULL, NULL, FALSE); #else GtkItemFactory *item_factory = gtk_item_factory_new (GTK_TYPE_MENU, "
", NULL); gtk_item_factory_create_items (item_factory, nmenu_items, sst_popmenu_items, NULL); GLOBALS->sst_signal_popup_menu = menu = gtk_item_factory_get_widget (item_factory, "
"); #endif } else { menu = GLOBALS->sst_signal_popup_menu; } if (event) { button = event->button; event_time = event->time; } else { button = 0; #if WAVE_USE_GTK2 event_time = gtk_get_current_event_time (); #else return; /* disabled in GTK1.2 */ #endif } gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, button, event_time); } #else void do_sst_popup_menu (GtkWidget *my_widget, GdkEventButton *event) { /* nothing */ } #endif void SetTraceScrollbarRowValue(int row, unsigned location) { if(row >= 0) { GtkAdjustment *wadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider); int target = row; int num_traces_displayable=(GLOBALS->signalarea->allocation.height)/(GLOBALS->fontheight); num_traces_displayable--; /* for the time trace that is always there */ /* center */ if (location == 1) { target = target - num_traces_displayable/2; } /* end */ if (location == 2) { target = target - num_traces_displayable; } if(target > GLOBALS->traces.visible - num_traces_displayable) target = GLOBALS->traces.visible - num_traces_displayable; if(target < 0) target = 0; wadj->value = target; gtk_signal_emit_by_name (GTK_OBJECT (wadj), "changed"); /* force bar update */ gtk_signal_emit_by_name (GTK_OBJECT (wadj), "value_changed"); /* force text update */ gtkwave_main_iteration(); } } #ifdef WAVE_USE_MLIST_T /* * the following is for the eventual migration to GtkMenu from the item factory. * all menu features are implemented. */ struct menu_item_t { struct menu_item_t *next; struct menu_item_t *child; char *name; int idx; unsigned valid : 1; }; static void decompose_path(char *pathname, int *items, char ***parts) { char *s, **slashes; int i; int slashcount = 0; char *p_copy = strdup_2(pathname); s = p_copy; while(*s) { if(*s == '/') slashcount++; s++; } *parts = calloc_2(slashcount, sizeof(char *)); slashes = calloc_2(slashcount, sizeof(char *)); s = p_copy; slashcount = 0; while(*s) { if(*s == '/') slashes[slashcount++] = s;; s++; } for(i=0;i%s", path); if(accelerator) { gtk_accelerator_parse(accelerator, &accelerator_key, &accelerator_mods); #ifdef MAC_INTEGRATION if((accelerator_mods & GDK_MOD1_MASK) || (!accelerator_mods) || (accelerator_mods == GDK_SHIFT_MASK)) { no_map = 1; /* ALT not available with GTK menus on OSX? */ /* also remove "normal" keys to avoid conflicts with OSX menubar */ } if(accelerator_mods & GDK_CONTROL_MASK) { accelerator_mods &= ~GDK_CONTROL_MASK; accelerator_mods |= GDK_META_MASK; } #endif } if(!no_map) { gtk_accel_map_add_entry (full_path, accelerator_key, accelerator_mods); gtk_widget_set_accel_path (menuitem, full_path, accel); } } } static GtkWidget *alt_menu_walk(gtkwave_mlist_t *mi, GtkWidget **wlist, struct menu_item_t *lst, int depth, GtkAccelGroup *accel) { struct menu_item_t *ptr = lst; struct menu_item_t *optr; GtkWidget *menu; GtkWidget *menuitem; if(depth) { menu = gtk_menu_new(); if(accel) gtk_menu_set_accel_group (GTK_MENU(menu), accel); } else { menu = gtk_menu_bar_new(); } while(ptr) { /* mi[ptr->idx] is menu item */ if(!strcmp(mi[ptr->idx].item_type, "")) { #ifdef MAC_INTEGRATION menuitem = gtk_separator_menu_item_new(); #else menuitem = gtk_menu_item_new(); #endif } else { if((!strcmp(mi[ptr->idx].item_type, "")) && !ptr->child) { menuitem = gtk_check_menu_item_new_with_label(ptr->name); } else { menuitem = gtk_menu_item_new_with_label(ptr->name); } if(!ptr->child && mi[ptr->idx].callback) { g_signal_connect (menuitem, "activate", G_CALLBACK (mi[ptr->idx].callback), (gpointer)(long)mi[ptr->idx].callback_action); alt_menu_install_accelerator(accel, menuitem, mi[ptr->idx].accelerator, mi[ptr->idx].path); } } gtk_menu_shell_append(GTK_MENU_SHELL (menu), menuitem); gtk_widget_show (menuitem); if(wlist) { wlist[ptr->idx] = menuitem; } if(ptr->child) { gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), alt_menu_walk(mi, wlist, ptr->child, depth+1, accel)); } optr = ptr; ptr = ptr->next; free_2(optr->name); free_2(optr); } return(menu); } GtkWidget *alt_menu(gtkwave_mlist_t *mi, int nmenu_items, GtkWidget **wlist, GtkAccelGroup *accel, gboolean is_menubar) { int i, j; struct menu_item_t *mtree = calloc_2(1, sizeof(struct menu_item_t)); struct menu_item_t *n, *n2 = NULL, *n3; GtkWidget *menubar; for(i=0;iname && (j != (items-1))) /* 2nd comparison is to let separators through */ { n2 = n; while(n2) { if(!strcmp(n2->name, parts[j])) break; n2 = n2->next; } } else { n2 = NULL; } if(!n2) { n3 = (j != (items-1)) ? calloc_2(1, sizeof(struct menu_item_t)) : NULL; assert(n != NULL); /* scan-build */ if(n->name) { while(n->next) { n = n->next; } n->next = calloc_2(1, sizeof(struct menu_item_t)); n = n->next; } n->name = strdup_2(parts[j]); n->child = n3; n2 = n; n = n3; } else { n = n2->child; } } if(n2) /* scan-build */ { n2->idx = i; n2->valid = 1; } free_decomposed_path(items, parts); } menubar = alt_menu_walk(mi, wlist, mtree, is_menubar ? 0 : 1, accel); /* returns a menubar */ return(menubar); } GtkWidget *alt_menu_top(GtkWidget *window) { gtkwave_mlist_t *mi = menu_items; int nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]); GtkWidget *menubar; GtkAccelGroup *global_accel = gtk_accel_group_new();; int i; GtkWidget *mw; menu_wlist = calloc(nmenu_items, sizeof(GtkWidget *)); /* calloc, not calloc_2() */ menubar = alt_menu(mi, nmenu_items, menu_wlist, global_accel, TRUE); GLOBALS->regexp_string_menu_c_1 = calloc_2(1, 129); if(GLOBALS->loaded_file_type == MISSING_FILE) { for(i=0;isocket_xid)|| (GLOBALS->partial_vcd)) { gtk_widget_destroy(menu_wlist[WV_MENU_FONVT]); } if(!GLOBALS->partial_vcd) { gtk_widget_destroy(menu_wlist[WV_MENU_VZDYN]); gtk_widget_destroy(menu_wlist[WV_MENU_VZDYNE]); } if(GLOBALS->loaded_file_type == DUMPLESS_FILE) { gtk_widget_destroy(menu_wlist[WV_MENU_FRW]); } if(GLOBALS->loaded_file_type != LXT_FILE) { gtk_widget_destroy(menu_wlist[WV_MENU_SEP18]); gtk_widget_destroy(menu_wlist[WV_MENU_LXTCC2Z]); } gtk_window_add_accel_group(GTK_WINDOW(window), global_accel); #ifdef MAC_INTEGRATION #if defined(HAVE_LIBTCL) gtk_widget_hide(menu_wlist[WV_MENU_TCLSEP]); #endif gtk_widget_hide(menu_wlist[WV_MENU_FQY]); #endif set_menu_toggles(); return(menubar); } #ifdef MAC_INTEGRATION void osx_menu_sensitivity(gboolean tr) { GtkWidget *mw; int nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]); int i; for(i=0;iloaded_file_type != MISSING_FILE) { osx_menu_sensitivity(TRUE); } else { int i; GtkWidget *mw; int nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]); for(i=0;i #include #include "vcd.h" struct vcd_keyword { const char *name; int token; }; %} struct vcd_keyword %% event, V_EVENT parameter, V_PARAMETER integer, V_INTEGER real, V_REAL real_parameter, V_REAL_PARAMETER realtime, V_REALTIME reg, V_REG supply0, V_SUPPLY0 supply1, V_SUPPLY1 time, V_TIME tri, V_TRI triand, V_TRIAND trior, V_TRIOR trireg, V_TRIREG tri0, V_TRI0 tri1, V_TRI1 wand, V_WAND wire, V_WIRE wor, V_WOR port, V_PORT in, V_IN out, V_OUT inout, V_INOUT string, V_STRINGTYPE bit, V_BIT logic, V_LOGIC int, V_INT shortint, V_SHORTINT longint, V_LONGINT byte, V_BYTE enum, V_ENUM shortreal, V_SHORTREAL $end, V_END %% int vcd_keyword_code(const char *s, unsigned int len) { const struct vcd_keyword *rc = check_identifier(s, len); return(rc ? rc->token : V_STRING); } gtkwave-3.3.66/src/tree.c0000664000076400007640000005425212341266475014513 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2011. * * 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. */ /* AIX may need this for alloca to work */ #if defined _AIX #pragma alloca #endif #include #include "globals.h" #include "tree.h" #include "vcd.h" enum TreeBuildTypes { MAKETREE_FLATTEN, MAKETREE_LEAF, MAKETREE_NODE }; #ifdef WAVE_USE_STRUCT_PACKING struct tree *talloc_2(size_t siz) { if(GLOBALS->talloc_pool_base) { if((siz + GLOBALS->talloc_idx) <= WAVE_TALLOC_POOL_SIZE) { unsigned char *m = GLOBALS->talloc_pool_base + GLOBALS->talloc_idx; GLOBALS->talloc_idx += siz; return((struct tree *)m); } else if(siz >= WAVE_TALLOC_ALTREQ_SIZE) { return(calloc_2(1, siz)); } } GLOBALS->talloc_pool_base = calloc_2(1, WAVE_TALLOC_POOL_SIZE); GLOBALS->talloc_idx = 0; return(talloc_2(siz)); } #endif /* * init pointers needed for n-way tree */ void init_tree(void) { GLOBALS->module_tree_c_1=(char *)malloc_2(GLOBALS->longestname+1); } /* * extract the next part of the name in the flattened * hierarchy name. return ptr to next name if it exists * else NULL */ static const char *get_module_name(const char *s) { char ch; char *pnt; pnt=GLOBALS->module_tree_c_1; for(;;) { ch=*(s++); if(((ch==GLOBALS->hier_delimeter) || (ch == '|')) && (*s)) /* added && null check to allow possible . at end of name */ { *(pnt)=0; GLOBALS->module_len_tree_c_1 = pnt - GLOBALS->module_tree_c_1; return(s); } if(!(*(pnt++)=ch)) { GLOBALS->module_len_tree_c_1 = pnt - GLOBALS->module_tree_c_1; return(NULL); /* nothing left to extract */ } } } /* * generate unique hierarchy pointer faster that sprintf("%p") * use 7-bit string to generate less characters */ #ifdef _WAVE_HAVE_JUDY static int gen_hier_string(char *dest, void *pnt) { unsigned long p = (unsigned long)(pnt); char *dest_copy = dest; while(p) { *(dest++) = (p & 0x7f) | 0x80; p >>= 7; } *(dest++) = '.'; return(dest - dest_copy); } #endif /* * decorated module cleanup (if judy active) */ int decorated_module_cleanup(void) { #ifdef _WAVE_HAVE_JUDY if(GLOBALS->sym_tree) { JudySLFreeArray(&GLOBALS->sym_tree, PJE0); } if(GLOBALS->sym_tree_addresses) { int rcValue; Word_t Index = 0; for (rcValue = Judy1First(GLOBALS->sym_tree_addresses, &Index, PJE0); rcValue != 0; rcValue = Judy1Next(GLOBALS->sym_tree_addresses, &Index, PJE0)) { ((struct tree *)Index)->children_in_gui = 0; } Judy1FreeArray(&GLOBALS->sym_tree_addresses, PJE0); } #endif return(1); } /* * decorated module add */ void allocate_and_decorate_module_tree_node(unsigned char ttype, const char *scopename, const char *compname, uint32_t scopename_len, uint32_t compname_len, uint32_t t_stem, uint32_t t_istem) { struct tree *t; int mtyp = WAVE_T_WHICH_UNDEFINED_COMPNAME; #ifdef _WAVE_HAVE_JUDY char str[2048]; #endif if(compname && compname[0] && strcmp(scopename, compname)) { int ix = add_to_comp_name_table(compname, compname_len); if(ix) { ix--; mtyp = WAVE_T_WHICH_COMPNAME_START - ix; } } if(GLOBALS->treeroot) { if(GLOBALS->mod_tree_parent) { #ifdef _WAVE_HAVE_JUDY if(GLOBALS->mod_tree_parent->children_in_gui) { PPvoid_t PPValue; /* find with judy */ int len = gen_hier_string(str, GLOBALS->mod_tree_parent); strcpy(str+len, scopename); PPValue = JudySLIns(&GLOBALS->sym_tree, (uint8_t *)str, PJE0); if(*PPValue) { GLOBALS->mod_tree_parent = *PPValue; return; } t = talloc_2(sizeof(struct tree) + scopename_len + 1); *PPValue = t; goto t_allocated; } else { int dep = 0; #endif t = GLOBALS->mod_tree_parent->child; while(t) { if(!strcmp(t->name, scopename)) { GLOBALS->mod_tree_parent = t; return; } t = t->next; #ifdef _WAVE_HAVE_JUDY dep++; #endif } #ifdef _WAVE_HAVE_JUDY if(dep >= FST_TREE_SEARCH_NEXT_LIMIT) { PPvoid_t PPValue; int len = gen_hier_string(str, GLOBALS->mod_tree_parent); GLOBALS->mod_tree_parent->children_in_gui = 1; /* "borrowed" for tree build */ t = GLOBALS->mod_tree_parent->child; Judy1Set ((Pvoid_t)&GLOBALS->sym_tree_addresses, (Word_t)GLOBALS->mod_tree_parent, PJE0); /* assemble judy based on scopename + GLOBALS->mod_tree_parent pnt */ while(t) { strcpy(str+len, t->name); PPValue = JudySLIns(&GLOBALS->sym_tree, (uint8_t *)str, PJE0); *PPValue = t; t = t->next; } strcpy(str+len, scopename); PPValue = JudySLIns(&GLOBALS->sym_tree, (uint8_t *)str, PJE0); t = talloc_2(sizeof(struct tree) + scopename_len + 1); *PPValue = t; goto t_allocated; } } #endif t = talloc_2(sizeof(struct tree) + scopename_len + 1); #ifdef _WAVE_HAVE_JUDY t_allocated: #endif strcpy(t->name, scopename); t->kind = ttype; t->t_which = mtyp; t->t_stem = t_stem; t->t_istem = t_istem; if(GLOBALS->mod_tree_parent->child) { t->next = GLOBALS->mod_tree_parent->child; } GLOBALS->mod_tree_parent->child = t; GLOBALS->mod_tree_parent = t; } else { t = GLOBALS->treeroot; while(t) { if(!strcmp(t->name, scopename)) { GLOBALS->mod_tree_parent = t; return; } t = t->next; } t = talloc_2(sizeof(struct tree) + scopename_len + 1); strcpy(t->name, scopename); t->kind = ttype; t->t_which = mtyp; t->t_stem = t_stem; t->t_istem = t_istem; t->next = GLOBALS->treeroot; GLOBALS->mod_tree_parent = GLOBALS->treeroot = t; } } else { t = talloc_2(sizeof(struct tree) + scopename_len + 1); strcpy(t->name, scopename); t->kind = ttype; t->t_which = mtyp; t->t_stem = t_stem; t->t_istem = t_istem; GLOBALS->mod_tree_parent = GLOBALS->treeroot = t; } } /* * adds back netnames */ int treegraft(struct tree **t) { struct tree *tx = GLOBALS->terminals_tchain_tree_c_1; struct tree *t2; struct tree *par; while(tx) { t2 = tx->next; par = tx->child; tx->child = NULL; if(par) { if(par->child) { tx->next = par->child; par->child = tx; } else { par->child = tx; tx->next = NULL; } } else { if(*t) { tx->next = (*t)->next; (*t)->next = tx; } else { *t = tx; tx->next = NULL; } } tx = t2; } return(1); } /* * unswizzle extended names in tree */ void treenamefix_str(char *s) { while(*s) { if(*s==VCDNAM_ESCAPE) *s=GLOBALS->hier_delimeter; s++; } } void treenamefix(struct tree *t) { struct tree *tnext; if(t->child) treenamefix(t->child); tnext = t->next; while(tnext) { if(tnext->name) treenamefix_str(tnext->name); tnext=tnext->next; } if(t->name) treenamefix_str(t->name); } /* * for debugging purposes only */ void treedebug(struct tree *t, char *s) { while(t) { char *s2; s2=(char *)malloc_2(strlen(s)+strlen(t->name)+2); strcpy(s2,s); strcat(s2,"."); strcat(s2,t->name); if(t->child) { treedebug(t->child, s2); } if(t->t_which>=0) /* for when valid netnames like A.B.C, A.B.C.D exist (not legal excluding texsim) */ /* otherwise this would be an 'else' */ { printf("%3d) %s\n", t->t_which, s2); } free_2(s2); t=t->next; } } static GtkCTreeNode *maketree_nodes(GtkCTreeNode *subtree, struct tree *t2, GtkCTreeNode *sibling, int mode) { char *tmp, *tmp2, *tmp3; gchar *text [1]; GdkDrawable *pxm, *msk; if(t2->t_which >= 0) { if(GLOBALS->facs[t2->t_which]->vec_root) { if(GLOBALS->autocoalesce) { if(GLOBALS->facs[t2->t_which]->vec_root!=GLOBALS->facs[t2->t_which]) { return(NULL); } tmp2=makename_chain(GLOBALS->facs[t2->t_which]); tmp3=leastsig_hiername(tmp2); tmp=wave_alloca(strlen(tmp3)+4); strcpy(tmp, "[] "); strcpy(tmp+3, tmp3); free_2(tmp2); } else { tmp=wave_alloca(strlen(t2->name)+4); strcpy(tmp, "[] "); strcpy(tmp+3, t2->name); } } else { tmp=t2->name; } } else { if(t2->t_which == WAVE_T_WHICH_UNDEFINED_COMPNAME) { tmp=t2->name; } else { int thidx = -t2->t_which + WAVE_T_WHICH_COMPNAME_START; if((thidx >= 0) && (thidx < GLOBALS->comp_name_serial)) { char *sc = GLOBALS->comp_name_idx[thidx]; int tlen = strlen(t2->name) + 2 + 1 + strlen(sc) + 1 + 1; tmp = wave_alloca(tlen); if(!GLOBALS->is_vhdl_component_format) { sprintf(tmp, "%s (%s)", t2->name, sc); } else { sprintf(tmp, "%s : %s", t2->name, sc); } } else { tmp=t2->name; /* should never get a value out of range here! */ } } } text[0]=tmp; switch(mode) { case MAKETREE_FLATTEN: if(t2->child) { sibling = gtk_ctree_insert_node (GLOBALS->ctree_main, subtree, sibling, text, 3, NULL, NULL, NULL, NULL, FALSE, FALSE); gtk_ctree_node_set_row_data(GLOBALS->ctree_main, sibling, t2); maketree(sibling, t2->child); } else { sibling = gtk_ctree_insert_node (GLOBALS->ctree_main, subtree, sibling, text, 3, NULL, NULL, NULL, NULL, TRUE, FALSE); gtk_ctree_node_set_row_data(GLOBALS->ctree_main, sibling, t2); } break; default: switch(t2->kind) { case TREE_VCD_ST_MODULE: pxm = GLOBALS->hiericon_module_pixmap; msk = GLOBALS->hiericon_module_mask; break; case TREE_VCD_ST_TASK: pxm = GLOBALS->hiericon_task_pixmap; msk = GLOBALS->hiericon_task_mask; break; case TREE_VCD_ST_FUNCTION: pxm = GLOBALS->hiericon_function_pixmap; msk = GLOBALS->hiericon_function_mask; break; case TREE_VCD_ST_BEGIN: pxm = GLOBALS->hiericon_begin_pixmap; msk = GLOBALS->hiericon_begin_mask; break; case TREE_VCD_ST_FORK: pxm = GLOBALS->hiericon_fork_pixmap; msk = GLOBALS->hiericon_fork_mask; break; case TREE_VCD_ST_GENERATE: pxm = GLOBALS->hiericon_generatefor_pixmap; msk = GLOBALS->hiericon_generatefor_mask; break; /* same as TREE_VHDL_ST_GENFOR */ case TREE_VCD_ST_STRUCT: pxm = GLOBALS->hiericon_block_pixmap; msk = GLOBALS->hiericon_block_mask; break; /* same as TREE_VHDL_ST_BLOCK */ case TREE_VCD_ST_UNION: pxm = GLOBALS->hiericon_instance_pixmap; msk = GLOBALS->hiericon_instance_mask; break; /* same as TREE_VHDL_ST_INSTANCE */ case TREE_VCD_ST_CLASS: pxm = GLOBALS->hiericon_class_pixmap; msk = GLOBALS->hiericon_class_mask; break; case TREE_VCD_ST_INTERFACE: pxm = GLOBALS->hiericon_interface_pixmap; msk = GLOBALS->hiericon_interface_mask; break; case TREE_VCD_ST_PACKAGE: pxm = GLOBALS->hiericon_svpackage_pixmap; msk = GLOBALS->hiericon_svpackage_mask; break; case TREE_VCD_ST_PROGRAM: pxm = GLOBALS->hiericon_program_pixmap; msk = GLOBALS->hiericon_program_mask; break; case TREE_VHDL_ST_DESIGN: pxm = GLOBALS->hiericon_design_pixmap; msk = GLOBALS->hiericon_design_mask; break; case TREE_VHDL_ST_BLOCK: pxm = GLOBALS->hiericon_block_pixmap; msk = GLOBALS->hiericon_block_mask; break; case TREE_VHDL_ST_GENIF: pxm = GLOBALS->hiericon_generateif_pixmap; msk = GLOBALS->hiericon_generateif_mask; break; case TREE_VHDL_ST_GENFOR: pxm = GLOBALS->hiericon_generatefor_pixmap; msk = GLOBALS->hiericon_generatefor_mask; break; case TREE_VHDL_ST_INSTANCE: pxm = GLOBALS->hiericon_instance_pixmap; msk = GLOBALS->hiericon_instance_mask; break; case TREE_VHDL_ST_PACKAGE: pxm = GLOBALS->hiericon_package_pixmap; msk = GLOBALS->hiericon_package_mask; break; case TREE_VHDL_ST_SIGNAL: pxm = GLOBALS->hiericon_signal_pixmap; msk = GLOBALS->hiericon_signal_mask; break; case TREE_VHDL_ST_PORTIN: pxm = GLOBALS->hiericon_portin_pixmap; msk = GLOBALS->hiericon_portin_mask; break; case TREE_VHDL_ST_PORTOUT: pxm = GLOBALS->hiericon_portout_pixmap; msk = GLOBALS->hiericon_portout_mask; break; case TREE_VHDL_ST_PORTINOUT: pxm = GLOBALS->hiericon_portinout_pixmap; msk = GLOBALS->hiericon_portinout_mask; break; case TREE_VHDL_ST_BUFFER: pxm = GLOBALS->hiericon_buffer_pixmap; msk = GLOBALS->hiericon_buffer_mask; break; case TREE_VHDL_ST_LINKAGE: pxm = GLOBALS->hiericon_linkage_pixmap; msk = GLOBALS->hiericon_linkage_mask; break; case TREE_VHDL_ST_ARCHITECTURE: pxm = GLOBALS->hiericon_module_pixmap; msk = GLOBALS->hiericon_module_mask; break; /* same as TREE_VCD_ST_MODULE */ case TREE_VHDL_ST_FUNCTION: pxm = GLOBALS->hiericon_function_pixmap; msk = GLOBALS->hiericon_function_mask; break; /* same as TREE_VCD_ST_FUNCTION */ case TREE_VHDL_ST_PROCESS: pxm = GLOBALS->hiericon_task_pixmap; msk = GLOBALS->hiericon_task_mask; break; /* same as TREE_VCD_ST_TASK */ case TREE_VHDL_ST_PROCEDURE: pxm = GLOBALS->hiericon_class_pixmap; msk = GLOBALS->hiericon_class_mask; break; /* same as TREE_VCD_ST_CLASS */ case TREE_VHDL_ST_RECORD: pxm = GLOBALS->hiericon_record_pixmap; msk = GLOBALS->hiericon_record_mask; break; case TREE_VHDL_ST_GENERATE: pxm = GLOBALS->hiericon_generate_pixmap; msk = GLOBALS->hiericon_generate_mask; break; default: pxm = msk = NULL; break; } sibling = gtk_ctree_insert_node (GLOBALS->ctree_main, subtree, sibling, text, 3, pxm, msk, pxm, msk, (mode==MAKETREE_LEAF), FALSE); gtk_ctree_node_set_row_data(GLOBALS->ctree_main, sibling, t2); break; } return(sibling); } /* * return least significant member name of a hierarchy * (used for tree and hier vec_root search hits) */ char *leastsig_hiername(char *nam) { char *t, *pnt=NULL; char ch; if(nam) { t=nam; while((ch=*(t++))) { if(ch==GLOBALS->hier_delimeter) pnt=t; } } return(pnt?pnt:nam); } /**********************************/ /* Experimental treesorting code */ /* (won't directly work with lxt2 */ /* because alias hier is after */ /* fac hier so fix with partial */ /* mergesort...) */ /**********************************/ /* * sort the hier tree..should be faster than * moving numfacs longer strings around */ static int tree_qsort_cmp(const void *v1, const void *v2) { struct tree *t1 = *(struct tree **)v1; struct tree *t2 = *(struct tree **)v2; return(sigcmp(t2->name, t1->name)); /* because list must be in rvs */ } static void treesort_2(struct tree *t, struct tree *p, struct tree ***tm, int *tm_siz) { struct tree *it; struct tree **srt; int cnt; int i; if(t->next) { it = t; cnt = 0; do { cnt++; it=it->next; } while(it); if(cnt > *tm_siz) { *tm_siz = cnt; if(*tm) { free_2(*tm); } *tm = malloc_2((cnt+1) * sizeof(struct tree *)); } srt = *tm; for(i=0;inext; } srt[i] = NULL; qsort((void *)srt, cnt, sizeof(struct tree *), tree_qsort_cmp); if(p) { p->child = srt[0]; } else { GLOBALS->treeroot = srt[0]; } for(i=0;inext = srt[i+1]; } it = srt[0]; for(i=0;ichild) { treesort_2(it->child, it, tm, tm_siz); } it = it->next; } } else if (t->child) { treesort_2(t->child, t, tm, tm_siz); } } void treesort(struct tree *t, struct tree *p) { struct tree **tm = NULL; int tm_siz = 0; treesort_2(t, p, &tm, &tm_siz); if(tm) { free_2(tm); } } void order_facs_from_treesort_2(struct tree *t) { while(t) { if(t->child) { order_facs_from_treesort_2(t->child); } if(t->t_which>=0) /* for when valid netnames like A.B.C, A.B.C.D exist (not legal excluding texsim) */ /* otherwise this would be an 'else' */ { GLOBALS->facs2_tree_c_1[GLOBALS->facs2_pos_tree_c_1] = GLOBALS->facs[t->t_which]; t->t_which = GLOBALS->facs2_pos_tree_c_1--; } t=t->next; } } void order_facs_from_treesort(struct tree *t, void *v) { struct symbol ***f = (struct symbol ***)v; /* eliminate compiler warning in tree.h as symbol.h refs tree.h */ GLOBALS->facs2_tree_c_1=(struct symbol **)malloc_2(GLOBALS->numfacs*sizeof(struct symbol *)); GLOBALS->facs2_pos_tree_c_1 = GLOBALS->numfacs-1; order_facs_from_treesort_2(t); if(GLOBALS->facs2_pos_tree_c_1>=0) { fprintf(stderr, "Internal Error: GLOBALS->facs2_pos_tree_c_1 = %d\n",GLOBALS->facs2_pos_tree_c_1); fprintf(stderr, "[This is usually the result of multiply defined facilities.]\n"); exit(255); } free_2(*f); *f = GLOBALS->facs2_tree_c_1; GLOBALS->facs2_tree_c_1 = NULL; } void build_tree_from_name(const char *s, int which) { struct tree *t, *nt; struct tree *tchain = NULL, *tchain_iter; struct tree *prevt; #ifdef _WAVE_HAVE_JUDY PPvoid_t PPValue = NULL; char str[2048]; #endif if(s==NULL || !s[0]) return; t = GLOBALS->treeroot; if(t) { prevt = NULL; while(s) { rs: s=get_module_name(s); if(t && !strcmp(t->name, GLOBALS->module_tree_c_1)) { prevt = t; t = t->child; continue; } #ifdef _WAVE_HAVE_JUDY rescan: if(prevt && prevt->children_in_gui) { /* find with judy */ int len = gen_hier_string(str, prevt); strcpy(str+len, GLOBALS->module_tree_c_1); PPValue = JudySLIns(&GLOBALS->sym_tree, (uint8_t *)str, PJE0); if(*PPValue) { t = *PPValue; prevt = t; t = t->child; continue; } goto construct; } #endif tchain = tchain_iter = t; if(s && t) { #ifdef _WAVE_HAVE_JUDY int dep = 0; #endif nt = t->next; while(nt) { if(nt && !strcmp(nt->name, GLOBALS->module_tree_c_1)) { /* move to front to speed up next compare if in same hier during build */ if(prevt) { tchain_iter->next = nt->next; nt->next = tchain; prevt->child = nt; } prevt = nt; t = nt->child; goto rs; } tchain_iter = nt; nt = nt->next; #ifdef _WAVE_HAVE_JUDY dep++; #endif } #ifdef _WAVE_HAVE_JUDY if(prevt && (dep >= FST_TREE_SEARCH_NEXT_LIMIT)) { int len = gen_hier_string(str, prevt); prevt->children_in_gui = 1; /* "borrowed" for tree build */ t = prevt->child; Judy1Set ((Pvoid_t)&GLOBALS->sym_tree_addresses, (Word_t)prevt, PJE0); /* assemble judy based on scopename + prevt pnt */ while(t) { strcpy(str+len, t->name); PPValue = JudySLIns(&GLOBALS->sym_tree, (uint8_t *)str, PJE0); *PPValue = t; t = t->next; } goto rescan; /* this level of hier is built, now do insert */ } #endif } #ifdef _WAVE_HAVE_JUDY construct: #endif nt=(struct tree *)talloc_2(sizeof(struct tree)+GLOBALS->module_len_tree_c_1 + 1); memcpy(nt->name, GLOBALS->module_tree_c_1, GLOBALS->module_len_tree_c_1); if(s) { nt->t_which = WAVE_T_WHICH_UNDEFINED_COMPNAME; #ifdef _WAVE_HAVE_JUDY if(prevt && prevt->children_in_gui) { *PPValue = nt; } #endif if(prevt) /* make first in chain */ { nt->next = prevt->child; prevt->child = nt; } else /* make second in chain as it's toplevel */ { nt->next = tchain->next; tchain->next = nt; } } else { nt->child = prevt; /* parent */ nt->t_which = which; nt->next = GLOBALS->terminals_tchain_tree_c_1; GLOBALS->terminals_tchain_tree_c_1 = nt; return; } /* blindly clone fac from next part of hier on down */ t = nt; while(s) { s=get_module_name(s); nt=(struct tree *)talloc_2(sizeof(struct tree)+GLOBALS->module_len_tree_c_1 + 1); memcpy(nt->name, GLOBALS->module_tree_c_1, GLOBALS->module_len_tree_c_1); if(s) { nt->t_which = WAVE_T_WHICH_UNDEFINED_COMPNAME; t->child = nt; t = nt; } else { nt->child = t; /* parent */ nt->t_which = which; nt->next = GLOBALS->terminals_tchain_tree_c_1; GLOBALS->terminals_tchain_tree_c_1 = nt; } } } } else { /* blindly create first fac in the tree (only ever called once) */ while(s) { s=get_module_name(s); nt=(struct tree *)talloc_2(sizeof(struct tree)+GLOBALS->module_len_tree_c_1 + 1); memcpy(nt->name, GLOBALS->module_tree_c_1, GLOBALS->module_len_tree_c_1); if(!s) nt->t_which=which; else nt->t_which = WAVE_T_WHICH_UNDEFINED_COMPNAME; if((GLOBALS->treeroot)&&(t)) /* scan-build : && t should be unnecessary to avoid null pointer deref, but add defensively */ { t->child = nt; t = nt; } else { GLOBALS->treeroot = t = nt; } } } } /* ######################## */ /* ## compatibility code ## */ /* ######################## */ /* * tree widgets differ between GTK2 and GTK1 so we need two different * maketree() routines */ #if WAVE_USE_GTK2 /* * GTK2: build the tree. */ void maketree2(GtkCTreeNode *subtree, struct tree *t, int depth, GtkCTreeNode *graft) { GtkCTreeNode *sibling=NULL, *sibling_test; struct tree *t2; #ifndef WAVE_DISABLE_FAST_TREE if(depth > 1) return; #endif /* * TG reworked treesearch widget so there is no need to * process anything other than nodes. Leaves are handled * in the filtered list below the node expand/contract * tree */ t2=t; while(t2) { #ifndef WAVE_DISABLE_FAST_TREE if(depth < 1) #endif { t2->children_in_gui = 1; } if(t2->child) { if(!graft) { sibling_test=maketree_nodes(subtree, t2, sibling, MAKETREE_NODE); } else { sibling_test = graft; } if(sibling_test) { GLOBALS->any_tree_node = sibling_test; maketree2(sibling=sibling_test, t2->child, depth + 1, NULL); } } if(graft) break; t2=t2->next; } } void maketree(GtkCTreeNode *subtree, struct tree *t) { maketree2(subtree, t, 0, NULL); } #else /* * GTK1: build the tree. */ void maketree(GtkCTreeNode *subtree, struct tree *t) { GtkCTreeNode *sibling=NULL, *sibling_test; struct tree *t2; if(!GLOBALS->hier_grouping) { t2=t; while(t2) { sibling_test=maketree_nodes(subtree, t2, sibling, MAKETREE_FLATTEN); sibling=sibling_test?sibling_test:sibling; t2=t2->next; } } else { t2=t; while(t2) { if(!t2->child) { sibling_test=maketree_nodes(subtree, t2, sibling, MAKETREE_LEAF); if(sibling_test) { maketree(sibling=sibling_test, t2->child); } } t2=t2->next; } t2=t; while(t2) { if(t2->child) { sibling_test=maketree_nodes(subtree, t2, sibling, MAKETREE_NODE); if(sibling_test) { maketree(sibling=sibling_test, t2->child); } } t2=t2->next; } } } #endif gtkwave-3.3.66/src/gconf.h0000664000076400007640000000153411677730173014652 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2012. * * 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. */ #ifndef WAVE_GCONF_H #define WAVE_GCONF_H #include #include #include #include #ifdef WAVE_HAVE_GCONF #include #endif #define WAVE_GCONF_DIR "/com.geda.gtkwave" /* 12345678901234567 */ #define WAVE_GCONF_DIR_LEN (17) int wave_rpc_id; void wave_gconf_init(int argc, char **argv); gboolean wave_gconf_client_set_string(const gchar *key, const gchar *val); void wave_gconf_restore(char **dumpfile, char **savefile, char **rcfile, char **wave_pwd, int *opt_vcd); #endif gtkwave-3.3.66/src/file.h0000664000076400007640000000116012234341730014453 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2010-2013 * * 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. */ #ifndef WAVE_FILESEL_H #define WAVE_FILESEL_H void fileselbox_old(char *title, char **filesel_path, GtkSignalFunc ok_func, GtkSignalFunc notok_func, char *pattn, int is_writemode); void fileselbox(char *title, char **filesel_path, GtkSignalFunc ok_func, GtkSignalFunc notok_func, char *pattn, int is_writemode); #endif gtkwave-3.3.66/src/gnu_regex.h0000664000076400007640000005030711572536221015533 0ustar bybellbybell/* Definitions for data structures and routines for the regular expression library, version 0.12. Copyright (C) 1985,89,90,91,92,93,95,96,97,98 Free Software Foundation, Inc. This file is part of the GNU C Library. Its master source is NOT part of the C library, however. The master source lives in /gd/gnu/lib. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. */ #ifndef _REGEX_H #define _REGEX_H 1 /* Allow the use in C++ code. */ #ifdef __cplusplus extern "C" { #endif /* POSIX says that must be included (by the caller) before . */ #if !defined _POSIX_C_SOURCE && !defined _POSIX_SOURCE && defined VMS /* VMS doesn't have `size_t' in , even though POSIX says it should be there. */ # include #endif /* The following two types have to be signed and unsigned integer type wide enough to hold a value of a pointer. For most ANSI compilers ptrdiff_t and size_t should be likely OK. Still size of these two types is 2 for Microsoft C. Ugh... */ typedef long int s_reg_t; typedef unsigned long int active_reg_t; /* The following bits are used to determine the regexp syntax we recognize. The set/not-set meanings are chosen so that Emacs syntax remains the value 0. The bits are given in alphabetical order, and the definitions shifted by one from the previous bit; thus, when we add or remove a bit, only one other definition need change. */ typedef unsigned long int reg_syntax_t; /* If this bit is not set, then \ inside a bracket expression is literal. If set, then such a \ quotes the following character. */ #define RE_BACKSLASH_ESCAPE_IN_LISTS ((unsigned long int) 1) /* If this bit is not set, then + and ? are operators, and \+ and \? are literals. If set, then \+ and \? are operators and + and ? are literals. */ #define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1) /* If this bit is set, then character classes are supported. They are: [:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:], [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:]. If not set, then character classes are not supported. */ #define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1) /* If this bit is set, then ^ and $ are always anchors (outside bracket expressions, of course). If this bit is not set, then it depends: ^ is an anchor if it is at the beginning of a regular expression or after an open-group or an alternation operator; $ is an anchor if it is at the end of a regular expression, or before a close-group or an alternation operator. This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because POSIX draft 11.2 says that * etc. in leading positions is undefined. We already implemented a previous draft which made those constructs invalid, though, so we haven't changed the code back. */ #define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1) /* If this bit is set, then special characters are always special regardless of where they are in the pattern. If this bit is not set, then special characters are special only in some contexts; otherwise they are ordinary. Specifically, * + ? and intervals are only special when not after the beginning, open-group, or alternation operator. */ #define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1) /* If this bit is set, then *, +, ?, and { cannot be first in an re or immediately after an alternation or begin-group operator. */ #define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1) /* If this bit is set, then . matches newline. If not set, then it doesn't. */ #define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1) /* If this bit is set, then . doesn't match NUL. If not set, then it does. */ #define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1) /* If this bit is set, nonmatching lists [^...] do not match newline. If not set, they do. */ #define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1) /* If this bit is set, either \{...\} or {...} defines an interval, depending on RE_NO_BK_BRACES. If not set, \{, \}, {, and } are literals. */ #define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1) /* If this bit is set, +, ? and | aren't recognized as operators. If not set, they are. */ #define RE_LIMITED_OPS (RE_INTERVALS << 1) /* If this bit is set, newline is an alternation operator. If not set, newline is literal. */ #define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1) /* If this bit is set, then `{...}' defines an interval, and \{ and \} are literals. If not set, then `\{...\}' defines an interval. */ #define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1) /* If this bit is set, (...) defines a group, and \( and \) are literals. If not set, \(...\) defines a group, and ( and ) are literals. */ #define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1) /* If this bit is set, then \ matches . If not set, then \ is a back-reference. */ #define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1) /* If this bit is set, then | is an alternation operator, and \| is literal. If not set, then \| is an alternation operator, and | is literal. */ #define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1) /* If this bit is set, then an ending range point collating higher than the starting range point, as in [z-a], is invalid. If not set, then when ending range point collates higher than the starting range point, the range is ignored. */ #define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1) /* If this bit is set, then an unmatched ) is ordinary. If not set, then an unmatched ) is invalid. */ #define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1) /* If this bit is set, succeed as soon as we match the whole pattern, without further backtracking. */ #define RE_NO_POSIX_BACKTRACKING (RE_UNMATCHED_RIGHT_PAREN_ORD << 1) /* If this bit is set, do not process the GNU regex operators. If not set, then the GNU regex operators are recognized. */ #define RE_NO_GNU_OPS (RE_NO_POSIX_BACKTRACKING << 1) /* If this bit is set, turn on internal regex debugging. If not set, and debugging was on, turn it off. This only works if regex.c is compiled -DDEBUG. We define this bit always, so that all that's needed to turn on debugging is to recompile regex.c; the calling code can always have this bit set, and it won't affect anything in the normal case. */ #define RE_DEBUG (RE_NO_GNU_OPS << 1) /* This global variable defines the particular regexp syntax to use (for some interfaces). When a regexp is compiled, the syntax used is stored in the pattern buffer, so changing this does not affect already-compiled regexps. */ extern reg_syntax_t re_syntax_options; /* Define combinations of the above bits for the standard possibilities. (The [[[ comments delimit what gets put into the Texinfo file, so don't delete them!) */ /* [[[begin syntaxes]]] */ #define RE_SYNTAX_EMACS 0 #define RE_SYNTAX_AWK \ (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \ | RE_NO_BK_PARENS | RE_NO_BK_REFS \ | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \ | RE_DOT_NEWLINE | RE_CONTEXT_INDEP_ANCHORS \ | RE_UNMATCHED_RIGHT_PAREN_ORD | RE_NO_GNU_OPS) #define RE_SYNTAX_GNU_AWK \ ((RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DEBUG) \ & ~(RE_DOT_NOT_NULL | RE_INTERVALS | RE_CONTEXT_INDEP_OPS)) #define RE_SYNTAX_POSIX_AWK \ (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS \ | RE_INTERVALS | RE_NO_GNU_OPS) #define RE_SYNTAX_GREP \ (RE_BK_PLUS_QM | RE_CHAR_CLASSES \ | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \ | RE_NEWLINE_ALT) #define RE_SYNTAX_EGREP \ (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \ | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \ | RE_NEWLINE_ALT | RE_NO_BK_PARENS \ | RE_NO_BK_VBAR) #define RE_SYNTAX_POSIX_EGREP \ (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES) /* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */ #define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC #define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC /* Syntax bits common to both basic and extended POSIX regex syntax. */ #define _RE_SYNTAX_POSIX_COMMON \ (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \ | RE_INTERVALS | RE_NO_EMPTY_RANGES) #define RE_SYNTAX_POSIX_BASIC \ (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM) /* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this isn't minimal, since other operators, such as \`, aren't disabled. */ #define RE_SYNTAX_POSIX_MINIMAL_BASIC \ (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS) #define RE_SYNTAX_POSIX_EXTENDED \ (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \ | RE_NO_BK_PARENS | RE_NO_BK_VBAR \ | RE_UNMATCHED_RIGHT_PAREN_ORD) /* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INVALID_OPS replaces RE_CONTEXT_INDEP_OPS and RE_NO_BK_REFS is added. */ #define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \ (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \ | RE_NO_BK_PARENS | RE_NO_BK_REFS \ | RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD) /* [[[end syntaxes]]] */ /* Maximum number of duplicates an interval can allow. Some systems (erroneously) define this in other header files, but we want our value, so remove any previous define. */ #ifdef RE_DUP_MAX # undef RE_DUP_MAX #endif /* If sizeof(int) == 2, then ((1 << 15) - 1) overflows. */ #define RE_DUP_MAX (0x7fff) /* POSIX `cflags' bits (i.e., information for `regcomp'). */ /* If this bit is set, then use extended regular expression syntax. If not set, then use basic regular expression syntax. */ #define REG_EXTENDED 1 /* If this bit is set, then ignore case when matching. If not set, then case is significant. */ #define REG_ICASE (REG_EXTENDED << 1) /* If this bit is set, then anchors do not match at newline characters in the string. If not set, then anchors do match at newlines. */ #define REG_NEWLINE (REG_ICASE << 1) /* If this bit is set, then report only success or fail in regexec. If not set, then returns differ between not matching and errors. */ #define REG_NOSUB (REG_NEWLINE << 1) /* POSIX `eflags' bits (i.e., information for regexec). */ /* If this bit is set, then the beginning-of-line operator doesn't match the beginning of the string (presumably because it's not the beginning of a line). If not set, then the beginning-of-line operator does match the beginning of the string. */ #define REG_NOTBOL 1 /* Like REG_NOTBOL, except for the end-of-line. */ #define REG_NOTEOL (1 << 1) /* If any error codes are removed, changed, or added, update the `re_error_msg' table in regex.c. */ typedef enum { #ifdef _XOPEN_SOURCE REG_ENOSYS = -1, /* This will never happen for this implementation. */ #endif REG_NOERROR = 0, /* Success. */ REG_NOMATCH, /* Didn't find a match (for regexec). */ /* POSIX regcomp return error codes. (In the order listed in the standard.) */ REG_BADPAT, /* Invalid pattern. */ REG_ECOLLATE, /* Not implemented. */ REG_ECTYPE, /* Invalid character class name. */ REG_EESCAPE, /* Trailing backslash. */ REG_ESUBREG, /* Invalid back reference. */ REG_EBRACK, /* Unmatched left bracket. */ REG_EPAREN, /* Parenthesis imbalance. */ REG_EBRACE, /* Unmatched \{. */ REG_BADBR, /* Invalid contents of \{\}. */ REG_ERANGE, /* Invalid range end. */ REG_ESPACE, /* Ran out of memory. */ REG_BADRPT, /* No preceding re for repetition op. */ /* Error codes we've added. */ REG_EEND, /* Premature end. */ REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */ REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */ } reg_errcode_t; /* This data structure represents a compiled pattern. Before calling the pattern compiler, the fields `buffer', `allocated', `fastmap', `translate', and `no_sub' can be set. After the pattern has been compiled, the `re_nsub' field is available. All other fields are private to the regex routines. */ #ifndef RE_TRANSLATE_TYPE # define RE_TRANSLATE_TYPE char * #endif struct re_pattern_buffer { /* [[[begin pattern_buffer]]] */ /* Space that holds the compiled pattern. It is declared as `unsigned char *' because its elements are sometimes used as array indexes. */ unsigned char *buffer; /* Number of bytes to which `buffer' points. */ unsigned long int allocated; /* Number of bytes actually used in `buffer'. */ unsigned long int used; /* Syntax setting with which the pattern was compiled. */ reg_syntax_t syntax; /* Pointer to a fastmap, if any, otherwise zero. re_search uses the fastmap, if there is one, to skip over impossible starting points for matches. */ char *fastmap; /* Either a translate table to apply to all characters before comparing them, or zero for no translation. The translation is applied to a pattern when it is compiled and to a string when it is matched. */ RE_TRANSLATE_TYPE translate; /* Number of subexpressions found by the compiler. */ size_t re_nsub; /* Zero if this pattern cannot match the empty string, one else. Well, in truth it's used only in `re_search_2', to see whether or not we should use the fastmap, so we don't set this absolutely perfectly; see `re_compile_fastmap' (the `duplicate' case). */ unsigned can_be_null : 1; /* If REGS_UNALLOCATED, allocate space in the `regs' structure for `max (RE_NREGS, re_nsub + 1)' groups. If REGS_REALLOCATE, reallocate space if necessary. If REGS_FIXED, use what's there. */ #define REGS_UNALLOCATED 0 #define REGS_REALLOCATE 1 #define REGS_FIXED 2 unsigned regs_allocated : 2; /* Set to zero when `regex_compile' compiles a pattern; set to one by `re_compile_fastmap' if it updates the fastmap. */ unsigned fastmap_accurate : 1; /* If set, `re_match_2' does not return information about subexpressions. */ unsigned no_sub : 1; /* If set, a beginning-of-line anchor doesn't match at the beginning of the string. */ unsigned not_bol : 1; /* Similarly for an end-of-line anchor. */ unsigned not_eol : 1; /* If true, an anchor at a newline matches. */ unsigned newline_anchor : 1; /* [[[end pattern_buffer]]] */ }; typedef struct re_pattern_buffer regex_t; /* Type for byte offsets within the string. POSIX mandates this. */ typedef int regoff_t; /* This is the structure we store register match data in. See regex.texinfo for a full description of what registers match. */ struct re_registers { unsigned num_regs; regoff_t *start; regoff_t *end; }; /* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer, `re_match_2' returns information about at least this many registers the first time a `regs' structure is passed. */ #ifndef RE_NREGS # define RE_NREGS 30 #endif /* POSIX specification for registers. Aside from the different names than `re_registers', POSIX uses an array of structures, instead of a structure of arrays. */ typedef struct { regoff_t rm_so; /* Byte offset from string's start to substring's start. */ regoff_t rm_eo; /* Byte offset from string's start to substring's end. */ } regmatch_t; /* Declarations for routines. */ /* To avoid duplicating every routine declaration -- once with a prototype (if we are ANSI), and once without (if we aren't) -- we use the following macro to declare argument types. This unfortunately clutters up the declarations a bit, but I think it's worth it. */ #if __STDC__ # define _RE_ARGS(args) args #else /* not __STDC__ */ # define _RE_ARGS(args) () #endif /* not __STDC__ */ /* Sets the current default syntax to SYNTAX, and return the old syntax. You can also simply assign to the `re_syntax_options' variable. */ extern reg_syntax_t re_set_syntax _RE_ARGS ((reg_syntax_t syntax)); /* Compile the regular expression PATTERN, with length LENGTH and syntax given by the global `re_syntax_options', into the buffer BUFFER. Return NULL if successful, and an error string if not. */ extern const char *re_compile_pattern _RE_ARGS ((const char *pattern, size_t length, struct re_pattern_buffer *buffer)); /* Compile a fastmap for the compiled pattern in BUFFER; used to accelerate searches. Return 0 if successful and -2 if was an internal error. */ extern int re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer)); /* Search in the string STRING (with length LENGTH) for the pattern compiled into BUFFER. Start searching at position START, for RANGE characters. Return the starting position of the match, -1 for no match, or -2 for an internal error. Also return register information in REGS (if REGS and BUFFER->no_sub are nonzero). */ extern int re_search _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, int length, int start, int range, struct re_registers *regs)); /* Like `re_search', but search in the concatenation of STRING1 and STRING2. Also, stop searching at index START + STOP. */ extern int re_search_2 _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, int length1, const char *string2, int length2, int start, int range, struct re_registers *regs, int stop)); /* Like `re_search', but return how many characters in STRING the regexp in BUFFER matched, starting at position START. */ extern int re_match _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, int length, int start, struct re_registers *regs)); /* Relates to `re_match' as `re_search_2' relates to `re_search'. */ extern int re_match_2 _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, int length1, const char *string2, int length2, int start, struct re_registers *regs, int stop)); /* Set REGS to hold NUM_REGS registers, storing them in STARTS and ENDS. Subsequent matches using BUFFER and REGS will use this memory for recording register information. STARTS and ENDS must be allocated with malloc, and must each be at least `NUM_REGS * sizeof (regoff_t)' bytes long. If NUM_REGS == 0, then subsequent matches should allocate their own register data. Unless this function is called, the first search or match using PATTERN_BUFFER will allocate its own register data, without freeing the old data. */ extern void re_set_registers _RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs, unsigned num_regs, regoff_t *starts, regoff_t *ends)); #if defined _REGEX_RE_COMP || defined _LIBC # ifndef _CRAY /* 4.2 bsd compatibility. */ extern char *re_comp _RE_ARGS ((const char *)); extern int re_exec _RE_ARGS ((const char *)); # endif #endif /* POSIX compatibility. */ extern int regcomp _RE_ARGS ((regex_t *__preg, const char *__pattern, int __cflags)); extern int regexec _RE_ARGS ((const regex_t *__preg, const char *__string, size_t __nmatch, regmatch_t __pmatch[], int __eflags)); extern size_t regerror _RE_ARGS ((int __errcode, const regex_t *__preg, char *__errbuf, size_t __errbuf_size)); extern void regfree _RE_ARGS ((regex_t *__preg)); #ifdef __cplusplus } #endif /* C++ */ #endif /* regex.h */ /* Local variables: make-backup-files: t version-control: t trim-versions-without-asking: nil End: */ gtkwave-3.3.66/src/hierpack.h0000664000076400007640000000116612360312657015336 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2008-2011. * * 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. */ #ifndef WAVE_HIERPACK_H #define WAVE_HIERPACK_H #include "globals.h" #define HIER_DEPACK_ALLOC (0) #define HIER_DEPACK_STATIC (1) void init_facility_pack(void); char *compress_facility(unsigned char *key, unsigned int len); void freeze_facility_pack(void); char *hier_decompress_flagged(char *n, int *was_packed); #endif gtkwave-3.3.66/src/edgebuttons.h0000664000076400007640000000073212341266475016076 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2010 * * 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. */ #ifndef WAVE_EDGEBUTTONS_H #define WAVE_EDGEBUTTONS_H void service_left_edge(GtkWidget *text, gpointer data); void service_right_edge(GtkWidget *text, gpointer data); #endif gtkwave-3.3.66/src/logfile.c0000664000076400007640000004422412360623564015170 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2010. * * 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. */ #include "globals.h" #include #include #include #include "debug.h" #include "symbol.h" #include "currenttime.h" #include "fgetdynamic.h" /* only for use locally */ struct wave_logfile_lines_t { struct wave_logfile_lines_t *next; char *text; }; struct logfile_instance_t { struct logfile_instance_t *next; GtkWidget *window; GtkWidget *text; #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) GtkTextTag *bold_tag; GtkTextTag *mono_tag; GtkTextTag *size_tag; #else GdkFont *font_logfile; #endif char default_text[1]; }; #define log_collection (*((struct logfile_instance_t **)GLOBALS->logfiles)) /* Add some text to our text widget - this is a callback that is invoked when our window is realized. We could also force our window to be realized with gtk_widget_realize, but it would have to be part of a hierarchy first */ void log_text(GtkWidget *text, GdkFont *font, char *str) { #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) (void)font; gtk_text_buffer_insert_with_tags (GTK_TEXT_VIEW (text)->buffer, &GLOBALS->iter_logfile_c_2, str, -1, GLOBALS->mono_tag_logfile_c_1, GLOBALS->size_tag_logfile_c_1, NULL); #else gtk_text_insert (GTK_TEXT (text), font, &text->style->black, NULL, str, -1); #endif } void log_text_bold(GtkWidget *text, GdkFont *font, char *str) { #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) (void)font; gtk_text_buffer_insert_with_tags (GTK_TEXT_VIEW (text)->buffer, &GLOBALS->iter_logfile_c_2, str, -1, GLOBALS->bold_tag_logfile_c_2, GLOBALS->mono_tag_logfile_c_1, GLOBALS->size_tag_logfile_c_1, NULL); #else gtk_text_insert (GTK_TEXT (text), font, &text->style->fg[GTK_STATE_SELECTED], &text->style->bg[GTK_STATE_SELECTED], str, -1); #endif } static void log_realize_text (GtkWidget *text, gpointer data) { (void)text; (void)data; /* nothing for now */ } static void center_op(void) { TimeType middle=0, width; if((GLOBALS->tims.marker<0)||(GLOBALS->tims.markertims.first)||(GLOBALS->tims.marker>GLOBALS->tims.last)) { if(GLOBALS->tims.end>GLOBALS->tims.last) GLOBALS->tims.end=GLOBALS->tims.last; middle=(GLOBALS->tims.start/2)+(GLOBALS->tims.end/2); if((GLOBALS->tims.start&1)&&(GLOBALS->tims.end&1)) middle++; } else { middle=GLOBALS->tims.marker; } width=(TimeType)(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx); GLOBALS->tims.start=time_trunc(middle-(width/2)); if(GLOBALS->tims.start+width>GLOBALS->tims.last) GLOBALS->tims.start=time_trunc(GLOBALS->tims.last-width); if(GLOBALS->tims.starttims.first) GLOBALS->tims.start=GLOBALS->tims.first; GTK_ADJUSTMENT(GLOBALS->wave_hslider)->value=GLOBALS->tims.timecache=GLOBALS->tims.start; fix_wavehadj(); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */ gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed"); /* force zoom update */ } static gboolean button_release_event (GtkWidget *text, GdkEventButton *event) { (void)event; gchar *sel; #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) GtkTextIter start; GtkTextIter end; if (gtk_text_buffer_get_selection_bounds (GTK_TEXT_VIEW(text)->buffer, &start, &end)) { if(gtk_text_iter_compare (&start, &end) < 0) { sel = gtk_text_buffer_get_text(GTK_TEXT_VIEW(text)->buffer, &start, &end, FALSE); if(sel) { int slen = strlen(sel); char *sel2 = NULL; if((slen)&&(sel[0]>='0')&&(sel[0]<='9')) { TimeType tm; gunichar gch = gtk_text_iter_get_char(&end); int do_si_append = 0; if(gch==' ') /* in case time is of format "100 ps" with a space */ { gtk_text_iter_forward_char(&end); gch = gtk_text_iter_get_char(&end); } if((sel[slen-1]>='0')&&(sel[slen-1]<='9')) /* need to append units? */ { int silen = strlen(WAVE_SI_UNITS); int silp; gch = tolower(gch); if(gch == 's') { do_si_append = 1; } else { for(silp=0;silptime_dimension); if((tm >= GLOBALS->tims.first) && (tm <= GLOBALS->tims.last)) { GLOBALS->tims.lmbcache = -1; update_markertime(GLOBALS->tims.marker = tm); center_op(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); update_markertime(GLOBALS->tims.marker = tm); /* centering problem in GTK2 */ } } if(sel2) { free_2(sel2); } g_free(sel); } } } #else #ifndef WAVE_USE_GTK2 GtkEditable *oe = GTK_EDITABLE(>K_TEXT(text)->editable); GtkTextClass *tc = (GtkTextClass *) ((GtkObject*) (GTK_OBJECT(text)))->klass; GtkEditableClass *oec = &tc->parent_class; #else GtkOldEditable *oe = GTK_OLD_EDITABLE(>K_TEXT(text)->old_editable); GtkOldEditableClass *oec = GTK_OLD_EDITABLE_GET_CLASS(oe); #endif if(oe->has_selection) { if(oec->get_chars) { sel = oec->get_chars(oe, oe->selection_start_pos, oe->selection_end_pos); if(sel) { int slen = strlen(sel); char *sel2 = NULL; if((slen)&&(sel[0]>='0')&&(sel[0]<='9')) { TimeType tm; gint gchpos = oe->selection_end_pos; gchar *extra = oec->get_chars(oe, gchpos, gchpos+2); gchar gch = extra ? extra[0] : 0; int do_si_append = 0; if(gch==' ') /* in case time is of format "100 ps" with a space */ { gch = gch ? extra[1] : 0; } if(extra) g_free(extra); if((sel[slen-1]>='0')&&(sel[slen-1]<='9')) /* need to append units? */ { int silen = strlen(WAVE_SI_UNITS); int silp; gch = tolower(gch); if(gch == 's') { do_si_append = 1; } else { for(silp=0;silptime_dimension); if((tm >= GLOBALS->tims.first) && (tm <= GLOBALS->tims.last)) { GLOBALS->tims.lmbcache = -1; update_markertime(GLOBALS->tims.marker = tm); center_op(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); update_markertime(GLOBALS->tims.marker = tm); /* centering problem in GTK2 */ } } if(sel2) { free_2(sel2); } g_free(sel); } } } #endif return(FALSE); /* call remaining handlers... */ } /* Create a scrolled text area that displays a "message" */ static GtkWidget *create_log_text (GtkWidget **textpnt) { GtkWidget *text; GtkWidget *table; GtkWidget *vscrollbar; /* Create a table to hold the text widget and scrollbars */ table = gtk_table_new (1, 16, FALSE); /* Put a text widget in the upper left hand corner. Note the use of * GTK_SHRINK in the y direction */ #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) text = gtk_text_view_new (); gtk_text_buffer_get_start_iter (gtk_text_view_get_buffer(GTK_TEXT_VIEW (text)), &GLOBALS->iter_logfile_c_2); GLOBALS->bold_tag_logfile_c_2 = gtk_text_buffer_create_tag (GTK_TEXT_VIEW (text)->buffer, "bold", "weight", PANGO_WEIGHT_BOLD, NULL); GLOBALS->mono_tag_logfile_c_1 = gtk_text_buffer_create_tag (GTK_TEXT_VIEW (text)->buffer, "monospace", "family", "monospace", NULL); GLOBALS->size_tag_logfile_c_1 = gtk_text_buffer_create_tag (GTK_TEXT_VIEW (text)->buffer, "fsiz", "size", (GLOBALS->use_big_fonts ? 12 : 8) * PANGO_SCALE, NULL); #else text = gtk_text_new (NULL, NULL); #endif *textpnt = text; gtk_table_attach (GTK_TABLE (table), text, 0, 14, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_SHRINK | GTK_EXPAND, 0, 0); gtk_widget_set_usize(GTK_WIDGET(text), 100, 100); #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) gtk_text_view_set_editable(GTK_TEXT_VIEW(text), TRUE); #else gtk_text_set_editable(GTK_TEXT(text), TRUE); #endif gtk_widget_show (text); /* And a VScrollbar in the upper right */ #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) { GtkTextViewClass *tc = (GtkTextViewClass*)GTK_OBJECT_GET_CLASS(GTK_OBJECT(text)); tc->set_scroll_adjustments(GTK_TEXT_VIEW (text), NULL, NULL); vscrollbar = gtk_vscrollbar_new (GTK_TEXT_VIEW (text)->vadjustment); } #else vscrollbar = gtk_vscrollbar_new (GTK_TEXT (text)->vadj); #endif gtk_table_attach (GTK_TABLE (table), vscrollbar, 15, 16, 0, 1, GTK_FILL, GTK_FILL | GTK_SHRINK | GTK_EXPAND, 0, 0); gtk_widget_show (vscrollbar); /* Add a handler to put a message in the text widget when it is realized */ gtk_signal_connect (GTK_OBJECT (text), "realize", GTK_SIGNAL_FUNC (log_realize_text), NULL); gtk_signal_connect(GTK_OBJECT(text), "button_release_event", GTK_SIGNAL_FUNC(button_release_event), NULL); #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text), GTK_WRAP_CHAR); #else gtk_text_set_word_wrap(GTK_TEXT(text), FALSE); gtk_text_set_line_wrap(GTK_TEXT(text), TRUE); #endif return(table); } /***********************************************************************************/ static void ok_callback(GtkWidget *widget, GtkWidget *cached_window) { (void)widget; struct logfile_instance_t *l = log_collection; struct logfile_instance_t *lprev = NULL; while(l) { if(l->window == cached_window) { if(lprev) { lprev->next = l->next; } else { log_collection = l->next; } free(l); /* deliberately not free_2 */ break; } lprev = l; l = l->next; } DEBUG(printf("OK\n")); gtk_widget_destroy(cached_window); } static void destroy_callback(GtkWidget *widget, GtkWidget *cached_window) { (void)cached_window; ok_callback(widget, widget); } void logbox(char *title, int width, char *default_text) { GtkWidget *window; GtkWidget *vbox; GtkWidget *hbox, *button1; GtkWidget *label, *separator; GtkWidget *ctext; GtkWidget *text; struct logfile_instance_t *log_c; FILE *handle; struct wave_logfile_lines_t *wlog_head=NULL, *wlog_curr=NULL; int wlog_size = 0; handle = fopen(default_text, "rb"); if(!handle) { char *buf = malloc_2(strlen(default_text)+128); sprintf(buf, "Could not open logfile '%s'\n", default_text); status_text(buf); free_2(buf); return; } /* fix problem where ungrab doesn't occur if button pressed + simultaneous accelerator key occurs */ if(GLOBALS->in_button_press_wavewindow_c_1) { gdk_pointer_ungrab(GDK_CURRENT_TIME); } #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) /* nothing */ #else if(!GLOBALS->font_logfile_c_1) { if(GLOBALS->fontname_logfile) { GLOBALS->font_logfile_c_1=gdk_font_load(GLOBALS->fontname_logfile); } if(!GLOBALS->font_logfile_c_1) { #ifndef __CYGWIN__ GLOBALS->font_logfile_c_1=gdk_font_load(GLOBALS->use_big_fonts ? "-*-courier-*-r-*-*-18-*-*-*-*-*-*-*" : "-*-courier-*-r-*-*-10-*-*-*-*-*-*-*"); #else GLOBALS->font_logfile_c_1=gdk_font_load(GLOBALS->use_big_fonts ? "-misc-fixed-*-*-*-*-18-*-*-*-*-*-*-*" : "-misc-fixed-*-*-*-*-10-*-*-*-*-*-*-*"); #endif } } #endif /* create a new nonmodal window */ window = gtk_window_new(GLOBALS->disable_window_manager ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL); if(GLOBALS->use_big_fonts || GLOBALS->fontname_logfile) { gtk_widget_set_usize( GTK_WIDGET (window), width*1.8, 600); } else { gtk_widget_set_usize( GTK_WIDGET (window), width, 400); } gtk_window_set_title(GTK_WINDOW (window), title); gtk_signal_connect(GTK_OBJECT (window), "delete_event", (GtkSignalFunc) destroy_callback, window); vbox = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (window), vbox); gtk_widget_show (vbox); label=gtk_label_new(default_text); gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); gtk_widget_show (label); separator = gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, TRUE, 0); gtk_widget_show (separator); ctext=create_log_text(&text); gtk_box_pack_start (GTK_BOX (vbox), ctext, TRUE, TRUE, 0); gtk_widget_show (ctext); separator = gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, TRUE, 0); gtk_widget_show (separator); hbox = gtk_hbox_new (FALSE, 1); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_widget_show (hbox); button1 = gtk_button_new_with_label ("Close Logfile"); gtk_widget_set_usize(button1, 100, -1); gtk_signal_connect(GTK_OBJECT (button1), "clicked", GTK_SIGNAL_FUNC(ok_callback), window); gtk_widget_show (button1); gtk_container_add (GTK_CONTAINER (hbox), button1); GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT); gtk_signal_connect_object (GTK_OBJECT (button1), "realize", (GtkSignalFunc) gtk_widget_grab_default, GTK_OBJECT (button1)); gtk_widget_show(window); log_text_bold(text, NULL, "Click-select"); log_text(text, NULL, " on numbers to jump to that time value in the wave viewer.\n"); log_text(text, NULL, " \n"); while(!feof(handle)) { char *pnt = fgetmalloc(handle); if(pnt) { struct wave_logfile_lines_t *w = calloc_2(1, sizeof(struct wave_logfile_lines_t)); wlog_size += (GLOBALS->fgetmalloc_len+1); w->text = pnt; if(!wlog_curr) { wlog_head = wlog_curr = w; } else { wlog_curr->next = w; wlog_curr = w; } } } if(wlog_curr) { struct wave_logfile_lines_t *w = wlog_head; struct wave_logfile_lines_t *wt; char *pnt = malloc_2(wlog_size + 1); char *pnt2 = pnt; while(w) { int len = strlen(w->text); memcpy(pnt2, w->text, len); pnt2 += len; *pnt2 = '\n'; pnt2++; free_2(w->text); wt = w; w = w->next; free_2(wt); } /* wlog_head = */ wlog_curr = NULL; /* scan-build */ *pnt2 = 0; log_text(text, GLOBALS->font_logfile_c_1, pnt); free_2(pnt); } fclose(handle); log_c = calloc(1, sizeof(struct logfile_instance_t) + strlen(default_text)); /* deliberately not calloc_2, needs to be persistent! */ strcpy(log_c->default_text, default_text); log_c->window = window; log_c->text = text; log_c->next = log_collection; #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) log_c->bold_tag = GLOBALS->bold_tag_logfile_c_2; log_c->mono_tag = GLOBALS->mono_tag_logfile_c_1; log_c->size_tag = GLOBALS->size_tag_logfile_c_1; #else log_c->font_logfile = GLOBALS->font_logfile_c_1; #endif log_collection = log_c; } static void logbox_reload_single(GtkWidget *window, GtkWidget *text, char *default_text) { (void)window; FILE *handle; struct wave_logfile_lines_t *wlog_head=NULL, *wlog_curr=NULL; int wlog_size = 0; handle = fopen(default_text, "rb"); if(!handle) { char *buf = malloc_2(strlen(default_text)+128); sprintf(buf, "Could not open logfile '%s'\n", default_text); status_text(buf); free_2(buf); return; } #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) { GtkTextIter st_iter, en_iter; gtk_text_buffer_get_start_iter(GTK_TEXT_VIEW (text)->buffer, &st_iter); gtk_text_buffer_get_end_iter(GTK_TEXT_VIEW (text)->buffer, &en_iter); gtk_text_buffer_delete(GTK_TEXT_VIEW (text)->buffer, &st_iter, &en_iter); gtk_text_buffer_get_start_iter (GTK_TEXT_VIEW (text)->buffer, &GLOBALS->iter_logfile_c_2); } #else { guint len = gtk_text_get_length(GTK_TEXT(text)); gtk_text_set_point(GTK_TEXT(text), 0); gtk_text_freeze(GTK_TEXT(text)); gtk_text_forward_delete (GTK_TEXT(text), len); } #endif log_text_bold(text, NULL, "Click-select"); log_text(text, NULL, " on numbers to jump to that time value in the wave viewer.\n"); log_text(text, NULL, " \n"); while(!feof(handle)) { char *pnt = fgetmalloc(handle); if(pnt) { struct wave_logfile_lines_t *w = calloc_2(1, sizeof(struct wave_logfile_lines_t)); wlog_size += (GLOBALS->fgetmalloc_len+1); w->text = pnt; if(!wlog_curr) { wlog_head = wlog_curr = w; } else { wlog_curr->next = w; wlog_curr = w; } } } if(wlog_curr) { struct wave_logfile_lines_t *w = wlog_head; struct wave_logfile_lines_t *wt; char *pnt = malloc_2(wlog_size + 1); char *pnt2 = pnt; while(w) { int len = strlen(w->text); memcpy(pnt2, w->text, len); pnt2 += len; *pnt2 = '\n'; pnt2++; free_2(w->text); wt = w; w = w->next; free_2(wt); } /* wlog_head = */ wlog_curr = NULL; /* scan-build */ *pnt2 = 0; log_text(text, GLOBALS->font_logfile_c_1, pnt); free_2(pnt); } #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) #else gtk_text_thaw(GTK_TEXT(text)); #endif fclose(handle); } void logbox_reload(void) { struct logfile_instance_t *l = log_collection; while(l) { #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) GLOBALS->bold_tag_logfile_c_2 = l->bold_tag; GLOBALS->mono_tag_logfile_c_1 = l->mono_tag; GLOBALS->size_tag_logfile_c_1 = l->size_tag; #else GLOBALS->font_logfile_c_1 = l->font_logfile; #endif logbox_reload_single(l->window, l->text, l->default_text); l = l->next; } } gtkwave-3.3.66/src/extload.c0000664000076400007640000012421712540444674015213 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2009-2015. * * 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. */ #include #include "globals.h" #include #include "vzt.h" #include "lx2.h" #include "fsdb_wrapper_api.h" #ifndef _MSC_VER #include #endif #include #include #include #include "symbol.h" #include "vcd.h" #include "lxt2_read.h" #include "vzt_read.h" #include "lxt.h" #include "extload.h" #include "debug.h" #include "busy.h" #include "hierpack.h" #ifndef EXTLOAD_SUFFIX const char *extload_loader_fail_msg = "Sorry, EXTLOAD support was not compiled into this executable, exiting.\n\n"; TimeType extload_main(char *fname, char *skip_start, char *skip_end) { (void)fname; (void)skip_start; (void)skip_end; fprintf(stderr, "%s", extload_loader_fail_msg); exit(255); return(0); /* for vc++ */ } void import_extload_trace(nptr np) { (void)np; fprintf(stderr, "%s", extload_loader_fail_msg); exit(255); } void fsdb_import_masked(void) { fprintf(stderr, "%s", extload_loader_fail_msg); exit(255); } void fsdb_set_fac_process_mask(nptr np) { (void)np; fprintf(stderr, "%s", extload_loader_fail_msg); exit(255); } #else /******************************************************************/ /* * reverse equality mem compare */ static int memrevcmp(int i, const char *s1, const char *s2) { i--; for(;i>=0;i--) { if(s1[i] != s2[i]) break; } return(i+1); } /* * fast itoa for decimal numbers */ static char* itoa_2(int value, char* result) { char* ptr = result, *ptr1 = result, tmp_char; int tmp_value; do { tmp_value = value; value /= 10; *ptr++ = "9876543210123456789" [9 + (tmp_value - value * 10)]; } while ( value ); if (tmp_value < 0) *ptr++ = '-'; result = ptr; *ptr-- = '\0'; while(ptr1 < ptr) { tmp_char = *ptr; *ptr--= *ptr1; *ptr1++ = tmp_char; } return(result); } /* * preformatted sprintf statements which remove parsing latency */ static int sprintf_2_sd(char *s, char *c, int d) { char *s2 = s; while(*c) { *(s2++) = *(c++); } *(s2++) = '['; s2 = itoa_2(d, s2); *(s2++) = ']'; *s2 = 0; return(s2 - s); } static int sprintf_2_sdd(char *s, char *c, int d, int d2) { char *s2 = s; while(*c) { *(s2++) = *(c++); } *(s2++) = '['; s2 = itoa_2(d, s2); *(s2++) = ':'; s2 = itoa_2(d2, s2); *(s2++) = ']'; *s2 = 0; return(s2 - s); } /******************************************************************/ #ifndef WAVE_FSDB_READER_IS_PRESENT static int last_modification_check(void) { #ifdef HAVE_SYS_STAT_H struct stat buf; int rc; errno = 0; rc = stat(GLOBALS->loaded_file_name, &buf); if(GLOBALS->extload_lastmod) { if(GLOBALS->extload_already_errored) { return(0); } else if(rc != 0) { fprintf(stderr, EXTLOAD"stat error on '%s'\n", GLOBALS->loaded_file_name); perror("Why"); errno = 0; GLOBALS->extload_already_errored = 1; return(0); } else if(GLOBALS->extload_lastmod != buf.st_mtime) { fprintf(stderr, EXTLOAD"file '%s' was modified!\n", GLOBALS->loaded_file_name); GLOBALS->extload_already_errored = 1; return(0); } else { return(1); } } else { GLOBALS->extload_lastmod = buf.st_mtime; return(1); } #else return(1); #endif } #endif #ifdef WAVE_FSDB_READER_IS_PRESENT static char *get_varname(char *sbuff, unsigned char *vtp, unsigned char *vdp, int i) { #else static char *get_varname(unsigned char *vtp, unsigned char *vdp, int i) { static char sbuff[65537]; #endif char * rc; int vt, vt_len; #ifndef WAVE_FSDB_READER_IS_PRESENT for(;;) #endif { #ifndef WAVE_FSDB_READER_IS_PRESENT rc = fgets(sbuff, 65536, GLOBALS->extload); if(rc) { if(isspace(rc[0])) { char *snp; char sbuff2[65537]; sbuff2[0] = 0; if((snp=strstr(rc+1, "Struct Name:"))) { sscanf(rc+14,"%s", sbuff2); if(sbuff2[0]) { sprintf(rc, "Scope: vcd_struct %s NULL\n", sbuff2); } } else if((snp=strstr(rc+1, "Struct End"))) { sprintf(rc, "Upscope:\n"); } } } else { return(NULL); } #else rc = sbuff; #endif if((rc[0] == 'V') && (i >= 0)) { #ifndef WAVE_FSDB_READER_IS_PRESENT if(!strncmp("Var: ", rc, 5)) #endif { char *pnt = rc + 5; char *last_l = NULL; char typ[64]; char *esc = NULL; char *lb = NULL; char *colon = NULL; char *rb = NULL; int state = 0; char *vtyp_nam; char *cpyto; char *pntd; char *typ_src = pnt; char *typ_dst = typ; /* following code replaces: sscanf(rc + 5, "%s", typ) */ while(*typ_src && !isspace(*typ_src)) { *(typ_dst++) = *(typ_src++); } *typ_dst = 0; while(*pnt) { if((pnt[0] == 'l') && (pnt[1] == ':')) { last_l = pnt; } else if(pnt[0] == '\\') { esc = pnt; } else if(!last_l) { if(pnt[0] == '[') { lb = pnt; colon = NULL; rb = NULL; state = 1; } else if(pnt[0] == ']') { rb = pnt; state = 0; if(!isspace(pnt[1])) { lb = colon = rb = NULL; } } else if(pnt[0] == ':') { if(state) { colon = pnt; } } } pnt++; } if(last_l) { unsigned int l, r; /* char s1[32]; */ unsigned int d2; /* sscanf(last_l+2, "%u r:%u %s %u", &l, &r, s1, &d2); */ char *ps = last_l+2; char *l_pnt, *r_pnt, *d2_pnt; while(*ps && isspace(*ps)) { ps++; } l_pnt = ps; while(*ps && !isspace(*ps)) { ps++; } while(*ps && isspace(*ps)) { ps++; } r_pnt = ps; while(*ps && !isspace(*ps)) { ps++; } while(*ps && isspace(*ps)) { ps++; } /* s1_pnt = ps; */ while(*ps && !isspace(*ps)) { ps++; } while(*ps && isspace(*ps)) { ps++; } d2_pnt = ps; l = atoi(l_pnt); r = atoi(r_pnt+2); d2 = atoi(d2_pnt); GLOBALS->extload_idcodes[i] = d2; if(GLOBALS->extload_inv_idcodes[d2] == 0) GLOBALS->extload_inv_idcodes[d2] = i+1; /* root alias */ if(!strcmp("vcd_real", typ)) { GLOBALS->mvlfacs_vzt_c_3[i].flags = VZT_RD_SYM_F_DOUBLE; GLOBALS->extload_node_block[i].msi=0; GLOBALS->extload_node_block[i].lsi=0; GLOBALS->mvlfacs_vzt_c_3[i].len=64; } else if(!strcmp("vcd_integer", typ)) { GLOBALS->mvlfacs_vzt_c_3[i].flags = VZT_RD_SYM_F_INTEGER; GLOBALS->extload_node_block[i].msi=0; GLOBALS->extload_node_block[i].lsi=0; GLOBALS->mvlfacs_vzt_c_3[i].len=32; } else { int len_parse = 1; GLOBALS->mvlfacs_vzt_c_3[i].len=(l>r) ? (l-r+1) : (r-l+1); if(esc && lb && rb) { GLOBALS->extload_node_block[i].msi = atoi(lb+1); if(colon) { GLOBALS->extload_node_block[i].lsi = atoi(colon+1); } else { GLOBALS->extload_node_block[i].lsi = GLOBALS->extload_node_block[i].msi; } len_parse = (GLOBALS->extload_node_block[i].msi > GLOBALS->extload_node_block[i].lsi) ? (GLOBALS->extload_node_block[i].msi - GLOBALS->extload_node_block[i].lsi + 1) : (GLOBALS->extload_node_block[i].lsi - GLOBALS->extload_node_block[i].msi + 1); if(len_parse != GLOBALS->mvlfacs_vzt_c_3[i].len) { GLOBALS->extload_node_block[i].msi=l; GLOBALS->extload_node_block[i].lsi=r; } } else { if(lb && !l && !r) /* fix for stranded signals */ { GLOBALS->extload_node_block[i].msi=atoi(lb+1); GLOBALS->extload_node_block[i].lsi=atoi(lb+1); } else { GLOBALS->extload_node_block[i].msi=l; GLOBALS->extload_node_block[i].lsi=r; } } GLOBALS->mvlfacs_vzt_c_3[i].flags = VZT_RD_SYM_F_BITS; } } /* now extract directional/type information */ pnt = rc + 5; vtyp_nam = pnt; cpyto = sbuff; pntd = strrchr(last_l ? last_l : pnt, ':'); if(pntd) { unsigned char vd = ND_DIR_IMPLICIT; pntd = strchr(pntd, ' '); if(pntd) { pntd++; if(*pntd == 'o') { vd = ND_DIR_OUT; GLOBALS->nonimplicit_direction_encountered = 1; } else if(!strncmp(pntd, "in", 2)) { vd = (pntd[2] == 'p') ? ND_DIR_IN : ND_DIR_INOUT; GLOBALS->nonimplicit_direction_encountered = 1; } } if(vdp) { *vdp = vd; } } while(*pnt) { if(!isspace(*pnt)) { pnt++; } else { break; } } /* is space */ /* vvv extract vartype vvv */ if(vtp) { *pnt = 0; vt_len = pnt-vtyp_nam; if(vt_len > 4) { if(!strncmp(vtyp_nam, "vcd_", 4)) { vt = vcd_keyword_code(vtyp_nam + 4, vt_len - 4); if(vt == V_STRINGTYPE) vt = V_WIRE; } else { if(!strcmp(vtyp_nam, "stream")) { GLOBALS->extload_idcodes[i] = 0; /* kill being able to read stream variables [transactions] for now */ } vt = V_WIRE; } } else { vt = V_WIRE; } *vtp = vt; *pnt = ' '; } /* ^^^ extract vartype ^^^ */ while(*pnt) { if(isspace(*pnt)) { pnt++; } else { break; } } if(*pnt) { while(*pnt) { /* if((*pnt == '[')||(isspace(*pnt))) break; */ if(isspace(*pnt)) break; if((*pnt == '[') && (pnt == strrchr(pnt, '['))) /* fix for arrays */ { /* now to fix possible generate... */ char *pnt2 = pnt; char lastch = *pnt2; int colon_seen = 0; pnt2++; while(*pnt2 && !isspace(*pnt2) && (*pnt2 != '[')) { lastch = *pnt2; pnt2++; if(lastch == ':') { colon_seen = 1; } }; if(lastch == ']') /* fix for NC verilog arrays */ { int rng; if(colon_seen) break; rng = GLOBALS->extload_node_block[i].msi - GLOBALS->extload_node_block[i].lsi; if(!rng) { break; } } } if(*pnt == '\\') /* this is not strictly correct, but fixes generic ranges from icarus */ { pnt++; continue; } *(cpyto++) = *(pnt++); } *cpyto = 0; return(sbuff); } } } else if(rc[0] == 'S') { #ifndef WAVE_FSDB_READER_IS_PRESENT if(!strncmp(rc, "Scope:", 6)) #endif { char vht[2048]; char cname[2048]; char ctype[2048]; unsigned char ttype; vht[0] = vht[4] = vht[5] = cname[0] = ctype[0] = 0; sscanf(rc+6, "%s %s %s", vht, cname, ctype); GLOBALS->fst_scope_name = fstReaderPushScope(GLOBALS->extload_xc, cname, GLOBALS->mod_tree_parent); if(!strcmp(ctype, "NULL")) { ctype[0] = 0; } if(!strncmp(vht, "vcd_", 4)) { switch(vht[4]) { case 'm': ttype = TREE_VCD_ST_MODULE; break; case 't': ttype = TREE_VCD_ST_TASK; break; case 'f': ttype = (vht[5] == 'u') ? TREE_VCD_ST_FUNCTION : TREE_VCD_ST_FORK; break; case 'b': ttype = TREE_VCD_ST_BEGIN; break; case 'g': ttype = TREE_VCD_ST_GENERATE; break; case 's': ttype = TREE_VCD_ST_STRUCT; break; default: ttype = TREE_UNKNOWN; break; } } else if(!strncmp(vht, "sv_", 3)) { switch(vht[3]) { case 'i': ttype = TREE_VCD_ST_INTERFACE; break; default: ttype = TREE_UNKNOWN; break; } } else if(!strncmp(vht, "vhdl_", 5)) { switch(vht[5]) { case 'a': ttype = TREE_VHDL_ST_ARCHITECTURE; break; case 'r': ttype = TREE_VHDL_ST_RECORD; break; case 'b': ttype = TREE_VHDL_ST_BLOCK; break; case 'g': ttype = TREE_VHDL_ST_GENERATE; break; case 'i': ttype = TREE_VHDL_ST_GENIF; break; case 'f': ttype = (vht[6] == 'u') ? TREE_VHDL_ST_FUNCTION : TREE_VHDL_ST_GENFOR; break; case 'p': ttype = (!strncmp(vht+6, "roces", 5)) ? TREE_VHDL_ST_PROCESS: TREE_VHDL_ST_PROCEDURE; break; default: ttype = TREE_UNKNOWN; break; } } else { ttype = TREE_UNKNOWN; } allocate_and_decorate_module_tree_node(ttype, cname, ctype, strlen(cname), strlen(ctype), 0, 0); } } else if(rc[0] == 'U') { GLOBALS->mod_tree_parent = fstReaderGetCurrentScopeUserInfo(GLOBALS->extload_xc); GLOBALS->fst_scope_name = fstReaderPopScope(GLOBALS->extload_xc); } } return(NULL); } #ifdef WAVE_FSDB_READER_IS_PRESENT static void process_extload_variable(char *s_gv) #else static void process_extload_variable(void) #endif { int i; unsigned char vt, nvt; unsigned char vd; struct Node *n; struct symbol *s; char buf[65537]; char *str; struct fac *f; char *fnam; int flen; int longest_nam_candidate = 0; i = GLOBALS->extload_i; if(i<0) { #ifdef WAVE_FSDB_READER_IS_PRESENT fnam = get_varname(s_gv, &GLOBALS->extload_vt_prev, &GLOBALS->extload_vd_prev, 0); flen = strlen(fnam); if(GLOBALS->extload_hlen) { GLOBALS->extload_namecache[0 & F_NAME_MODULUS]=malloc_2(GLOBALS->extload_namecache_max[0 & F_NAME_MODULUS]=GLOBALS->extload_hlen+1+flen+1); memcpy(GLOBALS->extload_namecache[0 & F_NAME_MODULUS], GLOBALS->fst_scope_name, GLOBALS->extload_hlen); *(GLOBALS->extload_namecache[0 & F_NAME_MODULUS]+GLOBALS->extload_hlen) = '.'; strcpy(GLOBALS->extload_namecache[0 & F_NAME_MODULUS]+GLOBALS->extload_hlen+1, fnam); GLOBALS->extload_namecache_lens[0 & F_NAME_MODULUS]=GLOBALS->extload_hlen + 1 + flen; } else { GLOBALS->extload_namecache[0 & F_NAME_MODULUS]=malloc_2(GLOBALS->extload_namecache_max[0 & F_NAME_MODULUS]=flen+1); strcpy(GLOBALS->extload_namecache[0 & F_NAME_MODULUS], fnam); GLOBALS->extload_namecache_lens[0 & F_NAME_MODULUS] = flen; } #else fnam = get_varname(&GLOBALS->extload_vt_prev, &GLOBALS->extload_vd_prev, 0); flen = strlen(fnam); GLOBALS->extload_namecache[0 & F_NAME_MODULUS]=malloc_2(GLOBALS->extload_namecache_max[0 & F_NAME_MODULUS]=flen+1); strcpy(GLOBALS->extload_namecache[0 & F_NAME_MODULUS], fnam); GLOBALS->extload_namecache_lens[0 & F_NAME_MODULUS] = flen; #endif } else { vt = GLOBALS->extload_vt_prev; vd = GLOBALS->extload_vd_prev; if(i!=(GLOBALS->numfacs-1)) { #ifdef WAVE_FSDB_READER_IS_PRESENT fnam = get_varname(s_gv, &GLOBALS->extload_vt_prev, &GLOBALS->extload_vd_prev, i+1); flen = strlen(fnam); if(GLOBALS->extload_hlen) { if(GLOBALS->extload_namecache_max[(i+1)&F_NAME_MODULUS] < (GLOBALS->extload_hlen+1+flen+1)) { if(GLOBALS->extload_namecache[(i+1)&F_NAME_MODULUS]) free_2(GLOBALS->extload_namecache[(i+1)&F_NAME_MODULUS]); GLOBALS->extload_namecache[(i+1)&F_NAME_MODULUS]=malloc_2(GLOBALS->extload_namecache_max[(i+1)&F_NAME_MODULUS] = GLOBALS->extload_hlen+1+flen+1); } memcpy(GLOBALS->extload_namecache[(i+1)&F_NAME_MODULUS], GLOBALS->fst_scope_name, GLOBALS->extload_hlen); *(GLOBALS->extload_namecache[(i+1)&F_NAME_MODULUS]+GLOBALS->extload_hlen) = '.'; strcpy(GLOBALS->extload_namecache[(i+1)&F_NAME_MODULUS]+GLOBALS->extload_hlen+1, fnam); GLOBALS->extload_namecache_lens[(i+1)&F_NAME_MODULUS] = GLOBALS->extload_hlen + 1 + flen; } else { if(GLOBALS->extload_namecache_max[(i+1)&F_NAME_MODULUS] < (flen+1)) { if(GLOBALS->extload_namecache[(i+1)&F_NAME_MODULUS])free_2(GLOBALS->extload_namecache[(i+1)&F_NAME_MODULUS]); GLOBALS->extload_namecache[(i+1)&F_NAME_MODULUS]=malloc_2(GLOBALS->extload_namecache_max[(i+1)&F_NAME_MODULUS] = flen+1); } strcpy(GLOBALS->extload_namecache[(i+1)&F_NAME_MODULUS], fnam); GLOBALS->extload_namecache_lens[(i+1)&F_NAME_MODULUS] = flen; } #else fnam = get_varname(&GLOBALS->extload_vt_prev, &GLOBALS->extload_vd_prev, i+1); flen = strlen(fnam); if(GLOBALS->extload_namecache_max[(i+1)&F_NAME_MODULUS] < (flen+1)) { GLOBALS->extload_namecache[(i+1)&F_NAME_MODULUS]=malloc_2(GLOBALS->extload_namecache_max[(i+1)&F_NAME_MODULUS] = flen+1); } strcpy(GLOBALS->extload_namecache[(i+1)&F_NAME_MODULUS], fnam); GLOBALS->extload_namecache_lens[(i+1)&F_NAME_MODULUS] = flen; #endif } f=GLOBALS->mvlfacs_vzt_c_3+i; if((f->len>1)&& (!(f->flags&(VZT_RD_SYM_F_INTEGER|VZT_RD_SYM_F_DOUBLE|VZT_RD_SYM_F_STRING))) ) { int len=sprintf_2_sdd(buf, GLOBALS->extload_namecache[i&F_NAME_MODULUS],GLOBALS->extload_node_block[i].msi, GLOBALS->extload_node_block[i].lsi); longest_nam_candidate = len; if(!GLOBALS->do_hier_compress) { str=malloc_2(len+1); } else { if(len > GLOBALS->f_name_build_buf_len) { free_2(GLOBALS->f_name_build_buf); GLOBALS->f_name_build_buf = malloc_2((GLOBALS->f_name_build_buf_len=len)+1); } str = GLOBALS->f_name_build_buf; } if(!GLOBALS->alt_hier_delimeter) { strcpy(str, buf); } else { strcpy_vcdalt(str, buf, GLOBALS->alt_hier_delimeter); } s=&GLOBALS->extload_sym_block[i]; symadd_name_exists_sym_exists(s,str,0); GLOBALS->extload_prevsymroot = GLOBALS->extload_prevsym = NULL; } else if ( ((f->len==1)&&(!(f->flags&(VZT_RD_SYM_F_INTEGER|VZT_RD_SYM_F_DOUBLE|VZT_RD_SYM_F_STRING)))&& ((i!=GLOBALS->numfacs-1)&&(GLOBALS->extload_namecache_lens[i&F_NAME_MODULUS]==GLOBALS->extload_namecache_lens[(i+1)&F_NAME_MODULUS])&&(!memrevcmp(GLOBALS->extload_namecache_lens[i&F_NAME_MODULUS],GLOBALS->extload_namecache[i&F_NAME_MODULUS], GLOBALS->extload_namecache[(i+1)&F_NAME_MODULUS])))) || (((i!=0)&&(GLOBALS->extload_namecache_lens[i&F_NAME_MODULUS]==GLOBALS->extload_namecache_lens[(i-1)&F_NAME_MODULUS])&&(!memrevcmp(GLOBALS->extload_namecache_lens[i&F_NAME_MODULUS], GLOBALS->extload_namecache[i&F_NAME_MODULUS], GLOBALS->extload_namecache[(i-1)&F_NAME_MODULUS]))) && (GLOBALS->extload_node_block[i].msi!=-1)&&(GLOBALS->extload_node_block[i].lsi!=-1)) ) { int len = sprintf_2_sd(buf, GLOBALS->extload_namecache[i&F_NAME_MODULUS],GLOBALS->extload_node_block[i].msi); longest_nam_candidate = len; if(!GLOBALS->do_hier_compress) { str=malloc_2(len+1); } else { if(len > GLOBALS->f_name_build_buf_len) { free_2(GLOBALS->f_name_build_buf); GLOBALS->f_name_build_buf = malloc_2((GLOBALS->f_name_build_buf_len=len)+1); } str = GLOBALS->f_name_build_buf; } if(!GLOBALS->alt_hier_delimeter) { strcpy(str, buf); } else { strcpy_vcdalt(str, buf, GLOBALS->alt_hier_delimeter); } s=&GLOBALS->extload_sym_block[i]; symadd_name_exists_sym_exists(s,str,0); if((GLOBALS->extload_prevsym)&&(i>0)&&(GLOBALS->extload_namecache_lens[i&F_NAME_MODULUS]==GLOBALS->extload_namecache_lens[(i-1)&F_NAME_MODULUS])&&(!memrevcmp(GLOBALS->extload_namecache_lens[i&F_NAME_MODULUS], GLOBALS->extload_namecache[i&F_NAME_MODULUS], GLOBALS->extload_namecache[(i-1)&F_NAME_MODULUS]))) /* allow chaining for search functions.. */ { GLOBALS->extload_prevsym->vec_root = GLOBALS->extload_prevsymroot; GLOBALS->extload_prevsym->vec_chain = s; s->vec_root = GLOBALS->extload_prevsymroot; GLOBALS->extload_prevsym = s; } else { GLOBALS->extload_prevsymroot = GLOBALS->extload_prevsym = s; } } else { int len = GLOBALS->extload_namecache_lens[i&F_NAME_MODULUS]; longest_nam_candidate = len; if(!GLOBALS->do_hier_compress) { str=malloc_2(len+1); } else { if(len > GLOBALS->f_name_build_buf_len) { free_2(GLOBALS->f_name_build_buf); GLOBALS->f_name_build_buf = malloc_2((GLOBALS->f_name_build_buf_len=len)+1); } str = GLOBALS->f_name_build_buf; } if(!GLOBALS->alt_hier_delimeter) { strcpy(str, GLOBALS->extload_namecache[i&F_NAME_MODULUS]); } else { strcpy_vcdalt(str, GLOBALS->extload_namecache[i&F_NAME_MODULUS], GLOBALS->alt_hier_delimeter); } s=&GLOBALS->extload_sym_block[i]; symadd_name_exists_sym_exists(s,str,0); GLOBALS->extload_prevsymroot = GLOBALS->extload_prevsym = NULL; if(f->flags&VZT_RD_SYM_F_INTEGER) { GLOBALS->extload_node_block[i].msi=31; GLOBALS->extload_node_block[i].lsi=0; GLOBALS->mvlfacs_vzt_c_3[i].len=32; } } n=&GLOBALS->extload_node_block[i]; if(longest_nam_candidate > GLOBALS->longestname) GLOBALS->longestname = longest_nam_candidate; if(GLOBALS->do_hier_compress) { n->nname = compress_facility((unsigned char *)s->name, longest_nam_candidate); /* free_2(s->name); ...removed as GLOBALS->f_name_build_buf is now used */ s->name = n->nname; } else { n->nname=s->name; } n->nname=s->name; n->mv.mvlfac = GLOBALS->mvlfacs_vzt_c_3+i; GLOBALS->mvlfacs_vzt_c_3[i].working_node = n; if((f->len>1)||(f->flags&(VZT_RD_SYM_F_DOUBLE|VZT_RD_SYM_F_STRING))) { n->extvals = 1; } n->head.time=-1; /* mark 1st node as negative time */ n->head.v.h_val=AN_X; s->n=n; switch(vt) { case V_EVENT: nvt = ND_VCD_EVENT; break; case V_PARAMETER: nvt = ND_VCD_PARAMETER; break; case V_INTEGER: nvt = ND_VCD_INTEGER; break; case V_REAL: nvt = ND_VCD_REAL; break; case V_REG: nvt = ND_VCD_REG; break; case V_SUPPLY0: nvt = ND_VCD_SUPPLY0; break; case V_SUPPLY1: nvt = ND_VCD_SUPPLY1; break; case V_TIME: nvt = ND_VCD_TIME; break; case V_TRI: nvt = ND_VCD_TRI; break; case V_TRIAND: nvt = ND_VCD_TRIAND; break; case V_TRIOR: nvt = ND_VCD_TRIOR; break; case V_TRIREG: nvt = ND_VCD_TRIREG; break; case V_TRI0: nvt = ND_VCD_TRI0; break; case V_TRI1: nvt = ND_VCD_TRI1; break; case V_WAND: nvt = ND_VCD_WAND; break; case V_WIRE: nvt = ND_VCD_WIRE; break; case V_WOR: nvt = ND_VCD_WOR; break; case V_PORT: nvt = ND_VCD_PORT; break; case V_STRINGTYPE: nvt = ND_GEN_STRING; break; default: nvt = ND_UNSPECIFIED_DEFAULT; break; } n->vartype = nvt; n->vardir = vd; } GLOBALS->extload_i++; } #ifdef WAVE_FSDB_READER_IS_PRESENT static void extload_hiertree_callback(void *pnt) { char *s = (char *)pnt; switch(s[0]) { case 'S': case 'U': get_varname(s, NULL, NULL, -1); GLOBALS->extload_hlen = GLOBALS->fst_scope_name ? strlen(GLOBALS->fst_scope_name) : 0; break; case 'V': process_extload_variable(s); default: break; } } #endif /* * mainline */ static TimeType extload_main_2(char *fname, char *skip_start, char *skip_end) { int max_idcode; #ifndef WAVE_FSDB_READER_IS_PRESENT char sbuff[65537]; unsigned int msk = 0; #endif int i; if(!(GLOBALS->extload=fopen(fname, "rb"))) { GLOBALS->extload_already_errored = 1; return(LLDescriptor(0)); /* look at GLOBALS->vzt_vzt_c_1 in caller for success status... */ } fclose(GLOBALS->extload); /* SPLASH */ splash_create(); #ifdef WAVE_FSDB_READER_IS_PRESENT GLOBALS->extload_ffr_ctx = fsdbReaderOpenFile(GLOBALS->loaded_file_name); GLOBALS->is_lx2 = LXT2_IS_FSDB; if(GLOBALS->extload_ffr_ctx) { int rv; int mult; char scale; uint64_t tim; struct fsdbReaderGetStatistics_t *gs; int success_count = 0; int attempt_count = 0; attempt_count++; rv = fsdbReaderExtractScaleUnit(GLOBALS->extload_ffr_ctx, &mult, &scale); if(rv) { GLOBALS->time_scale = mult; GLOBALS->time_dimension = tolower(scale); success_count++; } attempt_count++; rv = fsdbReaderGetMinFsdbTag64(GLOBALS->extload_ffr_ctx, &tim); if(rv) { GLOBALS->min_time = tim; success_count++; } attempt_count++; rv = fsdbReaderGetMaxFsdbTag64(GLOBALS->extload_ffr_ctx, &tim); if(rv) { GLOBALS->max_time = tim; if(GLOBALS->max_time == LLDescriptor(0)) { GLOBALS->max_time = LLDescriptor(1); } success_count++; } attempt_count++; gs = fsdbReaderGetStatistics(GLOBALS->extload_ffr_ctx); if(gs) { GLOBALS->numfacs = gs->varCount; free(gs); success_count++; } attempt_count++; max_idcode = fsdbReaderGetMaxVarIdcode(GLOBALS->extload_ffr_ctx); if(max_idcode) { success_count++; } else { max_idcode = GLOBALS->numfacs; /* for 1.x format files */ success_count++; } if(attempt_count != success_count) { fprintf(stderr, EXTLOAD"Could not initialize '%s' properly.\n", fname); GLOBALS->extload_already_errored = 1; return(LLDescriptor(0)); } } else { fprintf(stderr, EXTLOAD"Could not initialize '%s' properly.\n", fname); GLOBALS->extload_already_errored = 1; return(LLDescriptor(0)); } #else last_modification_check(); sprintf(sbuff, "%s -info %s 2>&1", EXTLOAD_PATH, fname); GLOBALS->extload = popen(sbuff, "r"); for(;;) { char * rc = fgets(sbuff, 65536, GLOBALS->extload); if(!rc) break; switch(rc[0]) { case 's': if(!strncmp("scale unit", rc, 10)) { char *pnt = strchr(rc+10, ':'); if(pnt) { pnt++; GLOBALS->time_scale = atoi(pnt); GLOBALS->time_dimension = 'n'; while(*pnt) { if(isalpha(*pnt)) { GLOBALS->time_dimension = tolower(*pnt); break; } pnt++; } msk |= 1; } } break; case 'm': if(!strncmp("minimum xtag", rc, 12)) { char *pnt = strchr(rc+12, '('); if(pnt) { unsigned int lo = 0, hi = 0; pnt++; sscanf(pnt, "%u %u", &hi, &lo); GLOBALS->min_time = (TimeType)((((UTimeType)hi)<<32) + ((UTimeType)lo)); msk |= 2; } } else if(!strncmp("maximum xtag", rc, 12)) { char *pnt = strchr(rc+12, '('); if(pnt) { unsigned int lo = 0, hi = 0; pnt++; sscanf(pnt, "%u %u", &hi, &lo); GLOBALS->max_time = (TimeType)((((UTimeType)hi)<<32) + ((UTimeType)lo)); if(GLOBALS->max_time == LLDescriptor(0)) { GLOBALS->max_time = LLDescriptor(1); } msk |= 4; } } else if(!strncmp("max var idcode", rc, 14)) { char *pnt = strchr(rc+14, ':'); if(pnt) { pnt++; sscanf(pnt, "%d", &max_idcode); msk |= 8; } } break; case 'v': if(!strncmp("var creation cnt", rc, 16)) { char *pnt = strchr(rc+16, ':'); if(pnt) { pnt++; sscanf(pnt, "%d", &GLOBALS->numfacs); msk |= 16; } } case 'f': if(!strncmp("file status", rc, 11)) { char *pnt = strchr(rc+11, ':'); if(pnt) { pnt++; if(strstr(pnt, "finished")) { msk |= 32; } } } break; default: break; } } pclose(GLOBALS->extload); if(msk != (1+2+4+8+16+32)) { fprintf(stderr, EXTLOAD"Could not initialize '%s' properly.\n", fname); if((msk & (1+2+4+8+16+32)) == (1+2+4+8+16)) { fprintf(stderr, EXTLOAD"File is not finished dumping.\n"); } GLOBALS->extload_already_errored = 1; return(LLDescriptor(0)); } #endif GLOBALS->min_time *= GLOBALS->time_scale; GLOBALS->max_time *= GLOBALS->time_scale; GLOBALS->mvlfacs_vzt_c_3=(struct fac *)calloc_2(GLOBALS->numfacs,sizeof(struct fac)); GLOBALS->vzt_table_vzt_c_1=(struct lx2_entry *)calloc_2(GLOBALS->numfacs, sizeof(struct lx2_entry)); GLOBALS->extload_namecache=(char **)calloc_2(F_NAME_MODULUS+1, sizeof(char *)); GLOBALS->extload_namecache_max=(int *)calloc_2(F_NAME_MODULUS+1, sizeof(int)); GLOBALS->extload_namecache_lens=(int *)calloc_2(F_NAME_MODULUS+1, sizeof(int)); GLOBALS->extload_sym_block = (struct symbol *)calloc_2(GLOBALS->numfacs, sizeof(struct symbol)); GLOBALS->extload_node_block=(struct Node *)calloc_2(GLOBALS->numfacs,sizeof(struct Node)); GLOBALS->extload_idcodes=(unsigned int *)calloc_2(GLOBALS->numfacs, sizeof(unsigned int)); GLOBALS->extload_inv_idcodes=(int *)calloc_2(max_idcode+1, sizeof(int)); if(!GLOBALS->fast_tree_sort) { GLOBALS->do_hier_compress = 0; } GLOBALS->f_name_build_buf_len = 128; GLOBALS->f_name_build_buf = malloc_2(GLOBALS->f_name_build_buf_len + 1); init_facility_pack(); /* SPLASH */ splash_sync(1, 5); #ifdef WAVE_FSDB_READER_IS_PRESENT if(!GLOBALS->hier_was_explicitly_set) /* set default hierarchy split char */ { GLOBALS->hier_delimeter='.'; } GLOBALS->extload_xc = fstReaderOpenForUtilitiesOnly(); GLOBALS->extload_i=-1; fsdbReaderReadScopeVarTree(GLOBALS->extload_ffr_ctx, extload_hiertree_callback); process_extload_variable(NULL); /* flush out final cached variable */ decorated_module_cleanup(); /* ...also now in gtk2_treesearch.c */ iter_through_comp_name_table(); for(i=0;i<=F_NAME_MODULUS;i++) { if(GLOBALS->extload_namecache[i]) { free_2(GLOBALS->extload_namecache[i]); GLOBALS->extload_namecache[i] = NULL; } } free_2(GLOBALS->extload_namecache); GLOBALS->extload_namecache = NULL; free_2(GLOBALS->extload_namecache_max); GLOBALS->extload_namecache_max = NULL; free_2(GLOBALS->extload_namecache_lens); GLOBALS->extload_namecache_lens = NULL; fstReaderClose(GLOBALS->extload_xc); /* corresponds to fstReaderOpenForUtilitiesOnly() */ #else if(!last_modification_check()) { GLOBALS->extload_already_errored = 1; return(LLDescriptor(0)); } sprintf(sbuff, "%s -hier_tree %s 2>&1", EXTLOAD_PATH, fname); GLOBALS->extload = popen(sbuff, "r"); /* do your stuff here..all useful info has been initialized by now */ if(!GLOBALS->hier_was_explicitly_set) /* set default hierarchy split char */ { GLOBALS->hier_delimeter='.'; } GLOBALS->extload_xc = fstReaderOpenForUtilitiesOnly(); for(GLOBALS->extload_i=-1;(GLOBALS->numfacs) && (GLOBALS->extload_inumfacs);) { process_extload_variable(); } while(get_varname(&GLOBALS->extload_vt_prev, NULL, -1)); /* read through end to process all upscopes */ decorated_module_cleanup(); /* ...also now in gtk2_treesearch.c */ iter_through_comp_name_table(); for(i=0;i<=F_NAME_MODULUS;i++) { if(GLOBALS->extload_namecache[i]) { free_2(GLOBALS->extload_namecache[i]); GLOBALS->extload_namecache[i] = NULL; } } free_2(GLOBALS->extload_namecache); GLOBALS->extload_namecache = NULL; free_2(GLOBALS->extload_namecache_max); GLOBALS->extload_namecache_max = NULL; free_2(GLOBALS->extload_namecache_lens); GLOBALS->extload_namecache_lens = NULL; pclose(GLOBALS->extload); fstReaderClose(GLOBALS->extload_xc); /* corresponds to fstReaderOpenForUtilitiesOnly() */ #endif /* SPLASH */ splash_sync(2, 5); if(GLOBALS->f_name_build_buf) { free_2(GLOBALS->f_name_build_buf); GLOBALS->f_name_build_buf = NULL; } freeze_facility_pack(); GLOBALS->facs=(struct symbol **)malloc_2(GLOBALS->numfacs*sizeof(struct symbol *)); if(GLOBALS->fast_tree_sort) { for(i=0;inumfacs;i++) { GLOBALS->facs[i]=&GLOBALS->extload_sym_block[i]; } /* SPLASH */ splash_sync(3, 5); fprintf(stderr, EXTLOAD"Building facility hierarchy tree.\n"); init_tree(); for(i=0;inumfacs;i++) { int was_packed = HIER_DEPACK_STATIC; /* no need to free_2() afterward then */ char *sb = hier_decompress_flagged(GLOBALS->facs[i]->name, &was_packed); build_tree_from_name(sb, i); } /* SPLASH */ splash_sync(4, 5); treegraft(&GLOBALS->treeroot); fprintf(stderr, EXTLOAD"Sorting facility hierarchy tree.\n"); treesort(GLOBALS->treeroot, NULL); /* SPLASH */ splash_sync(5, 5); order_facs_from_treesort(GLOBALS->treeroot, &GLOBALS->facs); GLOBALS->facs_are_sorted=1; } else { for(i=0;inumfacs;i++) { char *subst; #ifdef WAVE_HIERFIX char ch; #endif int len; GLOBALS->facs[i]=&GLOBALS->extload_sym_block[i]; subst=GLOBALS->facs[i]->name; if((len=strlen(subst))>GLOBALS->longestname) GLOBALS->longestname=len; #ifdef WAVE_HIERFIX while((ch=(*subst))) { if(ch==GLOBALS->hier_delimeter) { *subst=VCDNAM_HIERSORT; } /* forces sort at hier boundaries */ subst++; } #endif } /* SPLASH */ splash_sync(3, 5); fprintf(stderr, EXTLOAD"Sorting facilities at hierarchy boundaries.\n"); wave_heapsort(GLOBALS->facs,GLOBALS->numfacs); #ifdef WAVE_HIERFIX for(i=0;inumfacs;i++) { char *subst, ch; subst=GLOBALS->facs[i]->name; while((ch=(*subst))) { if(ch==VCDNAM_HIERSORT) { *subst=GLOBALS->hier_delimeter; } /* restore back to normal */ subst++; } } #endif GLOBALS->facs_are_sorted=1; /* SPLASH */ splash_sync(4, 5); fprintf(stderr, EXTLOAD"Building facility hierarchy tree.\n"); init_tree(); for(i=0;inumfacs;i++) { char *nf = GLOBALS->facs[i]->name; build_tree_from_name(nf, i); } /* SPLASH */ splash_sync(5, 5); treegraft(&GLOBALS->treeroot); treesort(GLOBALS->treeroot, NULL); } if(skip_start || skip_end) { TimeType b_start, b_end; if(!skip_start) b_start = GLOBALS->min_time; else b_start = unformat_time(skip_start, GLOBALS->time_dimension); if(!skip_end) b_end = GLOBALS->max_time; else b_end = unformat_time(skip_end, GLOBALS->time_dimension); if(b_startmin_time) b_start = GLOBALS->min_time; else if(b_start>GLOBALS->max_time) b_start = GLOBALS->max_time; if(b_endmin_time) b_end = GLOBALS->min_time; else if(b_end>GLOBALS->max_time) b_end = GLOBALS->max_time; if(b_start > b_end) { TimeType tmp_time = b_start; b_start = b_end; b_end = tmp_time; } GLOBALS->min_time = b_start; GLOBALS->max_time = b_end; } /* SPLASH */ splash_finalize(); return(GLOBALS->max_time); } TimeType extload_main(char *fname, char *skip_start, char *skip_end) { TimeType tt = extload_main_2(fname, skip_start, skip_end); if(!tt) { if(GLOBALS->extload_ffr_ctx) { #ifdef WAVE_FSDB_READER_IS_PRESENT fsdbReaderClose(GLOBALS->extload_ffr_ctx); #endif GLOBALS->extload_ffr_ctx = NULL; } } return(tt); } /* * extload callback (only does bits for now) */ static void extload_callback(TimeType *tim, int *facidx, char **value) { struct HistEnt *htemp = histent_calloc(); struct lx2_entry *l2e = GLOBALS->vzt_table_vzt_c_1+(*facidx); struct fac *f = GLOBALS->mvlfacs_vzt_c_3+(*facidx); GLOBALS->busycnt_vzt_c_2++; if(GLOBALS->busycnt_vzt_c_2==WAVE_BUSY_ITER) { busy_window_refresh(); GLOBALS->busycnt_vzt_c_2 = 0; } /* fprintf(stderr, "%lld %d %s\n", *tim, *facidx, *value); */ if(!(f->flags&(VZT_RD_SYM_F_DOUBLE|VZT_RD_SYM_F_STRING))) { if(f->len>1) { htemp->v.h_vector = (char *)malloc_2(f->len); memcpy(htemp->v.h_vector, *value, f->len); } else { switch(**value) { case '0': htemp->v.h_val = AN_0; break; case '1': htemp->v.h_val = AN_1; break; case 'z': htemp->v.h_val = AN_Z; break; default: htemp->v.h_val = AN_X; break; } } } else if(f->flags&VZT_RD_SYM_F_DOUBLE) { #ifdef WAVE_HAS_H_DOUBLE sscanf(*value, "%lg", &htemp->v.h_double); #else double *d = malloc_2(sizeof(double)); sscanf(*value, "%lg", d); htemp->v.h_vector = (char *)d; #endif htemp->flags = HIST_REAL; } else /* string */ { char *s = malloc_2(strlen(*value)+1); strcpy(s, *value); htemp->v.h_vector = s; htemp->flags = HIST_REAL|HIST_STRING; } htemp->time = (*tim) * (GLOBALS->time_scale); if(l2e->histent_head) { l2e->histent_curr->next = htemp; l2e->histent_curr = htemp; } else { l2e->histent_head = l2e->histent_curr = htemp; } l2e->numtrans++; } /* * this is the black magic that handles aliased signals... */ static void ext_resolver(nptr np, nptr resolve) { np->extvals = resolve->extvals; np->msi = resolve->msi; np->lsi = resolve->lsi; memcpy(&np->head, &resolve->head, sizeof(struct HistEnt)); np->curr = resolve->curr; np->harray = resolve->harray; np->numhist = resolve->numhist; np->mv.mvlfac=NULL; } /* * actually import a extload trace but don't do it if it's already been imported */ void import_extload_trace(nptr np) { struct HistEnt *htemp, *histent_tail; int len, i; struct fac *f; int txidx, txidx_in_trace; nptr nold = np; if(!(f=np->mv.mvlfac)) return; /* already imported */ txidx = f - GLOBALS->mvlfacs_vzt_c_3; txidx_in_trace = GLOBALS->extload_idcodes[txidx]; if(GLOBALS->extload_inv_idcodes[txidx_in_trace] < 0) { txidx = (-GLOBALS->extload_inv_idcodes[txidx_in_trace]) - 1; np = GLOBALS->mvlfacs_vzt_c_3[txidx].working_node; if(!(f=np->mv.mvlfac)) { ext_resolver(nold, np); return; /* already imported */ } } GLOBALS->extload_inv_idcodes[txidx_in_trace] = - (txidx + 1); #ifndef WAVE_FSDB_READER_IS_PRESENT fprintf(stderr, EXTLOAD"Import: %s\n", np->nname); #endif /* new stuff */ len = np->mv.mvlfac->len; #ifdef WAVE_FSDB_READER_IS_PRESENT if(0) { /* process transactions here */ } else /* "normal" VC data */ { void *hdl; /* fsdbReaderAddToSignalList(GLOBALS->extload_ffr_ctx, txidx_in_trace); */ /* fsdbReaderLoadSignals(GLOBALS->extload_ffr_ctx); */ hdl = fsdbReaderCreateVCTraverseHandle(GLOBALS->extload_ffr_ctx, txidx_in_trace); if(fsdbReaderHasIncoreVC(GLOBALS->extload_ffr_ctx, hdl)) { TimeType mxt_max = -2; TimeType mxt = (TimeType)fsdbReaderGetMinXTag(GLOBALS->extload_ffr_ctx, hdl); int rc_xtag = fsdbReaderGotoXTag(GLOBALS->extload_ffr_ctx, hdl, mxt); while(rc_xtag && (mxt >= mxt_max)) /* malformed traces sometimes backtrack time */ { void *val_ptr; char *b; if(!fsdbReaderGetVC(GLOBALS->extload_ffr_ctx, hdl, &val_ptr)) { break; } b = fsdbReaderTranslateVC(hdl, val_ptr); extload_callback(&mxt, &txidx, &b); if(!fsdbReaderGotoNextVC(GLOBALS->extload_ffr_ctx, hdl)) { break; } mxt_max = mxt; mxt = (TimeType)fsdbReaderGetXTag(GLOBALS->extload_ffr_ctx, hdl, &rc_xtag); } } fsdbReaderFree(GLOBALS->extload_ffr_ctx, hdl); /* fsdbReaderUnloadSignals(GLOBALS->extload_ffr_ctx); */ } #else if(last_modification_check()) /* place array height check here in an "&&" branch, sorry, arrays not supported */ { char sbuff[65537]; TimeType tim; sprintf(sbuff, "%s -vc -vidcode %d %s 2>&1", EXTLOAD_PATH, txidx_in_trace, GLOBALS->loaded_file_name); GLOBALS->extload = popen(sbuff, "r"); for(;;) { char *rc = fgets(sbuff, 65536, GLOBALS->extload); if(!rc) { break; } if(isdigit(rc[0])) { rc = strchr(rc, '('); if(rc) { unsigned int lo = 0, hi = 0; sscanf(rc+1, "%u %u", &hi, &lo); tim = (TimeType)((((UTimeType)hi)<<32) + ((UTimeType)lo)); rc = strchr(rc+1, ')'); if(rc) { rc = strchr(rc+1, ':'); if(rc) { char *rtn, *pnt; rc += 2; rtn = rc; while(*rtn) { if(isspace(*rtn)) { *rtn = 0; break; } rtn++; } pnt = rc; while(*pnt) { switch(*pnt) { case 'Z': case '3': *pnt = 'z'; break; case 'X': case '2': *pnt = 'x'; break; default: break; } pnt++; } extload_callback(&tim, &txidx, &rc); } } } } } pclose(GLOBALS->extload); } #endif histent_tail = htemp = histent_calloc(); if(len>1) { htemp->v.h_vector = (char *)malloc_2(len); for(i=0;iv.h_vector[i] = AN_Z; } else { htemp->v.h_val = AN_Z; /* z */ } htemp->time = MAX_HISTENT_TIME; htemp = histent_calloc(); if(len>1) { htemp->v.h_vector = (char *)malloc_2(len); for(i=0;iv.h_vector[i] = AN_X; } else { htemp->v.h_val = AN_X; /* x */ } htemp->time = MAX_HISTENT_TIME-1; htemp->next = histent_tail; if(GLOBALS->vzt_table_vzt_c_1[txidx].histent_curr) { GLOBALS->vzt_table_vzt_c_1[txidx].histent_curr->next = htemp; htemp = GLOBALS->vzt_table_vzt_c_1[txidx].histent_head; } if(!(f->flags&(VZT_RD_SYM_F_DOUBLE|VZT_RD_SYM_F_STRING))) { if(len>1) { np->head.v.h_vector = (char *)malloc_2(len); for(i=0;ihead.v.h_vector[i] = AN_X; } else { np->head.v.h_val = AN_X; /* x */ } } else { np->head.flags = HIST_REAL; if(f->flags&VZT_RD_SYM_F_STRING) np->head.flags |= HIST_STRING; } { struct HistEnt *htemp2 = histent_calloc(); htemp2->time = -1; if(len>1) { htemp2->v.h_vector = htemp->v.h_vector; } else { htemp2->v.h_val = htemp->v.h_val; } htemp2->next = htemp; htemp = htemp2; GLOBALS->vzt_table_vzt_c_1[txidx].numtrans++; } np->head.time = -2; np->head.next = htemp; np->numhist=GLOBALS->vzt_table_vzt_c_1[txidx].numtrans +2 /*endcap*/ +1 /*frontcap*/; memset(GLOBALS->vzt_table_vzt_c_1+txidx, 0, sizeof(struct lx2_entry)); /* zero it out */ np->curr = histent_tail; np->mv.mvlfac = NULL; /* it's imported and cached so we can forget it's an mvlfac now */ if(nold!=np) { ext_resolver(nold, np); } } void fsdb_import_masked(void) { #ifdef WAVE_FSDB_READER_IS_PRESENT fsdbReaderLoadSignals(GLOBALS->extload_ffr_ctx); GLOBALS->extload_ffr_import_count = 0; #endif } void fsdb_set_fac_process_mask(nptr np) { #ifdef WAVE_FSDB_READER_IS_PRESENT struct fac *f; int txidx, txidx_in_trace; if(!(f=np->mv.mvlfac)) return; /* already imported */ txidx = f - GLOBALS->mvlfacs_vzt_c_3; txidx_in_trace = GLOBALS->extload_idcodes[txidx]; if(GLOBALS->extload_inv_idcodes[txidx_in_trace] > 0) { if(!GLOBALS->extload_ffr_import_count) { fsdbReaderUnloadSignals(GLOBALS->extload_ffr_ctx); fsdbReaderResetSignalList(GLOBALS->extload_ffr_ctx); } GLOBALS->extload_ffr_import_count++; fsdbReaderAddToSignalList(GLOBALS->extload_ffr_ctx, txidx_in_trace); } #else (void)np; #endif } #endif gtkwave-3.3.66/src/tcl_support_commands.c0000664000076400007640000004060112372010236017766 0ustar bybellbybell/* * Copyright (c) Yiftach Tzori 2009-2012. * * 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. */ #include #include "globals.h" #include #include #include #include #include "gtk12compat.h" #include "analyzer.h" #include "tree.h" #include "symbol.h" #include "vcd.h" #include "lx2.h" #include "busy.h" #include "debug.h" #include "hierpack.h" #include "tcl_helper.h" #include "tcl_support_commands.h" /* ** * Search for a tree node that is associated with the hierarchical path * return pointer to this node or NULL */ GtkCTreeNode *SST_find_node_by_path(GtkCTreeRow *root, char *path) { char *s = strdup_2(path) ; char *p = s ; char *p1 ; GtkCTreeRow *gctr = root ; GtkCTreeNode *node = gctr->parent ; struct tree *t ; int i ; /* in the cases of path that where generated inside a `generate-for' block * path name will contain '[]'. This will prompt TCL to soround PATH with * '{' and '}' */ if (*p == '{' && (p1 = strrchr(p, '}'))) { p++ ; *p1 = '\0' ; } while (gctr) { if ((p1 = strchr(p, '.'))) *p1 = '\0' ; t = (struct tree *)(gctr->row.data) ; i = 0 ; while (strcmp(t->name, p)) { /* name mis-match */ if (!(node = gctr->sibling)) { /* no more siblings */ gctr = NULL ; break ; } else { gctr = GTK_CTREE_ROW(node); t = (struct tree *)(gctr->row.data) ; } i++ ; } if (gctr) { /* normal exit from the above */ if(!p1) {/* first/last in chain */ if(i == 0) /* first */ if(gctr->children) node = GTK_CTREE_ROW(gctr->children)->parent ; break ; } else { /* keep going down the hierarchy */ if (!(node = gctr->children)) break ; else { gctr = GTK_CTREE_ROW(gctr->children) ; p = p1 + 1 ; } } } } free_2(s) ; return node ; } /* ** * Open the hierarchy tree, starting from 'node' up to the root */ int SST_open_path(GtkCTree *ctree, GtkCTreeNode *node) { GtkCTreeRow *row ; for(row = GTK_CTREE_ROW(node) ; row->parent; row = GTK_CTREE_ROW(row->parent)) { if(row->parent) gtk_ctree_expand(ctree, row->parent); else break ; } return 0 ; } /* ** * Main function called by gtkwavetcl_forceOpenTreeNode * Inputs: * char *name :: hierachical path to open * Output: * One of: * SST_NODE_FOUND - if path is in the dump file * SST_NODE_NOT_EXIST - is path is not in the dump * SST_TREE_NOT_EXIST - is Tree widget does not exist * Side effects: * If path is in the dump then its tree is opened and scrolled * to be it to display. Node is selected and associated signals * are displayed. * No change in any other case */ int SST_open_node(char *name) { int rv ; #ifdef WAVE_USE_GTK2 GtkCTree *ctree = GLOBALS->ctree_main; if (ctree) { GtkCTreeRow *gctr; GtkCTreeNode *target_node ; for(gctr = GTK_CTREE_ROW(GLOBALS->any_tree_node); gctr->parent; gctr = GTK_CTREE_ROW(gctr->parent)) ; if ((target_node = SST_find_node_by_path(gctr, name))) { struct tree *t ; rv = SST_NODE_FOUND ; gtk_ctree_collapse_recursive(ctree, gctr->parent) ; SST_open_path(ctree, target_node) ; gtk_ctree_node_moveto(ctree, target_node, 0, 0.5, 0.5); gtk_ctree_select(ctree, target_node); gctr = GTK_CTREE_ROW(target_node) ; t = (struct tree *)(gctr->row.data) ; GLOBALS->sig_root_treesearch_gtk2_c_1 = t->child; fill_sig_store (); } else { rv = SST_NODE_NOT_EXIST ; } } else { rv = SST_TREE_NOT_EXIST ; } #else (void)name; rv = SST_TREE_NOT_EXIST ; #endif return rv ; } /* ===== Double link lists */ llist_p *llist_new(llist_u v, ll_elem_type type, int arg) { llist_p *p = (llist_p *)malloc_2(sizeof(llist_p)) ; p->next = p->prev = NULL ; switch(type) { case LL_INT: p->u.i = v.i ; break ; case LL_UINT: p->u.u = v.u ; break ; case LL_TIMETYPE: p->u.tt = v.tt ; break ; case LL_CHAR: p->u.c = v.c ; break ; case LL_SHORT: p->u.s = v.s ; break ; case LL_STR: if(arg == -1) p->u.str = strdup_2(v.str) ; else { p->u.str = (char *)malloc_2(arg) ; strncpy(p->u.str, v.str, arg) ; p->u.str[arg] = '\0' ; } break ; case LL_VOID_P: p->u.p = v.p ; break ; default: fprintf(stderr, "Internal error in llist_new(), type: %d\n", type); exit(255); } return p ; } /* * append llist_p element ELEM to the of the list whose first member is HEAD amd * last is TAIL. and return the head of the list. * if HEAD is NULL ELEM is returned. * if TAIL is defined then ELEM is chained to it and TAIL is set to point to * ELEM */ llist_p *llist_append(llist_p *head, llist_p *elem, llist_p **tail) { llist_p *p ; if (*tail) { p = tail[0] ; p->next = elem ; elem->prev = p ; tail[0] = elem ; } else { if (head) { for(p = head ; p->next; p = p->next) ; p->next = elem ; elem ->prev = p ; } else { head = elem ; } } return head ; } /* * Remove the last element from list whose first member is HEAD * if TYPE is LL_STR the memory allocated for this string is freed. * if the TYPE is LL_VOID_P that the caller supplied function pointer F() is * is executed (if not NULL) * HEAD and TAIL are updated. */ llist_p *llist_remove_last(llist_p *head, llist_p **tail, ll_elem_type type, void *f(void *) ) { if (head) { llist_p *p = tail[0] ; switch(type) { case LL_STR: free_2(p->u.str) ; break ; case LL_VOID_P: if (f) f(p->u.p) ; break ; default: fprintf(stderr, "Internal error in llist_remove_last(), type: %d\n", type); exit(255); } if (p->prev) { tail[0] = p->prev ; } else { head = tail[0] = NULL ; } free_2(p) ; } return head ; } /* Destroy the list whose first member is HEAD * function pointer F() is called in type is LL_VOID_P * if TYPE is LL_STR then string is freed */ void llist_free(llist_p *head, ll_elem_type type, void *f(void *)) { llist_p *p = head, *p1 ; while(p) { p1 = p->next ; switch(type) { case LL_STR: free_2(p->u.str) ; break ; case LL_VOID_P: if (f) f(p->u.p) ; break ; default: fprintf(stderr, "Internal error in llist_free(), type: %d\n", type); exit(255); } free_2(p) ; p = p1 ; } } /* ===================================================== */ /* Create a Trptr structure that contains the bit-vector VEC * This is based on the function AddVector() */ Trptr BitVector_to_Trptr(bvptr vec) { Trptr t; int n; GLOBALS->signalwindow_width_dirty=1; n = vec->nbits; t = (Trptr) calloc_2(1, sizeof( TraceEnt ) ); if( t == NULL ) { fprintf( stderr, "Out of memory, can't add %s to analyzer\n", vec->bvname ); return( 0 ); } t->name = vec->bvname; if(GLOBALS->hier_max_level) t->name = hier_extract(t->name, GLOBALS->hier_max_level); t->flags = ( n > 3 ) ? TR_HEX|TR_RJUSTIFY : TR_BIN|TR_RJUSTIFY; t->vector = TRUE; t->n.vec = vec; /* AddTrace( t ); */ return( t ); } Trptr find_first_highlighted_trace(void) { Trptr t=GLOBALS->traces.first; while(t) { if(t->flags&TR_HIGHLIGHT) { if(!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH))) { break; } } t=t->t_next; } return(t); } /* Find is signal named NAME is on display and return is Trptr value * or NULL * NAME is a full hierarchical name, but may not in include range '[..:..]' * information. */ Trptr is_signal_displayed(char *name) { Trptr t=GLOBALS->traces.first ; char *p = strchr(name, '['), *p1 ; unsigned int len, len1 ; if(p) *p = '\0' ; len = strlen(name) ; while(t) { int was_packed = HIER_DEPACK_ALLOC; int cc; if(t->vector) { p = t->n.vec->bvname; } else { if(t->n.vec) { p = hier_decompress_flagged(t->n.nd->nname, &was_packed); } else { p = NULL; } } if(p) { p1 = strchr(p,'[') ; len1 = (p1) ? (unsigned int)(p1 - p) : strlen(p) ; cc = ((len == len1) && !strncmp(name, p, len)); if(was_packed) free_2(p); if(cc) break ; } t = t->t_next ; } return t ; } /* Create a Trptr structure for ND and return its value * This is based on the function AddNodeTraceReturn() */ Trptr Node_to_Trptr(nptr nd) { Trptr t = NULL; hptr histpnt; hptr *harray; int histcount; int i; if(nd->mv.mvlfac) import_trace(nd); GLOBALS->signalwindow_width_dirty=1; if( (t = (Trptr) calloc_2( 1, sizeof( TraceEnt ))) == NULL ) { fprintf( stderr, "Out of memory, can't add to analyzer\n" ); return( 0 ); } if(!nd->harray) { /* make quick array lookup for aet display */ histpnt=&(nd->head); histcount=0; while(histpnt) { histcount++; histpnt=histpnt->next; } nd->numhist=histcount; if(!(nd->harray=harray=(hptr *)malloc_2(histcount*sizeof(hptr)))) { fprintf( stderr, "Out of memory, can't add to analyzer\n" ); free_2(t); return(0); } histpnt=&(nd->head); for(i=0;inext; } } if(!GLOBALS->hier_max_level) { int flagged = HIER_DEPACK_ALLOC; t->name = hier_decompress_flagged(nd->nname, &flagged); t->is_depacked = (flagged != 0); } else { int flagged = HIER_DEPACK_ALLOC; char *tbuff = hier_decompress_flagged(nd->nname, &flagged); if(!flagged) { t->name = hier_extract(nd->nname, GLOBALS->hier_max_level); } else { t->name = strdup_2(hier_extract(tbuff, GLOBALS->hier_max_level)); free_2(tbuff); t->is_depacked = 1; } } if(nd->extvals) { /* expansion vectors */ int n; n = nd->msi - nd->lsi; if(n<0)n=-n; n++; t->flags = (( n > 3 )||( n < -3 )) ? TR_HEX|TR_RJUSTIFY : TR_BIN|TR_RJUSTIFY; } else { t->flags |= TR_BIN; /* binary */ } t->vector = FALSE; t->n.nd = nd; /* if(tret) *tret = t; ... for expand */ return t ; } /* * Search for the signal named (full path) NAME in the signal data base and * create a Trptr structure for it * NAME is a full hierarchy name, but may not include range information. * Return the structure created or NULL */ Trptr sig_name_to_Trptr(char *name) { Trptr t = NULL ; int was_packed = HIER_DEPACK_ALLOC; int i, name_len; char *hfacname = NULL; struct symbol *s = NULL, *s2 ; int len = 0 ; bvptr v = NULL; bptr b = NULL; int pre_import = 0; if(name) { name_len = strlen(name); for(i=0;inumfacs;i++) { hfacname = hier_decompress_flagged(GLOBALS->facs[i]->name, &was_packed); if(!strcmp(name, hfacname) || ((!strncmp(name, hfacname, name_len) && hfacname[name_len] == '['))) { s = GLOBALS->facs[i]; if((s2 = s->vec_root)) { s = s2; } else { s2 = s; } if(GLOBALS->is_lx2) { while(s2) { if(s2->n->mv.mvlfac) /* the node doesn't exist yet! */ { lx2_set_fac_process_mask(s2->n); pre_import++; } s2 = s2->vec_chain; len++; } } else { while(s2) { s2 = s2->vec_chain; len++; } } if(was_packed) { free_2(hfacname); } break; } if(was_packed) { free_2(hfacname); } s = NULL; } if(s) { if(pre_import) { lx2_import_masked(); /* import any missing nodes */ } if(len > 1) { if ((b = makevec_chain(NULL, s, len))) { if((v=bits2vector(b))) { t = BitVector_to_Trptr(v) ; } else { free_2(b->name); if(b->attribs) free_2(b->attribs); free_2(b); } } } else { nptr node = s->n ; t = Node_to_Trptr(node) ; } } } return t ; } /* Return the base prefix for the signal value */ char *signal_value_prefix(int flags) { if(flags & TR_BIN) return "0b" ; if(flags & TR_HEX) return "0x" ; if(flags & TR_OCT) return "0" ; return "" ; } /* ===================================================== */ llist_p *signal_change_list(char *sig_name, int dir, TimeType start_time, TimeType end_time, int max_elements) { llist_p *l0_head = NULL, *l0_tail = NULL, *l1_head = NULL,*l_elem, *lp ; llist_p *l1_tail = NULL ; char *s, s1[1024] ; hptr h_ptr ; Trptr t = NULL ; Trptr t_created = NULL; if(!sig_name) { t = (Trptr)find_first_highlighted_trace(); } else { /* case of sig name, find the representing Trptr structure */ if (!(t = is_signal_displayed(sig_name))) t = t_created = sig_name_to_Trptr(sig_name) ; } if (t) { /* we have a signal */ /* create a list of value change structs (hptrs or vptrs */ int nelem = 0 /* , bw = -1 */ ; /* scan-build */ TimeType tstart = (dir == STRACE_FORWARD) ? start_time : end_time ; TimeType tend = (dir == STRACE_FORWARD) ? end_time : start_time ; if ((dir == STRACE_BACKWARD) && (max_elements == 1)) { max_elements++; } if (!t->vector) { hptr h, h1; int len = 0 ; /* scan-build : if(t->n.nd->extvals) { bw = abs(t->n.nd->msi - t->n.nd->lsi) + 1 ; } */ h = bsearch_node(t->n.nd, tstart - t->shift) ; for(h1 = h; h1; h1 = h1->next) { if (h1->time <= tend) { if (len++ < max_elements) { llist_u llp; llp.p = h1; l_elem = llist_new(llp, LL_VOID_P, -1) ; l0_head = llist_append(l0_head, l_elem, &l0_tail) ; if(!l0_tail) l0_tail = l0_head ; } else { if(dir == STRACE_FORWARD) break ; else { if(!l0_head) /* null pointer deref found by scan-build */ { llist_u llp; llp.p = h1; l_elem = llist_new(llp, LL_VOID_P, -1) ; l0_head = llist_append(l0_head, l_elem, &l0_tail) ; if(!l0_tail) l0_tail = l0_head ; } l_elem = l0_head ; l0_head = l0_head->next ; /* what scan-build flagged as null */ l0_head->prev = NULL ; l_elem->u.p = (void *)h1 ; l_elem->next = NULL ; l_elem->prev = l0_tail ; l0_tail->next = l_elem ; l0_tail = l_elem ; } } } } } else { vptr v, v1; v = bsearch_vector(t->n.vec, tstart - t->shift) ; for(v1 = v; v1; v1 = v1->next) { if (v1->time <= tend) { llist_u llp; llp.p = v1; l_elem = llist_new(llp, LL_VOID_P, -1) ; l0_head = llist_append(l0_head, l_elem, &l0_tail) ; if(!l0_tail) l0_tail = l0_head ; } } } lp = (start_time < end_time) ? l0_head : l0_tail ; /* now create a linked list of time,value.. */ while (lp && (nelem++ < max_elements)) { llist_u llp; llp.tt = ((t->vector) ? ((vptr)lp->u.p)->time: ((hptr)lp->u.p)->time); l_elem = llist_new(llp, LL_TIMETYPE, -1) ; l1_head = llist_append(l1_head, l_elem, &l1_tail) ; if(!l1_tail) l1_tail = l1_head ; if(t->vector == 0) { if(!t->n.nd->extvals) { /* really single bit */ switch(((hptr)lp->u.p)->v.h_val) { case AN_0: llp.str = "0"; l_elem = llist_new(llp, LL_STR, -1) ; break ; case AN_1: llp.str = "1"; l_elem = llist_new(llp, LL_STR, -1) ; break ; case AN_X: llp.str = "x"; l_elem = llist_new(llp, LL_STR, -1) ; break ; case AN_Z: llp.str = "z"; l_elem = llist_new(llp, LL_STR, -1) ; break ; } } else { /* this is still an array */ h_ptr = (hptr)lp->u.p ; if(h_ptr->flags&HIST_REAL) { if(!(h_ptr->flags&HIST_STRING)) { #ifdef WAVE_HAS_H_DOUBLE s=convert_ascii_real(t, &h_ptr->v.h_double); #else s=convert_ascii_real(t, (double *)h_ptr->v.h_vector); #endif } else { s=convert_ascii_string((char *)h_ptr->v.h_vector); } } else { s=convert_ascii_vec(t,h_ptr->v.h_vector); } if(s) { sprintf(s1,"%s%s", signal_value_prefix(t->flags), s) ; llp.str = s1; l_elem = llist_new(llp, LL_STR, -1) ; } else { l1_head = llist_remove_last(l1_head, &l1_tail, LL_INT, NULL) ; } } } else { sprintf(s1, "%s%s", signal_value_prefix(t->flags), convert_ascii(t, (vptr)lp->u.p)) ; llp.str = s1 ; l_elem = llist_new(llp, LL_STR, -1) ; } l1_head = llist_append(l1_head, l_elem, &l1_tail) ; lp = (start_time < end_time) ? lp->next : lp->prev ; } llist_free(l0_head, LL_VOID_P, NULL) ; } if(t_created) { FreeTrace(t_created); } return l1_head ; } gtkwave-3.3.66/src/simplereq.c0000664000076400007640000001134112362030630015526 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2012. * * 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. */ #include "globals.h" #include #include "gtk12compat.h" #include #include "menu.h" #include "debug.h" #include "pixmaps.h" #ifdef MAC_INTEGRATION #include #else static void ok_callback(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; DEBUG(printf("OK\n")); wave_gtk_grab_remove(GLOBALS->window_simplereq_c_9); gtk_widget_destroy(GLOBALS->window_simplereq_c_9); GLOBALS->window_simplereq_c_9 = NULL; if(GLOBALS->cleanup)GLOBALS->cleanup(NULL,(gpointer)1); } static void destroy_callback(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; DEBUG(printf("Cancel\n")); wave_gtk_grab_remove(GLOBALS->window_simplereq_c_9); gtk_widget_destroy(GLOBALS->window_simplereq_c_9); GLOBALS->window_simplereq_c_9 = NULL; if(GLOBALS->cleanup)GLOBALS->cleanup(NULL,NULL); } #endif void simplereqbox(char *title, int width, char *default_text, char *oktext, char *canceltext, GtkSignalFunc func, int is_alert) { #ifndef MAC_INTEGRATION GtkWidget *vbox, *hbox; GtkWidget *button1, *button2; GtkWidget *label, *separator; GtkWidget *pixmapwid1; #else (void)width; #endif if(GLOBALS->window_simplereq_c_9) return; /* only should happen with GtkPlug */ GLOBALS->cleanup=WAVE_GTK_SFUNCAST(func); /* fix problem where ungrab doesn't occur if button pressed + simultaneous accelerator key occurs */ if(GLOBALS->in_button_press_wavewindow_c_1) { gdk_pointer_ungrab(GDK_CURRENT_TIME); } if(GLOBALS->wave_script_args) { if(GLOBALS->cleanup)GLOBALS->cleanup(NULL,(gpointer)1); return; } #ifdef MAC_INTEGRATION /* requester is modal so it will block */ switch(gtk_simplereqbox_req_bridge(title, default_text, oktext, canceltext, is_alert)) { case 1: if(GLOBALS->cleanup)GLOBALS->cleanup(NULL,(gpointer)1); break; case 2: if(GLOBALS->cleanup)GLOBALS->cleanup(NULL,NULL); break; default: break; } #else /* create a new modal window */ GLOBALS->window_simplereq_c_9 = gtk_window_new(GLOBALS->disable_window_manager ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL); install_focus_cb(GLOBALS->window_simplereq_c_9, ((char *)&GLOBALS->window_simplereq_c_9) - ((char *)GLOBALS)); gtk_window_set_transient_for(GTK_WINDOW(GLOBALS->window_simplereq_c_9), GTK_WINDOW(GLOBALS->mainwindow)); gtk_widget_set_usize( GTK_WIDGET (GLOBALS->window_simplereq_c_9), width, 200 - 64); /* 200 is for 128 px icon */ gtk_window_set_title(GTK_WINDOW (GLOBALS->window_simplereq_c_9), title); gtkwave_signal_connect(GTK_OBJECT (GLOBALS->window_simplereq_c_9), "delete_event",(GtkSignalFunc) destroy_callback, NULL); gtk_window_set_policy(GTK_WINDOW(GLOBALS->window_simplereq_c_9), FALSE, FALSE, FALSE); vbox = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (GLOBALS->window_simplereq_c_9), vbox); gtk_widget_show (vbox); label=gtk_label_new(default_text); gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); gtk_widget_show (label); if(is_alert) { pixmapwid1=gtk_pixmap_new(GLOBALS->wave_alert_pixmap, GLOBALS->wave_alert_mask); } else { pixmapwid1=gtk_pixmap_new(GLOBALS->wave_info_pixmap, GLOBALS->wave_info_mask); } gtk_widget_show(pixmapwid1); gtk_container_add (GTK_CONTAINER (vbox), pixmapwid1); separator = gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, TRUE, 0); gtk_widget_show (separator); hbox = gtk_hbox_new (FALSE, 1); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_widget_show (hbox); button1 = gtk_button_new_with_label (oktext); gtk_widget_set_usize(button1, 100, -1); gtkwave_signal_connect(GTK_OBJECT (button1), "clicked", GTK_SIGNAL_FUNC(ok_callback), NULL); gtk_widget_show (button1); gtk_container_add (GTK_CONTAINER (hbox), button1); GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT); gtkwave_signal_connect_object (GTK_OBJECT (button1), "realize", (GtkSignalFunc) gtk_widget_grab_default, GTK_OBJECT (button1)); if(canceltext) { button2 = gtk_button_new_with_label (canceltext); gtk_widget_set_usize(button2, 100, -1); gtkwave_signal_connect(GTK_OBJECT (button2), "clicked", GTK_SIGNAL_FUNC(destroy_callback), NULL); GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT); gtk_widget_show (button2); gtk_container_add (GTK_CONTAINER (hbox), button2); } gtk_widget_show(GLOBALS->window_simplereq_c_9); wave_gtk_grab_add(GLOBALS->window_simplereq_c_9); #endif } gtkwave-3.3.66/src/treesearch.c0000664000076400007640000000121212360623564015662 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2006. * * 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. */ #include #include "globals.h" #include "gtk12compat.h" /* * gtk1 users are forced to use the old treesearch widget * for now, sorry. */ #if WAVE_USE_GTK2 #include "treesearch_gtk2.c" #else #include "treesearch_gtk1.c" #endif void mkmenu_treesearch_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; /* nothing */ } gtkwave-3.3.66/src/bsearch.h0000664000076400007640000000124412341266475015161 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999. * * 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. */ #include "globals.h" #ifndef BSEARCH_NODES_VECTORS_H #define BSEARCH_NODES_VECTORS_H int bsearch_timechain(TimeType key); int bsearch_aetinfo_timechain(TimeType key); hptr bsearch_node(nptr n, TimeType key); vptr bsearch_vector(bvptr b, TimeType key); char *bsearch_trunc(char *ascii, int maxlen); struct symbol *bsearch_facs(char *ascii, unsigned int *rows_return); #endif gtkwave-3.3.66/src/ptranslate.h0000664000076400007640000000127612341266475015734 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2005. * * 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. */ #include "globals.h" #ifndef WAVE_PTRANSLATE_H #define WAVE_PTRANSLATE_H #include #include #include #include "fgetdynamic.h" #include "debug.h" #define PROC_FILTER_MAX (128) void ptrans_searchbox(char *title); void init_proctrans_data(void); int install_proc_filter(int which); void set_current_translate_proc(char *name); void remove_all_proc_filters(void); #endif gtkwave-3.3.66/src/pagebuttons.c0000664000076400007640000001046112360623564016076 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2005. * * 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. */ #include "globals.h" #include #include "currenttime.h" #include "pixmaps.h" #include "debug.h" void service_left_page(GtkWidget *text, gpointer data) { (void)text; (void)data; TimeType ntinc, ntfrac; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nPage Left"); help_text( " scrolls the display window left one page worth of data." " The net action is that the data scrolls right a page." #ifdef WAVE_USE_GTK2 " Scrollwheel Up also hits this button in non-alternative wheel mode." #endif ); return; } ntinc=(TimeType)(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx); /* really don't need this var but the speed of ui code is human dependent.. */ ntfrac=ntinc*GLOBALS->page_divisor; if((ntfrac<1)||(ntinc<1)) ntfrac= /*ntinc=*/ 1; /* scan-build */ if((GLOBALS->tims.start-ntfrac)>GLOBALS->tims.first) GLOBALS->tims.timecache=GLOBALS->tims.start-ntfrac; else GLOBALS->tims.timecache=GLOBALS->tims.first; GTK_ADJUSTMENT(GLOBALS->wave_hslider)->value=GLOBALS->tims.timecache; time_update(); DEBUG(printf("Left Page\n")); } void service_right_page(GtkWidget *text, gpointer data) { (void)text; (void)data; TimeType ntinc, ntfrac; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nPage Right"); help_text( " scrolls the display window right one page worth of data." " The net action is that the data scrolls left a page." #ifdef WAVE_USE_GTK2 " Scrollwheel Down also hits this button in non-alternative wheel mode." #endif ); return; } ntinc=(TimeType)(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx); ntfrac=ntinc*GLOBALS->page_divisor; if((ntfrac<1)||(ntinc<1)) ntfrac=ntinc=1; if((GLOBALS->tims.start+ntfrac)<(GLOBALS->tims.last-ntinc+1)) { GLOBALS->tims.timecache=GLOBALS->tims.start+ntfrac; } else { GLOBALS->tims.timecache=GLOBALS->tims.last-ntinc+1; if(GLOBALS->tims.timecachetims.first) GLOBALS->tims.timecache=GLOBALS->tims.first; } GTK_ADJUSTMENT(GLOBALS->wave_hslider)->value=GLOBALS->tims.timecache; time_update(); DEBUG(printf("Right Page\n")); } /* Create page buttons */ GtkWidget * create_page_buttons (void) { GtkWidget *table; GtkWidget *table2; GtkWidget *frame; GtkWidget *main_vbox; GtkWidget *b1; GtkWidget *b2; GtkWidget *pixmapwid1, *pixmapwid2; GtkTooltips *tooltips; tooltips=gtk_tooltips_new_2(); gtk_tooltips_set_delay_2(tooltips,1500); pixmapwid1=gtk_pixmap_new(GLOBALS->prev_page_pixmap, GLOBALS->prev_page_mask); gtk_widget_show(pixmapwid1); pixmapwid2=gtk_pixmap_new(GLOBALS->next_page_pixmap, GLOBALS->next_page_mask); gtk_widget_show(pixmapwid2); /* Create a table to hold the text widget and scrollbars */ table = gtk_table_new (1, 1, FALSE); main_vbox = gtk_vbox_new (FALSE, 1); gtk_container_border_width (GTK_CONTAINER (main_vbox), 1); gtk_container_add (GTK_CONTAINER (table), main_vbox); frame = gtk_frame_new ("Page "); gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0); gtk_widget_show (frame); gtk_widget_show (main_vbox); table2 = gtk_table_new (2, 1, FALSE); b1 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b1), pixmapwid1); gtk_table_attach (GTK_TABLE (table2), b1, 0, 1, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); gtk_signal_connect_object (GTK_OBJECT (b1), "clicked", GTK_SIGNAL_FUNC(service_left_page), GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(tooltips, b1, "Scroll Window Left One Page", NULL); gtk_widget_show(b1); b2 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b2), pixmapwid2); gtk_table_attach (GTK_TABLE (table2), b2, 0, 1, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); gtk_signal_connect_object (GTK_OBJECT (b2), "clicked", GTK_SIGNAL_FUNC(service_right_page), GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(tooltips, b2, "Scroll Window Right One Page", NULL); gtk_widget_show(b2); gtk_container_add (GTK_CONTAINER (frame), table2); gtk_widget_show(table2); return(table); } gtkwave-3.3.66/src/fonts.c0000664000076400007640000002556112341266475014706 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2008 * * 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. */ #include "globals.h" #include #include "gtk12compat.h" #include "currenttime.h" #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) && GTK_CHECK_VERSION(2,8,0) #ifdef MAC_INTEGRATION #define WAVE_MONOSPACE_12 "Monaco 16" #define WAVE_MONOSPACE_10 "Monaco 14" #define WAVE_MONOSPACE_8 "Monaco 12" #define WAVE_MONOSPACE_6 "Monaco 10" #define WAVE_SANS_12 "Sans 22" #define WAVE_SANS_10 "Sans 16" #else #define WAVE_MONOSPACE_12 "Monospace 12" #define WAVE_MONOSPACE_10 "Monospace 10" #define WAVE_MONOSPACE_8 "Monospace 8" #define WAVE_MONOSPACE_6 "Monospace 6" #define WAVE_SANS_12 "Sans 12" #define WAVE_SANS_10 "Sans 10" #endif static struct font_engine_font_t *do_font_load(const char *name) { struct font_engine_font_t *fef = NULL; PangoFontDescription *desc; if( (name) && (desc = pango_font_description_from_string(name)) ) { fef = calloc_2(1, sizeof(struct font_engine_font_t)); fef->desc = desc; fef->font = pango_font_map_load_font( pango_cairo_font_map_get_default(), GLOBALS->fonts_context, fef->desc); fef->metrics=pango_font_get_metrics(fef->font, NULL /*pango_language_get_default()*/ ); fef->ascent = pango_font_metrics_get_ascent(fef->metrics) / 1000; fef->descent = pango_font_metrics_get_descent(fef->metrics) / 1000; fef->is_pango = 1; if(!strncmp(name, "Monospace", 9)) { int i_width = font_engine_string_measure(fef, "i"); fef->mono_width = font_engine_string_measure(fef, "O"); fef->is_mono = (i_width == fef->mono_width); } } return(fef); } static int setup_fonts(void) { int width, height; GdkDrawable *drawable=GDK_DRAWABLE(gtk_widget_get_root_window(GTK_WIDGET(GLOBALS->mainwindow))); GdkScreen *fonts_screen = gdk_drawable_get_screen (drawable); GLOBALS->fonts_renderer = gdk_pango_renderer_get_default (fonts_screen); gdk_pango_renderer_set_drawable (GDK_PANGO_RENDERER (GLOBALS->fonts_renderer), drawable); GLOBALS->fonts_gc = gdk_gc_new (drawable); gdk_pango_renderer_set_gc (GDK_PANGO_RENDERER (GLOBALS->fonts_renderer), GLOBALS->fonts_gc); gdk_drawable_get_size (drawable, &width, &height); GLOBALS->fonts_context = gdk_pango_context_get_for_screen (fonts_screen); GLOBALS->fonts_layout = pango_layout_new (GLOBALS->fonts_context); return 0; } static int my_font_height(struct font_engine_font_t *f) { return(f->ascent + f->descent); } static void pango_load_all_fonts(void) { setup_fonts(); GLOBALS->signalfont=do_font_load(GLOBALS->fontname_signals); if(!GLOBALS->signalfont) { if(GLOBALS->use_big_fonts) { GLOBALS->signalfont=do_font_load(GLOBALS->use_nonprop_fonts ? WAVE_MONOSPACE_12 : WAVE_SANS_12); } else { GLOBALS->signalfont=do_font_load(GLOBALS->use_nonprop_fonts ? WAVE_MONOSPACE_10 : WAVE_SANS_10); } } GLOBALS->fontheight= my_font_height(GLOBALS->signalfont)+4; GLOBALS->wavefont=GLOBALS->wavefont_smaller=do_font_load(GLOBALS->fontname_waves); if(!GLOBALS->wavefont) { if(GLOBALS->use_big_fonts) { GLOBALS->wavefont=do_font_load(WAVE_MONOSPACE_12); GLOBALS->wavefont_smaller=do_font_load(WAVE_MONOSPACE_10); } else { GLOBALS->wavefont=do_font_load(WAVE_MONOSPACE_8); GLOBALS->wavefont_smaller=do_font_load(WAVE_MONOSPACE_6); } } if( my_font_height(GLOBALS->signalfont) < my_font_height(GLOBALS->wavefont)) { fprintf(stderr, "Signalfont is smaller than wavefont (%d vs %d). Exiting!\n", my_font_height(GLOBALS->signalfont), my_font_height(GLOBALS->wavefont)); exit(1); } if(my_font_height(GLOBALS->signalfont)>100) { fprintf(stderr, "Fonts are too big! Try fonts with a smaller size. Exiting!\n"); exit(1); } GLOBALS->wavecrosspiece=GLOBALS->wavefont->ascent+1; } #endif /***/ static struct font_engine_font_t *font_engine_gdk_font_load(const char *string) { GdkFont *f = gdk_font_load(string); if(f) { struct font_engine_font_t *fef = calloc_2(1, sizeof(struct font_engine_font_t)); fef->gdkfont = f; fef->ascent = f->ascent; fef->descent = f->descent; return(fef); } else { return(NULL); } } void font_engine_draw_string (GdkDrawable *drawable, struct font_engine_font_t *font, GdkGC *gc, gint x, gint y, const gchar *string) { if(!font->is_pango) { gdk_draw_string(drawable, font->gdkfont, gc, x, y, string); } #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) && GTK_CHECK_VERSION(2,8,0) else { PangoRectangle ink,logical; pango_layout_set_text(GLOBALS->fonts_layout, string, -1); pango_layout_set_font_description(GLOBALS->fonts_layout, font->desc); pango_layout_get_extents(GLOBALS->fonts_layout,&ink,&logical); gdk_draw_layout(drawable, gc, x, y-font->ascent, GLOBALS->fonts_layout); } #endif } gint font_engine_string_measure (struct font_engine_font_t *font, const gchar *string) { gint rc = 1; /* dummy value */ if(!font->is_pango) { rc = gdk_string_measure(font->gdkfont, string); } #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) && GTK_CHECK_VERSION(2,8,0) else { if(font->is_mono) { rc = strlen(string) * font->mono_width; } else { PangoRectangle ink,logical; pango_layout_set_text(GLOBALS->fonts_layout, string, -1); pango_layout_set_font_description(GLOBALS->fonts_layout, font->desc); pango_layout_get_extents(GLOBALS->fonts_layout,&ink,&logical); rc = logical.width/1000; } } #endif return(rc); } void gdk_load_all_fonts(void) { if((GLOBALS->fontname_signals)&&(strlen(GLOBALS->fontname_signals))) { GLOBALS->signalfont=font_engine_gdk_font_load(GLOBALS->fontname_signals); } else { if(GLOBALS->use_big_fonts) { if(!GLOBALS->use_nonprop_fonts) { GLOBALS->signalfont=font_engine_gdk_font_load("-*-times-*-r-*-*-15-*-*-*-*-*-*-*"); } else { #ifdef __CYGWIN__ GLOBALS->signalfont=font_engine_gdk_font_load("-misc-fixed-*-*-*-*-15-*-*-*-*-*-*-*"); #else GLOBALS->signalfont=font_engine_gdk_font_load("-*-courier-*-r-*-*-15-*-*-*-*-*-*-*"); if(!GLOBALS->signalfont) GLOBALS->signalfont=font_engine_gdk_font_load("-misc-fixed-*-*-*-*-15-*-*-*-*-*-*-*"); #endif } } else { if(GLOBALS->use_nonprop_fonts) { #ifdef __CYGWIN__ GLOBALS->signalfont=font_engine_gdk_font_load("-misc-fixed-*-*-*-*-14-*-*-*-*-*-*-*"); #else GLOBALS->signalfont=font_engine_gdk_font_load("-*-courier-*-r-*-*-14-*-*-*-*-*-*-*"); if(!GLOBALS->signalfont) GLOBALS->signalfont=font_engine_gdk_font_load("-misc-fixed-*-*-*-*-14-*-*-*-*-*-*-*"); #endif } } } if(!GLOBALS->signalfont) { #if WAVE_USE_GTK2 GLOBALS->signalfont=font_engine_gdk_font_load("-*-courier-*-r-*-*-14-*-*-*-*-*-*-*"); if(!GLOBALS->signalfont) GLOBALS->signalfont=font_engine_gdk_font_load("-misc-fixed-*-*-*-*-14-*-*-*-*-*-*-*"); if(!GLOBALS->signalfont) { fprintf(stderr, "Could not load signalfont courier 14 or misc-fixed 14, exiting!\n"); exit(255); } #else GLOBALS->signalfont= calloc_2(1, sizeof(struct font_engine_font_t)); GLOBALS->signalfont->gdkfont = GLOBALS->wavearea->style->font; GLOBALS->signalfont->ascent = GLOBALS->wavearea->style->font->ascent; GLOBALS->signalfont->descent = GLOBALS->wavearea->style->font->descent; #endif } GLOBALS->fontheight=(GLOBALS->signalfont->ascent+GLOBALS->signalfont->descent)+4; if((GLOBALS->fontname_waves)&&(strlen(GLOBALS->fontname_waves))) { GLOBALS->wavefont=GLOBALS->wavefont_smaller=font_engine_gdk_font_load(GLOBALS->fontname_waves); } else { #ifndef __CYGWIN__ if(GLOBALS->use_big_fonts) { GLOBALS->wavefont=font_engine_gdk_font_load("-*-courier-*-r-*-*-14-*-*-*-*-*-*-*"); if(!GLOBALS->wavefont) GLOBALS->wavefont=font_engine_gdk_font_load("-misc-fixed-*-*-*-*-14-*-*-*-*-*-*-*"); GLOBALS->wavefont_smaller=font_engine_gdk_font_load("-*-courier-*-r-*-*-10-*-*-*-*-*-*-*"); if(!GLOBALS->wavefont_smaller) GLOBALS->wavefont_smaller=font_engine_gdk_font_load("-misc-fixed-*-*-*-*-10-*-*-*-*-*-*-*"); } else { GLOBALS->wavefont=GLOBALS->wavefont_smaller=font_engine_gdk_font_load("-*-courier-*-r-*-*-10-*-*-*-*-*-*-*"); if(!GLOBALS->wavefont) GLOBALS->wavefont=GLOBALS->wavefont_smaller=font_engine_gdk_font_load("-misc-fixed-*-*-*-*-10-*-*-*-*-*-*-*"); } #else if(GLOBALS->use_big_fonts) { GLOBALS->wavefont=font_engine_gdk_font_load("-misc-fixed-*-*-*-*-14-*-*-*-*-*-*-*"); GLOBALS->wavefont_smaller=font_engine_gdk_font_load("-misc-fixed-*-*-*-*-10-*-*-*-*-*-*-*"); } else { GLOBALS->wavefont=GLOBALS->wavefont_smaller=font_engine_gdk_font_load("-misc-fixed-*-*-*-*-10-*-*-*-*-*-*-*"); } #endif } if(!GLOBALS->wavefont) { #if WAVE_USE_GTK2 GLOBALS->wavefont=GLOBALS->wavefont_smaller=font_engine_gdk_font_load("-*-courier-*-r-*-*-10-*-*-*-*-*-*-*"); if(!GLOBALS->wavefont) GLOBALS->wavefont=GLOBALS->wavefont_smaller=font_engine_gdk_font_load("-misc-fixed-*-*-*-*-10-*-*-*-*-*-*-*"); if(!GLOBALS->wavefont) { fprintf(stderr, "Could not load wavefont courier 10 or misc-fixed 10, exiting!\n"); exit(255); } #else GLOBALS->wavefont = calloc_2(1, sizeof(struct font_engine_font_t)); GLOBALS->wavefont->gdkfont = GLOBALS->wavearea->style->font; GLOBALS->wavefont->ascent = GLOBALS->wavearea->style->font->ascent; GLOBALS->wavefont->descent = GLOBALS->wavearea->style->font->descent; GLOBALS->wavefont_smaller = calloc_2(1, sizeof(struct font_engine_font_t)); GLOBALS->wavefont_smaller->gdkfont = GLOBALS->wavearea->style->font; GLOBALS->wavefont_smaller->ascent = GLOBALS->wavearea->style->font->ascent; GLOBALS->wavefont_smaller->descent = GLOBALS->wavearea->style->font->descent; #endif } if(GLOBALS->signalfont->ascentwavefont->ascent) { fprintf(stderr, "Signalfont is smaller than wavefont. Exiting!\n"); exit(1); } if(GLOBALS->signalfont->ascent>100) { fprintf(stderr, "Fonts are too big! Try fonts with a smaller size. Exiting!\n"); exit(1); } GLOBALS->wavecrosspiece=GLOBALS->wavefont->ascent+1; } void load_all_fonts(void) { #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) && GTK_CHECK_VERSION(2,8,0) if(GLOBALS->use_pango_fonts) { pango_load_all_fonts(); } else #endif { gdk_load_all_fonts(); } } gtkwave-3.3.66/src/ghwlib.h0000664000076400007640000002012112341266475015021 0ustar bybellbybell/* GHDL Wavefile reader library. Copyright (C) 2005-2012 Tristan Gingold GHDL 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. GHDL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING. If not, write to the Free Software Foundation, 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. */ #ifndef _GHWLIB_H_ #define _GHWLIB_H_ #include #include #ifdef HAVE_INTTYPES_H #include #define GHWLLD "%"PRId64 #define GHWLD "%"PRId32 #endif #ifndef GHWLLD #if HAVE_STDINT_H #include #if __WORDSIZE == 64 #define GHWLLD "%ld" #define GHWLD "%d" #else #define GHWLLD "%lld" #define GHWLD "%ld" #endif #endif #endif enum ghdl_rtik { ghdl_rtik_top, /* 0 */ ghdl_rtik_library, ghdl_rtik_package, ghdl_rtik_package_body, ghdl_rtik_entity, ghdl_rtik_architecture, /* 5 */ ghdl_rtik_process, ghdl_rtik_block, ghdl_rtik_if_generate, ghdl_rtik_for_generate, ghdl_rtik_instance, ghdl_rtik_constant, ghdl_rtik_iterator, ghdl_rtik_variable, ghdl_rtik_signal, ghdl_rtik_file, ghdl_rtik_port, ghdl_rtik_generic, ghdl_rtik_alias, ghdl_rtik_guard, ghdl_rtik_component, ghdl_rtik_attribute, ghdl_rtik_type_b2, /* 22 */ ghdl_rtik_type_e8, ghdl_rtik_type_e32, ghdl_rtik_type_i32, /* 25 */ ghdl_rtik_type_i64, ghdl_rtik_type_f64, ghdl_rtik_type_p32, ghdl_rtik_type_p64, ghdl_rtik_type_access, /* 30 */ ghdl_rtik_type_array, ghdl_rtik_type_record, ghdl_rtik_type_file, ghdl_rtik_subtype_scalar, ghdl_rtik_subtype_array, /* 35 */ ghdl_rtik_subtype_array_ptr, ghdl_rtik_subtype_unconstrained_array, ghdl_rtik_subtype_record, ghdl_rtik_subtype_access, ghdl_rtik_type_protected, ghdl_rtik_element, ghdl_rtik_unit, ghdl_rtik_attribute_transaction, ghdl_rtik_attribute_quiet, ghdl_rtik_attribute_stable, ghdl_rtik_error }; /* Well-known types. */ enum ghw_wkt_type { ghw_wkt_unknown, ghw_wkt_boolean, ghw_wkt_bit, ghw_wkt_std_ulogic }; struct ghw_range_b2 { unsigned kind : 8; int dir : 8; /* 0: to, !0: downto. */ unsigned char left; unsigned char right; }; struct ghw_range_e8 { unsigned kind : 8; int dir : 8; /* 0: to, !0: downto. */ unsigned char left; unsigned char right; }; struct ghw_range_i32 { unsigned kind : 8; int dir : 8; /* 0: to, !0: downto. */ int32_t left; int32_t right; }; struct ghw_range_i64 { unsigned kind : 8; int dir : 8; int64_t left; int64_t right; }; struct ghw_range_f64 { unsigned kind : 8; int dir : 8; double left; double right; }; union ghw_range { unsigned kind : 8; struct ghw_range_e8 e8; struct ghw_range_i32 i32; struct ghw_range_i64 i64; struct ghw_range_f64 f64; }; /* Note: the first two fields must be kind and name. */ union ghw_type; struct ghw_type_common { enum ghdl_rtik kind; const char *name; }; struct ghw_type_enum { enum ghdl_rtik kind; const char *name; enum ghw_wkt_type wkt; int nbr; const char **lits; }; struct ghw_type_scalar { enum ghdl_rtik kind; const char *name; }; struct ghw_unit { const char *name; int64_t val; }; struct ghw_type_physical { enum ghdl_rtik kind; const char *name; uint32_t nbr_units; struct ghw_unit *units; }; struct ghw_type_array { enum ghdl_rtik kind; const char *name; int nbr_dim; union ghw_type *el; union ghw_type **dims; }; struct ghw_subtype_array { enum ghdl_rtik kind; const char *name; struct ghw_type_array *base; int nbr_el; union ghw_range **rngs; }; struct ghw_subtype_scalar { enum ghdl_rtik kind; const char *name; union ghw_type *base; union ghw_range *rng; }; struct ghw_record_element { const char *name; union ghw_type *type; }; struct ghw_type_record { enum ghdl_rtik kind; const char *name; int nbr_fields; int nbr_el; /* Number of scalar signals. */ struct ghw_record_element *el; }; union ghw_type { enum ghdl_rtik kind; struct ghw_type_common common; struct ghw_type_enum en; struct ghw_type_scalar sc; struct ghw_type_physical ph; struct ghw_subtype_scalar ss; struct ghw_subtype_array sa; struct ghw_type_array ar; struct ghw_type_record rec; }; union ghw_val { unsigned char b2; unsigned char e8; int32_t i32; int64_t i64; double f64; }; /* A non-composite signal. */ struct ghw_sig { union ghw_type *type; union ghw_val *val; }; enum ghw_hie_kind { ghw_hie_eoh = 0, ghw_hie_design = 1, ghw_hie_block = 3, ghw_hie_generate_if = 4, ghw_hie_generate_for = 5, ghw_hie_instance = 6, ghw_hie_package = 7, ghw_hie_process = 13, ghw_hie_generic = 14, ghw_hie_eos = 15, ghw_hie_signal = 16, ghw_hie_port_in = 17, ghw_hie_port_out = 18, ghw_hie_port_inout = 19, ghw_hie_port_buffer = 20, ghw_hie_port_linkage = 21 }; struct ghw_hie { enum ghw_hie_kind kind; struct ghw_hie *parent; const char *name; struct ghw_hie *brother; union { struct { struct ghw_hie *child; union ghw_type *iter_type; union ghw_val *iter_value; } blk; struct { union ghw_type *type; /* Array of signal elements. Last element is 0. */ unsigned int *sigs; } sig; } u; }; struct ghw_handler { FILE *stream; unsigned stream_ispipe : 1; /* True if words are big-endian. */ int word_be; int word_len; int off_len; /* Minor version. */ int version; /* Set by user. */ int flag_verbose; /* String table. */ /* Number of strings. */ int nbr_str; /* Size of the strings (without nul). */ int str_size; /* String table. */ char **str_table; /* Array containing strings. */ char *str_content; /* Type table. */ int nbr_types; union ghw_type **types; /* Non-composite (or basic) signals. */ int nbr_sigs; struct ghw_sig *sigs; /* Hierarchy. */ struct ghw_hie *hie; /* Time of the next cycle. */ int64_t snap_time; }; /* Open a GHW file with H. Return < 0 in case of error. */ int ghw_open (struct ghw_handler *h, const char *filename); union ghw_type *ghw_get_base_type (union ghw_type *t); /* Put the ASCII representation of VAL into BUF, whose size if LEN. A NUL is always written to BUF. */ void ghw_get_value (char *buf, int len, union ghw_val *val, union ghw_type *type); const char *ghw_get_hie_name (struct ghw_hie *h); void ghw_disp_hie (struct ghw_handler *h, struct ghw_hie *top); int ghw_read_base (struct ghw_handler *h); void ghw_disp_values (struct ghw_handler *h); int ghw_read_cycle_start (struct ghw_handler *h); int ghw_read_cycle_cont (struct ghw_handler *h, int *list); int ghw_read_cycle_next (struct ghw_handler *h); int ghw_read_cycle_end (struct ghw_handler *h); enum ghw_sm_type { /* At init; Read section name. */ ghw_sm_init = 0, ghw_sm_sect = 1, ghw_sm_cycle = 2 }; enum ghw_res { ghw_res_error = -1, ghw_res_eof = -2, ghw_res_ok = 0, ghw_res_snapshot = 1, ghw_res_cycle = 2, ghw_res_other = 3 }; int ghw_read_sm (struct ghw_handler *h, enum ghw_sm_type *sm); enum ghw_res ghw_read_sm_hdr (struct ghw_handler *h, int *list); int ghw_read_dump (struct ghw_handler *h); struct ghw_section { const char name[4]; int (*handler)(struct ghw_handler *h); }; extern struct ghw_section ghw_sections[]; int ghw_read_section (struct ghw_handler *h); void ghw_close (struct ghw_handler *h); const char *ghw_get_dir (int is_downto); int ghw_get_range_length (union ghw_range *rng); /* Note: TYPE must be a base type (used only to display literals). */ void ghw_disp_range (union ghw_type *type, union ghw_range *rng); void ghw_disp_type (struct ghw_handler *h, union ghw_type *t); void ghw_disp_types (struct ghw_handler *h); #endif /* _GHWLIB_H_ */ gtkwave-3.3.66/src/symbol.h0000664000076400007640000000635112341266475015063 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2011. * * 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. */ #include "globals.h" #ifndef WAVE_SYMBOL_H #define WAVE_SYMBOL_H #include #include #include #include #include "wavealloca.h" #include "analyzer.h" #include "currenttime.h" #include "tree.h" #include "debug.h" #define SYMPRIME 500009 #define WAVE_DECOMPRESSOR "gzip -cd " /* zcat alone doesn't cut it for AIX */ #ifndef _MSC_VER #include #ifdef HAVE_INTTYPES_H #include #endif #else typedef long off_t; #include #include #endif #ifdef WAVE_USE_STRUCT_PACKING #pragma pack(push) #pragma pack(1) #endif struct fac { struct Node *working_node; int node_alias; int len; unsigned int flags; }; #ifdef WAVE_USE_STRUCT_PACKING #pragma pack(pop) #endif struct symbol { #ifndef _WAVE_HAVE_JUDY struct symbol *sym_next; /* for hash chain, judy uses sym_judy in globals */ #endif struct symbol *vec_root, *vec_chain; char *name; struct Node *n; #ifndef _WAVE_HAVE_JUDY char s_selected; /* for the clist object */ #endif }; struct symchain /* for restoring state of ->selected in signal regex search */ { struct symchain *next; struct symbol *symbol; }; struct string_chain_t { struct string_chain_t *next; char *str; }; /* hash create/destroy */ void sym_hash_initialize(void *g); void sym_hash_destroy(void *g); struct symbol *symfind(char *, unsigned int *); struct symbol *symadd(char *, int); struct symbol *symadd_name_exists(char *name, int hv); int hash(char *s); /* typically use zero for hashval as it doesn't matter if facs are sorted as symfind will bsearch... */ #define symadd_name_exists_sym_exists(s, nam, hv) \ (s)->name = (nam); /* (s)->sym_next=GLOBALS->sym_hash[(hv)]; GLOBALS->sym_hash[(hv)]=(s); (obsolete) */ void facsplit(char *, int *, int *); int sigcmp(char *, char *); void quicksort(struct symbol **, int, int); void wave_heapsort(struct symbol **a, int num); struct Bits *makevec(char *, char *); struct Bits *makevec_annotated(char *, char *); int maketraces(char *, char *, int); /* additions to bitvec.c because of search.c/menu.c ==> formerly in analyzer.h */ bvptr bits2vector(struct Bits *b); struct Bits *makevec_selected(char *vec, int numrows, char direction); int add_vector_selected(char *alias, int numrows, char direction); struct Bits *makevec_range(char *vec, int lo, int hi, char direction); int add_vector_range(char *alias, int lo, int hi, char direction); struct Bits *makevec_chain(char *vec, struct symbol *sym, int len); int add_vector_chain(struct symbol *s, int len); char *makename_chain(struct symbol *sym); /* splash screen activation (version >= GTK2 only) */ void splash_create(void); void splash_sync(off_t current, off_t total); void splash_finalize(void); gint splash_button_press_event(GtkWidget *widget, GdkEventExpose *event); /* accessor functions for sym->selected moved (potentially) to sparse array */ char get_s_selected(struct symbol *s); char set_s_selected(struct symbol *s, char value); void destroy_s_selected(void); #endif gtkwave-3.3.66/src/tcl_commands.c0000664000076400007640000015072112360623564016212 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2008-2014. * * 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. */ #include #include "globals.h" #include #include #if WAVE_USE_GTK2 #include #endif #include #include #include #include #include #include "gtk12compat.h" #include "analyzer.h" #include "tree.h" #include "symbol.h" #include "vcd.h" #include "lx2.h" #include "busy.h" #include "debug.h" #include "hierpack.h" #include "menu.h" #include "tcl_helper.h" #include "tcl_support_commands.h" #if !defined __MINGW32__ && !defined _MSC_VER #include #include #endif #if defined(HAVE_LIBTCL) #include #endif #ifdef _MSC_VER #define strcasecmp _stricmp #endif /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ /* XXX functions for embedding TCL interpreter XXX */ /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ #if defined(HAVE_LIBTCL) static int gtkwavetcl_badNumArgs(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int expected) { (void)clientData; Tcl_Obj *aobj; char reportString[1024]; sprintf(reportString, "* wrong number of arguments for '%s': %d expected, %d encountered", Tcl_GetString(objv[0]), expected, objc-1); aobj = Tcl_NewStringObj(reportString, -1); Tcl_SetObjResult(interp, aobj); return(TCL_ERROR); } static int gtkwavetcl_nop(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { (void)clientData; (void)interp; (void)objc; (void)objv; /* nothing, this is simply to call gtk's main loop */ gtkwave_main_iteration(); return(TCL_OK); } static int gtkwavetcl_printInteger(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int intVal) { (void)clientData; (void)objc; (void)objv; Tcl_Obj *aobj; char reportString[33]; sprintf(reportString, "%d", intVal); aobj = Tcl_NewStringObj(reportString, -1); Tcl_SetObjResult(interp, aobj); return(TCL_OK); } static int gtkwavetcl_printTimeType(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], TimeType ttVal) { (void)clientData; (void)objc; (void)objv; Tcl_Obj *aobj; char reportString[65]; sprintf(reportString, TTFormat, ttVal); aobj = Tcl_NewStringObj(reportString, -1); Tcl_SetObjResult(interp, aobj); return(TCL_OK); } static int gtkwavetcl_printDouble(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], double dVal) { (void)clientData; (void)objc; (void)objv; Tcl_Obj *aobj; char reportString[65]; sprintf(reportString, "%e", dVal); aobj = Tcl_NewStringObj(reportString, -1); Tcl_SetObjResult(interp, aobj); return(TCL_OK); } static int gtkwavetcl_printString(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], const char *reportString) { (void)clientData; (void)objc; (void)objv; Tcl_Obj *aobj; aobj = Tcl_NewStringObj(reportString, -1); Tcl_SetObjResult(interp, aobj); return(TCL_OK); } static char *extractFullTraceName(Trptr t) { char *name = NULL; if(HasWave(t)) { if (HasAlias(t)) { name = strdup_2(t->name_full); } else if (t->vector) { name = strdup_2(t->n.vec->bvname); } else { int flagged = HIER_DEPACK_ALLOC; name = hier_decompress_flagged(t->n.nd->nname, &flagged); if(!flagged) { name = strdup_2(name); } } } return(name); } /* tcl interface functions */ char *get_Tcl_string(Tcl_Obj *obj) { char *s = Tcl_GetString(obj) ; if (*s == '{') { /* braced string */ char *p = strrchr(s, '}') ; if(p) { if(GLOBALS->previous_braced_tcl_string) { free_2(GLOBALS->previous_braced_tcl_string); } GLOBALS->previous_braced_tcl_string = strdup_2(s); GLOBALS->previous_braced_tcl_string[p-s] = 0; s = GLOBALS->previous_braced_tcl_string + 1; } } return s ; } static int gtkwavetcl_getNumFacs(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { int value = GLOBALS->numfacs; return(gtkwavetcl_printInteger(clientData, interp, objc, objv, value)); } static int gtkwavetcl_getLongestName(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { int value = GLOBALS->longestname; return(gtkwavetcl_printInteger(clientData, interp, objc, objv, value)); } static int gtkwavetcl_getFacName(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { Tcl_Obj *aobj; if(objc == 2) { char *s = get_Tcl_string(objv[1]); int which = atoi(s); if((which >= 0) && (which < GLOBALS->numfacs)) { int was_packed = HIER_DEPACK_ALLOC; char *hfacname = NULL; hfacname = hier_decompress_flagged(GLOBALS->facs[which]->name, &was_packed); aobj = Tcl_NewStringObj(hfacname, -1); Tcl_SetObjResult(interp, aobj); if(was_packed) free_2(hfacname); } } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } return(TCL_OK); } static int gtkwavetcl_getMinTime(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { TimeType value = GLOBALS->min_time; return(gtkwavetcl_printTimeType(clientData, interp, objc, objv, value)); } static int gtkwavetcl_getMaxTime(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { TimeType value = GLOBALS->max_time; return(gtkwavetcl_printTimeType(clientData, interp, objc, objv, value)); } static int gtkwavetcl_getTimeZero(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { TimeType value = GLOBALS->global_time_offset; return(gtkwavetcl_printTimeType(clientData, interp, objc, objv, value)); } static int gtkwavetcl_getTimeDimension(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { (void)clientData; (void)objc; (void)objv; Tcl_Obj *aobj; char reportString[2]; reportString[0] = GLOBALS->time_dimension; reportString[1] = 0; aobj = Tcl_NewStringObj(reportString, -1); Tcl_SetObjResult(interp, aobj); return(TCL_OK); } static int gtkwavetcl_getArgv(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { (void)clientData; (void)objc; (void)objv; if(GLOBALS->argvlist) { Tcl_Obj *aobj = Tcl_NewStringObj(GLOBALS->argvlist, -1); Tcl_SetObjResult(interp, aobj); } return(TCL_OK); } static int gtkwavetcl_getBaselineMarker(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { TimeType value = GLOBALS->tims.baseline; return(gtkwavetcl_printTimeType(clientData, interp, objc, objv, value)); } static int gtkwavetcl_getMarker(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { TimeType value = GLOBALS->tims.marker; return(gtkwavetcl_printTimeType(clientData, interp, objc, objv, value)); } static int gtkwavetcl_getWindowStartTime(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { TimeType value = GLOBALS->tims.start; return(gtkwavetcl_printTimeType(clientData, interp, objc, objv, value)); } static int gtkwavetcl_getWindowEndTime(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { TimeType value = GLOBALS->tims.end; return(gtkwavetcl_printTimeType(clientData, interp, objc, objv, value)); } static int gtkwavetcl_getDumpType(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { (void)clientData; (void)objc; (void)objv; Tcl_Obj *aobj; char *reportString = "UNKNOWN"; if(GLOBALS->is_vcd) { if(GLOBALS->partial_vcd) { reportString = "PVCD"; } else { reportString = "VCD"; } } else if(GLOBALS->is_lxt) { reportString = "LXT"; } else if(GLOBALS->is_ghw) { reportString = "GHW"; } else if(GLOBALS->is_lx2) { switch(GLOBALS->is_lx2) { case LXT2_IS_LXT2: reportString = "LXT2"; break; case LXT2_IS_AET2: reportString = "AET2"; break; case LXT2_IS_VZT: reportString = "VZT"; break; case LXT2_IS_VLIST:reportString = "VCD"; break; case LXT2_IS_FST: reportString = "FST"; break; case LXT2_IS_FSDB: reportString = "FSDB"; break; } } aobj = Tcl_NewStringObj(reportString, -1); Tcl_SetObjResult(interp, aobj); return(TCL_OK); } static int gtkwavetcl_getNamedMarker(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { if(objc == 2) { char *s = get_Tcl_string(objv[1]); int which = -1; if((s[0]>='A')&&(s[0]<='Z')) { which = bijective_marker_id_string_hash(s); } else if((s[0]>='a')&&(s[0]<='z')) { which = bijective_marker_id_string_hash(s); } else { which = atoi(s); } if((which >= 0) && (which < WAVE_NUM_NAMED_MARKERS)) { TimeType value = GLOBALS->named_markers[which]; return(gtkwavetcl_printTimeType(clientData, interp, objc, objv, value)); } } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } return(TCL_OK); } static int gtkwavetcl_getWaveHeight(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { int value = GLOBALS->waveheight; return(gtkwavetcl_printInteger(clientData, interp, objc, objv, value)); } static int gtkwavetcl_getWaveWidth(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { int value = GLOBALS->wavewidth; return(gtkwavetcl_printInteger(clientData, interp, objc, objv, value)); } static int gtkwavetcl_getPixelsUnitTime(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { double value = GLOBALS->pxns; return(gtkwavetcl_printDouble(clientData, interp, objc, objv, value)); } static int gtkwavetcl_getUnitTimePixels(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { double value = GLOBALS->nspx; return(gtkwavetcl_printDouble(clientData, interp, objc, objv, value)); } static int gtkwavetcl_getZoomFactor(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { double value = GLOBALS->tims.zoom; return(gtkwavetcl_printDouble(clientData, interp, objc, objv, value)); } static int gtkwavetcl_getDumpFileName(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { char *value = GLOBALS->loaded_file_name; return(gtkwavetcl_printString(clientData, interp, objc, objv, value)); } static int gtkwavetcl_getVisibleNumTraces(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { int value = GLOBALS->traces.visible; return(gtkwavetcl_printInteger(clientData, interp, objc, objv, value)); } static int gtkwavetcl_getTotalNumTraces(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { int value = GLOBALS->traces.total; return(gtkwavetcl_printInteger(clientData, interp, objc, objv, value)); } static int gtkwavetcl_getTraceNameFromIndex(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { if(objc == 2) { char *s = get_Tcl_string(objv[1]); int which = atoi(s); if((which >= 0) && (which < GLOBALS->traces.total)) { Trptr t = GLOBALS->traces.first; int i = 0; while(t) { if(i == which) { if(t->name) { return(gtkwavetcl_printString(clientData, interp, objc, objv, t->name)); } else { break; } } i++; t = t->t_next; } } } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 2)); } return(TCL_OK); } static int gtkwavetcl_getTraceFlagsFromIndex(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { if(objc == 2) { char *s = get_Tcl_string(objv[1]); int which = atoi(s); if((which >= 0) && (which < GLOBALS->traces.total)) { Trptr t = GLOBALS->traces.first; int i = 0; while(t) { if(i == which) { return(gtkwavetcl_printInteger(clientData, interp, objc, objv, t->flags)); } i++; t = t->t_next; } } } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } return(TCL_OK); } static int gtkwavetcl_getTraceValueAtMarkerFromIndex(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { if(objc == 2) { char *s = get_Tcl_string(objv[1]); int which = atoi(s); if((which >= 0) && (which < GLOBALS->traces.total)) { Trptr t = GLOBALS->traces.first; int i = 0; while(t) { if(i == which) { if(t->asciivalue) { char *pnt = t->asciivalue; if(*pnt == '=') pnt++; return(gtkwavetcl_printString(clientData, interp, objc, objv, pnt)); } else { break; } } i++; t = t->t_next; } } } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } return(TCL_OK); } static int gtkwavetcl_getTraceValueAtMarkerFromName(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { if(objc == 2) { char *s = get_Tcl_string(objv[1]); Trptr t = GLOBALS->traces.first; while(t) { if(!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH))) { char *name = extractFullTraceName(t); if(!strcmp(name, s)) { free_2(name); break; } free_2(name); } t = t-> t_next; } if(t) { if(t->asciivalue) { char *pnt = t->asciivalue; if(*pnt == '=') pnt++; return(gtkwavetcl_printString(clientData, interp, objc, objv, pnt)); } } } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } return(TCL_OK); } static int gtkwavetcl_getTraceValueAtNamedMarkerFromName(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { if(objc == 3) { char *sv = get_Tcl_string(objv[1]); int which = -1; TimeType oldmarker = GLOBALS->tims.marker; TimeType value = LLDescriptor(-1); if((sv[0]>='A')&&(sv[0]<='Z')) { which = bijective_marker_id_string_hash(sv); } else if((sv[0]>='a')&&(sv[0]<='z')) { which = bijective_marker_id_string_hash(sv); } else { which = atoi(sv); } if((which >= 0) && (which < WAVE_NUM_NAMED_MARKERS)) { char *s = get_Tcl_string(objv[2]); Trptr t = GLOBALS->traces.first; value = GLOBALS->named_markers[which]; while(t) { if(!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH))) { char *name = extractFullTraceName(t); if(!strcmp(name, s)) { free_2(name); break; } free_2(name); } t = t-> t_next; } if(t && (value >= LLDescriptor(0))) { GLOBALS->tims.marker = value; GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); gtkwave_main_iteration(); if(t->asciivalue) { Tcl_Obj *aobj; char *pnt = t->asciivalue; if(*pnt == '=') pnt++; aobj = Tcl_NewStringObj(pnt, -1); Tcl_SetObjResult(interp, aobj); GLOBALS->tims.marker = oldmarker; update_markertime(GLOBALS->tims.marker); GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); gtkwave_main_iteration(); return(TCL_OK); } GLOBALS->tims.marker = oldmarker; update_markertime(GLOBALS->tims.marker); GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); gtkwave_main_iteration(); } } } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } return(TCL_OK); } static int gtkwavetcl_getHierMaxLevel(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { int value = GLOBALS->hier_max_level; return(gtkwavetcl_printInteger(clientData, interp, objc, objv, value)); } static int gtkwavetcl_getFontHeight(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { int value = GLOBALS->fontheight; return(gtkwavetcl_printInteger(clientData, interp, objc, objv, value)); } static int gtkwavetcl_getLeftJustifySigs(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { int value = (GLOBALS->left_justify_sigs != 0); return(gtkwavetcl_printInteger(clientData, interp, objc, objv, value)); } static int gtkwavetcl_getSaveFileName(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { char *value = GLOBALS->filesel_writesave; if(value) { return(gtkwavetcl_printString(clientData, interp, objc, objv, value)); } return(TCL_OK); } static int gtkwavetcl_getStemsFileName(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { char *value = GLOBALS->stems_name; if(value) { return(gtkwavetcl_printString(clientData, interp, objc, objv, value)); } return(TCL_OK); } static int gtkwavetcl_getTraceScrollbarRowValue(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { GtkAdjustment *wadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider); int value = (int)wadj->value; return(gtkwavetcl_printInteger(clientData, interp, objc, objv, value)); } static int gtkwavetcl_setMarker(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { if(objc == 2) { char *s = get_Tcl_string(objv[1]); TimeType mrk = unformat_time(s, GLOBALS->time_dimension); if((mrk >= GLOBALS->min_time) && (mrk <= GLOBALS->max_time)) { GLOBALS->tims.marker = mrk; } else { GLOBALS->tims.marker = LLDescriptor(-1); } update_markertime(GLOBALS->tims.marker); GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); gtkwave_main_iteration(); } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } return(TCL_OK); } static int gtkwavetcl_setBaselineMarker(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { if(objc == 2) { char *s = get_Tcl_string(objv[1]); TimeType mrk = unformat_time(s, GLOBALS->time_dimension); if((mrk >= GLOBALS->min_time) && (mrk <= GLOBALS->max_time)) { GLOBALS->tims.baseline = mrk; } else { GLOBALS->tims.baseline = LLDescriptor(-1); } update_markertime(GLOBALS->tims.marker); GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); gtkwave_main_iteration(); } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } return(TCL_OK); } static int gtkwavetcl_setWindowStartTime(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { if(objc == 2) { char *s = get_Tcl_string(objv[1]); if(s) { TimeType gt; char timval[40]; GtkAdjustment *hadj; TimeType pageinc; gt=unformat_time(s, GLOBALS->time_dimension); if(gttims.first) gt=GLOBALS->tims.first; else if(gt>GLOBALS->tims.last) gt=GLOBALS->tims.last; hadj=GTK_ADJUSTMENT(GLOBALS->wave_hslider); hadj->value=gt; pageinc=(TimeType)(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx); if(gt<(GLOBALS->tims.last-pageinc+1)) GLOBALS->tims.timecache=gt; else { GLOBALS->tims.timecache=GLOBALS->tims.last-pageinc+1; if(GLOBALS->tims.timecachetims.first) GLOBALS->tims.timecache=GLOBALS->tims.first; } reformat_time(timval,GLOBALS->tims.timecache,GLOBALS->time_dimension); time_update(); } signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); gtkwave_main_iteration(); } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } return(TCL_OK); } static int gtkwavetcl_setZoomFactor(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { if(objc == 2) { char *s = get_Tcl_string(objv[1]); float f; sscanf(s, "%f", &f); if(f>0.0) { f=0.0; /* in case they try to go out of range */ } else if(f<-62.0) { f=-62.0; /* in case they try to go out of range */ } GLOBALS->tims.prevzoom=GLOBALS->tims.zoom; GLOBALS->tims.zoom=(gdouble)f; calczoom(GLOBALS->tims.zoom); fix_wavehadj(); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed"); gtkwave_main_iteration(); } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } return(TCL_OK); } static int gtkwavetcl_setZoomRangeTimes(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { if(objc == 3) { char *s, *t; TimeType time1, time2; TimeType oldmarker = GLOBALS->tims.marker; s = get_Tcl_string(objv[1]); time1 = unformat_time(s, GLOBALS->time_dimension); t = get_Tcl_string(objv[2]); time2 = unformat_time(t, GLOBALS->time_dimension); if(time1 < GLOBALS->tims.first) { time1 = GLOBALS->tims.first; } if(time1 > GLOBALS->tims.last) { time1 = GLOBALS->tims.last; } if(time2 < GLOBALS->tims.first) { time2 = GLOBALS->tims.first; } if(time2 > GLOBALS->tims.last) { time2 = GLOBALS->tims.last; } service_dragzoom(time1, time2); GLOBALS->tims.marker = oldmarker; GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); gtkwave_main_iteration(); } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } return(TCL_OK); } static int gtkwavetcl_setLeftJustifySigs(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { if(objc == 2) { char *s = get_Tcl_string(objv[1]); TimeType val = atoi_64(s); GLOBALS->left_justify_sigs = (val != LLDescriptor(0)) ? ~0 : 0; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); gtkwave_main_iteration(); } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } return(TCL_OK); } static int gtkwavetcl_setNamedMarker(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { if((objc == 3)||(objc == 4)) { char *s = get_Tcl_string(objv[1]); int which = -1; if((s[0]>='A')&&(s[0]<='Z')) { which = bijective_marker_id_string_hash(s); } else if((s[0]>='a')&&(s[0]<='z')) { which = bijective_marker_id_string_hash(s); } else { which = atoi(s); } if((which >= 0) && (which < WAVE_NUM_NAMED_MARKERS)) { char *t = get_Tcl_string(objv[2]); TimeType gt=unformat_time(t, GLOBALS->time_dimension); GLOBALS->named_markers[which] = gt; if(GLOBALS->marker_names[which]) { free_2(GLOBALS->marker_names[which]); GLOBALS->marker_names[which] = NULL; } if(objc == 4) { char *u = get_Tcl_string(objv[3]); GLOBALS->marker_names[which] = strdup_2(u); } wavearea_configure_event(GLOBALS->wavearea, NULL); gtkwave_main_iteration(); } } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 2)); } return(TCL_OK); } static int gtkwavetcl_setTraceScrollbarRowValue(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { if(objc == 2) { char *s = get_Tcl_string(objv[1]); int target = atoi(s); SetTraceScrollbarRowValue(target, 0); /* GtkAdjustment *wadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider); */ /* int num_traces_displayable=(GLOBALS->signalarea->allocation.height)/(GLOBALS->fontheight); */ /* num_traces_displayable--; /\* for the time trace that is always there *\/ */ /* if(target > GLOBALS->traces.visible - num_traces_displayable) target = GLOBALS->traces.visible - num_traces_displayable; */ /* if(target < 0) target = 0; */ /* wadj->value = target; */ /* gtk_signal_emit_by_name (GTK_OBJECT (wadj), "changed"); /\* force bar update *\/ */ /* gtk_signal_emit_by_name (GTK_OBJECT (wadj), "value_changed"); /\* force text update *\/ */ /* gtkwave_main_iteration(); */ } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } return(TCL_OK); } static int gtkwavetcl_addSignalsFromList(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { int i; char *one_entry = NULL, *mult_entry = NULL; unsigned int mult_len = 0; int num_found = 0; char reportString[33]; Tcl_Obj *aobj; if(objc==2) { char *s = Tcl_GetString(objv[1]); /* do not want to remove braces! */ char** elem = NULL; int l = 0; elem = zSplitTclList(s, &l); if(elem) { for(i=0;isignalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); gtkwave_main_iteration(); } } } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } sprintf(reportString, "%d", num_found); aobj = Tcl_NewStringObj(reportString, -1); Tcl_SetObjResult(interp, aobj); return(TCL_OK); } static int gtkwavetcl_deleteSignalsFromList(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { int i; int num_found = 0; char reportString[33]; Tcl_Obj *aobj; if(objc==2) { char *s = Tcl_GetString(objv[1]); /* do not want to remove braces */ char** elem = NULL; int l = 0; elem = zSplitTclList(s, &l); if(elem) { Trptr t = GLOBALS->traces.first; while(t) { t->cached_flags = t->flags; t->flags &= (~TR_HIGHLIGHT); t = t->t_next; } for(i=0;itraces.first; while(t) { if(!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH|TR_HIGHLIGHT))) { char *name = extractFullTraceName(t); if(name) { int len_name = strlen(name); int len_elem = strlen(elem[i]); int brackmatch = (len_name > len_elem) && (name[len_elem] == '['); if(((len_name == len_elem) && (!strcmp(name, elem[i]))) || (brackmatch && !strncmp(name, elem[i], len_elem))) { t->flags |= TR_HIGHLIGHT; num_found++; break; } free_2(name); } } t = t->t_next; } } free_2(elem); elem = NULL; if(num_found) { CutBuffer(); } t = GLOBALS->traces.first; while(t) { t->flags = t->cached_flags; t->cached_flags = 0; t = t-> t_next; } if(num_found) { MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); gtkwave_main_iteration(); } } } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } sprintf(reportString, "%d", num_found); aobj = Tcl_NewStringObj(reportString, -1); Tcl_SetObjResult(interp, aobj); return(TCL_OK); } static int gtkwavetcl_deleteSignalsFromListIncludingDuplicates(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { int i; int num_found = 0; char reportString[33]; Tcl_Obj *aobj; if(objc==2) { char *s = Tcl_GetString(objv[1]); /* do not want to remove braces */ char** elem = NULL; int l = 0; elem = zSplitTclList(s, &l); if(elem) { Trptr t = GLOBALS->traces.first; while(t) { t->cached_flags = t->flags; t->flags &= (~TR_HIGHLIGHT); if(!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH))) { char *name = extractFullTraceName(t); if(name) { for(i=0;i len_elem) && (name[len_elem] == '['); if(((len_name == len_elem) && (!strcmp(name, elem[i]))) || (brackmatch && !strncmp(name, elem[i], len_elem))) { t->flags |= TR_HIGHLIGHT; num_found++; break; } } free_2(name); } } t = t-> t_next; } free_2(elem); elem = NULL; if(num_found) { CutBuffer(); } t = GLOBALS->traces.first; while(t) { t->flags = t->cached_flags; t->cached_flags = 0; t = t-> t_next; } if(num_found) { MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); gtkwave_main_iteration(); } } } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } sprintf(reportString, "%d", num_found); aobj = Tcl_NewStringObj(reportString, -1); Tcl_SetObjResult(interp, aobj); return(TCL_OK); } static int gtkwavetcl_highlightSignalsFromList(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { int i; int num_found = 0; char reportString[33]; Tcl_Obj *aobj; if(objc==2) { char *s = Tcl_GetString(objv[1]); /* do not want to remove braces */ char** elem = NULL; int l = 0; elem = zSplitTclList(s, &l); if(elem) { Trptr t = GLOBALS->traces.first; while(t) { if(!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH))) { char *name = extractFullTraceName(t); if(name) { for(i=0;iflags |= TR_HIGHLIGHT; num_found++; break; } } free_2(name); } } t = t-> t_next; } free_2(elem); elem = NULL; if(num_found) { MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); gtkwave_main_iteration(); } } } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } sprintf(reportString, "%d", num_found); aobj = Tcl_NewStringObj(reportString, -1); Tcl_SetObjResult(interp, aobj); return(TCL_OK); } static int gtkwavetcl_unhighlightSignalsFromList(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { int i; int num_found = 0; char reportString[33]; Tcl_Obj *aobj; if(objc==2) { char *s = Tcl_GetString(objv[1]); /* do not want to remove braces */ char** elem = NULL; int l = 0; elem = zSplitTclList(s, &l); if(elem) { Trptr t = GLOBALS->traces.first; while(t) { if(!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH))) { char *name = extractFullTraceName(t); if(name) { for(i=0;iflags &= (~TR_HIGHLIGHT); num_found++; break; } } free_2(name); } } t = t-> t_next; } free_2(elem); elem = NULL; if(num_found) { MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); gtkwave_main_iteration(); } } } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } sprintf(reportString, "%d", num_found); aobj = Tcl_NewStringObj(reportString, -1); Tcl_SetObjResult(interp, aobj); return(TCL_OK); } static int gtkwavetcl_setTraceHighlightFromIndex(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { if(objc == 3) { char *s = get_Tcl_string(objv[1]); int which = atoi(s); char *ts = get_Tcl_string(objv[2]); int onoff = atoi_64(ts); if((which >= 0) && (which < GLOBALS->traces.total)) { Trptr t = GLOBALS->traces.first; int i = 0; while(t) { if(i == which) { if(onoff) { t->flags |= TR_HIGHLIGHT; } else { t->flags &= (~TR_HIGHLIGHT); } signalarea_configure_event(GLOBALS->signalarea, NULL); gtkwave_main_iteration(); break; } i++; t = t->t_next; } } } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 2)); } return(TCL_OK); } static int gtkwavetcl_setTraceHighlightFromNameMatch(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { if(objc == 3) { char *s = get_Tcl_string(objv[1]); int which = atoi(s); char *ts = get_Tcl_string(objv[2]); int onoff = atoi_64(ts); int mat = 0; if((which >= 0) && (which < GLOBALS->traces.total)) { Trptr t = GLOBALS->traces.first; int i = 0; while(t) { if(t->name && !strcmp(t->name, s)) { if(onoff) { t->flags |= TR_HIGHLIGHT; } else { t->flags &= (~TR_HIGHLIGHT); } mat++; } i++; t = t->t_next; } if(mat) { signalarea_configure_event(GLOBALS->signalarea, NULL); gtkwave_main_iteration(); } return(gtkwavetcl_printInteger(clientData, interp, objc, objv, mat)); } } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 2)); } return(TCL_OK); } static int gtkwavetcl_signalChangeList(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { (void) clientData; int dir = STRACE_FORWARD ; TimeType start_time = 0 ; TimeType end_time = MAX_HISTENT_TIME ; int max_elements = 0x7fffffff ; char *sig_name = NULL ; int i ; char *str_p, *str1_p ; int error = 0 ; llist_p *l_head ; Tcl_Obj *l_obj ; Tcl_Obj *obj ; llist_p *p, *p1 ; for(i=1; i end_time) ? STRACE_BACKWARD : STRACE_FORWARD ; } break ; case 'e': /* end time */ if(!strstr("-end_time", str_p)) error++ ; else { end_time = atoi_64(str1_p) ; dir = (start_time > end_time) ? STRACE_BACKWARD : STRACE_FORWARD ; } break ; case 'm': /* max */ if(!strstr("-max", str_p)) error++ ; else { max_elements = atoi(str1_p) ; } break ; case 'd': /* dir */ if(!strstr("-dir", str_p)) error++ ; else { if(strstr("forward", str1_p)) dir = STRACE_FORWARD ; else if(strstr("backward", str1_p)) dir = STRACE_BACKWARD ; else error++ ; } break ; default: error++ ; } } } /* consistancy check */ if(dir == STRACE_FORWARD) { if(start_time > end_time) error++ ; } else { if(start_time < end_time) { if(end_time == MAX_HISTENT_TIME) end_time = 0 ; else error ++ ; } } if(error) { Tcl_SetObjResult (interp, Tcl_NewStringObj("Usage: signal_change_list ?name? ?-start time? ?-end time? ?-max size? ?-dir forward|backward?", -1)) ; return TCL_ERROR; } l_head = signal_change_list(sig_name, dir, start_time, end_time, max_elements) ; l_obj = Tcl_NewListObj(0, NULL) ; p = l_head; while(p) { obj = Tcl_NewWideIntObj((Tcl_WideInt )p->u.tt) ; p1= p->next ; free_2(p) ; Tcl_ListObjAppendElement(interp, l_obj, obj) ; obj = Tcl_NewStringObj(p1->u.str,-1) ; Tcl_ListObjAppendElement(interp, l_obj, obj) ; p = p1->next ; free_2(p1->u.str) ; free_2(p1) ; } Tcl_SetObjResult(interp, l_obj) ; return TCL_OK ; } static int gtkwavetcl_findNextEdge(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { edge_search(STRACE_FORWARD); gtkwave_main_iteration(); return(gtkwavetcl_getMarker(clientData, interp, objc, objv)); } static int gtkwavetcl_findPrevEdge(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { edge_search(STRACE_BACKWARD); gtkwave_main_iteration(); return(gtkwavetcl_getMarker(clientData, interp, objc, objv)); } int SST_open_node(char *name) ; static int gtkwavetcl_forceOpenTreeNode(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { int rv = -100; /* Tree does not exist */ char *s = NULL ; if(objc == 2) s = get_Tcl_string(objv[1]); if(s && (strlen(s) > 1)) { /* exclude empty strings */ int len = strlen(s); if(s[len-1]!=GLOBALS->hier_delimeter) { #ifdef WAVE_USE_GTK2 rv = SST_open_node(s); #endif } else { #ifdef WAVE_USE_GTK2 rv = SST_open_node(s); #endif } } else { if (GLOBALS->selected_hierarchy_name) { rv = SST_NODE_CURRENT ; } gtkwave_main_iteration(); /* check if this is needed */ } if (rv == -100) { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } Tcl_SetObjResult(GLOBALS->interp, (rv == SST_NODE_CURRENT) ? Tcl_NewStringObj(GLOBALS->selected_hierarchy_name, strlen(GLOBALS->selected_hierarchy_name)) : Tcl_NewIntObj(rv)) ; return(TCL_OK); } static int gtkwavetcl_setFromEntry(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { if(objc == 2) { char *s = get_Tcl_string(objv[1]); if(s) { gtk_entry_set_text(GTK_ENTRY(GLOBALS->from_entry),s); from_entry_callback(NULL, GLOBALS->from_entry); } gtkwave_main_iteration(); } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } return(TCL_OK); } static int gtkwavetcl_setToEntry(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { if(objc == 2) { char *s = get_Tcl_string(objv[1]); if(s) { gtk_entry_set_text(GTK_ENTRY(GLOBALS->to_entry),s); to_entry_callback(NULL, GLOBALS->to_entry); } gtkwave_main_iteration(); } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } return(TCL_OK); } static int gtkwavetcl_getFromEntry(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { const char *value = gtk_entry_get_text(GTK_ENTRY(GLOBALS->from_entry)); if(value) { return(gtkwavetcl_printString(clientData, interp, objc, objv, value)); } return(TCL_OK); } static int gtkwavetcl_getToEntry(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { const char *value = gtk_entry_get_text(GTK_ENTRY(GLOBALS->to_entry)); if(value) { return(gtkwavetcl_printString(clientData, interp, objc, objv, value)); } return(TCL_OK); } static int gtkwavetcl_getDisplayedSignals(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { if(objc == 1) { char *rv = add_traces_from_signal_window(TRUE); int rc = gtkwavetcl_printString(clientData, interp, objc, objv, rv); free_2(rv); return(rc); } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } } static int gtkwavetcl_getTraceFlagsFromName(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { if(objc == 2) { char *s = get_Tcl_string(objv[1]); Trptr t = GLOBALS->traces.first; while(t) { if(!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH))) { char *name = extractFullTraceName(t); if(!strcmp(name, s)) { free_2(name); break; } free_2(name); } t = t-> t_next; } if(t) { return(gtkwavetcl_printInteger(clientData, interp, objc, objv, t->flags)); } } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } return(TCL_OK); } static int gtkwavetcl_loadFile(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { if(objc == 2) { char *s = get_Tcl_string(objv[1]); if(!GLOBALS->in_tcl_callback) { /* wave_gconf_client_set_string("/current/savefile", s); */ /* read_save_helper(s, NULL, NULL, NULL, NULL); */ process_url_file(s); /* process_url_list(s); */ /* gtkwave_main_iteration(); */ } else { gtkwavetcl_setvar_nonblocking(WAVE_TCLCB_ERROR,"gtkwave::loadFile prohibited in callback",WAVE_TCLCB_ERROR_FLAGS); } } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } return(TCL_OK); } static int gtkwavetcl_reLoadFile(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { if(objc == 1) { if(!GLOBALS->in_tcl_callback) { reload_into_new_context(); } else { gtkwavetcl_setvar_nonblocking(WAVE_TCLCB_ERROR,"gtkwave::reLoadFile prohibited in callback",WAVE_TCLCB_ERROR_FLAGS); } } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 0)); } return(TCL_OK); } static int gtkwavetcl_presentWindow(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { if(objc == 1) { #ifdef WAVE_USE_GTK2 gtk_window_present(GTK_WINDOW(GLOBALS->mainwindow)); #else gdk_window_raise(GTK_WIDGET(GLOBALS->mainwindow)->window); #endif } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 0)); } return(TCL_OK); } static int gtkwavetcl_showSignal(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { if(objc == 3) { char *s0 = get_Tcl_string(objv[1]); char *s1; int row; unsigned location; sscanf(s0, "%d", &row); if (row < 0) { row = 0; }; s1 = get_Tcl_string(objv[2]); sscanf(s1, "%u", &location); SetTraceScrollbarRowValue(row, location); } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 2)); } return(TCL_OK); } /* * swap to a given context based on tab number (from Tcl) */ static gint switch_to_tab_number(unsigned int i) { if(i < GLOBALS->num_notebook_pages) { struct Global *g_old = GLOBALS; /* printf("Switching to: %d\n", i); */ set_GLOBALS((*GLOBALS->contexts)[i]); GLOBALS->lxt_clock_compress_to_z = g_old->lxt_clock_compress_to_z; GLOBALS->autoname_bundles = g_old->autoname_bundles; GLOBALS->autocoalesce_reversal = g_old->autocoalesce_reversal; GLOBALS->autocoalesce = g_old->autocoalesce; GLOBALS->hier_grouping = g_old->hier_grouping; GLOBALS->wave_scrolling = g_old->wave_scrolling; GLOBALS->constant_marker_update = g_old->constant_marker_update; GLOBALS->do_zoom_center = g_old->do_zoom_center; GLOBALS->use_roundcaps = g_old->use_roundcaps; GLOBALS->do_resize_signals = g_old->do_resize_signals; GLOBALS->alt_wheel_mode = g_old->alt_wheel_mode; GLOBALS->initial_signal_window_width = g_old->initial_signal_window_width; GLOBALS->use_full_precision = g_old->use_full_precision; GLOBALS->show_base = g_old->show_base; GLOBALS->display_grid = g_old->display_grid; GLOBALS->highlight_wavewindow = g_old->highlight_wavewindow; GLOBALS->disable_mouseover = g_old->disable_mouseover; GLOBALS->zoom_pow10_snap = g_old->zoom_pow10_snap; GLOBALS->scale_to_time_dimension = g_old->scale_to_time_dimension; GLOBALS->zoom_dyn = g_old->zoom_dyn; GLOBALS->zoom_dyne = g_old->zoom_dyne; gtk_notebook_set_current_page(GTK_NOTEBOOK(GLOBALS->notebook), GLOBALS->this_context_page); return(TRUE); } return(FALSE); } static int gtkwavetcl_setTabActive(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { if(objc == 2) { gint rc; if(!GLOBALS->in_tcl_callback) { char *s = get_Tcl_string(objv[1]); unsigned int tabnum = atoi(s); rc = switch_to_tab_number(tabnum); MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); gtkwave_main_iteration(); } else { gtkwavetcl_setvar_nonblocking(WAVE_TCLCB_ERROR,"gtkwave::setTabActive prohibited in callback",WAVE_TCLCB_ERROR_FLAGS); rc = -1; } return(gtkwavetcl_printInteger(clientData, interp, objc, objv, rc)); } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } } static int gtkwavetcl_getNumTabs(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { int value = GLOBALS->num_notebook_pages; return(gtkwavetcl_printInteger(clientData, interp, objc, objv, value)); } static int gtkwavetcl_installFileFilter(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { if(objc == 2) { char *s = get_Tcl_string(objv[1]); unsigned int which = atoi(s); gint rc = install_file_filter(which); gtkwave_main_iteration(); return(gtkwavetcl_printInteger(clientData, interp, objc, objv, rc)); } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } } static int gtkwavetcl_setCurrentTranslateFile(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { if(objc == 2) { char *s = get_Tcl_string(objv[1]); set_current_translate_file(s); return(gtkwavetcl_printInteger(clientData, interp, objc, objv, GLOBALS->current_translate_file)); } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } } static int gtkwavetcl_setCurrentTranslateEnums(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { if(objc == 2) { char *s = get_Tcl_string(objv[1]); set_current_translate_enums(s); return(gtkwavetcl_printInteger(clientData, interp, objc, objv, GLOBALS->current_translate_file)); } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } } static int gtkwavetcl_installProcFilter(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { if(objc == 2) { char *s = get_Tcl_string(objv[1]); unsigned int which = atoi(s); gint rc = install_file_filter(which); gtkwave_main_iteration(); return(gtkwavetcl_printInteger(clientData, interp, objc, objv, rc)); } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } } static int gtkwavetcl_setCurrentTranslateProc(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { if(objc == 2) { char *s = get_Tcl_string(objv[1]); set_current_translate_proc(s); return(gtkwavetcl_printInteger(clientData, interp, objc, objv, GLOBALS->current_translate_proc)); } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } } static int gtkwavetcl_installTransFilter(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { if(objc == 2) { char *s = get_Tcl_string(objv[1]); unsigned int which = atoi(s); gint rc = install_ttrans_filter(which); gtkwave_main_iteration(); return(gtkwavetcl_printInteger(clientData, interp, objc, objv, rc)); } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } } static int gtkwavetcl_setCurrentTranslateTransProc(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { if(objc == 2) { char *s = get_Tcl_string(objv[1]); set_current_translate_ttrans(s); return(gtkwavetcl_printInteger(clientData, interp, objc, objv, GLOBALS->current_translate_ttrans)); } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } } tcl_cmdstruct gtkwave_commands[] = { {"addSignalsFromList", gtkwavetcl_addSignalsFromList}, {"deleteSignalsFromList", gtkwavetcl_deleteSignalsFromList}, {"deleteSignalsFromListIncludingDuplicates", gtkwavetcl_deleteSignalsFromListIncludingDuplicates}, {"findNextEdge", gtkwavetcl_findNextEdge}, {"findPrevEdge", gtkwavetcl_findPrevEdge}, {"forceOpenTreeNode", gtkwavetcl_forceOpenTreeNode}, {"getArgv", gtkwavetcl_getArgv}, {"getBaselineMarker", gtkwavetcl_getBaselineMarker}, {"getDisplayedSignals", gtkwavetcl_getDisplayedSignals}, {"getDumpFileName", gtkwavetcl_getDumpFileName}, {"getDumpType", gtkwavetcl_getDumpType}, {"getFacName", gtkwavetcl_getFacName}, {"getFontHeight", gtkwavetcl_getFontHeight}, {"getFromEntry", gtkwavetcl_getFromEntry}, {"getHierMaxLevel", gtkwavetcl_getHierMaxLevel}, {"getLeftJustifySigs", gtkwavetcl_getLeftJustifySigs}, {"getLongestName", gtkwavetcl_getLongestName}, {"getMarker", gtkwavetcl_getMarker}, {"getMaxTime", gtkwavetcl_getMaxTime}, {"getMinTime", gtkwavetcl_getMinTime}, {"getNamedMarker", gtkwavetcl_getNamedMarker}, {"getNumFacs", gtkwavetcl_getNumFacs}, {"getNumTabs", gtkwavetcl_getNumTabs}, {"getPixelsUnitTime", gtkwavetcl_getPixelsUnitTime}, {"getSaveFileName", gtkwavetcl_getSaveFileName}, {"getStemsFileName", gtkwavetcl_getStemsFileName}, {"getTimeDimension", gtkwavetcl_getTimeDimension}, {"getTimeZero", gtkwavetcl_getTimeZero}, {"getToEntry", gtkwavetcl_getToEntry}, {"getTotalNumTraces", gtkwavetcl_getTotalNumTraces}, {"getTraceFlagsFromIndex", gtkwavetcl_getTraceFlagsFromIndex}, {"getTraceFlagsFromName", gtkwavetcl_getTraceFlagsFromName}, {"getTraceNameFromIndex", gtkwavetcl_getTraceNameFromIndex}, {"getTraceScrollbarRowValue", gtkwavetcl_getTraceScrollbarRowValue}, {"getTraceValueAtMarkerFromIndex", gtkwavetcl_getTraceValueAtMarkerFromIndex}, {"getTraceValueAtMarkerFromName", gtkwavetcl_getTraceValueAtMarkerFromName}, {"getTraceValueAtNamedMarkerFromName", gtkwavetcl_getTraceValueAtNamedMarkerFromName}, {"getUnitTimePixels", gtkwavetcl_getUnitTimePixels}, {"getVisibleNumTraces", gtkwavetcl_getVisibleNumTraces}, {"getWaveHeight", gtkwavetcl_getWaveHeight}, {"getWaveWidth", gtkwavetcl_getWaveWidth}, {"getWindowEndTime", gtkwavetcl_getWindowEndTime}, {"getWindowStartTime", gtkwavetcl_getWindowStartTime}, {"getZoomFactor", gtkwavetcl_getZoomFactor}, {"highlightSignalsFromList", gtkwavetcl_highlightSignalsFromList}, {"installFileFilter", gtkwavetcl_installFileFilter}, {"installProcFilter", gtkwavetcl_installProcFilter}, {"installTransFilter", gtkwavetcl_installTransFilter}, {"nop", gtkwavetcl_nop}, {"setBaselineMarker", gtkwavetcl_setBaselineMarker}, {"setCurrentTranslateEnums", gtkwavetcl_setCurrentTranslateEnums}, {"setCurrentTranslateFile", gtkwavetcl_setCurrentTranslateFile}, {"setCurrentTranslateProc", gtkwavetcl_setCurrentTranslateProc}, {"setCurrentTranslateTransProc", gtkwavetcl_setCurrentTranslateTransProc}, {"setFromEntry", gtkwavetcl_setFromEntry}, {"setLeftJustifySigs", gtkwavetcl_setLeftJustifySigs}, {"setMarker", gtkwavetcl_setMarker}, {"setNamedMarker", gtkwavetcl_setNamedMarker}, {"setTabActive", gtkwavetcl_setTabActive}, {"setToEntry", gtkwavetcl_setToEntry}, {"setTraceHighlightFromIndex", gtkwavetcl_setTraceHighlightFromIndex}, {"setTraceHighlightFromNameMatch", gtkwavetcl_setTraceHighlightFromNameMatch}, {"setTraceScrollbarRowValue", gtkwavetcl_setTraceScrollbarRowValue}, {"setWindowStartTime", gtkwavetcl_setWindowStartTime}, {"setZoomFactor", gtkwavetcl_setZoomFactor}, {"setZoomRangeTimes", gtkwavetcl_setZoomRangeTimes}, {"loadFile", gtkwavetcl_loadFile}, {"reLoadFile", gtkwavetcl_reLoadFile}, {"presentWindow", gtkwavetcl_presentWindow}, {"showSignal", gtkwavetcl_showSignal}, {"unhighlightSignalsFromList", gtkwavetcl_unhighlightSignalsFromList}, {"signalChangeList", gtkwavetcl_signalChangeList}, /* changed from signal_change_list for consistency! */ {"", NULL} /* sentinel */ }; #else static void dummy_function(void) { /* nothing */ } #endif gtkwave-3.3.66/src/vcd_partial.c0000664000076400007640000022240212477613751016041 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2011. * * 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. */ /* * vcd.c 23jan99ajb * evcd parts 29jun99ajb * profiler optimizations 15jul99ajb * more profiler optimizations 25jan00ajb * finsim parameter fix 26jan00ajb * vector rechaining code 03apr00ajb * multiple var section code 06apr00ajb * fix for duplicate nets 19dec00ajb * support for alt hier seps 23dec00ajb * fix for rcs identifiers 16jan01ajb * coredump fix for bad VCD 04apr02ajb * min/maxid speedup 27feb03ajb * bugfix on min/maxid speedup 06jul03ajb * escaped hier modification 20feb06ajb * added partial loader support 04aug06ajb * added real_parameter vartype 04aug06ajb * added in/out port vartype 31jan07ajb * use gperf for port vartypes 19feb07ajb * MTI SV implicit-var fix 05apr07ajb * MTI SV len=0 is real var 05apr07ajb */ #include #include "globals.h" #include "vcd.h" #include "hierpack.h" #if !defined _MSC_VER && !defined __MINGW32__ #include #include #include #endif #ifdef __MINGW32__ #include #endif #undef VCD_BSEARCH_IS_PERFECT /* bsearch is imperfect under linux, but OK under AIX */ static hptr add_histent_p(TimeType time, struct Node *n, char ch, int regadd, char *vector); static void add_tail_histents(void); static void vcd_build_symbols(void); static void vcd_cleanup(void); static void evcd_strcpy(char *dst, char *src); /*******************************************************************************/ #define WAVE_PARTIAL_VCD_RING_BUFFER_SIZE (1024*1024) unsigned int get_8(char *p) { if(p >= (GLOBALS->buf_vcd_partial_c_2 + WAVE_PARTIAL_VCD_RING_BUFFER_SIZE)) { p-= WAVE_PARTIAL_VCD_RING_BUFFER_SIZE; } return((unsigned int)((unsigned char)*p)); } unsigned int get_32(char *p) { unsigned int rc; rc = (get_8(p++) << 24) ; rc|= (get_8(p++) << 16) ; rc|= (get_8(p++) << 8) ; rc|= (get_8(p) << 0) ; return(rc); } int consume(void) /* for testing only */ { int len; GLOBALS->consume_countdown_vcd_partial_c_1--; if(!GLOBALS->consume_countdown_vcd_partial_c_1) { GLOBALS->consume_countdown_vcd_partial_c_1 = 100000; return(0); } if((len = *GLOBALS->consume_ptr_vcd_partial_c_1)) { int i; len = get_32(GLOBALS->consume_ptr_vcd_partial_c_1+1); for(i=0;ivcdbuf_vcd_partial_c_2[i] = get_8(GLOBALS->consume_ptr_vcd_partial_c_1+i+5); } GLOBALS->vcdbuf_vcd_partial_c_2[i] = 0; *GLOBALS->consume_ptr_vcd_partial_c_1 = 0; GLOBALS->consume_ptr_vcd_partial_c_1 = GLOBALS->consume_ptr_vcd_partial_c_1+i+5; if(GLOBALS->consume_ptr_vcd_partial_c_1 >= (GLOBALS->buf_vcd_partial_c_2 + WAVE_PARTIAL_VCD_RING_BUFFER_SIZE)) { GLOBALS->consume_ptr_vcd_partial_c_1 -= WAVE_PARTIAL_VCD_RING_BUFFER_SIZE; } } return(len); } /******************************************************************/ enum Tokens { T_VAR, T_END, T_SCOPE, T_UPSCOPE, T_COMMENT, T_DATE, T_DUMPALL, T_DUMPOFF, T_DUMPON, T_DUMPVARS, T_ENDDEFINITIONS, T_DUMPPORTS, T_DUMPPORTSOFF, T_DUMPPORTSON, T_DUMPPORTSALL, T_TIMESCALE, T_VERSION, T_VCDCLOSE, T_TIMEZERO, T_EOF, T_STRING, T_UNKNOWN_KEY }; static char *tokens[]={ "var", "end", "scope", "upscope", "comment", "date", "dumpall", "dumpoff", "dumpon", "dumpvars", "enddefinitions", "dumpports", "dumpportsoff", "dumpportson", "dumpportsall", "timescale", "version", "vcdclose", "timezero", "", "", "" }; #define NUM_TOKENS 19 #define T_GET tok=get_token();if((tok==T_END)||(tok==T_EOF))break; /******************************************************************/ #define NUM_VTOKENS 23 /******************************************************************/ static unsigned int vcdid_hash(char *s, int len) { unsigned int val=0; int i; s+=(len-1); for(i=0;iid)); } /* * actual bsearch */ static struct vcdsymbol *bsearch_vcd(char *key, int len) { struct vcdsymbol **v; struct vcdsymbol *t; if(GLOBALS->indexed_vcd_partial_c_2) { unsigned int hsh = vcdid_hash(key, len); if((hsh>=GLOBALS->vcd_minid_vcd_partial_c_2)&&(hsh<=GLOBALS->vcd_maxid_vcd_partial_c_2)) { return(GLOBALS->indexed_vcd_partial_c_2[hsh-GLOBALS->vcd_minid_vcd_partial_c_2]); } return(NULL); } if(GLOBALS->sorted_vcd_partial_c_2) { v=(struct vcdsymbol **)bsearch(key, GLOBALS->sorted_vcd_partial_c_2, GLOBALS->numsyms_vcd_partial_c_2, sizeof(struct vcdsymbol *), vcdsymbsearchcompare); if(v) { #ifndef VCD_BSEARCH_IS_PERFECT for(;;) { t=*v; if((v==GLOBALS->sorted_vcd_partial_c_2)||(strcmp((*(--v))->id, key))) { return(t); } } #else return(*v); #endif } else { return(NULL); } } else { if(!GLOBALS->err_vcd_partial_c_2) { fprintf(stderr, "Near byte %d, VCD search table NULL..is this a VCD file?\n", (int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2))); GLOBALS->err_vcd_partial_c_2=1; } return(NULL); } } /* * sort on vcdsymbol pointers */ static int vcdsymcompare(const void *s1, const void *s2) { struct vcdsymbol *v1, *v2; v1=*((struct vcdsymbol **)s1); v2=*((struct vcdsymbol **)s2); return(strcmp(v1->id, v2->id)); } /* * create sorted (by id) table */ static void create_sorted_table(void) { struct vcdsymbol *v; struct vcdsymbol **pnt; unsigned int vcd_distance; if(GLOBALS->sorted_vcd_partial_c_2) { free_2(GLOBALS->sorted_vcd_partial_c_2); /* this means we saw a 2nd enddefinition chunk! */ GLOBALS->sorted_vcd_partial_c_2=NULL; } if(GLOBALS->indexed_vcd_partial_c_2) { free_2(GLOBALS->indexed_vcd_partial_c_2); GLOBALS->indexed_vcd_partial_c_2=NULL; } if(GLOBALS->numsyms_vcd_partial_c_2) { vcd_distance = GLOBALS->vcd_maxid_vcd_partial_c_2 - GLOBALS->vcd_minid_vcd_partial_c_2 + 1; if((vcd_distance <= VCD_INDEXSIZ)||(!GLOBALS->vcd_hash_kill)) { GLOBALS->indexed_vcd_partial_c_2 = (struct vcdsymbol **)calloc_2(vcd_distance, sizeof(struct vcdsymbol *)); /* printf("%d symbols span ID range of %d, using indexing...\n", numsyms, vcd_distance); */ v=GLOBALS->vcdsymroot_vcd_partial_c_2; while(v) { if(!GLOBALS->indexed_vcd_partial_c_2[v->nid - GLOBALS->vcd_minid_vcd_partial_c_2]) GLOBALS->indexed_vcd_partial_c_2[v->nid - GLOBALS->vcd_minid_vcd_partial_c_2] = v; v=v->next; } } else { pnt=GLOBALS->sorted_vcd_partial_c_2=(struct vcdsymbol **)calloc_2(GLOBALS->numsyms_vcd_partial_c_2, sizeof(struct vcdsymbol *)); v=GLOBALS->vcdsymroot_vcd_partial_c_2; while(v) { *(pnt++)=v; v=v->next; } qsort(GLOBALS->sorted_vcd_partial_c_2, GLOBALS->numsyms_vcd_partial_c_2, sizeof(struct vcdsymbol *), vcdsymcompare); } } } /******************************************************************/ /* * single char get inlined/optimized */ static void getch_alloc(void) { GLOBALS->vend_vcd_partial_c_2=GLOBALS->vst_vcd_partial_c_2=GLOBALS->vcdbuf_vcd_partial_c_2=(char *)calloc_2(1,VCD_BSIZ); } static int getch_fetch(void) { size_t rd; errno = 0; GLOBALS->vcdbyteno_vcd_partial_c_2+=(GLOBALS->vend_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2); rd=consume(); GLOBALS->vend_vcd_partial_c_2=(GLOBALS->vst_vcd_partial_c_2=GLOBALS->vcdbuf_vcd_partial_c_2)+rd; if(!rd) return(-1); return((int)(*GLOBALS->vst_vcd_partial_c_2)); } static inline signed char getch(void) { signed char ch = ((GLOBALS->vst_vcd_partial_c_2!=GLOBALS->vend_vcd_partial_c_2)?((int)(*GLOBALS->vst_vcd_partial_c_2)):(getch_fetch())); if(ch>=0) { GLOBALS->vst_vcd_partial_c_2++; }; return(ch); } static inline signed char getch_peek(void) { signed char ch = ((GLOBALS->vst_vcd_partial_c_2!=GLOBALS->vend_vcd_partial_c_2)?((int)(*GLOBALS->vst_vcd_partial_c_2)):(getch_fetch())); /* no increment */ return(ch); } static int getch_patched(void) { char ch; ch=*GLOBALS->vsplitcurr_vcd_partial_c_2; if(!ch) { return(-1); } else { GLOBALS->vsplitcurr_vcd_partial_c_2++; return((int)ch); } } /* * simple tokenizer */ static int get_token(void) { int ch; int i, len=0; int is_string=0; char *yyshadow; for(;;) { ch=getch(); if(ch<0) return(T_EOF); if(ch<=' ') continue; /* val<=' ' is a quick whitespace check */ break; /* (take advantage of fact that vcd is text) */ } if(ch=='$') { GLOBALS->yytext_vcd_partial_c_2[len++]=ch; for(;;) { ch=getch(); if(ch<0) return(T_EOF); if(ch<=' ') continue; break; } } else { is_string=1; } for(GLOBALS->yytext_vcd_partial_c_2[len++]=ch;;GLOBALS->yytext_vcd_partial_c_2[len++]=ch) { if(len==GLOBALS->T_MAX_STR_vcd_partial_c_2) { GLOBALS->yytext_vcd_partial_c_2=(char *)realloc_2(GLOBALS->yytext_vcd_partial_c_2, (GLOBALS->T_MAX_STR_vcd_partial_c_2=GLOBALS->T_MAX_STR_vcd_partial_c_2*2)+1); } ch=getch(); if(ch<=' ') break; } GLOBALS->yytext_vcd_partial_c_2[len]=0; /* terminator */ if(is_string) { GLOBALS->yylen_vcd_partial_c_2=len; return(T_STRING); } yyshadow=GLOBALS->yytext_vcd_partial_c_2; do { yyshadow++; for(i=0;ivar_prevch_vcd_partial_c_2) { for(;;) { ch=getch_patched(); if(ch<0) { free_2(GLOBALS->varsplit_vcd_partial_c_2); GLOBALS->varsplit_vcd_partial_c_2=NULL; return(V_END); } if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')) continue; break; } } else { ch=GLOBALS->var_prevch_vcd_partial_c_2; GLOBALS->var_prevch_vcd_partial_c_2=0; } if(ch=='[') return(V_LB); if(ch==':') return(V_COLON); if(ch==']') return(V_RB); for(GLOBALS->yytext_vcd_partial_c_2[len++]=ch;;GLOBALS->yytext_vcd_partial_c_2[len++]=ch) { if(len==GLOBALS->T_MAX_STR_vcd_partial_c_2) { GLOBALS->yytext_vcd_partial_c_2=(char *)realloc_2(GLOBALS->yytext_vcd_partial_c_2, (GLOBALS->T_MAX_STR_vcd_partial_c_2=GLOBALS->T_MAX_STR_vcd_partial_c_2*2)+1); } ch=getch_patched(); if(ch<0) { free_2(GLOBALS->varsplit_vcd_partial_c_2); GLOBALS->varsplit_vcd_partial_c_2=NULL; break; } if((ch==':')||(ch==']')) { GLOBALS->var_prevch_vcd_partial_c_2=ch; break; } } GLOBALS->yytext_vcd_partial_c_2[len]=0; /* terminator */ if(match_kw) { int vt = vcd_keyword_code(GLOBALS->yytext_vcd_partial_c_2, len); if(vt != V_STRING) { if(ch<0) { free_2(GLOBALS->varsplit_vcd_partial_c_2); GLOBALS->varsplit_vcd_partial_c_2=NULL; } return(vt); } } GLOBALS->yylen_vcd_partial_c_2=len; if(ch<0) { free_2(GLOBALS->varsplit_vcd_partial_c_2); GLOBALS->varsplit_vcd_partial_c_2=NULL; } return(V_STRING); } static int get_vartoken(int match_kw) { int ch; int len=0; if(GLOBALS->varsplit_vcd_partial_c_2) { int rc=get_vartoken_patched(match_kw); if(rc!=V_END) return(rc); GLOBALS->var_prevch_vcd_partial_c_2=0; } if(!GLOBALS->var_prevch_vcd_partial_c_2) { for(;;) { ch=getch(); if(ch<0) return(V_END); if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')) continue; break; } } else { ch=GLOBALS->var_prevch_vcd_partial_c_2; GLOBALS->var_prevch_vcd_partial_c_2=0; } if(ch=='[') return(V_LB); if(ch==':') return(V_COLON); if(ch==']') return(V_RB); if(ch=='#') /* for MTI System Verilog '$var reg 64 >w #implicit-var###VarElem:ram_di[0.0] [63:0] $end' style declarations */ { /* debussy simply escapes until the space */ GLOBALS->yytext_vcd_partial_c_2[len++]= '\\'; } for(GLOBALS->yytext_vcd_partial_c_2[len++]=ch;;GLOBALS->yytext_vcd_partial_c_2[len++]=ch) { if(len==GLOBALS->T_MAX_STR_vcd_partial_c_2) { GLOBALS->yytext_vcd_partial_c_2=(char *)realloc_2(GLOBALS->yytext_vcd_partial_c_2, (GLOBALS->T_MAX_STR_vcd_partial_c_2=GLOBALS->T_MAX_STR_vcd_partial_c_2*2)+1); } ch=getch(); if(ch==' ') { if(match_kw) break; if(getch_peek() == '[') { ch = getch(); GLOBALS->varsplit_vcd_partial_c_2=GLOBALS->yytext_vcd_partial_c_2+len; /* keep looping so we get the *last* one */ continue; } } if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')||(ch<0)) break; if((ch=='[')&&(GLOBALS->yytext_vcd_partial_c_2[0]!='\\')) { GLOBALS->varsplit_vcd_partial_c_2=GLOBALS->yytext_vcd_partial_c_2+len; /* keep looping so we get the *last* one */ } else if(((ch==':')||(ch==']'))&&(!GLOBALS->varsplit_vcd_partial_c_2)&&(GLOBALS->yytext_vcd_partial_c_2[0]!='\\')) { GLOBALS->var_prevch_vcd_partial_c_2=ch; break; } } GLOBALS->yytext_vcd_partial_c_2[len]=0; /* absolute terminator */ if((GLOBALS->varsplit_vcd_partial_c_2)&&(GLOBALS->yytext_vcd_partial_c_2[len-1]==']')) { char *vst; vst=malloc_2(strlen(GLOBALS->varsplit_vcd_partial_c_2)+1); strcpy(vst, GLOBALS->varsplit_vcd_partial_c_2); *GLOBALS->varsplit_vcd_partial_c_2=0x00; /* zero out var name at the left bracket */ len=GLOBALS->varsplit_vcd_partial_c_2-GLOBALS->yytext_vcd_partial_c_2; GLOBALS->varsplit_vcd_partial_c_2=GLOBALS->vsplitcurr_vcd_partial_c_2=vst; GLOBALS->var_prevch_vcd_partial_c_2=0; } else { GLOBALS->varsplit_vcd_partial_c_2=NULL; } if(match_kw) { int vt = vcd_keyword_code(GLOBALS->yytext_vcd_partial_c_2, len); if(vt != V_STRING) { return(vt); } } GLOBALS->yylen_vcd_partial_c_2=len; return(V_STRING); } static int get_strtoken(void) { int ch; int len=0; if(!GLOBALS->var_prevch_vcd_partial_c_2) { for(;;) { ch=getch(); if(ch<0) return(V_END); if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')) continue; break; } } else { ch=GLOBALS->var_prevch_vcd_partial_c_2; GLOBALS->var_prevch_vcd_partial_c_2=0; } for(GLOBALS->yytext_vcd_partial_c_2[len++]=ch;;GLOBALS->yytext_vcd_partial_c_2[len++]=ch) { if(len==GLOBALS->T_MAX_STR_vcd_partial_c_2) { GLOBALS->yytext_vcd_partial_c_2=(char *)realloc_2(GLOBALS->yytext_vcd_partial_c_2, (GLOBALS->T_MAX_STR_vcd_partial_c_2=GLOBALS->T_MAX_STR_vcd_partial_c_2*2)+1); } ch=getch(); if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')||(ch<0)) break; } GLOBALS->yytext_vcd_partial_c_2[len]=0; /* terminator */ GLOBALS->yylen_vcd_partial_c_2=len; return(V_STRING); } static void sync_end(char *hdr) { int tok; if(hdr) { DEBUG(fprintf(stderr,"%s",hdr)); } for(;;) { tok=get_token(); if((tok==T_END)||(tok==T_EOF)) break; if(hdr) { DEBUG(fprintf(stderr," %s",GLOBALS->yytext_vcd_partial_c_2)); } } if(hdr) { DEBUG(fprintf(stderr,"\n")); } } static int version_sync_end(char *hdr) { int tok; int rc = 0; if(hdr) { DEBUG(fprintf(stderr,"%s",hdr)); } for(;;) { tok=get_token(); if((tok==T_END)||(tok==T_EOF)) break; if(hdr) { DEBUG(fprintf(stderr," %s",GLOBALS->yytext_vcd_partial_c_2)); } if(strstr(GLOBALS->yytext_vcd_partial_c_2, "Icarus")) /* turn off autocoalesce for Icarus */ { GLOBALS->autocoalesce = 0; rc = 1; } } if(hdr) { DEBUG(fprintf(stderr,"\n")); } return(rc); } static void parse_valuechange(void) { struct vcdsymbol *v; char *vector; int vlen; /* hptr hsuf; */ /* scan-build */ switch(GLOBALS->yytext_vcd_partial_c_2[0]) { case '0': case '1': case 'x': case 'X': case 'z': case 'Z': case 'h': case 'H': case 'u': case 'U': case 'w': case 'W': case 'l': case 'L': case '-': if(GLOBALS->yylen_vcd_partial_c_2>1) { v=bsearch_vcd(GLOBALS->yytext_vcd_partial_c_2+1, GLOBALS->yylen_vcd_partial_c_2-1); if(!v) { fprintf(stderr,"Near byte %d, Unknown VCD identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2)),GLOBALS->yytext_vcd_partial_c_2+1); } else { v->value[0]=GLOBALS->yytext_vcd_partial_c_2[0]; DEBUG(fprintf(stderr,"%s = '%c'\n",v->name,v->value[0])); v->narray[0]->curr = v->app_array[0]; /* hsuf = */ add_histent_p(GLOBALS->current_time_vcd_partial_c_2,v->narray[0],v->value[0],1, NULL); /* scan-build */ v->app_array[0] = v->narray[0]->curr; v->narray[0]->curr->next = v->tr_array[0]; if(v->narray[0]->harray) { free_2(v->narray[0]->harray); v->narray[0]->harray = NULL; } } } else { fprintf(stderr,"Near byte %d, Malformed VCD identifier\n", (int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2))); } break; case 'b': case 'B': { /* extract binary number then.. */ vector=malloc_2(GLOBALS->yylen_cache_vcd_partial_c_2=GLOBALS->yylen_vcd_partial_c_2); strcpy(vector,GLOBALS->yytext_vcd_partial_c_2+1); vlen=GLOBALS->yylen_vcd_partial_c_2-1; get_strtoken(); v=bsearch_vcd(GLOBALS->yytext_vcd_partial_c_2, GLOBALS->yylen_vcd_partial_c_2); if(!v) { fprintf(stderr,"Near byte %d, Unknown identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2)), GLOBALS->yytext_vcd_partial_c_2); free_2(vector); } else { if ((v->vartype==V_REAL)||(v->vartype==V_STRINGTYPE)||((GLOBALS->convert_to_reals)&&((v->vartype==V_INTEGER)||(v->vartype==V_PARAMETER)))) { double *d; char *pnt; char ch; TimeType k=0; pnt=vector; while((ch=*(pnt++))) { k=(k<<1)|((ch=='1')?1:0); } free_2(vector); d=malloc_2(sizeof(double)); *d=(double)k; if(!v) { fprintf(stderr,"Near byte %d, Unknown identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2)), GLOBALS->yytext_vcd_partial_c_2); free_2(d); } else { v->narray[0]->curr = v->app_array[0]; add_histent_p(GLOBALS->current_time_vcd_partial_c_2, v->narray[0],'g',1,(char *)d); v->app_array[0] = v->narray[0]->curr; v->narray[0]->curr->next = v->tr_array[0]; if(v->narray[0]->harray) { free_2(v->narray[0]->harray); v->narray[0]->harray = NULL; } } break; } if(vlensize) /* fill in left part */ { char extend; int i, fill; extend=(vector[0]=='1')?'0':vector[0]; fill=v->size-vlen; for(i=0;ivalue[i]=extend; } strcpy(v->value+fill,vector); } else if(vlen==v->size) /* straight copy */ { strcpy(v->value,vector); } else /* too big, so copy only right half */ { int skip; skip=vlen-v->size; strcpy(v->value,vector+skip); } DEBUG(fprintf(stderr,"%s = '%s'\n",v->name, v->value)); if((v->size==1)||(!GLOBALS->atomic_vectors)) { int i; for(i=0;isize;i++) { v->narray[i]->curr = v->app_array[i]; add_histent_p(GLOBALS->current_time_vcd_partial_c_2, v->narray[i],v->value[i],1, NULL); v->app_array[i] = v->narray[i]->curr; v->narray[i]->curr->next = v->tr_array[i]; if(v->narray[i]->harray) { free_2(v->narray[i]->harray); v->narray[i]->harray = NULL; } } free_2(vector); } else { if(GLOBALS->yylen_cache_vcd_partial_c_2!=(v->size+1)) { free_2(vector); vector=malloc_2(v->size+1); } strcpy(vector,v->value); v->narray[0]->curr = v->app_array[0]; add_histent_p(GLOBALS->current_time_vcd_partial_c_2, v->narray[0],0,1,vector); v->app_array[0] = v->narray[0]->curr; v->narray[0]->curr->next = v->tr_array[0]; if(v->narray[0]->harray) { free_2(v->narray[0]->harray); v->narray[0]->harray = NULL; } } } break; } case 'p': /* extract port dump value.. */ vector=malloc_2(GLOBALS->yylen_cache_vcd_partial_c_2=GLOBALS->yylen_vcd_partial_c_2); strcpy(vector,GLOBALS->yytext_vcd_partial_c_2+1); vlen=GLOBALS->yylen_vcd_partial_c_2-1; get_strtoken(); /* throw away 0_strength_component */ get_strtoken(); /* throw away 0_strength_component */ get_strtoken(); /* this is the id */ v=bsearch_vcd(GLOBALS->yytext_vcd_partial_c_2, GLOBALS->yylen_vcd_partial_c_2); if(!v) { fprintf(stderr,"Near byte %d, Unknown identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2)), GLOBALS->yytext_vcd_partial_c_2); free_2(vector); } else { if ((v->vartype==V_REAL)||(v->vartype==V_STRINGTYPE)||((GLOBALS->convert_to_reals)&&((v->vartype==V_INTEGER)||(v->vartype==V_PARAMETER)))) { double *d; char *pnt; char ch; TimeType k=0; pnt=vector; while((ch=*(pnt++))) { k=(k<<1)|((ch=='1')?1:0); } free_2(vector); d=malloc_2(sizeof(double)); *d=(double)k; if(!v) { fprintf(stderr,"Near byte %d, Unknown identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2)), GLOBALS->yytext_vcd_partial_c_2); free_2(d); } else { v->narray[0]->curr = v->app_array[0]; add_histent_p(GLOBALS->current_time_vcd_partial_c_2, v->narray[0],'g',1,(char *)d); v->app_array[0] = v->narray[0]->curr; v->narray[0]->curr->next = v->tr_array[0]; if(v->narray[0]->harray) { free_2(v->narray[0]->harray); v->narray[0]->harray = NULL; } } break; } if(vlensize) /* fill in left part */ { char extend; int i, fill; extend='0'; fill=v->size-vlen; for(i=0;ivalue[i]=extend; } evcd_strcpy(v->value+fill,vector); } else if(vlen==v->size) /* straight copy */ { evcd_strcpy(v->value,vector); } else /* too big, so copy only right half */ { int skip; skip=vlen-v->size; evcd_strcpy(v->value,vector+skip); } DEBUG(fprintf(stderr,"%s = '%s'\n",v->name, v->value)); if((v->size==1)||(!GLOBALS->atomic_vectors)) { int i; for(i=0;isize;i++) { v->narray[i]->curr = v->app_array[i]; add_histent_p(GLOBALS->current_time_vcd_partial_c_2, v->narray[i],v->value[i],1, NULL); v->app_array[i] = v->narray[i]->curr; v->narray[i]->curr->next = v->tr_array[i]; if(v->narray[i]->harray) { free_2(v->narray[i]->harray); v->narray[i]->harray = NULL; } } free_2(vector); } else { if(GLOBALS->yylen_cache_vcd_partial_c_2size) { free_2(vector); vector=malloc_2(v->size+1); } strcpy(vector,v->value); v->narray[0]->curr = v->app_array[0]; add_histent_p(GLOBALS->current_time_vcd_partial_c_2, v->narray[0],0,1,vector); v->app_array[0] = v->narray[0]->curr; v->narray[0]->curr->next = v->tr_array[0]; if(v->narray[0]->harray) { free_2(v->narray[0]->harray); v->narray[0]->harray = NULL; } } } break; case 'r': case 'R': { double *d; d=malloc_2(sizeof(double)); sscanf(GLOBALS->yytext_vcd_partial_c_2+1,"%lg",d); get_strtoken(); v=bsearch_vcd(GLOBALS->yytext_vcd_partial_c_2, GLOBALS->yylen_vcd_partial_c_2); if(!v) { fprintf(stderr,"Near byte %d, Unknown identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2)), GLOBALS->yytext_vcd_partial_c_2); free_2(d); } else { v->narray[0]->curr = v->app_array[0]; add_histent_p(GLOBALS->current_time_vcd_partial_c_2, v->narray[0],'g',1,(char *)d); v->app_array[0] = v->narray[0]->curr; v->narray[0]->curr->next = v->tr_array[0]; if(v->narray[0]->harray) { free_2(v->narray[0]->harray); v->narray[0]->harray = NULL; } } break; } #ifndef STRICT_VCD_ONLY case 's': case 'S': { char *d; d=(char *)malloc_2(GLOBALS->yylen_vcd_partial_c_2); vlen = fstUtilityEscToBin((unsigned char *)d, (unsigned char *)(GLOBALS->yytext_vcd_partial_c_2+1), GLOBALS->yylen_vcd_partial_c_2); /* includes 0 term */ if(vlen != GLOBALS->yylen_vcd_partial_c_2) { d = realloc_2(d, vlen); } get_strtoken(); v=bsearch_vcd(GLOBALS->yytext_vcd_partial_c_2, GLOBALS->yylen_vcd_partial_c_2); if(!v) { fprintf(stderr,"Near byte %d, Unknown identifier: '%s'\n",(int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2)), GLOBALS->yytext_vcd_partial_c_2); free_2(d); } else { v->narray[0]->curr = v->app_array[0]; add_histent_p(GLOBALS->current_time_vcd_partial_c_2, v->narray[0],'s',1,(char *)d); v->app_array[0] = v->narray[0]->curr; v->narray[0]->curr->next = v->tr_array[0]; if(v->narray[0]->harray) { free_2(v->narray[0]->harray); v->narray[0]->harray = NULL; } } break; } #endif } } static void evcd_strcpy(char *dst, char *src) { static const char *evcd="DUNZduLHXTlh01?FAaBbCcf"; static const char *vcd="01xz0101xz0101xzxxxxxxz"; char ch; int i; while((ch=*src)) { for(i=0;i<23;i++) { if(evcd[i]==ch) { *dst=vcd[i]; break; } } if(i==23) *dst='x'; src++; dst++; } *dst=0; /* null terminate destination */ } static void vcd_parse(void) { int tok; unsigned char ttype; int disable_autocoalesce = 0; for(;;) { switch(get_token()) { case T_COMMENT: sync_end("COMMENT:"); break; case T_DATE: sync_end("DATE:"); break; case T_VERSION: disable_autocoalesce = version_sync_end("VERSION:"); break; case T_TIMEZERO: { int vtok=get_token(); if((vtok==T_END)||(vtok==T_EOF)) break; GLOBALS->global_time_offset=atoi_64(GLOBALS->yytext_vcd_partial_c_2); DEBUG(fprintf(stderr,"TIMEZERO: "TTFormat"\n",GLOBALS->global_time_offset)); sync_end(NULL); } break; case T_TIMESCALE: { int vtok; int i; char prefix=' '; vtok=get_token(); if((vtok==T_END)||(vtok==T_EOF)) break; fractional_timescale_fix(GLOBALS->yytext_vcd_partial_c_2); GLOBALS->time_scale=atoi_64(GLOBALS->yytext_vcd_partial_c_2); if(!GLOBALS->time_scale) GLOBALS->time_scale=1; for(i=0;iyylen_vcd_partial_c_2;i++) { if((GLOBALS->yytext_vcd_partial_c_2[i]<'0')||(GLOBALS->yytext_vcd_partial_c_2[i]>'9')) { prefix=GLOBALS->yytext_vcd_partial_c_2[i]; break; } } if(prefix==' ') { vtok=get_token(); if((vtok==T_END)||(vtok==T_EOF)) break; prefix=GLOBALS->yytext_vcd_partial_c_2[0]; } switch(prefix) { case ' ': case 'm': case 'u': case 'n': case 'p': case 'f': case 'a': case 'z': GLOBALS->time_dimension=prefix; break; case 's': GLOBALS->time_dimension=' '; break; default: /* unknown */ GLOBALS->time_dimension='n'; break; } DEBUG(fprintf(stderr,"TIMESCALE: "TTFormat" %cs\n",GLOBALS->time_scale, GLOBALS->time_dimension)); sync_end(NULL); } break; case T_SCOPE: T_GET; { switch(GLOBALS->yytext_vcd_partial_c_2[0]) { case 'm': ttype = TREE_VCD_ST_MODULE; break; case 't': ttype = TREE_VCD_ST_TASK; break; case 'f': ttype = (GLOBALS->yytext_vcd_partial_c_2[1] == 'u') ? TREE_VCD_ST_FUNCTION : TREE_VCD_ST_FORK; break; case 'b': ttype = TREE_VCD_ST_BEGIN; break; case 'g': ttype = TREE_VCD_ST_GENERATE; break; case 's': ttype = TREE_VCD_ST_STRUCT; break; case 'u': ttype = TREE_VCD_ST_UNION; break; case 'c': ttype = TREE_VCD_ST_CLASS; break; case 'i': ttype = TREE_VCD_ST_INTERFACE; break; case 'p': ttype = (GLOBALS->yytext_vcd_partial_c_2[1] == 'r') ? TREE_VCD_ST_PROGRAM : TREE_VCD_ST_PACKAGE; break; case 'v': { char *vht = GLOBALS->yytext_vcd_partial_c_2; if(!strncmp(vht, "vhdl_", 5)) { switch(vht[5]) { case 'a': ttype = TREE_VHDL_ST_ARCHITECTURE; break; case 'r': ttype = TREE_VHDL_ST_RECORD; break; case 'b': ttype = TREE_VHDL_ST_BLOCK; break; case 'g': ttype = TREE_VHDL_ST_GENERATE; break; case 'i': ttype = TREE_VHDL_ST_GENIF; break; case 'f': ttype = (vht[6] == 'u') ? TREE_VHDL_ST_FUNCTION : TREE_VHDL_ST_GENFOR; break; case 'p': ttype = (!strncmp(vht+6, "roces", 5)) ? TREE_VHDL_ST_PROCESS: TREE_VHDL_ST_PROCEDURE; break; default: ttype = TREE_UNKNOWN; break; } } else { ttype = TREE_UNKNOWN; } } break; default: ttype = TREE_UNKNOWN; break; } } T_GET; if(tok==T_STRING) { struct slist *s; s=(struct slist *)calloc_2(1,sizeof(struct slist)); s->len=GLOBALS->yylen_vcd_partial_c_2; s->str=(char *)malloc_2(GLOBALS->yylen_vcd_partial_c_2+1); strcpy(s->str, GLOBALS->yytext_vcd_partial_c_2); s->mod_tree_parent = GLOBALS->mod_tree_parent; allocate_and_decorate_module_tree_node(ttype, GLOBALS->yytext_vcd_partial_c_2, NULL, GLOBALS->yylen_vcd_partial_c_2, 0, 0, 0); if(GLOBALS->slistcurr) { GLOBALS->slistcurr->next=s; GLOBALS->slistcurr=s; } else { GLOBALS->slistcurr=GLOBALS->slistroot=s; } build_slisthier(); DEBUG(fprintf(stderr, "SCOPE: %s\n",GLOBALS->slisthier)); } sync_end(NULL); break; case T_UPSCOPE: if(GLOBALS->slistroot) { struct slist *s; GLOBALS->mod_tree_parent = GLOBALS->slistcurr->mod_tree_parent; s=GLOBALS->slistroot; if(!s->next) { free_2(s->str); free_2(s); GLOBALS->slistroot=GLOBALS->slistcurr=NULL; } else for(;;) { if(!s->next->next) { free_2(s->next->str); free_2(s->next); s->next=NULL; GLOBALS->slistcurr=s; break; } s=s->next; } build_slisthier(); DEBUG(fprintf(stderr, "SCOPE: %s\n",GLOBALS->slisthier)); } else { GLOBALS->mod_tree_parent = NULL; } sync_end(NULL); break; case T_VAR: if((GLOBALS->header_over_vcd_partial_c_2)&&(0)) { fprintf(stderr,"$VAR encountered after $ENDDEFINITIONS near byte %d. VCD is malformed, exiting.\n", (int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2))); exit(0); } else { int vtok; struct vcdsymbol *v=NULL; GLOBALS->var_prevch_vcd_partial_c_2=0; if(GLOBALS->varsplit_vcd_partial_c_2) { free_2(GLOBALS->varsplit_vcd_partial_c_2); GLOBALS->varsplit_vcd_partial_c_2=NULL; } vtok=get_vartoken(1); if(vtok>V_STRINGTYPE) goto bail; v=(struct vcdsymbol *)calloc_2(1,sizeof(struct vcdsymbol)); v->vartype=vtok; v->msi=v->lsi=GLOBALS->vcd_explicit_zero_subscripts; /* indicate [un]subscripted status */ if(vtok==V_PORT) { vtok=get_vartoken(1); if(vtok==V_STRING) { v->size=atoi_64(GLOBALS->yytext_vcd_partial_c_2); if(!v->size) v->size=1; } else if(vtok==V_LB) { vtok=get_vartoken(1); if(vtok==V_END) goto err; if(vtok!=V_STRING) goto err; v->msi=atoi_64(GLOBALS->yytext_vcd_partial_c_2); vtok=get_vartoken(0); if(vtok==V_RB) { v->lsi=v->msi; v->size=1; } else { if(vtok!=V_COLON) goto err; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; v->lsi=atoi_64(GLOBALS->yytext_vcd_partial_c_2); vtok=get_vartoken(0); if(vtok!=V_RB) goto err; if(v->msi>v->lsi) { v->size=v->msi-v->lsi+1; } else { v->size=v->lsi-v->msi+1; } } } else goto err; vtok=get_strtoken(); if(vtok==V_END) goto err; v->id=(char *)malloc_2(GLOBALS->yylen_vcd_partial_c_2+1); strcpy(v->id, GLOBALS->yytext_vcd_partial_c_2); v->nid=vcdid_hash(GLOBALS->yytext_vcd_partial_c_2,GLOBALS->yylen_vcd_partial_c_2); if(v->nid == (GLOBALS->vcd_hash_max+1)) { GLOBALS->vcd_hash_max = v->nid; } else if((v->nid>0)&&(v->nid<=GLOBALS->vcd_hash_max)) { /* general case with aliases */ } else { GLOBALS->vcd_hash_kill = 1; } if(v->nid < GLOBALS->vcd_minid_vcd_partial_c_2) GLOBALS->vcd_minid_vcd_partial_c_2 = v->nid; if(v->nid > GLOBALS->vcd_maxid_vcd_partial_c_2) GLOBALS->vcd_maxid_vcd_partial_c_2 = v->nid; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; if(GLOBALS->slisthier_len) { v->name=(char *)malloc_2(GLOBALS->slisthier_len+1+GLOBALS->yylen_vcd_partial_c_2+1); strcpy(v->name,GLOBALS->slisthier); strcpy(v->name+GLOBALS->slisthier_len,GLOBALS->vcd_hier_delimeter); if(GLOBALS->alt_hier_delimeter) { strcpy_vcdalt(v->name+GLOBALS->slisthier_len+1,GLOBALS->yytext_vcd_partial_c_2,GLOBALS->alt_hier_delimeter); } else { if((strcpy_delimfix(v->name+GLOBALS->slisthier_len+1,GLOBALS->yytext_vcd_partial_c_2)) && (GLOBALS->yytext_vcd_partial_c_2[0] != '\\')) { char *sd=(char *)malloc_2(GLOBALS->slisthier_len+1+GLOBALS->yylen_vcd_partial_c_2+2); strcpy(sd,GLOBALS->slisthier); strcpy(sd+GLOBALS->slisthier_len,GLOBALS->vcd_hier_delimeter); sd[GLOBALS->slisthier_len+1] = '\\'; strcpy(sd+GLOBALS->slisthier_len+2,v->name+GLOBALS->slisthier_len+1); free_2(v->name); v->name = sd; } } } else { v->name=(char *)malloc_2(GLOBALS->yylen_vcd_partial_c_2+1); if(GLOBALS->alt_hier_delimeter) { strcpy_vcdalt(v->name,GLOBALS->yytext_vcd_partial_c_2,GLOBALS->alt_hier_delimeter); } else { if((strcpy_delimfix(v->name,GLOBALS->yytext_vcd_partial_c_2)) && (GLOBALS->yytext_vcd_partial_c_2[0] != '\\')) { char *sd=(char *)malloc_2(GLOBALS->yylen_vcd_partial_c_2+2); sd[0] = '\\'; strcpy(sd+1,v->name); free_2(v->name); v->name = sd; } } } if(GLOBALS->pv_vcd_partial_c_2) { if(!strcmp(GLOBALS->pv_vcd_partial_c_2->name,v->name) && !disable_autocoalesce && (!strchr(v->name, '\\'))) { GLOBALS->pv_vcd_partial_c_2->chain=v; v->root=GLOBALS->rootv_vcd_partial_c_2; if(GLOBALS->pv_vcd_partial_c_2==GLOBALS->rootv_vcd_partial_c_2) GLOBALS->pv_vcd_partial_c_2->root=GLOBALS->rootv_vcd_partial_c_2; } else { GLOBALS->rootv_vcd_partial_c_2=v; } } else { GLOBALS->rootv_vcd_partial_c_2=v; } GLOBALS->pv_vcd_partial_c_2=v; } else /* regular vcd var, not an evcd port var */ { vtok=get_vartoken(1); if(vtok==V_END) goto err; v->size=atoi_64(GLOBALS->yytext_vcd_partial_c_2); vtok=get_strtoken(); if(vtok==V_END) goto err; v->id=(char *)malloc_2(GLOBALS->yylen_vcd_partial_c_2+1); strcpy(v->id, GLOBALS->yytext_vcd_partial_c_2); v->nid=vcdid_hash(GLOBALS->yytext_vcd_partial_c_2,GLOBALS->yylen_vcd_partial_c_2); if(v->nid == (GLOBALS->vcd_hash_max+1)) { GLOBALS->vcd_hash_max = v->nid; } else if((v->nid>0)&&(v->nid<=GLOBALS->vcd_hash_max)) { /* general case with aliases */ } else { GLOBALS->vcd_hash_kill = 1; } if(v->nid < GLOBALS->vcd_minid_vcd_partial_c_2) GLOBALS->vcd_minid_vcd_partial_c_2 = v->nid; if(v->nid > GLOBALS->vcd_maxid_vcd_partial_c_2) GLOBALS->vcd_maxid_vcd_partial_c_2 = v->nid; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; if(GLOBALS->slisthier_len) { v->name=(char *)malloc_2(GLOBALS->slisthier_len+1+GLOBALS->yylen_vcd_partial_c_2+1); strcpy(v->name,GLOBALS->slisthier); strcpy(v->name+GLOBALS->slisthier_len,GLOBALS->vcd_hier_delimeter); if(GLOBALS->alt_hier_delimeter) { strcpy_vcdalt(v->name+GLOBALS->slisthier_len+1,GLOBALS->yytext_vcd_partial_c_2,GLOBALS->alt_hier_delimeter); } else { if((strcpy_delimfix(v->name+GLOBALS->slisthier_len+1,GLOBALS->yytext_vcd_partial_c_2)) && (GLOBALS->yytext_vcd_partial_c_2[0] != '\\')) { char *sd=(char *)malloc_2(GLOBALS->slisthier_len+1+GLOBALS->yylen_vcd_partial_c_2+2); strcpy(sd,GLOBALS->slisthier); strcpy(sd+GLOBALS->slisthier_len,GLOBALS->vcd_hier_delimeter); sd[GLOBALS->slisthier_len+1] = '\\'; strcpy(sd+GLOBALS->slisthier_len+2,v->name+GLOBALS->slisthier_len+1); free_2(v->name); v->name = sd; } } } else { v->name=(char *)malloc_2(GLOBALS->yylen_vcd_partial_c_2+1); if(GLOBALS->alt_hier_delimeter) { strcpy_vcdalt(v->name,GLOBALS->yytext_vcd_partial_c_2,GLOBALS->alt_hier_delimeter); } else { if((strcpy_delimfix(v->name,GLOBALS->yytext_vcd_partial_c_2)) && (GLOBALS->yytext_vcd_partial_c_2[0] != '\\')) { char *sd=(char *)malloc_2(GLOBALS->yylen_vcd_partial_c_2+2); sd[0] = '\\'; strcpy(sd+1,v->name); free_2(v->name); v->name = sd; } } } if(GLOBALS->pv_vcd_partial_c_2) { if(!strcmp(GLOBALS->pv_vcd_partial_c_2->name,v->name)) { GLOBALS->pv_vcd_partial_c_2->chain=v; v->root=GLOBALS->rootv_vcd_partial_c_2; if(GLOBALS->pv_vcd_partial_c_2==GLOBALS->rootv_vcd_partial_c_2) GLOBALS->pv_vcd_partial_c_2->root=GLOBALS->rootv_vcd_partial_c_2; } else { GLOBALS->rootv_vcd_partial_c_2=v; } } else { GLOBALS->rootv_vcd_partial_c_2=v; } GLOBALS->pv_vcd_partial_c_2=v; vtok=get_vartoken(1); if(vtok==V_END) goto dumpv; if(vtok!=V_LB) goto err; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; v->msi=atoi_64(GLOBALS->yytext_vcd_partial_c_2); vtok=get_vartoken(0); if(vtok==V_RB) { v->lsi=v->msi; goto dumpv; } if(vtok!=V_COLON) goto err; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; v->lsi=atoi_64(GLOBALS->yytext_vcd_partial_c_2); vtok=get_vartoken(0); if(vtok!=V_RB) goto err; } dumpv: if(v->size == 0) { if(v->vartype != V_EVENT) { if(v->vartype != V_STRINGTYPE) { v->vartype = V_REAL; } } else { v->size = 1; } } /* MTI fix */ if((v->vartype==V_REAL)||(v->vartype==V_STRINGTYPE)||((GLOBALS->convert_to_reals)&&((v->vartype==V_INTEGER)||(v->vartype==V_PARAMETER)))) { if(v->vartype != V_STRINGTYPE) { v->vartype=V_REAL; } v->size=1; /* override any data we parsed in */ v->msi=v->lsi=0; } else if((v->size>1)&&(v->msi<=0)&&(v->lsi<=0)) { if(v->vartype==V_EVENT) { v->size=1; } else { /* any criteria for the direction here? */ v->msi=v->size-1; v->lsi=0; } } else if((v->msi>v->lsi)&&((v->msi-v->lsi+1)!=v->size)) { if((v->vartype!=V_EVENT)&&(v->vartype!=V_PARAMETER)) { v->msi = v->size-1; v->lsi = 0; /* all this formerly was goto err; */ } else { v->size=v->msi-v->lsi+1; } } else if((v->lsi>=v->msi)&&((v->lsi-v->msi+1)!=v->size)) { if((v->vartype!=V_EVENT)&&(v->vartype!=V_PARAMETER)) { v->lsi = v->size-1; v->msi = 0; /* all this formerly was goto err; */ } else { v->size=v->lsi-v->msi+1; } } /* initial conditions */ v->value=(char *)malloc_2(v->size+1); v->value[v->size]=0; v->narray=(struct Node **)calloc_2(v->size,sizeof(struct Node *)); v->tr_array=(hptr *)calloc_2(v->size,sizeof(hptr)); v->app_array=(hptr *)calloc_2(v->size,sizeof(hptr)); { int i; if(GLOBALS->atomic_vectors) { for(i=0;isize;i++) { v->value[i]='x'; } v->narray[0]=(struct Node *)calloc_2(1,sizeof(struct Node)); v->narray[0]->head.time=-1; v->narray[0]->head.v.h_val=AN_X; } else { for(i=0;isize;i++) { v->value[i]='x'; v->narray[i]=(struct Node *)calloc_2(1,sizeof(struct Node)); v->narray[i]->head.time=-1; v->narray[i]->head.v.h_val=AN_X; } } } if(!GLOBALS->vcdsymroot_vcd_partial_c_2) { GLOBALS->vcdsymroot_vcd_partial_c_2=GLOBALS->vcdsymcurr_vcd_partial_c_2=v; } else { GLOBALS->vcdsymcurr_vcd_partial_c_2->next=v; GLOBALS->vcdsymcurr_vcd_partial_c_2=v; } GLOBALS->numsyms_vcd_partial_c_2++; goto bail; err: if(v) { GLOBALS->error_count_vcd_partial_c_2++; if(v->name) { fprintf(stderr, "Near byte %d, $VAR parse error encountered with '%s'\n", (int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2)), v->name); free_2(v->name); } else { fprintf(stderr, "Near byte %d, $VAR parse error encountered\n", (int)(GLOBALS->vcdbyteno_vcd_partial_c_2+(GLOBALS->vst_vcd_partial_c_2-GLOBALS->vcdbuf_vcd_partial_c_2))); } if(v->id) free_2(v->id); if(v->value) free_2(v->value); free_2(v); GLOBALS->pv_vcd_partial_c_2 = NULL; } bail: if(vtok!=V_END) sync_end(NULL); break; } case T_ENDDEFINITIONS: GLOBALS->header_over_vcd_partial_c_2=1; /* do symbol table management here */ create_sorted_table(); if((!GLOBALS->sorted_vcd_partial_c_2)&&(!GLOBALS->indexed_vcd_partial_c_2)) { fprintf(stderr, "No symbols in VCD file..nothing to do!\n"); exit(1); } if(GLOBALS->error_count_vcd_partial_c_2) { fprintf(stderr, "\n%d VCD parse errors encountered, exiting.\n", GLOBALS->error_count_vcd_partial_c_2); exit(1); } return; break; case T_STRING: if(!GLOBALS->header_over_vcd_partial_c_2) { GLOBALS->header_over_vcd_partial_c_2=1; /* do symbol table management here */ create_sorted_table(); if((!GLOBALS->sorted_vcd_partial_c_2)&&(!GLOBALS->indexed_vcd_partial_c_2)) break; } { /* catchall for events when header over */ if(GLOBALS->yytext_vcd_partial_c_2[0]=='#') { TimeType tim; tim=atoi_64(GLOBALS->yytext_vcd_partial_c_2+1); if(GLOBALS->start_time_vcd_partial_c_2<0) { GLOBALS->start_time_vcd_partial_c_2=tim; } GLOBALS->current_time_vcd_partial_c_2=tim; if(GLOBALS->end_time_vcd_partial_c_2end_time_vcd_partial_c_2=tim; /* in case of malformed vcd files */ DEBUG(fprintf(stderr,"#"TTFormat"\n",tim)); } else { parse_valuechange(); } } break; case T_DUMPALL: /* dump commands modify vals anyway so */ case T_DUMPPORTSALL: break; /* just loop through.. */ case T_DUMPOFF: case T_DUMPPORTSOFF: GLOBALS->dumping_off_vcd_partial_c_2=1; if((!GLOBALS->blackout_regions)||((GLOBALS->blackout_regions)&&(GLOBALS->blackout_regions->bstart<=GLOBALS->blackout_regions->bend))) { struct blackout_region_t *bt = calloc_2(1, sizeof(struct blackout_region_t)); bt->bstart = GLOBALS->current_time_vcd_partial_c_2 * GLOBALS->time_scale; bt->next = GLOBALS->blackout_regions; GLOBALS->blackout_regions = bt; } break; case T_DUMPON: case T_DUMPPORTSON: GLOBALS->dumping_off_vcd_partial_c_2=0; if((GLOBALS->blackout_regions)&&(GLOBALS->blackout_regions->bstart>GLOBALS->blackout_regions->bend)) { GLOBALS->blackout_regions->bend = GLOBALS->current_time_vcd_partial_c_2 * GLOBALS->time_scale; } break; case T_DUMPVARS: case T_DUMPPORTS: if(GLOBALS->current_time_vcd_partial_c_2<0) { GLOBALS->start_time_vcd_partial_c_2=GLOBALS->current_time_vcd_partial_c_2=GLOBALS->end_time_vcd_partial_c_2=0; } break; case T_VCDCLOSE: sync_end("VCDCLOSE:"); break; /* next token will be '#' time related followed by $end */ case T_END: /* either closure for dump commands or */ break; /* it's spurious */ case T_UNKNOWN_KEY: sync_end(NULL); /* skip over unknown keywords */ break; case T_EOF: if((GLOBALS->blackout_regions)&&(GLOBALS->blackout_regions->bstart>GLOBALS->blackout_regions->bend)) { GLOBALS->blackout_regions->bend = GLOBALS->current_time_vcd_partial_c_2 * GLOBALS->time_scale; } return; default: DEBUG(fprintf(stderr,"UNKNOWN TOKEN\n")); } } } /*******************************************************************************/ hptr add_histent_p(TimeType tim, struct Node *n, char ch, int regadd, char *vector) { struct HistEnt *he, *rc; char heval; if(!vector) { if(!(rc=n->curr)) { he=histent_calloc(); he->time=-1; he->v.h_val=AN_X; n->curr=he; n->head.next=he; add_histent_p(tim,n,ch,regadd, vector); rc = he; } else { if(regadd) { tim*=(GLOBALS->time_scale); } if(ch=='0') heval=AN_0; else if(ch=='1') heval=AN_1; else if((ch=='x')||(ch=='X')) heval=AN_X; else if((ch=='z')||(ch=='Z')) heval=AN_Z; else if((ch=='h')||(ch=='H')) heval=AN_H; else if((ch=='u')||(ch=='U')) heval=AN_U; else if((ch=='w')||(ch=='W')) heval=AN_W; else if((ch=='l')||(ch=='L')) heval=AN_L; else /* if(ch=='-') */ heval=AN_DASH; /* default */ if((n->curr->v.h_val!=heval)||(tim==GLOBALS->start_time_vcd_partial_c_2)||(n->vartype==ND_VCD_EVENT)||(GLOBALS->vcd_preserve_glitches)) /* same region == go skip */ { if(n->curr->time==tim) { DEBUG(printf("Warning: Glitch at time ["TTFormat"] Signal [%p], Value [%c->%c].\n", tim, n, AN_STR[n->curr->v.h_val], ch)); n->curr->v.h_val=heval; /* we have a glitch! */ GLOBALS->num_glitches_vcd_partial_c_3++; if(!(n->curr->flags&HIST_GLITCH)) { n->curr->flags|=HIST_GLITCH; /* set the glitch flag */ GLOBALS->num_glitch_regions_vcd_partial_c_3++; } } else { he=histent_calloc(); he->time=tim; he->v.h_val=heval; n->curr->next=he; n->curr=he; GLOBALS->regions+=regadd; } } } } else { switch(ch) { case 's': /* string */ { if(!(rc=n->curr)) { he=histent_calloc(); he->flags=(HIST_STRING|HIST_REAL); he->time=-1; he->v.h_vector=NULL; n->curr=he; n->head.next=he; add_histent_p(tim,n,ch,regadd, vector); rc = he; } else { if(regadd) { tim*=(GLOBALS->time_scale); } if(n->curr->time==tim) { DEBUG(printf("Warning: String Glitch at time ["TTFormat"] Signal [%p].\n", tim, n)); if(n->curr->v.h_vector) free_2(n->curr->v.h_vector); n->curr->v.h_vector=vector; /* we have a glitch! */ GLOBALS->num_glitches_vcd_partial_c_3++; if(!(n->curr->flags&HIST_GLITCH)) { n->curr->flags|=HIST_GLITCH; /* set the glitch flag */ GLOBALS->num_glitch_regions_vcd_partial_c_3++; } } else { he=histent_calloc(); he->flags=(HIST_STRING|HIST_REAL); he->time=tim; he->v.h_vector=vector; n->curr->next=he; n->curr=he; GLOBALS->regions+=regadd; } } break; } case 'g': /* real number */ { if(!(rc=n->curr)) { he=histent_calloc(); he->flags=HIST_REAL; he->time=-1; #ifdef WAVE_HAS_H_DOUBLE he->v.h_double = strtod("NaN", NULL); #else he->v.h_vector=NULL; #endif n->curr=he; n->head.next=he; add_histent_p(tim,n,ch,regadd, vector); rc = he; } else { if(regadd) { tim*=(GLOBALS->time_scale); } if( #ifdef WAVE_HAS_H_DOUBLE (vector&&(n->curr->v.h_double!=*(double *)vector)) #else (n->curr->v.h_vector&&vector&&(*(double *)n->curr->v.h_vector!=*(double *)vector)) #endif ||(tim==GLOBALS->start_time_vcd_partial_c_2) #ifndef WAVE_HAS_H_DOUBLE ||(!n->curr->v.h_vector) #endif ||(GLOBALS->vcd_preserve_glitches)||(GLOBALS->vcd_preserve_glitches_real) ) /* same region == go skip */ { if(n->curr->time==tim) { DEBUG(printf("Warning: Real number Glitch at time ["TTFormat"] Signal [%p].\n", tim, n)); #ifdef WAVE_HAS_H_DOUBLE n->curr->v.h_double = *((double *)vector); #else if(n->curr->v.h_vector) free_2(n->curr->v.h_vector); n->curr->v.h_vector=vector; /* we have a glitch! */ #endif GLOBALS->num_glitches_vcd_partial_c_3++; if(!(n->curr->flags&HIST_GLITCH)) { n->curr->flags|=HIST_GLITCH; /* set the glitch flag */ GLOBALS->num_glitch_regions_vcd_partial_c_3++; } } else { he=histent_calloc(); he->flags=HIST_REAL; he->time=tim; #ifdef WAVE_HAS_H_DOUBLE he->v.h_double = *((double *)vector); #else he->v.h_vector=vector; #endif n->curr->next=he; n->curr=he; GLOBALS->regions+=regadd; } } else { #ifndef WAVE_HAS_H_DOUBLE free_2(vector); #endif } #ifdef WAVE_HAS_H_DOUBLE free_2(vector); #endif } break; } default: { if(!(rc=n->curr)) { he=histent_calloc(); he->time=-1; he->v.h_vector=NULL; n->curr=he; n->head.next=he; add_histent_p(tim,n,ch,regadd, vector); rc = he; } else { if(regadd) { tim*=(GLOBALS->time_scale); } if( (n->curr->v.h_vector&&vector&&(strcmp(n->curr->v.h_vector,vector))) ||(tim==GLOBALS->start_time_vcd_partial_c_2) ||(!n->curr->v.h_vector) ||(GLOBALS->vcd_preserve_glitches) ) /* same region == go skip */ { if(n->curr->time==tim) { DEBUG(printf("Warning: Glitch at time ["TTFormat"] Signal [%p], Value [%c->%c].\n", tim, n, AN_STR[n->curr->v.h_val], ch)); if(n->curr->v.h_vector) free_2(n->curr->v.h_vector); n->curr->v.h_vector=vector; /* we have a glitch! */ GLOBALS->num_glitches_vcd_partial_c_3++; if(!(n->curr->flags&HIST_GLITCH)) { n->curr->flags|=HIST_GLITCH; /* set the glitch flag */ GLOBALS->num_glitch_regions_vcd_partial_c_3++; } } else { he=histent_calloc(); he->time=tim; he->v.h_vector=vector; n->curr->next=he; n->curr=he; GLOBALS->regions+=regadd; } } else { free_2(vector); } } break; } } } return(rc); } static void add_tail_histents(void) { int j; struct vcdsymbol *v; hptr rc; /* do 'x' trailers */ v=GLOBALS->vcdsymroot_vcd_partial_c_2; while(v) { if((v->vartype==V_REAL)||(v->vartype==V_STRINGTYPE)) { double *d; d=malloc_2(sizeof(double)); *d=1.0; rc = add_histent_p(MAX_HISTENT_TIME-1, v->narray[0], 'g', 0, (char *)d); set_vcd_vartype(v, v->narray[0]); v->app_array[0] = rc; v->tr_array[0] = v->narray[0]->curr; } else if((v->size==1)||(!GLOBALS->atomic_vectors)) for(j=0;jsize;j++) { rc = add_histent_p(MAX_HISTENT_TIME-1, v->narray[j], 'x', 0, NULL); set_vcd_vartype(v, v->narray[j]); v->app_array[j] = rc; v->tr_array[j] = v->narray[j]->curr; } else { rc = add_histent_p(MAX_HISTENT_TIME-1, v->narray[0], 'x', 0, (char *)calloc_2(1,sizeof(char))); set_vcd_vartype(v, v->narray[0]); v->app_array[0] = rc; v->tr_array[0] = v->narray[0]->curr; } v=v->next; } v=GLOBALS->vcdsymroot_vcd_partial_c_2; while(v) { if((v->vartype==V_REAL)||(v->vartype==V_STRINGTYPE)) { double *d; d=malloc_2(sizeof(double)); *d=0.0; add_histent_p(MAX_HISTENT_TIME, v->narray[0], 'g', 0, (char *)d); } else if((v->size==1)||(!GLOBALS->atomic_vectors)) for(j=0;jsize;j++) { add_histent_p(MAX_HISTENT_TIME, v->narray[j], 'z', 0, NULL); } else { add_histent_p(MAX_HISTENT_TIME, v->narray[0], 'z', 0, (char *)calloc_2(1,sizeof(char))); } v=v->next; } } /*******************************************************************************/ static void vcd_build_symbols(void) { int j; int max_slen=-1; struct sym_chain *sym_chain=NULL, *sym_curr=NULL; int duphier=0; char hashdirty; struct vcdsymbol *v, *vprime; char *str = wave_alloca(1); /* quiet scan-build null pointer warning below */ #ifdef _WAVE_HAVE_JUDY int ss_len, longest = 0; #endif v=GLOBALS->vcdsymroot_vcd_partial_c_2; while(v) { int msi; int delta; { int slen; int substnode; msi=v->msi; delta=((v->lsi-v->msi)<0)?-1:1; substnode=0; slen=strlen(v->name); str=(slen>max_slen)?(wave_alloca((max_slen=slen)+32)):(str); /* more than enough */ strcpy(str,v->name); if(v->msi>=0) { strcpy(str+slen,GLOBALS->vcd_hier_delimeter); slen++; } if((vprime=bsearch_vcd(v->id, strlen(v->id)))!=v) /* hash mish means dup net */ { if(v->size!=vprime->size) { fprintf(stderr,"ERROR: Duplicate IDs with differing width: %s %s\n", v->name, vprime->name); } else { substnode=1; } } if(((v->size==1)||(!GLOBALS->atomic_vectors))&&(v->vartype!=V_REAL)&&(v->vartype!=V_STRINGTYPE)) { struct symbol *s = NULL; for(j=0;jsize;j++) { if(v->msi>=0) { if(!GLOBALS->vcd_explicit_zero_subscripts) sprintf(str+slen,"%d",msi); else sprintf(str+slen-1,"[%d]",msi); } hashdirty=0; if(symfind(str, NULL)) { char *dupfix=(char *)malloc_2(max_slen+32); #ifndef _WAVE_HAVE_JUDY hashdirty=1; #endif DEBUG(fprintf(stderr,"Warning: %s is a duplicate net name.\n",str)); do sprintf(dupfix, "$DUP%d%s%s", duphier++, GLOBALS->vcd_hier_delimeter, str); while(symfind(dupfix, NULL)); strcpy(str, dupfix); free_2(dupfix); duphier=0; /* reset for next duplicate resolution */ } /* fallthrough */ { s=symadd(str,hashdirty?hash(str):GLOBALS->hashcache); #ifdef _WAVE_HAVE_JUDY ss_len = strlen(str); if(ss_len >= longest) { longest = ss_len + 1; } #endif s->n=v->narray[j]; if(substnode) { struct Node *n, *n2; n=s->n; n2=vprime->narray[j]; /* nname stays same */ n->head=n2->head; n->curr=n2->curr; /* harray calculated later */ n->numhist=n2->numhist; } #ifndef _WAVE_HAVE_JUDY s->n->nname=s->name; #endif if(!GLOBALS->firstnode) { GLOBALS->firstnode= GLOBALS->curnode=calloc_2(1, sizeof(struct symchain)); } else { GLOBALS->curnode->next=calloc_2(1, sizeof(struct symchain)); GLOBALS->curnode=GLOBALS->curnode->next; } GLOBALS->curnode->symbol=s; GLOBALS->numfacs++; DEBUG(fprintf(stderr,"Added: %s\n",str)); } msi+=delta; } if((j==1)&&(v->root)) { s->vec_root=(struct symbol *)v->root; /* these will get patched over */ s->vec_chain=(struct symbol *)v->chain; /* these will get patched over */ v->sym_chain=s; if(!sym_chain) { sym_curr=(struct sym_chain *)calloc_2(1,sizeof(struct sym_chain)); sym_chain=sym_curr; } else { sym_curr->next=(struct sym_chain *)calloc_2(1,sizeof(struct sym_chain)); sym_curr=sym_curr->next; } sym_curr->val=s; } } else /* atomic vector */ { if((v->vartype!=V_REAL)&&(v->vartype!=V_STRINGTYPE)&&(v->vartype!=V_INTEGER)&&(v->vartype!=V_PARAMETER)) /* if((v->vartype!=V_REAL)&&(v->vartype!=V_STRINGTYPE)) */ { sprintf(str+slen-1,"[%d:%d]",v->msi,v->lsi); } else { *(str+slen-1)=0; } hashdirty=0; if(symfind(str, NULL)) { char *dupfix=(char *)malloc_2(max_slen+32); #ifndef _WAVE_HAVE_JUDY hashdirty=1; #endif DEBUG(fprintf(stderr,"Warning: %s is a duplicate net name.\n",str)); do sprintf(dupfix, "$DUP%d%s%s", duphier++, GLOBALS->vcd_hier_delimeter, str); while(symfind(dupfix, NULL)); strcpy(str, dupfix); free_2(dupfix); duphier=0; /* reset for next duplicate resolution */ } /* fallthrough */ { struct symbol *s; s=symadd(str,hashdirty?hash(str):GLOBALS->hashcache); /* cut down on double lookups.. */ #ifdef _WAVE_HAVE_JUDY ss_len = strlen(str); if(ss_len >= longest) { longest = ss_len + 1; } #endif s->n=v->narray[0]; if(substnode) { struct Node *n, *n2; n=s->n; n2=vprime->narray[0]; /* nname stays same */ n->head=n2->head; n->curr=n2->curr; /* harray calculated later */ n->numhist=n2->numhist; n->extvals=n2->extvals; n->msi=n2->msi; n->lsi=n2->lsi; } else { s->n->msi=v->msi; s->n->lsi=v->lsi; s->n->extvals=1; } #ifndef _WAVE_HAVE_JUDY s->n->nname=s->name; #endif if(!GLOBALS->firstnode) { GLOBALS->firstnode= GLOBALS->curnode=calloc_2(1, sizeof(struct symchain)); } else { GLOBALS->curnode->next=calloc_2(1, sizeof(struct symchain)); GLOBALS->curnode=GLOBALS->curnode->next; } GLOBALS->curnode->symbol=s; GLOBALS->numfacs++; DEBUG(fprintf(stderr,"Added: %s\n",str)); } } } v=v->next; } #ifdef _WAVE_HAVE_JUDY { Pvoid_t PJArray = GLOBALS->sym_judy; PPvoid_t PPValue; char *Index = calloc_2(1, longest); for (PPValue = JudySLFirst (PJArray, (uint8_t *)Index, PJE0); PPValue != (PPvoid_t) NULL; PPValue = JudySLNext (PJArray, (uint8_t *)Index, PJE0)) { struct symbol *s = *(struct symbol **)PPValue; s->name = strdup_2(Index); s->n->nname = s->name; } free_2(Index); } #endif if(sym_chain) { sym_curr=sym_chain; while(sym_curr) { sym_curr->val->vec_root= ((struct vcdsymbol *)sym_curr->val->vec_root)->sym_chain; if ((struct vcdsymbol *)sym_curr->val->vec_chain) sym_curr->val->vec_chain=((struct vcdsymbol *)sym_curr->val->vec_chain)->sym_chain; DEBUG(printf("Link: ('%s') '%s' -> '%s'\n",sym_curr->val->vec_root->name, sym_curr->val->name, sym_curr->val->vec_chain?sym_curr->val->vec_chain->name:"(END)")); sym_chain=sym_curr; sym_curr=sym_curr->next; free_2(sym_chain); } } } /*******************************************************************************/ static void vcd_cleanup(void) { struct slist *s, *s2; if(GLOBALS->slisthier) { free_2(GLOBALS->slisthier); GLOBALS->slisthier=NULL; } s=GLOBALS->slistroot; while(s) { s2=s->next; if(s->str)free_2(s->str); free_2(s); s=s2; } GLOBALS->slistroot=GLOBALS->slistcurr=NULL; GLOBALS->slisthier_len=0; } /*******************************************************************************/ TimeType vcd_partial_main(char *fname) { unsigned int shmidu = ~(0L); int shmid; GLOBALS->pv_vcd_partial_c_2=GLOBALS->rootv_vcd_partial_c_2=NULL; GLOBALS->vcd_hier_delimeter[0]=GLOBALS->hier_delimeter; errno=0; /* reset in case it's set for some reason */ GLOBALS->yytext_vcd_partial_c_2=(char *)malloc_2(GLOBALS->T_MAX_STR_vcd_partial_c_2+1); if(!GLOBALS->hier_was_explicitly_set) /* set default hierarchy split char */ { GLOBALS->hier_delimeter='.'; } #ifdef __MINGW32__ if(GetEnvironmentVariable("SHMID", NULL, 0)) { char sEnv[128]; GetEnvironmentVariable("SHMID", sEnv, 128); sscanf(sEnv, "%x", &shmidu); } else #endif { if(!strcmp(fname, "-vcd")) { if(!fscanf(stdin, "%x", &shmidu)) shmidu = ~(0L); /* allow use of -v flag to pass straight from stdin */ } else { sscanf(fname, "%x", &shmidu); /* passed as a filename */ } } shmid = (int)shmidu; #if !defined _MSC_VER #ifdef __MINGW32__ { HANDLE hMapFile; char mapName[257]; sprintf(mapName, "shmidcat%d", shmid); hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, mapName); if(hMapFile == NULL) { fprintf(stderr, "Could not attach shared memory map name '%s', exiting.\n", mapName); exit(255); } GLOBALS->consume_ptr_vcd_partial_c_1 = GLOBALS->buf_vcd_partial_c_2 = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, WAVE_PARTIAL_VCD_RING_BUFFER_SIZE); if(GLOBALS->consume_ptr_vcd_partial_c_1 == NULL) { fprintf(stderr, "Could not map view of file '%s', exiting.\n", mapName); exit(255); } } #else errno = 0; GLOBALS->consume_ptr_vcd_partial_c_1 = GLOBALS->buf_vcd_partial_c_2 = shmat(shmid, NULL, 0); if(errno) { fprintf(stderr, "Could not attach shared memory ID %08x\n", shmid); perror("Why"); exit(255); } #endif #else fprintf(stderr, "Interactive VCD mode does not work with Windows, exiting.\n"); exit(255); #endif sym_hash_initialize(GLOBALS); getch_alloc(); /* alloc membuff for vcd getch buffer */ build_slisthier(); GLOBALS->vcd_preserve_glitches = 1; /* splicing dictates that we override */ while(!GLOBALS->header_over_vcd_partial_c_2) { vcd_parse(); } if(GLOBALS->varsplit_vcd_partial_c_2) { free_2(GLOBALS->varsplit_vcd_partial_c_2); GLOBALS->varsplit_vcd_partial_c_2=NULL; } if((!GLOBALS->sorted_vcd_partial_c_2)&&(!GLOBALS->indexed_vcd_partial_c_2)) { fprintf(stderr, "No symbols in VCD file..is it malformed? Exiting!\n"); exit(1); } add_tail_histents(); vcd_build_symbols(); vcd_sortfacs(); vcd_cleanup(); GLOBALS->min_time=GLOBALS->start_time_vcd_partial_c_2*GLOBALS->time_scale; GLOBALS->max_time=GLOBALS->end_time_vcd_partial_c_2*GLOBALS->time_scale; GLOBALS->global_time_offset = GLOBALS->global_time_offset * GLOBALS->time_scale; if((GLOBALS->min_time==GLOBALS->max_time)||(GLOBALS->max_time==0)) { GLOBALS->min_time = GLOBALS->max_time = 0; } GLOBALS->is_vcd=~0; GLOBALS->partial_vcd = ~0; #ifdef __linux__ { struct shmid_ds ds; shmctl(shmid, IPC_RMID, &ds); /* mark for destroy */ } #endif return(GLOBALS->max_time); } /*******************************************************************************/ static void regen_harray(Trptr t, nptr nd) { int i, histcount; hptr histpnt; hptr *harray; if(!nd->harray) /* make quick array lookup for aet display */ { histpnt=&(nd->head); histcount=0; while(histpnt) { histcount++; histpnt=histpnt->next; } nd->numhist=histcount; if(!(nd->harray=harray=(hptr *)malloc_2(histcount*sizeof(hptr)))) { fprintf( stderr, "Out of memory, can't add %s to analyzer\n", nd->nname ); free_2(t); return; /* scan-build : really can't do anything here */ } histpnt=&(nd->head); for(i=0;inname, (*harray)->time, (*harray)->val); */ harray++; histpnt=histpnt->next; } } } /* mark vectors that need to be regenerated */ static void regen_trace_mark(Trptr t, int mandclear) { if(t->vector) { bvptr b = t->n.vec; bptr bts = b->bits; int i; if(1) { for(i=0;innbits;i++) { if(!bts->nodes[i]->expansion) { if(bts->nodes[i]->harray) { free_2(bts->nodes[i]->harray); bts->nodes[i]->harray = NULL; } } else { t->interactive_vector_needs_regeneration = 1; } } } for(i=0;innbits;i++) { if(!bts->nodes[i]->harray) { t->interactive_vector_needs_regeneration = 1; return; } } } else { if(t->n.nd) /* comment and blank traces don't have a valid node */ if((t->n.nd->harray) && (mandclear)) { free_2(t->n.nd->harray); t->n.nd->harray = NULL; } } } /* sweep through and regen nodes/dirty vectors */ static void regen_trace_sweep(Trptr t) { if(!t->vector) { if(t->n.nd) /* comment and blank traces don't have a valid node */ if(!t->n.nd->harray) { regen_harray(t, t->n.nd); } } else if(t->interactive_vector_needs_regeneration) { bvptr b = t->n.vec; bptr bts = b->bits; int i; bvptr b2; for(i=0;innbits;i++) { if(bts->nodes[i]->expansion) { nptr parent = bts->nodes[i]->expansion->parent; int parentbit = bts->nodes[i]->expansion->parentbit; DeleteNode(bts->nodes[i]); bts->nodes[i] = ExtractNodeSingleBit(parent, parentbit); } if(!bts->nodes[i]->harray) { regen_harray(t, bts->nodes[i]); } } if(!bts->name) { bts->name = ""; b2 = bits2vector(bts); bts->name = NULL; } else { b2 = bits2vector(bts); } t->n.vec = b2; b2->bits=bts; free_2(b2->bvname); b2->bvname = b->bvname; for(i=0;inumregions;i++) { free_2(b->vectors[i]); } free_2(b); } } /*******************************************************************************/ void kick_partial_vcd(void) { #if !defined _MSC_VER if(GLOBALS->partial_vcd) { #ifdef __MINGW32__ Sleep(10); #else struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 1000000 / 100; select(0, NULL, NULL, NULL, &tv); #endif while(*GLOBALS->consume_ptr_vcd_partial_c_1) { int old_maxtime_marker_conflict = (GLOBALS->tims.marker > GLOBALS->max_time); vcd_parse(); GLOBALS->min_time=GLOBALS->start_time_vcd_partial_c_2*GLOBALS->time_scale; GLOBALS->max_time=GLOBALS->end_time_vcd_partial_c_2*GLOBALS->time_scale; GLOBALS->tims.last=GLOBALS->max_time; GLOBALS->tims.end=GLOBALS->tims.last; /* until the configure_event of wavearea */ if(!GLOBALS->timeset_vcd_partial_c_1) { GLOBALS->tims.first=GLOBALS->tims.start=GLOBALS->tims.laststart=GLOBALS->min_time; GLOBALS->timeset_vcd_partial_c_1 = 1; } update_endcap_times_for_partial_vcd(); update_maxmarker_labels(); if(old_maxtime_marker_conflict) { old_maxtime_marker_conflict = (GLOBALS->tims.marker<=GLOBALS->max_time); /* data is now past what was invisible marker */ } vcd_partial_mark_and_sweep(1); if ((GLOBALS->zoom_dyn) && (!GLOBALS->helpbox_is_active)) { GLOBALS->tims.marker = GLOBALS->tims.last; service_zoom_full(NULL, NULL); GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); } else if ((GLOBALS->zoom_dyne) && (!GLOBALS->helpbox_is_active)) { GLOBALS->tims.marker = GLOBALS->tims.last; service_zoom_right(NULL, NULL); GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); } else if ((old_maxtime_marker_conflict) && (!GLOBALS->helpbox_is_active)) { GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } else { signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } update_maxmarker_labels(); gtkwave_main_iteration(); } } #endif gtkwave_main_iteration(); } static void vcd_partial_regen_node_expansion(Trptr t) { if(!t->vector) { if(t->n.nd && t->n.nd->expansion) { nptr np_ex = ExtractNodeSingleBit(t->n.nd->expansion->parent, t->n.nd->expansion->parentbit); DeleteNode(t->n.nd); t->n.nd = np_ex; t->name_full = np_ex->nname; t->name = (GLOBALS->hier_max_level) ? hier_extract(t->name_full, GLOBALS->hier_max_level) : t->name_full; } } } void vcd_partial_mark_and_sweep(int mandclear) { Trptr t; /* node */ t = GLOBALS->traces.first; while(t) { if(!t->vector) regen_trace_mark(t, mandclear); t = t->t_next; } t = GLOBALS->traces.buffer; while(t) { if(!t->vector) regen_trace_mark(t, mandclear); t = t->t_next; } t = GLOBALS->traces.first; while(t) { if(!t->vector) regen_trace_sweep(t); t = t->t_next; } t = GLOBALS->traces.buffer; while(t) { if(!t->vector) regen_trace_sweep(t); t = t->t_next; } /* node that is single bit extracted */ t = GLOBALS->traces.first; while(t) { vcd_partial_regen_node_expansion(t); t = t->t_next; } t = GLOBALS->traces.buffer; while(t) { vcd_partial_regen_node_expansion(t); t = t->t_next; } /* vector */ t = GLOBALS->traces.first; while(t) { if(t->vector) regen_trace_mark(t, mandclear); t = t->t_next; } t = GLOBALS->traces.buffer; while(t) { if(t->vector) regen_trace_mark(t, mandclear); t = t->t_next; } t = GLOBALS->traces.first; while(t) { if(t->vector) regen_trace_sweep(t); t = t->t_next; } t = GLOBALS->traces.buffer; while(t) { if(t->vector) regen_trace_sweep(t); t = t->t_next; } /* floating point */ t = GLOBALS->traces.first; while(t) { if(t->minmax_valid) t->minmax_valid = 0; t = t->t_next; } t = GLOBALS->traces.buffer; while(t) { if(t->minmax_valid) t->minmax_valid = 0; t = t->t_next; } } gtkwave-3.3.66/src/helpers/0000775000076400007640000000000012546303362015034 5ustar bybellbybellgtkwave-3.3.66/src/helpers/vcd2fst.c0000664000076400007640000011032612527430212016550 0ustar bybellbybell/* * Copyright (c) 2009-2014 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #if HAVE_GETOPT_H #include #endif #include "fst/fstapi.h" #include "../../contrib/rtlbrowse/jrb.h" #include "wave_locale.h" #ifdef EXTLOAD_SUFFIX #ifdef EXTCONV_PATH #define VCD2FST_EXTLOAD_CONV #endif #endif #ifdef EXT2LOAD_SUFFIX #ifdef EXT2CONV_PATH #define VCD2FST_EXT2LOAD_CONV #endif #endif #ifdef EXT3LOAD_SUFFIX #ifdef EXT3CONV_PATH #define VCD2FST_EXT3LOAD_CONV #endif #endif #if defined(VCD2FST_EXTLOAD_CONV) || defined(VCD2FST_EXT2LOAD_CONV) || defined(VCD2FST_EXT3LOAD_CONV) #define VCD2FST_EXTLOADERS_CONV #endif static uint32_t var_direction_idx = 0; static unsigned char *var_direction = NULL; static void *realloc_2(void *ptr, size_t siz) /* cppcheck */ { void *pnt = realloc(ptr, siz); if(!pnt) { fprintf(stderr, "ERROR: Out of memory in realloc(), exiting!\n"); /* normally free(ptr) here */ exit(255); } return(pnt); } /*********************************************************/ /*** vvv extload component type name determination vvv ***/ /*********************************************************/ #if defined(VCD2FST_EXTLOAD_CONV) #ifdef _WAVE_HAVE_JUDY #include Pvoid_t PJArray = NULL; #else JRB comp_name_jrb = NULL; #endif static const char *fst_scope_name = NULL; static uint32_t numfacs = 0; static char *get_info(FILE *extload) { static char sbuff[65537]; char * rc; for(;;) { rc = fgets(sbuff, 65536, extload); if(!rc) { return(NULL); } switch(rc[0]) { case 'v': if(!strncmp("var creation cnt", rc, 16)) { char *pnt = strchr(rc+16, ':'); if(pnt) { pnt++; sscanf(pnt, "%u", &numfacs); } } break; default: break; } } } static char *get_scopename(void *xc, FILE *extload) { static char sbuff[65537]; char * rc; #ifdef _WAVE_HAVE_JUDY PPvoid_t PPValue; #else JRB str; Jval jv; #endif for(;;) { rc = fgets(sbuff, 65536, extload); if(rc) { if(isspace(rc[0])) { char sbuff2[65537]; sbuff2[0] = 0; if(strstr(rc+1, "Struct Name:")) { sscanf(rc+14,"%s", sbuff2); if(sbuff2[0]) { sprintf(rc, "Scope: vcd_struct %s NULL\n", sbuff2); } } else if(strstr(rc+1, "Struct End")) { sprintf(rc, "Upscope:\n"); } } } else { return(NULL); } if(rc[0] == 'V') { if(!strncmp("Var: ", rc, 5)) { char *pnt = rc + 5; char *pntd = strrchr(pnt, ':'); if(pntd) { unsigned char vd = FST_VD_IMPLICIT; pntd = strchr(pntd, ' '); if(pntd) { pntd++; if(*pntd == 'o') { vd = FST_VD_OUTPUT; } else if(!strncmp(pntd, "in", 2)) { vd = (pntd[2] == 'p') ? FST_VD_INPUT : FST_VD_INOUT; } } var_direction[var_direction_idx++] = vd; } } } else if(rc[0] == 'S') { if(!strncmp(rc, "Scope:", 6)) { char vht[2048]; char cname[2048]; char ctype[2048]; int mtype = FST_ST_VCD_MODULE; cname[0] = ctype[1] = 0; sscanf(rc+6, "%s %s %s", vht, cname, ctype+1); if(!strncmp("vcd_", vht, 4)) { switch(vht[4]) { case 'g': mtype = FST_ST_VCD_GENERATE; break; /* other code looks for non-modules to replace type with */ case 's': mtype = FST_ST_VCD_STRUCT; break; /* other code looks for non-modules to replace type with */ default: break; } } else if(!strncmp("sv_", vht, 3)) { switch(vht[3]) { case 'i': mtype = FST_ST_VCD_INTERFACE; break; /* other code looks for non-modules to replace type with */ default: break; } } else if(!strncmp(vht, "vhdl_", 5)) { switch(vht[5]) { case 'a': mtype = FST_ST_VHDL_ARCHITECTURE; break; case 'r': mtype = FST_ST_VHDL_RECORD; break; case 'b': mtype = FST_ST_VHDL_BLOCK; break; case 'g': mtype = FST_ST_VHDL_GENERATE; break; case 'i': mtype = FST_ST_VHDL_IF_GENERATE; break; case 'f': mtype = (vht[6] == 'u') ? FST_ST_VHDL_FUNCTION : FST_ST_VHDL_FOR_GENERATE; break; case 'p': mtype = (!strncmp(vht+6, "roces", 5)) ? FST_ST_VHDL_PROCESS: FST_ST_VHDL_PROCEDURE; break; default: break; } } ctype[0] = mtype + 1; /* bias for zero terminated string */ fst_scope_name = fstReaderPushScope(xc, cname, NULL); /* process fst_scope_name + cname vs ctype here */ if((strcmp(ctype+1, "NULL") && strcmp(cname, ctype+1)) || (mtype != FST_ST_VCD_MODULE)) { #ifdef _WAVE_HAVE_JUDY PPValue = JudySLIns(&PJArray, (uint8_t *)fst_scope_name, PJE0); if(!*((char **)PPValue)) { *((char **)PPValue) = strdup(ctype); } #else char cstring[65537]; strcpy(cstring, fst_scope_name); str = jrb_find_str(comp_name_jrb, cstring); if(!str) { jv.s = strdup(ctype); jrb_insert_str(comp_name_jrb, strdup(cstring), jv); } #endif } } } else if(rc[0] == 'U') { fst_scope_name = fstReaderPopScope(xc); } } return(rc); } static void iter_scope(char *fname) { char sbuff[65537]; FILE *extload; void *xc = fstReaderOpenForUtilitiesOnly(); sprintf(sbuff, "%s -info %s 2>&1", EXTLOAD_PATH, fname); extload = popen(sbuff, "r"); if(extload) { while(get_info(extload)); pclose(extload); } if(numfacs) { var_direction = calloc(numfacs, sizeof(unsigned char)); var_direction_idx = 0; } sprintf(sbuff, "%s -tree %s 2>&1", EXTLOAD_PATH, fname); extload = popen(sbuff, "r"); if(extload) { while(get_scopename(xc, extload)); pclose(extload); } var_direction_idx = 0; fstReaderClose(xc); /* corresponds to fstReaderOpenForUtilitiesOnly() */ } static void dealloc_scope(void) { #ifdef _WAVE_HAVE_JUDY PPvoid_t PPValue; if(PJArray) { char Index[65537]; Index[0] = 0; for (PPValue = JudySLFirst (PJArray, (uint8_t *)Index, PJE0); PPValue != (PPvoid_t) NULL; PPValue = JudySLNext (PJArray, (uint8_t *)Index, PJE0)) { free(*(char **)PPValue); } JudySLFreeArray(&PJArray, PJE0); PJArray = NULL; } #else if(comp_name_jrb) { JRB node; char *Index; jrb_traverse(node, comp_name_jrb) { Index = node->key.s; free(Index); Index = node->val.s; free(Index); } jrb_free_tree(comp_name_jrb); comp_name_jrb = NULL; } #endif } #endif /*********************************************************/ /*** ^^^ extload component type name determination ^^^ ***/ /*********************************************************/ static uint64_t atoi_2(const unsigned char *s) { uint64_t res = 0; unsigned char ch; ch = *s - '0'; while(*s && (ch > 9)) { s++; ch = *s - '0'; } while(ch < 10) { s++; res *= 10; res += ch; ch = *s - '0'; } return(res); } static inline int getline_replace(char **wbuf, char **buf, size_t *len, FILE *f) { char *fgets_rc; if(!*wbuf) { *len = 32767; *wbuf = malloc((*len) + 1); (*wbuf)[*len] = 1; } (*wbuf)[0] = 0; fgets_rc = fgets(*wbuf, (*len) + 1, f); while(((*wbuf)[*len] != 1) && !feof(f)) { /* fprintf(stderr, "overflow %d\n", (int)(*len)); */ *wbuf = realloc_2(*wbuf, (*len) * 2 + 1); (*wbuf)[(*len) * 2] = 1; fgets_rc = fgets(*wbuf + (*len), (*len) + 1, f); *len = 2 * (*len); } *buf = *wbuf; while(*(buf)[0]==' ') { (*buf)++; } /* verilator leading spaces fix */ if((!(*buf)[0])||(!fgets_rc)) { return(0); } else { return(1); } } JRB vcd_ids = NULL; static unsigned int vcdid_hash(char *s, int len) { unsigned int val=0; int i; s += len; for(i=0;i=sfxlen)&&(!strcasecmp(s+strlen(s)-sfxlen,sfx))); } #endif int fst_main(char *vname, char *fstname) { FILE *f; char *buf = NULL, *wbuf = NULL; size_t glen = 0; void *ctx; int line = 0; int ss; fstHandle returnedhandle; JRB node; uint64_t prev_tim = 0; ssize_t bin_fixbuff_len = 65537; char *bin_fixbuff = NULL; int hash_kill = 0; unsigned int hash_max = 0; int *node_len_array = NULL; int is_popen = 0; #ifdef VCD2FST_EXTLOAD_CONV int is_extload = 0; void *xc = NULL; #endif int port_encountered = 0; bin_fixbuff = malloc(bin_fixbuff_len); if(!strcmp("-", vname)) { f = stdin; } else { #ifdef VCD2FST_EXTLOAD_CONV if(suffix_check(vname, "."EXTLOAD_SUFFIX)) { sprintf(bin_fixbuff, EXTCONV_PATH" %s", vname); f = popen(bin_fixbuff, "r"); is_popen = 1; is_extload = 1; #ifndef _WAVE_HAVE_JUDY comp_name_jrb = make_jrb(); #endif iter_scope(vname); } else #endif { #ifdef VCD2FST_EXT2LOAD_CONV if(suffix_check(vname, "."EXT2LOAD_SUFFIX)) { sprintf(bin_fixbuff, EXT2CONV_PATH" %s", vname); f = popen(bin_fixbuff, "r"); is_popen = 1; } else #endif #ifdef VCD2FST_EXT3LOAD_CONV if(suffix_check(vname, "."EXT3LOAD_SUFFIX)) { sprintf(bin_fixbuff, EXT3CONV_PATH" %s", vname); f = popen(bin_fixbuff, "r"); is_popen = 1; } else #endif { f = fopen(vname, "rb"); } } } if(!f) { printf("Could not open '%s', exiting.\n", vname); free(bin_fixbuff); bin_fixbuff = NULL; free(vname); free(fstname); exit(255); } ctx = fstWriterCreate(fstname, 1); if(!ctx) { printf("Could not open '%s', exiting.\n", fstname); free(bin_fixbuff); bin_fixbuff = NULL; free(vname); free(fstname); fclose(f); exit(255); } #if defined(VCD2FST_EXTLOAD_CONV) if(is_popen && is_extload) { xc = fstReaderOpenForUtilitiesOnly(); } #endif vcd_ids = make_jrb(); fstWriterSetPackType(ctx, pack_type); fstWriterSetRepackOnClose(ctx, repack_all); fstWriterSetParallelMode(ctx, parallel_mode); while(!feof(f)) { char *buf1; ss = getline_replace(&wbuf, &buf, &glen, f); if(!ss) { break; } line++; if(buf[0] != '$') continue; buf1 = buf + 1; if(!strncmp(buf1, "var", 3)) { char *st = strtok(buf+5, " \t"); enum fstVarType vartype; int len; char *nam; unsigned int hash; if(!st) { continue; /* variable declaration not on a single line */ } vartype = FST_VT_VCD_WIRE; switch(st[0]) { case 'w': if(!strcmp(st, "wire")) { } else if(!strcmp(st, "wand")) { vartype = FST_VT_VCD_WAND; } else if(!strcmp(st, "wor")) { vartype = FST_VT_VCD_WOR; } break; case 'r': if(!strcmp(st, "reg")) { vartype = FST_VT_VCD_REG; } else if(!strcmp(st, "real")) { vartype = FST_VT_VCD_REAL; } else if(!strcmp(st, "real_parameter")) { vartype = FST_VT_VCD_REAL_PARAMETER; } else if(!strcmp(st, "realtime")) { vartype = FST_VT_VCD_REALTIME; } break; case 'p': if(!strcmp(st, "parameter")) { vartype = FST_VT_VCD_PARAMETER; } else if(!strcmp(st, "port")) { vartype = FST_VT_VCD_PORT; port_encountered = 1; } break; case 'i': if(!strcmp(st, "integer")) { vartype = FST_VT_VCD_INTEGER; } else if(!strcmp(st, "int")) { vartype = FST_VT_SV_INT; } break; case 'e': if(!strcmp(st, "event")) { vartype = FST_VT_VCD_EVENT; } else if(!strcmp(st, "enum")) { vartype = FST_VT_SV_ENUM; } break; case 'b': if(!strcmp(st, "bit")) { vartype = FST_VT_SV_BIT; } else if(!strcmp(st, "byte")) { vartype = FST_VT_SV_BYTE; } break; case 'l': if(!strcmp(st, "logic")) { vartype = FST_VT_SV_LOGIC; } else if(!strcmp(st, "longint")) { vartype = FST_VT_SV_LONGINT; } break; case 's': if(!strcmp(st, "supply1")) { vartype = FST_VT_VCD_SUPPLY1; } else if(!strcmp(st, "supply0")) { vartype = FST_VT_VCD_SUPPLY0; } else if(!strcmp(st, "string")) { vartype = FST_VT_GEN_STRING; } else if(!strcmp(st, "shortint")) { vartype = FST_VT_SV_SHORTINT; } else if(!strcmp(st, "shortreal")) { vartype = FST_VT_SV_SHORTREAL; } else if(!strcmp(st, "sparray")) { vartype = FST_VT_VCD_SPARRAY; } break; case 't': if(!strcmp(st, "time")) { vartype = FST_VT_VCD_TIME; } else if(!strcmp(st, "tri")) { vartype = FST_VT_VCD_TRI; } else if(!strcmp(st, "triand")) { vartype = FST_VT_VCD_TRIAND; } else if(!strcmp(st, "trior")) { vartype = FST_VT_VCD_TRIOR; } else if(!strcmp(st, "trireg")) { vartype = FST_VT_VCD_TRIREG; } else if(!strcmp(st, "tri0")) { vartype = FST_VT_VCD_TRI0; } else if(!strcmp(st, "tri1")) { vartype = FST_VT_VCD_TRI1; } break; default: break; } st = strtok(NULL, " \t"); len = atoi(st); switch(vartype) { case FST_VT_VCD_PORT: if(*st == '[') /* VCS extension, so reparse */ { int p_hi = atoi(st+1); int p_lo = p_hi; char *p_colon = strchr(st+1, ':'); if(p_colon) { p_lo = atoi(p_colon+1); } if(p_hi > p_lo) { len = p_hi - p_lo + 1; } else { len = p_lo - p_hi + 1; } } len = (len * 3) + 2; break; case FST_VT_GEN_STRING: len = 0; break; case FST_VT_VCD_EVENT: len = (len != 0) ? len : 1; break; default: if(len == 0) { len = 1; } break; } st = strtok(NULL, " \t"); /* vcdid */ hash = vcdid_hash(st, strlen(st)); if(hash == (hash_max+1)) { hash_max = hash; } else if((hash>0)&&(hash<=hash_max)) { /* general case with aliases */ } else { hash_kill = 1; } nam = strtok(NULL, " \t"); /* name */ st = strtok(NULL, " \t"); /* $end */ if(st) { if(strncmp(st, "$end", 4)) { *(st-1) = ' '; } node = jrb_find_int(vcd_ids, hash); if(!node) { Jval val; returnedhandle = fstWriterCreateVar(ctx, vartype, !var_direction ? FST_VD_IMPLICIT : var_direction[var_direction_idx++], len, nam, 0); val.i = returnedhandle; jrb_insert_int(vcd_ids, hash, val)->val2.i = len; } else { fstWriterCreateVar(ctx, vartype, !var_direction ? FST_VD_IMPLICIT : var_direction[var_direction_idx++], node->val2.i, nam, node->val.i); } #if defined(VCD2FST_EXTLOAD_CONV) if(var_direction) { if(var_direction_idx == numfacs) { free(var_direction); var_direction = NULL; } } #endif } } else if(!strncmp(buf1, "scope", 5)) { char *st = strtok(buf+6, " \t"); enum fstScopeType scopetype = FST_ST_VCD_MODULE; switch(st[0]) { case 'm': if(!strcmp(st, "module")) { } break; case 't': if(!strcmp(st, "task")) { scopetype = FST_ST_VCD_TASK; } break; case 'f': if(!strcmp(st, "function")) { scopetype = FST_ST_VCD_FUNCTION; } else if(!strcmp(st, "fork")) { scopetype = FST_ST_VCD_FORK; } break; case 'b': if(!strcmp(st, "begin")) { scopetype = FST_ST_VCD_BEGIN; } break; case 'g': if(!strcmp(st, "generate")) { scopetype = FST_ST_VCD_GENERATE; } break; case 's': if(!strcmp(st, "struct")) { scopetype = FST_ST_VCD_STRUCT; } break; case 'u': if(!strcmp(st, "union")) { scopetype = FST_ST_VCD_UNION; } break; case 'c': if(!strcmp(st, "class")) { scopetype = FST_ST_VCD_CLASS; } break; case 'i': if(!strcmp(st, "interface")) { scopetype = FST_ST_VCD_INTERFACE; } break; case 'p': if(!strcmp(st, "package")) { scopetype = FST_ST_VCD_PACKAGE; } else if(!strcmp(st, "program")) { scopetype = FST_ST_VCD_PROGRAM; } break; case 'v': if(!strcmp(st, "vhdl_architecture")) { scopetype = FST_ST_VHDL_ARCHITECTURE; } else if(!strcmp(st, "vhdl_procedure")) { scopetype = FST_ST_VHDL_PROCEDURE; } else if(!strcmp(st, "vhdl_function")) { scopetype = FST_ST_VHDL_FUNCTION; } else if(!strcmp(st, "vhdl_record")) { scopetype = FST_ST_VHDL_RECORD; } else if(!strcmp(st, "vhdl_process")) { scopetype = FST_ST_VHDL_PROCESS; } else if(!strcmp(st, "vhdl_block")) { scopetype = FST_ST_VHDL_BLOCK; } else if(!strcmp(st, "vhdl_for_generate")) { scopetype = FST_ST_VHDL_FOR_GENERATE; } else if(!strcmp(st, "vhdl_if_generate")) { scopetype = FST_ST_VHDL_IF_GENERATE; } else if(!strcmp(st, "vhdl_generate")) { scopetype = FST_ST_VHDL_GENERATE; } break; default: break; } st = strtok(NULL, " \t"); #if defined(VCD2FST_EXTLOAD_CONV) #ifdef _WAVE_HAVE_JUDY if(PJArray) { const char *fst_scope_name2 = fstReaderPushScope(xc, st, NULL); PPvoid_t PPValue = JudySLGet(PJArray, (uint8_t *)fst_scope_name2, PJE0); if(PPValue) { unsigned char st_replace = (*((unsigned char *)*PPValue)) - 1; if(st_replace != FST_ST_VCD_MODULE) { scopetype = st_replace; } if((scopetype == FST_ST_VCD_GENERATE)||(scopetype == FST_ST_VCD_STRUCT)) { PPValue = NULL; } fstWriterSetScope(ctx, scopetype, st, PPValue ? ((char *)(*PPValue)+1) : NULL); } else { fstWriterSetScope(ctx, scopetype, st, NULL); } } #else if(comp_name_jrb) { const char *fst_scope_name2 = fstReaderPushScope(xc, st, NULL); char cstring[65537]; JRB str; strcpy(cstring, fst_scope_name2); str = jrb_find_str(comp_name_jrb, cstring); if(str) { unsigned char st_replace = str->val.s[0] - 1; if(st_replace != FST_ST_VCD_MODULE) { scopetype = st_replace; } if((scopetype == FST_ST_VCD_GENERATE)||(scopetype == FST_ST_VCD_STRUCT)) { str = NULL; } fstWriterSetScope(ctx, scopetype, st, str ? (str->val.s+1) : NULL); } else { fstWriterSetScope(ctx, scopetype, st, NULL); } } #endif else #endif { fstWriterSetScope(ctx, scopetype, st, NULL); } } else if(!strncmp(buf1, "upscope", 7)) { fstWriterSetUpscope(ctx); #if defined(VCD2FST_EXTLOAD_CONV) if(xc) { fstReaderPopScope(xc); } #endif } else if(!strncmp(buf1, "endd", 4)) { #if defined(VCD2FST_EXTLOAD_CONV) #ifdef _WAVE_HAVE_JUDY if(PJArray) #else if(comp_name_jrb) #endif { dealloc_scope(); } #endif if(port_encountered && (!compression_explicitly_set) && (pack_type == FST_WR_PT_LZ4)) /* EVCD data compresses far better with fastlz, so use if not directed explicitly */ { fstWriterSetPackType(ctx, (pack_type = FST_WR_PT_FASTLZ)); } break; } else if(!strncmp(buf1, "timezero", 8)) { char *pnt; int64_t tzero = 0; if((pnt = strstr(buf, "$end"))) { *pnt = 0; sscanf(buf+10, "%"SCNd64, &tzero); } else { ss = getline_replace(&wbuf, &buf, &glen, f); if(!ss) { break; } line++; sscanf(buf, "%"SCNd64, &tzero); } fstWriterSetTimezero(ctx, tzero); } else if(!strncmp(buf1, "timescale", 9)) { char *pnt; char *num = NULL; int exp = -9; int tv = 1; if((pnt = strstr(buf, "$end"))) { *pnt = 0; num = strchr(buf, '1'); if(!num) { num = strchr(buf, '0'); /* verilator */ if(num) { *num = '1'; } } } if(!num) { ss = getline_replace(&wbuf, &buf, &glen, f); if(!ss) { break; } line++; num = buf; } pnt = num; while(*pnt) { int mat = 0; switch(*pnt) { case 'm': exp = -3; mat = 1; break; case 'u': exp = -6; mat = 1; break; case 'n': exp = -9; mat = 1; break; case 'p': exp = -12; mat = 1; break; case 'f': exp = -15; mat = 1; break; case 'a': exp = -18; mat = 1; break; case 'z': exp = -21; mat = 1; break; case 's': exp = 0; mat = 1; break; default: break; } if(mat) break; pnt++; } tv = atoi(num); if(tv == 10) { exp++; } else if(tv == 100) { exp+=2; } fstWriterSetTimescale(ctx, exp); } else if(!strncmp(buf1, "date", 4)) { char *pnt, *rsp; int found = 0; if((pnt = strstr(buf, "$end"))) { *pnt = 0; pnt = buf + 5; while(*pnt && ((*pnt)==' ')) { pnt++; } while((rsp = strrchr(pnt, ' '))) { if(*(rsp+1) == 0) { *rsp = 0; } else { break; } } if(strlen(pnt)) { found = 1; } } else { pnt = buf + 5; while(*pnt && ((*pnt)==' ')) { pnt++; } while((rsp = strrchr(pnt, ' '))) { if(*(rsp+1) == 0) { *rsp = 0; } else { break; } } if(strlen(pnt) > 3) { found = 1; } } if(!found) { ss = getline_replace(&wbuf, &buf, &glen, f); if(!ss) { break; } line++; pnt = buf; } while(*pnt == '\t') pnt++; fstWriterSetDate(ctx, pnt); } else if((!strncmp(buf1, "version", 7)) || (!strncmp(buf1, "comment", 7))) { char *pnt, *crpnt, *rsp; int is_version = (buf[1] == 'v'); if((pnt = strstr(buf, "$end"))) { *pnt = 0; pnt = buf+8; while(*pnt && ((*pnt)==' ')) { pnt++; } while((rsp = strrchr(pnt, ' '))) { if(*(rsp+1) == 0) { *rsp = 0; } else { break; } } } else { ss = getline_replace(&wbuf, &buf, &glen, f); if(!ss) { break; } line++; pnt = buf; } while(*pnt == '\t') pnt++; crpnt = strchr(pnt, '\n'); if(crpnt) *crpnt = 0; crpnt = strchr(pnt, '\r'); if(crpnt) *crpnt = 0; if(is_version) { fstWriterSetVersion(ctx, pnt); } else { fstWriterSetComment(ctx, pnt); } } } if((!hash_kill) && (vcd_ids)) { unsigned int hash; node_len_array = calloc(hash_max + 1, sizeof(int)); for(hash=1;hash<=hash_max;hash++) { node = jrb_find_int(vcd_ids, hash); if(node) { node_len_array[hash] = node->val2.i; } else { node_len_array[hash] = 1; /* should never happen */ } } jrb_free_tree(vcd_ids); vcd_ids = NULL; } else { hash_kill = 1; /* scan-build */ } for(;;) /* was while(!feof(f)) */ { unsigned int hash; uint64_t tim; char *nl, *sp; double doub; ss = getline_replace(&wbuf, &buf, &glen, f); if(!ss) { break; } nl = buf; while(*nl) { if((*nl == '\n') || (*nl == '\r')) { *nl = 0; break; } nl++; } switch(buf[0]) { case '0': case '1': case 'x': case 'z': hash = vcdid_hash(buf+1, nl - (buf+1)); if(!hash_kill) { fstWriterEmitValueChange(ctx, hash, buf); } else { node = jrb_find_int(vcd_ids, hash); if(node) { fstWriterEmitValueChange(ctx, node->val.i, buf); } else { } } break; case 'b': { /* this block replaces the single statement sp = strchr(buf, ' '); */ /* as the odds are the VCD ID will be small compared to the vector length */ char *sp_scan = nl; sp = NULL; /* if(buf != sp_scan) [can't happen or switch() wouldn't get here] */ { while(buf != --sp_scan) { if(*sp_scan == ' ') { sp = sp_scan; break; } } } } if(!sp) break; *sp = 0; hash = vcdid_hash(sp+1, nl - (sp+1)); if(!hash_kill) { int bin_len = sp - (buf + 1); /* strlen(buf+1) */ int node_len = node_len_array[hash]; if(bin_len >= node_len) { fstWriterEmitValueChange(ctx, hash, buf+1); } else { int delta = node_len - bin_len; if(node_len >= bin_fixbuff_len) { bin_fixbuff_len = node_len + 1; bin_fixbuff = realloc_2(bin_fixbuff, bin_fixbuff_len); } memset(bin_fixbuff, buf[1] != '1' ? buf[1] : '0', delta); memcpy(bin_fixbuff + delta, buf+1, bin_len); fstWriterEmitValueChange(ctx, hash, bin_fixbuff); } } else { node = jrb_find_int(vcd_ids, hash); if(node) { int bin_len = sp - (buf + 1); /* strlen(buf+1) */ int node_len = node->val2.i; if(bin_len >= node_len) { fstWriterEmitValueChange(ctx, node->val.i, buf+1); } else { int delta = node_len - bin_len; if(node_len >= bin_fixbuff_len) { bin_fixbuff_len = node_len + 1; bin_fixbuff = realloc_2(bin_fixbuff, bin_fixbuff_len); } memset(bin_fixbuff, buf[1] != '1' ? buf[1] : '0', delta); memcpy(bin_fixbuff + delta, buf+1, bin_len); fstWriterEmitValueChange(ctx, node->val.i, bin_fixbuff); } } else { } } break; case 's': sp = strchr(buf, ' '); if(!sp) break; *sp = 0; hash = vcdid_hash(sp+1, nl - (sp+1)); if(!hash_kill) { int bin_len = sp - (buf + 1); /* strlen(buf+1) */ bin_len = fstUtilityEscToBin(NULL, (unsigned char *)(buf+1), bin_len); fstWriterEmitVariableLengthValueChange(ctx, hash, buf+1, bin_len); } else { node = jrb_find_int(vcd_ids, hash); if(node) { int bin_len = sp - (buf + 1); /* strlen(buf+1) */ bin_len = fstUtilityEscToBin(NULL, (unsigned char *)(buf+1), bin_len); fstWriterEmitVariableLengthValueChange(ctx, node->val.i, buf+1, bin_len); } else { } } break; case 'p': { char *src = buf+1; char *pnt; int pchar = 0; int p_len = strlen(src); if(p_len >= bin_fixbuff_len) { bin_fixbuff_len = p_len + 1; bin_fixbuff = realloc_2(bin_fixbuff, bin_fixbuff_len); } pnt = bin_fixbuff; for(;;) { if(!*src) break; if(isspace((int)(unsigned char)*src)) { if(pchar != ' ') { *(pnt++) = pchar = ' '; } src++; continue; } *(pnt++) = pchar = *(src++); } *pnt = 0; sp = strchr(bin_fixbuff, ' '); if(!sp) break; sp = strchr(sp+1, ' '); if(!sp) break; sp = strchr(sp+1, ' '); if(!sp) break; *sp = 0; hash = vcdid_hash(sp+1, strlen(sp+1)); /* nl is no longer good here */ if(!hash_kill) { fstWriterEmitValueChange(ctx, hash, bin_fixbuff); } else { node = jrb_find_int(vcd_ids, hash); if(node) { fstWriterEmitValueChange(ctx, node->val.i, bin_fixbuff); } else { } } } break; case 'r': sp = strchr(buf, ' '); if(!sp) break; hash = vcdid_hash(sp+1, nl - (sp+1)); if(!hash_kill) { sscanf(buf+1,"%lg",&doub); fstWriterEmitValueChange(ctx, hash, &doub); } else { node = jrb_find_int(vcd_ids, hash); if(node) { sscanf(buf+1,"%lg",&doub); fstWriterEmitValueChange(ctx, node->val.i, &doub); } else { } } break; case 'h': /* same as 01xz above but moved down here as it's less common */ case 'u': case 'w': case 'l': case '-': hash = vcdid_hash(buf+1, nl - (buf+1)); if(!hash_kill) { fstWriterEmitValueChange(ctx, hash, buf); } else { node = jrb_find_int(vcd_ids, hash); if(node) { fstWriterEmitValueChange(ctx, node->val.i, buf); } else { } } break; case '#': tim = atoi_2((unsigned char *)(buf+1)); if((tim >= prev_tim)||(!prev_tim)) { prev_tim = tim; fstWriterEmitTimeChange(ctx, tim); } break; default: if(!strncmp(buf, "$dumpon", 7)) { fstWriterEmitDumpActive(ctx, 1); } else if(!strncmp(buf, "$dumpoff", 8)) { fstWriterEmitDumpActive(ctx, 0); } else if(!strncmp(buf, "$dumpvars", 9)) { /* nothing */ } else { /* printf("FST '%s'\n", buf); */ } break; } } fstWriterClose(ctx); #if defined(VCD2FST_EXTLOAD_CONV) if(xc) { fstReaderClose(xc); } #endif if(vcd_ids) { jrb_free_tree(vcd_ids); vcd_ids = NULL; } free(bin_fixbuff); bin_fixbuff = NULL; free(wbuf); wbuf = NULL; free(node_len_array); node_len_array = NULL; if(f != stdin) { if(is_popen) { pclose(f); } else { fclose(f); } } return(0); } void print_help(char *nam) { #ifdef VCD2FST_EXTLOADERS_CONV int slen; char *ucase_ext = calloc(1, 1024); int i; ucase_ext[0] = 0; #if defined(VCD2FST_EXTLOAD_CONV) strcat(ucase_ext, "/"); strcat(ucase_ext, EXTLOAD_SUFFIX); #endif #if defined(VCD2FST_EXT2LOAD_CONV) strcat(ucase_ext, "/"); strcat(ucase_ext, EXT2LOAD_SUFFIX); #endif #if defined(VCD2FST_EXT3LOAD_CONV) strcat(ucase_ext, "/"); strcat(ucase_ext, EXT3LOAD_SUFFIX); #endif slen = strlen(ucase_ext); for(i=0;i.\n",nam #ifdef VCD2FST_EXTLOADERS_CONV ,ucase_ext #endif ); #else printf( "Usage: %s [OPTION]... [VCDFILE] [FSTFILE]\n\n" #ifdef VCD2FST_EXTLOADERS_CONV " -v FILE specify VCD%s input filename\n" #else " -v FILE specify VCD input filename\n" #endif " -f FILE specify FST output filename\n" " -4 use lz4 algorithm for speed (default)\n" " -F use fastlz algorithm for speed\n" " -Z use zlib algorithm for size\n" " -c zlib compress entire file on close\n" " -p enable parallel mode\n" " -h display this help then exit\n\n" "Note that VCDFILE and FSTFILE are optional provided the\n" "--vcdname and --fstname options are specified.\n\n" "Report bugs to <"PACKAGE_BUGREPORT">.\n",nam #ifdef VCD2FST_EXTLOADERS_CONV ,ucase_ext #endif ); #endif #ifdef VCD2FST_EXTLOADERS_CONV free(ucase_ext); #endif exit(0); } int main(int argc, char **argv) { char opt_errors_encountered=0; char *vname=NULL, *lxname=NULL; int c; WAVE_LOCALE_FIX while (1) { #ifdef __linux__ int option_index = 0; static struct option long_options[] = { {"vcdname", 1, 0, 'v'}, {"fstname", 1, 0, 'f'}, {"fastpack", 0, 0, 'F'}, {"fourpack", 0, 0, '4'}, {"zlibpack", 0, 0, 'Z'}, {"compress", 0, 0, 'c'}, {"parallel", 0, 0, 'p'}, {"help", 0, 0, 'h'}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "v:f:ZF4cph", long_options, &option_index); #else c = getopt (argc, argv, "v:f:ZF4cph"); #endif if (c == -1) break; /* no more args */ switch (c) { case 'v': if(vname) free(vname); vname = malloc(strlen(optarg)+1); strcpy(vname, optarg); break; case 'f': if(lxname) free(lxname); lxname = malloc(strlen(optarg)+1); strcpy(lxname, optarg); break; case 'Z': compression_explicitly_set = 1; pack_type = FST_WR_PT_ZLIB; break; case 'F': compression_explicitly_set = 1; pack_type = FST_WR_PT_FASTLZ; break; case '4': compression_explicitly_set = 1; pack_type = FST_WR_PT_LZ4; break; case 'c': repack_all = 1; break; case 'p': parallel_mode = 1; break; case 'h': print_help(argv[0]); break; case '?': opt_errors_encountered=1; break; default: /* unreachable */ break; } } if(opt_errors_encountered) { print_help(argv[0]); } if (optind < argc) { while (optind < argc) { if(!vname) { vname = malloc(strlen(argv[optind])+1); strcpy(vname, argv[optind++]); } else if(!lxname) { lxname = malloc(strlen(argv[optind])+1); strcpy(lxname, argv[optind++]); } else { break; } } } if((!vname)||(!lxname)) { print_help(argv[0]); } fst_main(vname, lxname); free(vname); free(lxname); return(0); } gtkwave-3.3.66/src/helpers/Makefile.in0000664000076400007640000011225312261434733017106 0ustar bybellbybell# Makefile.in generated by automake 1.13.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 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__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } 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 = : bin_PROGRAMS = evcd2vcd$(EXEEXT) fst2vcd$(EXEEXT) vcd2fst$(EXEEXT) \ fstminer$(EXEEXT) ghwdump$(EXEEXT) lxt2miner$(EXEEXT) \ lxt2vcd$(EXEEXT) shmidcat$(EXEEXT) vcd2lxt$(EXEEXT) \ vcd2lxt2$(EXEEXT) vcd2vzt$(EXEEXT) vzt2vcd$(EXEEXT) \ vztminer$(EXEEXT) subdir = src/helpers DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" PROGRAMS = $(bin_PROGRAMS) am_evcd2vcd_OBJECTS = evcd2vcd.$(OBJEXT) jrb.$(OBJEXT) evcd2vcd_OBJECTS = $(am_evcd2vcd_OBJECTS) evcd2vcd_LDADD = $(LDADD) am_fst2vcd_OBJECTS = fst2vcd.$(OBJEXT) lz4.$(OBJEXT) fastlz.$(OBJEXT) \ fstapi.$(OBJEXT) fst2vcd_OBJECTS = $(am_fst2vcd_OBJECTS) am__DEPENDENCIES_1 = fst2vcd_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_fstminer_OBJECTS = fstminer.$(OBJEXT) lz4.$(OBJEXT) \ fastlz.$(OBJEXT) fstapi.$(OBJEXT) fstminer_OBJECTS = $(am_fstminer_OBJECTS) fstminer_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_ghwdump_OBJECTS = ghwdump.$(OBJEXT) ghwlib.$(OBJEXT) ghwdump_OBJECTS = $(am_ghwdump_OBJECTS) ghwdump_LDADD = $(LDADD) am_lxt2miner_OBJECTS = lxt2miner.$(OBJEXT) lxt2_read.$(OBJEXT) lxt2miner_OBJECTS = $(am_lxt2miner_OBJECTS) lxt2miner_DEPENDENCIES = $(am__DEPENDENCIES_1) am_lxt2vcd_OBJECTS = lxt2_read.$(OBJEXT) lxt2vcd.$(OBJEXT) \ scopenav.$(OBJEXT) lxt2vcd_OBJECTS = $(am_lxt2vcd_OBJECTS) lxt2vcd_DEPENDENCIES = $(am__DEPENDENCIES_1) shmidcat_SOURCES = shmidcat.c shmidcat_OBJECTS = shmidcat.$(OBJEXT) shmidcat_LDADD = $(LDADD) am_vcd2fst_OBJECTS = vcd2fst.$(OBJEXT) lz4.$(OBJEXT) fastlz.$(OBJEXT) \ fstapi.$(OBJEXT) jrb.$(OBJEXT) vcd2fst_OBJECTS = $(am_vcd2fst_OBJECTS) vcd2fst_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_vcd2lxt_OBJECTS = vcd2lxt.$(OBJEXT) lxt_write.$(OBJEXT) \ v2l_debug.$(OBJEXT) vcd2lxt_OBJECTS = $(am_vcd2lxt_OBJECTS) vcd2lxt_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_vcd2lxt2_OBJECTS = vcd2lxt2.$(OBJEXT) lxt2_write.$(OBJEXT) \ v2l_debug_lxt2.$(OBJEXT) vcd2lxt2_OBJECTS = $(am_vcd2lxt2_OBJECTS) vcd2lxt2_DEPENDENCIES = $(am__DEPENDENCIES_1) am_vcd2vzt_OBJECTS = vcd2vzt.$(OBJEXT) vzt_write.$(OBJEXT) \ v2l_debug_lxt2.$(OBJEXT) LzmaLib.$(OBJEXT) vcd2vzt_OBJECTS = $(am_vcd2vzt_OBJECTS) am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) vcd2vzt_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_2) am_vzt2vcd_OBJECTS = vzt_read.$(OBJEXT) vzt2vcd.$(OBJEXT) \ scopenav.$(OBJEXT) LzmaLib.$(OBJEXT) vzt2vcd_OBJECTS = $(am_vzt2vcd_OBJECTS) vzt2vcd_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_2) am_vztminer_OBJECTS = vztminer.$(OBJEXT) vzt_read.$(OBJEXT) \ LzmaLib.$(OBJEXT) vztminer_OBJECTS = $(am_vztminer_OBJECTS) vztminer_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_2) 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__depfiles_maybe = depfiles am__mv = mv -f 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 = 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 = $(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 = SOURCES = $(evcd2vcd_SOURCES) $(fst2vcd_SOURCES) $(fstminer_SOURCES) \ $(ghwdump_SOURCES) $(lxt2miner_SOURCES) $(lxt2vcd_SOURCES) \ shmidcat.c $(vcd2fst_SOURCES) $(vcd2lxt_SOURCES) \ $(vcd2lxt2_SOURCES) $(vcd2vzt_SOURCES) $(vzt2vcd_SOURCES) \ $(vztminer_SOURCES) DIST_SOURCES = $(evcd2vcd_SOURCES) $(fst2vcd_SOURCES) \ $(fstminer_SOURCES) $(ghwdump_SOURCES) $(lxt2miner_SOURCES) \ $(lxt2vcd_SOURCES) shmidcat.c $(vcd2fst_SOURCES) \ $(vcd2lxt_SOURCES) $(vcd2lxt2_SOURCES) $(vcd2vzt_SOURCES) \ $(vzt2vcd_SOURCES) $(vztminer_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)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AET2_CFLAGS = @AET2_CFLAGS@ AET2_LDADD = @AET2_LDADD@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COCOA_GTK_CFLAGS = @COCOA_GTK_CFLAGS@ COCOA_GTK_LDADD = @COCOA_GTK_LDADD@ COCOA_GTK_LDFLAGS = @COCOA_GTK_LDFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTDEBUG = @EXTDEBUG@ EXTDEBUG2 = @EXTDEBUG2@ EXTDEBUG3 = @EXTDEBUG3@ EXTDEBUG4 = @EXTDEBUG4@ EXTLOAD_CFLAGS = @EXTLOAD_CFLAGS@ FASTTREE_CFLAGS = @FASTTREE_CFLAGS@ FSDB_CFLAGS = @FSDB_CFLAGS@ FSDB_LDADD = @FSDB_LDADD@ GCONF_CFLAGS = @GCONF_CFLAGS@ GCONF_LIBS = @GCONF_LIBS@ GEDITTEST = @GEDITTEST@ GEDIT_CFLAGS = @GEDIT_CFLAGS@ GPERF = @GPERF@ GREP = @GREP@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_CONFIG = @GTK_CONFIG@ GTK_LIBS = @GTK_LIBS@ GTK_MAC_CFLAGS = @GTK_MAC_CFLAGS@ GTK_MAC_LIBS = @GTK_MAC_LIBS@ GTK_UNIX_PRINT_CFLAGS = @GTK_UNIX_PRINT_CFLAGS@ GTK_UNIX_PRINT_LIBS = @GTK_UNIX_PRINT_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBBZ2_CFLAGS = @LIBBZ2_CFLAGS@ LIBBZ2_DIR = @LIBBZ2_DIR@ LIBBZ2_LDADD = @LIBBZ2_LDADD@ LIBJUDY_CFLAGS = @LIBJUDY_CFLAGS@ LIBJUDY_LDADD = @LIBJUDY_LDADD@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBXZ_CFLAGS = @LIBXZ_CFLAGS@ LIBXZ_LDADD = @LIBXZ_LDADD@ LIBZ_CFLAGS = @LIBZ_CFLAGS@ LIBZ_DIR = @LIBZ_DIR@ LIBZ_LDADD = @LIBZ_LDADD@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MINGW_LDADD = @MINGW_LDADD@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ 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@ POW_LIB = @POW_LIB@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ STRUCT_PACK = @STRUCT_PACK@ TCL_DEFADD = @TCL_DEFADD@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LDADD = @TCL_LDADD@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_MAJOR_VERSION = @TCL_MAJOR_VERSION@ TCL_MINOR_VERSION = @TCL_MINOR_VERSION@ TK_INCLUDE_SPEC = @TK_INCLUDE_SPEC@ TK_LDADD = @TK_LDADD@ TK_LIB_SPEC = @TK_LIB_SPEC@ UPDATE_DESKTOP_DATABASE = @UPDATE_DESKTOP_DATABASE@ UPDATE_MIME_DATABASE = @UPDATE_MIME_DATABASE@ VERSION = @VERSION@ XDGDATADIR = @XDGDATADIR@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ 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_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ 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@ 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@ BIGFILES = -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 AIXFLAGS = -bmaxdata:0xd0000000/dsa LIBLZMA_CFLAGS = -I$(srcdir)/../liblzma $(LIBXZ_CFLAGS) LIBLZMA_LDADD = $(LIBXZ_LDADD) AM_CFLAGS = -I$(srcdir)/.. -I$(srcdir)/../.. $(LIBZ_CFLAGS) $(LIBBZ2_CFLAGS) $(LIBLZMA_CFLAGS) $(LIBJUDY_CFLAGS) $(EXTLOAD_CFLAGS) -I$(srcdir)/fst -I$(srcdir)/../../contrib/rtlbrowse vcd2fst_SOURCES = vcd2fst.c $(srcdir)/fst/lz4.c $(srcdir)/fst/lz4.h $(srcdir)/fst/fastlz.c $(srcdir)/fst/fastlz.h $(srcdir)/fst/fstapi.c $(srcdir)/fst/fstapi.h $(srcdir)/../../contrib/rtlbrowse/jrb.h $(srcdir)/../../contrib/rtlbrowse/jrb.c vcd2fst_LDADD = $(LIBZ_LDADD) $(LIBJUDY_LDADD) fst2vcd_SOURCES = fst2vcd.c $(srcdir)/fst/lz4.c $(srcdir)/fst/lz4.h $(srcdir)/fst/fastlz.c $(srcdir)/fst/fastlz.h $(srcdir)/fst/fstapi.c $(srcdir)/fst/fstapi.h fst2vcd_LDADD = $(LIBZ_LDADD) $(LIBJUDY_LDADD) fstminer_SOURCES = fstminer.c $(srcdir)/fst/lz4.c $(srcdir)/fst/lz4.h $(srcdir)/fst/fastlz.c $(srcdir)/fst/fastlz.h $(srcdir)/fst/fstapi.c $(srcdir)/fst/fstapi.h fstminer_LDADD = $(LIBZ_LDADD) $(LIBJUDY_LDADD) vcd2lxt_SOURCES = vcd2lxt.c lxt_write.c lxt_write.h v2l_analyzer.h v2l_debug.c v2l_debug.h vcd2lxt_LDADD = $(LIBZ_LDADD) $(LIBBZ2_LDADD) lxt2vcd_SOURCES = lxt2_read.c lxt2_read.h lxt2vcd.c scopenav.c lxt2vcd_LDADD = $(LIBZ_LDADD) vcd2lxt2_SOURCES = vcd2lxt2.c lxt2_write.c lxt2_write.h v2l_analyzer_lxt2.h v2l_debug_lxt2.c v2l_debug_lxt2.h vcd2lxt2_LDADD = $(LIBZ_LDADD) vzt2vcd_SOURCES = vzt_read.c vzt_read.h vzt2vcd.c scopenav.c $(srcdir)/../liblzma/LzmaLib.c $(srcdir)/../liblzma/LzmaLib.h vzt2vcd_LDADD = $(LIBZ_LDADD) $(LIBBZ2_LDADD) $(LIBLZMA_LDADD) vcd2vzt_SOURCES = vcd2vzt.c vzt_write.c vzt_write.h v2l_analyzer_lxt2.h v2l_debug_lxt2.c v2l_debug_lxt2.h $(srcdir)/../liblzma/LzmaLib.c $(srcdir)/../liblzma/LzmaLib.h vcd2vzt_LDADD = $(LIBZ_LDADD) $(LIBBZ2_LDADD) $(LIBLZMA_LDADD) vztminer_SOURCES = vztminer.c vzt_read.c vzt_read.h $(srcdir)/../liblzma/LzmaLib.c $(srcdir)/../liblzma/LzmaLib.h vztminer_LDADD = $(LIBZ_LDADD) $(LIBBZ2_LDADD) $(LIBLZMA_LDADD) lxt2miner_SOURCES = lxt2miner.c lxt2_read.c lxt2_read.h lxt2miner_LDADD = $(LIBZ_LDADD) ghwdump_SOURCES = ghwdump.c $(srcdir)/../ghwlib.c evcd2vcd_SOURCES = evcd2vcd.c $(srcdir)/../../contrib/rtlbrowse/jrb.h $(srcdir)/../../contrib/rtlbrowse/jrb.c all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(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) --foreign src/helpers/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/helpers/Makefile .PRECIOUS: 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__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): 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 \ ; 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) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(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: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) evcd2vcd$(EXEEXT): $(evcd2vcd_OBJECTS) $(evcd2vcd_DEPENDENCIES) $(EXTRA_evcd2vcd_DEPENDENCIES) @rm -f evcd2vcd$(EXEEXT) $(AM_V_CCLD)$(LINK) $(evcd2vcd_OBJECTS) $(evcd2vcd_LDADD) $(LIBS) fst2vcd$(EXEEXT): $(fst2vcd_OBJECTS) $(fst2vcd_DEPENDENCIES) $(EXTRA_fst2vcd_DEPENDENCIES) @rm -f fst2vcd$(EXEEXT) $(AM_V_CCLD)$(LINK) $(fst2vcd_OBJECTS) $(fst2vcd_LDADD) $(LIBS) fstminer$(EXEEXT): $(fstminer_OBJECTS) $(fstminer_DEPENDENCIES) $(EXTRA_fstminer_DEPENDENCIES) @rm -f fstminer$(EXEEXT) $(AM_V_CCLD)$(LINK) $(fstminer_OBJECTS) $(fstminer_LDADD) $(LIBS) ghwdump$(EXEEXT): $(ghwdump_OBJECTS) $(ghwdump_DEPENDENCIES) $(EXTRA_ghwdump_DEPENDENCIES) @rm -f ghwdump$(EXEEXT) $(AM_V_CCLD)$(LINK) $(ghwdump_OBJECTS) $(ghwdump_LDADD) $(LIBS) lxt2miner$(EXEEXT): $(lxt2miner_OBJECTS) $(lxt2miner_DEPENDENCIES) $(EXTRA_lxt2miner_DEPENDENCIES) @rm -f lxt2miner$(EXEEXT) $(AM_V_CCLD)$(LINK) $(lxt2miner_OBJECTS) $(lxt2miner_LDADD) $(LIBS) lxt2vcd$(EXEEXT): $(lxt2vcd_OBJECTS) $(lxt2vcd_DEPENDENCIES) $(EXTRA_lxt2vcd_DEPENDENCIES) @rm -f lxt2vcd$(EXEEXT) $(AM_V_CCLD)$(LINK) $(lxt2vcd_OBJECTS) $(lxt2vcd_LDADD) $(LIBS) shmidcat$(EXEEXT): $(shmidcat_OBJECTS) $(shmidcat_DEPENDENCIES) $(EXTRA_shmidcat_DEPENDENCIES) @rm -f shmidcat$(EXEEXT) $(AM_V_CCLD)$(LINK) $(shmidcat_OBJECTS) $(shmidcat_LDADD) $(LIBS) vcd2fst$(EXEEXT): $(vcd2fst_OBJECTS) $(vcd2fst_DEPENDENCIES) $(EXTRA_vcd2fst_DEPENDENCIES) @rm -f vcd2fst$(EXEEXT) $(AM_V_CCLD)$(LINK) $(vcd2fst_OBJECTS) $(vcd2fst_LDADD) $(LIBS) vcd2lxt$(EXEEXT): $(vcd2lxt_OBJECTS) $(vcd2lxt_DEPENDENCIES) $(EXTRA_vcd2lxt_DEPENDENCIES) @rm -f vcd2lxt$(EXEEXT) $(AM_V_CCLD)$(LINK) $(vcd2lxt_OBJECTS) $(vcd2lxt_LDADD) $(LIBS) vcd2lxt2$(EXEEXT): $(vcd2lxt2_OBJECTS) $(vcd2lxt2_DEPENDENCIES) $(EXTRA_vcd2lxt2_DEPENDENCIES) @rm -f vcd2lxt2$(EXEEXT) $(AM_V_CCLD)$(LINK) $(vcd2lxt2_OBJECTS) $(vcd2lxt2_LDADD) $(LIBS) vcd2vzt$(EXEEXT): $(vcd2vzt_OBJECTS) $(vcd2vzt_DEPENDENCIES) $(EXTRA_vcd2vzt_DEPENDENCIES) @rm -f vcd2vzt$(EXEEXT) $(AM_V_CCLD)$(LINK) $(vcd2vzt_OBJECTS) $(vcd2vzt_LDADD) $(LIBS) vzt2vcd$(EXEEXT): $(vzt2vcd_OBJECTS) $(vzt2vcd_DEPENDENCIES) $(EXTRA_vzt2vcd_DEPENDENCIES) @rm -f vzt2vcd$(EXEEXT) $(AM_V_CCLD)$(LINK) $(vzt2vcd_OBJECTS) $(vzt2vcd_LDADD) $(LIBS) vztminer$(EXEEXT): $(vztminer_OBJECTS) $(vztminer_DEPENDENCIES) $(EXTRA_vztminer_DEPENDENCIES) @rm -f vztminer$(EXEEXT) $(AM_V_CCLD)$(LINK) $(vztminer_OBJECTS) $(vztminer_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LzmaLib.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/evcd2vcd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fastlz.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fst2vcd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstapi.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstminer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ghwdump.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ghwlib.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jrb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxt2_read.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxt2_write.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxt2miner.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxt2vcd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxt_write.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lz4.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scopenav.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shmidcat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/v2l_debug.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/v2l_debug_lxt2.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vcd2fst.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vcd2lxt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vcd2lxt2.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vcd2vzt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vzt2vcd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vzt_read.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vzt_write.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vztminer.Po@am__quote@ .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 $< .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 `$(CYGPATH_W) '$<'` jrb.o: $(srcdir)/../../contrib/rtlbrowse/jrb.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT jrb.o -MD -MP -MF $(DEPDIR)/jrb.Tpo -c -o jrb.o `test -f '$(srcdir)/../../contrib/rtlbrowse/jrb.c' || echo '$(srcdir)/'`$(srcdir)/../../contrib/rtlbrowse/jrb.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/jrb.Tpo $(DEPDIR)/jrb.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(srcdir)/../../contrib/rtlbrowse/jrb.c' object='jrb.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o jrb.o `test -f '$(srcdir)/../../contrib/rtlbrowse/jrb.c' || echo '$(srcdir)/'`$(srcdir)/../../contrib/rtlbrowse/jrb.c jrb.obj: $(srcdir)/../../contrib/rtlbrowse/jrb.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT jrb.obj -MD -MP -MF $(DEPDIR)/jrb.Tpo -c -o jrb.obj `if test -f '$(srcdir)/../../contrib/rtlbrowse/jrb.c'; then $(CYGPATH_W) '$(srcdir)/../../contrib/rtlbrowse/jrb.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/../../contrib/rtlbrowse/jrb.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/jrb.Tpo $(DEPDIR)/jrb.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(srcdir)/../../contrib/rtlbrowse/jrb.c' object='jrb.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o jrb.obj `if test -f '$(srcdir)/../../contrib/rtlbrowse/jrb.c'; then $(CYGPATH_W) '$(srcdir)/../../contrib/rtlbrowse/jrb.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/../../contrib/rtlbrowse/jrb.c'; fi` lz4.o: $(srcdir)/fst/lz4.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lz4.o -MD -MP -MF $(DEPDIR)/lz4.Tpo -c -o lz4.o `test -f '$(srcdir)/fst/lz4.c' || echo '$(srcdir)/'`$(srcdir)/fst/lz4.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lz4.Tpo $(DEPDIR)/lz4.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(srcdir)/fst/lz4.c' object='lz4.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lz4.o `test -f '$(srcdir)/fst/lz4.c' || echo '$(srcdir)/'`$(srcdir)/fst/lz4.c lz4.obj: $(srcdir)/fst/lz4.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lz4.obj -MD -MP -MF $(DEPDIR)/lz4.Tpo -c -o lz4.obj `if test -f '$(srcdir)/fst/lz4.c'; then $(CYGPATH_W) '$(srcdir)/fst/lz4.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/fst/lz4.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/lz4.Tpo $(DEPDIR)/lz4.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(srcdir)/fst/lz4.c' object='lz4.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lz4.obj `if test -f '$(srcdir)/fst/lz4.c'; then $(CYGPATH_W) '$(srcdir)/fst/lz4.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/fst/lz4.c'; fi` fastlz.o: $(srcdir)/fst/fastlz.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fastlz.o -MD -MP -MF $(DEPDIR)/fastlz.Tpo -c -o fastlz.o `test -f '$(srcdir)/fst/fastlz.c' || echo '$(srcdir)/'`$(srcdir)/fst/fastlz.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fastlz.Tpo $(DEPDIR)/fastlz.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(srcdir)/fst/fastlz.c' object='fastlz.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fastlz.o `test -f '$(srcdir)/fst/fastlz.c' || echo '$(srcdir)/'`$(srcdir)/fst/fastlz.c fastlz.obj: $(srcdir)/fst/fastlz.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fastlz.obj -MD -MP -MF $(DEPDIR)/fastlz.Tpo -c -o fastlz.obj `if test -f '$(srcdir)/fst/fastlz.c'; then $(CYGPATH_W) '$(srcdir)/fst/fastlz.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/fst/fastlz.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fastlz.Tpo $(DEPDIR)/fastlz.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(srcdir)/fst/fastlz.c' object='fastlz.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fastlz.obj `if test -f '$(srcdir)/fst/fastlz.c'; then $(CYGPATH_W) '$(srcdir)/fst/fastlz.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/fst/fastlz.c'; fi` fstapi.o: $(srcdir)/fst/fstapi.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fstapi.o -MD -MP -MF $(DEPDIR)/fstapi.Tpo -c -o fstapi.o `test -f '$(srcdir)/fst/fstapi.c' || echo '$(srcdir)/'`$(srcdir)/fst/fstapi.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fstapi.Tpo $(DEPDIR)/fstapi.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(srcdir)/fst/fstapi.c' object='fstapi.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fstapi.o `test -f '$(srcdir)/fst/fstapi.c' || echo '$(srcdir)/'`$(srcdir)/fst/fstapi.c fstapi.obj: $(srcdir)/fst/fstapi.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fstapi.obj -MD -MP -MF $(DEPDIR)/fstapi.Tpo -c -o fstapi.obj `if test -f '$(srcdir)/fst/fstapi.c'; then $(CYGPATH_W) '$(srcdir)/fst/fstapi.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/fst/fstapi.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/fstapi.Tpo $(DEPDIR)/fstapi.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(srcdir)/fst/fstapi.c' object='fstapi.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fstapi.obj `if test -f '$(srcdir)/fst/fstapi.c'; then $(CYGPATH_W) '$(srcdir)/fst/fstapi.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/fst/fstapi.c'; fi` ghwlib.o: $(srcdir)/../ghwlib.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ghwlib.o -MD -MP -MF $(DEPDIR)/ghwlib.Tpo -c -o ghwlib.o `test -f '$(srcdir)/../ghwlib.c' || echo '$(srcdir)/'`$(srcdir)/../ghwlib.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ghwlib.Tpo $(DEPDIR)/ghwlib.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(srcdir)/../ghwlib.c' object='ghwlib.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ghwlib.o `test -f '$(srcdir)/../ghwlib.c' || echo '$(srcdir)/'`$(srcdir)/../ghwlib.c ghwlib.obj: $(srcdir)/../ghwlib.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ghwlib.obj -MD -MP -MF $(DEPDIR)/ghwlib.Tpo -c -o ghwlib.obj `if test -f '$(srcdir)/../ghwlib.c'; then $(CYGPATH_W) '$(srcdir)/../ghwlib.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/../ghwlib.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ghwlib.Tpo $(DEPDIR)/ghwlib.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(srcdir)/../ghwlib.c' object='ghwlib.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ghwlib.obj `if test -f '$(srcdir)/../ghwlib.c'; then $(CYGPATH_W) '$(srcdir)/../ghwlib.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/../ghwlib.c'; fi` LzmaLib.o: $(srcdir)/../liblzma/LzmaLib.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT LzmaLib.o -MD -MP -MF $(DEPDIR)/LzmaLib.Tpo -c -o LzmaLib.o `test -f '$(srcdir)/../liblzma/LzmaLib.c' || echo '$(srcdir)/'`$(srcdir)/../liblzma/LzmaLib.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/LzmaLib.Tpo $(DEPDIR)/LzmaLib.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(srcdir)/../liblzma/LzmaLib.c' object='LzmaLib.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o LzmaLib.o `test -f '$(srcdir)/../liblzma/LzmaLib.c' || echo '$(srcdir)/'`$(srcdir)/../liblzma/LzmaLib.c LzmaLib.obj: $(srcdir)/../liblzma/LzmaLib.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT LzmaLib.obj -MD -MP -MF $(DEPDIR)/LzmaLib.Tpo -c -o LzmaLib.obj `if test -f '$(srcdir)/../liblzma/LzmaLib.c'; then $(CYGPATH_W) '$(srcdir)/../liblzma/LzmaLib.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/../liblzma/LzmaLib.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/LzmaLib.Tpo $(DEPDIR)/LzmaLib.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(srcdir)/../liblzma/LzmaLib.c' object='LzmaLib.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o LzmaLib.obj `if test -f '$(srcdir)/../liblzma/LzmaLib.c'; then $(CYGPATH_W) '$(srcdir)/../liblzma/LzmaLib.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/../liblzma/LzmaLib.c'; fi` 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: $(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 $(PROGRAMS) installdirs: for dir in "$(DESTDIR)$(bindir)"; 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-binPROGRAMS clean-generic mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -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-binPROGRAMS 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 -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic distclean-tags \ distdir 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-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 maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ ps ps-am tags tags-am uninstall uninstall-am \ uninstall-binPROGRAMS # 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: gtkwave-3.3.66/src/helpers/vzt_write.c0000664000076400007640000012157712527430212017244 0ustar bybellbybell/* * Copyright (c) 2003-2015 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifdef _AIX #pragma alloca #endif #include #include #if defined(__CYGWIN__) || defined(__MINGW32__) #undef HAVE_RPC_XDR_H #endif #if HAVE_RPC_XDR_H #include #include #endif #include "vzt_write.h" /* * in-place sort to keep chained facs from migrating... */ static void wave_mergesort(struct vzt_wr_symbol **a, struct vzt_wr_symbol **b, int lo, int hi) { int i, j, k; if (loname, a[j]->name) <= 0) { a[k++]=b[i++]; } else { a[k++]=a[j++]; } } while (kztype = lt->ztype_cfg; /* shadow config at file open */ switch(lt->ztype) { case VZT_WR_IS_GZ: return(gzdopen(fd, mode)); case VZT_WR_IS_BZ2: return(BZ2_bzdopen(fd, mode)); case VZT_WR_IS_LZMA: default: return(LZMA_fdopen(fd, mode)); } } return(NULL); } static _VZT_WR_INLINE int vzt_gzclose(struct vzt_wr_trace *lt, void *file) { if(lt) { switch(lt->ztype) { case VZT_WR_IS_GZ: return(gzclose(file)); case VZT_WR_IS_BZ2: BZ2_bzclose(file); return(0); case VZT_WR_IS_LZMA: default: LZMA_close(file); return(0); } } return(0); } static _VZT_WR_INLINE int vzt_gzflush(struct vzt_wr_trace *lt, void *file, int flush) { if(lt) { switch(lt->ztype) { case VZT_WR_IS_GZ: return(gzflush(file, flush)); case VZT_WR_IS_BZ2: return(BZ2_bzflush(file)); case VZT_WR_IS_LZMA: default: return(0); /* no real need to do a LZMA_flush(file) as the dictionary is so big */ } } return(0); } static _VZT_WR_INLINE int vzt_gzwrite(struct vzt_wr_trace *lt, void *file, void* buf, unsigned len) { if(lt) { switch(lt->ztype) { case VZT_WR_IS_GZ: return(gzwrite(file, buf, len)); case VZT_WR_IS_BZ2: return(BZ2_bzwrite(file, buf, len)); case VZT_WR_IS_LZMA: default: return(LZMA_write(file, buf, len)); } } return(0); } /************************ splay ************************/ #define cmp_l(i,j) ((int)(-(ij))) #define cmp_l_lt(i,j) (ij) static int vzt_wr_dsvzt_success; static vzt_wr_dsvzt_Tree * vzt_wr_dsvzt_splay (vztint32_t i, vzt_wr_dsvzt_Tree * t) { /* Simple top down splay, not requiring i to be in the tree t. */ /* What it does is described above. */ vzt_wr_dsvzt_Tree N, *l, *r, *y; int dir; vzt_wr_dsvzt_success = 0; if (t == NULL) return t; N.left = N.right = NULL; l = r = &N; for (;;) { dir = cmp_l(i, t->item); if (dir < 0) { if (t->left == NULL) break; if (cmp_l_lt(i, t->left->item)) { y = t->left; /* rotate right */ t->left = y->right; y->right = t; t = y; if (t->left == NULL) break; } r->left = t; /* link right */ r = t; t = t->left; } else if (dir > 0) { if (t->right == NULL) break; if (cmp_l_gt(i, t->right->item)) { y = t->right; /* rotate left */ t->right = y->left; y->left = t; t = y; if (t->right == NULL) break; } l->right = t; /* link left */ l = t; t = t->right; } else { vzt_wr_dsvzt_success=1; break; } } l->right = t->left; /* assemble */ r->left = t->right; t->left = N.right; t->right = N.left; return t; } static vzt_wr_dsvzt_Tree * vzt_wr_dsvzt_insert(vztint32_t i, vzt_wr_dsvzt_Tree * t, vztint32_t val) { /* Insert i into the tree t, unless it's already there. */ /* Return a pointer to the resulting tree. */ vzt_wr_dsvzt_Tree * n; int dir; n = (vzt_wr_dsvzt_Tree *) calloc (1, sizeof (vzt_wr_dsvzt_Tree)); if (n == NULL) { fprintf(stderr, "dsvzt_insert: ran out of memory, exiting.\n"); exit(255); } n->item = i; n->val = val; if (t == NULL) { n->left = n->right = NULL; return n; } t = vzt_wr_dsvzt_splay(i,t); dir = cmp_l(i,t->item); if (dir<0) { n->left = t->left; n->right = t; t->left = NULL; return n; } else if (dir>0) { n->right = t->right; n->left = t; t->right = NULL; return n; } else { /* We get here if it's already in the tree */ /* Don't add it again */ free(n); return t; } } /************************ splay ************************/ static int vzt2_wr_dsvzt_success; static vzt2_wr_dsvzt_Tree * vzt2_wr_dsvzt_splay (char *i, vzt2_wr_dsvzt_Tree * t) { /* Simple top down splay, not requiring i to be in the tree t. */ /* What it does is described above. */ vzt2_wr_dsvzt_Tree N, *l, *r, *y; int dir; vzt2_wr_dsvzt_success = 0; if (t == NULL) return t; N.left = N.right = NULL; l = r = &N; for (;;) { dir = strcmp(i, t->item); if (dir < 0) { if (t->left == NULL) break; if (strcmp(i, t->left->item)<0) { y = t->left; /* rotate right */ t->left = y->right; y->right = t; t = y; if (t->left == NULL) break; } r->left = t; /* link right */ r = t; t = t->left; } else if (dir > 0) { if (t->right == NULL) break; if (strcmp(i, t->right->item)>0) { y = t->right; /* rotate left */ t->right = y->left; y->left = t; t = y; if (t->right == NULL) break; } l->right = t; /* link left */ l = t; t = t->right; } else { vzt2_wr_dsvzt_success=1; break; } } l->right = t->left; /* assemble */ r->left = t->right; t->left = N.right; t->right = N.left; return t; } static vzt2_wr_dsvzt_Tree * vzt2_wr_dsvzt_insert(char *i, vzt2_wr_dsvzt_Tree * t, unsigned int val) { /* Insert i into the tree t, unless it's already there. */ /* Return a pointer to the resulting tree. */ vzt2_wr_dsvzt_Tree * n; int dir; n = (vzt2_wr_dsvzt_Tree *) calloc (1, sizeof (vzt2_wr_dsvzt_Tree)); if (n == NULL) { fprintf(stderr, "dsvzt_insert: ran out of memory, exiting.\n"); exit(255); } n->item = i; n->val = val; if (t == NULL) { n->left = n->right = NULL; return n; } t = vzt2_wr_dsvzt_splay(i,t); dir = strcmp(i,t->item); if (dir<0) { n->left = t->left; n->right = t; t->left = NULL; return n; } else if (dir>0) { n->right = t->right; n->left = t; t->right = NULL; return n; } else { /* We get here if it's already in the tree */ /* Don't add it again */ free(n); return t; } } /************************ splay ************************/ /* * functions which emit various big endian * data to a file */ static int vzt_wr_emit_u8(struct vzt_wr_trace *lt, int value) { unsigned char buf[1]; int nmemb; buf[0] = value & 0xff; nmemb=fwrite(buf, sizeof(char), 1, lt->handle); lt->position+=nmemb; return(nmemb); } static int vzt_wr_emit_u16(struct vzt_wr_trace *lt, int value) { unsigned char buf[2]; int nmemb; buf[0] = (value>>8) & 0xff; buf[1] = value & 0xff; nmemb = fwrite(buf, sizeof(char), 2, lt->handle); lt->position+=nmemb; return(nmemb); } static int vzt_wr_emit_u32(struct vzt_wr_trace *lt, int value) { unsigned char buf[4]; int nmemb; buf[0] = (value>>24) & 0xff; buf[1] = (value>>16) & 0xff; buf[2] = (value>>8) & 0xff; buf[3] = value & 0xff; nmemb=fwrite(buf, sizeof(char), 4, lt->handle); lt->position+=nmemb; return(nmemb); } static int vzt_wr_emit_u64(struct vzt_wr_trace *lt, int valueh, int valuel) { int rc; if((rc=vzt_wr_emit_u32(lt, valueh))) { rc=vzt_wr_emit_u32(lt, valuel); } return(rc); } /* * gzfunctions which emit various big endian * data to a file. (lt->position needs to be * fixed up on gzclose so the tables don't * get out of sync!) */ static int gzwrite_buffered(struct vzt_wr_trace *lt) { int rc = 1; if(lt->gzbufpnt > VZT_WR_GZWRITE_BUFFER) { rc = vzt_gzwrite(lt, lt->zhandle, lt->gzdest, lt->gzbufpnt); rc = rc ? 1 : 0; lt->gzbufpnt = 0; } return(rc); } static void gzflush_buffered(struct vzt_wr_trace *lt, int doclose) { if(lt->gzbufpnt) { vzt_gzwrite(lt, lt->zhandle, lt->gzdest, lt->gzbufpnt); lt->gzbufpnt = 0; if(!doclose) { vzt_gzflush(lt, lt->zhandle, Z_SYNC_FLUSH); } } if(doclose) { vzt_gzclose(lt, lt->zhandle); } } static int vzt_wr_emit_u8z(struct vzt_wr_trace *lt, int value) { int nmemb; lt->gzdest[lt->gzbufpnt++] = value & 0xff; nmemb=gzwrite_buffered(lt); lt->zpackcount++; lt->position++; return(nmemb); } static int vzt_wr_emit_u16z(struct vzt_wr_trace *lt, int value) { int nmemb; lt->gzdest[lt->gzbufpnt++] = (value>>8) & 0xff; lt->gzdest[lt->gzbufpnt++] = value & 0xff; nmemb = gzwrite_buffered(lt); lt->zpackcount+=2; lt->position+=2; return(nmemb); } static int vzt_wr_emit_u32z(struct vzt_wr_trace *lt, int value) { int nmemb; lt->gzdest[lt->gzbufpnt++] = (value>>24) & 0xff; lt->gzdest[lt->gzbufpnt++] = (value>>16) & 0xff; lt->gzdest[lt->gzbufpnt++] = (value>>8) & 0xff; lt->gzdest[lt->gzbufpnt++] = value & 0xff; nmemb=gzwrite_buffered(lt); lt->zpackcount+=4; lt->position+=4; return(nmemb); } static int vzt_wr_emit_u32rz(struct vzt_wr_trace *lt, int value) { int nmemb; lt->gzdest[lt->gzbufpnt++] = value & 0xff; lt->gzdest[lt->gzbufpnt++] = (value>>8) & 0xff; lt->gzdest[lt->gzbufpnt++] = (value>>16) & 0xff; lt->gzdest[lt->gzbufpnt++] = (value>>24) & 0xff; nmemb=gzwrite_buffered(lt); lt->zpackcount+=4; lt->position+=4; return(nmemb); } #if 0 static int vzt_wr_emit_u64z(struct vzt_wr_trace *lt, int valueh, int valuel) { int rc; if((rc=vzt_wr_emit_u32z(lt, valueh))) { rc=vzt_wr_emit_u32z(lt, valuel); } return(rc); } #endif static int vzt_wr_emit_stringz(struct vzt_wr_trace *lt, char *value) { int rc=1; do { rc&=vzt_wr_emit_u8z(lt, *value); } while(*(value++)); return(rc); } static int vzt_wr_emit_uv32z(struct vzt_wr_trace *lt, unsigned int v) { int nmemb; unsigned int nxt; unsigned int oldpnt = lt->gzbufpnt; while((nxt = v>>7)) { lt->gzdest[lt->gzbufpnt++] = (v&0x7f); v = nxt; } lt->gzdest[lt->gzbufpnt++] = (v&0x7f) | 0x80; lt->zpackcount+=(lt->gzbufpnt - oldpnt); lt->position+=(lt->gzbufpnt - oldpnt); nmemb=gzwrite_buffered(lt); return(nmemb); } static int vzt_wr_emit_uv64z(struct vzt_wr_trace *lt, vztint64_t v) { int nmemb; vztint64_t nxt; unsigned int oldpnt = lt->gzbufpnt; while((nxt = v>>7)) { lt->gzdest[lt->gzbufpnt++] = (v&0x7f); v = nxt; } lt->gzdest[lt->gzbufpnt++] = (v&0x7f) | 0x80; lt->zpackcount+=(lt->gzbufpnt - oldpnt); lt->position+=(lt->gzbufpnt - oldpnt); nmemb=gzwrite_buffered(lt); return(nmemb); } /* * hash/symtable manipulation */ static int vzt_wr_hash(const char *s) { const char *p; char ch; unsigned int h=0, h2=0, pos=0, g; for(p=s;*p;p++) { ch=*p; h2<<=3; h2-=((unsigned int)ch+(pos++)); /* this handles stranded vectors quite well.. */ h=(h<<4)+ch; if((g=h&0xf0000000)) { h=h^(g>>24); h=h^g; } } h^=h2; /* combine the two hashes */ return(h%VZT_WR_SYMPRIME); } static struct vzt_wr_symbol *vzt_wr_symadd(struct vzt_wr_trace *lt, const char *name, int hv) { struct vzt_wr_symbol *s; s=(struct vzt_wr_symbol *)calloc(1,sizeof(struct vzt_wr_symbol)); strcpy(s->name=(char *)malloc((s->namlen=strlen(name))+1),name); s->next=lt->sym[hv]; lt->sym[hv]=s; return(s); } static struct vzt_wr_symbol *vzt_wr_symfind(struct vzt_wr_trace *lt, const char *s) { int hv; struct vzt_wr_symbol *temp; hv=vzt_wr_hash(s); if(!(temp=lt->sym[hv])) return(NULL); /* no hash entry, add here wanted to add */ while(temp) { if(!strcmp(temp->name,s)) { return(temp); /* in table already */ } if(!temp->next) break; temp=temp->next; } return(NULL); /* not found, add here if you want to add*/ } /* * compress facs to a prefix count + string + 0x00 */ static void vzt_wr_compress_fac(struct vzt_wr_trace *lt, char *str) { int i; int len = strlen(str); int minlen = (lencompress_fac_len) ? len : lt->compress_fac_len; if(minlen>65535) minlen=65535; /* keep in printable range--most hierarchies won't be this big anyway */ if(lt->compress_fac_str) { for(i=0;icompress_fac_str[i]!=str[i]) break; } vzt_wr_emit_u16z(lt, i); vzt_wr_emit_stringz(lt, str+i); free(lt->compress_fac_str); } else { vzt_wr_emit_u16z(lt, 0); vzt_wr_emit_stringz(lt, str); } lt->compress_fac_str = (char *) malloc((lt->compress_fac_len=len)+1); strcpy(lt->compress_fac_str, str); } /* * emit facs in sorted order along with geometry * and sync table info */ static void strip_brack(struct vzt_wr_symbol *s) { char *lastch = s->name+s->namlen - 1; if(*lastch!=']') return; if(s->namlen<3) return; lastch--; while(lastch!=s->name) { if(*lastch=='.') { return; /* MTI SV [0.3] notation for implicit vars */ } if(*lastch=='[') { *lastch=0x00; return; } lastch--; } return; } static void vzt_wr_emitfacs(struct vzt_wr_trace *lt) { int i; if((lt)&&(lt->numfacs)) { struct vzt_wr_symbol *s = lt->symchain; struct vzt_wr_symbol **aliascache = calloc(lt->numalias ? lt->numalias : 1, sizeof(struct vzt_wr_symbol *)); int aliases_encountered, facs_encountered; lt->sorted_facs = (struct vzt_wr_symbol **)calloc(lt->numfacs, sizeof(struct vzt_wr_symbol *)); if(lt->sorted_facs && aliascache) { if(lt->do_strip_brackets) for(i=0;inumfacs;i++) { lt->sorted_facs[lt->numfacs - i - 1] = s; /* facs were chained backwards so reverse to restore bitslicing */ strip_brack(s); s=s->symchain; } else for(i=0;inumfacs;i++) { lt->sorted_facs[lt->numfacs - i - 1] = s; /* facs were chained backwards so reverse to restore bitslicing */ s=s->symchain; } wave_msort(lt->sorted_facs, lt->numfacs); /* move facs up */ aliases_encountered = 0, facs_encountered = 0; for(i=0;inumfacs;i++) { if((lt->sorted_facs[i]->flags&VZT_WR_SYM_F_ALIAS)==0) { lt->sorted_facs[facs_encountered] = lt->sorted_facs[i]; facs_encountered++; } else { aliascache[aliases_encountered] = lt->sorted_facs[i]; aliases_encountered++; } } /* then append the aliases */ for(i=0;isorted_facs[facs_encountered+i] = aliascache[i]; } for(i=0;inumfacs;i++) { lt->sorted_facs[i]->facnum = i; } if(!lt->timezero) { vzt_wr_emit_u32(lt, lt->numfacs); /* uncompressed */ } else { vzt_wr_emit_u32(lt, 0); /* uncompressed, flag to insert extra parameters */ vzt_wr_emit_u32(lt, 8); /* uncompressed 8 counts timezero and on */ vzt_wr_emit_u32(lt, lt->numfacs); /* uncompressed */ vzt_wr_emit_u64(lt, (lt->timezero >> 32) & 0xffffffffL, lt->timezero & 0xffffffffL); /* uncompressed */ } vzt_wr_emit_u32(lt, lt->numfacbytes); /* uncompressed */ vzt_wr_emit_u32(lt, lt->longestname); /* uncompressed */ lt->facname_offset=lt->position; vzt_wr_emit_u32(lt, 0); /* uncompressed : placeholder for zfacnamesize */ vzt_wr_emit_u32(lt, 0); /* uncompressed : placeholder for zfacname_predec_size */ vzt_wr_emit_u32(lt, 0); /* uncompressed : placeholder for zfacgeometrysize */ vzt_wr_emit_u8(lt, lt->timescale); /* timescale (-9 default == nsec) */ fflush(lt->handle); lt->zfacname_size = lt->position; lt->zhandle = vzt_gzdopen(lt, dup(fileno(lt->handle)), "wb9"); lt->zpackcount = 0; for(i=0;inumfacs;i++) { vzt_wr_compress_fac(lt, lt->sorted_facs[i]->name); free(lt->sorted_facs[i]->name); lt->sorted_facs[i]->name = NULL; } free(lt->compress_fac_str); lt->compress_fac_str=NULL; lt->compress_fac_len=0; lt->zfacname_predec_size = lt->zpackcount; gzflush_buffered(lt, 1); fseeko(lt->handle, 0L, SEEK_END); lt->position=ftello(lt->handle); lt->zfacname_size = lt->position - lt->zfacname_size; lt->zhandle = vzt_gzdopen(lt, dup(fileno(lt->handle)), "wb9"); lt->facgeometry_offset = lt->position; for(i=0;inumfacs;i++) { if((lt->sorted_facs[i]->flags&VZT_WR_SYM_F_ALIAS)==0) { vzt_wr_emit_u32z(lt, lt->sorted_facs[i]->rows); vzt_wr_emit_u32z(lt, lt->sorted_facs[i]->msb); vzt_wr_emit_u32z(lt, lt->sorted_facs[i]->lsb); vzt_wr_emit_u32z(lt, lt->sorted_facs[i]->flags & VZT_WR_SYM_MASK); } else { vzt_wr_emit_u32z(lt, lt->sorted_facs[i]->aliased_to->facnum); vzt_wr_emit_u32z(lt, lt->sorted_facs[i]->msb); vzt_wr_emit_u32z(lt, lt->sorted_facs[i]->lsb); vzt_wr_emit_u32z(lt, VZT_WR_SYM_F_ALIAS); } } gzflush_buffered(lt, 1); fseeko(lt->handle, 0L, SEEK_END); lt->position=ftello(lt->handle); lt->break_header_size = lt->position; /* in case we need to emit multiple vzts with same header */ lt->zfacgeometry_size = lt->position - lt->facgeometry_offset; fseeko(lt->handle, lt->facname_offset, SEEK_SET); vzt_wr_emit_u32(lt, lt->zfacname_size); /* backpatch sizes... */ vzt_wr_emit_u32(lt, lt->zfacname_predec_size); vzt_wr_emit_u32(lt, lt->zfacgeometry_size); lt->numfacs = facs_encountered; /* don't process alias value changes ever */ } if(aliascache) free(aliascache); } } /* * initialize the trace and get back an lt context */ struct vzt_wr_trace *vzt_wr_init(const char *name) { struct vzt_wr_trace *lt=(struct vzt_wr_trace *)calloc(1, sizeof(struct vzt_wr_trace)); if((!name)||(!(lt->handle=fopen(name, "wb")))) { free(lt); lt=NULL; } else { lt->vztname = strdup(name); vzt_wr_emit_u16(lt, VZT_WR_HDRID); vzt_wr_emit_u16(lt, VZT_WR_VERSION); vzt_wr_emit_u8 (lt, VZT_WR_GRANULE_SIZE); /* currently 32 */ lt->timescale = -9; lt->maxgranule = VZT_WR_GRANULE_NUM; lt->timetable = calloc(lt->maxgranule * VZT_WR_GRANULE_SIZE, sizeof(vzttime_t)); vzt_wr_set_compression_depth(lt, 4); /* set fast/loose compression depth, user can fix this any time after init */ lt->initial_value = 'x'; lt->multi_state = 1; } return(lt); } /* * force trace to two state */ void vzt_wr_force_twostate(struct vzt_wr_trace *lt) { if((lt)&&(!lt->symchain)) { lt->multi_state = 0; } } /* * setting break size */ void vzt_wr_set_break_size(struct vzt_wr_trace *lt, off_t siz) { if(lt) { lt->break_size = siz; } } /* * set initial value of trace (0, 1, x, z) only legal vals */ void vzt_wr_set_initial_value(struct vzt_wr_trace *lt, char value) { if(lt) { switch(value) { case '0': case '1': case 'x': case 'z': break; case 'Z': value = 'z'; break; default: value = 'x'; break; } lt->initial_value = value; } } /* * maint function for finding a symbol if it exists */ struct vzt_wr_symbol *vzt_wr_symbol_find(struct vzt_wr_trace *lt, const char *name) { struct vzt_wr_symbol *s=NULL; if((lt)&&(name)) s=vzt_wr_symfind(lt, name); return(s); } /* * add a trace (if it doesn't exist already) */ struct vzt_wr_symbol *vzt_wr_symbol_add(struct vzt_wr_trace *lt, const char *name, unsigned int rows, int msb, int lsb, int flags) { struct vzt_wr_symbol *s; int i, len; int flagcnt; if((!lt)||(lt->sorted_facs)) return(NULL); flagcnt = ((flags&VZT_WR_SYM_F_INTEGER)!=0) + ((flags&VZT_WR_SYM_F_DOUBLE)!=0) + ((flags&VZT_WR_SYM_F_STRING)!=0); if((flagcnt>1)||(!lt)||(!name)||(vzt_wr_symfind(lt, name))) return (NULL); if(!(flags & (VZT_WR_SYM_F_INTEGER|VZT_WR_SYM_F_STRING|VZT_WR_SYM_F_DOUBLE))) { len = (msbrows = rows; s->flags = flags&(~VZT_WR_SYM_F_ALIAS); /* aliasing makes no sense here.. */ s->prev = (vzt_wr_dsvzt_Tree **)calloc(len, sizeof(vzt_wr_dsvzt_Tree *)); s->chg = (vztint32_t *)calloc(len, sizeof(vztint32_t)); if(lt->multi_state) { s->prevx = (vzt_wr_dsvzt_Tree **)calloc(len, sizeof(vzt_wr_dsvzt_Tree *)); s->chgx = (vztint32_t *)calloc(len, sizeof(vztint32_t)); } if(!flagcnt) { s->msb = msb; s->lsb = lsb; } s->len = len; if(!(flags & (VZT_WR_SYM_F_INTEGER|VZT_WR_SYM_F_STRING|VZT_WR_SYM_F_DOUBLE))) { if((lt->initial_value == '1')||(lt->initial_value == 'z')) { for(i=0;ilen;i++) { s->chg[i] = ~0; } } if(lt->multi_state) { if((lt->initial_value == 'x')||(lt->initial_value == 'z')) { for(i=0;ilen;i++) { s->chgx[i] = ~0; } } } } s->symchain = lt->symchain; lt->symchain = s; lt->numfacs++; if((len=strlen(name)) > lt->longestname) lt->longestname = len; lt->numfacbytes += (len+1); return(s); } /* * add an alias trace (if it doesn't exist already and orig is found) */ struct vzt_wr_symbol *vzt_wr_symbol_alias(struct vzt_wr_trace *lt, const char *existing_name, const char *alias, int msb, int lsb) { struct vzt_wr_symbol *s, *sa; int len; int bitlen; int flagcnt; if((!lt)||(!existing_name)||(!alias)||(!(s=vzt_wr_symfind(lt, existing_name)))||(vzt_wr_symfind(lt, alias))) return (NULL); if(lt->sorted_facs) return(NULL); while(s->aliased_to) /* find root alias */ { s=s->aliased_to; } flagcnt = ((s->flags&VZT_WR_SYM_F_INTEGER)!=0) + ((s->flags&VZT_WR_SYM_F_DOUBLE)!=0) + ((s->flags&VZT_WR_SYM_F_STRING)!=0); bitlen = (msblen)) return(NULL); sa=vzt_wr_symadd(lt, alias, vzt_wr_hash(alias)); sa->flags = VZT_WR_SYM_F_ALIAS; /* only point this can get set */ sa->aliased_to = s; if(!flagcnt) { sa->msb = msb; sa->lsb = lsb; sa->len = bitlen; } sa->symchain = lt->symchain; lt->symchain = sa; lt->numfacs++; lt->numalias++; if((len=strlen(alias)) > lt->longestname) lt->longestname = len; lt->numfacbytes += (len+1); return(sa); } /* * set current time/granule updating */ int vzt_wr_inc_time_by_delta(struct vzt_wr_trace *lt, unsigned int timeval) { return(vzt_wr_set_time64(lt, lt->maxtime + (vzttime_t)timeval)); } int vzt_wr_set_time(struct vzt_wr_trace *lt, unsigned int timeval) { return(vzt_wr_set_time64(lt, (vzttime_t)timeval)); } int vzt_wr_inc_time_by_delta64(struct vzt_wr_trace *lt, vzttime_t timeval) { return(vzt_wr_set_time64(lt, lt->maxtime + timeval)); } /* * file size limiting/header cloning... */ static void vzt_wr_emit_do_breakfile(struct vzt_wr_trace *lt) { unsigned int len = strlen(lt->vztname); int i; char *tname = malloc(len + 30); FILE *f2, *clone; off_t cnt, seg; char buf[32768]; for(i=len;i>0;i--) { if(lt->vztname[i]=='.') break; } if(!i) { sprintf(tname, "%s_%03d.vzt", lt->vztname, ++lt->break_number); } else { memcpy(tname, lt->vztname, i); sprintf(tname+i, "_%03d.vzt", ++lt->break_number); } f2 = fopen(tname, "wb"); if(!f2) /* if error, keep writing to same output file...sorry */ { free(tname); return; } clone = fopen(lt->vztname, "rb"); if(!clone) { /* this should never happen */ fclose(f2); unlink(tname); free(tname); return; } /* clone original header */ for(cnt = 0; cnt < lt->break_header_size; cnt += sizeof(buf)) { seg = lt->break_header_size - cnt; if(seg > (off_t)sizeof(buf)) { seg = sizeof(buf); } if(fread(buf, seg, 1, clone)) { if(!fwrite(buf, seg, 1, f2)) break; /* write error! */ } } fclose(clone); fclose(lt->handle); lt->handle = f2; free(tname); } static void vzt_wr_recurse_reorder_dict(vzt_wr_dsvzt_Tree *t, struct vzt_wr_trace *lt, vztint32_t *newval, vztint32_t *bpnt, int depth) { int i, j; if(t->left) { vzt_wr_recurse_reorder_dict(t->left, lt, newval, bpnt, depth); } *bpnt = t->item; if(t->child) { vzt_wr_recurse_reorder_dict(t->child, lt, newval, bpnt+1, depth+1); } else { vztint32_t *bpnt2 = bpnt - depth + 1; t->val = *newval; /* resequence the dict entries in lexical order */ *newval = *newval+1; if(!lt->rle) { for(i=0;irle_start; vztint32_t run = 0; lt->rle_start = (*bpnt2) & 1; for(i=0;i>= 1; } } vzt_wr_emit_uv32z(lt, run); } } if(t->right) { vzt_wr_recurse_reorder_dict(t->right, lt, newval, bpnt, depth); } } static void vzt_wr_recurse_free_dict(vzt_wr_dsvzt_Tree *t) { if(t->left) { vzt_wr_recurse_free_dict(t->left); } if(t->child) { vzt_wr_recurse_free_dict(t->child); } if(t->right) { vzt_wr_recurse_free_dict(t->right); } free(t); } /* * emit granule */ void vzt_wr_flush_granule(struct vzt_wr_trace *lt, int do_finalize) { int i, j; vztsint32_t k; int val; unsigned int numticks; if(!lt->emitted) /* only happens if there are no value changes */ { vzt_wr_emitfacs(lt); lt->emitted = 1; } if(!lt->timegranule) { vzt_wr_dsvzt_Tree *t=NULL; val = 0; for(j=0;jnumfacs;j++) { struct vzt_wr_symbol *s = lt->sorted_facs[j]; for(i=0;ilen;i++) { t = vzt_wr_dsvzt_splay(s->chg[i], t); if(!vzt_wr_dsvzt_success) { t = vzt_wr_dsvzt_insert(s->chg[i], t, val++); } k = s->chg[i]; s->chg[i] = k>>31; s->prev[i] = t; } } if(lt->multi_state) for(j=0;jnumfacs;j++) { struct vzt_wr_symbol *s = lt->sorted_facs[j]; for(i=0;ilen;i++) { lt->use_multi_state |= s->chgx[i]; t = vzt_wr_dsvzt_splay(s->chgx[i], t); if(!vzt_wr_dsvzt_success) { t = vzt_wr_dsvzt_insert(s->chgx[i], t, val++); } k = s->chgx[i]; s->chgx[i] = k>>31; s->prevx[i] = t; } } lt->dict = t; } else { vzt_wr_dsvzt_Tree *t; val = 0; for(j=0;jnumfacs;j++) { struct vzt_wr_symbol *s = lt->sorted_facs[j]; for(i=0;ilen;i++) { t = s->prev[i]->child; t = vzt_wr_dsvzt_splay(s->chg[i], t); if(!vzt_wr_dsvzt_success) { t = vzt_wr_dsvzt_insert(s->chg[i], t, val++); } k = s->chg[i]; s->chg[i] = k>>31; s->prev[i]->child = t; s->prev[i] = t; } } if(lt->multi_state) for(j=0;jnumfacs;j++) { struct vzt_wr_symbol *s = lt->sorted_facs[j]; for(i=0;ilen;i++) { t = s->prevx[i]->child; lt->use_multi_state |= s->chgx[i]; t = vzt_wr_dsvzt_splay(s->chgx[i], t); if(!vzt_wr_dsvzt_success) { t = vzt_wr_dsvzt_insert(s->chgx[i], t, val++); } k = s->chgx[i]; s->chgx[i] = k>>31; s->prevx[i]->child = t; s->prevx[i] = t; } } } numticks = lt->timegranule * VZT_WR_GRANULE_SIZE + lt->timepos; lt->timepos = 0; lt->timegranule++; if((lt->timegranule >= lt->maxgranule)||(do_finalize)) { off_t clen, unclen; vztint32_t newval = 0; int attempt_break_state = 2; do { fseeko(lt->handle, 0L, SEEK_END); lt->current_chunk=lt->position = ftello(lt->handle); if((lt->break_size)&&(attempt_break_state==2)&&(lt->position >= lt->break_size)&&(lt->position != lt->break_header_size)) { vzt_wr_emit_do_breakfile(lt); attempt_break_state--; } else { attempt_break_state = 0; } } while(attempt_break_state); /* flush everything here */ fseeko(lt->handle, 0L, SEEK_END); lt->current_chunk=lt->position = ftello(lt->handle); vzt_wr_emit_u32(lt, 0); /* size of this section (uncompressed) */ vzt_wr_emit_u32(lt, 0); /* size of this section (compressed) */ vzt_wr_emit_u64(lt, 0, 0); /* begin time of section */ vzt_wr_emit_u64(lt, 0, 0); /* end time of section */ fflush(lt->handle); lt->current_chunkz = lt->position; lt->zhandle = vzt_gzdopen(lt, dup(fileno(lt->handle)), lt->zmode); lt->zpackcount = 0; if((lt->lasttime - lt->firsttime + 1) == numticks) { vzt_wr_emit_uv32z(lt, 0); /* special case for cycle simulation */ } else { vzt_wr_emit_uv32z(lt, numticks); /* number of time ticks */ for(i=0;i<((int)numticks);i++) { vzt_wr_emit_uv64z(lt, i ? lt->timetable[i] - lt->timetable[i-1] : lt->timetable[i]); /* emit delta */ } gzflush_buffered(lt, 0); } vzt_wr_emit_uv32z(lt, lt->timegranule); /* number of 32-bit sections */ lt->timegranule = 0; vzt_wr_emit_uv32z(lt, val); /* number of dict entries */ while((lt->zpackcount & 3) != 0) { vzt_wr_emit_u8z(lt, 0); /* pad to word boundary for machines which need aligned data on reads */ } { vztint32_t * buf = alloca(lt->maxgranule * sizeof(vztint32_t)); memset(buf, 0, lt->maxgranule * sizeof(vztint32_t)); if(lt->rle) lt->rle_start = 0; vzt_wr_recurse_reorder_dict(lt->dict, lt, &newval, buf, 1); } gzflush_buffered(lt, 0); vzt_wr_emit_u8z(lt, (lt->multi_state)&&(lt->use_multi_state)); /* indicates number of bitplanes past twostate */ while((lt->zpackcount & 3) != 0) { vzt_wr_emit_u8z(lt, 0); /* pad to word boundary for machines which need aligned data on reads */ } for(j=0;jnumfacs;j++) { struct vzt_wr_symbol *s = lt->sorted_facs[j]; for(i=0;ilen;i++) { vzt_wr_emit_u32rz(lt, s->prev[i]->val); } } if((lt->multi_state)&&(lt->use_multi_state)) { for(j=0;jnumfacs;j++) { struct vzt_wr_symbol *s = lt->sorted_facs[j]; for(i=0;ilen;i++) { vzt_wr_emit_u32rz(lt, s->prevx[i]->val); } } lt->use_multi_state = 0; } gzflush_buffered(lt, 0); vzt_wr_emit_uv32z(lt, lt->numstrings); if(lt->numstrings) { vzt2_wr_dsvzt_Tree *ds, *ds2; ds = lt->str_head; for(i=0;inumstrings;i++) { /* fprintf(stderr, "%8d %8d) '%s'\n", ds->val, i, ds->item); */ if(ds->val != ((vztint32_t)i)) { fprintf(stderr, "internal error line %d\n", __LINE__); exit(255); } vzt_wr_emit_stringz(lt, ds->item); ds2 = ds->next; free(ds->item); free(ds); ds = ds2; } lt->str_head = lt->str_curr = lt->str = NULL; lt->numstrings = 0; } gzflush_buffered(lt, 1); fseeko(lt->handle, 0L, SEEK_END); lt->position = ftello(lt->handle); unclen = lt->zpackcount; clen = lt->position - lt->current_chunkz; fseeko(lt->handle, lt->current_chunk, SEEK_SET); vzt_wr_emit_u32(lt, unclen); /* size of this section (uncompressed) */ vzt_wr_emit_u32(lt, clen); /* size of this section (compressed) */ if(!lt->rle) { vzt_wr_emit_u64(lt, (lt->firsttime >> 32) & 0xffffffffL, lt->firsttime & 0xffffffffL); /* begin time */ vzt_wr_emit_u64(lt, (lt->lasttime >> 32) & 0xffffffffL, lt->lasttime & 0xffffffffL); /* end time */ } else /* inverted time is the marker the reader needs to look at to see that RLE is used */ { vzt_wr_emit_u64(lt, (lt->lasttime >> 32) & 0xffffffffL, lt->lasttime & 0xffffffffL); /* end time */ vzt_wr_emit_u64(lt, (lt->firsttime >> 32) & 0xffffffffL, lt->firsttime & 0xffffffffL); /* begin time */ } fflush(lt->handle); vzt_wr_recurse_free_dict(lt->dict); lt->dict = NULL; } } int vzt_wr_set_time64(struct vzt_wr_trace *lt, vzttime_t timeval) { int rc=0; if(lt) { if(lt->timeset) { if(timeval > lt->maxtime) { if(lt->bumptime) { lt->bumptime = 0; if(!lt->flush_valid) { lt->timepos++; } else { lt->flush_valid = 0; } if(lt->timepos == VZT_WR_GRANULE_SIZE) { vzt_wr_flush_granule(lt, 0); } } lt->timetable[lt->timepos + lt->timegranule * VZT_WR_GRANULE_SIZE] = timeval; lt->lasttime = timeval; } } else { lt->timeset = 1; lt->mintime = lt->maxtime = timeval; lt->timetable[lt->timepos + lt->timegranule * VZT_WR_GRANULE_SIZE] = timeval; } if( (!lt->timepos) && (!lt->timegranule) ) { lt->firsttime = timeval; lt->lasttime = timeval; } lt->granule_dirty = 1; rc = 1; } return(rc); } /* * sets trace timescale as 10**x seconds */ void vzt_wr_set_timescale(struct vzt_wr_trace *lt, int timescale) { if(lt) { lt->timescale = timescale; } } /* * set number of granules per section * (can modify dynamically but size never can decrease) */ void vzt_wr_set_maxgranule(struct vzt_wr_trace *lt, unsigned int maxgranule) { if(lt) { if(!maxgranule) maxgranule = 8; if(maxgranule > lt->maxgranule) { vzttime_t *t = calloc(maxgranule * VZT_WR_GRANULE_SIZE, sizeof(vzttime_t)); memcpy(t, lt->timetable, lt->maxgranule * VZT_WR_GRANULE_SIZE * sizeof(vzttime_t)); free(lt->timetable); lt->timetable = t; lt->maxgranule = maxgranule; } } } /* * Sets bracket stripping (useful for VCD conversions of * bitblasted nets) */ void vzt_wr_symbol_bracket_stripping(struct vzt_wr_trace *lt, int doit) { if(lt) { lt->do_strip_brackets = (doit!=0); } } static char *vzt_wr_expand_integer_to_bits(unsigned int len, int value) { static char s[33]; char *p = s; unsigned int i; if(len>32) len=32; len--; for(i=0;i<=len;i++) { *(p++) = '0' | ((value & (1<<(len-i)))!=0); } *p = 0; return(s); } int vzt_wr_emit_value_int(struct vzt_wr_trace *lt, struct vzt_wr_symbol *s, unsigned int row, int value) { int rc=0; if((!lt)||(lt->blackout)||(!s)||(row)) return(rc); return(vzt_wr_emit_value_bit_string(lt, s, row, vzt_wr_expand_integer_to_bits(s->len, value))); } int vzt_wr_emit_value_double(struct vzt_wr_trace *lt, struct vzt_wr_symbol *s, unsigned int row, double value) { char xdrdata[8]; #if HAVE_RPC_XDR_H XDR x; #else const vztint32_t endian_matchword = 0x12345678; #endif vztint32_t msk, msk_n; int i; if((!lt)||(lt->blackout)||(!s)||(!(s->flags&VZT_WR_SYM_F_DOUBLE))||(row)) return(0); if(!lt->emitted) { vzt_wr_emitfacs(lt); lt->emitted = 1; if(!lt->timeset) { vzt_wr_set_time(lt, 0); } } while(s->aliased_to) /* find root alias if exists */ { s=s->aliased_to; } #if HAVE_RPC_XDR_H xdrmem_create(&x, xdrdata, sizeof(xdrdata), XDR_ENCODE); xdr_double(&x, &value); #else /* byte ordering in windows is reverse of XDR (on x86, that is) */ if(*((char *)&endian_matchword) == 0x78) { for(i=0;i<8;i++) { xdrdata[i] = ((char *)&value)[7-i]; } } else { memcpy(xdrdata, &value, sizeof(double)); /* big endian, don't bytereverse */ } #endif lt->bumptime = 1; msk = (~0 << lt->timepos); msk_n = ~msk; for(i=0;ilen;i++) { int byte = i/8; int bit = 7-(i&7); s->chg[i] &= msk_n; if(xdrdata[byte]&(1<chg[i] |= msk; } } lt->granule_dirty = 1; return(1); } int vzt_wr_emit_value_string(struct vzt_wr_trace *lt, struct vzt_wr_symbol *s, unsigned int row, char *value) { int rc=0; int idx; vztint32_t msk, msk_n; int i; if((!lt)||(lt->blackout)||(!s)||(!value)||(row)) return(rc); if(!lt->emitted) { vzt_wr_emitfacs(lt); lt->emitted = 1; if(!lt->timeset) { vzt_wr_set_time(lt, 0); } } while(s->aliased_to) /* find root alias if exists */ { s=s->aliased_to; } lt->str = vzt2_wr_dsvzt_splay (value, lt->str); if(!vzt2_wr_dsvzt_success) { char *vcopy = strdup(value); if(!lt->str_curr) { lt->str = vzt2_wr_dsvzt_insert(strdup(""), NULL, lt->numstrings++); /* zeroth string means no value change in future blocks */ lt->str_head = lt->str_curr = lt->str; } lt->str = vzt2_wr_dsvzt_insert(vcopy, lt->str, lt->numstrings); lt->str_curr->next = lt->str; lt->str_curr = lt->str; idx = lt->numstrings; lt->numstrings++; } else { idx = lt->str->val; } lt->bumptime = 1; msk = (~0 << lt->timepos); msk_n = ~msk; for(i=0;ilen;i++) { s->chg[i] &= msk_n; if(idx & (1 << (s->len - i - 1))) { s->chg[i] |= msk; } } lt->granule_dirty = 1; return(rc); } int vzt_wr_emit_value_bit_string(struct vzt_wr_trace *lt, struct vzt_wr_symbol *s, unsigned int row, char *value) { int rc=0; char *vfix; int valuelen; int i; vztint32_t msk, msk_n; if((!lt)||(lt->blackout)||(!s)||(!value)||(!*value)||(row)) return(rc); if(!lt->emitted) { vzt_wr_emitfacs(lt); lt->emitted = 1; if(!lt->timeset) { vzt_wr_set_time(lt, 0); } } while(s->aliased_to) /* find root alias if exists */ { s=s->aliased_to; } valuelen = strlen(value); /* ensure string is proper length */ if(valuelen == s->len) { vfix = alloca(s->len+1); strcpy(vfix, value); value = vfix; } else { vfix = alloca(s->len+1); if(valuelen < s->len) { int lendelta = s->len - valuelen; memset(vfix, (value[0]!='1') ? value[0] : '0', lendelta); strcpy(vfix+lendelta, value); } else { memcpy(vfix, value, s->len); vfix[s->len] = 0; } value = vfix; } msk = (~0 << lt->timepos); msk_n = ~msk; if(!lt->multi_state) { for(i=0;ilen;i++) { unsigned char ch = value[i]; if(ch>'1') { ch |= 1; } s->chg[i] &= msk_n; if(ch&1) { s->chg[i] |= msk; } } } else { for(i=0;ilen;i++) { /* 0 = 00, 1 = 01, x = 10, z = 11 */ unsigned char ch = value[i]; if((ch=='z')||(ch=='Z')) { ch |= 1; } s->chg[i] &= msk_n; if(ch&1) { s->chg[i] |= msk; } s->chgx[i] &= msk_n; if(ch>'1') { s->chgx[i] |= msk; } } } lt->bumptime = 1; lt->granule_dirty = 1; return(rc); } /* * dumping control */ void vzt_wr_set_dumpoff(struct vzt_wr_trace *lt) { int i, j; vztint32_t msk, msk_n; if(lt) { msk = (~0 << lt->timepos); msk_n = ~msk; for(j=0;jnumfacs;j++) { struct vzt_wr_symbol *s = lt->sorted_facs[j]; for(i=0;ilen;i++) { s->chg[i] &= msk_n; } if(lt->multi_state) { if(!(s->flags & (VZT_WR_SYM_F_INTEGER|VZT_WR_SYM_F_STRING|VZT_WR_SYM_F_DOUBLE))) { for(i=0;ilen;i++) { s->chgx[i] |= msk; } } } else { for(i=0;ilen;i++) { s->chgx[i] &= msk_n; /* simply precautionary: in case someone does assign an int to x */ } } } lt->blackout = 1; } } void vzt_wr_set_dumpon(struct vzt_wr_trace *lt) { if(lt) { lt->blackout = 0; } } /* * flush the trace... */ void vzt_wr_flush(struct vzt_wr_trace *lt) { if(lt) { if((lt->timegranule)||(lt->timepos > 0)) { if(lt->granule_dirty) { lt->timepos++; vzt_wr_flush_granule(lt, 1); } } } } /* * close out the trace and fixate it */ void vzt_wr_close(struct vzt_wr_trace *lt) { if(lt) { if(lt->granule_dirty) { lt->timepos++; vzt_wr_flush_granule(lt, 1); } if(lt->symchain) { struct vzt_wr_symbol *s = lt->symchain; struct vzt_wr_symbol *s2; while(s) { if(s->name) { free(s->name); } if(s->prev) { free(s->prev); } if(s->chg) { free(s->chg); } if(s->prevx){ free(s->prevx);} if(s->chgx) { free(s->chgx); } s2=s->symchain; free(s); s=s2; } lt->symchain = NULL; } free(lt->vztname); free(lt->timetable); free(lt->sorted_facs); fclose(lt->handle); free(lt); } } /* * set compression depth */ void vzt_wr_set_compression_depth(struct vzt_wr_trace *lt, unsigned int depth) { if(lt) { if(depth > 9) depth = 9; sprintf(lt->zmode, "wb%d", depth); } } /* * set compression type */ void vzt_wr_set_compression_type(struct vzt_wr_trace *lt, unsigned int type) { if(lt) { if((type == VZT_WR_IS_GZ) || (type == VZT_WR_IS_BZ2) || (type == VZT_WR_IS_LZMA)) { lt->ztype_cfg = type; } } } /* * set rle mode type */ void vzt_wr_set_rle(struct vzt_wr_trace *lt, unsigned int mode) { if(lt) { lt->rle = (mode != 0); } } /* * time zero offset */ void vzt_wr_set_timezero(struct vzt_wr_trace *lt, vztsint64_t timeval) { if(lt) { lt->timezero = timeval; } } gtkwave-3.3.66/src/helpers/fstminer.c0000664000076400007640000002223212357342523017032 0ustar bybellbybell/* * Copyright (c) 2012-2014 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include "fst/fstapi.h" #if HAVE_GETOPT_H #include #endif #include "wave_locale.h" static char *match = NULL; static uint32_t matchlen = 0; static int names_only = 0; static char *killed_list = NULL; char killed_value = 1; static char **fac_names = NULL; static unsigned int *scope_idx = NULL; static char **scope_names = NULL; long allocated_scopes = 1; static void strcpy_no_space(char *d, const char *s) { while(*s) { char ch = *(s++); if(ch != ' ') { *(d++) = ch; } } *d = 0; } static void extractVarNames(void *xc) { struct fstHier *h; char *s; const char *fst_scope_name = NULL; int fst_scope_name_len = 0; long snum = 0; long max_snum = 0; while((h = fstReaderIterateHier(xc))) { switch(h->htyp) { case FST_HT_SCOPE: snum = ++max_snum; fst_scope_name = fstReaderPushScope(xc, h->u.scope.name, (void *)(snum)); /* fst_scope_name_len = fstReaderGetCurrentScopeLen(xc); scan-build */ if(snum >= allocated_scopes) { long new_allocated_scopes = allocated_scopes * 2; char **scope_names_2 = calloc(new_allocated_scopes, sizeof(char *)); memcpy(scope_names_2, scope_names, allocated_scopes * sizeof(char *)); free(scope_names); scope_names = scope_names_2; allocated_scopes = new_allocated_scopes; } scope_names[snum] = strdup(fst_scope_name); break; case FST_HT_UPSCOPE: /* fst_scope_name = scan-build */ fstReaderPopScope(xc); fst_scope_name_len = fstReaderGetCurrentScopeLen(xc); snum = fst_scope_name_len ? (long)fstReaderGetCurrentScopeUserInfo(xc) : 0; break; case FST_HT_VAR: if(!h->u.var.is_alias) { scope_idx[h->u.var.handle] = snum; s = fac_names[h->u.var.handle] = malloc(h->u.var.name_length + 1); strcpy_no_space(s, h->u.var.name); } } } } static char *get_facname(void *lt, fstHandle pnt_facidx) { (void) lt; if(scope_idx[pnt_facidx] && scope_names[scope_idx[pnt_facidx]]) { char *fst_scope_name = scope_names[scope_idx[pnt_facidx]]; int fst_scope_name_len = strlen(fst_scope_name); int fst_signal_name = strlen(fac_names[pnt_facidx]); char *s = malloc(fst_scope_name_len + 1 + fst_signal_name + 1); memcpy(s, fst_scope_name, fst_scope_name_len); s[fst_scope_name_len] = '.'; memcpy(s + fst_scope_name_len + 1, fac_names[pnt_facidx], fst_signal_name + 1); return(s); } else { return(strdup(fac_names[pnt_facidx])); } } static void vcd_callback2(void *lt, uint64_t pnt_time, fstHandle pnt_facidx, const unsigned char *pnt_value, uint32_t plen) { if(plen >= matchlen) { if(!killed_list[pnt_facidx]) { if((!match) || (pnt_value /* scan-build */ && (strstr((const char *)pnt_value, match)))) { char *fn; fn = get_facname(lt, pnt_facidx); if(!names_only) { printf("#%"PRIu64" %s %s\n", pnt_time, fn, pnt_value); } else { printf("%s\n", fn); } free(fn); if(killed_value) { fstReaderClrFacProcessMask(lt, pnt_facidx); killed_list[pnt_facidx] = 1; } } } } } static void vcd_callback(void *lt, uint64_t pnt_time, fstHandle pnt_facidx, const unsigned char *pnt_value) { uint32_t plen; if(pnt_value) { plen = strlen((const char *)pnt_value); } else { plen = 0; } vcd_callback2(lt, pnt_time, pnt_facidx, pnt_value, plen); } int process_fst(char *fname) { void *lt; int i; lt=fstReaderOpen(fname); if(lt) { int numfacs; numfacs = fstReaderGetVarCount(lt) + 1; killed_list = calloc(numfacs, sizeof(char)); fac_names = calloc(numfacs, sizeof(char *)); scope_names = calloc(allocated_scopes, sizeof(char *)); scope_idx = calloc(numfacs, sizeof(unsigned int)); extractVarNames(lt); fstReaderSetFacProcessMaskAll(lt); fstReaderIterBlocks2(lt, vcd_callback, vcd_callback2, lt, NULL); for(i=0;i.\n",nam); #else printf( "Usage: %s [OPTION]... [FSTFILE]\n\n" " -d specify FST input dumpfile\n" " -m bitwise match value\n" " -x hex match value\n" " -n emit facsnames only\n" " -c do not stop after first match\n" " -h display this help then exit (gtkwave savefile)\n\n" "First occurrence of facnames with times and matching values are emitted to\nstdout. Using -n generates a gtkwave save file.\n\n" "Report bugs to <"PACKAGE_BUGREPORT">.\n",nam); #endif exit(0); } int main(int argc, char **argv) { char opt_errors_encountered=0; char *lxname=NULL; int c; int rc; uint32_t i, j, k; int comprehensive = 0; WAVE_LOCALE_FIX while (1) { #ifdef __linux__ int option_index = 0; static struct option long_options[] = { {"dumpfile", 1, 0, 'd'}, {"match", 1, 0, 'm'}, {"hex", 1, 0, 'x'}, {"namesonly", 0, 0, 'n'}, {"comprehensive", 0, 0, 'c'}, {"help", 0, 0, 'h'}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "d:m:x:nch", long_options, &option_index); #else c = getopt (argc, argv, "d:m:x:nch"); #endif if (c == -1) break; /* no more args */ switch (c) { case 'c': comprehensive = 1; break; case 'n': names_only = 1; break; case 'd': if(lxname) free(lxname); lxname = malloc(strlen(optarg)+1); strcpy(lxname, optarg); break; case 'm': if(match) free(match); match = malloc((matchlen = strlen(optarg))+1); strcpy(match, optarg); break; case 'x': if(match) free(match); match = malloc((matchlen = 4*strlen(optarg))+1); for(i=0,k=0;i='0')&&(ch<='9')) { ch -= '0'; for(j=0;j<4;j++) { match[i+j] = ((ch>>(3-j))&1) + '0'; } } else if((ch>='a')&&(ch<='f')) { ch = ch - 'a' + 10; for(j=0;j<4;j++) { match[i+j] = ((ch>>(3-j))&1) + '0'; } } else /* "x" */ { for(j=0;j<4;j++) { match[i+j] = 'x'; } } } match[matchlen] = 0; break; case 'h': print_help(argv[0]); break; case '?': opt_errors_encountered=1; break; default: /* unreachable */ break; } } if(!names_only && comprehensive) { killed_value = 0; } if(opt_errors_encountered) { print_help(argv[0]); } if (optind < argc) { while (optind < argc) { if(lxname) { free(lxname); } lxname = malloc(strlen(argv[optind])+1); strcpy(lxname, argv[optind++]); } } if(!lxname) { print_help(argv[0]); } rc=process_fst(lxname); free(match); free(lxname); return(rc); } gtkwave-3.3.66/src/helpers/evcd2vcd.c0000664000076400007640000002461112357036356016712 0ustar bybellbybell/* * Copyright (c) 2009-2014 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #if HAVE_GETOPT_H #include #endif #include "../../contrib/rtlbrowse/jrb.h" #include "wave_locale.h" #include #include #include #include #ifdef HAVE_INTTYPES_H #include #endif #include ssize_t getline_replace(char **buf, size_t *len, FILE *f) { char *fgets_rc; if(!*buf) { *buf = malloc(32768); *len = 32767; } (*buf)[0] = 0; fgets_rc = fgets(*buf, 32767, f); if((!(*buf)[0])||(!fgets_rc)) { return(-1); } else { return(1); } } JRB vcd_ids = NULL; static unsigned int vcdid_hash(char *s) { unsigned int val=0; int i; int len = strlen(s); s+=(len-1); for(i=0;i p_lo) { len = p_hi - p_lo + 1; } else { len = p_lo - p_hi + 1; } } else { len = atoi(st); } st = strtok(NULL, " \t"); /* vcdid */ hash = vcdid_hash(st); nam = strtok(NULL, " \t"); /* name */ st = strtok(NULL, " \t"); /* $end */ if(strncmp(st, "$end", 4)) { *(st-1) = ' '; } node = jrb_find_int(vcd_ids, hash); if(!node) { Jval val; jrb_insert_int(vcd_ids, hash, val)->val2.i = len; } lbrack = strchr(nam, '['); if(!lbrack) { printf("$var wire %d %s %s_I $end\n", len, vcdid_unhash(hash * 2), nam); printf("$var wire %d %s %s_O $end\n", len, vcdid_unhash(hash * 2 + 1), nam); } else { *lbrack = 0; printf("$var wire %d %s %s_I", len, vcdid_unhash(hash * 2), nam); printf("[%s $end", lbrack+1); printf("$var wire %d %s %s_O", len, vcdid_unhash(hash * 2 + 1), nam); printf("[%s $end", lbrack+1); } } else if(!strncmp(buf, "$scope", 6)) { printf("%s", buf); } else if(!strncmp(buf, "$upscope", 8)) { printf("%s", buf); } else if(!strncmp(buf, "$endd", 5)) { printf("%s", buf); break; } else if(!strncmp(buf, "$timescale", 10)) { char *pnt; ss = getline_replace(&buf, &glen, f); if(ss == -1) { break; } line++; pnt = buf; printf("$timescale\n%s$end\n", pnt); } else if(!strncmp(buf, "$date", 5)) { char *pnt; ss = getline_replace(&buf, &glen, f); if(ss == -1) { break; } line++; pnt = buf; printf("$date\n%s$end\n", pnt); } else if(!strncmp(buf, "$version", 8)) { char *pnt; ss = getline_replace(&buf, &glen, f); if(ss == -1) { break; } line++; pnt = buf; printf("$version\n%s$end\n", pnt); } } while(!feof(f)) { unsigned int hash; size_t len; char *nl, *sp; ss = getline_replace(&buf, &len, f); if(ss == -1) { break; } nl = strchr(buf, '\n'); if(nl) *nl = 0; nl = strchr(buf, '\r'); if(nl) *nl = 0; switch(buf[0]) { case 'p': { char *src = buf+1; char *pnt = bin_fixbuff; int pchar = 0; for(;;) { if(!*src) break; if(isspace((int)(unsigned char)*src)) { if(pchar != ' ') { *(pnt++) = pchar = ' '; } src++; continue; } *(pnt++) = pchar = *(src++); } *pnt = 0; sp = strchr(bin_fixbuff, ' '); sp = strchr(sp+1, ' '); sp = strchr(sp+1, ' '); *sp = 0; hash = vcdid_hash(sp+1); node = jrb_find_int(vcd_ids, hash); if(node) { bin_fixbuff[node->val2.i] = 0; if(node->val2.i == 1) { int dir; for(dir = 0; dir < 2; dir++) { evcd_strcpy(bin_fixbuff2, bin_fixbuff, dir); printf("%c%s\n", bin_fixbuff2[0], vcdid_unhash(hash*2+dir)); } } else { int dir; for(dir = 0; dir < 2; dir++) { evcd_strcpy(bin_fixbuff2, bin_fixbuff, dir); printf("b%s %s\n", bin_fixbuff2, vcdid_unhash(hash*2+dir)); } } } else { } } break; case '#': printf("%s\n", buf); break; default: if(!strncmp(buf, "$dumpon", 7)) { printf("%s\n", buf); } else if(!strncmp(buf, "$dumpoff", 8)) { printf("%s\n", buf); } else if(!strncmp(buf, "$dumpvars", 9)) { printf("%s\n", buf); } else { /* printf("EVCD '%s'\n", buf); */ } break; } } if(buf) { free(buf); } if(f != stdin) fclose(f); exit(0); } void print_help(char *nam) { #ifdef __linux__ printf( "Usage: %s [OPTION]... [EVCDFILE]\n\n" " -f, --filename=FILE specify EVCD input filename\n" " -h, --help display this help then exit\n\n" "Note that EVCDFILE is optional provided the --filename\n" "option is specified. VCD is emitted to stdout.\n\n" "Report bugs to <"PACKAGE_BUGREPORT">.\n",nam); #else printf( "Usage: %s [OPTION]... [EVCDFILE]\n\n" " -f FILE specify EVCD input filename\n" " -h display this help then exit\n\n" "Note that EVCDFILE is optional provided the --filename\n" "option is specified. VCD is emitted to stdout.\n\n" "Report bugs to <"PACKAGE_BUGREPORT">.\n",nam); #endif exit(0); } int main(int argc, char **argv) { char opt_errors_encountered=0; char *vname=NULL; int c; WAVE_LOCALE_FIX while (1) { #ifdef __linux__ int option_index = 0; static struct option long_options[] = { {"filename", 1, 0, 'f'}, {"help", 0, 0, 'h'}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "f:h", long_options, &option_index); #else c = getopt (argc, argv, "f:h"); #endif if (c == -1) break; /* no more args */ switch (c) { case 'f': if(vname) free(vname); vname = malloc(strlen(optarg)+1); strcpy(vname, optarg); break; case 'h': print_help(argv[0]); break; case '?': opt_errors_encountered=1; break; default: /* unreachable */ break; } } if(opt_errors_encountered) { print_help(argv[0]); } if (optind < argc) { while (optind < argc) { if(!vname) { vname = malloc(strlen(argv[optind])+1); strcpy(vname, argv[optind++]); } else { break; } } } if(!vname) { print_help(argv[0]); } evcd_main(vname); free(vname); return(0); } gtkwave-3.3.66/src/helpers/vztminer.c0000664000076400007640000001656512357036356017101 0ustar bybellbybell/* * Copyright (c) 2003-2009 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include "vzt_read.h" #if HAVE_GETOPT_H #include #endif #include "wave_locale.h" static char *match = NULL; static uint32_t matchlen = 0; static int names_only = 0; static char *killed_list = NULL; char killed_value = 1; char vcd_blackout; void vcd_callback(struct vzt_rd_trace **lt, vztint64_t *pnt_time, vztint32_t *pnt_facidx, char **pnt_value) { struct vzt_rd_geometry *g = vzt_rd_get_fac_geometry(*lt, *pnt_facidx); /* fprintf(stderr, VZT_RD_LLD" %d %s\n", *pnt_time, *pnt_facidx, *pnt_value); */ if(!(*pnt_value)[0]) { if(!vcd_blackout) { vcd_blackout = 1; /* printf("$dumpoff\n"); */ } return; } else { if(vcd_blackout) { vcd_blackout = 0; /* printf("$dumpon\n"); */ } } if(g->len >= matchlen) { if(!killed_list[*pnt_facidx]) { if((!match) || (strstr(*pnt_value, match))) { if(g->len > 1) { if(!names_only) { printf("#"VZT_RD_LLD" %s["VZT_RD_LD":"VZT_RD_LD"] %s\n", *pnt_time, vzt_rd_get_facname(*lt, *pnt_facidx), g->msb, g->lsb, *pnt_value); } else { printf("%s["VZT_RD_LD":"VZT_RD_LD"]\n", vzt_rd_get_facname(*lt, *pnt_facidx), g->msb, g->lsb); } } else { if(g->msb < 0) { if(!names_only) { printf("#"VZT_RD_LLD" %s %s\n", *pnt_time, vzt_rd_get_facname(*lt, *pnt_facidx), *pnt_value); } else { printf("%s\n", vzt_rd_get_facname(*lt, *pnt_facidx)); } } else { if(!names_only) { printf("#"VZT_RD_LLD" %s["VZT_RD_LD"] %s\n", *pnt_time, vzt_rd_get_facname(*lt, *pnt_facidx), g->msb, *pnt_value); } else { printf("%s["VZT_RD_LD"]\n", vzt_rd_get_facname(*lt, *pnt_facidx), g->msb); } } } if(killed_value) { vzt_rd_clr_fac_process_mask(*lt, *pnt_facidx); killed_list[*pnt_facidx] = 1; } } } } } int process_vzt(char *fname) { struct vzt_rd_trace *lt; lt=vzt_rd_init(fname); if(lt) { int numfacs; vzt_rd_vectorize(lt); /* coalesce bitblasted vectors */ numfacs = vzt_rd_get_num_facs(lt); killed_list = calloc(numfacs, sizeof(char)); vzt_rd_set_fac_process_mask_all(lt); vzt_rd_set_max_block_mem_usage(lt, 0); /* no need to cache blocks */ vzt_rd_iter_blocks(lt, vcd_callback, NULL); vzt_rd_close(lt); free(killed_list); } else { fprintf(stderr, "vzt_rd_init failed\n"); return(255); } return(0); } /*******************************************************************************/ void print_help(char *nam) { #ifdef __linux__ printf( "Usage: %s [OPTION]... [VZTFILE]\n\n" " -d, --dumpfile=FILE specify VZT input dumpfile\n" " -m, --match bitwise match value\n" " -x, --hex hex match value\n" " -n, --namesonly emit facsnames only (gtkwave savefile)\n" " -c, --comprehensive do not stop after first match\n" " -h, --help display this help then exit\n\n" "First occurrence of facnames with times and matching values are emitted to\nstdout. Using -n generates a gtkwave save file.\n\n" "Report bugs to <"PACKAGE_BUGREPORT">.\n",nam); #else printf( "Usage: %s [OPTION]... [VZTFILE]\n\n" " -d specify VZT input dumpfile\n" " -m bitwise match value\n" " -x hex match value\n" " -n emit facsnames only\n" " -c do not stop after first match\n" " -h display this help then exit (gtkwave savefile)\n\n" "First occurrence of facnames with times and matching values are emitted to\nstdout. Using -n generates a gtkwave save file.\n\n" "Report bugs to <"PACKAGE_BUGREPORT">.\n",nam); #endif exit(0); } int main(int argc, char **argv) { char opt_errors_encountered=0; char *lxname=NULL; int c; int rc; uint32_t i, j, k; int comprehensive = 0; WAVE_LOCALE_FIX while (1) { #ifdef __linux__ int option_index = 0; static struct option long_options[] = { {"dumpfile", 1, 0, 'd'}, {"match", 1, 0, 'm'}, {"hex", 1, 0, 'x'}, {"namesonly", 0, 0, 'n'}, {"comprehensive", 0, 0, 'c'}, {"help", 0, 0, 'h'}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "d:m:x:nch", long_options, &option_index); #else c = getopt (argc, argv, "d:m:x:nch"); #endif if (c == -1) break; /* no more args */ switch (c) { case 'c': comprehensive = 1; break; case 'n': names_only = 1; break; case 'd': if(lxname) free(lxname); lxname = malloc(strlen(optarg)+1); strcpy(lxname, optarg); break; case 'm': if(match) free(match); match = malloc((matchlen = strlen(optarg))+1); strcpy(match, optarg); break; case 'x': if(match) free(match); match = malloc((matchlen = 4*strlen(optarg))+1); for(i=0,k=0;i='0')&&(ch<='9')) { ch -= '0'; for(j=0;j<4;j++) { match[i+j] = ((ch>>(3-j))&1) + '0'; } } else if((ch>='a')&&(ch<='f')) { ch = ch - 'a' + 10; for(j=0;j<4;j++) { match[i+j] = ((ch>>(3-j))&1) + '0'; } } else /* "x" */ { for(j=0;j<4;j++) { match[i+j] = 'x'; } } } match[matchlen] = 0; break; case 'h': print_help(argv[0]); break; case '?': opt_errors_encountered=1; break; default: /* unreachable */ break; } } if(!names_only && comprehensive) { killed_value = 0; } if(opt_errors_encountered) { print_help(argv[0]); } if (optind < argc) { while (optind < argc) { if(lxname) { free(lxname); } lxname = malloc(strlen(argv[optind])+1); strcpy(lxname, argv[optind++]); } } if(!lxname) { print_help(argv[0]); } rc=process_vzt(lxname); free(lxname); return(rc); } gtkwave-3.3.66/src/helpers/lxt_write.c0000664000076400007640000016320612357342523017233 0ustar bybellbybell/* * Copyright (c) 2001-2012 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include "lxt_write.h" /* * in-place sort to keep chained facs from migrating... */ static void wave_mergesort(struct lt_symbol **a, struct lt_symbol **b, int lo, int hi) { int i, j, k; if (loname, a[j]->name) <= 0) { a[k++]=b[i++]; } else { a[k++]=a[j++]; } } while (kitem); if (dir < 0) { if (t->left == NULL) break; if (strcmp(i, t->left->item)<0) { y = t->left; /* rotate right */ t->left = y->right; y->right = t; t = y; if (t->left == NULL) break; } r->left = t; /* link right */ r = t; t = t->left; } else if (dir > 0) { if (t->right == NULL) break; if (strcmp(i, t->right->item)>0) { y = t->right; /* rotate left */ t->right = y->left; y->left = t; t = y; if (t->right == NULL) break; } l->right = t; /* link left */ l = t; t = t->right; } else { dslxt_success=1; break; } } l->right = t->left; /* assemble */ r->left = t->right; t->left = N.right; t->right = N.left; return t; } static dslxt_Tree * dslxt_insert(char *i, dslxt_Tree * t, unsigned int val) { /* Insert i into the tree t, unless it's already there. */ /* Return a pointer to the resulting tree. */ dslxt_Tree * n; int dir; n = (dslxt_Tree *) calloc (1, sizeof (dslxt_Tree)); if (n == NULL) { fprintf(stderr, "dslxt_insert: ran out of memory, exiting.\n"); exit(255); } n->item = i; n->val = val; if (t == NULL) { n->left = n->right = NULL; return n; } t = dslxt_splay(i,t); dir = strcmp(i,t->item); if (dir<0) { n->left = t->left; n->right = t; t->left = NULL; return n; } else if (dir>0) { n->right = t->right; n->left = t; t->right = NULL; return n; } else { /* We get here if it's already in the tree */ /* Don't add it again */ free(n); return t; } } #if 0 /* unused for now but delete is here for completeness */ static dslxt_Tree * dslxt_delete(char *i, dslxt_Tree * t) { /* Deletes i from the tree if it's there. */ /* Return a pointer to the resulting tree. */ dslxt_Tree * x; if (t==NULL) return NULL; t = dslxt_splay(i,t); if (!strcmp(i, t->item)) { /* found it */ if (t->left == NULL) { x = t->right; } else { x = dslxt_splay(i, t->left); x->right = t->right; } free(t); return x; } return t; /* It wasn't there */ } #endif /************************ splay ************************/ /* * functions which emit various big endian * data to a file */ static int lt_emit_u8(struct lt_trace *lt, int value) { unsigned char buf[1]; int nmemb; buf[0] = value & 0xff; nmemb=fwrite(buf, sizeof(char), 1, lt->handle); lt->position+=nmemb; return(nmemb); } static int lt_emit_u16(struct lt_trace *lt, int value) { unsigned char buf[2]; int nmemb; buf[0] = (value>>8) & 0xff; buf[1] = value & 0xff; nmemb = fwrite(buf, sizeof(char), 2, lt->handle); lt->position+=nmemb; return(nmemb); } static int lt_emit_u24(struct lt_trace *lt, int value) { unsigned char buf[3]; int nmemb; buf[0] = (value>>16) & 0xff; buf[1] = (value>>8) & 0xff; buf[2] = value & 0xff; nmemb=fwrite(buf, sizeof(char), 3, lt->handle); lt->position+=nmemb; return(nmemb); } static int lt_emit_u32(struct lt_trace *lt, int value) { unsigned char buf[4]; int nmemb; buf[0] = (value>>24) & 0xff; buf[1] = (value>>16) & 0xff; buf[2] = (value>>8) & 0xff; buf[3] = value & 0xff; nmemb=fwrite(buf, sizeof(char), 4, lt->handle); lt->position+=nmemb; return(nmemb); } static int lt_emit_u64(struct lt_trace *lt, int valueh, int valuel) { int rc; if((rc=lt_emit_u32(lt, valueh))) { rc=lt_emit_u32(lt, valuel); } return(rc); } static int lt_emit_double(struct lt_trace *lt, double value) { int nmemb; nmemb=fwrite(&value, sizeof(char), sizeof(double)/sizeof(char), lt->handle); lt->position+=nmemb; return(nmemb); } static int lt_emit_string(struct lt_trace *lt, char *value) { int rc=1; do { rc&=lt_emit_u8(lt, *value); } while(*(value++)); return(rc); } /* * gzfunctions which emit various big endian * data to a file. (lt->position needs to be * fixed up on gzclose so the tables don't * get out of sync!) */ static int lt_emit_u8z(struct lt_trace *lt, int value) { unsigned char buf[1]; int nmemb; buf[0] = value & 0xff; nmemb=gzwrite(lt->zhandle, buf, 1); lt->zpackcount++; lt->position++; return(nmemb); } static int lt_emit_u16z(struct lt_trace *lt, int value) { unsigned char buf[2]; int nmemb; buf[0] = (value>>8) & 0xff; buf[1] = value & 0xff; nmemb = gzwrite(lt->zhandle, buf, 2); lt->zpackcount+=2; lt->position+=2; return(nmemb); } static int lt_emit_u24z(struct lt_trace *lt, int value) { unsigned char buf[3]; int nmemb; buf[0] = (value>>16) & 0xff; buf[1] = (value>>8) & 0xff; buf[2] = value & 0xff; nmemb=gzwrite(lt->zhandle, buf, 3); lt->zpackcount+=3; lt->position+=3; return(nmemb); } static int lt_emit_u32z(struct lt_trace *lt, int value) { unsigned char buf[4]; int nmemb; buf[0] = (value>>24) & 0xff; buf[1] = (value>>16) & 0xff; buf[2] = (value>>8) & 0xff; buf[3] = value & 0xff; nmemb=gzwrite(lt->zhandle, buf, 4); lt->zpackcount+=4; lt->position+=4; return(nmemb); } static int lt_emit_u64z(struct lt_trace *lt, int valueh, int valuel) { int rc; if((rc=lt_emit_u32z(lt, valueh))) { rc=lt_emit_u32z(lt, valuel); } return(rc); } static int lt_emit_doublez(struct lt_trace *lt, double value) { int nmemb; nmemb=gzwrite(lt->zhandle, &value, sizeof(double)/sizeof(char)); lt->zpackcount+=(sizeof(double)/sizeof(char)); lt->position+=(sizeof(double)/sizeof(char));; return(nmemb); } static int lt_emit_stringz(struct lt_trace *lt, char *value) { int rc=1; do { rc&=lt_emit_u8z(lt, *value); } while(*(value++)); return(rc); } /* * bz2functions which emit various big endian * data to a file. (lt->position needs to be * fixed up on BZ2_bzclose so the tables don't * get out of sync!) */ static int lt_emit_u8bz(struct lt_trace *lt, int value) { unsigned char buf[1]; int nmemb; buf[0] = value & 0xff; nmemb=BZ2_bzwrite(lt->zhandle, buf, 1); lt->zpackcount++; lt->position++; return(nmemb); } static int lt_emit_u16bz(struct lt_trace *lt, int value) { unsigned char buf[2]; int nmemb; buf[0] = (value>>8) & 0xff; buf[1] = value & 0xff; nmemb = BZ2_bzwrite(lt->zhandle, buf, 2); lt->zpackcount+=2; lt->position+=2; return(nmemb); } static int lt_emit_u24bz(struct lt_trace *lt, int value) { unsigned char buf[3]; int nmemb; buf[0] = (value>>16) & 0xff; buf[1] = (value>>8) & 0xff; buf[2] = value & 0xff; nmemb=BZ2_bzwrite(lt->zhandle, buf, 3); lt->zpackcount+=3; lt->position+=3; return(nmemb); } static int lt_emit_u32bz(struct lt_trace *lt, int value) { unsigned char buf[4]; int nmemb; buf[0] = (value>>24) & 0xff; buf[1] = (value>>16) & 0xff; buf[2] = (value>>8) & 0xff; buf[3] = value & 0xff; nmemb=BZ2_bzwrite(lt->zhandle, buf, 4); lt->zpackcount+=4; lt->position+=4; return(nmemb); } static int lt_emit_u64bz(struct lt_trace *lt, int valueh, int valuel) { int rc; if((rc=lt_emit_u32bz(lt, valueh))) { rc=lt_emit_u32bz(lt, valuel); } return(rc); } static int lt_emit_doublebz(struct lt_trace *lt, double value) { int nmemb; nmemb=BZ2_bzwrite(lt->zhandle, &value, sizeof(double)/sizeof(char)); lt->zpackcount+=(sizeof(double)/sizeof(char)); lt->position+=(sizeof(double)/sizeof(char));; return(nmemb); } static int lt_emit_stringbz(struct lt_trace *lt, char *value) { int rc=1; do { rc&=lt_emit_u8bz(lt, *value); } while(*(value++)); return(rc); } /* * switch between compression modes above */ static void lt_set_zmode(struct lt_trace *lt, int mode) { switch(mode) { case LT_ZMODE_NONE: lt->lt_emit_u8 = lt_emit_u8; lt->lt_emit_u16 = lt_emit_u16; lt->lt_emit_u24 = lt_emit_u24; lt->lt_emit_u32 = lt_emit_u32; lt->lt_emit_u64 = lt_emit_u64; lt->lt_emit_double = lt_emit_double; lt->lt_emit_string = lt_emit_string; break; case LT_ZMODE_GZIP: lt->lt_emit_u8 = lt_emit_u8z; lt->lt_emit_u16 = lt_emit_u16z; lt->lt_emit_u24 = lt_emit_u24z; lt->lt_emit_u32 = lt_emit_u32z; lt->lt_emit_u64 = lt_emit_u64z; lt->lt_emit_double = lt_emit_doublez; lt->lt_emit_string = lt_emit_stringz; break; case LT_ZMODE_BZIP2: lt->lt_emit_u8 = lt_emit_u8bz; lt->lt_emit_u16 = lt_emit_u16bz; lt->lt_emit_u24 = lt_emit_u24bz; lt->lt_emit_u32 = lt_emit_u32bz; lt->lt_emit_u64 = lt_emit_u64bz; lt->lt_emit_double = lt_emit_doublebz; lt->lt_emit_string = lt_emit_stringbz; break; } } /* * hash/symtable manipulation */ static int lt_hash(const char *s) { const char *p; char ch; unsigned int h=0, h2=0, pos=0, g; for(p=s;*p;p++) { ch=*p; h2<<=3; h2-=((unsigned int)ch+(pos++)); /* this handles stranded vectors quite well.. */ h=(h<<4)+ch; if((g=h&0xf0000000)) { h=h^(g>>24); h=h^g; } } h^=h2; /* combine the two hashes */ return(h%LT_SYMPRIME); } static struct lt_symbol *lt_symadd(struct lt_trace *lt, const char *name, int hv) { struct lt_symbol *s; s=(struct lt_symbol *)calloc(1,sizeof(struct lt_symbol)); strcpy(s->name=(char *)malloc((s->namlen=strlen(name))+1),name); s->next=lt->sym[hv]; lt->sym[hv]=s; return(s); } static struct lt_symbol *lt_symfind(struct lt_trace *lt, const char *s) { int hv; struct lt_symbol *temp; hv=lt_hash(s); if(!(temp=lt->sym[hv])) return(NULL); /* no hash entry, add here wanted to add */ while(temp) { if(!strcmp(temp->name,s)) { return(temp); /* in table already */ } if(!temp->next) break; temp=temp->next; } return(NULL); /* not found, add here if you want to add*/ } /* * compress facs to a prefix count + string + 0x00 */ static void lt_compress_fac(struct lt_trace *lt, char *str) { int i; int len = strlen(str); int minlen = (lencompress_fac_len) ? len : lt->compress_fac_len; if(minlen>65535) minlen=65535; /* keep in printable range--most hierarchies won't be this big anyway */ if(lt->compress_fac_str) { for(i=0;icompress_fac_str[i]!=str[i]) break; } lt_emit_u16z(lt, i); lt_emit_stringz(lt, str+i); free(lt->compress_fac_str); } else { lt_emit_u16z(lt, 0); lt_emit_stringz(lt, str); } lt->compress_fac_str = (char *) malloc((lt->compress_fac_len=len)+1); strcpy(lt->compress_fac_str, str); } static void strip_brack(struct lt_symbol *s) { char *lastch = s->name+s->namlen - 1; if(*lastch!=']') return; if(s->namlen<3) return; lastch--; while(lastch!=s->name) { if(*lastch=='.') { return; /* MTI SV [0.3] notation for implicit vars */ } if(*lastch=='[') { *lastch=0x00; return; } lastch--; } return; } static void lt_emitfacs(struct lt_trace *lt) { int i; if((lt)&&(lt->numfacs)) { struct lt_symbol *s = lt->symchain; char is_interlaced_trace = (lt->sorted_facs==NULL); if(!lt->sorted_facs) { if((lt->sorted_facs = (struct lt_symbol **)calloc(lt->numfacs, sizeof(struct lt_symbol *)))) { if(lt->do_strip_brackets) for(i=0;inumfacs;i++) { lt->sorted_facs[lt->numfacs - i - 1] = s; /* facs were chained backwards so reverse to restore bitslicing */ strip_brack(s); s=s->symchain; } else for(i=0;inumfacs;i++) { lt->sorted_facs[lt->numfacs - i - 1] = s; /* facs were chained backwards so reverse to restore bitslicing*/ s=s->symchain; } wave_msort(lt->sorted_facs, lt->numfacs); for(i=0;inumfacs;i++) { lt->sorted_facs[i]->facnum = i; } } } if(lt->sorted_facs) { lt->facname_offset=lt->position; lt_emit_u32(lt, lt->numfacs); /* uncompressed */ lt_emit_u32(lt, lt->numfacbytes); /* uncompressed */ fflush(lt->handle); lt->zfacname_size = lt->position; lt->zhandle = gzdopen(dup(fileno(lt->handle)), "wb9"); lt->zpackcount = 0; for(i=0;inumfacs;i++) { lt_compress_fac(lt, lt->sorted_facs[i]->name); } free(lt->compress_fac_str); lt->compress_fac_str=NULL; lt->compress_fac_len=0; lt->zfacname_predec_size = lt->zpackcount; gzclose(lt->zhandle); fseeko(lt->handle, 0L, SEEK_END); lt->position=ftello(lt->handle); lt->zfacname_size = lt->position - lt->zfacname_size; lt->zhandle = gzdopen(dup(fileno(lt->handle)), "wb9"); lt->facgeometry_offset = lt->position; for(i=0;inumfacs;i++) { if((lt->sorted_facs[i]->flags<_SYM_F_ALIAS)==0) { lt_emit_u32z(lt, lt->sorted_facs[i]->rows); lt_emit_u32z(lt, lt->sorted_facs[i]->msb); lt_emit_u32z(lt, lt->sorted_facs[i]->lsb); lt_emit_u32z(lt, lt->sorted_facs[i]->flags); } else { lt_emit_u32z(lt, lt->sorted_facs[i]->aliased_to->facnum); lt_emit_u32z(lt, lt->sorted_facs[i]->msb); lt_emit_u32z(lt, lt->sorted_facs[i]->lsb); lt_emit_u32z(lt, LT_SYM_F_ALIAS); } } gzclose(lt->zhandle); fseeko(lt->handle, 0L, SEEK_END); lt->position=ftello(lt->handle); lt->zfacgeometry_size = lt->position - lt->facgeometry_offset; if(is_interlaced_trace) { lt->zhandle = gzdopen(dup(fileno(lt->handle)), "wb9"); lt->sync_table_offset = lt->position; for(i=0;inumfacs;i++) { lt_emit_u32z(lt, lt->sorted_facs[i]->last_change); } gzclose(lt->zhandle); lt->zhandle = NULL; fseeko(lt->handle, 0L, SEEK_END); lt->position=ftello(lt->handle); lt->zsync_table_size = lt->position - lt->sync_table_offset; } } } } /* * initialize the trace and get back an lt context */ struct lt_trace *lt_init(const char *name) { struct lt_trace *lt=(struct lt_trace *)calloc(1, sizeof(struct lt_trace)); if(!(lt->handle=fopen(name, "wb"))) { free(lt); lt=NULL; } else { lt_emit_u16(lt, LT_HDRID); lt_emit_u16(lt, LT_VERSION); lt->change_field_offset = lt->position; lt->initial_value = -1; /* if a user sets this it will have a different POSITIVE val */ lt->timescale = -256; /* will be in range of -128<=x<=127 if set */ lt_set_zmode(lt, LT_ZMODE_NONE); lt->mintime=ULLDescriptor(1); lt->maxtime=ULLDescriptor(0); } return(lt); } /* * clock flushing.. */ static void lt_flushclock(struct lt_trace *lt, struct lt_symbol *s) { unsigned int last_change_delta = lt->position - s->last_change - 2; unsigned int start_position = lt->position; int tag; int numbytes, numbytes_trans; int numtrans = s->clk_numtrans - LT_CLKPACK - 1; if(numtrans<0) { /* it never got around to caching */ fprintf(stderr, "Possible Problem with %s with %d?\n", s->name, s->clk_numtrans); return; } if(numtrans >= 256*65536) { numbytes_trans = 3; } else if(numtrans >= 65536) { numbytes_trans = 2; } else if(numtrans >= 256) { numbytes_trans = 1; } else { numbytes_trans = 0; } if(!lt->numfacs_bytes) { if(last_change_delta >= 256*65536) { numbytes = 3; } else if(last_change_delta >= 65536) { numbytes = 2; } else if(last_change_delta >= 256) { numbytes = 1; } else { numbytes = 0; } tag = (numbytes<<4) + 0xC + numbytes_trans; /* yields xC..xF */ lt->lt_emit_u8(lt, tag); switch(numbytes&3) { case 0: lt->lt_emit_u8(lt, last_change_delta); break; case 1: lt->lt_emit_u16(lt, last_change_delta); break; case 2: lt->lt_emit_u24(lt, last_change_delta); break; case 3: lt->lt_emit_u32(lt, last_change_delta); break; } } else { tag = 0xC + numbytes_trans; /* yields C..F */ switch(lt->numfacs_bytes) { case 1: lt->lt_emit_u8(lt, s->facnum); break; case 2: lt->lt_emit_u16(lt, s->facnum); break; case 3: lt->lt_emit_u24(lt, s->facnum); break; case 4: lt->lt_emit_u32(lt, s->facnum); break; } lt->lt_emit_u8(lt, tag); } s->last_change = start_position; /* s->clk_prevval CAN BE INFERRED! */ /* s->clk_prevtrans CAN BE INFERRED! */ /* s->clk_delta CAN BE INFERRED! */ switch(numbytes_trans&3) { case 0: lt->lt_emit_u8(lt, numtrans); break; case 1: lt->lt_emit_u16(lt, numtrans); break; case 2: lt->lt_emit_u24(lt, numtrans); break; case 3: lt->lt_emit_u32(lt, numtrans); break; } /* printf("Clock finish for '%s' at %lld ending with '%c' for %d repeats over a switch delta of %d\n", s->name, lt->timeval, s->clk_prevval, s->clk_numtrans - LT_CLKPACK, s->clk_delta); */ s->clk_prevtrans = ULLDescriptor(~0); s->clk_numtrans = 0; } static void lt_flushclock_m(struct lt_trace *lt, struct lt_symbol *s) { unsigned int last_change_delta = lt->position - s->last_change - 2; unsigned int start_position = lt->position; int tag; int numbytes, numbytes_trans; int numtrans = s->clk_numtrans - LT_CLKPACK_M - 1; if(numtrans<0) { /* it never got around to caching */ fprintf(stderr, "Possible Problem with %s with %d?\n", s->name, s->clk_numtrans); return; } if(numtrans >= 256*65536) { numbytes_trans = 3; } else if(numtrans >= 65536) { numbytes_trans = 2; } else if(numtrans >= 256) { numbytes_trans = 1; } else { numbytes_trans = 0; } if(!lt->numfacs_bytes) { if(last_change_delta >= 256*65536) { numbytes = 3; } else if(last_change_delta >= 65536) { numbytes = 2; } else if(last_change_delta >= 256) { numbytes = 1; } else { numbytes = 0; } tag = (numbytes<<4) + 0xC + numbytes_trans; /* yields xC..xF */ lt->lt_emit_u8(lt, tag); switch(numbytes&3) { case 0: lt->lt_emit_u8(lt, last_change_delta); break; case 1: lt->lt_emit_u16(lt, last_change_delta); break; case 2: lt->lt_emit_u24(lt, last_change_delta); break; case 3: lt->lt_emit_u32(lt, last_change_delta); break; } } else { tag = 0xC + numbytes_trans; /* yields C..F */ switch(lt->numfacs_bytes) { case 1: lt->lt_emit_u8(lt, s->facnum); break; case 2: lt->lt_emit_u16(lt, s->facnum); break; case 3: lt->lt_emit_u24(lt, s->facnum); break; case 4: lt->lt_emit_u32(lt, s->facnum); break; } lt->lt_emit_u8(lt, tag); } s->last_change = start_position; /* s->clk_prevval CAN BE INFERRED! */ /* s->clk_prevtrans CAN BE INFERRED! */ /* s->clk_delta CAN BE INFERRED! */ switch(numbytes_trans&3) { case 0: lt->lt_emit_u8(lt, numtrans); break; case 1: lt->lt_emit_u16(lt, numtrans); break; case 2: lt->lt_emit_u24(lt, numtrans); break; case 3: lt->lt_emit_u32(lt, numtrans); break; } /* printf("Clock finish for '%s' at %lld ending with '%08x' for %d repeats over a switch delta of %lld\n", s->name, lt->timeval, s->clk_prevval, s->clk_numtrans - LT_CLKPACK_M, s->clk_delta); */ s->clk_prevtrans = ULLDescriptor(~0); s->clk_numtrans = 0; } /* * recurse through dictionary */ static void lt_recurse_dictionary(struct lt_trace *lt, dslxt_Tree *ds) { if(ds->left) lt_recurse_dictionary(lt, ds->left); lt->sorted_dict[ds->val] = ds; if(ds->right) lt_recurse_dictionary(lt, ds->right); } static void lt_recurse_dictionary_free(struct lt_trace *lt, dslxt_Tree *ds) { dslxt_Tree *lft = ds->left; dslxt_Tree *rgh = ds->right; if(lft) lt_recurse_dictionary_free(lt, lft); free(ds->item); free(ds); if(rgh) lt_recurse_dictionary_free(lt, rgh); } static int lt_dictval_compare(const void *v1, const void *v2) { const dslxt_Tree *s1 = *(const dslxt_Tree * const *)v1; const dslxt_Tree *s2 = *(const dslxt_Tree * const *)v2; if(s1->val > s2->val) return(1); else return(-1); /* they're *never* equal */ } static void lt_finalize_dictionary(struct lt_trace *lt) { unsigned int i; lt->sorted_dict = calloc(lt->num_dict_entries, sizeof(dslxt_Tree *)); lt->dictionary_offset=lt->position; lt_emit_u32(lt, lt->num_dict_entries); /* uncompressed */ lt_emit_u32(lt, lt->dict_string_mem_required - lt->num_dict_entries); /* uncompressed : minus because leading '1' is implied so its stripped */ lt_emit_u32(lt, lt->dict16_offset); /* uncompressed */ lt_emit_u32(lt, lt->dict24_offset); /* uncompressed */ lt_emit_u32(lt, lt->dict32_offset); /* uncompressed */ lt_emit_u32(lt, lt->mindictwidth); /* uncompressed */ fflush(lt->handle); #if 0 fprintf(stderr, "*** dictionary_offset = %08x\n", lt->dictionary_offset); fprintf(stderr, "*** num_dict_entries = %d\n", lt->num_dict_entries); #endif lt->zdictionary_size = lt->position; lt->zhandle = gzdopen(dup(fileno(lt->handle)), "wb9"); lt_recurse_dictionary(lt, lt->dict); qsort((void *)lt->sorted_dict, lt->num_dict_entries, sizeof(struct dsTree **), lt_dictval_compare); for(i=0;inum_dict_entries;i++) { dslxt_Tree *ds = lt->sorted_dict[i]; /* fprintf(stderr, "%8d) '%s'\n", ds->val, ds->item); */ lt_emit_stringz(lt, ds->item+1); } gzclose(lt->zhandle); fseeko(lt->handle, 0L, SEEK_END); lt->position=ftello(lt->handle); lt->zdictionary_size = lt->position - lt->zdictionary_size; free(lt->sorted_dict); lt->sorted_dict = NULL; lt_recurse_dictionary_free(lt, lt->dict); lt->dict = NULL; } /* * close out the trace and fixate it */ void lt_close(struct lt_trace *lt) { lxttime_t lasttime=ULLDescriptor(0); int lastposition=0; char is64=0; if(lt) { struct lt_symbol *s = lt->symchain; if(lt->clock_compress) while(s) { if(s->clk_prevtrans!=ULLDescriptor(~0)) { int len = ((s->flags)<_SYM_F_INTEGER) ? 32 : s->len; if(len>1) { if(s->clk_numtrans > LT_CLKPACK_M) lt_flushclock_m(lt, s); } else { if(s->clk_numtrans > LT_CLKPACK) lt_flushclock(lt, s); } } s=s->symchain; } lt_set_dumpon(lt); /* in case it was turned off */ if(lt->zmode!=LT_ZMODE_NONE) { lt->chg_table_size = lt->position - lt->change_field_offset; switch(lt->zmode) { case LT_ZMODE_GZIP: gzclose(lt->zhandle); break; case LT_ZMODE_BZIP2: BZ2_bzclose(lt->zhandle); break; } lt->zhandle = NULL; fseeko(lt->handle, 0L, SEEK_END); lt->position=ftello(lt->handle); lt_set_zmode(lt, LT_ZMODE_NONE); lt->zchg_table_size = lt->position - lt->change_field_offset; } lt_emitfacs(lt); if(lt->dict) lt_finalize_dictionary(lt); free(lt->timebuff); lt->timebuff=NULL; if(lt->timehead) { struct lt_timetrail *t=lt->timehead; struct lt_timetrail *t2; lt->time_table_offset = lt->position; lt_emit_u32(lt, lt->timechangecount); /* this is uncompressed! */ fflush(lt->handle); lt->zhandle = gzdopen(dup(fileno(lt->handle)), "wb9"); lt->ztime_table_size = lt->position; is64=(lt->maxtime > ULLDescriptor(0xFFFFFFFF)); if(is64) { lt_emit_u64z(lt, (int)((lt->mintime)>>32), (int)lt->mintime); lt_emit_u64z(lt, (int)((lt->maxtime)>>32), (int)lt->maxtime); } else { lt_emit_u32z(lt, (int)lt->mintime); lt_emit_u32z(lt, (int)lt->maxtime); } while(t) { lt_emit_u32z(lt, t->position - lastposition); lastposition = t->position; t=t->next; } t=lt->timehead; if(is64) { while(t) { lxttime_t delta = t->timeval - lasttime; lt_emit_u64z(lt, (int)(delta>>32), (int)delta); lasttime = t->timeval; t2=t->next; free(t); t=t2; } } else { while(t) { lt_emit_u32z(lt, (int)(t->timeval - lasttime)); lasttime = t->timeval; t2=t->next; free(t); t=t2; } lt->timehead = lt->timecurr = NULL; } gzclose(lt->zhandle); lt->zhandle = NULL; fseeko(lt->handle, 0L, SEEK_END); lt->position=ftello(lt->handle); lt->ztime_table_size = lt->position - lt->ztime_table_size; } if(lt->initial_value>=0) { lt->initial_value_offset = lt->position; lt_emit_u8(lt, lt->initial_value); } if((lt->timescale>-129)&&(lt->timescale<128)) { lt->timescale_offset = lt->position; lt_emit_u8(lt, lt->timescale); } if(lt->double_used) { lt->double_test_offset = lt->position; lt_emit_double(lt, 3.14159); } if(lt->dumpoffcount) { struct lt_timetrail *ltt = lt->dumpoffhead; struct lt_timetrail *ltt2; lt->exclude_offset = lt->position; lt_emit_u32(lt, lt->dumpoffcount); while(ltt) { lt_emit_u64(lt, (int)((ltt->timeval)>>32), (int)ltt->timeval); ltt2 = ltt; ltt=ltt->next; free(ltt2); } lt->dumpoffhead = lt->dumpoffcurr = NULL; lt->dumpoffcount = 0; } if(lt->timezero) { lt->timezero_offset = lt->position; lt_emit_u64(lt, (int)((lt->timezero)>>32), (int)lt->timezero); } /* prefix */ lt_emit_u8(lt, LT_SECTION_END); /* Version 1 */ if(lt->change_field_offset) { lt_emit_u32(lt, lt->change_field_offset); lt_emit_u8(lt, LT_SECTION_CHG); lt->change_field_offset = 0; } if(lt->sync_table_offset) { lt_emit_u32(lt, lt->sync_table_offset); lt_emit_u8(lt, LT_SECTION_SYNC_TABLE); lt->sync_table_offset = 0; } if(lt->facname_offset) { lt_emit_u32(lt, lt->facname_offset); lt_emit_u8(lt, LT_SECTION_FACNAME); lt->facname_offset = 0; } if(lt->facgeometry_offset) { lt_emit_u32(lt, lt->facgeometry_offset); lt_emit_u8(lt, LT_SECTION_FACNAME_GEOMETRY); lt->facgeometry_offset = 0; } if(lt->timescale_offset) { lt_emit_u32(lt, lt->timescale_offset); lt_emit_u8(lt, LT_SECTION_TIMESCALE); lt->timescale_offset = 0; } if(lt->time_table_offset) { lt_emit_u32(lt, lt->time_table_offset); lt_emit_u8(lt, is64 ? LT_SECTION_TIME_TABLE64 : LT_SECTION_TIME_TABLE); lt->time_table_offset = 0; } if(lt->initial_value_offset) { lt_emit_u32(lt, lt->initial_value_offset); lt_emit_u8(lt, LT_SECTION_INITIAL_VALUE); lt->initial_value_offset = 0; } if(lt->double_test_offset) { lt_emit_u32(lt, lt->double_test_offset); lt_emit_u8(lt, LT_SECTION_DOUBLE_TEST); lt->double_test_offset = 0; } /* Version 2 adds */ if(lt->zfacname_predec_size) { lt_emit_u32(lt, lt->zfacname_predec_size); lt_emit_u8(lt, LT_SECTION_ZFACNAME_PREDEC_SIZE); lt->zfacname_predec_size = 0; } if(lt->zfacname_size) { lt_emit_u32(lt, lt->zfacname_size); lt_emit_u8(lt, LT_SECTION_ZFACNAME_SIZE); lt->zfacname_size = 0; } if(lt->zfacgeometry_size) { lt_emit_u32(lt, lt->zfacgeometry_size); lt_emit_u8(lt, LT_SECTION_ZFACNAME_GEOMETRY_SIZE); lt->zfacgeometry_size = 0; } if(lt->zsync_table_size) { lt_emit_u32(lt, lt->zsync_table_size); lt_emit_u8(lt, LT_SECTION_ZSYNC_SIZE); lt->zsync_table_size = 0; } if(lt->ztime_table_size) { lt_emit_u32(lt, lt->ztime_table_size); lt_emit_u8(lt, LT_SECTION_ZTIME_TABLE_SIZE); lt->ztime_table_size = 0; } if(lt->chg_table_size) { lt_emit_u32(lt, lt->chg_table_size); lt_emit_u8(lt, LT_SECTION_ZCHG_PREDEC_SIZE); lt->chg_table_size = 0; } if(lt->zchg_table_size) { lt_emit_u32(lt, lt->zchg_table_size); lt_emit_u8(lt, LT_SECTION_ZCHG_SIZE); lt->zchg_table_size = 0; } /* Version 4 adds */ if(lt->dictionary_offset) { lt_emit_u32(lt, lt->dictionary_offset); lt_emit_u8(lt, LT_SECTION_ZDICTIONARY); lt->dictionary_offset = 0; } if(lt->zdictionary_size) { lt_emit_u32(lt, lt->zdictionary_size); lt_emit_u8(lt, LT_SECTION_ZDICTIONARY_SIZE); lt->zdictionary_size = 0; } /* Version 5 adds */ if(lt->exclude_offset) { lt_emit_u32(lt, lt->exclude_offset); lt_emit_u8(lt, LT_SECTION_EXCLUDE_TABLE); lt->exclude_offset = 0; } /* Version 6 adds */ if(lt->timezero_offset) { lt_emit_u32(lt, lt->timezero_offset); lt_emit_u8(lt, LT_SECTION_TIMEZERO); lt->timezero_offset = 0; } /* suffix */ lt_emit_u8(lt, LT_TRLID); if(lt->symchain) { struct lt_symbol *sc = lt->symchain; struct lt_symbol *s2; while(sc) { free(sc->name); s2=sc->symchain; free(sc); sc=s2; } } free(lt->sorted_facs); fclose(lt->handle); free(lt); } } /* * maint function for finding a symbol if it exists */ struct lt_symbol *lt_symbol_find(struct lt_trace *lt, const char *name) { struct lt_symbol *s=NULL; if((lt)&&(name)) s=lt_symfind(lt, name); return(s); } /* * add a trace (if it doesn't exist already) */ struct lt_symbol *lt_symbol_add(struct lt_trace *lt, const char *name, unsigned int rows, int msb, int lsb, int flags) { struct lt_symbol *s; int len; int flagcnt; if((!lt)||(lt->sorted_facs)) return(NULL); flagcnt = ((flags<_SYM_F_INTEGER)!=0) + ((flags<_SYM_F_DOUBLE)!=0) + ((flags<_SYM_F_STRING)!=0); if((flagcnt>1)||(!lt)||(!name)||(lt_symfind(lt, name))) return (NULL); if(flags<_SYM_F_DOUBLE) lt->double_used = 1; s=lt_symadd(lt, name, lt_hash(name)); s->rows = rows; s->flags = flags&(~LT_SYM_F_ALIAS); /* aliasing makes no sense here.. */ if(!flagcnt) { s->msb = msb; s->lsb = lsb; s->len = (msblen==1)&&(s->rows==0)) s->clk_prevtrans = ULLDescriptor(~0); } s->symchain = lt->symchain; lt->symchain = s; lt->numfacs++; if((len=strlen(name)) > lt->longestname) lt->longestname = len; lt->numfacbytes += (len+1); return(s); } /* * add an alias trace (if it doesn't exist already and orig is found) */ struct lt_symbol *lt_symbol_alias(struct lt_trace *lt, const char *existing_name, const char *alias, int msb, int lsb) { struct lt_symbol *s, *sa; int len; int bitlen; int flagcnt; if((!lt)||(!existing_name)||(!alias)||(!(s=lt_symfind(lt, existing_name)))||(lt_symfind(lt, alias))) return (NULL); if(lt->sorted_facs) return(NULL); while(s->aliased_to) /* find root alias */ { s=s->aliased_to; } flagcnt = ((s->flags<_SYM_F_INTEGER)!=0) + ((s->flags<_SYM_F_DOUBLE)!=0) + ((s->flags<_SYM_F_STRING)!=0); bitlen = (msblen)) return(NULL); sa=lt_symadd(lt, alias, lt_hash(alias)); sa->flags = LT_SYM_F_ALIAS; /* only point this can get set */ sa->aliased_to = s; if(!flagcnt) { sa->msb = msb; sa->lsb = lsb; sa->len = bitlen; } sa->symchain = lt->symchain; lt->symchain = sa; lt->numfacs++; if((len=strlen(alias)) > lt->longestname) lt->longestname = len; lt->numfacbytes += (len+1); return(sa); } /* * set current time */ int lt_inc_time_by_delta(struct lt_trace *lt, unsigned int timeval) { return(lt_set_time64(lt, lt->maxtime + (lxttime_t)timeval)); } int lt_set_time(struct lt_trace *lt, unsigned int timeval) { return(lt_set_time64(lt, (lxttime_t)timeval)); } int lt_inc_time_by_delta64(struct lt_trace *lt, lxttime_t timeval) { return(lt_set_time64(lt, lt->maxtime + timeval)); } int lt_set_time64(struct lt_trace *lt, lxttime_t timeval) { int rc=0; if(lt) { struct lt_timetrail *trl=(struct lt_timetrail *)calloc(1, sizeof(struct lt_timetrail)); if(trl) { trl->timeval = timeval; trl->position = lt->position; if((lt->timecurr)||(lt->timebuff)) { if(((timeval>lt->mintime)&&(timeval>lt->maxtime))||((lt->mintime==ULLDescriptor(1))&&(lt->maxtime==ULLDescriptor(0)))) { lt->maxtime = timeval; } else { free(trl); goto bail; } } else { lt->mintime = lt->maxtime = timeval; } free(lt->timebuff); lt->timebuff = trl; lt->timeval = timeval; rc=1; } } bail: return(rc); } /* * sets trace timescale as 10**x seconds */ void lt_set_timescale(struct lt_trace *lt, int timescale) { if(lt) { lt->timescale = timescale; } } /* * sets clock compression heuristic */ void lt_set_clock_compress(struct lt_trace *lt) { if(lt) { lt->clock_compress = 1; } } /* * sets change dump compression */ void lt_set_chg_compress(struct lt_trace *lt) { if(lt) { if((lt->zmode==LT_ZMODE_NONE)&&(!lt->emitted)) { lt_set_zmode(lt, lt->zmode = LT_ZMODE_GZIP); fflush(lt->handle); lt->zhandle = gzdopen(dup(fileno(lt->handle)), "wb9"); } } } /* * sets change dictionary compression */ void lt_set_dict_compress(struct lt_trace *lt, unsigned int minwidth) { if((lt)&&(!lt->emitted)) { lt->dictmode = 1; if(minwidth>1) { lt->mindictwidth = minwidth; } } } /* * sets change interlace */ void lt_set_no_interlace(struct lt_trace *lt) { if((lt)&&(!lt->emitted)&&(!lt->sorted_facs)) { if(lt->zmode==LT_ZMODE_NONE) /* this mode implies BZIP2 compression! */ { lt_set_zmode(lt, lt->zmode = LT_ZMODE_BZIP2); fflush(lt->handle); lt->zhandle = BZ2_bzdopen(dup(fileno(lt->handle)), "wb9"); } if((lt->sorted_facs = (struct lt_symbol **)calloc(lt->numfacs, sizeof(struct lt_symbol *)))) { struct lt_symbol *s = lt->symchain; int i; if(lt->do_strip_brackets) for(i=0;inumfacs;i++) { lt->sorted_facs[lt->numfacs - i - 1] = s; /* facs were chained backwards so reverse to restore bitslicing */ strip_brack(s); s=s->symchain; } else for(i=0;inumfacs;i++) { lt->sorted_facs[lt->numfacs - i - 1] = s; /* facs were chained backwards so reverse to restore bitslicing */ s=s->symchain; } wave_msort(lt->sorted_facs, lt->numfacs); for(i=0;inumfacs;i++) { lt->sorted_facs[i]->facnum = i; } if(lt->numfacs >= 256*65536) { lt->numfacs_bytes = 4; } else if(lt->numfacs >= 65536) { lt->numfacs_bytes = 3; } else if(lt->numfacs >= 256) { lt->numfacs_bytes = 2; } else { lt->numfacs_bytes = 1; } } } } /* * sets trace initial value */ void lt_set_initial_value(struct lt_trace *lt, char value) { if(lt) { int tag; switch(value) { case '0': tag = 0; break; case '1': tag = 1; break; case 'Z': case 'z': tag = 2; break; case 'X': case 'x': tag = 3; break; case 'H': case 'h': tag = 4; break; case 'U': case 'u': tag = 5; break; case 'W': case 'w': tag = 6; break; case 'L': case 'l': tag = 0x7; break; case '-': tag = 0x8; break; default: tag = -1; break; } lt->initial_value = tag; } } /* * Sets bracket stripping (useful for VCD conversions of * bitblasted nets) */ void lt_symbol_bracket_stripping(struct lt_trace *lt, int doit) { if(lt) { lt->do_strip_brackets = (doit!=0); } } /* * emission for trace values.. */ static int lt_optimask[]= { 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff }; static char *lt_expand_integer_to_bits(int len, int value) { static char s[33]; char *p = s; int i; len--; for(i=0;i<=len;i++) { *(p++) = '0' | ((value & (1<<(len-i)))!=0); } *p = 0; return(s); } int lt_emit_value_int(struct lt_trace *lt, struct lt_symbol *s, unsigned int row, int value) { int rc=0; if((!lt)||(!s)) return(rc); if(!lt->emitted) lt->emitted = 1; while(s->aliased_to) /* find root alias if exists */ { s=s->aliased_to; } if(!(s->flags&(LT_SYM_F_DOUBLE|LT_SYM_F_STRING))) { int numbytes; /* number of bytes to store value minus one */ unsigned int len = ((s->flags)<_SYM_F_INTEGER) ? 32 : s->len; unsigned int last_change_delta; if((lt->clock_compress)&&(s->rows==0)) { if((len>1)&&(len<=32)) { int ivalue = value; int delta1, delta2; s->clk_mask <<= 1; s->clk_mask |= 1; if( ((s->clk_mask&0x1f)==0x1f) && ( (delta1=(ivalue - s->clk_prevval1) & lt_optimask[s->len]) == ((s->clk_prevval1 - s->clk_prevval3) & lt_optimask[s->len]) ) && ( (delta2=(s->clk_prevval - s->clk_prevval2) & lt_optimask[s->len]) == ((s->clk_prevval2 - s->clk_prevval4) & lt_optimask[s->len]) ) && ( (delta1==delta2) || ((!delta1)&&(!delta2)) ) ) { if(s->clk_prevtrans==ULLDescriptor(~0)) { s->clk_prevtrans = lt->timeval; s->clk_numtrans = 0; } else if(s->clk_numtrans == 0) { s->clk_delta = lt->timeval - s->clk_prevtrans; s->clk_prevtrans = lt->timeval; s->clk_numtrans++; } else { if(s->clk_delta == (lt->timeval - s->clk_prevtrans)) { s->clk_numtrans++; s->clk_prevtrans = lt->timeval; if(s->clk_numtrans > LT_CLKPACK_M) { s->clk_prevval4 = s->clk_prevval3; s->clk_prevval3 = s->clk_prevval2; s->clk_prevval2 = s->clk_prevval1; s->clk_prevval1 = s->clk_prevval; s->clk_prevval = ivalue; /* printf("Clock value '%08x' for '%s' at %lld (#%d)\n", ivalue, s->name, lt->timeval, s->clk_numtrans); */ return(1); } } else { if(s->clk_numtrans > LT_CLKPACK_M) { lt_flushclock_m(lt, s); /* flush clock then continue below! */ } else { s->clk_prevtrans=ULLDescriptor(~0); } } } } else { if(s->clk_numtrans > LT_CLKPACK_M) { lt_flushclock_m(lt, s); /* flush clock then continue below! */ } else { s->clk_prevtrans=ULLDescriptor(~0); } } s->clk_prevval4 = s->clk_prevval3; s->clk_prevval3 = s->clk_prevval2; s->clk_prevval2 = s->clk_prevval1; s->clk_prevval1 = s->clk_prevval; s->clk_prevval = ivalue; } else if(len==1) /* possible clock handling */ { int ivalue = value&1; if(((s->clk_prevval == '1') && (ivalue==0)) || ((s->clk_prevval == '0') && (ivalue==1))) { if(s->clk_prevtrans==ULLDescriptor(~0)) { s->clk_prevtrans = lt->timeval; s->clk_numtrans = 0; } else if(s->clk_numtrans == 0) { s->clk_delta = lt->timeval - s->clk_prevtrans; s->clk_prevtrans = lt->timeval; s->clk_numtrans++; } else { if(s->clk_delta == (lt->timeval - s->clk_prevtrans)) { s->clk_numtrans++; s->clk_prevtrans = lt->timeval; if(s->clk_numtrans > LT_CLKPACK) { s->clk_prevval = ivalue + '0'; /* printf("Clock value '%d' for '%s' at %d (#%d)\n", ivalue, s->name, lt->timeval, s->clk_numtrans); */ return(1); } } else { if(s->clk_numtrans > LT_CLKPACK) { lt_flushclock(lt, s); /* flush clock then continue below! */ } else { s->clk_prevtrans=ULLDescriptor(~0); } } } } else { if(s->clk_numtrans > LT_CLKPACK) { lt_flushclock(lt, s); /* flush clock then continue below! */ } else { s->clk_prevtrans=ULLDescriptor(~0); } } s->clk_prevval = ivalue + '0'; } } /* normal trace handling */ last_change_delta = lt->position - s->last_change - 2; if(last_change_delta >= 256*65536) { numbytes = 3; } else if(last_change_delta >= 65536) { numbytes = 2; } else if(last_change_delta >= 256) { numbytes = 1; } else { numbytes = 0; } if(len<=32) { int start_position = lt->position; int tag; int optimized0 = ((value<_optimask[len])==0); int optimized1 = ((value<_optimask[len])==lt_optimask[len]); int optimized = optimized0|optimized1; if(!lt->numfacs_bytes) { if(optimized) { tag = (numbytes<<4) | (3+optimized1); /* for x3 and x4 cases */ } else { tag = (numbytes<<4); } lt->lt_emit_u8(lt, tag); switch(numbytes&3) { case 0: lt->lt_emit_u8(lt, last_change_delta); break; case 1: lt->lt_emit_u16(lt, last_change_delta); break; case 2: lt->lt_emit_u24(lt, last_change_delta); break; case 3: lt->lt_emit_u32(lt, last_change_delta); break; } } else { switch(lt->numfacs_bytes) { case 1: lt->lt_emit_u8(lt, s->facnum); break; case 2: lt->lt_emit_u16(lt, s->facnum); break; case 3: lt->lt_emit_u24(lt, s->facnum); break; case 4: lt->lt_emit_u32(lt, s->facnum); break; } lt->lt_emit_u8(lt, optimized ? (3+optimized1) : 0); } s->last_change = start_position; if(s->rows>0) { if(s->rows >= 256*65536) { numbytes = 3; } else if(s->rows >= 65536) { numbytes = 2; } else if(s->rows >= 256) { numbytes = 1; } else { numbytes = 0; } switch(numbytes&3) { case 0: lt->lt_emit_u8(lt, row); break; case 1: lt->lt_emit_u16(lt, row); break; case 2: lt->lt_emit_u24(lt, row); break; case 3: lt->lt_emit_u32(lt, row); break; } } if(!optimized) { if((lt->dictmode)&&(len>lt->mindictwidth)) { char *vpnt_orig = lt_expand_integer_to_bits(len, value); char *vpnt = vpnt_orig; while ( (*vpnt == '0') && (*(vpnt+1)) ) vpnt++; lt->dict = dslxt_splay (vpnt, lt->dict); if(!dslxt_success) { unsigned int vlen = strlen(vpnt)+1; char *vcopy = (char *)malloc(vlen); strcpy(vcopy, vpnt); lt->dict_string_mem_required += vlen; lt->dict = dslxt_insert(vcopy, lt->dict, lt->num_dict_entries); if(!lt->dict16_offset) { if(lt->num_dict_entries==256) lt->dict16_offset = lt->position; } else if(!lt->dict24_offset) { if(lt->num_dict_entries==65536) lt->dict24_offset = lt->position; } else if(!lt->dict32_offset) { if(lt->num_dict_entries==(256*65536)) lt->dict32_offset = lt->position; } lt->num_dict_entries++; } if(lt->dict24_offset) { if(lt->dict32_offset) { lt->lt_emit_u32(lt, lt->dict->val); } else { lt->lt_emit_u24(lt, lt->dict->val); } } else { if(lt->dict16_offset) { lt->lt_emit_u16(lt, lt->dict->val); } else { lt->lt_emit_u8(lt, lt->dict->val); } } } else if(len<9) { value <<= (8-len); rc=lt->lt_emit_u8(lt, value); } else if(len<17) { value <<= (16-len); rc=lt->lt_emit_u16(lt, value); } else if(len<25) { value <<= (24-len); rc=lt->lt_emit_u24(lt, value); } else { value <<= (32-len); rc=lt->lt_emit_u32(lt, value); } } } if(lt->timebuff) { lt->timechangecount++; if(lt->timecurr) { lt->timecurr->next = lt->timebuff; lt->timecurr = lt->timebuff; } else { lt->timehead = lt->timecurr = lt->timebuff; } lt->timebuff=NULL; } } return(rc); } int lt_emit_value_double(struct lt_trace *lt, struct lt_symbol *s, unsigned int row, double value) { int rc=0; int start_position; int tag; if((!lt)||(!s)) return(rc); if(!lt->emitted) lt->emitted = 1; while(s->aliased_to) /* find root alias if exists */ { s=s->aliased_to; } if((s->flags)<_SYM_F_DOUBLE) { int numbytes; /* number of bytes to store value minus one */ unsigned int last_change_delta = lt->position - s->last_change - 2; if(!lt->numfacs_bytes) { if(last_change_delta >= 256*65536) { numbytes = 3; } else if(last_change_delta >= 65536) { numbytes = 2; } else if(last_change_delta >= 256) { numbytes = 1; } else { numbytes = 0; } start_position = lt->position; s->last_change = start_position; tag = (numbytes<<4); lt->lt_emit_u8(lt, tag); switch(numbytes&3) { case 0: lt->lt_emit_u8(lt, last_change_delta); break; case 1: lt->lt_emit_u16(lt, last_change_delta); break; case 2: lt->lt_emit_u24(lt, last_change_delta); break; case 3: lt->lt_emit_u32(lt, last_change_delta); break; } } else { switch(lt->numfacs_bytes) { case 1: lt->lt_emit_u8(lt, s->facnum); break; case 2: lt->lt_emit_u16(lt, s->facnum); break; case 3: lt->lt_emit_u24(lt, s->facnum); break; case 4: lt->lt_emit_u32(lt, s->facnum); break; } } if(s->rows>0) { if(s->rows >= 256*65536) { numbytes = 3; } else if(s->rows >= 65536) { numbytes = 2; } else if(s->rows >= 256) { numbytes = 1; } else { numbytes = 0; } switch(numbytes&3) { case 0: lt->lt_emit_u8(lt, row); break; case 1: lt->lt_emit_u16(lt, row); break; case 2: lt->lt_emit_u24(lt, row); break; case 3: lt->lt_emit_u32(lt, row); break; } } rc=lt->lt_emit_double(lt, value); if(lt->timebuff) { lt->timechangecount++; if(lt->timecurr) { lt->timecurr->next = lt->timebuff; lt->timecurr = lt->timebuff; } else { lt->timehead = lt->timecurr = lt->timebuff; } lt->timebuff=NULL; } } return(rc); } int lt_emit_value_string(struct lt_trace *lt, struct lt_symbol *s, unsigned int row, char *value) { int rc=0; int start_position; int tag; if((!lt)||(!s)||(!value)) return(rc); if(!lt->emitted) lt->emitted = 1; while(s->aliased_to) /* find root alias if exists */ { s=s->aliased_to; } if((s->flags)<_SYM_F_STRING) { int numbytes; /* number of bytes to store value minus one */ unsigned int last_change_delta = lt->position - s->last_change - 2; if(!lt->numfacs_bytes) { if(last_change_delta >= 256*65536) { numbytes = 3; } else if(last_change_delta >= 65536) { numbytes = 2; } else if(last_change_delta >= 256) { numbytes = 1; } else { numbytes = 0; } start_position = lt->position; s->last_change = start_position; tag = (numbytes<<4); lt->lt_emit_u8(lt, tag); switch(numbytes&3) { case 0: lt->lt_emit_u8(lt, last_change_delta); break; case 1: lt->lt_emit_u16(lt, last_change_delta); break; case 2: lt->lt_emit_u24(lt, last_change_delta); break; case 3: lt->lt_emit_u32(lt, last_change_delta); break; } } else { switch(lt->numfacs_bytes) { case 1: lt->lt_emit_u8(lt, s->facnum); break; case 2: lt->lt_emit_u16(lt, s->facnum); break; case 3: lt->lt_emit_u24(lt, s->facnum); break; case 4: lt->lt_emit_u32(lt, s->facnum); break; } } if(s->rows>0) { if(s->rows >= 256*65536) { numbytes = 3; } else if(s->rows >= 65536) { numbytes = 2; } else if(s->rows >= 256) { numbytes = 1; } else { numbytes = 0; } switch(numbytes&3) { case 0: lt->lt_emit_u8(lt, row); break; case 1: lt->lt_emit_u16(lt, row); break; case 2: lt->lt_emit_u24(lt, row); break; case 3: lt->lt_emit_u32(lt, row); break; } } rc=lt->lt_emit_string(lt, value); if(lt->timebuff) { lt->timechangecount++; if(lt->timecurr) { lt->timecurr->next = lt->timebuff; lt->timecurr = lt->timebuff; } else { lt->timehead = lt->timecurr = lt->timebuff; } lt->timebuff=NULL; } } return(rc); } int lt_emit_value_bit_string(struct lt_trace *lt, struct lt_symbol *s, unsigned int row, char *value) { int rc=0; int start_position; int tag, tagadd; if((!lt)||(!s)||(!value)||(!*value)) return(rc); if(!lt->emitted) lt->emitted = 1; while(s->aliased_to) /* find root alias if exists */ { s=s->aliased_to; } if(!(s->flags&(LT_SYM_F_DOUBLE|LT_SYM_F_STRING))) { int numbytes; /* number of bytes to store value minus one */ char *pnt; int mvl=0; char ch; char prevch; unsigned int last_change_delta; unsigned int len = ((s->flags)<_SYM_F_INTEGER) ? 32 : s->len; if((lt->clock_compress)&&(s->rows==0)) { if((len>1)&&(len<=32)) { int legal = 0; int ivalue = 0; unsigned int i; char *pntv = value; int delta1, delta2; for(i=0;i0)) { pntv--; } else { legal = 0; break; } } ivalue = (((unsigned int)ivalue) << 1); ivalue |= (*pntv & 1); legal = 1; pntv++; } s->clk_mask <<= 1; s->clk_mask |= legal; if( ((s->clk_mask&0x1f)==0x1f) && ( (delta1=(ivalue - s->clk_prevval1) & lt_optimask[s->len]) == ((s->clk_prevval1 - s->clk_prevval3) & lt_optimask[s->len]) ) && ( (delta2=(s->clk_prevval - s->clk_prevval2) & lt_optimask[s->len]) == ((s->clk_prevval2 - s->clk_prevval4) & lt_optimask[s->len]) ) && ( (delta1==delta2) || ((!delta1)&&(!delta2)) ) ) { if(s->clk_prevtrans==ULLDescriptor(~0)) { s->clk_prevtrans = lt->timeval; s->clk_numtrans = 0; } else if(s->clk_numtrans == 0) { s->clk_delta = lt->timeval - s->clk_prevtrans; s->clk_prevtrans = lt->timeval; s->clk_numtrans++; } else { if(s->clk_delta == (lt->timeval - s->clk_prevtrans)) { s->clk_numtrans++; s->clk_prevtrans = lt->timeval; if(s->clk_numtrans > LT_CLKPACK_M) { s->clk_prevval4 = s->clk_prevval3; s->clk_prevval3 = s->clk_prevval2; s->clk_prevval2 = s->clk_prevval1; s->clk_prevval1 = s->clk_prevval; s->clk_prevval = ivalue; /* printf("Clock value '%08x' for '%s' [len=%d] at %lld (#%d)\n", ivalue, s->name, len, lt->timeval, s->clk_numtrans); */ return(1); } } else { if(s->clk_numtrans > LT_CLKPACK_M) { lt_flushclock_m(lt, s); /* flush clock then continue below! */ } else { s->clk_prevtrans=ULLDescriptor(~0); } } } } else { if(s->clk_numtrans > LT_CLKPACK_M) { lt_flushclock_m(lt, s); /* flush clock then continue below! */ } else { s->clk_prevtrans=ULLDescriptor(~0); } } s->clk_prevval4 = s->clk_prevval3; s->clk_prevval3 = s->clk_prevval2; s->clk_prevval2 = s->clk_prevval1; s->clk_prevval1 = s->clk_prevval; s->clk_prevval = ivalue; } else if(len==1) /* possible clock handling */ { if(((s->clk_prevval == '1') && (value[0]=='0')) || ((s->clk_prevval == '0') && (value[0]=='1'))) { if(s->clk_prevtrans==ULLDescriptor(~0)) { s->clk_prevtrans = lt->timeval; s->clk_numtrans = 0; } else if(s->clk_numtrans == 0) { s->clk_delta = lt->timeval - s->clk_prevtrans; s->clk_prevtrans = lt->timeval; s->clk_numtrans++; } else { if(s->clk_delta == (lt->timeval - s->clk_prevtrans)) { s->clk_numtrans++; s->clk_prevtrans = lt->timeval; if(s->clk_numtrans > LT_CLKPACK) { s->clk_prevval = value[0]; /* printf("Clock value '%c' for '%s' at %lld (#%d)\n", value[0], s->name, lt->timeval, s->clk_numtrans); */ return(1); } } else { if(s->clk_numtrans > LT_CLKPACK) { lt_flushclock(lt, s); /* flush clock then continue below! */ } else { s->clk_prevtrans=ULLDescriptor(~0); } } } } else { if(s->clk_numtrans > LT_CLKPACK) { lt_flushclock(lt, s); /* flush clock then continue below! */ } else { s->clk_prevtrans=ULLDescriptor(~0); } } s->clk_prevval = value[0]; } } /* normal trace handling */ last_change_delta = lt->position - s->last_change - 2; if(last_change_delta >= 256*65536) { numbytes = 3; } else if(last_change_delta >= 65536) { numbytes = 2; } else if(last_change_delta >= 256) { numbytes = 1; } else { numbytes = 0; } pnt = value; prevch = *pnt; while((ch=*(pnt++))) { switch(ch) { case '0': case '1': mvl|=LT_MVL_2; break; case 'Z': case 'z': case 'X': case 'x': mvl|=LT_MVL_4; break; default: mvl|=LT_MVL_9; break; } if(prevch!=ch) prevch = 0; } switch(prevch) { case 0x00: tagadd = 0; break; case '0': tagadd = 3; break; case '1': tagadd = 4; break; case 'Z': case 'z': tagadd = 5; break; case 'X': case 'x': tagadd = 6; break; case 'H': case 'h': tagadd = 7; break; case 'U': case 'u': tagadd = 8; break; case 'W': case 'w': tagadd = 9; break; case 'L': case 'l': tagadd = 0xa; break; default: tagadd = 0xb; break; } if(mvl) { start_position = lt->position; if(!lt->numfacs_bytes) { if(tagadd) { tag = (numbytes<<4) + tagadd; } else { tag = (numbytes<<4) + ((mvl<_MVL_9)? 2 : ((mvl<_MVL_4)? 1 : 0)); } lt->lt_emit_u8(lt, tag); switch(numbytes&3) { case 0: lt->lt_emit_u8(lt, last_change_delta); break; case 1: lt->lt_emit_u16(lt, last_change_delta); break; case 2: lt->lt_emit_u24(lt, last_change_delta); break; case 3: lt->lt_emit_u32(lt, last_change_delta); break; } } else { switch(lt->numfacs_bytes) { case 1: lt->lt_emit_u8(lt, s->facnum); break; case 2: lt->lt_emit_u16(lt, s->facnum); break; case 3: lt->lt_emit_u24(lt, s->facnum); break; case 4: lt->lt_emit_u32(lt, s->facnum); break; } if(tagadd) { lt->lt_emit_u8(lt, tagadd); } else { lt->lt_emit_u8(lt, (mvl<_MVL_9)? 2 : ((mvl<_MVL_4)? 1 : 0) ); } } s->last_change = start_position; if(s->rows>0) { if(s->rows >= 256*65536) { numbytes = 3; } else if(s->rows >= 65536) { numbytes = 2; } else if(s->rows >= 256) { numbytes = 1; } else { numbytes = 0; } switch(numbytes&3) { case 0: lt->lt_emit_u8(lt, row); break; case 1: lt->lt_emit_u16(lt, row); break; case 2: lt->lt_emit_u24(lt, row); break; case 3: lt->lt_emit_u32(lt, row); break; } } if(!tagadd) { unsigned int len2 = ((s->flags)<_SYM_F_INTEGER) ? 32 : s->len; if((mvl & (LT_MVL_2|LT_MVL_4|LT_MVL_9)) == LT_MVL_2) { unsigned int i; int bitpos = 7; int outval = 0; int thisval= 0; pnt = value; if((lt->dictmode)&&(len2>lt->mindictwidth)) { char *vpnt = value; while ( (*vpnt == '0') && (*(vpnt+1)) ) vpnt++; lt->dict = dslxt_splay (vpnt, lt->dict); if(!dslxt_success) { unsigned int vlen = strlen(vpnt)+1; char *vcopy = (char *)malloc(vlen); strcpy(vcopy, vpnt); lt->dict_string_mem_required += vlen; lt->dict = dslxt_insert(vcopy, lt->dict, lt->num_dict_entries); if(!lt->dict16_offset) { if(lt->num_dict_entries==256) lt->dict16_offset = lt->position; } else if(!lt->dict24_offset) { if(lt->num_dict_entries==65536) lt->dict24_offset = lt->position; } else if(!lt->dict32_offset) { if(lt->num_dict_entries==(256*65536)) lt->dict32_offset = lt->position; } lt->num_dict_entries++; } if(lt->dict24_offset) { if(lt->dict32_offset) { lt->lt_emit_u32(lt, lt->dict->val); } else { lt->lt_emit_u24(lt, lt->dict->val); } } else { if(lt->dict16_offset) { lt->lt_emit_u16(lt, lt->dict->val); } else { lt->lt_emit_u8(lt, lt->dict->val); } } } else for(i=0;ilt_emit_u8(lt, outval); outval = 0; bitpos = 7; } } } else if((mvl & (LT_MVL_4|LT_MVL_9)) == LT_MVL_4) { unsigned int i; int bitpos = 6; int outval = 0; int thisval= 0; pnt = value; for(i=0;ilt_emit_u8(lt, outval); outval = 0; bitpos = 6; } } } else /* if(mvl & LT_MVL_9) */ { unsigned int i; int bitpos = 4; int outval = 0; int thisval= 0; pnt = value; for(i=0;ilt_emit_u8(lt, outval); outval = 0; bitpos = 4; } } } } rc=1; } if(lt->timebuff) { lt->timechangecount++; if(lt->timecurr) { lt->timecurr->next = lt->timebuff; lt->timecurr = lt->timebuff; } else { lt->timehead = lt->timecurr = lt->timebuff; } lt->timebuff=NULL; } } return(rc); } /* * blackout functions */ void lt_set_dumpoff(struct lt_trace *lt) { if((lt)&&(!lt->dumpoff_active)) { struct lt_timetrail *ltt = calloc(1, sizeof(struct lt_timetrail)); ltt->timeval = lt->timeval; if(lt->dumpoffhead) { lt->dumpoffcurr->next = ltt; lt->dumpoffcurr = ltt; } else { lt->dumpoffhead = lt->dumpoffcurr = ltt; } lt->dumpoff_active = 1; lt->dumpoffcount++; } } void lt_set_dumpon(struct lt_trace *lt) { if((lt)&&(lt->dumpoff_active)) { struct lt_timetrail *ltt = calloc(1, sizeof(struct lt_timetrail)); ltt->timeval = lt->timeval; lt->dumpoffcurr->next = ltt; lt->dumpoffcurr = ltt; lt->dumpoff_active = 0; } } void lt_set_timezero(struct lt_trace *lt, lxtotime_t timeval) { if(lt) { lt->timezero = timeval; } } gtkwave-3.3.66/src/helpers/lxt_write.h0000664000076400007640000002014412341266475017235 0ustar bybellbybell/* * Copyright (c) 2001-2012 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifndef DEFS_LXT_H #define DEFS_LXT_H #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include #include #include #include #ifdef HAVE_INTTYPES_H #include #endif #ifndef HAVE_FSEEKO #define fseeko fseek #define ftello ftell #endif typedef struct dslxt_tree_node dslxt_Tree; struct dslxt_tree_node { dslxt_Tree * left, * right; char *item; unsigned int val; }; #define LT_HDRID (0x0138) #define LT_VERSION (0x0004) #define LT_TRLID (0xB4) #define LT_CLKPACK (4) #define LT_CLKPACK_M (2) #define LT_MVL_2 (1<<0) #define LT_MVL_4 (1<<1) #define LT_MVL_9 (1<<2) #define LT_MINDICTWIDTH (16) enum lt_zmode_types { LT_ZMODE_NONE, LT_ZMODE_GZIP, LT_ZMODE_BZIP2 }; #ifndef _MSC_VER typedef uint64_t lxttime_t; #define ULLDescriptor(x) x##ULL typedef int64_t lxtotime_t; #else typedef unsigned __int64 lxttime_t; #define ULLDescriptor(x) x##i64 typedef __int64 lxtotime_t; #endif struct lt_timetrail { struct lt_timetrail *next; lxttime_t timeval; unsigned int position; }; #define LT_SYMPRIME 500009 #define LT_SECTION_END (0) #define LT_SECTION_CHG (1) #define LT_SECTION_SYNC_TABLE (2) #define LT_SECTION_FACNAME (3) #define LT_SECTION_FACNAME_GEOMETRY (4) #define LT_SECTION_TIMESCALE (5) #define LT_SECTION_TIME_TABLE (6) #define LT_SECTION_INITIAL_VALUE (7) #define LT_SECTION_DOUBLE_TEST (8) #define LT_SECTION_TIME_TABLE64 (9) #define LT_SECTION_ZFACNAME_PREDEC_SIZE (10) #define LT_SECTION_ZFACNAME_SIZE (11) #define LT_SECTION_ZFACNAME_GEOMETRY_SIZE (12) #define LT_SECTION_ZSYNC_SIZE (13) #define LT_SECTION_ZTIME_TABLE_SIZE (14) #define LT_SECTION_ZCHG_PREDEC_SIZE (15) #define LT_SECTION_ZCHG_SIZE (16) #define LT_SECTION_ZDICTIONARY (17) #define LT_SECTION_ZDICTIONARY_SIZE (18) #define LT_SECTION_EXCLUDE_TABLE (19) #define LT_SECTION_TIMEZERO (20) struct lt_trace { FILE *handle; gzFile zhandle; dslxt_Tree *dict; /* dictionary manipulation */ unsigned int mindictwidth; unsigned int num_dict_entries; unsigned int dict_string_mem_required; dslxt_Tree **sorted_dict; /* assume dict8_offset == filepos zero */ unsigned int dict16_offset; unsigned int dict24_offset; unsigned int dict32_offset; int (*lt_emit_u8)(struct lt_trace *lt, int value); int (*lt_emit_u16)(struct lt_trace *lt, int value); int (*lt_emit_u24)(struct lt_trace *lt, int value); int (*lt_emit_u32)(struct lt_trace *lt, int value); int (*lt_emit_u64)(struct lt_trace *lt, int valueh, int valuel); int (*lt_emit_double)(struct lt_trace *lt, double value); int (*lt_emit_string)(struct lt_trace *lt, char *value); unsigned int position; unsigned int zfacname_predec_size, zfacname_size, zfacgeometry_size, zsync_table_size, ztime_table_size, zdictionary_size; unsigned int zpackcount, zchg_table_size, chg_table_size; struct lt_symbol *sym[LT_SYMPRIME]; struct lt_symbol **sorted_facs; struct lt_symbol *symchain; int numfacs, numfacs_bytes; int numfacbytes; int longestname; lxttime_t mintime, maxtime; int timescale; int initial_value; struct lt_timetrail *timehead, *timecurr, *timebuff; int timechangecount; struct lt_timetrail *dumpoffhead, *dumpoffcurr; int dumpoffcount; unsigned int change_field_offset; unsigned int facname_offset; unsigned int facgeometry_offset; unsigned int time_table_offset; unsigned int sync_table_offset; unsigned int initial_value_offset; unsigned int timescale_offset; unsigned int double_test_offset; unsigned int dictionary_offset; unsigned int exclude_offset; unsigned int timezero_offset; char *compress_fac_str; int compress_fac_len; lxttime_t timeval; /* for clock induction, current time */ lxtotime_t timezero; /* for allowing negative values */ unsigned dumpoff_active : 1; /* when set we're not dumping */ unsigned double_used : 1; unsigned do_strip_brackets : 1; unsigned clock_compress : 1; unsigned dictmode : 1; /* dictionary compression enabled */ unsigned zmode : 2; /* for value changes */ unsigned emitted : 1; /* gate off change field zmode changes when set */ }; struct lt_symbol { struct lt_symbol *next; struct lt_symbol *symchain; char *name; int namlen; int facnum; struct lt_symbol *aliased_to; unsigned int rows; int msb, lsb; int len; int flags; unsigned int last_change; lxttime_t clk_delta; lxttime_t clk_prevtrans; int clk_numtrans; int clk_prevval; int clk_prevval1; int clk_prevval2; int clk_prevval3; int clk_prevval4; unsigned char clk_mask; }; #define LT_SYM_F_BITS (0) #define LT_SYM_F_INTEGER (1<<0) #define LT_SYM_F_DOUBLE (1<<1) #define LT_SYM_F_STRING (1<<2) #define LT_SYM_F_ALIAS (1<<3) struct lt_trace * lt_init(const char *name); void lt_close(struct lt_trace *lt); struct lt_symbol * lt_symbol_find(struct lt_trace *lt, const char *name); struct lt_symbol * lt_symbol_add(struct lt_trace *lt, const char *name, unsigned int rows, int msb, int lsb, int flags); struct lt_symbol * lt_symbol_alias(struct lt_trace *lt, const char *existing_name, const char *alias, int msb, int lsb); void lt_symbol_bracket_stripping(struct lt_trace *lt, int doit); /* lt_set_no_interlace implies bzip2 compression. if you use lt_set_chg_compress before this, */ /* less efficient gzip compression will be used instead so make sure lt_set_no_interlace is first */ /* if you are using it! */ void lt_set_no_interlace(struct lt_trace *lt); void lt_set_chg_compress(struct lt_trace *lt); void lt_set_clock_compress(struct lt_trace *lt); void lt_set_dict_compress(struct lt_trace *lt, unsigned int minwidth); void lt_set_initial_value(struct lt_trace *lt, char value); void lt_set_timescale(struct lt_trace *lt, int timescale); void lt_set_timezero(struct lt_trace *lt, lxtotime_t timeval); int lt_set_time(struct lt_trace *lt, unsigned int timeval); int lt_inc_time_by_delta(struct lt_trace *lt, unsigned int timeval); int lt_set_time64(struct lt_trace *lt, lxttime_t timeval); int lt_inc_time_by_delta64(struct lt_trace *lt, lxttime_t timeval); /* allows blackout regions in LXT files */ void lt_set_dumpoff(struct lt_trace *lt); void lt_set_dumpon(struct lt_trace *lt); /* * value change functions..note that if the value string len for * lt_emit_value_bit_string() is shorter than the symbol length * it will be left justified with the rightmost character used as * a repeat value that will be propagated to pad the value string out: * * "10x" for 8 bits becomes "10xxxxxx" * "z" for 8 bits becomes "zzzzzzzz" */ int lt_emit_value_int(struct lt_trace *lt, struct lt_symbol *s, unsigned int row, int value); int lt_emit_value_double(struct lt_trace *lt, struct lt_symbol *s, unsigned int row, double value); int lt_emit_value_string(struct lt_trace *lt, struct lt_symbol *s, unsigned int row, char *value); int lt_emit_value_bit_string(struct lt_trace *lt, struct lt_symbol *s, unsigned int row, char *value); #ifdef __cplusplus } #endif #endif gtkwave-3.3.66/src/helpers/vzt_read.h0000664000076400007640000002275012357342523017033 0ustar bybellbybell/* * Copyright (c) 2004-2012 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifndef DEFS_VZTR_H #define DEFS_VZTR_H #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include #ifndef _MSC_VER #include #ifdef HAVE_INTTYPES_H #include #endif #else typedef long off_t; #include #include #endif #ifndef HAVE_FSEEKO #define fseeko fseek #define ftello ftell #endif #if defined _MSC_VER || defined __MINGW32__ typedef int pthread_t; typedef int pthread_attr_t; typedef int pthread_mutex_t; typedef int pthread_mutexattr_t; #else #include #endif #include #include #include #ifdef __GNUC__ #if __STDC_VERSION__ >= 199901L #define _VZT_RD_INLINE inline __attribute__((__gnu_inline__)) #else #define _VZT_RD_INLINE inline #endif #else #define _VZT_RD_INLINE #endif #define VZT_RDLOAD "VZTLOAD | " #define VZT_RD_HDRID (('V' << 8) + ('Z')) #define VZT_RD_VERSION (0x0001) #define VZT_RD_GRANULE_SIZE (32) #define VZT_RD_MAX_BLOCK_MEM_USAGE (64*1024*1024) /* 64MB */ #ifndef _MSC_VER typedef uint8_t vztint8_t; typedef uint16_t vztint16_t; typedef uint32_t vztint32_t; typedef uint64_t vztint64_t; typedef int64_t vztsint64_t; typedef int32_t vztsint32_t; #ifndef __MINGW32__ #define VZT_RD_LLD "%"PRId64 #define VZT_RD_LD "%"PRId32 #else #define VZT_RD_LLD "%I64d" #define VZT_RD_LD "%d" #endif #define VZT_RD_LLDESC(x) x##LL #define VZT_RD_ULLDESC(x) x##ULL #else typedef unsigned __int8 vztint8_t; typedef unsigned __int16 vztint16_t; typedef unsigned __int32 vztint32_t; typedef unsigned __int64 vztint64_t; typedef __int64 vztsint64_t; typedef __int32 vztsint32_t; #define VZT_RD_LLD "%I64d" #define VZT_RD_LD "%d" #define VZT_RD_LLDESC(x) x##i64 #define VZT_RD_ULLDESC(x) x##i64 #endif #define VZT_RD_IS_GZ (0) #define VZT_RD_IS_BZ2 (1) #define VZT_RD_IS_LZMA (2) #define VZT_RD_SYM_F_BITS (0) #define VZT_RD_SYM_F_INTEGER (1<<0) #define VZT_RD_SYM_F_DOUBLE (1<<1) #define VZT_RD_SYM_F_STRING (1<<2) #define VZT_RD_SYM_F_TIME (VZT_RD_SYM_F_STRING) /* user must correctly format this as a string */ #define VZT_RD_SYM_F_ALIAS (1<<3) #define VZT_RD_SYM_F_SIGNED (1<<4) #define VZT_RD_SYM_F_BOOLEAN (1<<5) #define VZT_RD_SYM_F_NATURAL ((1<<6)|(VZT_RD_SYM_F_INTEGER)) #define VZT_RD_SYM_F_POSITIVE ((1<<7)|(VZT_RD_SYM_F_INTEGER)) #define VZT_RD_SYM_F_CHARACTER (1<<8) #define VZT_RD_SYM_F_CONSTANT (1<<9) #define VZT_RD_SYM_F_VARIABLE (1<<10) #define VZT_RD_SYM_F_SIGNAL (1<<11) #define VZT_RD_SYM_F_IN (1<<12) #define VZT_RD_SYM_F_OUT (1<<13) #define VZT_RD_SYM_F_INOUT (1<<14) #define VZT_RD_SYM_F_WIRE (1<<15) #define VZT_RD_SYM_F_REG (1<<16) #define VZT_RD_SYM_MASK (VZT_RD_SYM_F_BITS|VZT_RD_SYM_F_INTEGER|VZT_RD_SYM_F_DOUBLE|VZT_RD_SYM_F_STRING|VZT_RD_SYM_F_TIME| \ VZT_RD_SYM_F_ALIAS|VZT_RD_SYM_F_SIGNED|VZT_RD_SYM_F_BOOLEAN|VZT_RD_SYM_F_NATURAL| \ VZT_RD_SYM_F_POSITIVE|VZT_RD_SYM_F_CHARACTER|VZT_RD_SYM_F_CONSTANT|VZT_RD_SYM_F_VARIABLE| \ VZT_RD_SYM_F_SIGNAL|VZT_RD_SYM_F_IN|VZT_RD_SYM_F_OUT|VZT_RD_SYM_F_INOUT|VZT_RD_SYM_F_WIRE| \ VZT_RD_SYM_F_REG) #define VZT_RD_SYM_F_SYNVEC (1<<17) /* reader synthesized vector in alias sec'n from non-adjacent vectorizing */ struct vzt_rd_block { char *mem; struct vzt_rd_block *next; struct vzt_rd_block *prev; vztint32_t uncompressed_siz, compressed_siz, num_rle_bytes; vztint64_t start, end; vztint32_t *vindex; vztint64_t *times; vztint32_t *change_dict; vztint32_t *val_dict; char **sindex; unsigned int num_time_ticks, num_sections, num_dict_entries, num_str_entries; off_t filepos; /* where block starts in file if we have to reload */ unsigned short_read_ignore : 1; /* tried to read once and it was corrupt so ignore next time */ unsigned exclude_block : 1; /* user marked this block off to be ignored */ unsigned multi_state : 1; /* not just two state value changes */ unsigned killed : 1; /* we're in vzt_close(), don't grab anymore blocks */ unsigned ztype : 2; /* 1: gzip, 0: bzip2, 2: lzma */ unsigned rle : 1; /* set when end < start which says that an rle depack is necessary */ pthread_t pth; pthread_attr_t pth_attr; pthread_mutex_t mutex; vztint64_t last_rd_value_simtime; vztint32_t last_rd_value_idx; }; struct vzt_rd_geometry { vztint32_t rows; vztsint32_t msb, lsb; vztint32_t flags, len; }; struct vzt_rd_facname_cache { char *n; char *bufprev, *bufcurr; vztint32_t old_facidx; }; struct vzt_rd_trace { vztint32_t *rows; vztsint32_t *msb, *lsb; vztint32_t *flags, *len, *vindex_offset; vztsint64_t timezero; char *value_current_sector; char *value_previous_sector; vztint32_t longest_len; vztint32_t total_values; /* number of value index entries in table */ char *process_mask; void (*value_change_callback)(struct vzt_rd_trace **lt, vztint64_t *time, vztint32_t *facidx, char **value); void *user_callback_data_pointer; vztint8_t granule_size; vztint32_t numfacs, numrealfacs, numfacbytes, longestname, zfacnamesize, zfacname_predec_size, zfacgeometrysize; vztint8_t timescale; char *zfacnames; unsigned int numblocks; struct vzt_rd_block *block_head, *block_curr; vztint64_t start, end; struct vzt_rd_geometry geometry; struct vzt_rd_facname_cache *faccache; vztint64_t last_rd_value_simtime; /* for single value reads w/o using the callback mechanism */ struct vzt_rd_block *last_rd_value_block; char *filename; /* for multithread */ FILE *handle; void *zhandle; vztint64_t block_mem_consumed, block_mem_max; pthread_mutex_t mutex; /* for these */ unsigned int pthreads; /* pthreads are enabled, set to max processor # (starting at zero for a uni) */ unsigned process_linear : 1; /* set by gtkwave for read optimization */ unsigned vectorize : 1; /* set when coalescing blasted bitvectors */ }; /* * VZT Reader API functions... */ struct vzt_rd_trace * vzt_rd_init(const char *name); struct vzt_rd_trace * vzt_rd_init_smp(const char *name, unsigned int num_cpus); void vzt_rd_close(struct vzt_rd_trace *lt); vztint64_t vzt_rd_set_max_block_mem_usage(struct vzt_rd_trace *lt, vztint64_t block_mem_max); vztint64_t vzt_rd_get_block_mem_usage(struct vzt_rd_trace *lt); unsigned int vzt_rd_get_num_blocks(struct vzt_rd_trace *lt); unsigned int vzt_rd_get_num_active_blocks(struct vzt_rd_trace *lt); vztint32_t vzt_rd_get_num_facs(struct vzt_rd_trace *lt); char * vzt_rd_get_facname(struct vzt_rd_trace *lt, vztint32_t facidx); struct vzt_rd_geometry * vzt_rd_get_fac_geometry(struct vzt_rd_trace *lt, vztint32_t facidx); vztint32_t vzt_rd_get_fac_rows(struct vzt_rd_trace *lt, vztint32_t facidx); vztsint32_t vzt_rd_get_fac_msb(struct vzt_rd_trace *lt, vztint32_t facidx); vztsint32_t vzt_rd_get_fac_lsb(struct vzt_rd_trace *lt, vztint32_t facidx); vztint32_t vzt_rd_get_fac_flags(struct vzt_rd_trace *lt, vztint32_t facidx); vztint32_t vzt_rd_get_fac_len(struct vzt_rd_trace *lt, vztint32_t facidx); vztint32_t vzt_rd_get_alias_root(struct vzt_rd_trace *lt, vztint32_t facidx); char vzt_rd_get_timescale(struct vzt_rd_trace *lt); vztint64_t vzt_rd_get_start_time(struct vzt_rd_trace *lt); vztint64_t vzt_rd_get_end_time(struct vzt_rd_trace *lt); vztsint64_t vzt_rd_get_timezero(struct vzt_rd_trace *lt); int vzt_rd_get_fac_process_mask(struct vzt_rd_trace *lt, vztint32_t facidx); int vzt_rd_set_fac_process_mask(struct vzt_rd_trace *lt, vztint32_t facidx); int vzt_rd_clr_fac_process_mask(struct vzt_rd_trace *lt, vztint32_t facidx); int vzt_rd_set_fac_process_mask_all(struct vzt_rd_trace *lt); int vzt_rd_clr_fac_process_mask_all(struct vzt_rd_trace *lt); /* null value_change_callback calls an empty dummy function */ int vzt_rd_iter_blocks(struct vzt_rd_trace *lt, void (*value_change_callback)(struct vzt_rd_trace **lt, vztint64_t *time, vztint32_t *facidx, char **value), void *user_callback_data_pointer); void * vzt_rd_get_user_callback_data_pointer(struct vzt_rd_trace *lt); void vzt_rd_process_blocks_linearly(struct vzt_rd_trace *lt, int doit); /* time (un)/restricted read ops */ unsigned int vzt_rd_limit_time_range(struct vzt_rd_trace *lt, vztint64_t strt_time, vztint64_t end_time); unsigned int vzt_rd_unlimit_time_range(struct vzt_rd_trace *lt); /* naive read on time/facidx */ char * vzt_rd_value(struct vzt_rd_trace *lt, vztint64_t simtime, vztint32_t facidx); /* experimental function for reconstituting bitblasted nets */ void vzt_rd_vectorize(struct vzt_rd_trace *lt); #ifdef __cplusplus } #endif #endif gtkwave-3.3.66/src/helpers/vzt2vcd.c0000664000076400007640000002713412341266475016617 0ustar bybellbybell/* * Copyright (c) 2003-2014 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include "vzt_read.h" #if HAVE_GETOPT_H #include #endif #include #include "wave_locale.h" #define VZT_VCD_WRITE_BUF_SIZ (2 * 1024 * 1024) static int flat_earth = 0; static int vectorize = 0; static int notruncate = 0; static FILE *fv = NULL; extern void free_hier(void); extern char *fv_output_hier(FILE *fv, char *name); /* * generate a vcd identifier for a given facindx */ static char *vcdid(unsigned int value) { static char buf[16]; char *pnt = buf; value++; /* zero is illegal for a value...it is assumed they start at one */ while (value) { value--; *(pnt++) = (char)('!' + value % 94); value = value / 94; } *pnt = 0; return(buf); } /* static char *vcdid(int value) { static char buf[16]; int i; for(i=0;i<15;i++) { buf[i]=(char)((value%94)+33); value=value/94; if(!value) {buf[i+1]=0; break;} } return(buf); } */ static char *vcd_truncate_bitvec(char *s) { char l, r; if(notruncate) return(s); r=*s; if(r=='1') { return s; } else { s++; } for(;;s++) { l=r; r=*s; if(!r) return (s-1); if(l!=r) { return(((l=='0')&&(r=='1'))?s:s-1); } } } static vztint64_t vcd_prevtime; char vcd_blackout; void vcd_callback(struct vzt_rd_trace **lt, vztint64_t *pnt_time, vztint32_t *pnt_facidx, char **pnt_value) { struct vzt_rd_geometry *g = vzt_rd_get_fac_geometry(*lt, *pnt_facidx); /* fprintf(stderr, VZT_RD_LLD" %d %s\n", *pnt_time, *pnt_facidx, *pnt_value); */ if(vcd_prevtime != *pnt_time) { vcd_prevtime = *pnt_time; fprintf(fv, "#"VZT_RD_LLD"\n", *pnt_time); } if(!(*pnt_value)[0]) { if(!vcd_blackout) { vcd_blackout = 1; fprintf(fv, "$dumpoff\n"); } return; } else { if(vcd_blackout) { vcd_blackout = 0; fprintf(fv, "$dumpon\n"); } } if(g->flags & VZT_RD_SYM_F_DOUBLE) { fprintf(fv, "r%s %s\n", *pnt_value, vcdid(*pnt_facidx)); } else if(g->flags & VZT_RD_SYM_F_STRING) { fprintf(fv, "s%s %s\n", *pnt_value, vcdid(*pnt_facidx)); } else { if(g->len==1) { fprintf(fv, "%c%s\n", (*pnt_value)[0], vcdid(*pnt_facidx)); } else { fprintf(fv, "b%s %s\n", vcd_truncate_bitvec(*pnt_value), vcdid(*pnt_facidx)); } } } int process_vzt(char *fname) { struct vzt_rd_trace *lt; char *netname; lt=vzt_rd_init(fname); if(lt) { int i; int numfacs; char time_dimension; int time_scale = 1; signed char scale; time_t walltime; vztsint64_t timezero; if(vectorize) { vzt_rd_vectorize(lt); } numfacs = vzt_rd_get_num_facs(lt); vzt_rd_set_fac_process_mask_all(lt); vzt_rd_set_max_block_mem_usage(lt, 0); /* no need to cache blocks */ scale = vzt_rd_get_timescale(lt); switch(scale) { case 0: time_dimension = 's'; break; case -1: time_scale = 100; time_dimension = 'm'; break; case -2: time_scale = 10; case -3: time_dimension = 'm'; break; case -4: time_scale = 100; time_dimension = 'u'; break; case -5: time_scale = 10; case -6: time_dimension = 'u'; break; case -10: time_scale = 100; time_dimension = 'p'; break; case -11: time_scale = 10; case -12: time_dimension = 'p'; break; case -13: time_scale = 100; time_dimension = 'f'; break; case -14: time_scale = 10; case -15: time_dimension = 'f'; break; case -7: time_scale = 100; time_dimension = 'n'; break; case -8: time_scale = 10; case -9: default: time_dimension = 'n'; break; } time(&walltime); fprintf(fv, "$date\n"); fprintf(fv, "\t%s",asctime(localtime(&walltime))); fprintf(fv, "$end\n"); fprintf(fv, "$version\n\tvzt2vcd\n$end\n"); fprintf(fv, "$timescale %d%c%c $end\n", time_scale, time_dimension, !scale ? ' ' : 's'); timezero = vzt_rd_get_timezero(lt); if(timezero) { fprintf(fv, "$timezero "VZT_RD_LLD" $end\n", timezero); } for(i=0;ilen==0) continue; } if(!flat_earth) { netname = fv_output_hier(fv, vzt_rd_get_facname(lt, i)); } else { netname = vzt_rd_get_facname(lt, i); } if(g->flags & VZT_RD_SYM_F_DOUBLE) { fprintf(fv, "$var real 1 %s %s $end\n", vcdid(newindx), netname); } else if(g->flags & VZT_RD_SYM_F_STRING) { fprintf(fv, "$var real 1 %s %s $end\n", vcdid(newindx), netname); } else { if(g->len==1) { if(g->msb!=-1) { fprintf(fv, "$var wire 1 %s %s ["VZT_RD_LD"] $end\n", vcdid(newindx), netname, g->msb); } else { fprintf(fv, "$var wire 1 %s %s $end\n", vcdid(newindx), netname); } } else { if(!(g->flags & VZT_RD_SYM_F_INTEGER)) { if(g->len) fprintf(fv, "$var wire "VZT_RD_LD" %s %s ["VZT_RD_LD":"VZT_RD_LD"] $end\n", g->len, vcdid(newindx), netname, g->msb, g->lsb); } else { fprintf(fv, "$var integer "VZT_RD_LD" %s %s $end\n", g->len, vcdid(newindx), netname); } } } } if(!flat_earth) { fv_output_hier(fv, ""); /* flush any remaining hierarchy if not back to toplevel */ free_hier(); } fprintf(fv, "$enddefinitions $end\n"); fprintf(fv, "$dumpvars\n"); vcd_prevtime = vzt_rd_get_start_time(lt)-1; vzt_rd_iter_blocks(lt, vcd_callback, NULL); if(vcd_prevtime!=vzt_rd_get_end_time(lt)) { fprintf(fv, "#"VZT_RD_LLD"\n", vzt_rd_get_end_time(lt)); } vzt_rd_close(lt); } else { fprintf(stderr, "vzt_rd_init failed\n"); return(255); } return(0); } /*******************************************************************************/ void print_help(char *nam) { #ifdef __linux__ printf( "Usage: %s [OPTION]... [VZTFILE]\n\n" " -v, --vztname=FILE specify VZT input filename\n" " -o, --output=FILE specify output filename\n" " -f, --flatearth emit flattened hierarchies\n" " -c, --coalesce coalesce bitblasted vectors\n" " -n, --notruncate do not shorten bitvectors\n" " -h, --help display this help then exit\n\n" "VCD is emitted to stdout if output filename is unspecified.\n\n" "Report bugs to <"PACKAGE_BUGREPORT">.\n",nam); #else printf( "Usage: %s [OPTION]... [VZTFILE]\n\n" " -v specify VZT input filename\n" " -o specify output filename\n" " -f emit flattened hierarchies\n" " -c coalesce bitblasted vectors\n" " -n do not shorten bitvectors\n" " -h display this help then exit\n\n" "VCD is emitted to stdout if output filename is unspecified.\n\n" "Report bugs to <"PACKAGE_BUGREPORT">.\n",nam); #endif exit(0); } int main(int argc, char **argv) { char opt_errors_encountered=0; char *lxname=NULL; char *outname=NULL; char *fvbuf=NULL; int c; int rc; WAVE_LOCALE_FIX while (1) { #ifdef __linux__ int option_index = 0; static struct option long_options[] = { {"vztname", 1, 0, 'v'}, {"output", 1, 0, 'o'}, {"coalesce", 0, 0, 'c'}, {"flatearth", 0, 0, 'f'}, {"notruncate", 0, 0, 'n'}, {"help", 0, 0, 'h'}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "v:o:cfnh", long_options, &option_index); #else c = getopt (argc, argv, "v:o:cfnh"); #endif if (c == -1) break; /* no more args */ switch (c) { case 'v': if(lxname) free(lxname); lxname = malloc(strlen(optarg)+1); strcpy(lxname, optarg); break; case 'o': if(outname) free(outname); outname = malloc(strlen(optarg)+1); strcpy(outname, optarg); break; case 'c': vectorize=1; break; case 'n': notruncate=1; break; case 'f': flat_earth=1; break; case 'h': print_help(argv[0]); break; case '?': opt_errors_encountered=1; break; default: /* unreachable */ break; } } if(opt_errors_encountered) { print_help(argv[0]); } if (optind < argc) { while (optind < argc) { if(!lxname) { lxname = malloc(strlen(argv[optind])+1); strcpy(lxname, argv[optind++]); } else { break; } } } if(!lxname) { print_help(argv[0]); } if(outname) { fv = fopen(outname, "wb"); if(!fv) { fprintf(stderr, "Could not open '%s', exiting.\n", outname); perror("Why"); exit(255); } fvbuf = malloc(VZT_VCD_WRITE_BUF_SIZ); setvbuf(fv, fvbuf, _IOFBF, VZT_VCD_WRITE_BUF_SIZ); } else { fv = stdout; } rc=process_vzt(lxname); if(outname) { free(outname); fclose(fv); } free(fvbuf); free(lxname); return(rc); } gtkwave-3.3.66/src/helpers/v2l_debug_lxt2.h0000664000076400007640000000462512341266475020044 0ustar bybellbybell/* * Copyright (c) 2001-2014 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifndef WAVE_DEBUG_H #define WAVE_DEBUG_H #include #include #ifdef HAVE_INTTYPES_H #include #endif #include struct memchunk { struct memchunk *next; void *ptr; size_t size; }; /* * If you have problems viewing traces (mangled timevalues), * make sure that you use longs rather than the glib 64-bit * types... */ #define G_HAVE_GINT64 #define gint64 int64_t #define guint64 uint64_t #ifdef G_HAVE_GINT64 typedef gint64 TimeType; typedef guint64 UTimeType; #ifndef _MSC_VER #define LLDescriptor(x) x##LL #define ULLDescriptor(x) x##ULL #ifndef __MINGW32__ #if __WORDSIZE == 64 #define TTFormat "%ld" #else #define TTFormat "%lld" #endif #else #define TTFormat "%I64d" #endif #else #define LLDescriptor(x) x##i64 #define ULLDescriptor(x) x##i64 #define TTFormat "%I64d" #endif #else typedef long TimeType; typedef unsigned long UTimeType; #define TTFormat "%d" #define LLDescriptor(x) x #define ULLDescriptor(x) x #endif #ifdef DEBUG_PRINTF #define DEBUG(x) x #else #define DEBUG(x) #endif #ifdef DEBUG_MALLOC #define DEBUG_M(x) x #else #define DEBUG_M(x) #endif void *malloc_2(size_t size); void *realloc_2(void *ptr, size_t size); void *calloc_2(size_t nmemb, size_t size); void free_2(void *ptr); TimeType atoi_64(char *str); #endif gtkwave-3.3.66/src/helpers/vcd2vzt.c0000664000076400007640000012770012527430212016603 0ustar bybellbybell/* * Copyright (c) 1999-2015 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ /* * vcd.c 23jan99ajb * evcd parts 29jun99ajb * profiler optimizations 15jul99ajb * stripped out of gtkwave 21jul99ajb * fix for duplicate nets 19dec00ajb * lxt conversion added 20nov01ajb */ #if defined _AIX #pragma alloca #endif #include #include #include "v2l_analyzer_lxt2.h" #include "vzt_write.h" #include "wave_locale.h" #undef VCD_BSEARCH_IS_PERFECT /* bsearch is imperfect under linux, but OK under AIX */ struct vzt_wr_trace *lt=NULL; int numfacs=0; int deadcnt=0; int ziptype=0; int opt_depth = 4; uint64_t opt_break_size = 0; int opt_maxgranule = 8; int opt_twostate = 0; int opt_rle = 0; struct symbol **sym=NULL; struct symbol **facs=NULL; struct symbol *firstnode=NULL; struct symbol *curnode=NULL; TimeType min_time=-1, max_time=-1; char hier_delimeter='.'; char deadchar='X'; int vcd_explicit_zero_subscripts=-1; /* 0=yes, -1=no */ char atomic_vectors=1; static FILE *vcd_handle=NULL; static char vcd_is_compressed=0; static void add_histent(TimeType time, struct Node *n, char ch, int regadd, char *vector); static void add_tail_histents(void); static void evcd_strcpy(char *dst, char *src); static int vcdlineno=1; static int header_over=0; static int dumping_off=0; static TimeType start_time=-1; static TimeType end_time=-1; static TimeType current_time=-1; static TimeType time_scale=1; /* multiplier is 1, 10, 100 */ static TimeType time_zero=0; static char vcd_hier_delimeter[2]={0, 0}; /* fill in after rc reading code */ /******************************************************************/ static struct slist *slistroot=NULL, *slistcurr=NULL; static char *slisthier=NULL; static int slisthier_len=0; /******************************************************************/ enum Tokens { T_VAR, T_END, T_SCOPE, T_UPSCOPE, T_COMMENT, T_DATE, T_DUMPALL, T_DUMPOFF, T_DUMPON, T_DUMPVARS, T_ENDDEFINITIONS, T_DUMPPORTS, T_DUMPPORTSOFF, T_DUMPPORTSON, T_DUMPPORTSALL, T_TIMESCALE, T_VERSION, T_VCDCLOSE, T_TIMEZERO, T_EOF, T_STRING, T_UNKNOWN_KEY }; char *tokens[]={ "var", "end", "scope", "upscope", "comment", "date", "dumpall", "dumpoff", "dumpon", "dumpvars", "enddefinitions", "dumpports", "dumpportsoff", "dumpportson", "dumpportsall", "timescale", "version", "vcdclose", "timezero", "", "", "" }; #define NUM_TOKENS 19 static int T_MAX_STR=1024; /* was originally a const..now it reallocs */ static char *yytext=NULL; static int yylen=0, yylen_cache=0; #define T_GET tok=get_token();if((tok==T_END)||(tok==T_EOF))break; /******************************************************************/ static struct vcdsymbol *vcdsymroot=NULL, *vcdsymcurr=NULL; static struct vcdsymbol **sorted=NULL; static struct vcdsymbol **indexed=NULL; enum VarTypes { V_EVENT, V_PARAMETER, V_INTEGER, V_REAL, V_REAL_PARAMETER=V_REAL, V_REALTIME=V_REAL, V_STRINGTYPE=V_REAL, V_REG, V_SUPPLY0, V_SUPPLY1, V_TIME, V_TRI, V_TRIAND, V_TRIOR, V_TRIREG, V_TRI0, V_TRI1, V_WAND, V_WIRE, V_WOR, V_PORT, V_IN=V_PORT, V_OUT=V_PORT, V_INOUT=V_PORT, V_END, V_LB, V_COLON, V_RB, V_STRING }; static char *vartypes[]={ "event", "parameter", "integer", "real", "real_parameter", "realtime", "string", "reg", "supply0", "supply1", "time", "tri", "triand", "trior", "trireg", "tri0", "tri1", "wand", "wire", "wor", "port", "in", "out", "inout", "$end", "", "", "", ""}; static const unsigned char varenums[] = { V_EVENT, V_PARAMETER, V_INTEGER, V_REAL, V_REAL_PARAMETER, V_REALTIME, V_STRINGTYPE, V_REG, V_SUPPLY0, V_SUPPLY1, V_TIME, V_TRI, V_TRIAND, V_TRIOR, V_TRIREG, V_TRI0, V_TRI1, V_WAND, V_WIRE, V_WOR, V_PORT, V_IN, V_OUT, V_INOUT, V_END, V_LB, V_COLON, V_RB, V_STRING }; #define NUM_VTOKENS 25 static int numsyms=0; /******************************************************************/ static struct queuedevent *queuedevents=NULL; /******************************************************************/ static unsigned int vcd_minid = ~0; static unsigned int vcd_maxid = 0; static unsigned int vcdid_hash(char *s, int len) { unsigned int val=0; int i; s+=(len-1); for(i=0;iid)); } /* * actual bsearch */ static struct vcdsymbol *bsearch_vcd(char *key, int len) { struct vcdsymbol **v; struct vcdsymbol *t; if(indexed) { unsigned int hsh = vcdid_hash(key, len); if((hsh>=vcd_minid)&&(hsh<=vcd_maxid)) { return(indexed[hsh-vcd_minid]); } } v=(struct vcdsymbol **)bsearch(key, sorted, numsyms, sizeof(struct vcdsymbol *), vcdsymbsearchcompare); if(v) { #ifndef VCD_BSEARCH_IS_PERFECT for(;;) { t=*v; if((v==sorted)||(strcmp((*(--v))->id, key))) { return(t); } } #else return(*v); #endif } else { return(NULL); } } /* * sort on vcdsymbol pointers */ static int vcdsymcompare(const void *s1, const void *s2) { struct vcdsymbol *v1, *v2; v1=*((struct vcdsymbol **)s1); v2=*((struct vcdsymbol **)s2); return(strcmp(v1->id, v2->id)); } /* * alias vs normal symbol adding */ static void alias_vs_normal_symadd(struct vcdsymbol *v, struct vcdsymbol *root_v) { if(!v) return; /* scan-build : should never happen */ if(!root_v) { if((v->vartype==V_INTEGER)||(v->vartype==V_REAL)) { v->ltsym = vzt_wr_symbol_add(lt, v->name, 0, v->msi, v->lsi, (v->vartype==V_INTEGER)?VZT_WR_SYM_F_INTEGER:((v->vartype==V_REAL)?VZT_WR_SYM_F_DOUBLE:VZT_WR_SYM_F_BITS)); } else { char buf[65537]; if(v->msi==v->lsi) { sprintf(buf, "%s[%d]", v->name, v->msi); } else { sprintf(buf, "%s[%d:%d]", v->name, v->msi, v->lsi); } v->ltsym = vzt_wr_symbol_add(lt, buf, 0, v->msi, v->lsi, (v->vartype==V_INTEGER)?VZT_WR_SYM_F_INTEGER:((v->vartype==V_REAL)?VZT_WR_SYM_F_DOUBLE:VZT_WR_SYM_F_BITS)); } } else { if((v->vartype==V_INTEGER)||(v->vartype==V_REAL)) { vzt_wr_symbol_alias(lt, root_v->name, v->name, v->msi, v->lsi); } else { char bufold[65537], buf[65537]; if(v->msi==v->lsi) { sprintf(bufold, "%s[%d]", root_v->name, root_v->msi); sprintf(buf, "%s[%d]", v->name, v->msi); } else { sprintf(bufold, "%s[%d:%d]", root_v->name, root_v->msi, root_v->lsi); sprintf(buf, "%s[%d:%d]", v->name, v->msi, v->lsi); } vzt_wr_symbol_alias(lt, bufold, buf, v->msi, v->lsi); } } } /* * create sorted (by id) table */ static void create_sorted_table(void) { struct vcdsymbol *v; struct vcdsymbol **pnt; unsigned int vcd_distance; struct vcdsymbol *root_v; int i; if(numsyms) { vcd_distance = vcd_maxid - vcd_minid + 1; if(vcd_distance <= 8 * 1024 * 1024) { indexed = (struct vcdsymbol **)calloc_2(vcd_distance, sizeof(struct vcdsymbol *)); printf("%d symbols span ID range of %d, using indexing...\n", numsyms, vcd_distance); v=vcdsymroot; while(v) { if(!(root_v=indexed[v->nid - vcd_minid])) { indexed[v->nid - vcd_minid] = v; } alias_vs_normal_symadd(v, root_v); v=v->next; } } else { pnt=sorted=(struct vcdsymbol **)calloc_2(numsyms, sizeof(struct vcdsymbol *)); v=vcdsymroot; while(v) { *(pnt++)=v; v=v->next; } qsort(sorted, numsyms, sizeof(struct vcdsymbol *), vcdsymcompare); root_v = NULL; for(i=0;iname); v->name = NULL; v=v->next; } } } /******************************************************************/ /* * single char get */ static int getch(void) { int ch; ch=fgetc(vcd_handle); if(ch=='\n') vcdlineno++; return(((ch==EOF)||(errno))?(-1):(ch)); } static int getch_peek(void) { int ch; ch=fgetc(vcd_handle); ungetc(ch, vcd_handle); return(((ch==EOF)||(errno))?(-1):(ch)); } static char *varsplit=NULL, *vsplitcurr=NULL; static int getch_patched(void) { char ch; ch=*vsplitcurr; if(!ch) { return(-1); } else { vsplitcurr++; return((int)ch); } } /* * simple tokenizer */ static int get_token(void) { int ch; int i, len=0; int is_string=0; char *yyshadow; for(;;) { ch=getch(); if(ch<0) return(T_EOF); if(ch<=' ') continue; /* val<=' ' is a quick whitespace check */ break; /* (take advantage of fact that vcd is text) */ } if(ch=='$') { yytext[len++]=ch; for(;;) { ch=getch(); if(ch<0) return(T_EOF); if(ch<=' ') continue; break; } } else { is_string=1; } for(yytext[len++]=ch;;yytext[len++]=ch) { if(len==T_MAX_STR) { yytext=(char *)realloc_2(yytext, (T_MAX_STR=T_MAX_STR*2)+1); } ch=getch(); if(ch<=' ') break; } yytext[len]=0; /* terminator */ if(is_string) { yylen=len; return(T_STRING); } yyshadow=yytext; do { yyshadow++; for(i=0;iw #implicit-var###VarElem:ram_di[0.0] [63:0] $end' style declarations */ { /* debussy simply escapes until the space */ yytext[len++]= '\\'; } for(yytext[len++]=ch;;yytext[len++]=ch) { if(len==T_MAX_STR) { yytext=(char *)realloc_2(yytext, (T_MAX_STR=T_MAX_STR*2)+1); } ch=getch(); if(ch==' ') { if(match_kw) break; if(getch_peek() == '[') { ch = getch(); varsplit=yytext+len; /* keep looping so we get the *last* one */ continue; } } if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')||(ch<0)) break; if((ch=='[')&&(yytext[0]!='\\')) { varsplit=yytext+len; /* keep looping so we get the *last* one */ } else if(((ch==':')||(ch==']'))&&(!varsplit)&&(yytext[0]!='\\')) { var_prevch=ch; break; } } yytext[len]=0; /* absolute terminator */ if((varsplit)&&(yytext[len-1]==']')) { char *vst; vst=malloc_2(strlen(varsplit)+1); strcpy(vst, varsplit); *varsplit=0x00; /* zero out var name at the left bracket */ len=varsplit-yytext; varsplit=vsplitcurr=vst; var_prevch=0; } else { varsplit=NULL; } if(match_kw) for(i=0;ilen+(s->next?1:0); s=s->next; } if(slisthier) { free_2(slisthier); } slisthier=(char *)malloc_2((slisthier_len=len)+1); s=slistroot; len=0; while(s) { strcpy(slisthier+len,s->str); len+=s->len; if(s->next) { strcpy(slisthier+len,vcd_hier_delimeter); len++; } s=s->next; } return(slisthier); } void append_vcd_slisthier(char *str) { struct slist *s; s=(struct slist *)calloc_2(1,sizeof(struct slist)); s->len=strlen(str); s->str=(char *)malloc_2(s->len+1); strcpy(s->str,str); if(slistcurr) { slistcurr->next=s; slistcurr=s; } else { slistcurr=slistroot=s; } build_slisthier(); DEBUG(fprintf(stderr, "SCOPE: %s\n",slisthier)); } static void parse_valuechange(void) { struct vcdsymbol *v; char *vector; int vlen; switch(yytext[0]) { case '0': case '1': case 'x': case 'X': case 'z': case 'Z': case 'h': case 'H': case 'u': case 'U': case 'w': case 'W': case 'l': case 'L': case '-': if(yylen>1) { v=bsearch_vcd(yytext+1, yylen-1); if(!v) { fprintf(stderr,"Near line %d, Unknown VCD identifier: '%s'\n",vcdlineno,yytext+1); } else { if(v->vartype!=V_EVENT) { char vl[2]; vl[0]=yytext[0]; vl[1]=0; vzt_wr_emit_value_bit_string(lt, v->ltsym, 0, vl); v->value[0]=yytext[0]; DEBUG(fprintf(stderr,"%s = '%c'\n",v->name,v->value[0])); add_histent(current_time,v->narray[0],v->value[0],1, NULL); } else { char vl[2]; v->value[0]=(dumping_off)?'x':'1'; /* only '1' is relevant */ if(current_time!=(v->ev->last_event_time+1)) { /* dump degating event */ DEBUG(fprintf(stderr,"#"TTFormat" %s = '%c' (event)\n",v->ev->last_event_time+1,v->name,'0')); add_histent(v->ev->last_event_time+1,v->narray[0],'0',1, NULL); } DEBUG(fprintf(stderr,"%s = '%c' (event)\n",v->name,v->value[0])); add_histent(current_time,v->narray[0],v->value[0],1, NULL); vl[0]='1'; vl[1]=0; vzt_wr_emit_value_bit_string(lt, v->ltsym, 0, vl); vl[0]='0'; vl[1]=0; vzt_wr_emit_value_bit_string(lt, v->ltsym, 0, vl); v->ev->last_event_time=current_time; } } } else { fprintf(stderr,"Near line %d, Malformed VCD identifier\n", vcdlineno); } break; case 'b': case 'B': /* extract binary number then.. */ vector=malloc_2(yylen_cache=yylen); strcpy(vector,yytext+1); vlen=yylen-1; get_strtoken(); v=bsearch_vcd(yytext, yylen); if(!v) { fprintf(stderr,"Near line %d, Unknown identifier: '%s'\n",vcdlineno, yytext); free_2(vector); } else { if(vlensize) /* fill in left part */ { char extend; int i, fill; extend=(vector[0]=='1')?'0':vector[0]; fill=v->size-vlen; for(i=0;ivalue[i]=extend; } strcpy(v->value+fill,vector); } else if(vlen==v->size) /* straight copy */ { strcpy(v->value,vector); } else /* too big, so copy only right half */ { int skip; skip=vlen-v->size; strcpy(v->value,vector+skip); } DEBUG(fprintf(stderr,"%s = '%s'\n",v->name, v->value)); vzt_wr_emit_value_bit_string(lt, v->ltsym, 0, v->value); if((v->size==1)||(!atomic_vectors)) { int i; for(i=0;isize;i++) { add_histent(current_time, v->narray[i],v->value[i],1, NULL); } free_2(vector); } else { if(yylen_cache!=(v->size+1)) { free_2(vector); vector=malloc_2(v->size+1); } strcpy(vector,v->value); add_histent(current_time, v->narray[0],0,1,vector); free_2(vector); } } break; case 'p': /* extract port dump value.. */ vector=malloc_2(yylen_cache=yylen); strcpy(vector,yytext+1); vlen=yylen-1; get_strtoken(); /* throw away 0_strength_component */ get_strtoken(); /* throw away 0_strength_component */ get_strtoken(); /* this is the id */ v=bsearch_vcd(yytext, yylen); if(!v) { fprintf(stderr,"Near line %d, Unknown identifier: '%s'\n",vcdlineno, yytext); free_2(vector); } else { if(vlensize) /* fill in left part */ { char extend; int i, fill; extend='0'; fill=v->size-vlen; for(i=0;ivalue[i]=extend; } evcd_strcpy(v->value+fill,vector); } else if(vlen==v->size) /* straight copy */ { evcd_strcpy(v->value,vector); } else /* too big, so copy only right half */ { int skip; skip=vlen-v->size; evcd_strcpy(v->value,vector+skip); } DEBUG(fprintf(stderr,"%s = '%s'\n",v->name, v->value)); vzt_wr_emit_value_bit_string(lt, v->ltsym, 0, v->value); if((v->size==1)||(!atomic_vectors)) { int i; for(i=0;isize;i++) { add_histent(current_time, v->narray[i],v->value[i],1, NULL); } free_2(vector); } else { if(yylen_cachesize) { free_2(vector); vector=malloc_2(v->size+1); } strcpy(vector,v->value); add_histent(current_time, v->narray[0],0,1,vector); free_2(vector); } } break; case 'r': case 'R': { double *d; d=malloc_2(sizeof(double)); *d = 0; sscanf(yytext+1,"%lg",d); errno = 0; get_strtoken(); v=bsearch_vcd(yytext, yylen); if(!v) { fprintf(stderr,"Near line %d, Unknown identifier: '%s'\n",vcdlineno, yytext); free_2(d); } else { if(v->vartype == V_REAL) { vzt_wr_emit_value_double(lt, v->ltsym, 0, *d); add_histent(current_time, v->narray[0],'g',1,(char *)d); } else { fprintf(stderr,"Near line %d, real value change for non-real '%s'\n",vcdlineno, yytext); } free_2(d); } break; } case 's': case 'S': { get_strtoken(); /* simply skip for now */ break; } } } static void evcd_strcpy(char *dst, char *src) { static const char *evcd="DUNZduLHXTlh01?FAaBbCcf"; static const char *vcd="01xz0101xz0101xzxxxxxxz"; char ch; int i; while((ch=*src)) { for(i=0;i<23;i++) { if(evcd[i]==ch) { *dst=vcd[i]; break; } } if(i==23) *dst='x'; src++; dst++; } *dst=0; /* null terminate destination */ } static void vcd_parse(void) { int tok; for(;;) { switch(get_token()) { case T_COMMENT: sync_end("COMMENT:"); break; case T_DATE: sync_end("DATE:"); break; case T_VERSION: sync_end("VERSION:"); break; case T_TIMEZERO: { int vtok=get_token(); if((vtok==T_END)||(vtok==T_EOF)) break; time_zero=atoi_64(yytext); vzt_wr_set_timezero(lt, time_zero); sync_end(NULL); } break; case T_TIMESCALE: { int vtok; int i; char prefix=' '; int timelogadjust = 0; vtok=get_token(); if((vtok==T_END)||(vtok==T_EOF)) break; time_scale=atoi_64(yytext); if(!time_scale) time_scale=1; else if (time_scale == 10 ) timelogadjust = +1; else if (time_scale == 100) timelogadjust = +2; for(i=0;i'9')) { prefix=yytext[i]; break; } } if(prefix==' ') { vtok=get_token(); if((vtok==T_END)||(vtok==T_EOF)) break; prefix=yytext[0]; } switch(prefix) { case 's': case ' ': vzt_wr_set_timescale(lt, 0+timelogadjust); break; case 'm': vzt_wr_set_timescale(lt, -3+timelogadjust); break; case 'u': vzt_wr_set_timescale(lt, -6+timelogadjust); break; case 'n': vzt_wr_set_timescale(lt, -9+timelogadjust); break; case 'p': vzt_wr_set_timescale(lt, -12+timelogadjust); break; case 'f': vzt_wr_set_timescale(lt, -15+timelogadjust); break; default: /* unknown */ vzt_wr_set_timescale(lt, -9+timelogadjust); break; } sync_end(NULL); } break; case T_SCOPE: T_GET; T_GET; if(tok==T_STRING) { struct slist *s; s=(struct slist *)calloc_2(1,sizeof(struct slist)); s->len=yylen; s->str=(char *)malloc_2(yylen+1); strcpy(s->str,yytext); if(slistcurr) { slistcurr->next=s; slistcurr=s; } else { slistcurr=slistroot=s; } build_slisthier(); DEBUG(fprintf(stderr, "SCOPE: %s\n",slisthier)); } sync_end(NULL); break; case T_UPSCOPE: if(slistroot) { struct slist *s; s=slistroot; if(!s->next) { free_2(s->str); free_2(s); slistroot=slistcurr=NULL; } else for(;;) { if(!s->next->next) { free_2(s->next->str); free_2(s->next); s->next=NULL; slistcurr=s; break; } s=s->next; } build_slisthier(); DEBUG(fprintf(stderr, "SCOPE: %s\n",slisthier)); } sync_end(NULL); break; case T_VAR: { int vtok; struct vcdsymbol *v=NULL; var_prevch=0; if(varsplit) { free_2(varsplit); varsplit=NULL; } vtok=get_vartoken(1); if(vtok>V_PORT) goto bail; v=(struct vcdsymbol *)calloc_2(1,sizeof(struct vcdsymbol)); v->vartype=vtok; v->msi=v->lsi=vcd_explicit_zero_subscripts; /* indicate [un]subscripted status */ if(vtok==V_PORT) { vtok=get_vartoken(1); if(vtok==V_STRING) { v->size=atoi_64(yytext); if(!v->size) v->size=1; } else if(vtok==V_LB) { vtok=get_vartoken(1); if(vtok==V_END) goto err; if(vtok!=V_STRING) goto err; v->msi=atoi_64(yytext); vtok=get_vartoken(0); if(vtok==V_RB) { v->lsi=v->msi; v->size=1; } else { if(vtok!=V_COLON) goto err; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; v->lsi=atoi_64(yytext); vtok=get_vartoken(0); if(vtok!=V_RB) goto err; if(v->msi>v->lsi) { v->size=v->msi-v->lsi+1; } else { v->size=v->lsi-v->msi+1; } } } else goto err; vtok=get_strtoken(); if(vtok==V_END) goto err; v->id=(char *)malloc_2(yylen+1); strcpy(v->id, yytext); v->nid=vcdid_hash(yytext,yylen); if(v->nid < vcd_minid) vcd_minid = v->nid; if(v->nid > vcd_maxid) vcd_maxid = v->nid; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; if(slisthier_len) { v->name=(char *)malloc_2(slisthier_len+1+yylen+1); strcpy(v->name,slisthier); strcpy(v->name+slisthier_len,vcd_hier_delimeter); strcpy(v->name+slisthier_len+1,yytext); } else { v->name=(char *)malloc_2(yylen+1); strcpy(v->name,yytext); } } else /* regular vcd var, not an evcd port var */ { vtok=get_vartoken(1); if(vtok==V_END) goto err; v->size=atoi_64(yytext); vtok=get_strtoken(); if(vtok==V_END) goto err; v->id=(char *)malloc_2(yylen+1); strcpy(v->id, yytext); v->nid=vcdid_hash(yytext,yylen); if(v->nid < vcd_minid) vcd_minid = v->nid; if(v->nid > vcd_maxid) vcd_maxid = v->nid; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; if(slisthier_len) { v->name=(char *)malloc_2(slisthier_len+1+yylen+1); strcpy(v->name,slisthier); strcpy(v->name+slisthier_len,vcd_hier_delimeter); strcpy(v->name+slisthier_len+1,yytext); } else { v->name=(char *)malloc_2(yylen+1); strcpy(v->name,yytext); } vtok=get_vartoken(1); if(vtok==V_END) goto dumpv; if(vtok!=V_LB) goto err; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; v->msi=atoi_64(yytext); vtok=get_vartoken(0); if(vtok==V_RB) { v->lsi=v->msi; goto dumpv; } if(vtok!=V_COLON) goto err; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; v->lsi=atoi_64(yytext); vtok=get_vartoken(0); if(vtok!=V_RB) goto err; } dumpv: if(v->size == 0) { v->vartype = V_REAL; } /* MTI fix */ if(v->vartype==V_REAL) { v->size=1; /* override any data we parsed in */ v->msi=v->lsi=0; } else if((v->size>1)&&(v->msi<=0)&&(v->lsi<=0)) { if(v->vartype==V_EVENT) { v->size=1; } else { /* any criteria for the direction here? */ v->msi=v->size-1; v->lsi=0; } } else if((v->msi>v->lsi)&&((v->msi-v->lsi+1)!=v->size)) { if(v->vartype!=V_EVENT) goto err; v->size=v->msi-v->lsi+1; } else if((v->lsi>=v->msi)&&((v->lsi-v->msi+1)!=v->size)) { if(v->vartype!=V_EVENT) goto err; v->size=v->msi-v->lsi+1; } /* initial conditions */ v->value=(char *)malloc_2(v->size+1); v->value[v->size]=0; v->narray=(struct Node **)calloc_2(v->size,sizeof(struct Node *)); { int i; for(i=0;isize;i++) { v->value[i]='x'; v->narray[i]=(struct Node *)calloc_2(1,sizeof(struct Node)); v->narray[i]->head.time=-1; v->narray[i]->head.v.val=1; } } if(v->vartype==V_EVENT) { struct queuedevent *q; v->ev=q=(struct queuedevent *)calloc_2(1,sizeof(struct queuedevent)); q->sym=v; q->last_event_time=-1; q->next=queuedevents; queuedevents=q; } if(!vcdsymroot) { vcdsymroot=vcdsymcurr=v; } else { vcdsymcurr->next=v; vcdsymcurr=v; } numsyms++; #if 0 if((v->vartype==V_INTEGER)||(v->vartype==V_REAL)) { v->ltsym = vzt_wr_symbol_add(lt, v->name, 0, v->msi, v->lsi, (v->vartype==V_INTEGER)?VZT_WR_SYM_F_INTEGER:((v->vartype==V_REAL)?VZT_WR_SYM_F_DOUBLE:VZT_WR_SYM_F_BITS)); } else { char buf[65537]; if(v->msi==v->lsi) { sprintf(buf, "%s[%d]", v->name, v->msi); } else { sprintf(buf, "%s[%d:%d]", v->name, v->msi, v->lsi); } v->ltsym = vzt_wr_symbol_add(lt, buf, 0, v->msi, v->lsi, (v->vartype==V_INTEGER)?VZT_WR_SYM_F_INTEGER:((v->vartype==V_REAL)?VZT_WR_SYM_F_DOUBLE:VZT_WR_SYM_F_BITS)); } #endif DEBUG(fprintf(stderr,"VAR %s %d %s %s[%d:%d]\n", vartypes[v->vartype], v->size, v->id, v->name, v->msi, v->lsi)); goto bail; err: if(v) { if(v->name) free_2(v->name); if(v->id) free_2(v->id); if(v->value) free_2(v->value); free_2(v); } bail: if(vtok!=V_END) sync_end(NULL); break; } case T_ENDDEFINITIONS: if(!header_over) { header_over=1; /* do symbol table management here */ create_sorted_table(); if((!sorted)&&(!indexed)) { fprintf(stderr, "No symbols in VCD file..nothing to do!\n"); exit(1); } } break; case T_STRING: if(header_over) { /* catchall for events when header over */ if(yytext[0]=='#') { TimeType t_time; t_time=atoi_64(yytext+1); if(start_time<0) { start_time=t_time; } if(t_time < current_time) /* avoid backtracking time counts which can happen on malformed files */ { t_time = current_time; } current_time=t_time; if(end_timecurr) { he=(struct HistEnt *)calloc_2(1,sizeof(struct HistEnt)); he->time=-1; he->v.val=1; n->curr=he; n->head.next=he; add_histent(t_time,n,ch,regadd, vector); } else { /* if(regadd) { t_time*=(time_scale); } */ /* scan-build : never read */ if(toupper((int)(unsigned char)ch)!=deadchar) n->notdead=1; n->numtrans++; } } else { if(ch=='g') /* real number */ { if(!n->curr) { he=(struct HistEnt *)calloc_2(1,sizeof(struct HistEnt)); he->time=-1; he->v.vector=NULL; n->curr=he; n->head.next=he; add_histent(t_time,n,ch,regadd, vector); } else { n->notdead=1; n->numtrans++; } } else { if(!n->curr) { he=(struct HistEnt *)calloc_2(1,sizeof(struct HistEnt)); he->time=-1; he->v.vector=NULL; n->curr=he; n->head.next=he; add_histent(t_time,n,ch,regadd, vector); } else { int i, nlen; nlen = strlen(vector); if(nlen) { n->numtrans++; for(i=0;inotdead=1; return; } } } } } } } static void add_tail_histents(void) { /* dump out any pending events 1st */ struct queuedevent *q; q=queuedevents; while(q) { struct vcdsymbol *v; v=q->sym; if(current_time!=(v->ev->last_event_time+1)) { /* dump degating event */ DEBUG(fprintf(stderr,"#"TTFormat" %s = '%c' (event)\n",v->ev->last_event_time+1,v->name,'0')); add_histent(v->ev->last_event_time+1,v->narray[0],'0',1, NULL); } q=q->next; } } /*******************************************************************************/ TimeType vcd_main(char *fname, char *lxname) { #ifdef ONLY_NEEDED_FOR_VALGRIND_CLEAN_TEST struct vcdsymbol *v, *v2; #endif vcd_hier_delimeter[0]=hier_delimeter; errno=0; /* reset in case it's set for some reason */ yytext=(char *)malloc_2(T_MAX_STR+1); if((strlen(fname)>2)&&(!strcmp(fname+strlen(fname)-3,".gz"))) { char *str; int dlen; dlen=strlen(WAVE_DECOMPRESSOR); str=(char *)wave_alloca(strlen(fname)+dlen+1); strcpy(str,WAVE_DECOMPRESSOR); strcpy(str+dlen,fname); vcd_handle=popen(str,"r"); vcd_is_compressed=~0; } else { if(strcmp("-",fname)) { vcd_handle=fopen(fname,"rb"); } else { vcd_handle=stdin; } vcd_is_compressed=0; } if(!vcd_handle) { fprintf(stderr, "Error opening %s .vcd file '%s'.\n", vcd_is_compressed?"compressed":"", fname); exit(1); } lt=vzt_wr_init(lxname); if(!lt) { fprintf(stderr, "Problem opening output file '%s'\n", lxname); perror("Why"); exit(255); } vzt_wr_set_compression_type(lt, ziptype); if(opt_twostate) { vzt_wr_force_twostate(lt); } vzt_wr_set_rle(lt, opt_rle); vzt_wr_set_compression_depth(lt, opt_depth); vzt_wr_set_break_size(lt, (off_t)opt_break_size); vzt_wr_set_maxgranule(lt, opt_maxgranule); vzt_wr_symbol_bracket_stripping(lt, 1); /* this is intentional */ sym=(struct symbol **)calloc_2(SYMPRIME,sizeof(struct symbol *)); printf("\nConverting VCD File '%s' to VZT file '%s'...\n\n",(vcd_handle!=stdin)?fname:"from stdin", lxname); build_slisthier(); vcd_parse(); if(varsplit) { free_2(varsplit); varsplit=NULL; } add_tail_histents(); printf("["TTFormat"] start time.\n["TTFormat"] end time.\n\n", start_time, end_time); vzt_wr_close(lt); lt=NULL; min_time=start_time*time_scale; max_time=end_time*time_scale; if((min_time==max_time)||(max_time==0)) { fprintf(stderr, "VCD times range is equal to zero. Exiting.\n"); exit(1); } if(vcd_handle!=stdin) { fclose(vcd_handle); vcd_handle=NULL; } free(yytext); yytext=NULL; if(indexed) { free(indexed); indexed=NULL; } if(sorted) { free(sorted); sorted=NULL; } #ifdef ONLY_NEEDED_FOR_VALGRIND_CLEAN_TEST v=vcdsymroot; while(v) { if(v->name) { free(v->name); v->name=NULL; } if(v->id) { free(v->id); v->id=NULL; } if(v->value) { free(v->value); v->value=NULL; } if(v->narray) { int i; for(i=0;isize;i++) { struct HistEnt *h1, *h2; if((h1 = v->narray[i]->head.next)) { h1 = v->narray[i]->head.next; while(h1) { h2 = h1->next; free(h1); h1 = h2; } } free(v->narray[i]); v->narray[i]=NULL; } free(v->narray); v->narray=NULL; } v2=v->next; free(v); v=v2; } vcdsymroot=vcdsymcurr=NULL; #endif free(sym); sym=NULL; if(slisthier) { free(slisthier); slisthier=NULL; } return(max_time); } /*******************************************************************************/ /* * Generic hash function for symbol names... */ int hash(char *s) { char *p; unsigned int h=0, g; for(p=s;*p;p++) { h=(h<<4)+(*p); if((g=h&0xf0000000)) { h=h^(g>>24); h=h^g; } } return(h%SYMPRIME); } /* * add symbol to table. no duplicate checking * is necessary as aet's are "correct." */ struct symbol *symadd(char *name, int hv) { struct symbol *s; s=(struct symbol *)calloc_2(1,sizeof(struct symbol)); strcpy(s->name=(char *)malloc_2(strlen(name)+1),name); s->next=sym[hv]; sym[hv]=s; return(s); } /* * find a slot already in the table... */ struct symbol *symfind(char *s) { int hv; struct symbol *temp; hv=hash(s); if(!(temp=sym[hv])) return(NULL); /* no hash entry, add here wanted to add */ while(temp) { if(!strcmp(temp->name,s)) { return(temp); /* in table already */ } if(!temp->next) break; temp=temp->next; } return(NULL); /* not found, add here if you want to add*/ } int sigcmp(char *s1, char *s2) { unsigned char c1, c2; int u1, u2; for(;;) { c1=(unsigned char)*(s1++); c2=(unsigned char)*(s2++); if((!c1)&&(!c2)) return(0); if((c1<='9')&&(c2<='9')&&(c2>='0')&&(c1>='0')) { u1=(int)(c1&15); u2=(int)(c2&15); while(((c2=(unsigned char)*s2)>='0')&&(c2<='9')) { u2*=10; u2+=(unsigned int)(c2&15); s2++; } while(((c2=(unsigned char)*s1)>='0')&&(c2<='9')) { u1*=10; u1+=(unsigned int)(c2&15); s1++; } if(u1==u2) continue; else return((int)u1-(int)u2); } else { if(c1!=c2) return((int)c1-(int)c2); } } } int partition(struct symbol **a, int p, int r) { struct symbol *x, *t; int i,j; x=a[p]; i=p-1; j=r+1; while(1) { do { j--; } while(sigcmp(a[j]->name,x->name)>0); do { i++; } while(sigcmp(a[i]->name,x->name)<0); if(i.\n",nam); #else printf( "Usage: %s [OPTION]... [VCDFILE] [VZTFILE]\n\n" " -v FILE specify VCD input filename\n" " -l FILE specify VZT output filename\n" " -d value specify 0..9 compression depth (default = 4)\n" " -m value specify number of granules per section (def = 8)\n" " -b value specify break size (default = 0 = off)\n" " -z value specify zip type (default: 0 gzip, 1 bzip2, 2 lzma)\n" " -t force MVL2 twostate mode (default is MVL4)\n" " -r use bitwise RLE compression on value table\n" " -h display this help then exit\n\n" "VCD files may be compressed with zip or gzip. Note that VCDFILE and VZTFILE\n" "are optional provided the --vcdname and --vztname options are specified.\n" "Use \"-\" as a VCD filename to accept uncompressed input from stdin.\n\n" "Report bugs to <"PACKAGE_BUGREPORT">.\n",nam); #endif exit(0); } int main(int argc, char **argv) { char opt_errors_encountered=0; char *vname=NULL, *lxname=NULL; int c; WAVE_LOCALE_FIX while (1) { #ifdef __linux__ int option_index = 0; static struct option long_options[] = { {"vcdname", 1, 0, 'v'}, {"vztname", 1, 0, 'l'}, {"depth", 1, 0, 'd'}, {"maxgranule", 1, 0, 'm'}, {"break", 1, 0, 'b'}, {"help", 0, 0, 'h'}, {"twostate", 0, 0, 't'}, {"rle", 0, 0, 'r'}, {"ziptype", 1, 0, 'z'}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "v:l:d:m:b:z:htr", long_options, &option_index); #else c = getopt (argc, argv, "v:l:d:m:b:z:htr"); #endif if (c == -1) break; /* no more args */ switch (c) { case 'v': if(vname) free(vname); vname = malloc_2(strlen(optarg)+1); strcpy(vname, optarg); break; case 'l': if(lxname) free(lxname); lxname = malloc_2(strlen(optarg)+1); strcpy(lxname, optarg); break; case 'd': opt_depth = atoi(optarg); if(opt_depth<0) opt_depth = 0; if(opt_depth>9) opt_depth = 9; break; case 'm': opt_maxgranule = atoi(optarg); if(opt_maxgranule<1) opt_maxgranule=1; break; case 'b': sscanf(optarg, "%"SCNu64, &opt_break_size); errno = 0; break; case 'h': print_help(argv[0]); break; case 't': opt_twostate = 1; break; case 'r': opt_rle = 1; break; case 'z': ziptype = atoi(optarg); if((ziptype < VZT_WR_IS_GZ) || (ziptype > VZT_WR_IS_LZMA)) ziptype = VZT_WR_IS_GZ; break; case '?': opt_errors_encountered=1; break; default: /* unreachable */ break; } } if(opt_errors_encountered) { print_help(argv[0]); } if (optind < argc) { while (optind < argc) { if(!vname) { vname = malloc_2(strlen(argv[optind])+1); strcpy(vname, argv[optind++]); } else if(!lxname) { lxname = malloc_2(strlen(argv[optind])+1); strcpy(lxname, argv[optind++]); } else { break; } } } if((!vname)||(!lxname)) { print_help(argv[0]); } vcd_main(vname, lxname); free(vname); free(lxname); return(0); } gtkwave-3.3.66/src/helpers/vzt_read.c0000664000076400007640000015321512523241774017030 0ustar bybellbybell/* * Copyright (c) 2003-2015 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #if defined(__CYGWIN__) || defined(__MINGW32__) #undef HAVE_RPC_XDR_H #endif #if HAVE_RPC_XDR_H #include #include #endif #include "vzt_read.h" #ifdef HAVE_FCNTL_H #include #endif /****************************************************************************/ static int is_big_endian(void) { union { vztint32_t u32; unsigned char c[sizeof(vztint32_t)]; } u; u.u32 = 1; return(u.c[sizeof(vztint32_t)-1] == 1); } /****************************************************************************/ struct vzt_ncycle_autosort { struct vzt_ncycle_autosort *next; }; struct vzt_pth_args { struct vzt_rd_trace *lt; struct vzt_rd_block *b; }; struct vzt_synvec_chain { vztint32_t num_entries; vztint32_t chain[1]; }; #ifdef PTHREAD_CREATE_DETACHED _VZT_RD_INLINE static int vzt_rd_pthread_mutex_init(struct vzt_rd_trace *lt, pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr) { if(lt->pthreads) { pthread_mutex_init(mutex, mutexattr); } return(0); } _VZT_RD_INLINE static void vzt_rd_pthread_mutex_lock(struct vzt_rd_trace *lt, pthread_mutex_t *mx) { if(lt->pthreads) { pthread_mutex_lock(mx); } } _VZT_RD_INLINE static void vzt_rd_pthread_mutex_unlock(struct vzt_rd_trace *lt, pthread_mutex_t *mx) { if(lt->pthreads) { pthread_mutex_unlock(mx); } } _VZT_RD_INLINE static void vzt_rd_pthread_mutex_destroy(struct vzt_rd_trace *lt, pthread_mutex_t *mutex) { if(lt->pthreads) { pthread_mutex_destroy(mutex); } } _VZT_RD_INLINE static void vzt_rd_pthread_create(struct vzt_rd_trace *lt, pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) { if(lt->pthreads) { pthread_attr_init(attr); pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED); pthread_create(thread, attr, start_routine, arg); } } #else #define vzt_rd_pthread_mutex_init(a, b, c) #define vzt_rd_pthread_mutex_lock(a, b) #define vzt_rd_pthread_mutex_unlock(a, b) #define vzt_rd_pthread_mutex_destroy(a, b) #define vzt_rd_pthread_create(a, b, c, d, e) #endif /****************************************************************************/ #ifdef _WAVE_BE32 /* * reconstruct 8/16/32/64 bits out of the vzt's representation * of a big-endian integer. this is for 32-bit PPC so no byte * swizzling needs to be done at all. */ #define vzt_rd_get_byte(mm,offset) ((unsigned int)(*((unsigned char *)(mm)+(offset)))) #define vzt_rd_get_16(mm,offset) ((unsigned int)(*((unsigned short *)(((unsigned char *)(mm))+(offset))))) #define vzt_rd_get_32(mm,offset) (*(unsigned int *)(((unsigned char *)(mm))+(offset))) #define vzt_rd_get_64(mm,offset) ((((vztint64_t)vzt_rd_get_32((mm),(offset)))<<32)|((vztint64_t)vzt_rd_get_32((mm),(offset)+4))) #else /* * reconstruct 8/16/24/32 bits out of the vzt's representation * of a big-endian integer. this should work on all architectures. */ #define vzt_rd_get_byte(mm,offset) ((unsigned int)(*((unsigned char *)(mm)+(offset)))) static unsigned int vzt_rd_get_16(void *mm, int offset) { unsigned char *nn=(unsigned char *)mm+offset; unsigned int m1=*((unsigned char *)(nn++)); unsigned int m2=*((unsigned char *)nn); return((m1<<8)|m2); } static unsigned int vzt_rd_get_32(void *mm, int offset) { unsigned char *nn=(unsigned char *)mm+offset; unsigned int m1=*((unsigned char *)(nn++)); unsigned int m2=*((unsigned char *)(nn++)); unsigned int m3=*((unsigned char *)(nn++)); unsigned int m4=*((unsigned char *)nn); return((m1<<24)|(m2<<16)|(m3<<8)|m4); } static vztint64_t vzt_rd_get_64(void *mm, int offset) { return( (((vztint64_t)vzt_rd_get_32(mm,offset))<<32) |((vztint64_t)vzt_rd_get_32(mm,offset+4)) ); } #endif static unsigned int vzt_rd_get_32r(void *mm, int offset) { unsigned char *nn=(unsigned char *)mm+offset; unsigned int m4=*((unsigned char *)(nn++)); unsigned int m3=*((unsigned char *)(nn++)); unsigned int m2=*((unsigned char *)(nn++)); unsigned int m1=*((unsigned char *)nn); return((m1<<24)|(m2<<16)|(m3<<8)|m4); } static vztint32_t vzt_rd_get_v32(char **mmx) { signed char *c; signed char *beg; vztint32_t val; signed char **mm = (signed char **)mmx; c = *mm; beg = c; if(*c>=0) { while(*c>=0) c++; *mm = c+1; val = (vztint32_t)(*c&0x7f); do { val <<= 7; val |= (vztint32_t)*(--c); } while (c!=beg); } else { *mm = c+1; val = (vztint32_t)(*c&0x7f); } return(val); } static vztint64_t vzt_rd_get_v64(char **mmx) { signed char *c; signed char *beg; vztint64_t val; signed char **mm = (signed char **)mmx; c = *mm; beg = c; if(*c>=0) { while(*c>=0) c++; *mm = c+1; val = (vztint64_t)(*c&0x7f); do { val <<= 7; val |= (vztint64_t)*(--c); } while (c!=beg); } else { val = (vztint64_t)(*c&0x7f); *mm = c+1; } return(val); } #if 0 _VZT_RD_INLINE static vztint32_t vzt_rd_get_v32_rvs(signed char **mm) { signed char *c = *mm; vztint32_t val; val = (vztint32_t)(*(c--)&0x7f); while(*c>=0) { val <<= 7; val |= (vztint32_t)*(c--); } *mm = c; return(val); } #endif /****************************************************************************/ /* * fast SWAR ones count for 32 bits */ _VZT_RD_INLINE static vztint32_t vzt_rd_ones_cnt(vztint32_t x) { x -= ((x >> 1) & 0x55555555); x = (((x >> 2) & 0x33333333) + (x & 0x33333333)); x = (((x >> 4) + x) & 0x0f0f0f0f); return((x * 0x01010101) >> 24); } /* * total zero count to the right of the first rightmost one bit * encountered. its intended use is to * "return the bitposition of the least significant 1 in vztint32_t" * (use x &= ~(x&-x) to clear out that bit quickly) */ _VZT_RD_INLINE static vztint32_t vzt_rd_tzc(vztint32_t x) { return (vzt_rd_ones_cnt((x & -x) - 1)); } /****************************************************************************/ /* * i2c utility function */ unsigned int vzt_rd_expand_bits_to_integer(int len, char *s) { unsigned int v = 0; int i; for(i=0;imutex); if((!b->times)&&(b->mem)) { vztint64_t *times=NULL; vztint32_t *change_dict=NULL; vztint32_t *val_dict=NULL; unsigned int num_time_ticks, num_sections, num_dict_entries; char *pnt = b->mem; vztint32_t i, j, m, num_dict_words; /* vztint32_t *block_end = (vztint32_t *)(pnt + b->uncompressed_siz); */ vztint32_t *val_tmp; unsigned int num_bitplanes; uintptr_t padskip; num_time_ticks = vzt_rd_get_v32(&pnt); /* fprintf(stderr, "* num_time_ticks = %d\n", num_time_ticks); */ if(num_time_ticks != 0) { vztint64_t cur_time; times = malloc(num_time_ticks * sizeof(vztint64_t)); times[0] = cur_time = vzt_rd_get_v64(&pnt); for(i=1;istart; num_time_ticks = b->end - b->start + 1; times = malloc(num_time_ticks * sizeof(vztint64_t)); for(i=0;irle) { vztint32_t *curr_dec_dict; vztint32_t first_bit = 0, curr_bit = 0; vztint32_t runlen; val_dict = calloc(1, b->num_rle_bytes = (num_dict_words = num_sections * num_dict_entries) * sizeof(vztint32_t)); curr_dec_dict = val_dict; vzt_rd_pthread_mutex_lock(lt, <->mutex); lt->block_mem_consumed += b->num_rle_bytes; vzt_rd_pthread_mutex_unlock(lt, <->mutex); for(i=0;imulti_state = (num_bitplanes > 1); padskip = ((uintptr_t)pnt)&3; pnt += (padskip) ? 4-padskip : 0; /* skip pad to next 4 byte boundary */ b->vindex = (vztint32_t *)(pnt); if(is_big_endian()) /* have to bswap the value changes on big endian machines... */ { if(!b->rle) { for(i=0;ivindex; for(i=0;itotal_values;j++) { *val_tmp = vzt_rd_get_32r(val_tmp, 0); val_tmp++; } } } pnt = (char *)(b->vindex + num_bitplanes * lt->total_values); b->num_str_entries = vzt_rd_get_v32(&pnt); if(b->num_str_entries) { b->sindex = calloc(b->num_str_entries, sizeof(char *)); for(i=0;inum_str_entries;i++) { b->sindex[i] = pnt; pnt += (strlen(pnt) + 1); } } num_dict_words = (num_sections * num_dict_entries) * sizeof(vztint32_t); change_dict = malloc(num_dict_words ? num_dict_words : sizeof(vztint32_t)); /* scan-build */ m = 0; for(i=0;i> 31; } } b->val_dict = val_dict; b->change_dict = change_dict; b->times = times; b->num_time_ticks = num_time_ticks; b->num_dict_entries = num_dict_entries; b->num_sections = num_sections; } vzt_rd_pthread_mutex_unlock(lt, &b->mutex); } static int vzt_rd_block_vch_free(struct vzt_rd_trace *lt, struct vzt_rd_block *b, int killed) { vzt_rd_pthread_mutex_lock(lt, &b->mutex); if(killed) b->killed = killed; /* never allocate ever again (in case we prefetch on process kill) */ if((b->rle) && (b->val_dict)) { free(b->val_dict); b->val_dict = NULL; vzt_rd_pthread_mutex_lock(lt, <->mutex); lt->block_mem_consumed -= b->num_rle_bytes; vzt_rd_pthread_mutex_unlock(lt, <->mutex); } if(b->mem) { free(b->mem); b->mem = NULL; } if(b->change_dict) { free(b->change_dict); b->change_dict = NULL; } if(b->times) { free(b->times); b->times = NULL; } if(b->sindex) { free(b->sindex); b->sindex = NULL; } vzt_rd_pthread_mutex_unlock(lt, &b->mutex); return(1); } vztint32_t vzt_rd_next_value_chg_time(struct vzt_rd_trace *lt, struct vzt_rd_block *b, vztint32_t time_offset, vztint32_t facidx) { unsigned int i; vztint32_t len = lt->len[facidx]; vztint32_t vindex_offset = lt->vindex_offset[facidx]; vztint32_t vindex_offset_x = vindex_offset + lt->total_values; vztint32_t old_time_offset = time_offset; int word = time_offset / 32; int bit = (time_offset & 31) + 1; int row_size = b->num_sections; vztint32_t *valpnt, *valpnt_x; vztint32_t change_msk; if((time_offset>=(b->num_time_ticks-1))||(facidx>lt->numrealfacs)) return(time_offset); time_offset &= ~31; for(;wordflags[facidx]&VZT_RD_SYM_F_SYNVEC)) { if(b->multi_state) { for(i=0;ichange_dict + (b->vindex[vindex_offset+i] * row_size + word); valpnt_x = b->change_dict + (b->vindex[vindex_offset_x+i] * row_size + word); change_msk |= *valpnt; change_msk |= *valpnt_x; } } else { for(i=0;ichange_dict + (b->vindex[vindex_offset+i] * row_size + word); change_msk |= *valpnt; } } } else { if(b->multi_state) { for(i=0;i=lt->numfacs) break; vindex_offset = lt->vindex_offset[facidx+i]; vindex_offset_x = vindex_offset + lt->total_values; valpnt = b->change_dict + (b->vindex[vindex_offset] * row_size + word); valpnt_x = b->change_dict + (b->vindex[vindex_offset_x] * row_size + word); change_msk |= *valpnt; change_msk |= *valpnt_x; } } else { for(i=0;i=lt->numfacs) break; vindex_offset = lt->vindex_offset[facidx+i]; valpnt = b->change_dict + (b->vindex[vindex_offset] * row_size + word); change_msk |= *valpnt; } } } change_msk >>= bit; if(change_msk) { return( (change_msk & 1 ? 0 : vzt_rd_tzc(change_msk)) + time_offset + bit ); } } time_offset += 32; bit = 0; } return(old_time_offset); } int vzt_rd_fac_value(struct vzt_rd_trace *lt, struct vzt_rd_block *b, vztint32_t time_offset, vztint32_t facidx, char *value) { vztint32_t len = lt->len[facidx]; unsigned int i; int word = time_offset / 32; int bit = time_offset & 31; int row_size = b->num_sections; vztint32_t *valpnt; vztint32_t *val_base; if((time_offset>b->num_time_ticks)||(facidx>lt->numrealfacs)) return(0); val_base = b->val_dict + word; if(!(lt->flags[facidx]&VZT_RD_SYM_F_SYNVEC)) { vztint32_t vindex_offset = lt->vindex_offset[facidx]; if(b->multi_state) { vztint32_t vindex_offset_x = vindex_offset + lt->total_values; vztint32_t *valpnt_x; int which; for(i=0;ivindex[vindex_offset++] * row_size); valpnt_x = val_base + (b->vindex[vindex_offset_x++] * row_size); which = (((*valpnt_x >> bit) & 1) << 1) | ((*valpnt >> bit) & 1); value[i] = "01xz"[which]; } } else { for(i=0;ivindex[vindex_offset++] * row_size); value[i] = '0' | ((*valpnt >> bit) & 1); } } } else { vztint32_t vindex_offset; if(b->multi_state) { vztint32_t vindex_offset_x; vztint32_t *valpnt_x; int which; for(i=0;i=lt->numfacs) break; vindex_offset = lt->vindex_offset[facidx+i]; vindex_offset_x = vindex_offset + lt->total_values; valpnt = val_base + (b->vindex[vindex_offset] * row_size); valpnt_x = val_base + (b->vindex[vindex_offset_x] * row_size); which = (((*valpnt_x >> bit) & 1) << 1) | ((*valpnt >> bit) & 1); value[i] = "01xz"[which]; } } else { for(i=0;i=lt->numfacs) break; vindex_offset = lt->vindex_offset[facidx+i]; valpnt = val_base + (b->vindex[vindex_offset] * row_size); value[i] = '0' | ((*valpnt >> bit) & 1); } } } value[i] = 0; return(1); } static void vzt_rd_double_xdr(char *pnt, char *buf) { int j; #if HAVE_RPC_XDR_H XDR x; #else const vztint32_t endian_matchword = 0x12345678; #endif double d; char xdrdata[8] = { 0,0,0,0,0,0,0,0 }; /* scan-build */ for(j=0;j<64;j++) { int byte = j/8; int bit = 7-(j&7); if(pnt[j]=='1') { xdrdata[byte] |= (1<value_current_sector, *pnt2=lt->value_previous_sector; char buf[32]; char *bufpnt; vzt_rd_block_vch_decode(lt, b); vzt_rd_pthread_mutex_lock(lt, &b->mutex); for(idx=0;idxnumrealfacs;idx++) { int process_idx = idx/8; int process_bit = idx&7; if(lt->process_mask[process_idx]&(1<prev)&&(!b->prev->exclude_block)) { vzt_rd_fac_value(lt, b->prev, b->prev->num_time_ticks - 1, idx, pnt2); /* get last val of prev sector */ if(strcmp(pnt, pnt2)) { goto do_vch; } } else { do_vch: if(!(lt->flags[idx] & (VZT_RD_SYM_F_DOUBLE|VZT_RD_SYM_F_STRING))) { lt->value_change_callback(<, &b->times[i], &idx, &pnt); } else { if(lt->flags[idx] & VZT_RD_SYM_F_DOUBLE) { bufpnt = buf; vzt_rd_double_xdr(pnt, buf); lt->value_change_callback(<, &b->times[i], &idx, &bufpnt); } else { unsigned int spnt=vzt_rd_make_sindex(pnt); char *msg = ((!i)&(!b->prev)) ? "UNDEF" : b->sindex[spnt]; lt->value_change_callback(<, &b->times[i], &idx, &msg); } } } i2 = vzt_rd_next_value_chg_time(lt, b, i, idx); if(i==i2) break; i=i2; } } } vzt_rd_pthread_mutex_unlock(lt, &b->mutex); return(1); } /* * most clients want this */ int vzt_rd_process_block(struct vzt_rd_trace *lt, struct vzt_rd_block *b) { unsigned int i, i2; vztint32_t idx; char *pnt=lt->value_current_sector, *pnt2=lt->value_previous_sector; char buf[32]; char *bufpnt; struct vzt_ncycle_autosort **autosort; struct vzt_ncycle_autosort *deadlist=NULL; struct vzt_ncycle_autosort *autofacs= calloc(lt->numrealfacs, sizeof(struct vzt_ncycle_autosort)); vzt_rd_block_vch_decode(lt, b); vzt_rd_pthread_mutex_lock(lt, &b->mutex); autosort = calloc(b->num_time_ticks, sizeof(struct vzt_ncycle_autosort *)); for(i=0;inum_time_ticks;i++) autosort[i]=NULL; deadlist=NULL; for(idx=0;idxnumrealfacs;idx++) { int process_idx = idx/8; int process_bit = idx&7; if(lt->process_mask[process_idx]&(1<prev)&&(!b->prev->exclude_block)) { vzt_rd_fac_value(lt, b->prev, b->prev->num_time_ticks - 1, idx, pnt2); /* get last val of prev sector */ if(strcmp(pnt, pnt2)) { goto do_vch_0; } } else { do_vch_0: if(!(lt->flags[idx] & (VZT_RD_SYM_F_DOUBLE|VZT_RD_SYM_F_STRING))) { lt->value_change_callback(<, &b->times[i], &idx, &pnt); } else { if(lt->flags[idx] & VZT_RD_SYM_F_DOUBLE) { bufpnt = buf; vzt_rd_double_xdr(pnt, buf); lt->value_change_callback(<, &b->times[i], &idx, &bufpnt); } else { unsigned int spnt=vzt_rd_make_sindex(pnt); char *msg = ((!i)&(!b->prev)) ? "UNDEF" : b->sindex[spnt]; lt->value_change_callback(<, &b->times[i], &idx, &msg); } } } i2 = vzt_rd_next_value_chg_time(lt, b, i, idx); if(i2) { struct vzt_ncycle_autosort *t = autosort[i2]; autofacs[idx].next = t; autosort[i2] = autofacs+idx; } else { struct vzt_ncycle_autosort *t = deadlist; autofacs[idx].next = t; deadlist = autofacs+idx; } } } for(i = 1; i < b->num_time_ticks; i++) { struct vzt_ncycle_autosort *t = autosort[i]; if(t) { while(t) { struct vzt_ncycle_autosort *tn = t->next; idx = t-autofacs; vzt_rd_fac_value(lt, b, i, idx, pnt); if(!(lt->flags[idx] & (VZT_RD_SYM_F_DOUBLE|VZT_RD_SYM_F_STRING))) { lt->value_change_callback(<, &b->times[i], &idx, &pnt); } else { if(lt->flags[idx] & VZT_RD_SYM_F_DOUBLE) { bufpnt = buf; vzt_rd_double_xdr(pnt, buf); lt->value_change_callback(<, &b->times[i], &idx, &bufpnt); } else { unsigned int spnt=vzt_rd_make_sindex(pnt); char *msg = ((!i)&(!b->prev)) ? "UNDEF" : b->sindex[spnt]; lt->value_change_callback(<, &b->times[i], &idx, &msg); } } i2 = vzt_rd_next_value_chg_time(lt, b, i, idx); if(i2!=i) { struct vzt_ncycle_autosort *ta = autosort[i2]; autofacs[idx].next = ta; autosort[i2] = autofacs+idx; } else { struct vzt_ncycle_autosort *ta = deadlist; autofacs[idx].next = ta; deadlist = autofacs+idx; } t = tn; } } } vzt_rd_pthread_mutex_unlock(lt, &b->mutex); free(autofacs); free(autosort); return(1); } /****************************************************************************/ /* * null callback used when a user passes NULL as an argument to vzt_rd_iter_blocks() */ void vzt_rd_null_callback(struct vzt_rd_trace **lt, vztint64_t *pnt_time, vztint32_t *pnt_facidx, char **pnt_value) { (void) lt; (void) pnt_time; (void) pnt_facidx; (void) pnt_value; /* fprintf(stderr, VZT_RDLOAD"%lld %d %s\n", *pnt_time, *pnt_facidx, *pnt_value); */ } /****************************************************************************/ /* * return number of facs in trace */ _VZT_RD_INLINE vztint32_t vzt_rd_get_num_facs(struct vzt_rd_trace *lt) { return(lt ? lt->numfacs : 0); } /* * return fac geometry for a given index */ struct vzt_rd_geometry *vzt_rd_get_fac_geometry(struct vzt_rd_trace *lt, vztint32_t facidx) { if((lt)&&(facidxnumfacs)) { lt->geometry.rows = lt->rows[facidx]; lt->geometry.msb = lt->msb[facidx]; lt->geometry.lsb = lt->lsb[facidx]; lt->geometry.flags = lt->flags[facidx]; lt->geometry.len = lt->len[facidx]; return(<->geometry); } else { return(NULL); } } /* * return partial fac geometry for a given index */ _VZT_RD_INLINE vztint32_t vzt_rd_get_fac_rows(struct vzt_rd_trace *lt, vztint32_t facidx) { if((lt)&&(facidxnumfacs)) { return(lt->rows[facidx]); } else { return(0); } } _VZT_RD_INLINE vztsint32_t vzt_rd_get_fac_msb(struct vzt_rd_trace *lt, vztint32_t facidx) { if((lt)&&(facidxnumfacs)) { return(lt->msb[facidx]); } else { return(0); } } _VZT_RD_INLINE vztsint32_t vzt_rd_get_fac_lsb(struct vzt_rd_trace *lt, vztint32_t facidx) { if((lt)&&(facidxnumfacs)) { return(lt->lsb[facidx]); } else { return(0); } } _VZT_RD_INLINE vztint32_t vzt_rd_get_fac_flags(struct vzt_rd_trace *lt, vztint32_t facidx) { if((lt)&&(facidxnumfacs)) { return(lt->flags[facidx]); } else { return(0); } } _VZT_RD_INLINE vztint32_t vzt_rd_get_fac_len(struct vzt_rd_trace *lt, vztint32_t facidx) { if((lt)&&(facidxnumfacs)) { return(lt->len[facidx]); } else { return(0); } } _VZT_RD_INLINE vztint32_t vzt_rd_get_alias_root(struct vzt_rd_trace *lt, vztint32_t facidx) { if((lt)&&(facidxnumfacs)) { while(lt->flags[facidx] & VZT_RD_SYM_F_ALIAS) { facidx = lt->rows[facidx]; /* iterate to next alias */ } return(facidx); } else { return(~((vztint32_t)0)); } } /* * time queries */ _VZT_RD_INLINE vztint64_t vzt_rd_get_start_time(struct vzt_rd_trace *lt) { return(lt ? lt->start : 0); } _VZT_RD_INLINE vztint64_t vzt_rd_get_end_time(struct vzt_rd_trace *lt) { return(lt ? lt->end : 0); } _VZT_RD_INLINE char vzt_rd_get_timescale(struct vzt_rd_trace *lt) { return(lt ? lt->timescale : 0); } _VZT_RD_INLINE vztsint64_t vzt_rd_get_timezero(struct vzt_rd_trace *lt) { return(lt ? lt->timezero : 0); } /* * extract facname from prefix-compressed table. this * performs best when extracting facs with monotonically * increasing indices... */ char *vzt_rd_get_facname(struct vzt_rd_trace *lt, vztint32_t facidx) { char *pnt; unsigned int clonecnt, j; if(lt) { if((facidx==(lt->faccache->old_facidx+1))||(!facidx)) { if(!facidx) { lt->faccache->n = lt->zfacnames; lt->faccache->bufcurr[0] = 0; lt->faccache->bufprev[0] = 0; } if(facidx!=lt->numfacs) { pnt = lt->faccache->bufcurr; lt->faccache->bufcurr = lt->faccache->bufprev; lt->faccache->bufprev = pnt; clonecnt=vzt_rd_get_16(lt->faccache->n, 0); lt->faccache->n+=2; pnt=lt->faccache->bufcurr; for(j=0;jfaccache->bufprev[j]; } while((*(pnt++)=vzt_rd_get_byte(lt->faccache->n++,0))); lt->faccache->old_facidx = facidx; return(lt->faccache->bufcurr); } else { return(NULL); /* no more left */ } } else { if(facidxnumfacs) { int strt; if(facidx==lt->faccache->old_facidx) { return(lt->faccache->bufcurr); } if(facidx>(lt->faccache->old_facidx+1)) { strt = lt->faccache->old_facidx+1; } else { strt=0; } for(j=strt;jnumfacs) { int process_idx = facidx/8; int process_bit = facidx&7; return( (lt->process_mask[process_idx]&(1<numfacs) { int idx = facidx/8; int bitpos = facidx&7; if(!(lt->flags[facidx]&VZT_RD_SYM_F_ALIAS)) { lt->process_mask[idx] |= (1<process_mask[idx] &= (~(1<numfacs) { int idx = facidx/8; int bitpos = facidx&7; lt->process_mask[idx] &= (~(1<process_mask, 0xff, (lt->numfacs+7)/8); rc=1; for(i=0;inumfacs;i++) { if((!lt->len[i])||(lt->flags[i]&VZT_RD_SYM_F_ALIAS)) vzt_rd_clr_fac_process_mask(lt, i); } } return(rc); } _VZT_RD_INLINE int vzt_rd_clr_fac_process_mask_all(struct vzt_rd_trace *lt) { int rc=0; if(lt) { memset(lt->process_mask, 0x00, (lt->numfacs+7)/8); rc=1; } return(rc); } /* * block memory set/get used to control buffering */ _VZT_RD_INLINE vztint64_t vzt_rd_set_max_block_mem_usage(struct vzt_rd_trace *lt, vztint64_t block_mem_max) { vztint64_t rc = lt->block_mem_max; lt->block_mem_max = block_mem_max; return(rc); } vztint64_t vzt_rd_get_block_mem_usage(struct vzt_rd_trace *lt) { vztint64_t mem; vzt_rd_pthread_mutex_lock(lt, <->mutex); mem = lt->block_mem_consumed; vzt_rd_pthread_mutex_unlock(lt, <->mutex); return(mem); } /* * return total number of blocks */ _VZT_RD_INLINE unsigned int vzt_rd_get_num_blocks(struct vzt_rd_trace *lt) { return(lt->numblocks); } /* * return number of active blocks */ unsigned int vzt_rd_get_num_active_blocks(struct vzt_rd_trace *lt) { int blk=0; if(lt) { struct vzt_rd_block *b = lt->block_head; while(b) { if((!b->short_read_ignore)&&(!b->exclude_block)) { blk++; } b=b->next; } } return(blk); } /****************************************************************************/ static int vzt_rd_det_gzip_type(FILE *handle) { unsigned char cbuf[2] = { 0, 0 }; off_t off = ftello(handle); if(!fread(cbuf, 1, 2, handle)) { cbuf[0] = cbuf[1] = 0; } fseeko(handle, off, SEEK_SET); if((cbuf[0] == 0x1f) && (cbuf[1] == 0x8b)) { return(VZT_RD_IS_GZ); } if((cbuf[0] == 'z') && (cbuf[1] == '7')) { return(VZT_RD_IS_LZMA); } return(VZT_RD_IS_BZ2); } /****************************************************************************/ static void vzt_rd_decompress_blk(struct vzt_rd_trace *lt, struct vzt_rd_block *b, int reopen) { unsigned int rc; void *zhandle; FILE *handle; if(reopen) { handle = fopen(lt->filename, "rb"); } else { handle = lt->handle; } fseeko(handle, b->filepos, SEEK_SET); vzt_rd_pthread_mutex_lock(lt, &b->mutex); if((!b->killed)&&(!b->mem)) { b->mem = malloc(b->uncompressed_siz); switch(b->ztype) { case VZT_RD_IS_GZ: zhandle = gzdopen(dup(fileno(handle)), "rb"); rc=gzread(zhandle, b->mem, b->uncompressed_siz); gzclose(zhandle); break; case VZT_RD_IS_BZ2: zhandle = BZ2_bzdopen(dup(fileno(handle)), "rb"); rc=BZ2_bzread(zhandle, b->mem, b->uncompressed_siz); BZ2_bzclose(zhandle); break; case VZT_RD_IS_LZMA: default: zhandle = LZMA_fdopen(dup(fileno(handle)), "rb"); rc=LZMA_read(zhandle, b->mem, b->uncompressed_siz); LZMA_close(zhandle); break; } if(rc!=b->uncompressed_siz) { fprintf(stderr, VZT_RDLOAD"short read on block %p %d vs "VZT_RD_LD" (exp), ignoring\n", (void *)b, rc, b->uncompressed_siz); free(b->mem); b->mem=NULL; b->short_read_ignore = 1; } else { vzt_rd_pthread_mutex_lock(lt, <->mutex); lt->block_mem_consumed += b->uncompressed_siz; vzt_rd_pthread_mutex_unlock(lt, <->mutex); } } vzt_rd_pthread_mutex_unlock(lt, &b->mutex); if(reopen) { fclose(handle); } } static void *vzt_rd_decompress_blk_pth_actual(void *args) { struct vzt_pth_args *vpa = (struct vzt_pth_args *)args; vzt_rd_decompress_blk(vpa->lt, vpa->b, 1); vzt_rd_block_vch_decode(vpa->lt, vpa->b); free(vpa); return(NULL); } static void vzt_rd_decompress_blk_pth(struct vzt_rd_trace *lt, struct vzt_rd_block *b) { struct vzt_pth_args *vpa = malloc(sizeof(struct vzt_pth_args)); vpa->lt = lt; vpa->b = b; vzt_rd_pthread_create(lt, &b->pth, &b->pth_attr, vzt_rd_decompress_blk_pth_actual, vpa); /* cppcheck misfires thinking vpa is not freed even though vzt_rd_decompress_blk_pth_actual() does it */ } /* * block iteration...purge/reload code here isn't sophisticated as it * merely caches the FIRST set of blocks which fit in lt->block_mem_max. * n.b., returns number of blocks processed */ int vzt_rd_iter_blocks(struct vzt_rd_trace *lt, void (*value_change_callback)(struct vzt_rd_trace **lt, vztint64_t *time, vztint32_t *facidx, char **value), void *user_callback_data_pointer) { struct vzt_rd_block *b, *bpre; int blk=0, blkfinal=0; int processed = 0; struct vzt_rd_block *bcutoff=NULL, *bfinal=NULL; if(lt) { lt->value_change_callback = value_change_callback ? value_change_callback : vzt_rd_null_callback; lt->user_callback_data_pointer = user_callback_data_pointer; b = lt->block_head; blk=0; while(b) { if((!b->mem)&&(!b->short_read_ignore)&&(!b->exclude_block)) { if(processed<5) { int gate = (processed==4) && b->next; fprintf(stderr, VZT_RDLOAD"block [%d] processing "VZT_RD_LLD" / "VZT_RD_LLD"%s\n", blk, b->start, b->end, gate ? " ..." : ""); if(gate) { bcutoff = b; } } processed++; if(lt->pthreads) { int count = lt->pthreads; /* prefetch next *empty* block(s) on an alternate thread */ bpre = b->next; while(bpre) { if((!bpre->mem)&&(!bpre->short_read_ignore)&&(!bpre->exclude_block)) { vzt_rd_decompress_blk_pth(lt, bpre); count--; if(!count) break; } bpre = bpre->next; } } vzt_rd_decompress_blk(lt, b, 0); bfinal=b; blkfinal = blk; } if(b->mem) { if(lt->process_linear) { vzt_rd_process_block_linear(lt, b); } else { vzt_rd_process_block(lt, b); } if(lt->numblocks > 2) /* no sense freeing up when not so many blocks */ { vztint64_t block_mem_consumed; vzt_rd_pthread_mutex_lock(lt, <->mutex); block_mem_consumed = lt->block_mem_consumed; vzt_rd_pthread_mutex_unlock(lt, <->mutex); if(block_mem_consumed > lt->block_mem_max) { if(b->prev) { vzt_rd_pthread_mutex_lock(lt, <->mutex); lt->block_mem_consumed -= b->prev->uncompressed_siz; vzt_rd_pthread_mutex_unlock(lt, <->mutex); vzt_rd_block_vch_free(lt, b->prev, 0); } } } } blk++; b=b->next; } } if((bcutoff)&&(bfinal!=bcutoff)) { fprintf(stderr, VZT_RDLOAD"block [%d] processed "VZT_RD_LLD" / "VZT_RD_LLD"\n", blkfinal, bfinal->start, bfinal->end); } return(blk); } /* * callback access to the user callback data pointer (if required) */ _VZT_RD_INLINE void *vzt_rd_get_user_callback_data_pointer(struct vzt_rd_trace *lt) { if(lt) { return(lt->user_callback_data_pointer); } else { return(NULL); } } /* * limit access to certain timerange in file * and return number of active blocks */ unsigned int vzt_rd_limit_time_range(struct vzt_rd_trace *lt, vztint64_t strt_time, vztint64_t end_time) { vztint64_t tmp_time; int blk=0; if(lt) { struct vzt_rd_block *b = lt->block_head; struct vzt_rd_block *bprev = NULL; int state = 0; if(strt_time > end_time) { tmp_time = strt_time; strt_time = end_time; end_time = tmp_time; } while(b) { switch(state) { case 0: if(b->end >= strt_time) { state = 1; if((b->start > strt_time) && (bprev)) { bprev->exclude_block = 0; blk++; } } break; case 1: if(b->start > end_time) state = 2; break; default: break; } if((state==1) && (!b->short_read_ignore)) { b->exclude_block = 0; blk++; } else { b->exclude_block = 1; } bprev = b; b = b->next; } } return(blk); } /* * unrestrict access to the whole file * and return number of active blocks */ unsigned int vzt_rd_unlimit_time_range(struct vzt_rd_trace *lt) { int blk=0; if(lt) { struct vzt_rd_block *b = lt->block_head; while(b) { b->exclude_block = 0; if(!b->short_read_ignore) { blk++; } b=b->next; } } return(blk); } /* * mode switch for linear accessing */ void vzt_rd_process_blocks_linearly(struct vzt_rd_trace *lt, int doit) { if(lt) { lt->process_linear = (doit != 0); } } /****************************************************************************/ /* * initialize the trace, get compressed facnames, get geometries, * and get block offset/size/timestart/timeend... */ struct vzt_rd_trace *vzt_rd_init_smp(const char *name, unsigned int num_cpus) { struct vzt_rd_trace *lt=(struct vzt_rd_trace *)calloc(1, sizeof(struct vzt_rd_trace)); unsigned int i; unsigned int vindex_offset; if(!(lt->handle=fopen(name, "rb"))) { vzt_rd_close(lt); lt=NULL; } else { vztint16_t id = 0, version = 0; lt->filename = strdup(name); lt->block_mem_max = VZT_RD_MAX_BLOCK_MEM_USAGE; /* cutoff after this number of bytes and force flush */ if(num_cpus<1) num_cpus = 1; if(num_cpus>8) num_cpus = 8; lt->pthreads = num_cpus - 1; setvbuf(lt->handle, (char *)NULL, _IONBF, 0); /* keeps gzip from acting weird in tandem with fopen */ if(!fread(&id, 2, 1, lt->handle)) { id = 0; } if(!fread(&version, 2, 1, lt->handle)) { id = 0; } if(!fread(<->granule_size, 1, 1, lt->handle)) { id = 0; } if(vzt_rd_get_16(&id,0) != VZT_RD_HDRID) { fprintf(stderr, VZT_RDLOAD"*** Not a vzt file ***\n"); vzt_rd_close(lt); lt=NULL; } else if((version=vzt_rd_get_16(&version,0)) > VZT_RD_VERSION) { fprintf(stderr, VZT_RDLOAD"*** Version %d vzt not supported ***\n", version); vzt_rd_close(lt); lt=NULL; } else if(lt->granule_size > VZT_RD_GRANULE_SIZE) { fprintf(stderr, VZT_RDLOAD"*** Granule size of %d (>%d) not supported ***\n", lt->granule_size, VZT_RD_GRANULE_SIZE); vzt_rd_close(lt); lt=NULL; } else { size_t rcf; unsigned int rc; char *m; off_t pos, fend; unsigned int t; struct vzt_rd_block *b; vzt_rd_pthread_mutex_init(lt, <->mutex, NULL); rcf = fread(<->numfacs, 4, 1, lt->handle); lt->numfacs = rcf ? vzt_rd_get_32(<->numfacs,0) : 0; if(!lt->numfacs) { vztint32_t num_expansion_bytes; rcf = fread(&num_expansion_bytes, 4, 1, lt->handle); num_expansion_bytes = rcf ? vzt_rd_get_32(&num_expansion_bytes,0) : 0; rcf = fread(<->numfacs, 4, 1, lt->handle); lt->numfacs = rcf ? vzt_rd_get_32(<->numfacs,0) : 0; if(num_expansion_bytes >= 8) { rcf = fread(<->timezero, 8, 1, lt->handle); lt->timezero = rcf ? vzt_rd_get_64(<->timezero,0) : 0; if(num_expansion_bytes > 8) { /* future version? */ fseeko(lt->handle, num_expansion_bytes - 8, SEEK_CUR); } } else { /* malformed */ fseeko(lt->handle, num_expansion_bytes, SEEK_CUR); } } rcf = fread(<->numfacbytes, 4, 1, lt->handle); lt->numfacbytes = rcf ? vzt_rd_get_32(<->numfacbytes,0) : 0; rcf = fread(<->longestname, 4, 1, lt->handle); lt->longestname = rcf ? vzt_rd_get_32(<->longestname,0) : 0; rcf = fread(<->zfacnamesize, 4, 1, lt->handle); lt->zfacnamesize = rcf ? vzt_rd_get_32(<->zfacnamesize,0) : 0; rcf = fread(<->zfacname_predec_size, 4, 1, lt->handle);lt->zfacname_predec_size = rcf ? vzt_rd_get_32(<->zfacname_predec_size,0) : 0; rcf = fread(<->zfacgeometrysize, 4, 1, lt->handle); lt->zfacgeometrysize = rcf ? vzt_rd_get_32(<->zfacgeometrysize,0) : 0; rcf = fread(<->timescale, 1, 1, lt->handle); if(!rcf) lt->timescale = 0; /* no swap necessary */ fprintf(stderr, VZT_RDLOAD VZT_RD_LD" facilities\n", lt->numfacs); pos = ftello(lt->handle); /* fprintf(stderr, VZT_RDLOAD"gzip facnames start at pos %d (zsize=%d)\n", pos, lt->zfacnamesize); */ lt->process_mask = calloc(1, lt->numfacs/8+1); switch(vzt_rd_det_gzip_type(lt->handle)) { case VZT_RD_IS_GZ: lt->zhandle = gzdopen(dup(fileno(lt->handle)), "rb"); m=(char *)malloc(lt->zfacname_predec_size); rc=gzread(lt->zhandle, m, lt->zfacname_predec_size); gzclose(lt->zhandle); lt->zhandle=NULL; break; case VZT_RD_IS_BZ2: lt->zhandle = BZ2_bzdopen(dup(fileno(lt->handle)), "rb"); m=(char *)malloc(lt->zfacname_predec_size); rc=BZ2_bzread(lt->zhandle, m, lt->zfacname_predec_size); BZ2_bzclose(lt->zhandle); lt->zhandle=NULL; break; case VZT_RD_IS_LZMA: default: lt->zhandle = LZMA_fdopen(dup(fileno(lt->handle)), "rb"); m=(char *)malloc(lt->zfacname_predec_size); rc=LZMA_read(lt->zhandle, m, lt->zfacname_predec_size); LZMA_close(lt->zhandle); lt->zhandle=NULL; break; } if(rc!=lt->zfacname_predec_size) { fprintf(stderr, VZT_RDLOAD"*** name section mangled %d (act) vs "VZT_RD_LD" (exp)\n", rc, lt->zfacname_predec_size); free(m); vzt_rd_close(lt); lt=NULL; return(lt); } lt->zfacnames = m; lt->faccache = calloc(1, sizeof(struct vzt_rd_facname_cache)); lt->faccache->old_facidx = lt->numfacs; /* causes vzt_rd_get_facname to initialize its unroll ptr as this is always invalid */ lt->faccache->bufcurr = malloc(lt->longestname+1); lt->faccache->bufprev = malloc(lt->longestname+1); fseeko(lt->handle, pos = pos+lt->zfacnamesize, SEEK_SET); /* fprintf(stderr, VZT_RDLOAD"seeking to geometry at %d (0x%08x)\n", pos, pos); */ switch(vzt_rd_det_gzip_type(lt->handle)) { case VZT_RD_IS_GZ: lt->zhandle = gzdopen(dup(fileno(lt->handle)), "rb"); t = lt->numfacs * 4 * sizeof(vztint32_t); m=(char *)malloc(t); rc=gzread(lt->zhandle, m, t); gzclose(lt->zhandle); lt->zhandle=NULL; break; case VZT_RD_IS_BZ2: lt->zhandle = BZ2_bzdopen(dup(fileno(lt->handle)), "rb"); t = lt->numfacs * 4 * sizeof(vztint32_t); m=(char *)malloc(t); rc=BZ2_bzread(lt->zhandle, m, t); BZ2_bzclose(lt->zhandle); lt->zhandle=NULL; break; case VZT_RD_IS_LZMA: default: lt->zhandle = LZMA_fdopen(dup(fileno(lt->handle)), "rb"); t = lt->numfacs * 4 * sizeof(vztint32_t); m=(char *)malloc(t); rc=LZMA_read(lt->zhandle, m, t); LZMA_close(lt->zhandle); lt->zhandle=NULL; break; } if(rc!=t) { fprintf(stderr, VZT_RDLOAD"*** geometry section mangled %d (act) vs %d (exp)\n", rc, t); free(m); vzt_rd_close(lt); lt=NULL; return(lt); } pos = pos+lt->zfacgeometrysize; lt->rows = malloc(lt->numfacs * sizeof(vztint32_t)); lt->msb = malloc(lt->numfacs * sizeof(vztsint32_t)); lt->lsb = malloc(lt->numfacs * sizeof(vztsint32_t)); lt->flags = malloc(lt->numfacs * sizeof(vztint32_t)); lt->len = malloc(lt->numfacs * sizeof(vztint32_t)); lt->vindex_offset = malloc(lt->numfacs * sizeof(vztint32_t)); lt->longest_len = 32; /* big enough for decoded double in vzt_rd_process_block_single_factime() */ for(i=0;inumfacs;i++) { int j; lt->rows[i] = vzt_rd_get_32(m+i*16, 0); lt->msb[i] = vzt_rd_get_32(m+i*16, 4); lt->lsb[i] = vzt_rd_get_32(m+i*16, 8); lt->flags[i] = vzt_rd_get_32(m+i*16, 12) & VZT_RD_SYM_MASK; /* strip out unsupported bits */ j = (!(lt->flags[i] & VZT_RD_SYM_F_ALIAS)) ? i : vzt_rd_get_alias_root(lt, i); if(!(lt->flags[i] & (VZT_RD_SYM_F_INTEGER|VZT_RD_SYM_F_STRING|VZT_RD_SYM_F_DOUBLE))) { lt->len[i] = (lt->msb[j] <= lt->lsb[j]) ? (lt->lsb[j] - lt->msb[j] + 1) : (lt->msb[j] - lt->lsb[j] + 1); } else { lt->len[i] = (lt->flags[j] & (VZT_RD_SYM_F_INTEGER|VZT_RD_SYM_F_STRING)) ? 32 : 64; } if(lt->len[i] > lt->longest_len) { lt->longest_len = lt->len[i]; } } vindex_offset = 0; /* offset in value table */ for(lt->numrealfacs=0; lt->numrealfacsnumfacs; lt->numrealfacs++) { if(lt->flags[lt->numrealfacs] & VZT_RD_SYM_F_ALIAS) { break; } lt->vindex_offset[lt->numrealfacs] = vindex_offset; vindex_offset += lt->len[lt->numrealfacs]; } lt->total_values = vindex_offset; fprintf(stderr, VZT_RDLOAD"Total value bits: "VZT_RD_LD"\n", lt->total_values); if(lt->numrealfacs > lt->numfacs) lt->numrealfacs = lt->numfacs; lt->value_current_sector = malloc(lt->longest_len + 1); lt->value_previous_sector = malloc(lt->longest_len + 1); free(m); for(;;) { fseeko(lt->handle, 0L, SEEK_END); fend=ftello(lt->handle); if(pos>=fend) break; fseeko(lt->handle, pos, SEEK_SET); /* fprintf(stderr, VZT_RDLOAD"seeking to block at %d (0x%08x)\n", pos, pos); */ b=calloc(1, sizeof(struct vzt_rd_block)); b->last_rd_value_idx = ~0; rcf = fread(&b->uncompressed_siz, 4, 1, lt->handle); b->uncompressed_siz = rcf ? vzt_rd_get_32(&b->uncompressed_siz,0) : 0; rcf = fread(&b->compressed_siz, 4, 1, lt->handle); b->compressed_siz = rcf ? vzt_rd_get_32(&b->compressed_siz,0) : 0; rcf = fread(&b->start, 8, 1, lt->handle); b->start = rcf ? vzt_rd_get_64(&b->start,0) : 0; rcf = fread(&b->end, 8, 1, lt->handle); b->end = rcf ? vzt_rd_get_64(&b->end,0) : 0; pos = ftello(lt->handle); if((b->rle = (b->start > b->end))) { vztint64_t tb = b->start; b->start = b->end; b->end = tb; } b->ztype = vzt_rd_det_gzip_type(lt->handle); /* fprintf(stderr, VZT_RDLOAD"block gzip start at pos %d (0x%08x)\n", pos, pos); */ if(pos>=fend) { free(b); break; } b->filepos = pos; /* mark startpos for later in case we purge it from memory */ /* fprintf(stderr, VZT_RDLOAD"un/compressed size: %d/%d\n", b->uncompressed_siz, b->compressed_siz); */ if((b->uncompressed_siz)&&(b->compressed_siz)&&(b->end)) { /* fprintf(stderr, VZT_RDLOAD"block [%d] %lld / %lld\n", lt->numblocks, b->start, b->end); */ fseeko(lt->handle, b->compressed_siz, SEEK_CUR); lt->numblocks++; if(lt->numblocks <= lt->pthreads) { vzt_rd_pthread_mutex_init(lt, &b->mutex, NULL); vzt_rd_decompress_blk_pth(lt, b); /* prefetch first block */ } if(lt->block_curr) { b->prev = lt->block_curr; lt->block_curr->next = b; lt->block_curr = b; lt->end = b->end; } else { lt->block_head = lt->block_curr = b; lt->start = b->start; lt->end = b->end; } } else { free(b); break; } pos+=b->compressed_siz; } if(lt->numblocks) { fprintf(stderr, VZT_RDLOAD"Read %d block header%s OK\n", lt->numblocks, (lt->numblocks!=1) ? "s" : ""); fprintf(stderr, VZT_RDLOAD"["VZT_RD_LLD"] start time\n", lt->start); fprintf(stderr, VZT_RDLOAD"["VZT_RD_LLD"] end time\n", lt->end); fprintf(stderr, VZT_RDLOAD"\n"); lt->value_change_callback = vzt_rd_null_callback; } else { vzt_rd_close(lt); lt=NULL; } } } return(lt); } /* * experimental, only really useful for vztminer right now... */ void vzt_rd_vectorize(struct vzt_rd_trace *lt) { if((!lt)||(lt->vectorize)||(lt->numfacs<2)) { return; } else { unsigned int old_longest_len = lt->longest_len; int pmxlen = 31; char *pbuff = malloc(pmxlen+1); char *pname; int plen, plen2; unsigned int i; int pidx; int num_after_combine = lt->numfacs; int num_synvecs = 0; int num_synalias = 0; struct vzt_synvec_chain **synvec_chain = calloc(lt->numfacs, sizeof(struct vzt_synvec_chain *)); for(i=0;inumfacs-1;i++) { unsigned int j; if(lt->len[i] != 1) continue; pname = vzt_rd_get_facname(lt, i); plen = strlen(pname); if(plen > pmxlen) { free(pbuff); pbuff = malloc(plen+1); } memcpy(pbuff, pname, plen); pbuff[plen] = 0; pidx = lt->msb[i]; for(j=i+1;jnumfacs-1;j++) { pname = vzt_rd_get_facname(lt, j); plen2 = strlen(pname); if((plen != plen2) || (strcmp(pbuff, pname)) || (lt->len[j] != 1) || ((pidx != lt->msb[j]-1) && (pidx != lt->msb[j]+1))) { i = j-1; break; } pidx = lt->msb[j]; lt->len[i] += lt->len[j]; lt->lsb[i] = lt->lsb[j]; lt->len[j] = 0; num_after_combine--; if(lt->len[i] > lt->longest_len) { lt->longest_len = lt->len[i]; } } } free(pbuff); /* scan-build */ for(i=lt->numrealfacs;inumfacs;i++) { if(lt->flags[i] & VZT_RD_SYM_F_ALIAS) /* not necessary, only for sanity */ { unsigned int j = vzt_rd_get_alias_root(lt, i); unsigned int k, l; if(lt->len[i]) { if((lt->len[i]==1) && (lt->len[j]==1)) { /* nothing to do, single bit alias */ continue; } if(lt->len[i]==lt->len[j]) { unsigned int nfm1 = lt->numfacs-1; if((i != nfm1) && (j != nfm1)) { if(lt->len[i+1] && lt->len[j+1]) { /* nothing to do, multi-bit alias */ continue; } } } if(1) /* seems like this doesn't need to be conditional (for now) */ { lt->vindex_offset[i] = lt->vindex_offset[j]; for(k=1;klen[i];k++) { if((k+i) <= (lt->numfacs-1)) { lt->vindex_offset[k+i] = lt->vindex_offset[vzt_rd_get_alias_root(lt, k+i)]; } } if(synvec_chain[j]) { int alias_found = 0; for(k=0;knum_entries;k++) { vztint32_t idx = synvec_chain[j]->chain[k]; if(lt->len[i] == lt->len[idx]) { for(l=0;llen[i];l++) { if((idx+l)<=(lt->numfacs-1)) { if(lt->vindex_offset[idx+l] != lt->vindex_offset[i+l]) break; } } if(l == (lt->len[i])) { lt->rows[i] = idx; /* already exists */ num_synalias++; alias_found = 1; break; } } } if(!alias_found) { synvec_chain[j] = realloc(synvec_chain[j], sizeof(struct vzt_synvec_chain) + synvec_chain[j]->num_entries * sizeof(vztint32_t)); synvec_chain[j]->chain[synvec_chain[j]->num_entries++] = i; lt->flags[i] |= VZT_RD_SYM_F_SYNVEC; lt->flags[i] &= ~VZT_RD_SYM_F_ALIAS; lt->numrealfacs = i+1; /* bump up to end */ num_synvecs++; } } else { synvec_chain[j] = malloc(sizeof(struct vzt_synvec_chain)); if(synvec_chain[j]) /* scan-build : deref of null pointer below */ { synvec_chain[j]->num_entries = 1; synvec_chain[j]->chain[0] = i; } lt->flags[i] |= VZT_RD_SYM_F_SYNVEC; lt->flags[i] &= ~VZT_RD_SYM_F_ALIAS; lt->numrealfacs = i+1; /* bump up to end */ num_synvecs++; } } } } } for(i=0;inumfacs;i++) { if(synvec_chain[i]) free(synvec_chain[i]); } free(synvec_chain); fprintf(stderr, VZT_RDLOAD"%d facilities (after vectorization)\n", num_after_combine); if(num_synvecs) { fprintf(stderr, VZT_RDLOAD"%d complex vectors synthesized\n", num_synvecs); if(num_synalias) fprintf(stderr, VZT_RDLOAD"%d complex aliases synthesized\n", num_synalias); } fprintf(stderr, VZT_RDLOAD"\n"); if(lt->longest_len != old_longest_len) { free(lt->value_current_sector); free(lt->value_previous_sector); lt->value_current_sector = malloc(lt->longest_len + 1); lt->value_previous_sector = malloc(lt->longest_len + 1); } } } struct vzt_rd_trace *vzt_rd_init(const char *name) { return(vzt_rd_init_smp(name, 1)); } /* * free up/deallocate any resources still left out there: * blindly do it based on NULL pointer comparisons (ok, since * calloc() is used to allocate all structs) as performance * isn't an issue for this set of cleanup code */ void vzt_rd_close(struct vzt_rd_trace *lt) { if(lt) { struct vzt_rd_block *b, *bt; if(lt->process_mask) { free(lt->process_mask); lt->process_mask=NULL; } if(lt->rows) { free(lt->rows); lt->rows=NULL; } if(lt->msb) { free(lt->msb); lt->msb=NULL; } if(lt->lsb) { free(lt->lsb); lt->lsb=NULL; } if(lt->flags) { free(lt->flags); lt->flags=NULL; } if(lt->len) { free(lt->len); lt->len=NULL; } if(lt->vindex_offset) { free(lt->vindex_offset); lt->vindex_offset=NULL; } if(lt->zfacnames) { free(lt->zfacnames); lt->zfacnames=NULL; } if(lt->value_current_sector) { free(lt->value_current_sector); lt->value_current_sector=NULL; } if(lt->value_previous_sector) { free(lt->value_previous_sector); lt->value_previous_sector=NULL; } if(lt->faccache) { if(lt->faccache->bufprev) { free(lt->faccache->bufprev); lt->faccache->bufprev=NULL; } if(lt->faccache->bufcurr) { free(lt->faccache->bufcurr); lt->faccache->bufcurr=NULL; } free(lt->faccache); lt->faccache=NULL; } b=lt->block_head; while(b) { bt=b->next; vzt_rd_block_vch_free(lt, b, 1); vzt_rd_pthread_mutex_destroy(lt, &b->mutex); free(b); b=bt; } lt->block_head=lt->block_curr=NULL; if(lt->zhandle) { gzclose(lt->zhandle); lt->zhandle=NULL; } if(lt->handle) { fclose(lt->handle); lt->handle=NULL; } if(lt->filename) { free(lt->filename); lt->filename=NULL; } vzt_rd_pthread_mutex_destroy(lt, <->mutex); free(lt); } } /*******************************************/ /* * read single fac value at a given time */ static char *vzt_rd_process_block_single_factime(struct vzt_rd_trace *lt, struct vzt_rd_block *b, vztint64_t simtime, vztint32_t idx) { unsigned int i; char *pnt=lt->value_current_sector; /* convenient workspace mem */ char *buf = lt->value_previous_sector; /* convenient workspace mem */ char *rcval = NULL; vzt_rd_block_vch_decode(lt, b); vzt_rd_pthread_mutex_lock(lt, &b->mutex); if((b->last_rd_value_simtime == simtime) && (b->last_rd_value_idx != ((vztint32_t)~0))) { i = b->last_rd_value_idx; } else { int i_ok = 0; for(i=0;inum_time_ticks;i++) /* for(i=b->num_time_ticks-1; i>=0; i--) */ { if(simtime == b->times[i]) { i_ok = i; break; } if(simtime < b->times[i]) break; i_ok = i; /* replace with maximal bsearch if this caching doesn't work out */ } b->last_rd_value_idx = i_ok; b->last_rd_value_simtime = simtime; } vzt_rd_fac_value(lt, b, i, idx, pnt); if(!(lt->flags[idx] & (VZT_RD_SYM_F_DOUBLE|VZT_RD_SYM_F_STRING))) { rcval = pnt; } else { if(lt->flags[idx] & VZT_RD_SYM_F_DOUBLE) { vzt_rd_double_xdr(pnt, buf); rcval = buf; } else { unsigned int spnt=vzt_rd_make_sindex(pnt); rcval = b->sindex[spnt]; } } vzt_rd_pthread_mutex_unlock(lt, &b->mutex); return(rcval); } char *vzt_rd_value(struct vzt_rd_trace *lt, vztint64_t simtime, vztint32_t idx) { struct vzt_rd_block *b, *b2; char *rcval = NULL; if(lt) { b = lt->block_head; if((simtime == lt->last_rd_value_simtime) && (lt->last_rd_value_block)) { b = lt->last_rd_value_block; goto b_chk; } else { lt->last_rd_value_simtime = simtime; } while(b) { if((b->start > simtime) || (b->end < simtime)) { b = b->next; continue; } lt->last_rd_value_block = b; b_chk: if((!b->mem)&&(!b->short_read_ignore)) { vzt_rd_decompress_blk(lt, b, 0); } if(b->mem) { rcval = vzt_rd_process_block_single_factime(lt, b, simtime, idx); break; } b=b->next; } } else { return(NULL); } if((b)&&(lt->numblocks > 2)) /* no sense freeing up when not so many blocks */ { vztint64_t block_mem_consumed; vzt_rd_pthread_mutex_lock(lt, <->mutex); block_mem_consumed = lt->block_mem_consumed; vzt_rd_pthread_mutex_unlock(lt, <->mutex); if(block_mem_consumed > lt->block_mem_max) { b2 = lt->block_head; while(b2) { if((block_mem_consumed > lt->block_mem_max) && (b2 != b)) { vzt_rd_pthread_mutex_lock(lt, <->mutex); lt->block_mem_consumed -= b2->uncompressed_siz; vzt_rd_pthread_mutex_unlock(lt, <->mutex); vzt_rd_block_vch_free(lt, b2, 0); } b2 = b2->next; } } } return(rcval); } gtkwave-3.3.66/src/helpers/lxt2_read.c0000664000076400007640000012601212357342523017070 0ustar bybellbybell/* * Copyright (c) 2003-2014 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include "lxt2_read.h" /****************************************************************************/ #ifdef _WAVE_BE32 /* * reconstruct 8/16/24/32 bits out of the lxt's representation * of a big-endian integer. this is for 32-bit PPC so no byte * swizzling needs to be done at all. for 24-bit ints, we have no danger of * running off the end of memory provided we do the "-1" trick * since we'll never read a 24-bit int at the very start of a file which * means that we'll have a 32-bit word that we can read. */ #define lxt2_rd_get_byte(mm,offset) ((unsigned int)(*((unsigned char *)(mm)+(offset)))) #define lxt2_rd_get_16(mm,offset) ((unsigned int)(*((unsigned short *)(((unsigned char *)(mm))+(offset))))) #define lxt2_rd_get_32(mm,offset) (*(unsigned int *)(((unsigned char *)(mm))+(offset))) #define lxt2_rd_get_24(mm,offset) ((lxt2_rd_get_32((mm),(offset)-1)<<8)>>8) #define lxt2_rd_get_64(mm,offset) ((((lxtint64_t)lxt2_rd_get_32((mm),(offset)))<<32)|((lxtint64_t)lxt2_rd_get_32((mm),(offset)+4))) #else /* * reconstruct 8/16/24/32 bits out of the lxt's representation * of a big-endian integer. this should work on all architectures. */ #define lxt2_rd_get_byte(mm,offset) ((unsigned int)(*((unsigned char *)(mm)+(offset)))) static unsigned int lxt2_rd_get_16(void *mm, int offset) { unsigned char *nn=(unsigned char *)mm+offset; unsigned int m1=*((unsigned char *)(nn++)); unsigned int m2=*((unsigned char *)nn); return((m1<<8)|m2); } static unsigned int lxt2_rd_get_24(void *mm,int offset) { unsigned char *nn=(unsigned char *)mm+offset; unsigned int m1=*((unsigned char *)(nn++)); unsigned int m2=*((unsigned char *)(nn++)); unsigned int m3=*((unsigned char *)nn); return((m1<<16)|(m2<<8)|m3); } static unsigned int lxt2_rd_get_32(void *mm, int offset) { unsigned char *nn=(unsigned char *)mm+offset; unsigned int m1=*((unsigned char *)(nn++)); unsigned int m2=*((unsigned char *)(nn++)); unsigned int m3=*((unsigned char *)(nn++)); unsigned int m4=*((unsigned char *)nn); return((m1<<24)|(m2<<16)|(m3<<8)|m4); } static lxtint64_t lxt2_rd_get_64(void *mm, int offset) { return( (((lxtint64_t)lxt2_rd_get_32(mm,offset))<<32) |((lxtint64_t)lxt2_rd_get_32(mm,offset+4)) ); } #endif /****************************************************************************/ /* * fast SWAR ones count for 32 and 64 bits */ #if LXT2_RD_GRANULE_SIZE > 32 _LXT2_RD_INLINE granmsk_t lxt2_rd_ones_cnt(granmsk_t x) { x -= ((x >> 1) & LXT2_RD_ULLDESC(0x5555555555555555)); x = (((x >> 2) & LXT2_RD_ULLDESC(0x3333333333333333)) + (x & LXT2_RD_ULLDESC(0x3333333333333333))); x = (((x >> 4) + x) & LXT2_RD_ULLDESC(0x0f0f0f0f0f0f0f0f)); return((x * LXT2_RD_ULLDESC(0x0101010101010101)) >> 56); } #else _LXT2_RD_INLINE granmsk_t lxt2_rd_ones_cnt(granmsk_t x) { x -= ((x >> 1) & 0x55555555); x = (((x >> 2) & 0x33333333) + (x & 0x33333333)); x = (((x >> 4) + x) & 0x0f0f0f0f); return((x * 0x01010101) >> 24); } #endif /* * total zero count to the right of the first rightmost one bit * encountered. its intended use is to * "return the bitposition of the least significant 1 in a granmsk_t" * (use x &= ~(x&-x) to clear out that bit quickly) */ _LXT2_RD_INLINE granmsk_t lxt2_rd_tzc(granmsk_t x) { return (lxt2_rd_ones_cnt((x & -x) - LXT2_RD_GRAN_1VAL)); } /****************************************************************************/ /* * i2c and c2i utility functions */ static char *lxt2_rd_expand_integer_to_bits(int len, unsigned int value) { static char s[33]; char *p = s; int i; int len2 = len-1; for(i=0;inum_time_table_entries; which_time++, msk <<= 1) while((top_elem = lt->radix_sort[which_time])) { lxtint32_t idx = top_elem - lt->next_radix; unsigned int vch; lxtint32_t i; switch(lt->fac_curpos_width) { case 1: vch = lxt2_rd_get_byte(lt->fac_curpos[idx], 0); break; case 2: vch = lxt2_rd_get_16(lt->fac_curpos[idx], 0); break; case 3: vch = lxt2_rd_get_24(lt->fac_curpos[idx], 0); break; case 4: default: vch = lxt2_rd_get_32(lt->fac_curpos[idx], 0); break; } lt->fac_curpos[idx] += lt->fac_curpos_width; offset = lxt2_rd_tzc(lt->fac_map[idx] &= msk); /* offset = next "which time" for this fac */ lt->radix_sort[which_time] = lt->next_radix[idx]; /* get next list item for this "which time" bucket */ lt->next_radix[idx] = lt->radix_sort[offset]; /* promote fac to its next (higher) possible bucket (if any) */ lt->radix_sort[offset] = <->next_radix[idx]; /* ...and put it at the head of that list */ switch(vch) { case LXT2_RD_ENC_0: case LXT2_RD_ENC_1: memset(lt->value[idx], '0'+(vch-LXT2_RD_ENC_0), lt->len[idx]); break; case LXT2_RD_ENC_INV: for(i=0;ilen[idx];i++) { lt->value[idx][i] ^= 1; } break; case LXT2_RD_ENC_LSH0: case LXT2_RD_ENC_LSH1: memmove(lt->value[idx], lt->value[idx]+1, lt->len[idx]-1); lt->value[idx][lt->len[idx]-1] = '0'+(vch-LXT2_RD_ENC_LSH0); break; case LXT2_RD_ENC_RSH0: case LXT2_RD_ENC_RSH1: memmove(lt->value[idx]+1, lt->value[idx], lt->len[idx]-1); lt->value[idx][0] = '0'+(vch-LXT2_RD_ENC_RSH0); break; case LXT2_RD_ENC_ADD1: case LXT2_RD_ENC_ADD2: case LXT2_RD_ENC_ADD3: case LXT2_RD_ENC_ADD4: x=lxt2_rd_expand_bits_to_integer(lt->len[idx], lt->value[idx]); x+= (vch-LXT2_RD_ENC_ADD1+1); memcpy(lt->value[idx], lxt2_rd_expand_integer_to_bits(lt->len[idx], x), lt->len[idx]); break; case LXT2_RD_ENC_SUB1: case LXT2_RD_ENC_SUB2: case LXT2_RD_ENC_SUB3: case LXT2_RD_ENC_SUB4: x=lxt2_rd_expand_bits_to_integer(lt->len[idx], lt->value[idx]); x-= (vch-LXT2_RD_ENC_SUB1+1); memcpy(lt->value[idx], lxt2_rd_expand_integer_to_bits(lt->len[idx], x), lt->len[idx]); break; case LXT2_RD_ENC_X: memset(lt->value[idx], 'x', lt->len[idx]); break; case LXT2_RD_ENC_Z: memset(lt->value[idx], 'z', lt->len[idx]); break; case LXT2_RD_ENC_BLACKOUT: lt->value[idx][0] = 0; break; default: vch -= LXT2_RD_DICT_START; if(vch >= b->num_dict_entries) { fprintf(stderr, LXT2_RDLOAD"Internal error: vch(%d) >= num_dict_entries("LXT2_RD_LD")\n", vch, b->num_dict_entries); exit(255); } if(lt->flags[idx] & (LXT2_RD_SYM_F_DOUBLE|LXT2_RD_SYM_F_STRING)) { /* fprintf(stderr, LXT2_RDLOAD"DOUBLE: %s\n", b->string_pointers[vch]); */ free(lt->value[idx]); lt->value[idx] = strdup(b->string_pointers[vch]); break; } if(lt->len[idx] == b->string_lens[vch]) { memcpy(lt->value[idx], b->string_pointers[vch], lt->len[idx]); } else if(lt->len[idx] > b->string_lens[vch]) { int lendelta = lt->len[idx] - b->string_lens[vch]; memset(lt->value[idx], (b->string_pointers[vch][0]!='1') ? b->string_pointers[vch][0] : '0', lendelta); strcpy(lt->value[idx]+lendelta, b->string_pointers[vch]); } else { fprintf(stderr, LXT2_RDLOAD"Internal error "LXT2_RD_LD" ('%s') vs %d ('%s')\n", lt->len[idx], lt->value[idx], b->string_lens[vch], b->string_pointers[vch]); exit(255); } break; } /* this string is _always_ unique */ /* fprintf(stderr, LXT2_RDLOAD"%lld : [%d] '%s'\n", lt->time_table[which_time], idx, lt->value[idx]); */ if(lt->time_table[which_time] != lt->prev_time) { lt->prev_time = lt->time_table[which_time]; } lt->value_change_callback(<, <->time_table[which_time], &idx, <->value[idx]); } } /* * called for only 1st vch in a block: blocks out emission of duplicate * vch from preceeding block */ void lxt2_rd_iter_radix0(struct lxt2_rd_trace *lt, struct lxt2_rd_block *b, lxtint32_t idx) { unsigned int vch; unsigned int which_time; lxtint32_t i; int uniq = 0; switch(lt->fac_curpos_width) { case 1: vch = lxt2_rd_get_byte(lt->fac_curpos[idx], 0); break; case 2: vch = lxt2_rd_get_16(lt->fac_curpos[idx], 0); break; case 3: vch = lxt2_rd_get_24(lt->fac_curpos[idx], 0); break; case 4: default: vch = lxt2_rd_get_32(lt->fac_curpos[idx], 0); break; } lt->fac_curpos[idx] += lt->fac_curpos_width; which_time = 0; switch(vch) { case LXT2_RD_ENC_0: for(i=0;ilen[idx];i++) { if(lt->value[idx][i]!='0') { memset(lt->value[idx]+i, '0', lt->len[idx] - i); uniq = 1; break; } } break; case LXT2_RD_ENC_1: for(i=0;ilen[idx];i++) { if(lt->value[idx][i]!='1') { memset(lt->value[idx]+i, '1', lt->len[idx] - i); uniq = 1; break; } } break; case LXT2_RD_ENC_INV: case LXT2_RD_ENC_LSH0: case LXT2_RD_ENC_LSH1: case LXT2_RD_ENC_RSH0: case LXT2_RD_ENC_RSH1: case LXT2_RD_ENC_ADD1: case LXT2_RD_ENC_ADD2: case LXT2_RD_ENC_ADD3: case LXT2_RD_ENC_ADD4: case LXT2_RD_ENC_SUB1: case LXT2_RD_ENC_SUB2: case LXT2_RD_ENC_SUB3: case LXT2_RD_ENC_SUB4: fprintf(stderr, LXT2_RDLOAD"Internal error in granule 0 position 0\n"); exit(255); case LXT2_RD_ENC_X: for(i=0;ilen[idx];i++) { if(lt->value[idx][i]!='x') { memset(lt->value[idx]+i, 'x', lt->len[idx] - i); uniq = 1; break; } } break; case LXT2_RD_ENC_Z: for(i=0;ilen[idx];i++) { if(lt->value[idx][i]!='z') { memset(lt->value[idx]+i, 'z', lt->len[idx] - i); uniq = 1; break; } } break; case LXT2_RD_ENC_BLACKOUT: if(lt->value[idx]) { lt->value[idx][0] = 0; uniq=1; } break; default: vch -= LXT2_RD_DICT_START; if(vch >= b->num_dict_entries) { fprintf(stderr, LXT2_RDLOAD"Internal error: vch(%d) >= num_dict_entries("LXT2_RD_LD")\n", vch, b->num_dict_entries); exit(255); } if(lt->flags[idx] & (LXT2_RD_SYM_F_DOUBLE|LXT2_RD_SYM_F_STRING)) { /* fprintf(stderr, LXT2_RDLOAD"DOUBLE: %s\n", b->string_pointers[vch]); */ if(strcmp(lt->value[idx], b->string_pointers[vch])) { free(lt->value[idx]); lt->value[idx] = strdup(b->string_pointers[vch]); uniq = 1; } break; } if(lt->len[idx] == b->string_lens[vch]) { for(i=0;ilen[idx];i++) { if(lt->value[idx][i] != b->string_pointers[vch][i]) { memcpy(lt->value[idx]+i, b->string_pointers[vch]+i, lt->len[idx]-i); uniq = 1; } } } else if(lt->len[idx] > b->string_lens[vch]) { lxtint32_t lendelta = lt->len[idx] - b->string_lens[vch]; int fill = (b->string_pointers[vch][0]!='1') ? b->string_pointers[vch][0] : '0'; for(i=0;ivalue[idx][i] != fill) { memset(lt->value[idx] + i, fill, lendelta - i); strcpy(lt->value[idx]+lendelta, b->string_pointers[vch]); uniq = 1; goto fini; } } for(i=lendelta;ilen[idx];i++) { if(lt->value[idx][i] != b->string_pointers[vch][i-lendelta]) { memcpy(lt->value[idx]+i, b->string_pointers[vch]+i-lendelta, lt->len[idx]-i); uniq = 1; } } } else { fprintf(stderr, LXT2_RDLOAD"Internal error "LXT2_RD_LD" ('%s') vs %d ('%s')\n", lt->len[idx], lt->value[idx], b->string_lens[vch], b->string_pointers[vch]); exit(255); } break; } /* this string is unique if uniq != 0 */ /* fprintf(stderr, LXT2_RDLOAD"%lld : [%d] '%s'\n", lt->time_table[which_time], idx, lt->value[idx]); */ fini: if(uniq) { if(lt->time_table[which_time] != lt->prev_time) { lt->prev_time = lt->time_table[which_time]; } lt->value_change_callback(<, <->time_table[which_time], &idx, <->value[idx]); } } /* * radix sort the fac entries based upon their first entry in the * time change table. this runs in strict linear time: we can * do this because of the limited domain of the dataset. */ static void lxt2_rd_build_radix(struct lxt2_rd_trace *lt, struct lxt2_rd_block *b, int granule, lxtint32_t strtfac, lxtint32_t endfac) { lxtint32_t i; int offset; for(i=0;iradix_sort[i] = NULL; /* each one is a linked list: we get fac number based on address of item from lt->next_radix */ } for(i=strtfac;iprocess_mask[process_idx]&(1<fac_map[i])) { if((!granule)&&(x&LXT2_RD_GRAN_1VAL)) { lxt2_rd_iter_radix0(lt, b, i); /* emit vcd only if it's unique */ x&=(~LXT2_RD_GRAN_1VAL); /* clear out least sig bit */ lt->fac_map[i] = x; if(!x) continue; } offset = lxt2_rd_tzc(x); /* get "which time" bucket number of new least sig one bit */ lt->next_radix[i] = lt->radix_sort[offset]; /* insert item into head of radix sorted "which time" buckets */ lt->radix_sort[offset] = <->next_radix[i]; } } } } /****************************************************************************/ /* * build compressed process mask if necessary */ static void lxt2_rd_regenerate_process_mask(struct lxt2_rd_trace *lt) { lxtint32_t i; int j, lim, idx; if((lt)&&(lt->process_mask_dirty)) { lt->process_mask_dirty = 0; idx=0; for(i=0;inumrealfacs;i+=LXT2_RD_PARTIAL_SIZE) { if(i+LXT2_RD_PARTIAL_SIZE>lt->numrealfacs) { lim = lt->numrealfacs; } else { lim = i+LXT2_RD_PARTIAL_SIZE; } lt->process_mask_compressed[idx] = 0; for(j=i;jprocess_mask[process_idx]&(1<process_mask_compressed[idx] = 1; break; } } idx++; } } } /****************************************************************************/ /* * process a single block and execute the vch callback as necessary */ int lxt2_rd_process_block(struct lxt2_rd_trace *lt, struct lxt2_rd_block *b) { char vld; char *pnt; lxtint32_t i; int granule = 0; char sect_typ; lxtint32_t strtfac_gran=0; char granvld=0; b->num_map_entries = lxt2_rd_get_32(b->mem, b->uncompressed_siz - 4); b->num_dict_entries = lxt2_rd_get_32(b->mem, b->uncompressed_siz - 12); #if LXT2_RD_GRANULE_SIZE > 32 if(lt->granule_size==LXT2_RD_GRANULE_SIZE) { b->map_start = (b->mem + b->uncompressed_siz - 12) - sizeof(granmsk_t) * b->num_map_entries; } else { b->map_start = (b->mem + b->uncompressed_siz - 12) - sizeof(granmsk_smaller_t) * b->num_map_entries; } #else b->map_start = (b->mem + b->uncompressed_siz - 12) - sizeof(granmsk_t) * b->num_map_entries; #endif b->dict_start = b->map_start - lxt2_rd_get_32(b->mem, b->uncompressed_siz - 8); /* fprintf(stderr, LXT2_RDLOAD"num_map_entries: %d, num_dict_entries: %d, map_start: %08x, dict_start: %08x, mem: %08x end: %08x\n", b->num_map_entries, b->num_dict_entries, b->map_start, b->dict_start, b->mem, b->mem+b->uncompressed_siz); */ vld = lxt2_rd_get_byte(b->dict_start - 1, 0); if(vld != LXT2_RD_GRAN_SECT_DICT) { fprintf(stderr, LXT2_RDLOAD"Malformed section\n"); exit(255); } if(b->num_dict_entries) { b->string_pointers = malloc(b->num_dict_entries * sizeof(char *)); b->string_lens = malloc(b->num_dict_entries * sizeof(unsigned int)); pnt = b->dict_start; for(i=0;inum_dict_entries;i++) { b->string_pointers[i] = pnt; b->string_lens[i] = strlen(pnt); pnt += (b->string_lens[i] + 1); /* fprintf(stderr, LXT2_RDLOAD"%d '%s'\n", i, b->string_pointers[i]); */ } if(pnt!=b->map_start) { fprintf(stderr, LXT2_RDLOAD"dictionary corrupt, exiting\n"); exit(255); } } pnt = b->mem; while(((sect_typ=*pnt) == LXT2_RD_GRAN_SECT_TIME)||(sect_typ == LXT2_RD_GRAN_SECT_TIME_PARTIAL)) { lxtint32_t strtfac, endfac; if(sect_typ == LXT2_RD_GRAN_SECT_TIME_PARTIAL) { lxtint32_t sublen; lxt2_rd_regenerate_process_mask(lt); strtfac = lxt2_rd_get_32(pnt, 1); sublen = lxt2_rd_get_32(pnt, 5); if(!granvld) { granvld=1; strtfac_gran = strtfac; } else { granule += (strtfac==strtfac_gran); } if(!lt->process_mask_compressed[strtfac/LXT2_RD_PARTIAL_SIZE]) { /* fprintf(stderr, "skipping group %d for %d bytes\n", strtfac, sublen); */ pnt += 9; pnt += sublen; continue; } /* fprintf(stderr, "processing group %d for %d bytes\n", strtfac, sublen); */ endfac=strtfac+LXT2_RD_PARTIAL_SIZE; if(endfac>lt->numrealfacs) endfac=lt->numrealfacs; pnt += 8; } else { strtfac=0; endfac=lt->numrealfacs; } /* fprintf(stderr, LXT2_RDLOAD"processing granule %d\n", granule); */ pnt++; lt->num_time_table_entries = lxt2_rd_get_byte(pnt, 0); pnt++; for(i=0;inum_time_table_entries;i++) { lt->time_table[i] = lxt2_rd_get_64(pnt, 0); pnt+=8; /* fprintf(stderr, LXT2_RDLOAD"\t%d) %lld\n", i, lt->time_table[i]); */ } lt->fac_map_index_width = lxt2_rd_get_byte(pnt, 0); if((!lt->fac_map_index_width)||(lt->fac_map_index_width > 4)) { fprintf(stderr, LXT2_RDLOAD"Map index width of %d is illegal, exiting.\n", lt->fac_map_index_width); exit(255); } pnt++; for(i=strtfac;ifac_map_index_width) { case 1: mskindx = lxt2_rd_get_byte(pnt, 0); break; case 2: mskindx = lxt2_rd_get_16(pnt, 0); break; case 3: mskindx = lxt2_rd_get_24(pnt, 0); break; case 4: default: mskindx = lxt2_rd_get_32(pnt, 0); break; } pnt += lt->fac_map_index_width; #if LXT2_RD_GRANULE_SIZE > 32 if(lt->granule_size==LXT2_RD_GRANULE_SIZE) { lt->fac_map[i] = get_fac_msk(b->map_start, mskindx * sizeof(granmsk_t)); } else { lt->fac_map[i] = get_fac_msk_smaller(b->map_start, mskindx * sizeof(granmsk_smaller_t)); } #else lt->fac_map[i] = get_fac_msk(b->map_start, mskindx * sizeof(granmsk_t)); #endif } lt->fac_curpos_width = lxt2_rd_get_byte(pnt, 0); if((!lt->fac_curpos_width)||(lt->fac_curpos_width > 4)) { fprintf(stderr, LXT2_RDLOAD"Curpos index width of %d is illegal, exiting.\n", lt->fac_curpos_width); exit(255); } pnt++; for(i=strtfac;ifac_curpos[i] = pnt; if(lt->fac_map[i]) { pnt += (lxt2_rd_ones_cnt(lt->fac_map[i]) * lt->fac_curpos_width); } } lxt2_rd_build_radix(lt, b, granule, strtfac, endfac); lxt2_rd_iter_radix(lt, b); if(sect_typ != LXT2_RD_GRAN_SECT_TIME_PARTIAL) { granule++; } } return(1); } /****************************************************************************/ /* * null callback used when a user passes NULL as an argument to lxt2_rd_iter_blocks() */ void lxt2_rd_null_callback(struct lxt2_rd_trace **lt, lxtint64_t *pnt_time, lxtint32_t *pnt_facidx, char **pnt_value) { (void) lt; (void) pnt_time; (void) pnt_facidx; (void) pnt_value; /* fprintf(stderr, LXT2_RDLOAD"%lld %d %s\n", *pnt_time, *pnt_facidx, *pnt_value); */ } /****************************************************************************/ /* * initialize the trace, get compressed facnames, get geometries, * and get block offset/size/timestart/timeend... */ struct lxt2_rd_trace *lxt2_rd_init(const char *name) { struct lxt2_rd_trace *lt=(struct lxt2_rd_trace *)calloc(1, sizeof(struct lxt2_rd_trace)); lxtint32_t i; if(!(lt->handle=fopen(name, "rb"))) { lxt2_rd_close(lt); lt=NULL; } else { lxtint16_t id = 0, version = 0; lt->block_mem_max = LXT2_RD_MAX_BLOCK_MEM_USAGE; /* cutoff after this number of bytes and force flush */ setvbuf(lt->handle, (char *)NULL, _IONBF, 0); /* keeps gzip from acting weird in tandem with fopen */ if(!fread(&id, 2, 1, lt->handle)) { id = 0; } if(!fread(&version, 2, 1, lt->handle)) { id = 0; } if(!fread(<->granule_size, 1, 1, lt->handle)) { id = 0; } if(lxt2_rd_get_16(&id,0) != LXT2_RD_HDRID) { fprintf(stderr, LXT2_RDLOAD"*** Not an lxt file ***\n"); lxt2_rd_close(lt); lt=NULL; } else if((version=lxt2_rd_get_16(&version,0)) > LXT2_RD_VERSION) { fprintf(stderr, LXT2_RDLOAD"*** Version %d lxt not supported ***\n", version); lxt2_rd_close(lt); lt=NULL; } else if(lt->granule_size > LXT2_RD_GRANULE_SIZE) { fprintf(stderr, LXT2_RDLOAD"*** Granule size of %d (>%d) not supported ***\n", lt->granule_size, LXT2_RD_GRANULE_SIZE); lxt2_rd_close(lt); lt=NULL; } else { size_t rcf; int rc; char *m; off_t pos, fend; int t; struct lxt2_rd_block *b; rcf=fread(<->numfacs, 4, 1, lt->handle); lt->numfacs = rcf ? lxt2_rd_get_32(<->numfacs,0) : 0; if(!lt->numfacs) { lxtint32_t num_expansion_bytes; rcf = fread(&num_expansion_bytes, 4, 1, lt->handle); num_expansion_bytes = rcf ? lxt2_rd_get_32(&num_expansion_bytes,0) : 0; rcf = fread(<->numfacs, 4, 1, lt->handle); lt->numfacs = rcf ? lxt2_rd_get_32(<->numfacs,0) : 0; if(num_expansion_bytes >= 8) { rcf = fread(<->timezero, 8, 1, lt->handle); lt->timezero = rcf ? lxt2_rd_get_64(<->timezero,0) : 0; if(num_expansion_bytes > 8) { /* future version? */ fseeko(lt->handle, num_expansion_bytes - 8, SEEK_CUR); } } else { /* malformed */ fseeko(lt->handle, num_expansion_bytes, SEEK_CUR); } } rcf=fread(<->numfacbytes, 4, 1, lt->handle); lt->numfacbytes = rcf ? lxt2_rd_get_32(<->numfacbytes,0) : 0; rcf=fread(<->longestname, 4, 1, lt->handle); lt->longestname = rcf ? lxt2_rd_get_32(<->longestname,0) : 0; rcf=fread(<->zfacnamesize, 4, 1, lt->handle); lt->zfacnamesize = rcf ? lxt2_rd_get_32(<->zfacnamesize,0) : 0; rcf=fread(<->zfacname_predec_size, 4, 1, lt->handle); lt->zfacname_predec_size = rcf ? lxt2_rd_get_32(<->zfacname_predec_size,0) : 0; rcf=fread(<->zfacgeometrysize, 4, 1, lt->handle); lt->zfacgeometrysize = rcf ? lxt2_rd_get_32(<->zfacgeometrysize,0) : 0; rcf=fread(<->timescale, 1, 1, lt->handle); if(!rcf) lt->timescale = 0; /* no swap necessary */ if(!lt->numfacs) /* scan-build for mallocs below */ { fprintf(stderr, LXT2_RDLOAD"*** Nothing to do, zero facilities found.\n"); lxt2_rd_close(lt); lt=NULL; } else { fprintf(stderr, LXT2_RDLOAD LXT2_RD_LD" facilities\n", lt->numfacs); pos = ftello(lt->handle); /* fprintf(stderr, LXT2_RDLOAD"gzip facnames start at pos %d (zsize=%d)\n", pos, lt->zfacnamesize); */ lt->process_mask = calloc(1, lt->numfacs/8+1); lt->process_mask_compressed = calloc(1, lt->numfacs/LXT2_RD_PARTIAL_SIZE+1); lt->zhandle = gzdopen(dup(fileno(lt->handle)), "rb"); m=(char *)malloc(lt->zfacname_predec_size); rc=gzread(lt->zhandle, m, lt->zfacname_predec_size); gzclose(lt->zhandle); lt->zhandle=NULL; if(((lxtint32_t)rc)!=lt->zfacname_predec_size) { fprintf(stderr, LXT2_RDLOAD"*** name section mangled %d (act) vs "LXT2_RD_LD" (exp)\n", rc, lt->zfacname_predec_size); free(m); lxt2_rd_close(lt); lt=NULL; return(lt); } lt->zfacnames = m; lt->faccache = calloc(1, sizeof(struct lxt2_rd_facname_cache)); lt->faccache->old_facidx = lt->numfacs; /* causes lxt2_rd_get_facname to initialize its unroll ptr as this is always invalid */ lt->faccache->bufcurr = malloc(lt->longestname+1); lt->faccache->bufprev = malloc(lt->longestname+1); fseeko(lt->handle, pos = pos+lt->zfacnamesize, SEEK_SET); /* fprintf(stderr, LXT2_RDLOAD"seeking to geometry at %d (0x%08x)\n", pos, pos); */ lt->zhandle = gzdopen(dup(fileno(lt->handle)), "rb"); t = lt->numfacs * 4 * sizeof(lxtint32_t); m=(char *)malloc(t); rc=gzread(lt->zhandle, m, t); gzclose(lt->zhandle); lt->zhandle=NULL; if(rc!=t) { fprintf(stderr, LXT2_RDLOAD"*** geometry section mangled %d (act) vs %d (exp)\n", rc, t); free(m); lxt2_rd_close(lt); lt=NULL; return(lt); } pos = pos+lt->zfacgeometrysize; lt->rows = malloc(lt->numfacs * sizeof(lxtint32_t)); lt->msb = malloc(lt->numfacs * sizeof(lxtsint32_t)); lt->lsb = malloc(lt->numfacs * sizeof(lxtsint32_t)); lt->flags = malloc(lt->numfacs * sizeof(lxtint32_t)); lt->len = malloc(lt->numfacs * sizeof(lxtint32_t)); lt->value = malloc(lt->numfacs * sizeof(char *)); lt->next_radix = malloc(lt->numfacs * sizeof(void *)); for(i=0;inumfacs;i++) { lt->rows[i] = lxt2_rd_get_32(m+i*16, 0); lt->msb[i] = lxt2_rd_get_32(m+i*16, 4); lt->lsb[i] = lxt2_rd_get_32(m+i*16, 8); lt->flags[i] = lxt2_rd_get_32(m+i*16, 12); if(!(lt->flags[i] & LXT2_RD_SYM_F_INTEGER)) { lt->len[i] = (lt->msb[i] <= lt->lsb[i]) ? (lt->lsb[i] - lt->msb[i] + 1) : (lt->msb[i] - lt->lsb[i] + 1); } else { lt->len[i] = 32; } lt->value[i] = calloc(lt->len[i] + 1, sizeof(char)); } for(lt->numrealfacs=0; lt->numrealfacsnumfacs; lt->numrealfacs++) { if(lt->flags[lt->numrealfacs] & LXT2_RD_SYM_F_ALIAS) { break; } } if(lt->numrealfacs > lt->numfacs) lt->numrealfacs = lt->numfacs; lt->prev_time = ~(LXT2_RD_GRAN_0VAL); free(m); lt->fac_map = malloc(lt->numfacs * sizeof(granmsk_t)); lt->fac_curpos = malloc(lt->numfacs * sizeof(char *)); for(;;) { fseeko(lt->handle, 0L, SEEK_END); fend=ftello(lt->handle); if(pos>=fend) break; fseeko(lt->handle, pos, SEEK_SET); /* fprintf(stderr, LXT2_RDLOAD"seeking to block at %d (0x%08x)\n", pos, pos); */ b=calloc(1, sizeof(struct lxt2_rd_block)); rcf = fread(&b->uncompressed_siz, 4, 1, lt->handle); b->uncompressed_siz = rcf ? lxt2_rd_get_32(&b->uncompressed_siz,0) : 0; rcf = fread(&b->compressed_siz, 4, 1, lt->handle); b->compressed_siz = rcf ? lxt2_rd_get_32(&b->compressed_siz,0) : 0; rcf = fread(&b->start, 8, 1, lt->handle); b->start = rcf ? lxt2_rd_get_64(&b->start,0) : 0; rcf = fread(&b->end, 8, 1, lt->handle); b->end = rcf ? lxt2_rd_get_64(&b->end,0) : 0; pos = ftello(lt->handle); fseeko(lt->handle, pos, SEEK_SET); /* fprintf(stderr, LXT2_RDLOAD"block gzip start at pos %d (0x%08x)\n", pos, pos); */ if(pos>=fend) { free(b); break; } b->filepos = pos; /* mark startpos for later in case we purge it from memory */ /* fprintf(stderr, LXT2_RDLOAD"un/compressed size: %d/%d\n", b->uncompressed_siz, b->compressed_siz); */ if((b->uncompressed_siz)&&(b->compressed_siz)&&(b->end)) { /* fprintf(stderr, LXT2_RDLOAD"block [%d] %lld / %lld\n", lt->numblocks, b->start, b->end); */ fseeko(lt->handle, b->compressed_siz, SEEK_CUR); lt->numblocks++; if(lt->block_curr) { lt->block_curr->next = b; lt->block_curr = b; lt->end = b->end; } else { lt->block_head = lt->block_curr = b; lt->start = b->start; lt->end = b->end; } } else { free(b); break; } pos+=b->compressed_siz; } if(lt->numblocks) { fprintf(stderr, LXT2_RDLOAD"Read %d block header%s OK\n", lt->numblocks, (lt->numblocks!=1) ? "s" : ""); fprintf(stderr, LXT2_RDLOAD"["LXT2_RD_LLD"] start time\n", lt->start); fprintf(stderr, LXT2_RDLOAD"["LXT2_RD_LLD"] end time\n", lt->end); fprintf(stderr, LXT2_RDLOAD"\n"); lt->value_change_callback = lxt2_rd_null_callback; } else { lxt2_rd_close(lt); lt=NULL; } } } } return(lt); } /* * free up/deallocate any resources still left out there: * blindly do it based on NULL pointer comparisons (ok, since * calloc() is used to allocate all structs) as performance * isn't an issue for this set of cleanup code */ void lxt2_rd_close(struct lxt2_rd_trace *lt) { if(lt) { struct lxt2_rd_block *b, *bt; lxtint32_t i; if(lt->process_mask) { free(lt->process_mask); lt->process_mask=NULL; } if(lt->process_mask_compressed) { free(lt->process_mask_compressed); lt->process_mask_compressed=NULL; } if(lt->rows) { free(lt->rows); lt->rows=NULL; } if(lt->msb) { free(lt->msb); lt->msb=NULL; } if(lt->lsb) { free(lt->lsb); lt->lsb=NULL; } if(lt->flags) { free(lt->flags); lt->flags=NULL; } if(lt->len) { free(lt->len); lt->len=NULL; } if(lt->next_radix) { free(lt->next_radix); lt->next_radix=NULL; } for(i=0;inumfacs;i++) { if(lt->value[i]) { free(lt->value[i]); lt->value[i]=NULL; } } if(lt->value) { free(lt->value); lt->value=NULL; } if(lt->zfacnames) { free(lt->zfacnames); lt->zfacnames=NULL; } if(lt->faccache) { if(lt->faccache->bufprev) { free(lt->faccache->bufprev); lt->faccache->bufprev=NULL; } if(lt->faccache->bufcurr) { free(lt->faccache->bufcurr); lt->faccache->bufcurr=NULL; } free(lt->faccache); lt->faccache=NULL; } if(lt->fac_map) { free(lt->fac_map); lt->fac_map=NULL; } if(lt->fac_curpos) { free(lt->fac_curpos); lt->fac_curpos=NULL; } b=lt->block_head; while(b) { bt=b->next; if(b->mem) { free(b->mem); b->mem=NULL; } if(b->string_pointers) { free(b->string_pointers); b->string_pointers=NULL; } if(b->string_lens) { free(b->string_lens); b->string_lens=NULL; } free(b); b=bt; } lt->block_head=lt->block_curr=NULL; if(lt->zhandle) { gzclose(lt->zhandle); lt->zhandle=NULL; } if(lt->handle) { fclose(lt->handle); lt->handle=NULL; } free(lt); } } /****************************************************************************/ /* * return number of facs in trace */ _LXT2_RD_INLINE lxtint32_t lxt2_rd_get_num_facs(struct lxt2_rd_trace *lt) { return(lt ? lt->numfacs : 0); } /* * return fac geometry for a given index */ struct lxt2_rd_geometry *lxt2_rd_get_fac_geometry(struct lxt2_rd_trace *lt, lxtint32_t facidx) { if((lt)&&(facidxnumfacs)) { lt->geometry.rows = lt->rows[facidx]; lt->geometry.msb = lt->msb[facidx]; lt->geometry.lsb = lt->lsb[facidx]; lt->geometry.flags = lt->flags[facidx]; lt->geometry.len = lt->len[facidx]; return(<->geometry); } else { return(NULL); } } /* * return partial fac geometry for a given index */ _LXT2_RD_INLINE lxtint32_t lxt2_rd_get_fac_rows(struct lxt2_rd_trace *lt, lxtint32_t facidx) { if((lt)&&(facidxnumfacs)) { return(lt->rows[facidx]); } else { return(0); } } _LXT2_RD_INLINE lxtsint32_t lxt2_rd_get_fac_msb(struct lxt2_rd_trace *lt, lxtint32_t facidx) { if((lt)&&(facidxnumfacs)) { return(lt->msb[facidx]); } else { return(0); } } _LXT2_RD_INLINE lxtsint32_t lxt2_rd_get_fac_lsb(struct lxt2_rd_trace *lt, lxtint32_t facidx) { if((lt)&&(facidxnumfacs)) { return(lt->lsb[facidx]); } else { return(0); } } _LXT2_RD_INLINE lxtint32_t lxt2_rd_get_fac_flags(struct lxt2_rd_trace *lt, lxtint32_t facidx) { if((lt)&&(facidxnumfacs)) { return(lt->flags[facidx]); } else { return(0); } } _LXT2_RD_INLINE lxtint32_t lxt2_rd_get_fac_len(struct lxt2_rd_trace *lt, lxtint32_t facidx) { if((lt)&&(facidxnumfacs)) { return(lt->len[facidx]); } else { return(0); } } _LXT2_RD_INLINE lxtint32_t lxt2_rd_get_alias_root(struct lxt2_rd_trace *lt, lxtint32_t facidx) { if((lt)&&(facidxnumfacs)) { while(lt->flags[facidx] & LXT2_RD_SYM_F_ALIAS) { facidx = lt->rows[facidx]; /* iterate to next alias */ } return(facidx); } else { return(~((lxtint32_t)0)); } } /* * time queries */ _LXT2_RD_INLINE lxtint64_t lxt2_rd_get_start_time(struct lxt2_rd_trace *lt) { return(lt ? lt->start : LXT2_RD_GRAN_0VAL); } _LXT2_RD_INLINE lxtint64_t lxt2_rd_get_end_time(struct lxt2_rd_trace *lt) { return(lt ? lt->end : LXT2_RD_GRAN_0VAL); } _LXT2_RD_INLINE char lxt2_rd_get_timescale(struct lxt2_rd_trace *lt) { return(lt ? lt->timescale : 0); } _LXT2_RD_INLINE lxtsint64_t lxt2_rd_get_timezero(struct lxt2_rd_trace *lt) { return(lt ? lt->timezero : 0); } /* * extract facname from prefix-compressed table. this * performs best when extracting facs with monotonically * increasing indices... */ char *lxt2_rd_get_facname(struct lxt2_rd_trace *lt, lxtint32_t facidx) { char *pnt; lxtint32_t clone, j; if(lt) { if((facidx==(lt->faccache->old_facidx+1))||(!facidx)) { if(!facidx) { lt->faccache->n = lt->zfacnames; lt->faccache->bufcurr[0] = 0; lt->faccache->bufprev[0] = 0; } if(facidx!=lt->numfacs) { pnt = lt->faccache->bufcurr; lt->faccache->bufcurr = lt->faccache->bufprev; lt->faccache->bufprev = pnt; clone=lxt2_rd_get_16(lt->faccache->n, 0); lt->faccache->n+=2; pnt=lt->faccache->bufcurr; for(j=0;jfaccache->bufprev[j]; } while((*(pnt++)=lxt2_rd_get_byte(lt->faccache->n++,0))); lt->faccache->old_facidx = facidx; return(lt->faccache->bufcurr); } else { return(NULL); /* no more left */ } } else { if(facidxnumfacs) { int strt; if(facidx==lt->faccache->old_facidx) { return(lt->faccache->bufcurr); } if(facidx>(lt->faccache->old_facidx+1)) { strt = lt->faccache->old_facidx+1; } else { strt=0; } for(j=strt;jnumfacs) { int process_idx = facidx/8; int process_bit = facidx&7; return( (lt->process_mask[process_idx]&(1<process_mask_dirty = 1; if(facidxnumfacs) { int idx = facidx/8; int bitpos = facidx&7; lt->process_mask[idx] |= (1<process_mask_dirty = 1; if(facidxnumfacs) { int idx = facidx/8; int bitpos = facidx&7; lt->process_mask[idx] &= (~(1<process_mask_dirty = 1; memset(lt->process_mask, 0xff, (lt->numfacs+7)/8); rc=1; } return(rc); } _LXT2_RD_INLINE int lxt2_rd_clr_fac_process_mask_all(struct lxt2_rd_trace *lt) { int rc=0; if(lt) { lt->process_mask_dirty = 1; memset(lt->process_mask, 0x00, (lt->numfacs+7)/8); rc=1; } return(rc); } /* * block memory set/get used to control buffering */ _LXT2_RD_INLINE lxtint64_t lxt2_rd_set_max_block_mem_usage(struct lxt2_rd_trace *lt, lxtint64_t block_mem_max) { lxtint64_t rc = lt->block_mem_max; lt->block_mem_max = block_mem_max; return(rc); } _LXT2_RD_INLINE lxtint64_t lxt2_rd_get_block_mem_usage(struct lxt2_rd_trace *lt) { return(lt->block_mem_consumed); } /* * return total number of blocks */ _LXT2_RD_INLINE unsigned int lxt2_rd_get_num_blocks(struct lxt2_rd_trace *lt) { return(lt->numblocks); } /* * return number of active blocks */ unsigned int lxt2_rd_get_num_active_blocks(struct lxt2_rd_trace *lt) { int blk=0; if(lt) { struct lxt2_rd_block *b = lt->block_head; while(b) { if((!b->short_read_ignore)&&(!b->exclude_block)) { blk++; } b=b->next; } } return(blk); } /****************************************************************************/ /* * block iteration...purge/reload code here isn't sophisticated as it * merely caches the FIRST set of blocks which fit in lt->block_mem_max. * n.b., returns number of blocks processed */ int lxt2_rd_iter_blocks(struct lxt2_rd_trace *lt, void (*value_change_callback)(struct lxt2_rd_trace **lt, lxtint64_t *time, lxtint32_t *facidx, char **value), void *user_callback_data_pointer) { struct lxt2_rd_block *b; int blk=0, blkfinal=0; int processed = 0; struct lxt2_rd_block *bcutoff=NULL, *bfinal=NULL; int striped_kill = 0; unsigned int real_uncompressed_siz = 0; unsigned char gzid[2]; lxtint32_t i; if(lt) { lt->value_change_callback = value_change_callback ? value_change_callback : lxt2_rd_null_callback; lt->user_callback_data_pointer = user_callback_data_pointer; b = lt->block_head; blk=0; for(i=0;inumfacs;i++) { if(lt->value[i]) lt->value[i][0] = 0; } while(b) { if((!b->mem)&&(!b->short_read_ignore)&&(!b->exclude_block)) { if(processed<5) { int gate = (processed==4) && b->next; fprintf(stderr, LXT2_RDLOAD"block [%d] processing "LXT2_RD_LLD" / "LXT2_RD_LLD"%s\n", blk, b->start, b->end, gate ? " ..." : ""); if(gate) { bcutoff = b; } } processed++; fseeko(lt->handle, b->filepos, SEEK_SET); gzid[0]=gzid[1]=0; if(!fread(&gzid, 2, 1, lt->handle)) { gzid[0] = gzid[1] = 0; } fseeko(lt->handle, b->filepos, SEEK_SET); if((striped_kill = (gzid[0]!=0x1f)||(gzid[1]!=0x8b))) { lxtint32_t clen, unclen, iter=0; char *pnt; off_t fspos = b->filepos; lxtint32_t zlen = 16; char *zbuff=malloc(zlen); struct z_stream_s strm; real_uncompressed_siz = b->uncompressed_siz; pnt = b->mem = malloc(b->uncompressed_siz); b->uncompressed_siz = 0; lxt2_rd_regenerate_process_mask(lt); while(iter!=0xFFFFFFFF) { size_t rcf; clen = unclen = iter = 0; rcf = fread(&clen, 4, 1, lt->handle); clen = rcf ? lxt2_rd_get_32(&clen,0) : 0; rcf = fread(&unclen, 4, 1, lt->handle); unclen = rcf ? lxt2_rd_get_32(&unclen,0) : 0; rcf = fread(&iter, 4, 1, lt->handle); iter = rcf ? lxt2_rd_get_32(&iter,0) : 0; fspos += 12; if((iter==0xFFFFFFFF)||(lt->process_mask_compressed[iter/LXT2_RD_PARTIAL_SIZE])) { if(clen > zlen) { if(zbuff) free(zbuff); zlen = clen * 2; zbuff = malloc(zlen ? zlen : 1 /* scan-build */); } if(!fread(zbuff, clen, 1, lt->handle)) { clen = 0; } strm.avail_in = clen-10; strm.avail_out = unclen; strm.total_in = strm.total_out = 0; strm.zalloc = NULL; strm.zfree = NULL; strm.opaque = NULL; strm.next_in = (unsigned char *)(zbuff+10); strm.next_out = (unsigned char *)(pnt); if((clen != 0)&&(unclen != 0)) { inflateInit2(&strm, -MAX_WBITS); while (Z_OK == inflate(&strm, Z_NO_FLUSH)); inflateEnd(&strm); } if((strm.total_out!=unclen)||(clen == 0)||(unclen == 0)) { fprintf(stderr, LXT2_RDLOAD"short read on subblock %ld vs "LXT2_RD_LD" (exp), ignoring\n", strm.total_out, unclen); free(b->mem); b->mem=NULL; b->short_read_ignore = 1; b->uncompressed_siz = real_uncompressed_siz; break; } b->uncompressed_siz+=strm.total_out; pnt += strm.total_out; fspos += clen; } else { fspos += clen; fseeko(lt->handle, fspos, SEEK_SET); } } if(zbuff) free(zbuff); } else { int rc; b->mem = malloc(b->uncompressed_siz); lt->zhandle = gzdopen(dup(fileno(lt->handle)), "rb"); rc=gzread(lt->zhandle, b->mem, b->uncompressed_siz); gzclose(lt->zhandle); lt->zhandle=NULL; if(((lxtint32_t)rc)!=b->uncompressed_siz) { fprintf(stderr, LXT2_RDLOAD"short read on block %d vs "LXT2_RD_LD" (exp), ignoring\n", rc, b->uncompressed_siz); free(b->mem); b->mem=NULL; b->short_read_ignore = 1; } else { lt->block_mem_consumed += b->uncompressed_siz; } } bfinal=b; blkfinal = blk; } if(b->mem) { lxt2_rd_process_block(lt, b); if(striped_kill) { free(b->mem); b->mem=NULL; b->uncompressed_siz = real_uncompressed_siz; } else if(lt->numblocks > 1) /* no sense freeing up the single block case */ { if(lt->block_mem_consumed > lt->block_mem_max) { lt->block_mem_consumed -= b->uncompressed_siz; free(b->mem); b->mem=NULL; } } } blk++; b=b->next; } } if((bcutoff)&&(bfinal!=bcutoff)) { fprintf(stderr, LXT2_RDLOAD"block [%d] processed "LXT2_RD_LLD" / "LXT2_RD_LLD"\n", blkfinal, bfinal->start, bfinal->end); } return(blk); } /* * callback access to the user callback data pointer (if required) */ _LXT2_RD_INLINE void *lxt2_rd_get_user_callback_data_pointer(struct lxt2_rd_trace *lt) { if(lt) { return(lt->user_callback_data_pointer); } else { return(NULL); } } /* * limit access to certain timerange in file * and return number of active blocks */ unsigned int lxt2_rd_limit_time_range(struct lxt2_rd_trace *lt, lxtint64_t strt_time, lxtint64_t end_time) { lxtint64_t tmp_time; int blk=0; if(lt) { struct lxt2_rd_block *b = lt->block_head; struct lxt2_rd_block *bprev = NULL; int state = 0; if(strt_time > end_time) { tmp_time = strt_time; strt_time = end_time; end_time = tmp_time; } while(b) { switch(state) { case 0: if(b->end >= strt_time) { state = 1; if((b->start > strt_time) && (bprev)) { bprev->exclude_block = 0; blk++; } } break; case 1: if(b->start > end_time) state = 2; break; default: break; } if((state==1) && (!b->short_read_ignore)) { b->exclude_block = 0; blk++; } else { b->exclude_block = 1; } bprev = b; b = b->next; } } return(blk); } /* * unrestrict access to the whole file * and return number of active blocks */ unsigned int lxt2_rd_unlimit_time_range(struct lxt2_rd_trace *lt) { int blk=0; if(lt) { struct lxt2_rd_block *b = lt->block_head; while(b) { b->exclude_block = 0; if(!b->short_read_ignore) { blk++; } b=b->next; } } return(blk); } gtkwave-3.3.66/src/helpers/v2l_debug.h0000664000076400007640000000550412341266475017070 0ustar bybellbybell/* * Copyright (c) 2001-2014 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifndef WAVE_DEBUG_H #define WAVE_DEBUG_H #include #include #ifdef HAVE_INTTYPES_H #include #endif struct memchunk { struct memchunk *next; void *ptr; size_t size; }; /* * If you have problems viewing traces (mangled timevalues), * make sure that you use longs rather than the glib 64-bit * types... */ #define G_HAVE_GINT64 #define gint64 int64_t #define guint64 uint64_t #ifdef G_HAVE_GINT64 typedef gint64 TimeType; typedef guint64 UTimeType; #ifndef _MSC_VER #define LLDescriptor(x) x##LL #define ULLDescriptor(x) x##ULL #ifndef __MINGW32__ #if __WORDSIZE == 64 #define TTFormat "%ld" #else #define TTFormat "%lld" #endif #else #define TTFormat "%I64d" #endif #else #define LLDescriptor(x) x##i64 #define ULLDescriptor(x) x##i64 #define TTFormat "%I64d" #endif #else typedef long TimeType; typedef unsigned long UTimeType; #define TTFormat "%d" #define LLDescriptor(x) x #define ULLDescriptor(x) x #endif #ifdef DEBUG_PRINTF #define DEBUG(x) x #else #define DEBUG(x) #endif #ifdef DEBUG_MALLOC #define DEBUG_M(x) x #else #define DEBUG_M(x) #endif void *malloc_2(size_t size); void *realloc_2(void *ptr, size_t size); void *calloc_2(size_t nmemb, size_t size); void free_2(void *ptr); TimeType atoi_64(char *str); /* * if your system really doesn't have alloca() at all, * you can force functionality by using malloc * instead. but note that you're going to have some * memory leaks because of it. you have been warned. */ #include #if HAVE_ALLOCA_H #include #elif defined(__GNUC__) #ifndef alloca #define alloca __builtin_alloca #endif #elif defined(_MSC_VER) #include #define alloca _alloca #endif #define wave_alloca alloca #endif gtkwave-3.3.66/src/helpers/vcd2lxt.c0000664000076400007640000012416512341266475016605 0ustar bybellbybell/* * Copyright (c) 2001-2014 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ /* * vcd.c 23jan99ajb * evcd parts 29jun99ajb * profiler optimizations 15jul99ajb * stripped out of gtkwave 21jul99ajb * fix for duplicate nets 19dec00ajb * lxt conversion added 20nov01ajb */ /* AIX may need this for alloca to work */ #if defined _AIX #pragma alloca #endif #include #include "v2l_analyzer.h" #include "wave_locale.h" #undef VCD_BSEARCH_IS_PERFECT /* bsearch is imperfect under linux, but OK under AIX */ struct lt_trace *lt=NULL; int numfacs=0; int deadcnt=0; struct symbol **sym=NULL; struct symbol **facs=NULL; struct symbol *firstnode=NULL; struct symbol *curnode=NULL; TimeType min_time=-1, max_time=-1; char hier_delimeter='.'; char deadchar='X'; int vcd_explicit_zero_subscripts=-1; /* 0=yes, -1=no */ char atomic_vectors=1; static FILE *vcd_handle=NULL; static char vcd_is_compressed=0; static void add_histent(TimeType time, struct Node *n, char ch, int regadd, char *vector); static void add_tail_histents(void); static void evcd_strcpy(char *dst, char *src); static int vcdlineno=1; static int header_over=0; static int dumping_off=0; static TimeType start_time=-1; static TimeType end_time=-1; static TimeType current_time=-1; static TimeType time_scale=1; /* multiplier is 1, 10, 100 */ static TimeType time_zero=0; static char vcd_hier_delimeter[2]={0, 0}; /* fill in after rc reading code */ /******************************************************************/ static struct slist *slistroot=NULL, *slistcurr=NULL; static char *slisthier=NULL; static int slisthier_len=0; /******************************************************************/ enum Tokens { T_VAR, T_END, T_SCOPE, T_UPSCOPE, T_COMMENT, T_DATE, T_DUMPALL, T_DUMPOFF, T_DUMPON, T_DUMPVARS, T_ENDDEFINITIONS, T_DUMPPORTS, T_DUMPPORTSOFF, T_DUMPPORTSON, T_DUMPPORTSALL, T_TIMESCALE, T_VERSION, T_VCDCLOSE, T_TIMEZERO, T_EOF, T_STRING, T_UNKNOWN_KEY }; char *tokens[]={ "var", "end", "scope", "upscope", "comment", "date", "dumpall", "dumpoff", "dumpon", "dumpvars", "enddefinitions", "dumpports", "dumpportsoff", "dumpportson", "dumpportsall", "timescale", "version", "vcdclose", "timezero", "", "", "" }; #define NUM_TOKENS 19 static int T_MAX_STR=1024; /* was originally a const..now it reallocs */ static char *yytext=NULL; static int yylen=0, yylen_cache=0; #define T_GET tok=get_token();if((tok==T_END)||(tok==T_EOF))break; /******************************************************************/ static struct vcdsymbol *vcdsymroot=NULL, *vcdsymcurr=NULL; static struct vcdsymbol **sorted=NULL; static struct vcdsymbol **indexed=NULL; enum VarTypes { V_EVENT, V_PARAMETER, V_INTEGER, V_REAL, V_REAL_PARAMETER=V_REAL, V_REALTIME=V_REAL, V_STRINGTYPE=V_REAL, V_REG, V_SUPPLY0, V_SUPPLY1, V_TIME, V_TRI, V_TRIAND, V_TRIOR, V_TRIREG, V_TRI0, V_TRI1, V_WAND, V_WIRE, V_WOR, V_PORT, V_IN=V_PORT, V_OUT=V_PORT, V_INOUT=V_PORT, V_END, V_LB, V_COLON, V_RB, V_STRING }; static char *vartypes[]={ "event", "parameter", "integer", "real", "real_parameter", "realtime", "string", "reg", "supply0", "supply1", "time", "tri", "triand", "trior", "trireg", "tri0", "tri1", "wand", "wire", "wor", "port", "in", "out", "inout", "$end", "", "", "", ""}; static const unsigned char varenums[] = { V_EVENT, V_PARAMETER, V_INTEGER, V_REAL, V_REAL_PARAMETER, V_REALTIME, V_STRINGTYPE, V_REG, V_SUPPLY0, V_SUPPLY1, V_TIME, V_TRI, V_TRIAND, V_TRIOR, V_TRIREG, V_TRI0, V_TRI1, V_WAND, V_WIRE, V_WOR, V_PORT, V_IN, V_OUT, V_INOUT, V_END, V_LB, V_COLON, V_RB, V_STRING }; #define NUM_VTOKENS 25 static int numsyms=0; /******************************************************************/ static struct queuedevent *queuedevents=NULL; /******************************************************************/ static unsigned int vcd_minid = ~0; static unsigned int vcd_maxid = 0; static unsigned int vcdid_hash(char *s, int len) { unsigned int val=0; int i; s+=(len-1); for(i=0;iid)); } /* * actual bsearch */ static struct vcdsymbol *bsearch_vcd(char *key, int len) { struct vcdsymbol **v; struct vcdsymbol *t; if(indexed) { unsigned int hsh = vcdid_hash(key, len); if((hsh>=vcd_minid)&&(hsh<=vcd_maxid)) { return(indexed[hsh-vcd_minid]); } } v=(struct vcdsymbol **)bsearch(key, sorted, numsyms, sizeof(struct vcdsymbol *), vcdsymbsearchcompare); if(v) { #ifndef VCD_BSEARCH_IS_PERFECT for(;;) { t=*v; if((v==sorted)||(strcmp((*(--v))->id, key))) { return(t); } } #else return(*v); #endif } else { return(NULL); } } /* * sort on vcdsymbol pointers */ static int vcdsymcompare(const void *s1, const void *s2) { struct vcdsymbol *v1, *v2; v1=*((struct vcdsymbol **)s1); v2=*((struct vcdsymbol **)s2); return(strcmp(v1->id, v2->id)); } /* * alias vs normal symbol adding */ static void alias_vs_normal_symadd(struct vcdsymbol *v, struct vcdsymbol *root_v) { if(!v) return; /* scan-build : should never happen */ if(!root_v) { if((v->vartype==V_INTEGER)||(v->vartype==V_REAL)) { v->ltsym = lt_symbol_add(lt, v->name, 0, v->msi, v->lsi, (v->vartype==V_INTEGER)?LT_SYM_F_INTEGER:((v->vartype==V_REAL)?LT_SYM_F_DOUBLE:LT_SYM_F_BITS)); } else { char buf[65537]; if(v->msi==v->lsi) { sprintf(buf, "%s[%d]", v->name, v->msi); } else { sprintf(buf, "%s[%d:%d]", v->name, v->msi, v->lsi); } v->ltsym = lt_symbol_add(lt, buf, 0, v->msi, v->lsi, (v->vartype==V_INTEGER)?LT_SYM_F_INTEGER:((v->vartype==V_REAL)?LT_SYM_F_DOUBLE:LT_SYM_F_BITS)); } } else { if((v->vartype==V_INTEGER)||(v->vartype==V_REAL)) { lt_symbol_alias(lt, root_v->name, v->name, v->msi, v->lsi); } else { char bufold[65537], buf[65537]; if(v->msi==v->lsi) { sprintf(bufold, "%s[%d]", root_v->name, root_v->msi); sprintf(buf, "%s[%d]", v->name, v->msi); } else { sprintf(bufold, "%s[%d:%d]", root_v->name, root_v->msi, root_v->lsi); sprintf(buf, "%s[%d:%d]", v->name, v->msi, v->lsi); } lt_symbol_alias(lt, bufold, buf, v->msi, v->lsi); } } } /* * create sorted (by id) table */ static void create_sorted_table(void) { struct vcdsymbol *v; struct vcdsymbol **pnt; unsigned int vcd_distance; struct vcdsymbol *root_v; int i; if(numsyms) { vcd_distance = vcd_maxid - vcd_minid + 1; if(vcd_distance <= 8 * 1024 * 1024) { indexed = (struct vcdsymbol **)calloc_2(vcd_distance, sizeof(struct vcdsymbol *)); printf("%d symbols span ID range of %d, using indexing...\n", numsyms, vcd_distance); v=vcdsymroot; while(v) { if(!(root_v=indexed[v->nid - vcd_minid])) { indexed[v->nid - vcd_minid] = v; } alias_vs_normal_symadd(v, root_v); v=v->next; } } else { pnt=sorted=(struct vcdsymbol **)calloc_2(numsyms, sizeof(struct vcdsymbol *)); v=vcdsymroot; while(v) { *(pnt++)=v; v=v->next; } qsort(sorted, numsyms, sizeof(struct vcdsymbol *), vcdsymcompare); root_v = NULL; for(i=0;iname); v->name = NULL; v=v->next; } } } /******************************************************************/ /* * single char get */ static int getch(void) { int ch; ch=fgetc(vcd_handle); if(ch=='\n') vcdlineno++; return(((ch==EOF)||(errno))?(-1):(ch)); } static int getch_peek(void) { int ch; ch=fgetc(vcd_handle); ungetc(ch, vcd_handle); return(((ch==EOF)||(errno))?(-1):(ch)); } static char *varsplit=NULL, *vsplitcurr=NULL; static int getch_patched(void) { char ch; ch=*vsplitcurr; if(!ch) { return(-1); } else { vsplitcurr++; return((int)ch); } } /* * simple tokenizer */ static int get_token(void) { int ch; int i, len=0; int is_string=0; char *yyshadow; for(;;) { ch=getch(); if(ch<0) return(T_EOF); if(ch<=' ') continue; /* val<=' ' is a quick whitespace check */ break; /* (take advantage of fact that vcd is text) */ } if(ch=='$') { yytext[len++]=ch; for(;;) { ch=getch(); if(ch<0) return(T_EOF); if(ch<=' ') continue; break; } } else { is_string=1; } for(yytext[len++]=ch;;yytext[len++]=ch) { if(len==T_MAX_STR) { yytext=(char *)realloc_2(yytext, (T_MAX_STR=T_MAX_STR*2)+1); } ch=getch(); if(ch<=' ') break; } yytext[len]=0; /* terminator */ if(is_string) { yylen=len; return(T_STRING); } yyshadow=yytext; do { yyshadow++; for(i=0;iw #implicit-var###VarElem:ram_di[0.0] [63:0] $end' style declarations */ { /* debussy simply escapes until the space */ yytext[len++]= '\\'; } for(yytext[len++]=ch;;yytext[len++]=ch) { if(len==T_MAX_STR) { yytext=(char *)realloc_2(yytext, (T_MAX_STR=T_MAX_STR*2)+1); } ch=getch(); if(ch==' ') { if(match_kw) break; if(getch_peek() == '[') { ch = getch(); varsplit=yytext+len; /* keep looping so we get the *last* one */ continue; } } if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')||(ch<0)) break; if((ch=='[')&&(yytext[0]!='\\')) { varsplit=yytext+len; /* keep looping so we get the *last* one */ } else if(((ch==':')||(ch==']'))&&(!varsplit)&&(yytext[0]!='\\')) { var_prevch=ch; break; } } yytext[len]=0; /* absolute terminator */ if((varsplit)&&(yytext[len-1]==']')) { char *vst; vst=malloc_2(strlen(varsplit)+1); strcpy(vst, varsplit); *varsplit=0x00; /* zero out var name at the left bracket */ len=varsplit-yytext; varsplit=vsplitcurr=vst; var_prevch=0; } else { varsplit=NULL; } if(match_kw) for(i=0;ilen+(s->next?1:0); s=s->next; } if(slisthier) { free_2(slisthier); } slisthier=(char *)malloc_2((slisthier_len=len)+1); s=slistroot; len=0; while(s) { strcpy(slisthier+len,s->str); len+=s->len; if(s->next) { strcpy(slisthier+len,vcd_hier_delimeter); len++; } s=s->next; } return(slisthier); } void append_vcd_slisthier(char *str) { struct slist *s; s=(struct slist *)calloc_2(1,sizeof(struct slist)); s->len=strlen(str); s->str=(char *)malloc_2(s->len+1); strcpy(s->str,str); if(slistcurr) { slistcurr->next=s; slistcurr=s; } else { slistcurr=slistroot=s; } build_slisthier(); DEBUG(fprintf(stderr, "SCOPE: %s\n",slisthier)); } static void parse_valuechange(void) { struct vcdsymbol *v; char *vector; int vlen; switch(yytext[0]) { case '0': case '1': case 'x': case 'X': case 'z': case 'Z': case 'h': case 'H': case 'u': case 'U': case 'w': case 'W': case 'l': case 'L': case '-': if(yylen>1) { v=bsearch_vcd(yytext+1, yylen-1); if(!v) { fprintf(stderr,"Near line %d, Unknown VCD identifier: '%s'\n",vcdlineno,yytext+1); } else { if(v->vartype!=V_EVENT) { char vl[2]; vl[0]=yytext[0]; vl[1]=0; lt_emit_value_bit_string(lt, v->ltsym, 0, vl); v->value[0]=yytext[0]; DEBUG(fprintf(stderr,"%s = '%c'\n",v->name,v->value[0])); add_histent(current_time,v->narray[0],v->value[0],1, NULL); } else { char vl[2]; v->value[0]=(dumping_off)?'x':'1'; /* only '1' is relevant */ if(current_time!=(v->ev->last_event_time+1)) { /* dump degating event */ DEBUG(fprintf(stderr,"#"TTFormat" %s = '%c' (event)\n",v->ev->last_event_time+1,v->name,'0')); add_histent(v->ev->last_event_time+1,v->narray[0],'0',1, NULL); } DEBUG(fprintf(stderr,"%s = '%c' (event)\n",v->name,v->value[0])); add_histent(current_time,v->narray[0],v->value[0],1, NULL); vl[0]='1'; vl[1]=0; lt_emit_value_bit_string(lt, v->ltsym, 0, vl); vl[0]='0'; vl[1]=0; lt_emit_value_bit_string(lt, v->ltsym, 0, vl); v->ev->last_event_time=current_time; } } } else { fprintf(stderr,"Near line %d, Malformed VCD identifier\n", vcdlineno); } break; case 'b': case 'B': /* extract binary number then.. */ vector=malloc_2(yylen_cache=yylen); strcpy(vector,yytext+1); vlen=yylen-1; get_strtoken(); v=bsearch_vcd(yytext, yylen); if(!v) { fprintf(stderr,"Near line %d, Unknown identifier: '%s'\n",vcdlineno, yytext); free_2(vector); } else { if(vlensize) /* fill in left part */ { char extend; int i, fill; extend=(vector[0]=='1')?'0':vector[0]; fill=v->size-vlen; for(i=0;ivalue[i]=extend; } strcpy(v->value+fill,vector); } else if(vlen==v->size) /* straight copy */ { strcpy(v->value,vector); } else /* too big, so copy only right half */ { int skip; skip=vlen-v->size; strcpy(v->value,vector+skip); } DEBUG(fprintf(stderr,"%s = '%s'\n",v->name, v->value)); lt_emit_value_bit_string(lt, v->ltsym, 0, v->value); if((v->size==1)||(!atomic_vectors)) { int i; for(i=0;isize;i++) { add_histent(current_time, v->narray[i],v->value[i],1, NULL); } free_2(vector); } else { if(yylen_cache!=(v->size+1)) { free_2(vector); vector=malloc_2(v->size+1); } strcpy(vector,v->value); add_histent(current_time, v->narray[0],0,1,vector); free_2(vector); } } break; case 'p': /* extract port dump value.. */ vector=malloc_2(yylen_cache=yylen); strcpy(vector,yytext+1); vlen=yylen-1; get_strtoken(); /* throw away 0_strength_component */ get_strtoken(); /* throw away 0_strength_component */ get_strtoken(); /* this is the id */ v=bsearch_vcd(yytext, yylen); if(!v) { fprintf(stderr,"Near line %d, Unknown identifier: '%s'\n",vcdlineno, yytext); free_2(vector); } else { if(vlensize) /* fill in left part */ { char extend; int i, fill; extend='0'; fill=v->size-vlen; for(i=0;ivalue[i]=extend; } evcd_strcpy(v->value+fill,vector); } else if(vlen==v->size) /* straight copy */ { evcd_strcpy(v->value,vector); } else /* too big, so copy only right half */ { int skip; skip=vlen-v->size; evcd_strcpy(v->value,vector+skip); } DEBUG(fprintf(stderr,"%s = '%s'\n",v->name, v->value)); lt_emit_value_bit_string(lt, v->ltsym, 0, v->value); if((v->size==1)||(!atomic_vectors)) { int i; for(i=0;isize;i++) { add_histent(current_time, v->narray[i],v->value[i],1, NULL); } free_2(vector); } else { if(yylen_cachesize) { free_2(vector); vector=malloc_2(v->size+1); } strcpy(vector,v->value); add_histent(current_time, v->narray[0],0,1,vector); free_2(vector); } } break; case 'r': case 'R': { double *d; d=malloc_2(sizeof(double)); *d = 0; sscanf(yytext+1,"%lg",d); errno = 0; get_strtoken(); v=bsearch_vcd(yytext, yylen); if(!v) { fprintf(stderr,"Near line %d, Unknown identifier: '%s'\n",vcdlineno, yytext); free_2(d); } else { lt_emit_value_double(lt, v->ltsym, 0, *d); lt_emit_value_bit_string(lt, v->ltsym, 0, v->value); add_histent(current_time, v->narray[0],'g',1,(char *)d); free_2(d); } break; } case 's': case 'S': { get_strtoken(); /* simply skip for now */ break; } } } static void evcd_strcpy(char *dst, char *src) { static const char *evcd="DUNZduLHXTlh01?FAaBbCcf"; static const char *vcd="01xz0101xz0101xzxxxxxxz"; char ch; int i; while((ch=*src)) { for(i=0;i<23;i++) { if(evcd[i]==ch) { *dst=vcd[i]; break; } } if(i==23) *dst='x'; src++; dst++; } *dst=0; /* null terminate destination */ } static void vcd_parse(int linear) { int tok; for(;;) { switch(get_token()) { case T_COMMENT: sync_end("COMMENT:"); break; case T_DATE: sync_end("DATE:"); break; case T_VERSION: sync_end("VERSION:"); break; case T_TIMEZERO: { int vtok=get_token(); if((vtok==T_END)||(vtok==T_EOF)) break; time_zero=atoi_64(yytext); lt_set_timezero(lt, time_zero); sync_end(NULL); } break; case T_TIMESCALE: { int vtok; int i; char prefix=' '; int timelogadjust = 0; vtok=get_token(); if((vtok==T_END)||(vtok==T_EOF)) break; time_scale=atoi_64(yytext); if(!time_scale) time_scale=1; else if (time_scale == 10) timelogadjust = +1; else if (time_scale == 100) timelogadjust = +2; for(i=0;i'9')) { prefix=yytext[i]; break; } } if(prefix==' ') { vtok=get_token(); if((vtok==T_END)||(vtok==T_EOF)) break; prefix=yytext[0]; } switch(prefix) { case 's': case ' ': lt_set_timescale(lt, 0+timelogadjust); break; case 'm': lt_set_timescale(lt, -3+timelogadjust); break; case 'u': lt_set_timescale(lt, -6+timelogadjust); break; case 'n': lt_set_timescale(lt, -9+timelogadjust); break; case 'p': lt_set_timescale(lt, -12+timelogadjust); break; case 'f': lt_set_timescale(lt, -15+timelogadjust); break; default: /* unknown */ lt_set_timescale(lt, -9+timelogadjust); break; } sync_end(NULL); } break; case T_SCOPE: T_GET; T_GET; if(tok==T_STRING) { struct slist *s; s=(struct slist *)calloc_2(1,sizeof(struct slist)); s->len=yylen; s->str=(char *)malloc_2(yylen+1); strcpy(s->str,yytext); if(slistcurr) { slistcurr->next=s; slistcurr=s; } else { slistcurr=slistroot=s; } build_slisthier(); DEBUG(fprintf(stderr, "SCOPE: %s\n",slisthier)); } sync_end(NULL); break; case T_UPSCOPE: if(slistroot) { struct slist *s; s=slistroot; if(!s->next) { free_2(s->str); free_2(s); slistroot=slistcurr=NULL; } else for(;;) { if(!s->next->next) { free_2(s->next->str); free_2(s->next); s->next=NULL; slistcurr=s; break; } s=s->next; } build_slisthier(); DEBUG(fprintf(stderr, "SCOPE: %s\n",slisthier)); } sync_end(NULL); break; case T_VAR: { int vtok; struct vcdsymbol *v=NULL; var_prevch=0; if(varsplit) { free_2(varsplit); varsplit=NULL; } vtok=get_vartoken(1); if(vtok>V_PORT) goto bail; v=(struct vcdsymbol *)calloc_2(1,sizeof(struct vcdsymbol)); v->vartype=vtok; v->msi=v->lsi=vcd_explicit_zero_subscripts; /* indicate [un]subscripted status */ if(vtok==V_PORT) { vtok=get_vartoken(1); if(vtok==V_STRING) { v->size=atoi_64(yytext); if(!v->size) v->size=1; } else if(vtok==V_LB) { vtok=get_vartoken(1); if(vtok==V_END) goto err; if(vtok!=V_STRING) goto err; v->msi=atoi_64(yytext); vtok=get_vartoken(0); if(vtok==V_RB) { v->lsi=v->msi; v->size=1; } else { if(vtok!=V_COLON) goto err; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; v->lsi=atoi_64(yytext); vtok=get_vartoken(0); if(vtok!=V_RB) goto err; if(v->msi>v->lsi) { v->size=v->msi-v->lsi+1; } else { v->size=v->lsi-v->msi+1; } } } else goto err; vtok=get_strtoken(); if(vtok==V_END) goto err; v->id=(char *)malloc_2(yylen+1); strcpy(v->id, yytext); v->nid=vcdid_hash(yytext,yylen); if(v->nid < vcd_minid) vcd_minid = v->nid; if(v->nid > vcd_maxid) vcd_maxid = v->nid; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; if(slisthier_len) { v->name=(char *)malloc_2(slisthier_len+1+yylen+1); strcpy(v->name,slisthier); strcpy(v->name+slisthier_len,vcd_hier_delimeter); strcpy(v->name+slisthier_len+1,yytext); } else { v->name=(char *)malloc_2(yylen+1); strcpy(v->name,yytext); } } else /* regular vcd var, not an evcd port var */ { vtok=get_vartoken(1); if(vtok==V_END) goto err; v->size=atoi_64(yytext); vtok=get_strtoken(); if(vtok==V_END) goto err; v->id=(char *)malloc_2(yylen+1); strcpy(v->id, yytext); v->nid=vcdid_hash(yytext,yylen); if(v->nid < vcd_minid) vcd_minid = v->nid; if(v->nid > vcd_maxid) vcd_maxid = v->nid; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; if(slisthier_len) { v->name=(char *)malloc_2(slisthier_len+1+yylen+1); strcpy(v->name,slisthier); strcpy(v->name+slisthier_len,vcd_hier_delimeter); strcpy(v->name+slisthier_len+1,yytext); } else { v->name=(char *)malloc_2(yylen+1); strcpy(v->name,yytext); } vtok=get_vartoken(1); if(vtok==V_END) goto dumpv; if(vtok!=V_LB) goto err; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; v->msi=atoi_64(yytext); vtok=get_vartoken(0); if(vtok==V_RB) { v->lsi=v->msi; goto dumpv; } if(vtok!=V_COLON) goto err; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; v->lsi=atoi_64(yytext); vtok=get_vartoken(0); if(vtok!=V_RB) goto err; } dumpv: if(v->size == 0) { v->vartype = V_REAL; } /* MTI fix */ if(v->vartype==V_REAL) { v->size=1; /* override any data we parsed in */ v->msi=v->lsi=0; } else if((v->size>1)&&(v->msi<=0)&&(v->lsi<=0)) { if(v->vartype==V_EVENT) { v->size=1; } else { /* any criteria for the direction here? */ v->msi=v->size-1; v->lsi=0; } } else if((v->msi>v->lsi)&&((v->msi-v->lsi+1)!=v->size)) { if(v->vartype!=V_EVENT) goto err; v->size=v->msi-v->lsi+1; } else if((v->lsi>=v->msi)&&((v->lsi-v->msi+1)!=v->size)) { if(v->vartype!=V_EVENT) goto err; v->size=v->msi-v->lsi+1; } /* initial conditions */ v->value=(char *)malloc_2(v->size+1); v->value[v->size]=0; v->narray=(struct Node **)calloc_2(v->size,sizeof(struct Node *)); { int i; for(i=0;isize;i++) { v->value[i]='x'; v->narray[i]=(struct Node *)calloc_2(1,sizeof(struct Node)); v->narray[i]->head.time=-1; v->narray[i]->head.v.val=1; } } if(v->vartype==V_EVENT) { struct queuedevent *q; v->ev=q=(struct queuedevent *)calloc_2(1,sizeof(struct queuedevent)); q->sym=v; q->last_event_time=-1; q->next=queuedevents; queuedevents=q; } if(!vcdsymroot) { vcdsymroot=vcdsymcurr=v; } else { vcdsymcurr->next=v; vcdsymcurr=v; } numsyms++; #if 0 if((v->vartype==V_INTEGER)||(v->vartype==V_REAL)) { v->ltsym = lt_symbol_add(lt, v->name, 0, v->msi, v->lsi, (v->vartype==V_INTEGER)?LT_SYM_F_INTEGER:((v->vartype==V_REAL)?LT_SYM_F_DOUBLE:LT_SYM_F_BITS)); } else { char buf[65537]; if(v->msi==v->lsi) { sprintf(buf, "%s[%d]", v->name, v->msi); } else { sprintf(buf, "%s[%d:%d]", v->name, v->msi, v->lsi); } v->ltsym = lt_symbol_add(lt, buf, 0, v->msi, v->lsi, (v->vartype==V_INTEGER)?LT_SYM_F_INTEGER:((v->vartype==V_REAL)?LT_SYM_F_DOUBLE:LT_SYM_F_BITS)); } #endif DEBUG(fprintf(stderr,"VAR %s %d %s %s[%d:%d]\n", vartypes[v->vartype], v->size, v->id, v->name, v->msi, v->lsi)); goto bail; err: if(v) { if(v->name) free_2(v->name); if(v->id) free_2(v->id); if(v->value) free_2(v->value); free_2(v); } bail: if(vtok!=V_END) sync_end(NULL); break; } case T_ENDDEFINITIONS: if(!header_over) { header_over=1; /* do symbol table management here */ create_sorted_table(); if((!sorted)&&(!indexed)) { fprintf(stderr, "No symbols in VCD file..nothing to do!\n"); exit(1); } if(linear) lt_set_no_interlace(lt); } break; case T_STRING: if(header_over) { /* catchall for events when header over */ if(yytext[0]=='#') { TimeType t_time; t_time=atoi_64(yytext+1); if(start_time<0) { start_time=t_time; } if(t_time < current_time) /* avoid backtracking time counts which can happen on malformed files */ { t_time = current_time; } current_time=t_time; if(end_timecurr) { he=(struct HistEnt *)calloc_2(1,sizeof(struct HistEnt)); he->time=-1; he->v.val=1; n->curr=he; n->head.next=he; add_histent(t_time,n,ch,regadd, vector); } else { /* if(regadd) { t_time*=(time_scale); } */ /* scan-build : never read */ if(toupper((int)(unsigned char)ch)!=deadchar) n->notdead=1; n->numtrans++; } } else { if(ch=='g') /* real number */ { if(!n->curr) { he=(struct HistEnt *)calloc_2(1,sizeof(struct HistEnt)); he->time=-1; he->v.vector=NULL; n->curr=he; n->head.next=he; add_histent(t_time,n,ch,regadd, vector); } else { n->notdead=1; n->numtrans++; } } else { if(!n->curr) { he=(struct HistEnt *)calloc_2(1,sizeof(struct HistEnt)); he->time=-1; he->v.vector=NULL; n->curr=he; n->head.next=he; add_histent(t_time,n,ch,regadd, vector); } else { int i, nlen; nlen = strlen(vector); if(nlen) { n->numtrans++; for(i=0;inotdead=1; return; } } } } } } } static void add_tail_histents(void) { /* dump out any pending events 1st */ struct queuedevent *q; q=queuedevents; while(q) { struct vcdsymbol *v; v=q->sym; if(current_time!=(v->ev->last_event_time+1)) { /* dump degating event */ DEBUG(fprintf(stderr,"#"TTFormat" %s = '%c' (event)\n",v->ev->last_event_time+1,v->name,'0')); add_histent(v->ev->last_event_time+1,v->narray[0],'0',1, NULL); } q=q->next; } } /*******************************************************************************/ void vcd_sortfacs(void) { int i; facs=(struct symbol **)malloc_2(numfacs*sizeof(struct symbol *)); curnode=firstnode; for(i=0;iname; curnode=curnode->nextinaet; while((ch=(*subst))) { if(ch==hier_delimeter) { *subst=0x01; } /* forces sort at hier boundaries */ subst++; } } quicksort(facs,0,numfacs-1); for(i=0;iname; while((ch=(*subst))) { if(ch==0x01) { *subst=hier_delimeter; } /* restore back to normal */ subst++; } } for(i=0;in->substnode) { n=facs[i]->n; printf("[%c] [%5d] %s", facs[i]->n->notdead?' ':'*',facs[i]->n->numtrans,facs[i]->name); if(!facs[i]->n->notdead) { deadcnt++; } do_indent=0; } else { n=facs[i]->n->substnode; printf("[%c] [%5d] %s <-> %s", n->notdead?' ':'*',n->numtrans,facs[i]->name,n->nname); if(!n->notdead) { deadcnt++; } do_indent=1; } { n=n->substhead; while(n) { if(strcmp(n->nname, facs[i]->name)) { if(do_indent) { printf("\n\t\t\t"); } else { do_indent=1; } printf(" <-> %s",n->nname); } n=n->substhead; } printf("\n"); } } printf("\n[%d] total facilities: [%d] facilit%s defined, [%d] facilit%s undefined.\n\n", numfacs,numfacs-deadcnt,(numfacs-deadcnt!=1)?"ies":"y",deadcnt, (deadcnt!=1)?"ies":"y"); } /*******************************************************************************/ TimeType vcd_main(char *fname, char *lxname, int dostats, int doclock, int dochg, int dodict, int linear) { struct vcdsymbol *v, *v2; vcd_hier_delimeter[0]=hier_delimeter; errno=0; /* reset in case it's set for some reason */ yytext=(char *)malloc_2(T_MAX_STR+1); if((strlen(fname)>2)&&(!strcmp(fname+strlen(fname)-3,".gz"))) { char *str; int dlen; dlen=strlen(WAVE_DECOMPRESSOR); str=(char *)wave_alloca(strlen(fname)+dlen+1); strcpy(str,WAVE_DECOMPRESSOR); strcpy(str+dlen,fname); vcd_handle=popen(str,"r"); vcd_is_compressed=~0; } else { if(strcmp("-",fname)) { vcd_handle=fopen(fname,"rb"); } else { vcd_handle=stdin; } vcd_is_compressed=0; } if(!vcd_handle) { fprintf(stderr, "Error opening %s .vcd file '%s'.\n", vcd_is_compressed?"compressed":"", fname); exit(1); } lt=lt_init(lxname); if(!lt) { fprintf(stderr, "Problem opening output file '%s'\n", lxname); perror("Why"); exit(255); } if(doclock) lt_set_clock_compress(lt); if(dochg) lt_set_chg_compress(lt); if(dodict) lt_set_dict_compress(lt, dodict); lt_set_initial_value(lt, 'x'); lt_symbol_bracket_stripping(lt, 1); /* this is intentional */ sym=(struct symbol **)calloc_2(SYMPRIME,sizeof(struct symbol *)); printf("\nConverting VCD File '%s' to LXT file '%s'...\n\n",(vcd_handle!=stdin)?fname:"from stdin", lxname); build_slisthier(); vcd_parse(linear); if(varsplit) { free_2(varsplit); varsplit=NULL; } add_tail_histents(); printf("["TTFormat"] start time.\n["TTFormat"] end time.\n\n", start_time, end_time); lt_close(lt); lt=NULL; if (dostats) vcd_sortfacs(); min_time=start_time*time_scale; max_time=end_time*time_scale; if((min_time==max_time)||(max_time==0)) { fprintf(stderr, "VCD times range is equal to zero. Exiting.\n"); exit(1); } if(vcd_handle!=stdin) { fclose(vcd_handle); vcd_handle=NULL; } free(yytext); yytext=NULL; if(indexed) { free(indexed); indexed=NULL; } if(sorted) { free(sorted); sorted=NULL; } v=vcdsymroot; while(v) { if(v->name) { free(v->name); v->name=NULL; } if(v->id) { free(v->id); v->id=NULL; } if(v->value) { free(v->value); v->value=NULL; } if(v->narray) { int i; for(i=0;isize;i++) { struct HistEnt *h1, *h2; if((h1 = v->narray[i]->head.next)) { while(h1) { h2 = h1->next; free(h1); h1 = h2; } } free(v->narray[i]); v->narray[i]=NULL; } free(v->narray); v->narray=NULL; } v2=v->next; free(v); v=v2; } vcdsymroot=vcdsymcurr=NULL; free(sym); sym=NULL; if(slisthier) { free(slisthier); slisthier=NULL; } return(max_time); } /*******************************************************************************/ /* * Generic hash function for symbol names... */ int hash(char *s) { char *p; unsigned int h=0, g; for(p=s;*p;p++) { h=(h<<4)+(*p); if((g=h&0xf0000000)) { h=h^(g>>24); h=h^g; } } return(h%SYMPRIME); } /* * add symbol to table. no duplicate checking * is necessary as aet's are "correct." */ struct symbol *symadd(char *name, int hv) { struct symbol *s; s=(struct symbol *)calloc_2(1,sizeof(struct symbol)); strcpy(s->name=(char *)malloc_2(strlen(name)+1),name); s->next=sym[hv]; sym[hv]=s; return(s); } /* * find a slot already in the table... */ struct symbol *symfind(char *s) { int hv; struct symbol *temp; hv=hash(s); if(!(temp=sym[hv])) return(NULL); /* no hash entry, add here wanted to add */ while(temp) { if(!strcmp(temp->name,s)) { return(temp); /* in table already */ } if(!temp->next) break; temp=temp->next; } return(NULL); /* not found, add here if you want to add*/ } int sigcmp(char *s1, char *s2) { unsigned char c1, c2; int u1, u2; for(;;) { c1=(unsigned char)*(s1++); c2=(unsigned char)*(s2++); if((!c1)&&(!c2)) return(0); if((c1<='9')&&(c2<='9')&&(c2>='0')&&(c1>='0')) { u1=(int)(c1&15); u2=(int)(c2&15); while(((c2=(unsigned char)*s2)>='0')&&(c2<='9')) { u2*=10; u2+=(unsigned int)(c2&15); s2++; } while(((c2=(unsigned char)*s1)>='0')&&(c2<='9')) { u1*=10; u1+=(unsigned int)(c2&15); s1++; } if(u1==u2) continue; else return((int)u1-(int)u2); } else { if(c1!=c2) return((int)c1-(int)c2); } } } int partition(struct symbol **a, int p, int r) { struct symbol *x, *t; int i,j; x=a[p]; i=p-1; j=r+1; while(1) { do { j--; } while(sigcmp(a[j]->name,x->name)>0); do { i++; } while(sigcmp(a[i]->name,x->name)<0); if(i=3) { for(i=3;i #include #if HAVE_STDINT_H #include #endif #include #include #include #include "ghwlib.h" #include "wave_locale.h" static const char *progname; void usage (void) { printf ("usage: %s [OPTIONS] FILEs...\n", progname); printf ("Options are:\n" " -t display types\n" " -h display hierarchy\n" " -T display time\n" " -s display signals (and time)\n" " -l display list of sections\n" " -v verbose\n"); } int main (int argc, char **argv) { int i; int flag_disp_types; int flag_disp_hierarchy; int flag_disp_time; int flag_disp_signals; int flag_list; int flag_verbose; int eof; enum ghw_sm_type sm; progname = argv[0]; flag_disp_types = 0; flag_disp_hierarchy = 0; flag_disp_time = 0; flag_disp_signals = 0; flag_list = 0; flag_verbose = 0; WAVE_LOCALE_FIX while (1) { int c; c = getopt (argc, argv, "thTslv"); if (c == -1) break; switch (c) { case 't': flag_disp_types = 1; break; case 'h': flag_disp_hierarchy = 1; break; case 'T': flag_disp_time = 1; break; case 's': flag_disp_signals = 1; flag_disp_time = 1; break; case 'l': flag_list = 1; break; case 'v': flag_verbose++; break; default: usage (); exit (2); } } if (optind >= argc) { usage (); return 1; } for (i = optind; i < argc; i++) { struct ghw_handler h; struct ghw_handler *hp = &h; hp->flag_verbose = flag_verbose; if (ghw_open (hp, argv[i]) != 0) { fprintf (stderr, "cannot open ghw file %s\n", argv[i]); return 1; } if (flag_list) { while (1) { int section; section = ghw_read_section (hp); if (section == -2) { printf ("eof of file\n"); break; } else if (section < 0) { printf ("Error in file\n"); break; } else if (section == 0) { printf ("Unknown section\n"); break; } printf ("Section %s\n", ghw_sections[section].name); if ((*ghw_sections[section].handler)(hp) < 0) break; } } else { if (ghw_read_base (hp) < 0) { fprintf (stderr, "cannot read ghw file\n"); return 2; } if (0) { int ix; printf ("String table:\n"); for (ix = 1; ix < hp->nbr_str; ix++) printf (" %s\n", hp->str_table[ix]); } if (flag_disp_types) ghw_disp_types (hp); if (flag_disp_hierarchy) ghw_disp_hie (hp, hp->hie); #if 1 sm = ghw_sm_init; eof = 0; while (!eof) { switch (ghw_read_sm (hp, &sm)) { case ghw_res_snapshot: case ghw_res_cycle: if (flag_disp_time) printf ("Time is "GHWLLD" fs\n", hp->snap_time); if (flag_disp_signals) ghw_disp_values (hp); break; case ghw_res_eof: eof = 1; break; default: abort (); } } #else if (ghw_read_dump (hp) < 0) { fprintf (stderr, "error in ghw dump\n"); return 3; } #endif } ghw_close (&h); } return 0; } gtkwave-3.3.66/src/helpers/vcd2lxt2.c0000664000076400007640000012715612341266475016672 0ustar bybellbybell/* * Copyright (c) 2001-2014 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ /* * vcd.c 23jan99ajb * evcd parts 29jun99ajb * profiler optimizations 15jul99ajb * stripped out of gtkwave 21jul99ajb * fix for duplicate nets 19dec00ajb * lxt conversion added 20nov01ajb */ #if defined _AIX #pragma alloca #endif #include #include #include "v2l_analyzer_lxt2.h" #include "lxt2_write.h" #include "wave_locale.h" #undef VCD_BSEARCH_IS_PERFECT /* bsearch is imperfect under linux, but OK under AIX */ struct lxt2_wr_trace *lt=NULL; int numfacs=0; int deadcnt=0; int opt_depth = 4; uint64_t opt_break_size = 0; int opt_partial_mode = -1; int opt_checkpoint_disable = 0; int opt_maxgranule = 8; struct symbol **sym=NULL; struct symbol **facs=NULL; struct symbol *firstnode=NULL; struct symbol *curnode=NULL; TimeType min_time=-1, max_time=-1; char hier_delimeter='.'; char deadchar='X'; int vcd_explicit_zero_subscripts=-1; /* 0=yes, -1=no */ char atomic_vectors=1; static FILE *vcd_handle=NULL; static char vcd_is_compressed=0; static void add_histent(TimeType time, struct Node *n, char ch, int regadd, char *vector); static void add_tail_histents(void); static void evcd_strcpy(char *dst, char *src); static int vcdlineno=1; static int header_over=0; static int dumping_off=0; static TimeType start_time=-1; static TimeType end_time=-1; static TimeType current_time=-1; static TimeType time_scale=1; /* multiplier is 1, 10, 100 */ static TimeType time_zero=0; static char vcd_hier_delimeter[2]={0, 0}; /* fill in after rc reading code */ /******************************************************************/ static struct slist *slistroot=NULL, *slistcurr=NULL; static char *slisthier=NULL; static int slisthier_len=0; /******************************************************************/ enum Tokens { T_VAR, T_END, T_SCOPE, T_UPSCOPE, T_COMMENT, T_DATE, T_DUMPALL, T_DUMPOFF, T_DUMPON, T_DUMPVARS, T_ENDDEFINITIONS, T_DUMPPORTS, T_DUMPPORTSOFF, T_DUMPPORTSON, T_DUMPPORTSALL, T_TIMESCALE, T_VERSION, T_VCDCLOSE, T_TIMEZERO, T_EOF, T_STRING, T_UNKNOWN_KEY }; char *tokens[]={ "var", "end", "scope", "upscope", "comment", "date", "dumpall", "dumpoff", "dumpon", "dumpvars", "enddefinitions", "dumpports", "dumpportsoff", "dumpportson", "dumpportsall", "timescale", "version", "vcdclose", "timezero", "", "", "" }; #define NUM_TOKENS 19 static int T_MAX_STR=1024; /* was originally a const..now it reallocs */ static char *yytext=NULL; static int yylen=0, yylen_cache=0; #define T_GET tok=get_token();if((tok==T_END)||(tok==T_EOF))break; /******************************************************************/ static struct vcdsymbol *vcdsymroot=NULL, *vcdsymcurr=NULL; static struct vcdsymbol **sorted=NULL; static struct vcdsymbol **indexed=NULL; enum VarTypes { V_EVENT, V_PARAMETER, V_INTEGER, V_REAL, V_REAL_PARAMETER=V_REAL, V_REALTIME=V_REAL, V_STRINGTYPE=V_REAL, V_REG, V_SUPPLY0, V_SUPPLY1, V_TIME, V_TRI, V_TRIAND, V_TRIOR, V_TRIREG, V_TRI0, V_TRI1, V_WAND, V_WIRE, V_WOR, V_PORT, V_IN=V_PORT, V_OUT=V_PORT, V_INOUT=V_PORT, V_END, V_LB, V_COLON, V_RB, V_STRING }; static char *vartypes[]={ "event", "parameter", "integer", "real", "real_parameter", "realtime", "string", "reg", "supply0", "supply1", "time", "tri", "triand", "trior", "trireg", "tri0", "tri1", "wand", "wire", "wor", "port", "in", "out", "inout", "$end", "", "", "", ""}; static const unsigned char varenums[] = { V_EVENT, V_PARAMETER, V_INTEGER, V_REAL, V_REAL_PARAMETER, V_REALTIME, V_STRINGTYPE, V_REG, V_SUPPLY0, V_SUPPLY1, V_TIME, V_TRI, V_TRIAND, V_TRIOR, V_TRIREG, V_TRI0, V_TRI1, V_WAND, V_WIRE, V_WOR, V_PORT, V_IN, V_OUT, V_INOUT, V_END, V_LB, V_COLON, V_RB, V_STRING }; #define NUM_VTOKENS 25 static int numsyms=0; /******************************************************************/ static struct queuedevent *queuedevents=NULL; /******************************************************************/ static unsigned int vcd_minid = ~0; static unsigned int vcd_maxid = 0; static unsigned int vcdid_hash(char *s, int len) { unsigned int val=0; int i; s+=(len-1); for(i=0;iid)); } /* * actual bsearch */ static struct vcdsymbol *bsearch_vcd(char *key, int len) { struct vcdsymbol **v; struct vcdsymbol *t; if(indexed) { unsigned int hsh = vcdid_hash(key, len); if((hsh>=vcd_minid)&&(hsh<=vcd_maxid)) { return(indexed[hsh-vcd_minid]); } } v=(struct vcdsymbol **)bsearch(key, sorted, numsyms, sizeof(struct vcdsymbol *), vcdsymbsearchcompare); if(v) { #ifndef VCD_BSEARCH_IS_PERFECT for(;;) { t=*v; if((v==sorted)||(strcmp((*(--v))->id, key))) { return(t); } } #else return(*v); #endif } else { return(NULL); } } /* * sort on vcdsymbol pointers */ static int vcdsymcompare(const void *s1, const void *s2) { struct vcdsymbol *v1, *v2; v1=*((struct vcdsymbol **)s1); v2=*((struct vcdsymbol **)s2); return(strcmp(v1->id, v2->id)); } /* * alias vs normal symbol adding */ static void alias_vs_normal_symadd(struct vcdsymbol *v, struct vcdsymbol *root_v) { if(!v) return; /* scan-build : should never happen */ if(!root_v) { if((v->vartype==V_INTEGER)||(v->vartype==V_REAL)) { v->ltsym = lxt2_wr_symbol_add(lt, v->name, 0, v->msi, v->lsi, (v->vartype==V_INTEGER)?LXT2_WR_SYM_F_INTEGER:((v->vartype==V_REAL)?LXT2_WR_SYM_F_DOUBLE:LXT2_WR_SYM_F_BITS)); } else { char buf[65537]; if(v->msi==v->lsi) { sprintf(buf, "%s[%d]", v->name, v->msi); } else { sprintf(buf, "%s[%d:%d]", v->name, v->msi, v->lsi); } v->ltsym = lxt2_wr_symbol_add(lt, buf, 0, v->msi, v->lsi, (v->vartype==V_INTEGER)?LXT2_WR_SYM_F_INTEGER:((v->vartype==V_REAL)?LXT2_WR_SYM_F_DOUBLE:LXT2_WR_SYM_F_BITS)); } } else { if((v->vartype==V_INTEGER)||(v->vartype==V_REAL)) { lxt2_wr_symbol_alias(lt, root_v->name, v->name, v->msi, v->lsi); } else { char bufold[65537], buf[65537]; if(v->msi==v->lsi) { sprintf(bufold, "%s[%d]", root_v->name, root_v->msi); sprintf(buf, "%s[%d]", v->name, v->msi); } else { sprintf(bufold, "%s[%d:%d]", root_v->name, root_v->msi, root_v->lsi); sprintf(buf, "%s[%d:%d]", v->name, v->msi, v->lsi); } lxt2_wr_symbol_alias(lt, bufold, buf, v->msi, v->lsi); } } } /* * create sorted (by id) table */ static void create_sorted_table(void) { struct vcdsymbol *v; struct vcdsymbol **pnt; unsigned int vcd_distance; struct vcdsymbol *root_v; int i; if(numsyms) { vcd_distance = vcd_maxid - vcd_minid + 1; if(vcd_distance <= 8 * 1024 * 1024) { indexed = (struct vcdsymbol **)calloc_2(vcd_distance, sizeof(struct vcdsymbol *)); printf("%d symbols span ID range of %d, using indexing...\n", numsyms, vcd_distance); v=vcdsymroot; while(v) { if(!(root_v=indexed[v->nid - vcd_minid])) { indexed[v->nid - vcd_minid] = v; } alias_vs_normal_symadd(v, root_v); v=v->next; } } else { pnt=sorted=(struct vcdsymbol **)calloc_2(numsyms, sizeof(struct vcdsymbol *)); v=vcdsymroot; while(v) { *(pnt++)=v; v=v->next; } qsort(sorted, numsyms, sizeof(struct vcdsymbol *), vcdsymcompare); root_v = NULL; for(i=0;iname); v->name = NULL; v=v->next; } } } /******************************************************************/ /* * single char get */ static int getch(void) { int ch; ch=fgetc(vcd_handle); if(ch=='\n') vcdlineno++; return(((ch==EOF)||(errno))?(-1):(ch)); } static int getch_peek(void) { int ch; ch=fgetc(vcd_handle); ungetc(ch, vcd_handle); return(((ch==EOF)||(errno))?(-1):(ch)); } static char *varsplit=NULL, *vsplitcurr=NULL; static int getch_patched(void) { char ch; ch=*vsplitcurr; if(!ch) { return(-1); } else { vsplitcurr++; return((int)ch); } } /* * simple tokenizer */ static int get_token(void) { int ch; int i, len=0; int is_string=0; char *yyshadow; for(;;) { ch=getch(); if(ch<0) return(T_EOF); if(ch<=' ') continue; /* val<=' ' is a quick whitespace check */ break; /* (take advantage of fact that vcd is text) */ } if(ch=='$') { yytext[len++]=ch; for(;;) { ch=getch(); if(ch<0) return(T_EOF); if(ch<=' ') continue; break; } } else { is_string=1; } for(yytext[len++]=ch;;yytext[len++]=ch) { if(len==T_MAX_STR) { yytext=(char *)realloc_2(yytext, (T_MAX_STR=T_MAX_STR*2)+1); } ch=getch(); if(ch<=' ') break; } yytext[len]=0; /* terminator */ if(is_string) { yylen=len; return(T_STRING); } yyshadow=yytext; do { yyshadow++; for(i=0;iw #implicit-var###VarElem:ram_di[0.0] [63:0] $end' style declarations */ { /* debussy simply escapes until the space */ yytext[len++]= '\\'; } for(yytext[len++]=ch;;yytext[len++]=ch) { if(len==T_MAX_STR) { yytext=(char *)realloc_2(yytext, (T_MAX_STR=T_MAX_STR*2)+1); } ch=getch(); if(ch==' ') { if(match_kw) break; if(getch_peek() == '[') { ch = getch(); varsplit=yytext+len; /* keep looping so we get the *last* one */ continue; } } if((ch==' ')||(ch=='\t')||(ch=='\n')||(ch=='\r')||(ch<0)) break; if((ch=='[')&&(yytext[0]!='\\')) { varsplit=yytext+len; /* keep looping so we get the *last* one */ } else if(((ch==':')||(ch==']'))&&(!varsplit)&&(yytext[0]!='\\')) { var_prevch=ch; break; } } yytext[len]=0; /* absolute terminator */ if((varsplit)&&(yytext[len-1]==']')) { char *vst; vst=malloc_2(strlen(varsplit)+1); strcpy(vst, varsplit); *varsplit=0x00; /* zero out var name at the left bracket */ len=varsplit-yytext; varsplit=vsplitcurr=vst; var_prevch=0; } else { varsplit=NULL; } if(match_kw) for(i=0;ilen+(s->next?1:0); s=s->next; } if(slisthier) { free_2(slisthier); } slisthier=(char *)malloc_2((slisthier_len=len)+1); s=slistroot; len=0; while(s) { strcpy(slisthier+len,s->str); len+=s->len; if(s->next) { strcpy(slisthier+len,vcd_hier_delimeter); len++; } s=s->next; } return(slisthier); } void append_vcd_slisthier(char *str) { struct slist *s; s=(struct slist *)calloc_2(1,sizeof(struct slist)); s->len=strlen(str); s->str=(char *)malloc_2(s->len+1); strcpy(s->str,str); if(slistcurr) { slistcurr->next=s; slistcurr=s; } else { slistcurr=slistroot=s; } build_slisthier(); DEBUG(fprintf(stderr, "SCOPE: %s\n",slisthier)); } static void parse_valuechange(void) { struct vcdsymbol *v; char *vector; int vlen; switch(yytext[0]) { case '0': case '1': case 'x': case 'X': case 'z': case 'Z': case 'h': case 'H': case 'u': case 'U': case 'w': case 'W': case 'l': case 'L': case '-': if(yylen>1) { v=bsearch_vcd(yytext+1, yylen-1); if(!v) { fprintf(stderr,"Near line %d, Unknown VCD identifier: '%s'\n",vcdlineno,yytext+1); } else { if(v->vartype!=V_EVENT) { char vl[2]; vl[0]=yytext[0]; vl[1]=0; lxt2_wr_emit_value_bit_string(lt, v->ltsym, 0, vl); v->value[0]=yytext[0]; DEBUG(fprintf(stderr,"%s = '%c'\n",v->name,v->value[0])); add_histent(current_time,v->narray[0],v->value[0],1, NULL); } else { char vl[2]; v->value[0]=(dumping_off)?'x':'1'; /* only '1' is relevant */ if(current_time!=(v->ev->last_event_time+1)) { /* dump degating event */ DEBUG(fprintf(stderr,"#"TTFormat" %s = '%c' (event)\n",v->ev->last_event_time+1,v->name,'0')); add_histent(v->ev->last_event_time+1,v->narray[0],'0',1, NULL); } DEBUG(fprintf(stderr,"%s = '%c' (event)\n",v->name,v->value[0])); add_histent(current_time,v->narray[0],v->value[0],1, NULL); vl[0]='1'; vl[1]=0; lxt2_wr_emit_value_bit_string(lt, v->ltsym, 0, vl); vl[0]='0'; vl[1]=0; lxt2_wr_emit_value_bit_string(lt, v->ltsym, 0, vl); v->ev->last_event_time=current_time; } } } else { fprintf(stderr,"Near line %d, Malformed VCD identifier\n", vcdlineno); } break; case 'b': case 'B': /* extract binary number then.. */ vector=malloc_2(yylen_cache=yylen); strcpy(vector,yytext+1); vlen=yylen-1; get_strtoken(); v=bsearch_vcd(yytext, yylen); if(!v) { fprintf(stderr,"Near line %d, Unknown identifier: '%s'\n",vcdlineno, yytext); free_2(vector); } else { if(vlensize) /* fill in left part */ { char extend; int i, fill; extend=(vector[0]=='1')?'0':vector[0]; fill=v->size-vlen; for(i=0;ivalue[i]=extend; } strcpy(v->value+fill,vector); } else if(vlen==v->size) /* straight copy */ { strcpy(v->value,vector); } else /* too big, so copy only right half */ { int skip; skip=vlen-v->size; strcpy(v->value,vector+skip); } DEBUG(fprintf(stderr,"%s = '%s'\n",v->name, v->value)); lxt2_wr_emit_value_bit_string(lt, v->ltsym, 0, v->value); if((v->size==1)||(!atomic_vectors)) { int i; for(i=0;isize;i++) { add_histent(current_time, v->narray[i],v->value[i],1, NULL); } free_2(vector); } else { if(yylen_cache!=(v->size+1)) { free_2(vector); vector=malloc_2(v->size+1); } strcpy(vector,v->value); add_histent(current_time, v->narray[0],0,1,vector); free_2(vector); } } break; case 'p': /* extract port dump value.. */ vector=malloc_2(yylen_cache=yylen); strcpy(vector,yytext+1); vlen=yylen-1; get_strtoken(); /* throw away 0_strength_component */ get_strtoken(); /* throw away 0_strength_component */ get_strtoken(); /* this is the id */ v=bsearch_vcd(yytext, yylen); if(!v) { fprintf(stderr,"Near line %d, Unknown identifier: '%s'\n",vcdlineno, yytext); free_2(vector); } else { if(vlensize) /* fill in left part */ { char extend; int i, fill; extend='0'; fill=v->size-vlen; for(i=0;ivalue[i]=extend; } evcd_strcpy(v->value+fill,vector); } else if(vlen==v->size) /* straight copy */ { evcd_strcpy(v->value,vector); } else /* too big, so copy only right half */ { int skip; skip=vlen-v->size; evcd_strcpy(v->value,vector+skip); } DEBUG(fprintf(stderr,"%s = '%s'\n",v->name, v->value)); lxt2_wr_emit_value_bit_string(lt, v->ltsym, 0, v->value); if((v->size==1)||(!atomic_vectors)) { int i; for(i=0;isize;i++) { add_histent(current_time, v->narray[i],v->value[i],1, NULL); } free_2(vector); } else { if(yylen_cachesize) { free_2(vector); vector=malloc_2(v->size+1); } strcpy(vector,v->value); add_histent(current_time, v->narray[0],0,1,vector); free_2(vector); } } break; case 'r': case 'R': { double *d; d=malloc_2(sizeof(double)); *d = 0; sscanf(yytext+1,"%lg",d); errno = 0; get_strtoken(); v=bsearch_vcd(yytext, yylen); if(!v) { fprintf(stderr,"Near line %d, Unknown identifier: '%s'\n",vcdlineno, yytext); free_2(d); } else { lxt2_wr_emit_value_double(lt, v->ltsym, 0, *d); add_histent(current_time, v->narray[0],'g',1,(char *)d); free_2(d); } break; } case 's': case 'S': { get_strtoken(); /* simply skip for now */ break; } } } static void evcd_strcpy(char *dst, char *src) { static const char *evcd="DUNZduLHXTlh01?FAaBbCcf"; static const char *vcd="01xz0101xz0101xzxxxxxxz"; char ch; int i; while((ch=*src)) { for(i=0;i<23;i++) { if(evcd[i]==ch) { *dst=vcd[i]; break; } } if(i==23) *dst='x'; src++; dst++; } *dst=0; /* null terminate destination */ } static void vcd_parse(void) { int tok; for(;;) { switch(get_token()) { case T_COMMENT: sync_end("COMMENT:"); break; case T_DATE: sync_end("DATE:"); break; case T_VERSION: sync_end("VERSION:"); break; case T_TIMEZERO: { int vtok=get_token(); if((vtok==T_END)||(vtok==T_EOF)) break; time_zero=atoi_64(yytext); lxt2_wr_set_timezero(lt, time_zero); sync_end(NULL); } break; case T_TIMESCALE: { int vtok; int i; char prefix=' '; int timelogadjust = 0; vtok=get_token(); if((vtok==T_END)||(vtok==T_EOF)) break; time_scale=atoi_64(yytext); if(!time_scale) time_scale=1; else if (time_scale == 10) timelogadjust = +1; else if (time_scale == 100) timelogadjust = +2; for(i=0;i'9')) { prefix=yytext[i]; break; } } if(prefix==' ') { vtok=get_token(); if((vtok==T_END)||(vtok==T_EOF)) break; prefix=yytext[0]; } switch(prefix) { case 's': case ' ': lxt2_wr_set_timescale(lt, 0+timelogadjust); break; case 'm': lxt2_wr_set_timescale(lt, -3+timelogadjust); break; case 'u': lxt2_wr_set_timescale(lt, -6+timelogadjust); break; case 'n': lxt2_wr_set_timescale(lt, -9+timelogadjust); break; case 'p': lxt2_wr_set_timescale(lt, -12+timelogadjust); break; case 'f': lxt2_wr_set_timescale(lt, -15+timelogadjust); break; default: /* unknown */ lxt2_wr_set_timescale(lt, -9+timelogadjust); break; } sync_end(NULL); } break; case T_SCOPE: T_GET; T_GET; if(tok==T_STRING) { struct slist *s; s=(struct slist *)calloc_2(1,sizeof(struct slist)); s->len=yylen; s->str=(char *)malloc_2(yylen+1); strcpy(s->str,yytext); if(slistcurr) { slistcurr->next=s; slistcurr=s; } else { slistcurr=slistroot=s; } build_slisthier(); DEBUG(fprintf(stderr, "SCOPE: %s\n",slisthier)); } sync_end(NULL); break; case T_UPSCOPE: if(slistroot) { struct slist *s; s=slistroot; if(!s->next) { free_2(s->str); free_2(s); slistroot=slistcurr=NULL; } else for(;;) { if(!s->next->next) { free_2(s->next->str); free_2(s->next); s->next=NULL; slistcurr=s; break; } s=s->next; } build_slisthier(); DEBUG(fprintf(stderr, "SCOPE: %s\n",slisthier)); } sync_end(NULL); break; case T_VAR: { int vtok; struct vcdsymbol *v=NULL; var_prevch=0; if(varsplit) { free_2(varsplit); varsplit=NULL; } vtok=get_vartoken(1); if(vtok>V_PORT) goto bail; v=(struct vcdsymbol *)calloc_2(1,sizeof(struct vcdsymbol)); v->vartype=vtok; v->msi=v->lsi=vcd_explicit_zero_subscripts; /* indicate [un]subscripted status */ if(vtok==V_PORT) { vtok=get_vartoken(1); if(vtok==V_STRING) { v->size=atoi_64(yytext); if(!v->size) v->size=1; } else if(vtok==V_LB) { vtok=get_vartoken(1); if(vtok==V_END) goto err; if(vtok!=V_STRING) goto err; v->msi=atoi_64(yytext); vtok=get_vartoken(0); if(vtok==V_RB) { v->lsi=v->msi; v->size=1; } else { if(vtok!=V_COLON) goto err; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; v->lsi=atoi_64(yytext); vtok=get_vartoken(0); if(vtok!=V_RB) goto err; if(v->msi>v->lsi) { v->size=v->msi-v->lsi+1; } else { v->size=v->lsi-v->msi+1; } } } else goto err; vtok=get_strtoken(); if(vtok==V_END) goto err; v->id=(char *)malloc_2(yylen+1); strcpy(v->id, yytext); v->nid=vcdid_hash(yytext,yylen); if(v->nid < vcd_minid) vcd_minid = v->nid; if(v->nid > vcd_maxid) vcd_maxid = v->nid; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; if(slisthier_len) { v->name=(char *)malloc_2(slisthier_len+1+yylen+1); strcpy(v->name,slisthier); strcpy(v->name+slisthier_len,vcd_hier_delimeter); strcpy(v->name+slisthier_len+1,yytext); } else { v->name=(char *)malloc_2(yylen+1); strcpy(v->name,yytext); } } else /* regular vcd var, not an evcd port var */ { vtok=get_vartoken(1); if(vtok==V_END) goto err; v->size=atoi_64(yytext); vtok=get_strtoken(); if(vtok==V_END) goto err; v->id=(char *)malloc_2(yylen+1); strcpy(v->id, yytext); v->nid=vcdid_hash(yytext,yylen); if(v->nid < vcd_minid) vcd_minid = v->nid; if(v->nid > vcd_maxid) vcd_maxid = v->nid; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; if(slisthier_len) { v->name=(char *)malloc_2(slisthier_len+1+yylen+1); strcpy(v->name,slisthier); strcpy(v->name+slisthier_len,vcd_hier_delimeter); strcpy(v->name+slisthier_len+1,yytext); } else { v->name=(char *)malloc_2(yylen+1); strcpy(v->name,yytext); } vtok=get_vartoken(1); if(vtok==V_END) goto dumpv; if(vtok!=V_LB) goto err; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; v->msi=atoi_64(yytext); vtok=get_vartoken(0); if(vtok==V_RB) { v->lsi=v->msi; goto dumpv; } if(vtok!=V_COLON) goto err; vtok=get_vartoken(0); if(vtok!=V_STRING) goto err; v->lsi=atoi_64(yytext); vtok=get_vartoken(0); if(vtok!=V_RB) goto err; } dumpv: if(v->size == 0) { v->vartype = V_REAL; } /* MTI fix */ if(v->vartype==V_REAL) { v->size=1; /* override any data we parsed in */ v->msi=v->lsi=0; } else if((v->size>1)&&(v->msi<=0)&&(v->lsi<=0)) { if(v->vartype==V_EVENT) { v->size=1; } else { /* any criteria for the direction here? */ v->msi=v->size-1; v->lsi=0; } } else if((v->msi>v->lsi)&&((v->msi-v->lsi+1)!=v->size)) { if(v->vartype!=V_EVENT) goto err; v->size=v->msi-v->lsi+1; } else if((v->lsi>=v->msi)&&((v->lsi-v->msi+1)!=v->size)) { if(v->vartype!=V_EVENT) goto err; v->size=v->msi-v->lsi+1; } /* initial conditions */ v->value=(char *)malloc_2(v->size+1); v->value[v->size]=0; v->narray=(struct Node **)calloc_2(v->size,sizeof(struct Node *)); { int i; for(i=0;isize;i++) { v->value[i]='x'; v->narray[i]=(struct Node *)calloc_2(1,sizeof(struct Node)); v->narray[i]->head.time=-1; v->narray[i]->head.v.val=1; } } if(v->vartype==V_EVENT) { struct queuedevent *q; v->ev=q=(struct queuedevent *)calloc_2(1,sizeof(struct queuedevent)); q->sym=v; q->last_event_time=-1; q->next=queuedevents; queuedevents=q; } if(!vcdsymroot) { vcdsymroot=vcdsymcurr=v; } else { vcdsymcurr->next=v; vcdsymcurr=v; } numsyms++; #if 0 if((v->vartype==V_INTEGER)||(v->vartype==V_REAL)) { v->ltsym = lxt2_wr_symbol_add(lt, v->name, 0, v->msi, v->lsi, (v->vartype==V_INTEGER)?LXT2_WR_SYM_F_INTEGER:((v->vartype==V_REAL)?LXT2_WR_SYM_F_DOUBLE:LXT2_WR_SYM_F_BITS)); } else { char buf[65537]; if(v->msi==v->lsi) { sprintf(buf, "%s[%d]", v->name, v->msi); } else { sprintf(buf, "%s[%d:%d]", v->name, v->msi, v->lsi); } v->ltsym = lxt2_wr_symbol_add(lt, buf, 0, v->msi, v->lsi, (v->vartype==V_INTEGER)?LXT2_WR_SYM_F_INTEGER:((v->vartype==V_REAL)?LXT2_WR_SYM_F_DOUBLE:LXT2_WR_SYM_F_BITS)); } #endif DEBUG(fprintf(stderr,"VAR %s %d %s %s[%d:%d]\n", vartypes[v->vartype], v->size, v->id, v->name, v->msi, v->lsi)); goto bail; err: if(v) { if(v->name) free_2(v->name); if(v->id) free_2(v->id); if(v->value) free_2(v->value); free_2(v); } bail: if(vtok!=V_END) sync_end(NULL); break; } case T_ENDDEFINITIONS: if(!header_over) { header_over=1; /* do symbol table management here */ create_sorted_table(); if((!sorted)&&(!indexed)) { fprintf(stderr, "No symbols in VCD file..nothing to do!\n"); exit(1); } } break; case T_STRING: if(header_over) { /* catchall for events when header over */ if(yytext[0]=='#') { TimeType t_time; t_time=atoi_64(yytext+1); if(start_time<0) { start_time=t_time; } if(t_time < current_time) /* avoid backtracking time counts which can happen on malformed files */ { t_time = current_time; } current_time=t_time; if(end_timecurr) { he=(struct HistEnt *)calloc_2(1,sizeof(struct HistEnt)); he->time=-1; he->v.val=1; n->curr=he; n->head.next=he; add_histent(t_time,n,ch,regadd, vector); } else { /* if(regadd) { t_time*=(time_scale); } */ /* scan-build : never read */ if(toupper((int)(unsigned char)ch)!=deadchar) n->notdead=1; n->numtrans++; } } else { if(ch=='g') /* real number */ { if(!n->curr) { he=(struct HistEnt *)calloc_2(1,sizeof(struct HistEnt)); he->time=-1; he->v.vector=NULL; n->curr=he; n->head.next=he; add_histent(t_time,n,ch,regadd, vector); } else { n->notdead=1; n->numtrans++; } } else { if(!n->curr) { he=(struct HistEnt *)calloc_2(1,sizeof(struct HistEnt)); he->time=-1; he->v.vector=NULL; n->curr=he; n->head.next=he; add_histent(t_time,n,ch,regadd, vector); } else { int i, nlen; nlen = strlen(vector); if(nlen) { n->numtrans++; for(i=0;inotdead=1; return; } } } } } } } static void add_tail_histents(void) { /* dump out any pending events 1st */ struct queuedevent *q; q=queuedevents; while(q) { struct vcdsymbol *v; v=q->sym; if(current_time!=(v->ev->last_event_time+1)) { /* dump degating event */ DEBUG(fprintf(stderr,"#"TTFormat" %s = '%c' (event)\n",v->ev->last_event_time+1,v->name,'0')); add_histent(v->ev->last_event_time+1,v->narray[0],'0',1, NULL); } q=q->next; } } /*******************************************************************************/ TimeType vcd_main(char *fname, char *lxname) { #ifdef ONLY_NEEDED_FOR_VALGRIND_CLEAN_TEST struct vcdsymbol *v, *v2; #endif vcd_hier_delimeter[0]=hier_delimeter; errno=0; /* reset in case it's set for some reason */ yytext=(char *)malloc_2(T_MAX_STR+1); if((strlen(fname)>2)&&(!strcmp(fname+strlen(fname)-3,".gz"))) { char *str; int dlen; dlen=strlen(WAVE_DECOMPRESSOR); str=(char *)wave_alloca(strlen(fname)+dlen+1); strcpy(str,WAVE_DECOMPRESSOR); strcpy(str+dlen,fname); vcd_handle=popen(str,"r"); vcd_is_compressed=~0; } else { if(strcmp("-",fname)) { vcd_handle=fopen(fname,"rb"); } else { vcd_handle=stdin; } vcd_is_compressed=0; } if(!vcd_handle) { fprintf(stderr, "Error opening %s .vcd file '%s'.\n", vcd_is_compressed?"compressed":"", fname); exit(1); } lt=lxt2_wr_init(lxname); if(!lt) { fprintf(stderr, "Problem opening output file '%s'\n", lxname); perror("Why"); exit(255); } if(opt_partial_mode>=0) { lxt2_wr_set_partial_on(lt, opt_partial_mode); } if((opt_checkpoint_disable)&&(!opt_break_size)) { lxt2_wr_set_checkpoint_off(lt); } lxt2_wr_set_compression_depth(lt, opt_depth); lxt2_wr_set_break_size(lt, (off_t)opt_break_size); lxt2_wr_set_maxgranule(lt, opt_maxgranule); lxt2_wr_symbol_bracket_stripping(lt, 1); /* this is intentional */ sym=(struct symbol **)calloc_2(SYMPRIME,sizeof(struct symbol *)); printf("\nConverting VCD File '%s' to LXT2 file '%s'...\n\n",(vcd_handle!=stdin)?fname:"from stdin", lxname); build_slisthier(); vcd_parse(); if(varsplit) { free_2(varsplit); varsplit=NULL; } add_tail_histents(); printf("["TTFormat"] start time.\n["TTFormat"] end time.\n\n", start_time, end_time); lxt2_wr_close(lt); lt=NULL; min_time=start_time*time_scale; max_time=end_time*time_scale; if((min_time==max_time)||(max_time==0)) { fprintf(stderr, "VCD times range is equal to zero. Exiting.\n"); exit(1); } if(vcd_handle!=stdin) { fclose(vcd_handle); vcd_handle=NULL; } free(yytext); yytext=NULL; if(indexed) { free(indexed); indexed=NULL; } if(sorted) { free(sorted); sorted=NULL; } #ifdef ONLY_NEEDED_FOR_VALGRIND_CLEAN_TEST v=vcdsymroot; while(v) { if(v->name) { free(v->name); v->name=NULL; } if(v->id) { free(v->id); v->id=NULL; } if(v->value) { free(v->value); v->value=NULL; } if(v->narray) { int i; for(i=0;isize;i++) { struct HistEnt *h1, *h2; if((h1 = v->narray[i]->head.next)) { h1 = v->narray[i]->head.next; while(h1) { h2 = h1->next; free(h1); h1 = h2; } } free(v->narray[i]); v->narray[i]=NULL; } free(v->narray); v->narray=NULL; } v2=v->next; free(v); v=v2; } vcdsymroot=vcdsymcurr=NULL; #endif free(sym); sym=NULL; if(slisthier) { free(slisthier); slisthier=NULL; } return(max_time); } /*******************************************************************************/ /* * Generic hash function for symbol names... */ int hash(char *s) { char *p; unsigned int h=0, g; for(p=s;*p;p++) { h=(h<<4)+(*p); if((g=h&0xf0000000)) { h=h^(g>>24); h=h^g; } } return(h%SYMPRIME); } /* * add symbol to table. no duplicate checking * is necessary as aet's are "correct." */ struct symbol *symadd(char *name, int hv) { struct symbol *s; s=(struct symbol *)calloc_2(1,sizeof(struct symbol)); strcpy(s->name=(char *)malloc_2(strlen(name)+1),name); s->next=sym[hv]; sym[hv]=s; return(s); } /* * find a slot already in the table... */ struct symbol *symfind(char *s) { int hv; struct symbol *temp; hv=hash(s); if(!(temp=sym[hv])) return(NULL); /* no hash entry, add here wanted to add */ while(temp) { if(!strcmp(temp->name,s)) { return(temp); /* in table already */ } if(!temp->next) break; temp=temp->next; } return(NULL); /* not found, add here if you want to add*/ } int sigcmp(char *s1, char *s2) { unsigned char c1, c2; int u1, u2; for(;;) { c1=(unsigned char)*(s1++); c2=(unsigned char)*(s2++); if((!c1)&&(!c2)) return(0); if((c1<='9')&&(c2<='9')&&(c2>='0')&&(c1>='0')) { u1=(int)(c1&15); u2=(int)(c2&15); while(((c2=(unsigned char)*s2)>='0')&&(c2<='9')) { u2*=10; u2+=(unsigned int)(c2&15); s2++; } while(((c2=(unsigned char)*s1)>='0')&&(c2<='9')) { u1*=10; u1+=(unsigned int)(c2&15); s1++; } if(u1==u2) continue; else return((int)u1-(int)u2); } else { if(c1!=c2) return((int)c1-(int)c2); } } } int partition(struct symbol **a, int p, int r) { struct symbol *x, *t; int i,j; x=a[p]; i=p-1; j=r+1; while(1) { do { j--; } while(sigcmp(a[j]->name,x->name)>0); do { i++; } while(sigcmp(a[i]->name,x->name)<0); if(i.\n",nam); #else printf( "Usage: %s [OPTION]... [VCDFILE] [LXT2FILE]\n\n" " -v FILE specify VCD input filename\n" " -l FILE specify LXT2 output filename\n" " -d value specify 0..9 compression depth (default = 4)\n" " -m value specify number of granules per section (def = 8)\n" " -b value specify break size (default = 0 = off)\n" " -p mode specify partial zip mode 0=monolithic/1=separate\n" " -c mode specify checkpoint mode (0 = on [def], 1 = off)\n" " -h display this help then exit\n\n" "VCD files may be compressed with zip or gzip. Note that VCDFILE and LXTFILE\n" "are optional provided the --vcdname and --lxtname options are specified.\n" "Use \"-\" as a VCD filename to accept uncompressed input from stdin.\n\n" "Report bugs to <"PACKAGE_BUGREPORT">.\n",nam); #endif exit(0); } int main(int argc, char **argv) { char opt_errors_encountered=0; char *vname=NULL, *lxname=NULL; int c; WAVE_LOCALE_FIX while (1) { #ifdef __linux__ int option_index = 0; static struct option long_options[] = { {"vcdname", 1, 0, 'v'}, {"lxtname", 1, 0, 'l'}, {"depth", 1, 0, 'd'}, {"maxgranule", 1, 0, 'm'}, {"break", 1, 0, 'b'}, {"partialmode", 1, 0, 'p'}, {"checkpoint", 1, 0, 'c'}, {"help", 0, 0, 'h'}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "v:l:d:m:b:p:c:h", long_options, &option_index); #else c = getopt (argc, argv, "v:l:d:m:b:p:c:h"); #endif if (c == -1) break; /* no more args */ switch (c) { case 'v': if(vname) free(vname); vname = malloc_2(strlen(optarg)+1); strcpy(vname, optarg); break; case 'l': if(lxname) free(lxname); lxname = malloc_2(strlen(optarg)+1); strcpy(lxname, optarg); break; case 'd': opt_depth = atoi(optarg); if(opt_depth<0) opt_depth = 0; if(opt_depth>9) opt_depth = 9; break; case 'm': opt_maxgranule = atoi(optarg); if(opt_maxgranule<1) opt_maxgranule=1; break; case 'b': sscanf(optarg, "%"SCNu64, &opt_break_size); errno = 0; break; case 'p': opt_partial_mode = atoi(optarg); if(opt_depth<0) opt_partial_mode = 0; if(opt_depth>1) opt_partial_mode = 1; break; case 'c': opt_checkpoint_disable = atoi(optarg); break; case 'h': print_help(argv[0]); break; case '?': opt_errors_encountered=1; break; default: /* unreachable */ break; } } if(opt_errors_encountered) { print_help(argv[0]); } if (optind < argc) { while (optind < argc) { if(!vname) { vname = malloc_2(strlen(argv[optind])+1); strcpy(vname, argv[optind++]); } else if(!lxname) { lxname = malloc_2(strlen(argv[optind])+1); strcpy(lxname, argv[optind++]); } else { break; } } } if((!vname)||(!lxname)) { print_help(argv[0]); } vcd_main(vname, lxname); free(vname); free(lxname); return(0); } gtkwave-3.3.66/src/helpers/lxt2_read.h0000664000076400007640000002124712354676614017111 0ustar bybellbybell/* * Copyright (c) 2003-2012 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifndef DEFS_LXTR_H #define DEFS_LXTR_H #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include #ifndef _MSC_VER #include #if HAVE_INTTYPES_H #include #endif #else typedef long off_t; #include #include #endif #ifndef HAVE_FSEEKO #define fseeko fseek #define ftello ftell #endif #include #ifdef __GNUC__ #if __STDC_VERSION__ >= 199901L #define _LXT2_RD_INLINE inline __attribute__((__gnu_inline__)) #else #define _LXT2_RD_INLINE inline #endif #else #define _LXT2_RD_INLINE #endif #define LXT2_RDLOAD "LXTLOAD | " #define LXT2_RD_HDRID (0x1380) #define LXT2_RD_VERSION (0x0001) #define LXT2_RD_GRANULE_SIZE (64) #define LXT2_RD_PARTIAL_SIZE (2048) #define LXT2_RD_GRAN_SECT_TIME 0 #define LXT2_RD_GRAN_SECT_DICT 1 #define LXT2_RD_GRAN_SECT_TIME_PARTIAL 2 #define LXT2_RD_MAX_BLOCK_MEM_USAGE (64*1024*1024) /* 64MB */ #ifndef _MSC_VER typedef uint8_t lxtint8_t; typedef uint16_t lxtint16_t; typedef uint32_t lxtint32_t; typedef uint64_t lxtint64_t; typedef int32_t lxtsint32_t; typedef int64_t lxtsint64_t; #ifndef __MINGW32__ #define LXT2_RD_LLD "%"PRId64 #define LXT2_RD_LD "%"PRId32 #else #define LXT2_RD_LLD "%I64d" #define LXT2_RD_LD "%d" #endif #define LXT2_RD_LLDESC(x) x##LL #define LXT2_RD_ULLDESC(x) x##ULL #else typedef unsigned __int8 lxtint8_t; typedef unsigned __int16 lxtint16_t; typedef unsigned __int32 lxtint32_t; typedef unsigned __int64 lxtint64_t; typedef __int32 lxtsint32_t; typedef __int64 lxtsint64_t; #define LXT2_RD_LLD "%I64d" #define LXT2_RD_LD "%d" #define LXT2_RD_LLDESC(x) x##i64 #define LXT2_RD_ULLDESC(x) x##i64 #endif #if LXT2_RD_GRANULE_SIZE > 32 typedef lxtint64_t granmsk_t; typedef lxtint32_t granmsk_smaller_t; #define LXT2_RD_GRAN_0VAL (LXT2_RD_ULLDESC(0)) #define LXT2_RD_GRAN_1VAL (LXT2_RD_ULLDESC(1)) #define get_fac_msk lxt2_rd_get_64 #define get_fac_msk_smaller lxt2_rd_get_32 #else typedef lxtint32_t granmsk_t; #define LXT2_RD_GRAN_0VAL (0) #define LXT2_RD_GRAN_1VAL (1) #define get_fac_msk lxt2_rd_get_32 #endif #define LXT2_RD_SYM_F_BITS (0) #define LXT2_RD_SYM_F_INTEGER (1<<0) #define LXT2_RD_SYM_F_DOUBLE (1<<1) #define LXT2_RD_SYM_F_STRING (1<<2) #define LXT2_RD_SYM_F_TIME (LXT2_RD_SYM_F_STRING) /* user must correctly format this as a string */ #define LXT2_RD_SYM_F_ALIAS (1<<3) #define LXT2_RD_SYM_F_SIGNED (1<<4) #define LXT2_RD_SYM_F_BOOLEAN (1<<5) #define LXT2_RD_SYM_F_NATURAL ((1<<6)|(LXT2_RD_SYM_F_INTEGER)) #define LXT2_RD_SYM_F_POSITIVE ((1<<7)|(LXT2_RD_SYM_F_INTEGER)) #define LXT2_RD_SYM_F_CHARACTER (1<<8) #define LXT2_RD_SYM_F_CONSTANT (1<<9) #define LXT2_RD_SYM_F_VARIABLE (1<<10) #define LXT2_RD_SYM_F_SIGNAL (1<<11) #define LXT2_RD_SYM_F_IN (1<<12) #define LXT2_RD_SYM_F_OUT (1<<13) #define LXT2_RD_SYM_F_INOUT (1<<14) #define LXT2_RD_SYM_F_WIRE (1<<15) #define LXT2_RD_SYM_F_REG (1<<16) enum LXT2_RD_Encodings { LXT2_RD_ENC_0, LXT2_RD_ENC_1, LXT2_RD_ENC_INV, LXT2_RD_ENC_LSH0, LXT2_RD_ENC_LSH1, LXT2_RD_ENC_RSH0, LXT2_RD_ENC_RSH1, LXT2_RD_ENC_ADD1, LXT2_RD_ENC_ADD2, LXT2_RD_ENC_ADD3, LXT2_RD_ENC_ADD4, LXT2_RD_ENC_SUB1, LXT2_RD_ENC_SUB2, LXT2_RD_ENC_SUB3, LXT2_RD_ENC_SUB4, LXT2_RD_ENC_X, LXT2_RD_ENC_Z, LXT2_RD_ENC_BLACKOUT, LXT2_RD_DICT_START }; struct lxt2_rd_block { char *mem; struct lxt2_rd_block *next; lxtint32_t uncompressed_siz, compressed_siz; lxtint64_t start, end; lxtint32_t num_map_entries, num_dict_entries; char *map_start; char *dict_start; char **string_pointers; /* based inside dict_start */ unsigned int *string_lens; off_t filepos; /* where block starts in file if we have to reload */ unsigned short_read_ignore : 1; /* tried to read once and it was corrupt so ignore next time */ unsigned exclude_block : 1; /* user marked this block off to be ignored */ }; struct lxt2_rd_geometry { lxtint32_t rows; lxtsint32_t msb, lsb; lxtint32_t flags, len; }; struct lxt2_rd_facname_cache { char *n; char *bufprev, *bufcurr; lxtint32_t old_facidx; }; struct lxt2_rd_trace { lxtint32_t *rows; lxtsint32_t *msb, *lsb; lxtint32_t *flags, *len; char **value; granmsk_t *fac_map; char **fac_curpos; char *process_mask; char *process_mask_compressed; void **radix_sort[LXT2_RD_GRANULE_SIZE+1]; void **next_radix; void (*value_change_callback)(struct lxt2_rd_trace **lt, lxtint64_t *time, lxtint32_t *facidx, char **value); void *user_callback_data_pointer; unsigned char fac_map_index_width; unsigned char fac_curpos_width; lxtint8_t granule_size; lxtint32_t numfacs, numrealfacs, numfacbytes, longestname, zfacnamesize, zfacname_predec_size, zfacgeometrysize; lxtint8_t timescale; lxtsint64_t timezero; lxtint64_t prev_time; unsigned char num_time_table_entries; lxtint64_t time_table[LXT2_RD_GRANULE_SIZE]; char *zfacnames; unsigned int numblocks; struct lxt2_rd_block *block_head, *block_curr; lxtint64_t start, end; struct lxt2_rd_geometry geometry; struct lxt2_rd_facname_cache *faccache; FILE *handle; gzFile zhandle; lxtint64_t block_mem_consumed, block_mem_max; unsigned process_mask_dirty : 1; /* only used on partial block reads */ }; /* * LXT2 Reader API functions... */ struct lxt2_rd_trace * lxt2_rd_init(const char *name); void lxt2_rd_close(struct lxt2_rd_trace *lt); lxtint64_t lxt2_rd_set_max_block_mem_usage(struct lxt2_rd_trace *lt, lxtint64_t block_mem_max); lxtint64_t lxt2_rd_get_block_mem_usage(struct lxt2_rd_trace *lt); unsigned int lxt2_rd_get_num_blocks(struct lxt2_rd_trace *lt); unsigned int lxt2_rd_get_num_active_blocks(struct lxt2_rd_trace *lt); lxtint32_t lxt2_rd_get_num_facs(struct lxt2_rd_trace *lt); char * lxt2_rd_get_facname(struct lxt2_rd_trace *lt, lxtint32_t facidx); struct lxt2_rd_geometry * lxt2_rd_get_fac_geometry(struct lxt2_rd_trace *lt, lxtint32_t facidx); lxtint32_t lxt2_rd_get_fac_rows(struct lxt2_rd_trace *lt, lxtint32_t facidx); lxtsint32_t lxt2_rd_get_fac_msb(struct lxt2_rd_trace *lt, lxtint32_t facidx); lxtsint32_t lxt2_rd_get_fac_lsb(struct lxt2_rd_trace *lt, lxtint32_t facidx); lxtint32_t lxt2_rd_get_fac_flags(struct lxt2_rd_trace *lt, lxtint32_t facidx); lxtint32_t lxt2_rd_get_fac_len(struct lxt2_rd_trace *lt, lxtint32_t facidx); lxtint32_t lxt2_rd_get_alias_root(struct lxt2_rd_trace *lt, lxtint32_t facidx); char lxt2_rd_get_timescale(struct lxt2_rd_trace *lt); lxtsint64_t lxt2_rd_get_timezero(struct lxt2_rd_trace *lt); lxtint64_t lxt2_rd_get_start_time(struct lxt2_rd_trace *lt); lxtint64_t lxt2_rd_get_end_time(struct lxt2_rd_trace *lt); int lxt2_rd_get_fac_process_mask(struct lxt2_rd_trace *lt, lxtint32_t facidx); int lxt2_rd_set_fac_process_mask(struct lxt2_rd_trace *lt, lxtint32_t facidx); int lxt2_rd_clr_fac_process_mask(struct lxt2_rd_trace *lt, lxtint32_t facidx); int lxt2_rd_set_fac_process_mask_all(struct lxt2_rd_trace *lt); int lxt2_rd_clr_fac_process_mask_all(struct lxt2_rd_trace *lt); /* null value_change_callback calls an empty dummy function */ int lxt2_rd_iter_blocks(struct lxt2_rd_trace *lt, void (*value_change_callback)(struct lxt2_rd_trace **lt, lxtint64_t *time, lxtint32_t *facidx, char **value), void *user_callback_data_pointer); void * lxt2_rd_get_user_callback_data_pointer(struct lxt2_rd_trace *lt); /* time (un)/restricted read ops */ unsigned int lxt2_rd_limit_time_range(struct lxt2_rd_trace *lt, lxtint64_t strt_time, lxtint64_t end_time); unsigned int lxt2_rd_unlimit_time_range(struct lxt2_rd_trace *lt); #ifdef __cplusplus } #endif #endif gtkwave-3.3.66/src/helpers/lxt2_write.c0000664000076400007640000013424312362030630017301 0ustar bybellbybell/* * Copyright (c) 2003-2012 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifdef _AIX #pragma alloca #endif #include #include "lxt2_write.h" static char *lxt2_wr_vcd_truncate_bitvec(char *s) { char l, r; r=*s; if(r=='1') { return s; } else { s++; } for(;;s++) { l=r; r=*s; if(!r) return (s-1); if(l!=r) { return(((l=='0')&&(r=='1'))?s:s-1); } } } /* * in-place sort to keep chained facs from migrating... */ static void wave_mergesort(struct lxt2_wr_symbol **a, struct lxt2_wr_symbol **b, int lo, int hi) { int i, j, k; if (loname, a[j]->name) <= 0) { a[k++]=b[i++]; } else { a[k++]=a[j++]; } } while (kitem) { if (t->left == NULL) break; if (i < t->left->item) { y = t->left; /* rotate right */ t->left = y->right; y->right = t; t = y; if (t->left == NULL) break; } r->left = t; /* link right */ r = t; t = t->left; } else if (i > t->item) { if (t->right == NULL) break; if (i > t->right->item) { y = t->right; /* rotate left */ t->right = y->left; y->left = t; t = y; if (t->right == NULL) break; } l->right = t; /* link left */ l = t; t = t->right; } else { break; } } l->right = t->left; /* assemble */ r->left = t->right; t->left = N.right; t->right = N.left; return t; } static lxt2_wr_ds_Tree * lxt2_wr_ds_insert(granmsk_t i, lxt2_wr_ds_Tree * t, int val) { /* Insert i into the tree t, unless it's already there. */ /* Return a pointer to the resulting tree. */ lxt2_wr_ds_Tree * n; n = (lxt2_wr_ds_Tree *) calloc (1, sizeof (lxt2_wr_ds_Tree)); if (n == NULL) { fprintf(stderr, "ds_insert: ran out of memory, exiting.\n"); exit(255); } n->item = i; n->val = val; if (t == NULL) { n->left = n->right = NULL; return n; } t = lxt2_wr_ds_splay(i,t); if (i < t->item) { n->left = t->left; n->right = t; t->left = NULL; return n; } else if (i > t->item) { n->right = t->right; n->left = t; t->right = NULL; return n; } else { /* We get here if it's already in the tree */ /* Don't add it again */ free(n); return t; } } /************************ splay ************************/ static int lxt2_wr_dslxt_success; static lxt2_wr_dslxt_Tree * lxt2_wr_dslxt_splay (char *i, lxt2_wr_dslxt_Tree * t) { /* Simple top down splay, not requiring i to be in the tree t. */ /* What it does is described above. */ lxt2_wr_dslxt_Tree N, *l, *r, *y; int dir; lxt2_wr_dslxt_success = 0; if (t == NULL) return t; N.left = N.right = NULL; l = r = &N; for (;;) { dir = strcmp(i, t->item); if (dir < 0) { if (t->left == NULL) break; if (strcmp(i, t->left->item)<0) { y = t->left; /* rotate right */ t->left = y->right; y->right = t; t = y; if (t->left == NULL) break; } r->left = t; /* link right */ r = t; t = t->left; } else if (dir > 0) { if (t->right == NULL) break; if (strcmp(i, t->right->item)>0) { y = t->right; /* rotate left */ t->right = y->left; y->left = t; t = y; if (t->right == NULL) break; } l->right = t; /* link left */ l = t; t = t->right; } else { lxt2_wr_dslxt_success=1; break; } } l->right = t->left; /* assemble */ r->left = t->right; t->left = N.right; t->right = N.left; return t; } static lxt2_wr_dslxt_Tree * lxt2_wr_dslxt_insert(char *i, lxt2_wr_dslxt_Tree * t, unsigned int val) { /* Insert i into the tree t, unless it's already there. */ /* Return a pointer to the resulting tree. */ lxt2_wr_dslxt_Tree * n; int dir; n = (lxt2_wr_dslxt_Tree *) calloc (1, sizeof (lxt2_wr_dslxt_Tree)); if (n == NULL) { fprintf(stderr, "dslxt_insert: ran out of memory, exiting.\n"); exit(255); } n->item = i; n->val = val; if (t == NULL) { n->left = n->right = NULL; return n; } t = lxt2_wr_dslxt_splay(i,t); dir = strcmp(i,t->item); if (dir<0) { n->left = t->left; n->right = t; t->left = NULL; return n; } else if (dir>0) { n->right = t->right; n->left = t; t->right = NULL; return n; } else { /* We get here if it's already in the tree */ /* Don't add it again */ free(n); return t; } } /************************ splay ************************/ /* * functions which emit various big endian * data to a file */ static int lxt2_wr_emit_u8(struct lxt2_wr_trace *lt, int value) { unsigned char buf[1]; int nmemb; buf[0] = value & 0xff; nmemb=fwrite(buf, sizeof(char), 1, lt->handle); lt->position+=nmemb; return(nmemb); } static int lxt2_wr_emit_u16(struct lxt2_wr_trace *lt, int value) { unsigned char buf[2]; int nmemb; buf[0] = (value>>8) & 0xff; buf[1] = value & 0xff; nmemb = fwrite(buf, sizeof(char), 2, lt->handle); lt->position+=nmemb; return(nmemb); } static int lxt2_wr_emit_u32(struct lxt2_wr_trace *lt, int value) { unsigned char buf[4]; int nmemb; buf[0] = (value>>24) & 0xff; buf[1] = (value>>16) & 0xff; buf[2] = (value>>8) & 0xff; buf[3] = value & 0xff; nmemb=fwrite(buf, sizeof(char), 4, lt->handle); lt->position+=nmemb; return(nmemb); } static int lxt2_wr_emit_u64(struct lxt2_wr_trace *lt, int valueh, int valuel) { int rc; if((rc=lxt2_wr_emit_u32(lt, valueh))) { rc=lxt2_wr_emit_u32(lt, valuel); } return(rc); } /* * gzfunctions which emit various big endian * data to a file. (lt->position needs to be * fixed up on gzclose so the tables don't * get out of sync!) */ static int gzwrite_buffered(struct lxt2_wr_trace *lt) { int rc = 1; if(lt->gzbufpnt > LXT2_WR_GZWRITE_BUFFER) { rc = gzwrite(lt->zhandle, lt->gzdest, lt->gzbufpnt); rc = rc ? 1 : 0; lt->gzbufpnt = 0; } return(rc); } static void gzflush_buffered(struct lxt2_wr_trace *lt, int doclose) { if(lt->gzbufpnt) { gzwrite(lt->zhandle, lt->gzdest, lt->gzbufpnt); lt->gzbufpnt = 0; if(!doclose) { gzflush(lt->zhandle, Z_SYNC_FLUSH); } } if(doclose) { gzclose(lt->zhandle); } } static int lxt2_wr_emit_u8z(struct lxt2_wr_trace *lt, int value) { int nmemb; lt->gzdest[lt->gzbufpnt++] = value & 0xff; nmemb=gzwrite_buffered(lt); lt->zpackcount++; lt->position++; return(nmemb); } static int lxt2_wr_emit_u16z(struct lxt2_wr_trace *lt, int value) { int nmemb; lt->gzdest[lt->gzbufpnt++] = (value>>8) & 0xff; lt->gzdest[lt->gzbufpnt++] = value & 0xff; nmemb = gzwrite_buffered(lt); lt->zpackcount+=2; lt->position+=2; return(nmemb); } static int lxt2_wr_emit_u24z(struct lxt2_wr_trace *lt, int value) { int nmemb; lt->gzdest[lt->gzbufpnt++] = (value>>16) & 0xff; lt->gzdest[lt->gzbufpnt++] = (value>>8) & 0xff; lt->gzdest[lt->gzbufpnt++] = value & 0xff; nmemb=gzwrite_buffered(lt); lt->zpackcount+=3; lt->position+=3; return(nmemb); } static int lxt2_wr_emit_u32z(struct lxt2_wr_trace *lt, int value) { int nmemb; lt->gzdest[lt->gzbufpnt++] = (value>>24) & 0xff; lt->gzdest[lt->gzbufpnt++] = (value>>16) & 0xff; lt->gzdest[lt->gzbufpnt++] = (value>>8) & 0xff; lt->gzdest[lt->gzbufpnt++] = value & 0xff; nmemb=gzwrite_buffered(lt); lt->zpackcount+=4; lt->position+=4; return(nmemb); } static int lxt2_wr_emit_u64z(struct lxt2_wr_trace *lt, int valueh, int valuel) { int rc; if((rc=lxt2_wr_emit_u32z(lt, valueh))) { rc=lxt2_wr_emit_u32z(lt, valuel); } return(rc); } static int lxt2_wr_emit_stringz(struct lxt2_wr_trace *lt, char *value) { int rc=1; do { rc&=lxt2_wr_emit_u8z(lt, *value); } while(*(value++)); return(rc); } /* * hash/symtable manipulation */ static int lxt2_wr_hash(const char *s) { const char *p; char ch; unsigned int h=0, h2=0, pos=0, g; for(p=s;*p;p++) { ch=*p; h2<<=3; h2-=((unsigned int)ch+(pos++)); /* this handles stranded vectors quite well.. */ h=(h<<4)+ch; if((g=h&0xf0000000)) { h=h^(g>>24); h=h^g; } } h^=h2; /* combine the two hashes */ return(h%LXT2_WR_SYMPRIME); } static struct lxt2_wr_symbol *lxt2_wr_symadd(struct lxt2_wr_trace *lt, const char *name, int hv) { struct lxt2_wr_symbol *s; s=(struct lxt2_wr_symbol *)calloc(1,sizeof(struct lxt2_wr_symbol)); strcpy(s->name=(char *)malloc((s->namlen=strlen(name))+1),name); s->next=lt->sym[hv]; lt->sym[hv]=s; return(s); } static struct lxt2_wr_symbol *lxt2_wr_symfind(struct lxt2_wr_trace *lt, const char *s) { int hv; struct lxt2_wr_symbol *temp; hv=lxt2_wr_hash(s); if(!(temp=lt->sym[hv])) return(NULL); /* no hash entry, add here wanted to add */ while(temp) { if(!strcmp(temp->name,s)) { return(temp); /* in table already */ } if(!temp->next) break; temp=temp->next; } return(NULL); /* not found, add here if you want to add*/ } /* * compress facs to a prefix count + string + 0x00 */ static void lxt2_wr_compress_fac(struct lxt2_wr_trace *lt, char *str) { int i; int len = strlen(str); int minlen = (lencompress_fac_len) ? len : lt->compress_fac_len; if(minlen>65535) minlen=65535; /* keep in printable range--most hierarchies won't be this big anyway */ if(lt->compress_fac_str) { for(i=0;icompress_fac_str[i]!=str[i]) break; } lxt2_wr_emit_u16z(lt, i); lxt2_wr_emit_stringz(lt, str+i); free(lt->compress_fac_str); } else { lxt2_wr_emit_u16z(lt, 0); lxt2_wr_emit_stringz(lt, str); } lt->compress_fac_str = (char *) malloc((lt->compress_fac_len=len)+1); strcpy(lt->compress_fac_str, str); } /* * emit facs in sorted order along with geometry * and sync table info */ static void strip_brack(struct lxt2_wr_symbol *s) { char *lastch = s->name+s->namlen - 1; if(*lastch!=']') return; if(s->namlen<3) return; lastch--; while(lastch!=s->name) { if(*lastch=='.') { return; /* MTI SV [0.3] notation for implicit vars */ } if(*lastch=='[') { *lastch=0x00; return; } lastch--; } return; } static void lxt2_wr_emitfacs(struct lxt2_wr_trace *lt) { unsigned int i; if((lt)&&(lt->numfacs)) { struct lxt2_wr_symbol *s = lt->symchain; struct lxt2_wr_symbol **aliascache = calloc(lt->numalias ? lt->numalias : 1, sizeof(struct lxt2_wr_symbol *)); unsigned int aliases_encountered, facs_encountered; lt->sorted_facs = (struct lxt2_wr_symbol **)calloc(lt->numfacs, sizeof(struct lxt2_wr_symbol *)); if(lt->sorted_facs && aliascache) { if(lt->do_strip_brackets) for(i=0;inumfacs;i++) { lt->sorted_facs[lt->numfacs - i - 1] = s; /* facs were chained backwards so reverse to restore bitslicing */ strip_brack(s); s=s->symchain; } else for(i=0;inumfacs;i++) { lt->sorted_facs[lt->numfacs - i - 1] = s; /* facs were chained backwards so reverse to restore bitslicing */ s=s->symchain; } wave_msort(lt->sorted_facs, lt->numfacs); if(lt->partial_preference) { /* move preferenced facs up */ struct lxt2_wr_symbol **prefcache = aliascache; int prefs_encountered = 0; facs_encountered = 0; for(i=0;inumfacs;i++) { if((lt->sorted_facs[i]->partial_preference)==0) { lt->sorted_facs[facs_encountered] = lt->sorted_facs[i]; facs_encountered++; } else { prefcache[prefs_encountered] = lt->sorted_facs[i]; prefs_encountered++; } } /* then append the non-preferenced facs */ for(i=0;isorted_facs[i]; } /* now make prefcache the main cache */ aliascache = lt->sorted_facs; lt->sorted_facs = prefcache; } /* move facs up */ aliases_encountered = 0, facs_encountered = 0; for(i=0;inumfacs;i++) { if((lt->sorted_facs[i]->flags&LXT2_WR_SYM_F_ALIAS)==0) { lt->sorted_facs[facs_encountered] = lt->sorted_facs[i]; facs_encountered++; } else { aliascache[aliases_encountered] = lt->sorted_facs[i]; aliases_encountered++; } } /* then append the aliases */ for(i=0;isorted_facs[facs_encountered+i] = aliascache[i]; } for(i=0;inumfacs;i++) { lt->sorted_facs[i]->facnum = i; } if(!lt->timezero) { lxt2_wr_emit_u32(lt, lt->numfacs); /* uncompressed */ } else { lxt2_wr_emit_u32(lt, 0); /* uncompressed, flag to insert extra parameters */ lxt2_wr_emit_u32(lt, 8); /* uncompressed 8 counts timezero and on */ lxt2_wr_emit_u32(lt, lt->numfacs); /* uncompressed */ lxt2_wr_emit_u64(lt, (lt->timezero >> 32) & 0xffffffffL, lt->timezero & 0xffffffffL); /* uncompressed */ } lxt2_wr_emit_u32(lt, lt->numfacbytes); /* uncompressed */ lxt2_wr_emit_u32(lt, lt->longestname); /* uncompressed */ lt->facname_offset=lt->position; lxt2_wr_emit_u32(lt, 0); /* uncompressed : placeholder for zfacnamesize */ lxt2_wr_emit_u32(lt, 0); /* uncompressed : placeholder for zfacname_predec_size */ lxt2_wr_emit_u32(lt, 0); /* uncompressed : placeholder for zfacgeometrysize */ lxt2_wr_emit_u8(lt, lt->timescale); /* timescale (-9 default == nsec) */ fflush(lt->handle); lt->zfacname_size = lt->position; lt->zhandle = gzdopen(dup(fileno(lt->handle)), "wb9"); lt->zpackcount = 0; for(i=0;inumfacs;i++) { lxt2_wr_compress_fac(lt, lt->sorted_facs[i]->name); free(lt->sorted_facs[i]->name); lt->sorted_facs[i]->name = NULL; } free(lt->compress_fac_str); lt->compress_fac_str=NULL; lt->compress_fac_len=0; lt->zfacname_predec_size = lt->zpackcount; gzflush_buffered(lt, 1); fseeko(lt->handle, 0L, SEEK_END); lt->position=ftello(lt->handle); lt->zfacname_size = lt->position - lt->zfacname_size; lt->zhandle = gzdopen(dup(fileno(lt->handle)), "wb9"); lt->facgeometry_offset = lt->position; for(i=0;inumfacs;i++) { if((lt->sorted_facs[i]->flags&LXT2_WR_SYM_F_ALIAS)==0) { lxt2_wr_emit_u32z(lt, lt->sorted_facs[i]->rows); lxt2_wr_emit_u32z(lt, lt->sorted_facs[i]->msb); lxt2_wr_emit_u32z(lt, lt->sorted_facs[i]->lsb); lxt2_wr_emit_u32z(lt, lt->sorted_facs[i]->flags); } else { lxt2_wr_emit_u32z(lt, lt->sorted_facs[i]->aliased_to->facnum); lxt2_wr_emit_u32z(lt, lt->sorted_facs[i]->msb); lxt2_wr_emit_u32z(lt, lt->sorted_facs[i]->lsb); lxt2_wr_emit_u32z(lt, LXT2_WR_SYM_F_ALIAS); } } gzflush_buffered(lt, 1); fseeko(lt->handle, 0L, SEEK_END); lt->position=ftello(lt->handle); lt->break_header_size = lt->position; /* in case we need to emit multiple lxt2s with same header */ lt->zfacgeometry_size = lt->position - lt->facgeometry_offset; fseeko(lt->handle, lt->facname_offset, SEEK_SET); lxt2_wr_emit_u32(lt, lt->zfacname_size); /* backpatch sizes... */ lxt2_wr_emit_u32(lt, lt->zfacname_predec_size); lxt2_wr_emit_u32(lt, lt->zfacgeometry_size); lt->numfacs = facs_encountered; /* don't process alias value changes ever */ } free(aliascache); } } /* * initialize the trace and get back an lt context */ struct lxt2_wr_trace *lxt2_wr_init(const char *name) { struct lxt2_wr_trace *lt=(struct lxt2_wr_trace *)calloc(1, sizeof(struct lxt2_wr_trace)); if((!name)||(!(lt->handle=fopen(name, "wb")))) { free(lt); lt=NULL; } else { lt->lxtname = strdup(name); lxt2_wr_emit_u16(lt, LXT2_WR_HDRID); lxt2_wr_emit_u16(lt, LXT2_WR_VERSION); lxt2_wr_emit_u8 (lt, LXT2_WR_GRANULE_SIZE); /* currently 32 or 64 */ lt->timescale = -9; lt->maxgranule = LXT2_WR_GRANULE_NUM; lxt2_wr_set_compression_depth(lt, 4); /* set fast/loose compression depth, user can fix this any time after init */ lt->initial_value = 'x'; } return(lt); } /* * setting break size */ void lxt2_wr_set_break_size(struct lxt2_wr_trace *lt, off_t siz) { if(lt) { lt->break_size = siz; } } /* * enable/disable partial dump mode (for faster reads) */ void lxt2_wr_set_partial_off(struct lxt2_wr_trace *lt) { if(lt) { lt->partial = 0; lt->partial_zip = 0; } } void lxt2_wr_set_partial_on(struct lxt2_wr_trace *lt, int zipmode) { if(lt) { lt->partial = 1; lt->partial_zip = (zipmode != 0); lt->partial_iter = LXT2_WR_PARTIAL_SIZE; } } void lxt2_wr_set_partial_preference(struct lxt2_wr_trace *lt, const char *name) { struct lxt2_wr_symbol *s; if((lt)&&(name)&&(!lt->sorted_facs)) { s=lxt2_wr_symfind(lt, name); if(s) { while(s->aliased_to) /* find root alias */ { s=s->aliased_to; } s->partial_preference = 1; } } } /* * enable/disable checkpointing (for smaller files) */ void lxt2_wr_set_checkpoint_off(struct lxt2_wr_trace *lt) { if(lt) { lt->no_checkpoint = 1; } } void lxt2_wr_set_checkpoint_on(struct lxt2_wr_trace *lt) { if(lt) { lt->no_checkpoint = 0; } } /* * set initial value of trace (0, 1, x, z) only legal vals */ void lxt2_wr_set_initial_value(struct lxt2_wr_trace *lt, char value) { if(lt) { switch(value) { case '0': case '1': case 'x': case 'z': break; case 'Z': value = 'z'; break; default: value = 'x'; break; } lt->initial_value = value; } } /* * maint function for finding a symbol if it exists */ struct lxt2_wr_symbol *lxt2_wr_symbol_find(struct lxt2_wr_trace *lt, const char *name) { struct lxt2_wr_symbol *s=NULL; if((lt)&&(name)) s=lxt2_wr_symfind(lt, name); return(s); } /* * add a trace (if it doesn't exist already) */ struct lxt2_wr_symbol *lxt2_wr_symbol_add(struct lxt2_wr_trace *lt, const char *name, unsigned int rows, int msb, int lsb, int flags) { struct lxt2_wr_symbol *s; int len; int flagcnt; if((!lt)||(lt->sorted_facs)) return(NULL); flagcnt = ((flags&LXT2_WR_SYM_F_INTEGER)!=0) + ((flags&LXT2_WR_SYM_F_DOUBLE)!=0) + ((flags&LXT2_WR_SYM_F_STRING)!=0); if((flagcnt>1)||(!lt)||(!name)||(lxt2_wr_symfind(lt, name))) return (NULL); s=lxt2_wr_symadd(lt, name, lxt2_wr_hash(name)); s->rows = rows; s->flags = flags&(~LXT2_WR_SYM_F_ALIAS); /* aliasing makes no sense here.. */ if(!flagcnt) { s->msb = msb; s->lsb = lsb; s->len = (msbvalue = strdup("NaN"); } else { if(flags & LXT2_WR_SYM_F_INTEGER) { s->len = 32; } s->value = malloc(s->len + 1); memset(s->value, lt->initial_value, s->len); s->value[s->len]=0; s->msk = LXT2_WR_GRAN_1VAL; /* stuff in an initial value */ switch(lt->initial_value) { case '0': s->chg[0] = LXT2_WR_ENC_0; break; case '1': s->chg[0] = LXT2_WR_ENC_1; break; case 'z': s->chg[0] = LXT2_WR_ENC_Z; break; default: s->chg[0] = LXT2_WR_ENC_X; break; } s->chgpos++; /* don't worry that a time doesn't exist as it will soon enough.. */ } s->symchain = lt->symchain; lt->symchain = s; lt->numfacs++; if((len=strlen(name)) > lt->longestname) lt->longestname = len; lt->numfacbytes += (len+1); return(s); } /* * add an alias trace (if it doesn't exist already and orig is found) */ struct lxt2_wr_symbol *lxt2_wr_symbol_alias(struct lxt2_wr_trace *lt, const char *existing_name, const char *alias, int msb, int lsb) { struct lxt2_wr_symbol *s, *sa; int len; int bitlen; int flagcnt; if((!lt)||(!existing_name)||(!alias)||(!(s=lxt2_wr_symfind(lt, existing_name)))||(lxt2_wr_symfind(lt, alias))) return (NULL); if(lt->sorted_facs) return(NULL); while(s->aliased_to) /* find root alias */ { s=s->aliased_to; } flagcnt = ((s->flags&LXT2_WR_SYM_F_INTEGER)!=0) + ((s->flags&LXT2_WR_SYM_F_DOUBLE)!=0) + ((s->flags&LXT2_WR_SYM_F_STRING)!=0); bitlen = (msblen)) return(NULL); sa=lxt2_wr_symadd(lt, alias, lxt2_wr_hash(alias)); sa->flags = LXT2_WR_SYM_F_ALIAS; /* only point this can get set */ sa->aliased_to = s; if(!flagcnt) { sa->msb = msb; sa->lsb = lsb; sa->len = bitlen; } sa->symchain = lt->symchain; lt->symchain = sa; lt->numfacs++; lt->numalias++; if((len=strlen(alias)) > lt->longestname) lt->longestname = len; lt->numfacbytes += (len+1); return(sa); } /* * set current time/granule updating */ int lxt2_wr_inc_time_by_delta(struct lxt2_wr_trace *lt, unsigned int timeval) { return(lxt2_wr_set_time64(lt, lt->maxtime + (lxttime_t)timeval)); } int lxt2_wr_set_time(struct lxt2_wr_trace *lt, unsigned int timeval) { return(lxt2_wr_set_time64(lt, (lxttime_t)timeval)); } int lxt2_wr_inc_time_by_delta64(struct lxt2_wr_trace *lt, lxttime_t timeval) { return(lxt2_wr_set_time64(lt, lt->maxtime + timeval)); } /* * file size limiting/header cloning... */ static void lxt2_wr_emit_do_breakfile(struct lxt2_wr_trace *lt) { unsigned int len = strlen(lt->lxtname); int i; char *tname = malloc(len + 30); FILE *f2, *clone; off_t cnt, seg; char buf[32768]; for(i=len;i>0;i--) { if(lt->lxtname[i]=='.') break; } if(!i) { sprintf(tname, "%s_%03d.lxt", lt->lxtname, ++lt->break_number); } else { memcpy(tname, lt->lxtname, i); sprintf(tname+i, "_%03d.lxt", ++lt->break_number); } f2 = fopen(tname, "wb"); if(!f2) /* if error, keep writing to same output file...sorry */ { free(tname); return; } clone = fopen(lt->lxtname, "rb"); if(!clone) { /* this should never happen */ fclose(f2); unlink(tname); free(tname); return; } /* clone original header */ for(cnt = 0; cnt < lt->break_header_size; cnt += sizeof(buf)) { seg = lt->break_header_size - cnt; if(seg > (off_t)sizeof(buf)) { seg = sizeof(buf); } if(fread(buf, seg, 1, clone)) { if(!fwrite(buf, seg, 1, f2)) break; /* write error! */ } } fclose(clone); fclose(lt->handle); lt->handle = f2; free(tname); } /* * emit granule */ void lxt2_wr_flush_granule(struct lxt2_wr_trace *lt, int do_finalize) { unsigned int idx_nbytes, map_nbytes, i, j; struct lxt2_wr_symbol *s; unsigned int partial_iter; unsigned int iter, iter_hi; unsigned char using_partial, using_partial_zip=0; off_t current_iter_pos=0; int early_flush; if(lt->flush_valid) { if(lt->flushtime == lt->lasttime) { return; } lt->flush_valid = 0; } lt->granule_dirty = 0; if((using_partial=(lt->partial)&&(lt->numfacs>lt->partial_iter))) { partial_iter = lt->partial_iter; using_partial_zip = lt->partial_zip; } else { partial_iter = lt->numfacs; } if(!lt->timegranule) { int attempt_break_state = 2; do { fseeko(lt->handle, 0L, SEEK_END); lt->current_chunk=lt->position = ftello(lt->handle); if((lt->break_size)&&(attempt_break_state==2)&&(lt->position >= lt->break_size)&&(lt->position != lt->break_header_size)) { lxt2_wr_emit_do_breakfile(lt); attempt_break_state--; } else { attempt_break_state = 0; } } while(attempt_break_state); /* fprintf(stderr, "First chunk position is %d (0x%08x)\n", lt->current_chunk, lt->current_chunk); */ lxt2_wr_emit_u32(lt, 0); /* size of this section (uncompressed) */ lxt2_wr_emit_u32(lt, 0); /* size of this section (compressed) */ lxt2_wr_emit_u64(lt, 0, 0); /* begin time of section */ lxt2_wr_emit_u64(lt, 0, 0); /* end time of section */ fflush(lt->handle); lt->current_chunkz = lt->position; /* fprintf(stderr, "First chunkz position is %d (0x%08x)\n", lt->current_chunkz, lt->current_chunkz); */ if(!using_partial_zip) { lt->zhandle = gzdopen(dup(fileno(lt->handle)), lt->zmode); } else { lt->zpackcount_cumulative = 0; } lt->zpackcount = 0; } for(iter=0; iternumfacs; iter=iter_hi) { unsigned int total_chgs; unsigned int partial_length; total_chgs = 0; /* partial_length = 0; */ /* scan-build : never read */ iter_hi = iter + partial_iter; if(iter_hi > lt->numfacs) iter_hi = lt->numfacs; for(j=iter;jsorted_facs[j]->msk; lt->mapdict = lxt2_wr_ds_splay (msk, lt->mapdict); if((!lt->mapdict)||(lt->mapdict->item != msk)) { lt->mapdict = lxt2_wr_ds_insert(msk, lt->mapdict, lt->num_map_entries); lt->num_map_entries++; if(lt->mapdict_curr) { lt->mapdict_curr->next = lt->mapdict; lt->mapdict_curr = lt->mapdict; } else { lt->mapdict_head = lt->mapdict_curr = lt->mapdict; } } } if(lt->num_map_entries <= 256) { map_nbytes = 1; } else if(lt->num_map_entries <= 256*256) { map_nbytes = 2; } else if(lt->num_map_entries <= 256*256*256) { map_nbytes = 3; } else { map_nbytes = 4; } if((lt->num_dict_entries+LXT2_WR_DICT_START) <= 256) { idx_nbytes = 1; } else if((lt->num_dict_entries+LXT2_WR_DICT_START) <= 256*256) { idx_nbytes = 2; } else if((lt->num_dict_entries+LXT2_WR_DICT_START) <= 256*256*256) { idx_nbytes = 3; } else { idx_nbytes = 4; } if(using_partial) { /* skip */ partial_length = 1 + /* lt->timepos */ lt->timepos * sizeof(lxttime_t)+ /* timevals */ 1 + /* map_nbytes */ (iter_hi-iter) * map_nbytes + /* actual map */ 1; /* idx_nbytes */ for(j=iter;jsorted_facs[j]; total_chgs += s->chgpos; } total_chgs *= idx_nbytes; /* vch skip */ partial_length += total_chgs; /* actual changes */ if(using_partial_zip) { fseeko(lt->handle, 0L, SEEK_END); current_iter_pos = ftello(lt->handle); lxt2_wr_emit_u32(lt, 0); /* size of this section (compressed) */ lxt2_wr_emit_u32(lt, partial_length+9); /* size of this section (uncompressed) */ lxt2_wr_emit_u32(lt, iter); /* begin iter of section */ fflush(lt->handle); lt->zhandle = gzdopen(dup(fileno(lt->handle)), lt->zmode); lt->zpackcount = 0; } lxt2_wr_emit_u8z(lt, LXT2_WR_GRAN_SECT_TIME_PARTIAL); lxt2_wr_emit_u32z(lt, iter); lxt2_wr_emit_u32z(lt, partial_length); } else { lxt2_wr_emit_u8z(lt, LXT2_WR_GRAN_SECT_TIME); } lxt2_wr_emit_u8z(lt, lt->timepos); for(i=0;itimepos;i++) { lxt2_wr_emit_u64z(lt, (lt->timetable[i]>>32)&0xffffffff, lt->timetable[i]&0xffffffff); } gzflush_buffered(lt, 0); lxt2_wr_emit_u8z(lt, map_nbytes); for(j=iter;jsorted_facs[j]; lt->mapdict = lxt2_wr_ds_splay (s->msk, lt->mapdict); val = lt->mapdict->val; switch(map_nbytes) { case 1: lxt2_wr_emit_u8z(lt, val); break; case 2: lxt2_wr_emit_u16z(lt, val); break; case 3: lxt2_wr_emit_u24z(lt, val); break; case 4: lxt2_wr_emit_u32z(lt, val); break; } s->msk = LXT2_WR_GRAN_0VAL; } lxt2_wr_emit_u8z(lt, idx_nbytes); gzflush_buffered(lt, 0); for(j=iter;jsorted_facs[j]; for(i=0;ichgpos;i++) { switch(idx_nbytes) { case 1: lxt2_wr_emit_u8z (lt, s->chg[i]); break; case 2: lxt2_wr_emit_u16z(lt, s->chg[i]); break; case 3: lxt2_wr_emit_u24z(lt, s->chg[i]); break; case 4: lxt2_wr_emit_u32z(lt, s->chg[i]); break; } } s->chgpos = 0; } if(using_partial_zip) { off_t clen; gzflush_buffered(lt, 1); fseeko(lt->handle, 0L, SEEK_END); lt->position=ftello(lt->handle); clen = lt->position - current_iter_pos - 12; fseeko(lt->handle, current_iter_pos, SEEK_SET); lt->zpackcount_cumulative+=lt->zpackcount; lxt2_wr_emit_u32(lt, clen); } else { gzflush_buffered(lt, 0); } } /* ...for(iter) */ lt->timepos = 0; lt->timegranule++; if(lt->break_size) { early_flush = (ftello(lt->handle) >= lt->break_size); } else { early_flush = 0; } if((lt->timegranule>=lt->maxgranule)||(do_finalize)||(early_flush)) { off_t unclen, clen; lxt2_wr_ds_Tree *dt, *dt2; lxt2_wr_dslxt_Tree *ds, *ds2; if(using_partial_zip) { fseeko(lt->handle, 0L, SEEK_END); current_iter_pos = ftello(lt->handle); lxt2_wr_emit_u32(lt, 0); /* size of this section (compressed) */ lxt2_wr_emit_u32(lt, 0); /* size of this section (uncompressed) */ lxt2_wr_emit_u32(lt, ~0); /* control section */ fflush(lt->handle); lt->zhandle = gzdopen(dup(fileno(lt->handle)), lt->zmode); lt->zpackcount = 0; } /* fprintf(stderr, "reached granule %d, finalizing block for section %d\n", lt->timegranule, lt->numsections); */ lt->numsections++; /* finalize string dictionary */ lxt2_wr_emit_u8z(lt, LXT2_WR_GRAN_SECT_DICT); ds = lt->dict_head; /* fprintf(stderr, "num_dict_entries: %d\n", lt->num_dict_entries); */ gzflush_buffered(lt, 0); for(i=0;inum_dict_entries;i++) { /* fprintf(stderr, "%8d %8d) '%s'\n", ds->val, i, ds->item); */ if(ds->val != i) { fprintf(stderr, "internal error line %d\n", __LINE__); exit(255); } lxt2_wr_emit_stringz(lt, ds->item); ds2 = ds->next; free(ds->item); free(ds); ds = ds2; } lt->dict_head = lt->dict_curr = lt->dict = NULL; /* finalize map dictionary */ dt = lt->mapdict_head; /* fprintf(stderr, "num_map_entries: %d\n", lt->num_map_entries); */ gzflush_buffered(lt, 0); for(i=0;inum_map_entries;i++) { /* fprintf(stderr, "+++ %08x (%d)(%d)\n", dt->item, i, dt->val); */ if(((unsigned int)dt->val) != i) { fprintf(stderr, "internal error line %d\n", __LINE__); exit(255); } #if LXT2_WR_GRANULE_SIZE > 32 lxt2_wr_emit_u64z(lt, (dt->item>>32)&0xffffffff, dt->item&0xffffffff); #else lxt2_wr_emit_u32z(lt, dt->item); #endif dt2 = dt->next; free(dt); dt = dt2; } lt->mapdict_head = lt->mapdict_curr = lt->mapdict = NULL; lxt2_wr_emit_u32z(lt, lt->num_dict_entries); /* -12 */ lxt2_wr_emit_u32z(lt, lt->dict_string_mem_required); /* -8 */ lxt2_wr_emit_u32z(lt, lt->num_map_entries); /* -4 */ lt->num_map_entries = 0; lt->num_dict_entries = lt->dict_string_mem_required = 0; /* fprintf(stderr, "returned from finalize..\n"); */ if(using_partial_zip) { off_t c_len; gzflush_buffered(lt, 1); fseeko(lt->handle, 0L, SEEK_END); lt->position=ftello(lt->handle); c_len = lt->position - current_iter_pos - 12; fseeko(lt->handle, current_iter_pos, SEEK_SET); lt->zpackcount_cumulative+=lt->zpackcount; lxt2_wr_emit_u32(lt, c_len); lxt2_wr_emit_u32(lt, lt->zpackcount); } else { gzflush_buffered(lt, 1); } fseeko(lt->handle, 0L, SEEK_END); lt->position=ftello(lt->handle); /* fprintf(stderr, "file position after dumping dict: %d 0x%08x\n", lt->position, lt->position); */ unclen = lt->zpackcount; clen = lt->position - lt->current_chunkz; /* fprintf(stderr, "%d/%d un/compressed bytes in section\n", unclen, clen); */ fseeko(lt->handle, lt->current_chunk, SEEK_SET); if(using_partial_zip) { lxt2_wr_emit_u32(lt, lt->zpackcount_cumulative); lxt2_wr_emit_u32(lt, clen); } else { lxt2_wr_emit_u32(lt, unclen); lxt2_wr_emit_u32(lt, clen); } lxt2_wr_emit_u64(lt, (lt->firsttime>>32)&0xffffffff, lt->firsttime&0xffffffff); lxt2_wr_emit_u64(lt, (lt->lasttime>>32)&0xffffffff, lt->lasttime&0xffffffff); /* fprintf(stderr, "start: %lld, end %lld\n", lt->firsttime, lt->lasttime); */ lt->timegranule=0; lt->numblock++; } if(do_finalize) { lt->flush_valid = 1; lt->flushtime = lt->lasttime; } } int lxt2_wr_set_time64(struct lxt2_wr_trace *lt, lxttime_t timeval) { int rc=0; if(lt) { if(lt->timeset) { if(timeval > lt->maxtime) { if(lt->bumptime) { lt->bumptime = 0; if(!lt->flush_valid) { lt->timepos++; } else { lt->flush_valid = 0; } if(lt->timepos == LXT2_WR_GRANULE_SIZE) { /* fprintf(stderr, "flushing granule to disk at time %d\n", (unsigned int)timeval); */ lxt2_wr_flush_granule(lt, 0); } } /* fprintf(stderr, "updating time to %d (%d dict entries/%d bytes)\n", (unsigned int)timeval, lt->num_dict_entries, lt->dict_string_mem_required); */ lt->timetable[lt->timepos] = timeval; lt->lasttime = timeval; } } else { lt->timeset = 1; lt->mintime = lt->maxtime = timeval; lt->timetable[lt->timepos] = timeval; } if( (!lt->timepos) && (!lt->timegranule) ) { lt->firsttime = timeval; lt->lasttime = timeval; } if( (!lt->timepos) && (!lt->timegranule) && ((!lt->numblock)||(!lt->no_checkpoint)) ) { /* fprintf(stderr, "initial value burst timepos==0, timegranule==0\n"); */ if(lt->blackout) { lt->blackout = 0; lxt2_wr_set_dumpoff(lt); } else { struct lxt2_wr_symbol *s = lt->symchain; while(s) { if((!(s->flags&LXT2_WR_SYM_F_ALIAS))&&(s->rows<2)) { if(!(s->flags&(LXT2_WR_SYM_F_DOUBLE|LXT2_WR_SYM_F_STRING))) { lxt2_wr_emit_value_bit_string(lt, s, 0, s->value); } else if (s->flags&LXT2_WR_SYM_F_DOUBLE) { double value = 0; sscanf(s->value, "%lg", &value); errno = 0; lxt2_wr_emit_value_double(lt, s, 0, value); } else if (s->flags&LXT2_WR_SYM_F_STRING) { lxt2_wr_emit_value_string(lt, s, 0, s->value); } } s=s->symchain; } } /* fprintf(stderr, "done initial value burst timepos==0, timegranule==0\n"); */ } lt->granule_dirty = 1; rc = 1; } return(rc); } /* * sets trace timescale as 10**x seconds */ void lxt2_wr_set_timescale(struct lxt2_wr_trace *lt, int timescale) { if(lt) { lt->timescale = timescale; } } /* * set number of granules per section * (can modify dynamically) */ void lxt2_wr_set_maxgranule(struct lxt2_wr_trace *lt, unsigned int maxgranule) { if(lt) { if(!maxgranule) maxgranule = ~0; lt->maxgranule = maxgranule; } } /* * Sets bracket stripping (useful for VCD conversions of * bitblasted nets) */ void lxt2_wr_symbol_bracket_stripping(struct lxt2_wr_trace *lt, int doit) { if(lt) { lt->do_strip_brackets = (doit!=0); } } static char *lxt2_wr_expand_integer_to_bits(unsigned int len, int value) { static char s[33]; char *p = s; unsigned int i; if(len>32) len=32; len--; for(i=0;i<=len;i++) { *(p++) = '0' | ((value & (1<<(len-i)))!=0); } *p = 0; return(s); } int lxt2_wr_emit_value_int(struct lxt2_wr_trace *lt, struct lxt2_wr_symbol *s, unsigned int row, int value) { int rc=0; if((!lt)||(lt->blackout)||(!s)||(row)) return(rc); return(lxt2_wr_emit_value_bit_string(lt, s, row, lxt2_wr_expand_integer_to_bits(s->len, value))); } int lxt2_wr_emit_value_double(struct lxt2_wr_trace *lt, struct lxt2_wr_symbol *s, unsigned int row, double value) { int rc=0; if((!lt)||(lt->blackout)||(!s)||(row)) return(rc); if(!lt->emitted) { lxt2_wr_emitfacs(lt); lt->emitted = 1; if(!lt->timeset) { lxt2_wr_set_time(lt, 0); } } while(s->aliased_to) /* find root alias if exists */ { s=s->aliased_to; } if(s->flags&LXT2_WR_SYM_F_DOUBLE) { char d_buf[32]; unsigned int idx; rc = 1; sprintf(d_buf, "%.16g", value); if(!strcmp(d_buf, s->value)) return(rc); lt->bumptime = 1; free(s->value); s->value = strdup(d_buf); lt->dict = lxt2_wr_dslxt_splay (s->value, lt->dict); if(!lxt2_wr_dslxt_success) { unsigned int vlen = strlen(d_buf)+1; char *vcopy = (char *)malloc(vlen); strcpy(vcopy, d_buf); lt->dict_string_mem_required += vlen; lt->dict = lxt2_wr_dslxt_insert(vcopy, lt->dict, lt->num_dict_entries); if(lt->dict_curr) { lt->dict_curr->next = lt->dict; lt->dict_curr = lt->dict; } else { lt->dict_head = lt->dict_curr = lt->dict; } idx = lt->num_dict_entries + LXT2_WR_DICT_START; lt->num_dict_entries++; } else { idx = lt->dict->val + LXT2_WR_DICT_START; } if((s->msk & (LXT2_WR_GRAN_1VAL<timepos)) == LXT2_WR_GRAN_0VAL) { s->msk |= (LXT2_WR_GRAN_1VAL<timepos); s->chg[s->chgpos] = idx; s->chgpos++; } else { s->chg[s->chgpos-1] = idx; } lt->granule_dirty = 1; } return(rc); } int lxt2_wr_emit_value_string(struct lxt2_wr_trace *lt, struct lxt2_wr_symbol *s, unsigned int row, char *value) { int rc=0; if((!lt)||(lt->blackout)||(!s)||(!value)||(row)) return(rc); if(!lt->emitted) { lxt2_wr_emitfacs(lt); lt->emitted = 1; if(!lt->timeset) { lxt2_wr_set_time(lt, 0); } } while(s->aliased_to) /* find root alias if exists */ { s=s->aliased_to; } if(s->flags&LXT2_WR_SYM_F_STRING) { unsigned int idx; rc = 1; if(!strcmp(value, s->value)) return(rc); lt->bumptime = 1; free(s->value); s->value = strdup(value); lt->dict = lxt2_wr_dslxt_splay (s->value, lt->dict); if(!lxt2_wr_dslxt_success) { unsigned int vlen = strlen(value)+1; char *vcopy = (char *)malloc(vlen); strcpy(vcopy, value); lt->dict_string_mem_required += vlen; lt->dict = lxt2_wr_dslxt_insert(vcopy, lt->dict, lt->num_dict_entries); if(lt->dict_curr) { lt->dict_curr->next = lt->dict; lt->dict_curr = lt->dict; } else { lt->dict_head = lt->dict_curr = lt->dict; } idx = lt->num_dict_entries + LXT2_WR_DICT_START; lt->num_dict_entries++; } else { idx = lt->dict->val + LXT2_WR_DICT_START; } if((s->msk & (LXT2_WR_GRAN_1VAL<timepos)) == LXT2_WR_GRAN_0VAL) { s->msk |= (LXT2_WR_GRAN_1VAL<timepos); s->chg[s->chgpos] = idx; s->chgpos++; } else { s->chg[s->chgpos-1] = idx; } lt->granule_dirty = 1; } return(rc); } int lxt2_wr_emit_value_bit_string(struct lxt2_wr_trace *lt, struct lxt2_wr_symbol *s, unsigned int row, char *value) { int rc=0; char *vpnt; char *vfix; int valuelen; int i; if((!lt)||(lt->blackout)||(!s)||(!value)||(!*value)||(row)) return(rc); if(!lt->emitted) { lxt2_wr_emitfacs(lt); lt->emitted = 1; if(!lt->timeset) { lxt2_wr_set_time(lt, 0); } } while(s->aliased_to) /* find root alias if exists */ { s=s->aliased_to; } valuelen = strlen(value); /* ensure string is proper length */ if(valuelen == s->len) { vfix = wave_alloca(s->len+1); strcpy(vfix, value); value = vfix; } else { vfix = wave_alloca(s->len+1); if(valuelen < s->len) { int lendelta = s->len - valuelen; memset(vfix, (value[0]!='1') ? value[0] : '0', lendelta); strcpy(vfix+lendelta, value); } else { memcpy(vfix, value, s->len); vfix[s->len] = 0; } value = vfix; } for(i=0;ilen;i++) { unsigned char ch = value[i]; if((ch>='A')&&(ch<='Z')) value[i] = ch + ('a'-'A'); } if ( (lt->timepos || lt->timegranule) && !strcmp(value, s->value) ) { return(1); /* redundant value change */ } if(!(s->flags&(LXT2_WR_SYM_F_DOUBLE|LXT2_WR_SYM_F_STRING))) { char prevch; int idx; lt->bumptime = 1; vpnt = value; prevch = *vpnt; while(*vpnt) { if(prevch == *vpnt) { vpnt++; } else { prevch = 0; break; } } switch(prevch) { case '0': idx = LXT2_WR_ENC_0; break; case '1': idx = LXT2_WR_ENC_1; break; case 'X': case 'x': idx = LXT2_WR_ENC_X; break; case 'Z': case 'z': idx = LXT2_WR_ENC_Z; break; default: idx = -1; break; } if((lt->timepos)||(lt->timegranule)) { for(i=0;ilen;i++) { char ch = value[i]; switch(ch) { case '0': if(s->value[i]!='1') goto nextalg; else break; case '1': if(s->value[i]!='0') goto nextalg; else break; default: goto nextalg; } } idx = LXT2_WR_ENC_INV; goto do_enc; nextalg: if(s->len > 1) { if(!memcmp(s->value+1, value, s->len-1)) { if((value[s->len-1]&0xfe)=='0') { idx = LXT2_WR_ENC_LSH0 + (value[s->len-1]&0x01); goto do_enc; } } else if(!memcmp(s->value, value+1, s->len-1)) { if((value[0]&0xfe)=='0') { idx = LXT2_WR_ENC_RSH0 + (value[0]&0x01); goto do_enc; } } if(s->len <= 32) { unsigned int intval_old = 0, intval_new = 0; unsigned int msk; for(i=0;ilen;i++) { char ch = value[i]; if((ch!='0')&&(ch!='1')) goto idxchk; intval_new <<= 1; intval_new |= ((unsigned int)(ch&1)); ch = s->value[i]; if((ch!='0')&&(ch!='1')) goto idxchk; intval_old <<= 1; intval_old |= ((unsigned int)(ch&1)); } msk = (~0)>>(32-s->len); if( ((intval_old+1)&msk) == intval_new ) { idx = LXT2_WR_ENC_ADD1; goto do_enc; } if( ((intval_old-1)&msk) == intval_new ) { idx = LXT2_WR_ENC_SUB1; goto do_enc; } if( ((intval_old+2)&msk) == intval_new ) { idx = LXT2_WR_ENC_ADD2; goto do_enc; } if( ((intval_old-2)&msk) == intval_new ) { idx = LXT2_WR_ENC_SUB2; goto do_enc; } if( ((intval_old+3)&msk) == intval_new ) { idx = LXT2_WR_ENC_ADD3; goto do_enc; } if( ((intval_old-3)&msk) == intval_new ) { idx = LXT2_WR_ENC_SUB3; goto do_enc; } if(s->len > 2) { if( ((intval_old+4)&msk) == intval_new ) { idx = LXT2_WR_ENC_ADD4; goto do_enc; } if( ((intval_old-4)&msk) == intval_new ) { idx = LXT2_WR_ENC_SUB4; goto do_enc; } } } } } idxchk: if(idx<0) { vpnt = lxt2_wr_vcd_truncate_bitvec(value); lt->dict = lxt2_wr_dslxt_splay (vpnt, lt->dict); if(!lxt2_wr_dslxt_success) { unsigned int vlen = strlen(vpnt)+1; char *vcopy = (char *)malloc(vlen); strcpy(vcopy, vpnt); lt->dict_string_mem_required += vlen; lt->dict = lxt2_wr_dslxt_insert(vcopy, lt->dict, lt->num_dict_entries); if(lt->dict_curr) { lt->dict_curr->next = lt->dict; lt->dict_curr = lt->dict; } else { lt->dict_head = lt->dict_curr = lt->dict; } idx = lt->num_dict_entries + LXT2_WR_DICT_START; lt->num_dict_entries++; } else { idx = lt->dict->val + LXT2_WR_DICT_START; } } do_enc: if((s->msk & (LXT2_WR_GRAN_1VAL<timepos)) == LXT2_WR_GRAN_0VAL) { s->msk |= (LXT2_WR_GRAN_1VAL<timepos); s->chg[s->chgpos] = idx; s->chgpos++; } else { s->chg[s->chgpos-1] = idx; } strncpy(s->value, value, s->len); lt->granule_dirty = 1; } return(rc); } /* * dumping control */ void lxt2_wr_set_dumpoff(struct lxt2_wr_trace *lt) { struct lxt2_wr_symbol *s; if((lt)&&(!lt->blackout)) { if(!lt->emitted) { lxt2_wr_emitfacs(lt); lt->emitted = 1; if(!lt->timeset) { lxt2_wr_set_time(lt, 0); } } s = lt->symchain; while(s) { if(!(s->flags&LXT2_WR_SYM_F_ALIAS)) { if((s->msk & (LXT2_WR_GRAN_1VAL<timepos)) == LXT2_WR_GRAN_0VAL) { s->msk |= (LXT2_WR_GRAN_1VAL<timepos); s->chg[s->chgpos] = LXT2_WR_ENC_BLACKOUT; s->chgpos++; } else { s->chg[s->chgpos-1] = LXT2_WR_ENC_BLACKOUT; } } s=s->symchain; } lt->bumptime = 1; lt->blackout = 1; lt->granule_dirty = 1; } } void lxt2_wr_set_dumpon(struct lxt2_wr_trace *lt) { int i; struct lxt2_wr_symbol *s; if((lt)&&(lt->blackout)) { lt->blackout = 0; s = lt->symchain; while(s) { if(!(s->flags&LXT2_WR_SYM_F_ALIAS)) { if(s->flags&LXT2_WR_SYM_F_DOUBLE) { free(s->value); s->value = strdup("0"); /* will cause mismatch then flush */ } else { if(!(s->flags&LXT2_WR_SYM_F_STRING)) { s->value[0] = '-'; /* will cause mismatch then flush */ for(i=1;ilen;i++) { s->value[i] = 'x'; /* initial value */ } s->value[i]=0; } else { free(s->value); s->value = calloc(1, 1*sizeof(char)); } } } s=s->symchain; } s = lt->symchain; while(s) { if((!(s->flags&LXT2_WR_SYM_F_ALIAS))&&(s->rows<2)) { if(!(s->flags&(LXT2_WR_SYM_F_DOUBLE|LXT2_WR_SYM_F_STRING))) { lxt2_wr_emit_value_bit_string(lt, s, 0, "x"); } else if (s->flags&LXT2_WR_SYM_F_DOUBLE) { double value; sscanf("NaN", "%lg", &value); lxt2_wr_emit_value_double(lt, s, 0, value); } else if (s->flags&LXT2_WR_SYM_F_STRING) { lxt2_wr_emit_value_string(lt, s, 0, "UNDEF"); } } s=s->symchain; } } } /* * flush the trace... */ void lxt2_wr_flush(struct lxt2_wr_trace *lt) { if(lt) { if((lt->timegranule)||(lt->timepos > 0)) { if(lt->granule_dirty) { lt->timepos++; lxt2_wr_flush_granule(lt, 1); } } } } /* * close out the trace and fixate it */ void lxt2_wr_close(struct lxt2_wr_trace *lt) { if(lt) { if(lt->granule_dirty) { lt->timepos++; lxt2_wr_flush_granule(lt, 1); } if(lt->symchain) { struct lxt2_wr_symbol *s = lt->symchain; struct lxt2_wr_symbol *s2; while(s) { free(s->name); free(s->value); s2=s->symchain; free(s); s=s2; } lt->symchain=NULL; } free(lt->lxtname); free(lt->sorted_facs); fclose(lt->handle); free(lt); } } /* * set compression depth */ void lxt2_wr_set_compression_depth(struct lxt2_wr_trace *lt, unsigned int depth) { if(lt) { if(depth > 9) depth = 9; sprintf(lt->zmode, "wb%u", depth); } } /* * time zero offset */ void lxt2_wr_set_timezero(struct lxt2_wr_trace *lt, lxtstime_t timeval) { if(lt) { lt->timezero = timeval; } } gtkwave-3.3.66/src/helpers/lxt2miner.c0000664000076400007640000001662512357342523017140 0ustar bybellbybell/* * Copyright (c) 2003-2009 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include "lxt2_read.h" #if HAVE_GETOPT_H #include #endif #include "wave_locale.h" static char *match = NULL; static unsigned int matchlen = 0; static int names_only = 0; static char *killed_list = NULL; char killed_value = 1; char vcd_blackout; void vcd_callback(struct lxt2_rd_trace **lt, lxtint64_t *pnt_time, lxtint32_t *pnt_facidx, char **pnt_value) { struct lxt2_rd_geometry *g = lxt2_rd_get_fac_geometry(*lt, *pnt_facidx); /* fprintf(stderr, LXT2_RD_LLD" %d %s\n", *pnt_time, *pnt_facidx, *pnt_value); */ if(!(*pnt_value)[0]) { if(!vcd_blackout) { vcd_blackout = 1; /* printf("$dumpoff\n"); */ } return; } else { if(vcd_blackout) { vcd_blackout = 0; /* printf("$dumpon\n"); */ } } if(g->len >= matchlen) { if(!killed_list[*pnt_facidx]) { if((!match)|| (strstr(*pnt_value, match))) { if(g->len > 1) { if(!names_only) { printf("#"LXT2_RD_LLD" %s["LXT2_RD_LD":"LXT2_RD_LD"] %s\n", *pnt_time, lxt2_rd_get_facname(*lt, *pnt_facidx), g->msb, g->lsb, *pnt_value); } else { printf("%s["LXT2_RD_LD":"LXT2_RD_LD"]\n", lxt2_rd_get_facname(*lt, *pnt_facidx), g->msb, g->lsb); } } else { if(g->msb < 0) { if(!names_only) { printf("#"LXT2_RD_LLD" %s %s\n", *pnt_time, lxt2_rd_get_facname(*lt, *pnt_facidx), *pnt_value); } else { printf("%s\n", lxt2_rd_get_facname(*lt, *pnt_facidx)); } } else { if(!names_only) { printf("#"LXT2_RD_LLD" %s["LXT2_RD_LD"] %s\n", *pnt_time, lxt2_rd_get_facname(*lt, *pnt_facidx), g->msb, *pnt_value); } else { printf("%s["LXT2_RD_LD"]\n", lxt2_rd_get_facname(*lt, *pnt_facidx), g->msb); } } } if(killed_value) { lxt2_rd_clr_fac_process_mask(*lt, *pnt_facidx); killed_list[*pnt_facidx] = 1; } } } } } int process_lxt2(char *fname) { struct lxt2_rd_trace *lt; lt=lxt2_rd_init(fname); if(lt) { int numfacs; numfacs = lxt2_rd_get_num_facs(lt); killed_list = calloc(numfacs, sizeof(char)); lxt2_rd_set_fac_process_mask_all(lt); lxt2_rd_set_max_block_mem_usage(lt, 0); /* no need to cache blocks */ lxt2_rd_iter_blocks(lt, vcd_callback, NULL); lxt2_rd_close(lt); free(killed_list); } else { fprintf(stderr, "lxt2_rd_init failed\n"); return(255); } return(0); } /*******************************************************************************/ void print_help(char *nam) { #ifdef __linux__ printf( "Usage: %s [OPTION]... [VZTFILE]\n\n" " -d, --dumpfile=FILE specify LXT2 input dumpfile\n" " -m, --match bitwise match value\n" " -x, --hex hex match value\n" " -n, --namesonly emit facsnames only (gtkwave savefile)\n" " -c, --comprehensive do not stop after first match\n" " -h, --help display this help then exit\n\n" "First occurrence of facnames with times and matching values are emitted to\nstdout. Using -n generates a gtkwave save file.\n\n" "Report bugs to <"PACKAGE_BUGREPORT">.\n",nam); #else printf( "Usage: %s [OPTION]... [VZTFILE]\n\n" " -d specify LXT2 input dumpfile\n" " -m bitwise match value\n" " -x hex match value\n" " -n emit facsnames only\n" " -c do not stop after first match\n" " -h display this help then exit (gtkwave savefile)\n\n" "First occurrence of facnames with times and matching values are emitted to\nstdout. Using -n generates a gtkwave save file.\n\n" "Report bugs to <"PACKAGE_BUGREPORT">.\n",nam); #endif exit(0); } int main(int argc, char **argv) { char opt_errors_encountered=0; char *lxname=NULL; int c; int rc; unsigned int i; int j, k; int comprehensive = 0; WAVE_LOCALE_FIX while (1) { #ifdef __linux__ int option_index = 0; static struct option long_options[] = { {"comprehensive", 0, 0, 'c'}, {"dumpfile", 1, 0, 'd'}, {"match", 1, 0, 'm'}, {"hex", 1, 0, 'x'}, {"namesonly", 0, 0, 'n'}, {"help", 0, 0, 'h'}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "d:m:x:nch", long_options, &option_index); #else c = getopt (argc, argv, "d:m:x:nch"); #endif if (c == -1) break; /* no more args */ switch (c) { case 'c': comprehensive = 1; break; case 'n': names_only = 1; break; case 'd': if(lxname) free(lxname); lxname = malloc(strlen(optarg)+1); strcpy(lxname, optarg); break; case 'm': if(match) free(match); match = malloc((matchlen = strlen(optarg))+1); strcpy(match, optarg); break; case 'x': if(match) free(match); match = malloc((matchlen = 4*strlen(optarg))+1); for(i=0,k=0;i='0')&&(ch<='9')) { ch -= '0'; for(j=0;j<4;j++) { match[i+j] = ((ch>>(3-j))&1) + '0'; } } else if((ch>='a')&&(ch<='f')) { ch = ch - 'a' + 10; for(j=0;j<4;j++) { match[i+j] = ((ch>>(3-j))&1) + '0'; } } else /* "x" */ { for(j=0;j<4;j++) { match[i+j] = 'x'; } } } match[matchlen] = 0; break; case 'h': print_help(argv[0]); break; case '?': opt_errors_encountered=1; break; default: /* unreachable */ break; } } if(opt_errors_encountered) { print_help(argv[0]); } if (optind < argc) { while (optind < argc) { if(!lxname) { lxname = malloc(strlen(argv[optind])+1); strcpy(lxname, argv[optind++]); } else { break; } } } if(!names_only && comprehensive) { killed_value = 0; } if(!lxname) { print_help(argv[0]); } rc=process_lxt2(lxname); free(lxname); return(rc); } gtkwave-3.3.66/src/helpers/scopenav.c0000664000076400007640000000630412341266475017027 0ustar bybellbybell/* * Copyright (c) 2004-2009 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include struct namehier { struct namehier *next; char *name; char not_final; }; static struct namehier *nhold=NULL; void free_hier(void) { struct namehier *nhtemp; while(nhold) { nhtemp=nhold->next; free(nhold->name); free(nhold); nhold=nhtemp; } } /* * navigate up and down the scope hierarchy and * emit the appropriate vcd scope primitives */ static void diff_hier(FILE *fv, struct namehier *nh1, struct namehier *nh2) { if(!nh2) { while((nh1)&&(nh1->not_final)) { fprintf(fv, "$scope module %s $end\n", nh1->name); nh1=nh1->next; } return; } for(;;) { if((nh1->not_final==0)&&(nh2->not_final==0)) /* both are equal */ { break; } if(nh2->not_final==0) /* old hier is shorter */ { while((nh1)&&(nh1->not_final)) { fprintf(fv, "$scope module %s $end\n", nh1->name); nh1=nh1->next; } break; } if(nh1->not_final==0) /* new hier is shorter */ { while((nh2)&&(nh2->not_final)) { fprintf(fv, "$upscope $end\n"); nh2=nh2->next; } break; } if(strcmp(nh1->name, nh2->name)) { /* prune old hier */ while((nh2)&&(nh2->not_final)) { fprintf(fv, "$upscope $end\n"); nh2=nh2->next; } /* add new hier */ while((nh1)&&(nh1->not_final)) { fprintf(fv, "$scope module %s $end\n", nh1->name); nh1=nh1->next; } break; } nh1=nh1->next; nh2=nh2->next; } } /* * output scopedata for a given name if needed, return pointer to name string */ char *fv_output_hier(FILE *fv, char *name) { char *pnt, *pnt2; char *s; int len; struct namehier *nh_head=NULL, *nh_curr=NULL, *nhtemp; char esc = '.'; pnt=pnt2=name; for(;;) { while((*pnt2!=esc)&&(*pnt2)) { if(*pnt2=='\\') { esc = 0; } pnt2++; } s=(char *)calloc(1,(len=pnt2-pnt)+1); memcpy(s, pnt, len); nhtemp=(struct namehier *)calloc(1,sizeof(struct namehier)); nhtemp->name=s; if(!nh_curr) { nh_head=nh_curr=nhtemp; } else { nh_curr->next=nhtemp; nh_curr->not_final=1; nh_curr=nhtemp; } if(!*pnt2) break; pnt=(++pnt2); } diff_hier(fv, nh_head, nhold); free_hier(); nhold=nh_head; return(nh_curr->name); } gtkwave-3.3.66/src/helpers/shmidcat.c0000664000076400007640000001550612523241774017006 0ustar bybellbybell/* * Copyright (c) 2006-2009 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include #include #include #if !defined _MSC_VER && !defined __MINGW32__ #include #include #endif #ifdef __MINGW32__ #include #endif #include #include #include #ifndef _MSC_VER #ifndef __MINGW32__ #include #else #include #endif #endif #include "wave_locale.h" #if !defined _MSC_VER /* size *must* match in gtkwave */ #define WAVE_PARTIAL_VCD_RING_BUFFER_SIZE (1024*1024) char *buf_top, *buf_curr, *buf; char *consume_ptr; unsigned int get_8(char *p) { if(p >= (buf + WAVE_PARTIAL_VCD_RING_BUFFER_SIZE)) { p-= WAVE_PARTIAL_VCD_RING_BUFFER_SIZE; } return((unsigned int)((unsigned char)*p)); } unsigned int get_32(char *p) { unsigned int rc; rc = (get_8(p++) << 24); rc |= (get_8(p++) << 16); rc |= (get_8(p++) << 8); rc |= (get_8(p) << 0); return(rc); } void put_8(char *p, unsigned int v) { if(p >= (buf + WAVE_PARTIAL_VCD_RING_BUFFER_SIZE)) { p -= WAVE_PARTIAL_VCD_RING_BUFFER_SIZE; } *p = (unsigned char)v; } void put_32(char *p, unsigned int v) { put_8(p++, (v>>24)); put_8(p++, (v>>16)); put_8(p++, (v>>8)); put_8(p, (v>>0)); } int consume(void) /* for testing only...similar code also is on the receiving end in gtkwave */ { char mybuff[32769]; int rc; if((rc = *consume_ptr)) { unsigned int len = get_32(consume_ptr+1); unsigned int i; for(i=0;i= (buf + WAVE_PARTIAL_VCD_RING_BUFFER_SIZE)) { consume_ptr -= WAVE_PARTIAL_VCD_RING_BUFFER_SIZE; } } return(rc); } void emit_string(char *s) { int len = strlen(s); uintptr_t l_top, l_curr; int consumed; int blksiz; for(;;) { while(!*buf_top) { if((blksiz = get_32(buf_top+1))) { buf_top += 1 + 4 + blksiz; if(buf_top >= (buf + WAVE_PARTIAL_VCD_RING_BUFFER_SIZE)) { buf_top -= WAVE_PARTIAL_VCD_RING_BUFFER_SIZE; } } else { break; } } l_top = (uintptr_t)buf_top; l_curr = (uintptr_t)buf_curr; if(l_curr >= l_top) { consumed = l_curr - l_top; } else { consumed = (l_curr + WAVE_PARTIAL_VCD_RING_BUFFER_SIZE) - l_top; } if((consumed + len + 16) > WAVE_PARTIAL_VCD_RING_BUFFER_SIZE) /* just a guardband, it's oversized */ { #ifdef __MINGW32__ Sleep(10); #else struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 1000000 / 100; select(0, NULL, NULL, NULL, &tv); #endif continue; } else { char *ss, *sd; put_32(buf_curr + 1, len); sd = buf_curr + 1 + 4; ss = s; while(*ss) { put_8(sd, *ss); ss++; sd++; } put_8(sd, 0); /* next valid */ put_32(sd+1, 0); /* next len */ put_8(buf_curr, 1); /* current valid */ buf_curr += 1 + 4 + len; if(buf_curr >= (buf + WAVE_PARTIAL_VCD_RING_BUFFER_SIZE)) { buf_curr -= WAVE_PARTIAL_VCD_RING_BUFFER_SIZE; } break; } } } /* * example driver code. this merely copies from stdin to the shared memory block. * emit_string() will ensure that buffer overruns do not occur; all you have to * do is write the block with the provision that the last character in the block is * a newline so that the VCD parser doesn't get lost. (in effect, when we run out * of buffer, gtkwave thinks it's EOF, but we restart again later. if the last * character is a newline, we EOF on a null string which is OK.) * the shared memory ID will print on stdout. pass that on to gtkwave for reading. */ int main(int argc, char **argv) { int buf_strlen = 0; char l_buf[32769]; FILE *f; #ifdef __MINGW32__ char mapName[65]; HANDLE hMapFile; #else struct shmid_ds ds; #endif int shmid; WAVE_LOCALE_FIX if(argc != 1) { f = fopen(argv[1], "rb"); if(!f) { fprintf(stderr, "Could not open '%s', exiting.\n", argv[1]); perror("Why"); exit(255); } } else { f = stdin; } #ifdef __MINGW32__ shmid = getpid(); sprintf(mapName, "shmidcat%d", shmid); hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, WAVE_PARTIAL_VCD_RING_BUFFER_SIZE, mapName); if(hMapFile != NULL) { buf_top = buf_curr = buf = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, WAVE_PARTIAL_VCD_RING_BUFFER_SIZE); #else shmid = shmget(0, WAVE_PARTIAL_VCD_RING_BUFFER_SIZE, IPC_CREAT | 0600 ); if(shmid >= 0) { buf_top = buf_curr = buf = shmat(shmid, NULL, 0); #endif memset(buf, 0, WAVE_PARTIAL_VCD_RING_BUFFER_SIZE); #ifdef __linux__ shmctl(shmid, IPC_RMID, &ds); /* mark for destroy, linux allows queuing up destruction now */ #endif printf("%08X\n", shmid); fflush(stdout); consume_ptr = buf; while(!feof(f)) { char *s = fgets(l_buf+buf_strlen, 32768-buf_strlen, f); if(!s) { #ifdef __MINGW32__ Sleep(200); #else struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 1000000 / 5; select(0, NULL, NULL, NULL, &tv); #endif continue; } if(strchr(l_buf+buf_strlen, '\n') || strchr(l_buf+buf_strlen, '\r')) { emit_string(l_buf); buf_strlen = 0; } else { buf_strlen += strlen(l_buf+buf_strlen); /* fprintf(stderr, "update len to: %d\n", buf_strlen); */ } } #ifndef __linux__ #ifdef __MINGW32__ UnmapViewOfFile(buf); CloseHandle(hMapFile); #else shmctl(shmid, IPC_RMID, &ds); /* mark for destroy */ #endif #endif } return(0); } #else int main(int argc, char **argv) { #if defined _MSC_VER fprintf(stderr, "Sorry, this doesn't run under Win32!\n"); #endif fprintf(stderr, "If you find that this program works on your platform, please report this to the maintainers.\n"); return(255); } #endif gtkwave-3.3.66/src/helpers/Makefile.am0000664000076400007640000000457112261434733017100 0ustar bybellbybell## -*- makefile -*- ## BIGFILES = -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 AIXFLAGS = -bmaxdata:0xd0000000/dsa LIBLZMA_CFLAGS = -I$(srcdir)/../liblzma $(LIBXZ_CFLAGS) LIBLZMA_LDADD = $(LIBXZ_LDADD) AM_CFLAGS= -I$(srcdir)/.. -I$(srcdir)/../.. $(LIBZ_CFLAGS) $(LIBBZ2_CFLAGS) $(LIBLZMA_CFLAGS) $(LIBJUDY_CFLAGS) $(EXTLOAD_CFLAGS) -I$(srcdir)/fst -I$(srcdir)/../../contrib/rtlbrowse bin_PROGRAMS= evcd2vcd fst2vcd vcd2fst fstminer ghwdump lxt2miner lxt2vcd \ shmidcat vcd2lxt vcd2lxt2 vcd2vzt \ vzt2vcd vztminer vcd2fst_SOURCES= vcd2fst.c $(srcdir)/fst/lz4.c $(srcdir)/fst/lz4.h $(srcdir)/fst/fastlz.c $(srcdir)/fst/fastlz.h $(srcdir)/fst/fstapi.c $(srcdir)/fst/fstapi.h $(srcdir)/../../contrib/rtlbrowse/jrb.h $(srcdir)/../../contrib/rtlbrowse/jrb.c vcd2fst_LDADD= $(LIBZ_LDADD) $(LIBJUDY_LDADD) fst2vcd_SOURCES= fst2vcd.c $(srcdir)/fst/lz4.c $(srcdir)/fst/lz4.h $(srcdir)/fst/fastlz.c $(srcdir)/fst/fastlz.h $(srcdir)/fst/fstapi.c $(srcdir)/fst/fstapi.h fst2vcd_LDADD= $(LIBZ_LDADD) $(LIBJUDY_LDADD) fstminer_SOURCES= fstminer.c $(srcdir)/fst/lz4.c $(srcdir)/fst/lz4.h $(srcdir)/fst/fastlz.c $(srcdir)/fst/fastlz.h $(srcdir)/fst/fstapi.c $(srcdir)/fst/fstapi.h fstminer_LDADD= $(LIBZ_LDADD) $(LIBJUDY_LDADD) vcd2lxt_SOURCES= vcd2lxt.c lxt_write.c lxt_write.h v2l_analyzer.h v2l_debug.c v2l_debug.h vcd2lxt_LDADD= $(LIBZ_LDADD) $(LIBBZ2_LDADD) lxt2vcd_SOURCES= lxt2_read.c lxt2_read.h lxt2vcd.c scopenav.c lxt2vcd_LDADD= $(LIBZ_LDADD) vcd2lxt2_SOURCES= vcd2lxt2.c lxt2_write.c lxt2_write.h v2l_analyzer_lxt2.h v2l_debug_lxt2.c v2l_debug_lxt2.h vcd2lxt2_LDADD= $(LIBZ_LDADD) vzt2vcd_SOURCES= vzt_read.c vzt_read.h vzt2vcd.c scopenav.c $(srcdir)/../liblzma/LzmaLib.c $(srcdir)/../liblzma/LzmaLib.h vzt2vcd_LDADD= $(LIBZ_LDADD) $(LIBBZ2_LDADD) $(LIBLZMA_LDADD) vcd2vzt_SOURCES= vcd2vzt.c vzt_write.c vzt_write.h v2l_analyzer_lxt2.h v2l_debug_lxt2.c v2l_debug_lxt2.h $(srcdir)/../liblzma/LzmaLib.c $(srcdir)/../liblzma/LzmaLib.h vcd2vzt_LDADD= $(LIBZ_LDADD) $(LIBBZ2_LDADD) $(LIBLZMA_LDADD) vztminer_SOURCES= vztminer.c vzt_read.c vzt_read.h $(srcdir)/../liblzma/LzmaLib.c $(srcdir)/../liblzma/LzmaLib.h vztminer_LDADD= $(LIBZ_LDADD) $(LIBBZ2_LDADD) $(LIBLZMA_LDADD) lxt2miner_SOURCES= lxt2miner.c lxt2_read.c lxt2_read.h lxt2miner_LDADD= $(LIBZ_LDADD) ghwdump_SOURCES= ghwdump.c $(srcdir)/../ghwlib.c evcd2vcd_SOURCES= evcd2vcd.c $(srcdir)/../../contrib/rtlbrowse/jrb.h $(srcdir)/../../contrib/rtlbrowse/jrb.c gtkwave-3.3.66/src/helpers/fst2vcd.c0000664000076400007640000001163712341266475016571 0ustar bybellbybell/* * Copyright (c) 2003-2013 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include "fst/fstapi.h" #if HAVE_GETOPT_H #include #endif #include "wave_locale.h" #define FST_VCD_WRITE_BUF_SIZ (2 * 1024 * 1024) void print_help(char *nam) { #ifdef __linux__ printf( "Usage: %s [OPTION]... [FSTFILE]\n\n" " -f, --fstname=FILE specify FST input filename\n" " -o, --output=FILE specify output filename\n" " -e, --extensions emit FST extensions to VCD\n" " -h, --help display this help then exit\n\n" "VCD is emitted to stdout if output filename is unspecified.\n\n" "Report bugs to <"PACKAGE_BUGREPORT">.\n",nam); #else printf( "Usage: %s [OPTION]... [FSTFILE]\n\n" " -f specify FST input filename\n" " -o specify output filename\n" " -e emit FST extensions to VCD\n" " -h display this help then exit\n\n" "VCD is emitted to stdout if output filename is unspecified.\n\n" "Report bugs to <"PACKAGE_BUGREPORT">.\n",nam); #endif exit(0); } int main(int argc, char **argv) { char opt_errors_encountered=0; char *fstname=NULL; char *outname=NULL; char *fvbuf=NULL; int c; struct fstReaderContext *xc; FILE *fv; int use_extensions = 0; WAVE_LOCALE_FIX while (1) { #ifdef __linux__ int option_index = 0; static struct option long_options[] = { {"extensions", 0, 0, 'e'}, {"fstname", 1, 0, 'f'}, {"output", 1, 0, 'o'}, {"help", 0, 0, 'h'}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "ef:o:h", long_options, &option_index); #else c = getopt (argc, argv, "ef:o:h"); #endif if (c == -1) break; /* no more args */ switch (c) { case 'e': use_extensions = 1; break; case 'f': if(fstname) free(fstname); fstname = malloc(strlen(optarg)+1); strcpy(fstname, optarg); break; case 'o': if(outname) free(outname); outname = malloc(strlen(optarg)+1); strcpy(outname, optarg); break; case 'h': print_help(argv[0]); break; case '?': opt_errors_encountered=1; break; default: /* unreachable */ break; } } if(opt_errors_encountered) { print_help(argv[0]); } if (optind < argc) { while (optind < argc) { if(!fstname) { fstname = malloc(strlen(argv[optind])+1); strcpy(fstname, argv[optind++]); } else { break; } } } if(!fstname) { print_help(argv[0]); } xc = fstReaderOpen(fstname); if(!xc) { fprintf(stderr, "Could not open '%s', exiting.\n", fstname); exit(255); } if(outname) { fv = fopen(outname, "wb"); if(!fv) { fprintf(stderr, "Could not open '%s', exiting.\n", outname); perror("Why"); exit(255); } fvbuf = malloc(FST_VCD_WRITE_BUF_SIZ); setvbuf(fv, fvbuf, _IOFBF, FST_VCD_WRITE_BUF_SIZ); } else { fv = stdout; } fstReaderSetVcdExtensions(xc, use_extensions); /* TRUE is incompatible with vfast and other tools */ if(!fstReaderProcessHier(xc, fv)) /* these 3 lines do all the VCD writing work */ { fprintf(stderr, "could not process hierarchy for '%s', exiting.\n", fstname); exit(255); } fstReaderSetFacProcessMaskAll(xc); /* these 3 lines do all the VCD writing work */ fstReaderIterBlocks(xc, NULL, NULL, fv); /* these 3 lines do all the VCD writing work */ fstReaderClose(xc); if(outname) { free(outname); fclose(fv); } free(fvbuf); free(fstname); exit(0); } gtkwave-3.3.66/src/helpers/v2l_debug_lxt2.c0000664000076400007640000000733412341266475020037 0ustar bybellbybell/* * Copyright (c) 2001 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ /* * debug.c 01feb99ajb * malloc debugs added on 13jul99ajb */ #include #include "v2l_debug_lxt2.h" #ifdef DEBUG_MALLOC /* normally this should be undefined..this is *only* for finding stray allocations/frees */ static struct memchunk *mem=NULL; static size_t mem_total=0; static int mem_chunks=0; static void mem_addnode(void *ptr, size_t size) { struct memchunk *m; m=(struct memchunk *)malloc(sizeof(struct memchunk)); m->ptr=ptr; m->size=size; m->next=mem; mem=m; mem_total+=size; mem_chunks++; fprintf(stderr,"mem_addnode: TC:%05d TOT:%010d PNT:%010p LEN:+%d\n",mem_chunks,mem_total,ptr,size); } static void mem_freenode(void *ptr) { struct memchunk *m, *mprev=NULL; m=mem; while(m) { if(m->ptr==ptr) { if(mprev) { mprev->next=m->next; } else { mem=m->next; } mem_total=mem_total-m->size; mem_chunks--; fprintf(stderr,"mem_freenode: TC:%05d TOT:%010d PNT:%010p LEN:-%d\n",mem_chunks,mem_total,ptr,m->size); free(m); return; } mprev=m; m=m->next; } fprintf(stderr,"mem_freenode: PNT:%010p *INVALID*\n",ptr); sleep(1); } #endif /* * wrapped malloc family... */ void *malloc_2(size_t size) { void *ret; ret=malloc(size); if(ret) { DEBUG_M(mem_addnode(ret,size)); } else { fprintf(stderr, "FATAL ERROR : Out of memory, sorry.\n"); exit(1); } return(ret); } void *realloc_2(void *ptr, size_t size) { void *ret; ret=realloc(ptr, size); if(ret) { DEBUG_M(mem_freenode(ptr)); DEBUG_M(mem_addnode(ret,size)); } else { fprintf(stderr, "FATAL ERROR : Out of memory, sorry.\n"); exit(1); } return(ret); } void *calloc_2(size_t nmemb, size_t size) { void *ret; ret=calloc(nmemb, size); if(ret) { DEBUG_M(mem_addnode(ret, nmemb*size)); } else { fprintf(stderr, "FATAL ERROR: Out of memory, sorry.\n"); exit(1); } return(ret); } void free_2(void *ptr) { if(ptr) { DEBUG_M(mem_freenode(ptr)); free(ptr); } else { fprintf(stderr, "WARNING: Attempt to free NULL pointer caught.\n"); } } /* * atoi 64-bit version.. * y/on default to '1' * n/nonnum default to '0' */ TimeType atoi_64(char *str) { TimeType val=0; unsigned char ch, nflag=0; #if 0 switch(*str) { case 'y': case 'Y': return(LLDescriptor(1)); case 'o': case 'O': str++; ch=*str; if((ch=='n')||(ch=='N')) return(LLDescriptor(1)); else return(LLDescriptor(0)); case 'n': case 'N': return(LLDescriptor(0)); break; default: break; } #endif while((ch=*(str++))) { if((ch>='0')&&(ch<='9')) { val=(val*10+(ch&15)); } else if((ch=='-')&&(val==0)&&(!nflag)) { nflag=1; } else if(val) { break; } } return(nflag?(-val):val); } gtkwave-3.3.66/src/helpers/v2l_analyzer.h0000664000076400007640000000714012341266475017625 0ustar bybellbybell/* * Copyright (c) 2001 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifndef L2V_ANALYZER_H #define L2V_ANALYZER_H #include #include #include #include #include #include #include #include #include "v2l_debug.h" #include "lxt_write.h" #ifndef _MSC_VER #include #endif #define SYMPRIME 500009 #define WAVE_DECOMPRESSOR "gzip -cd " /* zcat alone doesn't cut it for AIX */ typedef struct Node *nptr; typedef struct HistEnt *hptr; typedef struct HistEnt { hptr next; /* next transition in history */ TimeType time; /* time of transition */ TimeType previous_width; /* to avoid thrashing */ union { unsigned char val; /* value: "0XU1"[val] */ char *vector; /* pointer to a whole vector */ } v; } HistEnt; typedef struct ExtNode { int msi, lsi; } ExtNode; struct Node { char *nname; /* ascii name of node */ ExtNode *ext; /* extension to node for vectors */ HistEnt head; /* first entry in transition history */ hptr curr; /* ptr. to current history entry */ hptr *harray; /* fill this in when we make a trace.. contains */ /* a ptr to an array of histents for bsearching */ int numhist; /* number of elements in the harray */ char notdead; /* indicates if this node gets a non-x value */ int numtrans; /* number of transitions */ struct Node *substnode; /* pointer to substitutions on buses */ struct Node *substhead; /* pointer to substitution head (originator) on buses */ }; struct symbol { struct symbol *nextinaet;/* for aet node chaining */ struct HistEnt *h; /* points to previous one */ struct symbol *next; /* for hash chain */ char *name; char selected; /* for the clist object */ struct Node *n; }; struct slist { struct slist *next; char *str; int len; }; struct vcdsymbol { struct vcdsymbol *next; struct lt_symbol *ltsym; char *name; char *id; char *value; struct queuedevent *ev; /* only if vartype==V_EVENT */ struct Node **narray; unsigned int nid; int msi, lsi; int size; unsigned char vartype; }; struct queuedevent { struct queuedevent *next; struct vcdsymbol *sym; TimeType last_event_time; /* make +1 == 0 if there's not an event there too */ }; struct symbol *symfind(char *); struct symbol *symadd(char *, int); int hash(char *s); int sigcmp(char *, char *); void quicksort(struct symbol **, int, int); TimeType vcd_main(char *fname, char *lxname, int dostats, int doclock, int dochange, int dodict, int linear); void append_vcd_slisthier(char *str); #endif gtkwave-3.3.66/src/helpers/lxt2vcd.c0000664000076400007640000002731312341266475016602 0ustar bybellbybell/* * Copyright (c) 2003-2014 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include #include "lxt2_read.h" #if HAVE_GETOPT_H #include #endif #include #include "wave_locale.h" #define LXT_VCD_WRITE_BUF_SIZ (2 * 1024 * 1024) int flat_earth = 0; int notruncate = 0; static FILE *fv = NULL; extern void free_hier(void); extern char *fv_output_hier(FILE *fv, char *name); /* * generate a vcd identifier for a given facindx */ static char *vcdid(unsigned int value) { static char buf[16]; char *pnt = buf; value++; /* zero is illegal for a value...it is assumed they start at one */ while (value) { value--; *(pnt++) = (char)('!' + value % 94); value = value / 94; } *pnt = 0; return(buf); } /* static char *vcdid(int value) { static char buf[16]; int i; for(i=0;i<15;i++) { buf[i]=(char)((value%94)+33); value=value/94; if(!value) {buf[i+1]=0; break;} } return(buf); } */ static char *vcd_truncate_bitvec(char *s) { char l, r; if(notruncate) return(s); r=*s; if(r=='1') { return s; } else { s++; } for(;;s++) { l=r; r=*s; if(!r) return (s-1); if(l!=r) { return(((l=='0')&&(r=='1'))?s:s-1); } } } static lxtint64_t vcd_prevtime; char vcd_blackout; void vcd_callback(struct lxt2_rd_trace **lt, lxtint64_t *pnt_time, lxtint32_t *pnt_facidx, char **pnt_value) { struct lxt2_rd_geometry *g = lxt2_rd_get_fac_geometry(*lt, *pnt_facidx); /* fprintf(stderr, LXT2_RD_LLD" %d %s\n", *pnt_time, *pnt_facidx, *pnt_value); */ if(vcd_prevtime != *pnt_time) { vcd_prevtime = *pnt_time; fprintf(fv, "#"LXT2_RD_LLD"\n", *pnt_time); } if(!(*pnt_value)[0]) { if(!vcd_blackout) { vcd_blackout = 1; fprintf(fv, "$dumpoff\n"); } return; } else { if(vcd_blackout) { vcd_blackout = 0; fprintf(fv, "$dumpon\n"); } } if(g->flags & LXT2_RD_SYM_F_DOUBLE) { fprintf(fv, "r%s %s\n", *pnt_value, vcdid(*pnt_facidx)); } else if(g->flags & LXT2_RD_SYM_F_STRING) { fprintf(fv, "s%s %s\n", *pnt_value, vcdid(*pnt_facidx)); } else { if(g->len==1) { fprintf(fv, "%c%s\n", (*pnt_value)[0], vcdid(*pnt_facidx)); } else { fprintf(fv, "b%s %s\n", vcd_truncate_bitvec(*pnt_value), vcdid(*pnt_facidx)); } } } int process_lxt(char *fname) { struct lxt2_rd_trace *lt; char *netname; lt=lxt2_rd_init(fname); if(lt) { int i; int numfacs; char time_dimension; int time_scale = 1; signed char scale; time_t walltime; lxtsint64_t timezero; numfacs = lxt2_rd_get_num_facs(lt); lxt2_rd_set_fac_process_mask_all(lt); lxt2_rd_set_max_block_mem_usage(lt, 0); /* no need to cache blocks */ scale = lxt2_rd_get_timescale(lt); switch(scale) { case 0: time_dimension = 's'; break; case -1: time_scale = 100; time_dimension = 'm'; break; case -2: time_scale = 10; case -3: time_dimension = 'm'; break; case -4: time_scale = 100; time_dimension = 'u'; break; case -5: time_scale = 10; case -6: time_dimension = 'u'; break; case -10: time_scale = 100; time_dimension = 'p'; break; case -11: time_scale = 10; case -12: time_dimension = 'p'; break; case -13: time_scale = 100; time_dimension = 'f'; break; case -14: time_scale = 10; case -15: time_dimension = 'f'; break; case -7: time_scale = 100; time_dimension = 'n'; break; case -8: time_scale = 10; case -9: default: time_dimension = 'n'; break; } time(&walltime); fprintf(fv, "$date\n"); fprintf(fv, "\t%s",asctime(localtime(&walltime))); fprintf(fv, "$end\n"); fprintf(fv, "$version\n\tlxt2vcd\n$end\n"); fprintf(fv, "$timescale %d%c%c $end\n", time_scale, time_dimension, !scale ? ' ' : 's'); timezero = lxt2_rd_get_timezero(lt); if(timezero) { fprintf(fv, "$timezero "LXT2_RD_LLD" $end\n", timezero); } for(i=0;iflags & LXT2_RD_SYM_F_DOUBLE) { fprintf(fv, "$var real 1 %s %s $end\n", vcdid(newindx), netname); } else if(g->flags & LXT2_RD_SYM_F_STRING) { fprintf(fv, "$var real 1 %s %s $end\n", vcdid(newindx), netname); } else { if(g->len==1) { if(g->msb!=-1) { fprintf(fv, "$var wire 1 %s %s ["LXT2_RD_LD"] $end\n", vcdid(newindx), netname, g->msb); } else { fprintf(fv, "$var wire 1 %s %s $end\n", vcdid(newindx), netname); } } else { if(!(g->flags & LXT2_RD_SYM_F_INTEGER)) { fprintf(fv, "$var wire "LXT2_RD_LD" %s %s ["LXT2_RD_LD":"LXT2_RD_LD"] $end\n", g->len, vcdid(newindx), netname, g->msb, g->lsb); } else { fprintf(fv, "$var integer "LXT2_RD_LD" %s %s $end\n", g->len, vcdid(newindx), netname); } } } } if(!flat_earth) { fv_output_hier(fv, ""); /* flush any remaining hierarchy if not back to toplevel */ free_hier(); } fprintf(fv, "$enddefinitions $end\n"); fprintf(fv, "$dumpvars\n"); vcd_prevtime = lxt2_rd_get_start_time(lt)-1; lxt2_rd_iter_blocks(lt, vcd_callback, NULL); if(vcd_prevtime!=lxt2_rd_get_end_time(lt)) { fprintf(fv, "#"LXT2_RD_LLD"\n", lxt2_rd_get_end_time(lt)); } lxt2_rd_close(lt); } else { fprintf(stderr, "lxt2_rd_init failed\n"); return(255); } return(0); } /*******************************************************************************/ void print_help(char *nam) { #ifdef __linux__ printf( "Usage: %s [OPTION]... [LXT2FILE]\n\n" " -l, --lxtname=FILE specify LXT2 input filename\n" " -o, --output=FILE specify output filename\n" " -f, --flatearth emit flattened hierarchies\n" " -n, --notruncate do not shorten bitvectors\n" " -h, --help display this help then exit\n\n" "VCD is emitted to stdout if output filename is unspecified.\n\n" "Report bugs to <"PACKAGE_BUGREPORT">.\n",nam); #else printf( "Usage: %s [OPTION]... [LXT2FILE]\n\n" " -l specify LXT2 input filename\n" " -o specify output filename\n" " -f emit flattened hierarchies\n" " -n do not shorten bitvectors\n" " -h display this help then exit\n\n" "VCD is emitted to stdout if output filename is unspecified.\n\n" "Report bugs to <"PACKAGE_BUGREPORT">.\n",nam); #endif exit(0); } int main(int argc, char **argv) { char opt_errors_encountered=0; char *lxname=NULL; char *outname=NULL; char *fvbuf=NULL; int c; int rc; WAVE_LOCALE_FIX while (1) { #ifdef __linux__ int option_index = 0; static struct option long_options[] = { {"lxtname", 1, 0, 'l'}, {"output", 1, 0, 'o'}, {"flatearth", 0, 0, 'f'}, {"notruncate", 0, 0, 'n'}, {"help", 0, 0, 'h'}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "l:o:fnh", long_options, &option_index); #else c = getopt (argc, argv, "l:o:fnh"); #endif if (c == -1) break; /* no more args */ switch (c) { case 'l': if(lxname) free(lxname); lxname = malloc(strlen(optarg)+1); strcpy(lxname, optarg); break; case 'o': if(outname) free(outname); outname = malloc(strlen(optarg)+1); strcpy(outname, optarg); break; case 'f': flat_earth=1; break; case 'n': notruncate=1; break; case 'h': print_help(argv[0]); break; case '?': opt_errors_encountered=1; break; default: /* unreachable */ break; } } if(opt_errors_encountered) { print_help(argv[0]); } if (optind < argc) { while (optind < argc) { if(!lxname) { lxname = malloc(strlen(argv[optind])+1); strcpy(lxname, argv[optind++]); } else { break; } } } if(!lxname) { print_help(argv[0]); } if(outname) { fv = fopen(outname, "wb"); if(!fv) { fprintf(stderr, "Could not open '%s', exiting.\n", outname); perror("Why"); exit(255); } fvbuf = malloc(LXT_VCD_WRITE_BUF_SIZ); setvbuf(fv, fvbuf, _IOFBF, LXT_VCD_WRITE_BUF_SIZ); } else { fv = stdout; } rc=process_lxt(lxname); if(outname) { free(outname); fclose(fv); } free(fvbuf); free(lxname); return(rc); } gtkwave-3.3.66/src/helpers/v2l_debug.c0000664000076400007640000000732712341266475017070 0ustar bybellbybell/* * Copyright (c) 2001 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ /* * debug.c 01feb99ajb * malloc debugs added on 13jul99ajb */ #include #include "v2l_debug.h" #ifdef DEBUG_MALLOC /* normally this should be undefined..this is *only* for finding stray allocations/frees */ static struct memchunk *mem=NULL; static size_t mem_total=0; static int mem_chunks=0; static void mem_addnode(void *ptr, size_t size) { struct memchunk *m; m=(struct memchunk *)malloc(sizeof(struct memchunk)); m->ptr=ptr; m->size=size; m->next=mem; mem=m; mem_total+=size; mem_chunks++; fprintf(stderr,"mem_addnode: TC:%05d TOT:%010d PNT:%010p LEN:+%d\n",mem_chunks,mem_total,ptr,size); } static void mem_freenode(void *ptr) { struct memchunk *m, *mprev=NULL; m=mem; while(m) { if(m->ptr==ptr) { if(mprev) { mprev->next=m->next; } else { mem=m->next; } mem_total=mem_total-m->size; mem_chunks--; fprintf(stderr,"mem_freenode: TC:%05d TOT:%010d PNT:%010p LEN:-%d\n",mem_chunks,mem_total,ptr,m->size); free(m); return; } mprev=m; m=m->next; } fprintf(stderr,"mem_freenode: PNT:%010p *INVALID*\n",ptr); sleep(1); } #endif /* * wrapped malloc family... */ void *malloc_2(size_t size) { void *ret; ret=malloc(size); if(ret) { DEBUG_M(mem_addnode(ret,size)); return(ret); } else { fprintf(stderr, "FATAL ERROR : Out of memory, sorry.\n"); exit(1); } } void *realloc_2(void *ptr, size_t size) { void *ret; ret=realloc(ptr, size); if(ret) { DEBUG_M(mem_freenode(ptr)); DEBUG_M(mem_addnode(ret,size)); return(ret); } else { fprintf(stderr, "FATAL ERROR : Out of memory, sorry.\n"); exit(1); } } void *calloc_2(size_t nmemb, size_t size) { void *ret; ret=calloc(nmemb, size); if(ret) { DEBUG_M(mem_addnode(ret, nmemb*size)); return(ret); } else { fprintf(stderr, "FATAL ERROR: Out of memory, sorry.\n"); exit(1); } } void free_2(void *ptr) { if(ptr) { DEBUG_M(mem_freenode(ptr)); free(ptr); } else { fprintf(stderr, "WARNING: Attempt to free NULL pointer caught.\n"); } } /* * atoi 64-bit version.. * y/on default to '1' * n/nonnum default to '0' */ TimeType atoi_64(char *str) { TimeType val=0; unsigned char ch, nflag=0; #if 0 switch(*str) { case 'y': case 'Y': return(LLDescriptor(1)); case 'o': case 'O': str++; ch=*str; if((ch=='n')||(ch=='N')) return(LLDescriptor(1)); else return(LLDescriptor(0)); case 'n': case 'N': return(LLDescriptor(0)); break; default: break; } #endif while((ch=*(str++))) { if((ch>='0')&&(ch<='9')) { val=(val*10+(ch&15)); } else if((ch=='-')&&(val==0)&&(!nflag)) { nflag=1; } else if(val) { break; } } return(nflag?(-val):val); } gtkwave-3.3.66/src/helpers/vzt_write.h0000664000076400007640000002362512341266475017260 0ustar bybellbybell/* * Copyright (c) 2004-2010 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifndef DEFS_VZTW_H #define DEFS_VZTW_H #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include #include #ifdef HAVE_INTTYPES_H #include #endif #include #include #include #ifndef HAVE_FSEEKO #define fseeko fseek #define ftello ftell #endif #define VZT_WR_HDRID (('V' << 8) + ('Z')) #define VZT_WR_VERSION (0x0001) #define VZT_WR_GRANULE_SIZE (32) #define VZT_WR_GRANULE_NUM (8) #define VZT_WR_GZWRITE_BUFFER 4096 #define VZT_WR_SYMPRIME 500009 #ifndef _MSC_VER typedef uint8_t vztint8_t; typedef uint16_t vztint16_t; typedef uint32_t vztint32_t; typedef uint64_t vztint64_t; typedef int32_t vztsint32_t; typedef int64_t vztsint64_t; typedef uint64_t vzttime_t; #ifndef __MINGW32__ #define VZT_WR_LLD "%lld" #else #define VZT_WR_LLD "%I64d" #endif #define VZT_WR_LLDESC(x) x##LL #define VZT_WR_ULLDESC(x) x##ULL #else typedef unsigned __int8 vztint8_t; typedef unsigned __int16 vztint16_t; typedef unsigned __int32 vztint32_t; typedef unsigned __int64 vztint64_t; typedef __int32 vztsint32_t; typedef __int64 vztsint64_t; typedef unsigned __int64 vzttime_t; #define VZT_WR_LLD "%I64d" #define VZT_WR_LLDESC(x) x##i64 #define VZT_WR_ULLDESC(x) x##i64 #endif #ifdef __GNUC__ #if __STDC_VERSION__ >= 199901L #define _VZT_WR_INLINE inline __attribute__((__gnu_inline__)) #else #define _VZT_WR_INLINE inline #endif #else #define _VZT_WR_INLINE #endif /* * integer splay */ typedef struct vzt_wr_dsvzt_tree_node vzt_wr_dsvzt_Tree; struct vzt_wr_dsvzt_tree_node { vzt_wr_dsvzt_Tree * left, * right; vzt_wr_dsvzt_Tree * child; vztint32_t item; vztint32_t val; }; /* * string splay */ typedef struct vzt2_wr_dsvzt_tree_node vzt2_wr_dsvzt_Tree; struct vzt2_wr_dsvzt_tree_node { vzt2_wr_dsvzt_Tree * left, * right; char *item; unsigned int val; vzt2_wr_dsvzt_Tree * next; }; struct vzt_wr_trace { FILE *handle; void *zhandle; vzt_wr_dsvzt_Tree *dict; vzt_wr_dsvzt_Tree *dict_cache; /* for fast malloc/free */ int numstrings; vzt2_wr_dsvzt_Tree *str_head, *str_curr, *str; /* for potential string vchgs */ off_t position; off_t zfacname_predec_size, zfacname_size, zfacgeometry_size; off_t zpackcount, zpackcount_cumulative; off_t current_chunk, current_chunkz; struct vzt_wr_symbol **sorted_facs; struct vzt_wr_symbol *symchain; int numfacs, numalias; int numfacbytes; int longestname; int numsections, numblock; off_t facname_offset, facgeometry_offset; vzttime_t mintime, maxtime; unsigned int timegranule; int timescale; int timepos; vzttime_t *timetable; unsigned int maxgranule; vzttime_t firsttime, lasttime; char *compress_fac_str; int compress_fac_len; vztsint64_t timezero; vzttime_t flushtime; unsigned flush_valid : 1; unsigned do_strip_brackets : 1; unsigned emitted : 1; /* gate off change field zmode changes when set */ unsigned timeset : 1; /* time has been modified from 0..0 */ unsigned bumptime : 1; /* says that must go to next time position in granule as value change exists for current time */ unsigned granule_dirty : 1; /* for flushing out final block */ unsigned blackout : 1; /* blackout on/off */ unsigned multi_state : 1; /* 2 or 4 state marker */ unsigned use_multi_state : 1; /* if zero, can shortcut to 2 state */ unsigned ztype : 2; /* 0: gzip (default), 1: bzip2, 2: lzma */ unsigned ztype_cfg : 2; /* 0: gzip (default), 1: bzip2, 2: lzma */ unsigned rle : 1; /* emit rle packed value section */ unsigned rle_start : 1; /* initial/previous rle value */ char initial_value; char zmode[4]; /* fills in with "wb0".."wb9" */ unsigned int gzbufpnt; char *vztname; off_t break_size; off_t break_header_size; unsigned int break_number; /* larger datasets at end */ unsigned char gzdest[VZT_WR_GZWRITE_BUFFER + 10]; /* enough for zlib buffering */ struct vzt_wr_symbol *sym[VZT_WR_SYMPRIME]; }; struct vzt_wr_symbol { struct vzt_wr_symbol *next; struct vzt_wr_symbol *symchain; char *name; int namlen; int facnum; struct vzt_wr_symbol *aliased_to; unsigned int rows; int msb, lsb; int len; int flags; vzt_wr_dsvzt_Tree **prev; /* previous chain (for len bits) */ vztint32_t *chg; /* for len bits */ vzt_wr_dsvzt_Tree **prevx; /* previous xchain (for len bits) */ vztint32_t *chgx; /* for len xbits */ }; #define VZT_WR_IS_GZ (0) #define VZT_WR_IS_BZ2 (1) #define VZT_WR_IS_LZMA (2) #define VZT_WR_SYM_F_BITS (0) #define VZT_WR_SYM_F_INTEGER (1<<0) #define VZT_WR_SYM_F_DOUBLE (1<<1) #define VZT_WR_SYM_F_STRING (1<<2) #define VZT_WR_SYM_F_TIME (VZT_WR_SYM_F_STRING) /* user must correctly format this as a string */ #define VZT_WR_SYM_F_ALIAS (1<<3) #define VZT_WR_SYM_F_SIGNED (1<<4) #define VZT_WR_SYM_F_BOOLEAN (1<<5) #define VZT_WR_SYM_F_NATURAL ((1<<6)|(VZT_WR_SYM_F_INTEGER)) #define VZT_WR_SYM_F_POSITIVE ((1<<7)|(VZT_WR_SYM_F_INTEGER)) #define VZT_WR_SYM_F_CHARACTER (1<<8) #define VZT_WR_SYM_F_CONSTANT (1<<9) #define VZT_WR_SYM_F_VARIABLE (1<<10) #define VZT_WR_SYM_F_SIGNAL (1<<11) #define VZT_WR_SYM_F_IN (1<<12) #define VZT_WR_SYM_F_OUT (1<<13) #define VZT_WR_SYM_F_INOUT (1<<14) #define VZT_WR_SYM_F_WIRE (1<<15) #define VZT_WR_SYM_F_REG (1<<16) #define VZT_WR_SYM_MASK (VZT_WR_SYM_F_BITS|VZT_WR_SYM_F_INTEGER|VZT_WR_SYM_F_DOUBLE|VZT_WR_SYM_F_STRING|VZT_WR_SYM_F_TIME| \ VZT_WR_SYM_F_ALIAS|VZT_WR_SYM_F_SIGNED|VZT_WR_SYM_F_BOOLEAN|VZT_WR_SYM_F_NATURAL| \ VZT_WR_SYM_F_POSITIVE|VZT_WR_SYM_F_CHARACTER|VZT_WR_SYM_F_CONSTANT|VZT_WR_SYM_F_VARIABLE| \ VZT_WR_SYM_F_SIGNAL|VZT_WR_SYM_F_IN|VZT_WR_SYM_F_OUT|VZT_WR_SYM_F_INOUT|VZT_WR_SYM_F_WIRE| \ VZT_WR_SYM_F_REG) #define VZT_WR_SYM_F_SYNVEC (1<<17) /* reader synthesized vector in alias sec'n from non-adjacent vectorizing */ /* file I/O */ struct vzt_wr_trace * vzt_wr_init(const char *name); void vzt_wr_flush(struct vzt_wr_trace *lt); void vzt_wr_close(struct vzt_wr_trace *lt); /* for dealing with very large traces, split into multiple files approximately "siz" in length */ void vzt_wr_set_break_size(struct vzt_wr_trace *lt, off_t siz); /* 0 = gzip, 1 = bzip2 */ void vzt_wr_set_compression_type(struct vzt_wr_trace *lt, unsigned int type); /* 0 = no compression, 9 = best compression, 4 = default */ void vzt_wr_set_compression_depth(struct vzt_wr_trace *lt, unsigned int depth); /* 0 = pure value changes, 1 = rle packed */ void vzt_wr_set_rle(struct vzt_wr_trace *lt, unsigned int mode); /* bitplane depth: must call before adding any facilities */ void vzt_wr_force_twostate(struct vzt_wr_trace *lt); /* facility creation */ void vzt_wr_set_initial_value(struct vzt_wr_trace *lt, char value); struct vzt_wr_symbol * vzt_wr_symbol_find(struct vzt_wr_trace *lt, const char *name); struct vzt_wr_symbol * vzt_wr_symbol_add(struct vzt_wr_trace *lt, const char *name, unsigned int rows, int msb, int lsb, int flags); struct vzt_wr_symbol * vzt_wr_symbol_alias(struct vzt_wr_trace *lt, const char *existing_name, const char *alias, int msb, int lsb); void vzt_wr_symbol_bracket_stripping(struct vzt_wr_trace *lt, int doit); /* each granule is VZT_WR_GRANULE_SIZE (32) timesteps, default is 8 per section */ void vzt_wr_set_maxgranule(struct vzt_wr_trace *lt, unsigned int maxgranule); /* time ops */ void vzt_wr_set_timescale(struct vzt_wr_trace *lt, int timescale); void vzt_wr_set_timezero(struct vzt_wr_trace *lt, vztsint64_t timeval); int vzt_wr_set_time(struct vzt_wr_trace *lt, unsigned int timeval); int vzt_wr_inc_time_by_delta(struct vzt_wr_trace *lt, unsigned int timeval); int vzt_wr_set_time64(struct vzt_wr_trace *lt, vzttime_t timeval); int vzt_wr_inc_time_by_delta64(struct vzt_wr_trace *lt, vzttime_t timeval); /* allows blackout regions in VZT files */ void vzt_wr_set_dumpoff(struct vzt_wr_trace *lt); void vzt_wr_set_dumpon(struct vzt_wr_trace *lt); /* left fill on bit_string uses vcd semantics (left fill with value[0] unless value[0]=='1', then use '0') */ int vzt_wr_emit_value_int(struct vzt_wr_trace *lt, struct vzt_wr_symbol *s, unsigned int row, int value); int vzt_wr_emit_value_double(struct vzt_wr_trace *lt, struct vzt_wr_symbol *s, unsigned int row, double value); int vzt_wr_emit_value_string(struct vzt_wr_trace *lt, struct vzt_wr_symbol *s, unsigned int row, char *value); int vzt_wr_emit_value_bit_string(struct vzt_wr_trace *lt, struct vzt_wr_symbol *s, unsigned int row, char *value); #ifdef __cplusplus } #endif #endif gtkwave-3.3.66/src/helpers/lxt2_write.h0000664000076400007640000002321512357036356017321 0ustar bybellbybell/* * Copyright (c) 2003-2012 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifndef DEFS_LXTW_H #define DEFS_LXTW_H #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include #include #ifdef HAVE_INTTYPES_H #include #endif #include #ifndef HAVE_FSEEKO #define fseeko fseek #define ftello ftell #endif #include #define LXT2_WR_HDRID (0x1380) #define LXT2_WR_VERSION (0x0001) #define LXT2_WR_GRANULE_SIZE (64) #define LXT2_WR_GRANULE_NUM (256) #define LXT2_WR_PARTIAL_SIZE (2048) #define LXT2_WR_GRAN_SECT_TIME 0 #define LXT2_WR_GRAN_SECT_DICT 1 #define LXT2_WR_GRAN_SECT_TIME_PARTIAL 2 #define LXT2_WR_GZWRITE_BUFFER 4096 #define LXT2_WR_SYMPRIME 500009 typedef uint64_t lxttime_t; typedef int64_t lxtstime_t; #ifndef _MSC_VER #ifdef __MINGW32__ #define LXT2_WR_LLD "%I64d" #else #define LXT2_WR_LLD "%lld" #endif #define LXT2_WR_LLDESC(x) x##LL #define LXT2_WR_ULLDESC(x) x##ULL #else #define LXT2_WR_LLD "%I64d" #define LXT2_WR_LLDESC(x) x##i64 #define LXT2_WR_ULLDESC(x) x##i64 #endif #if LXT2_WR_GRANULE_SIZE > 32 typedef unsigned long long granmsk_t; #define LXT2_WR_GRAN_0VAL (LXT2_WR_ULLDESC(0)) #define LXT2_WR_GRAN_1VAL (LXT2_WR_ULLDESC(1)) #else typedef unsigned int granmsk_t; #define LXT2_WR_GRAN_0VAL (0) #define LXT2_WR_GRAN_1VAL (1) #endif enum LXT2_WR_Encodings { LXT2_WR_ENC_0, LXT2_WR_ENC_1, LXT2_WR_ENC_INV, LXT2_WR_ENC_LSH0, LXT2_WR_ENC_LSH1, LXT2_WR_ENC_RSH0, LXT2_WR_ENC_RSH1, LXT2_WR_ENC_ADD1, LXT2_WR_ENC_ADD2, LXT2_WR_ENC_ADD3, LXT2_WR_ENC_ADD4, LXT2_WR_ENC_SUB1, LXT2_WR_ENC_SUB2, LXT2_WR_ENC_SUB3, LXT2_WR_ENC_SUB4, LXT2_WR_ENC_X, LXT2_WR_ENC_Z, LXT2_WR_ENC_BLACKOUT, LXT2_WR_DICT_START }; /* * integer splay */ typedef struct lxt2_wr_ds_tree_node lxt2_wr_ds_Tree; struct lxt2_wr_ds_tree_node { lxt2_wr_ds_Tree * left, * right; granmsk_t item; int val; lxt2_wr_ds_Tree * next; }; /* * string splay */ typedef struct lxt2_wr_dslxt_tree_node lxt2_wr_dslxt_Tree; struct lxt2_wr_dslxt_tree_node { lxt2_wr_dslxt_Tree * left, * right; char *item; unsigned int val; lxt2_wr_dslxt_Tree * next; }; struct lxt2_wr_trace { FILE *handle; gzFile zhandle; lxt2_wr_dslxt_Tree *dict; /* dictionary manipulation */ unsigned int num_dict_entries; unsigned int dict_string_mem_required; lxt2_wr_dslxt_Tree *dict_head; lxt2_wr_dslxt_Tree *dict_curr; lxt2_wr_ds_Tree *mapdict; /* bitmap compression */ unsigned int num_map_entries; lxt2_wr_ds_Tree *mapdict_head; lxt2_wr_ds_Tree *mapdict_curr; off_t position; off_t zfacname_predec_size, zfacname_size, zfacgeometry_size; off_t zpackcount, zpackcount_cumulative; off_t current_chunk, current_chunkz; struct lxt2_wr_symbol *sym[LXT2_WR_SYMPRIME]; struct lxt2_wr_symbol **sorted_facs; struct lxt2_wr_symbol *symchain; unsigned int numfacs, numalias; int numfacbytes; int longestname; int numsections, numblock; off_t facname_offset, facgeometry_offset; lxttime_t mintime, maxtime; lxtstime_t timezero; unsigned int timegranule; int timescale; unsigned int timepos; unsigned int maxgranule; lxttime_t firsttime, lasttime; lxttime_t timetable[LXT2_WR_GRANULE_SIZE]; unsigned int partial_iter; char *compress_fac_str; int compress_fac_len; lxttime_t flushtime; unsigned flush_valid : 1; unsigned do_strip_brackets : 1; unsigned emitted : 1; /* gate off change field zmode changes when set */ unsigned timeset : 1; /* time has been modified from 0..0 */ unsigned bumptime : 1; /* says that must go to next time position in granule as value change exists for current time */ unsigned granule_dirty : 1; /* for flushing out final block */ unsigned blackout : 1; /* blackout on/off */ unsigned partial : 1; /* partial (vertical) trace support */ unsigned partial_zip : 1; /* partial (vertical) trace support for zip subregions */ unsigned no_checkpoint : 1; /* turns off interblock checkpointing */ unsigned partial_preference : 1; /* partial preference encountered on some facs */ char initial_value; char zmode[4]; /* fills in with "wb0".."wb9" */ unsigned int gzbufpnt; unsigned char gzdest[LXT2_WR_GZWRITE_BUFFER + 4]; /* enough for zlib buffering */ char *lxtname; off_t break_size; off_t break_header_size; unsigned int break_number; }; struct lxt2_wr_symbol { struct lxt2_wr_symbol *next; struct lxt2_wr_symbol *symchain; char *name; int namlen; int facnum; struct lxt2_wr_symbol *aliased_to; char *value; /* fac's actual value */ unsigned int rows; int msb, lsb; int len; int flags; unsigned partial_preference : 1; /* in order to shove nets to the first partial group */ unsigned int chgpos; granmsk_t msk; /* must contain LXT2_WR_GRANULE_SIZE bits! */ unsigned int chg[LXT2_WR_GRANULE_SIZE]; }; #define LXT2_WR_SYM_F_BITS (0) #define LXT2_WR_SYM_F_INTEGER (1<<0) #define LXT2_WR_SYM_F_DOUBLE (1<<1) #define LXT2_WR_SYM_F_STRING (1<<2) #define LXT2_WR_SYM_F_TIME (LXT2_WR_SYM_F_STRING) /* user must correctly format this as a string */ #define LXT2_WR_SYM_F_ALIAS (1<<3) #define LXT2_WR_SYM_F_SIGNED (1<<4) #define LXT2_WR_SYM_F_BOOLEAN (1<<5) #define LXT2_WR_SYM_F_NATURAL ((1<<6)|(LXT2_WR_SYM_F_INTEGER)) #define LXT2_WR_SYM_F_POSITIVE ((1<<7)|(LXT2_WR_SYM_F_INTEGER)) #define LXT2_WR_SYM_F_CHARACTER (1<<8) #define LXT2_WR_SYM_F_CONSTANT (1<<9) #define LXT2_WR_SYM_F_VARIABLE (1<<10) #define LXT2_WR_SYM_F_SIGNAL (1<<11) #define LXT2_WR_SYM_F_IN (1<<12) #define LXT2_WR_SYM_F_OUT (1<<13) #define LXT2_WR_SYM_F_INOUT (1<<14) #define LXT2_WR_SYM_F_WIRE (1<<15) #define LXT2_WR_SYM_F_REG (1<<16) /* file I/O */ struct lxt2_wr_trace * lxt2_wr_init(const char *name); void lxt2_wr_flush(struct lxt2_wr_trace *lt); void lxt2_wr_close(struct lxt2_wr_trace *lt); /* for dealing with very large traces, split into multiple files approximately "siz" in length */ void lxt2_wr_set_break_size(struct lxt2_wr_trace *lt, off_t siz); /* 0 = no compression, 9 = best compression, 4 = default */ void lxt2_wr_set_compression_depth(struct lxt2_wr_trace *lt, unsigned int depth); /* default is partial off, turning on makes for faster trace reads, nonzero zipmode causes vertical compression */ void lxt2_wr_set_partial_off(struct lxt2_wr_trace *lt); void lxt2_wr_set_partial_on(struct lxt2_wr_trace *lt, int zipmode); void lxt2_wr_set_partial_preference(struct lxt2_wr_trace *lt, const char *name); /* turning off checkpointing makes for smaller files */ void lxt2_wr_set_checkpoint_off(struct lxt2_wr_trace *lt); void lxt2_wr_set_checkpoint_on(struct lxt2_wr_trace *lt); /* facility creation */ void lxt2_wr_set_initial_value(struct lxt2_wr_trace *lt, char value); struct lxt2_wr_symbol * lxt2_wr_symbol_find(struct lxt2_wr_trace *lt, const char *name); struct lxt2_wr_symbol * lxt2_wr_symbol_add(struct lxt2_wr_trace *lt, const char *name, unsigned int rows, int msb, int lsb, int flags); struct lxt2_wr_symbol * lxt2_wr_symbol_alias(struct lxt2_wr_trace *lt, const char *existing_name, const char *alias, int msb, int lsb); void lxt2_wr_symbol_bracket_stripping(struct lxt2_wr_trace *lt, int doit); /* each granule is LXT2_WR_GRANULE_SIZE (32 or 64) timesteps, default is 256 per section */ void lxt2_wr_set_maxgranule(struct lxt2_wr_trace *lt, unsigned int maxgranule); /* time ops */ void lxt2_wr_set_timescale(struct lxt2_wr_trace *lt, int timescale); void lxt2_wr_set_timezero(struct lxt2_wr_trace *lt, lxtstime_t timeval); int lxt2_wr_set_time(struct lxt2_wr_trace *lt, unsigned int timeval); int lxt2_wr_inc_time_by_delta(struct lxt2_wr_trace *lt, unsigned int timeval); int lxt2_wr_set_time64(struct lxt2_wr_trace *lt, lxttime_t timeval); int lxt2_wr_inc_time_by_delta64(struct lxt2_wr_trace *lt, lxttime_t timeval); /* allows blackout regions in LXT files */ void lxt2_wr_set_dumpoff(struct lxt2_wr_trace *lt); void lxt2_wr_set_dumpon(struct lxt2_wr_trace *lt); /* left fill on bit_string uses vcd semantics (left fill with value[0] unless value[0]=='1', then use '0') */ int lxt2_wr_emit_value_int(struct lxt2_wr_trace *lt, struct lxt2_wr_symbol *s, unsigned int row, int value); int lxt2_wr_emit_value_double(struct lxt2_wr_trace *lt, struct lxt2_wr_symbol *s, unsigned int row, double value); int lxt2_wr_emit_value_string(struct lxt2_wr_trace *lt, struct lxt2_wr_symbol *s, unsigned int row, char *value); int lxt2_wr_emit_value_bit_string(struct lxt2_wr_trace *lt, struct lxt2_wr_symbol *s, unsigned int row, char *value); #ifdef __cplusplus } #endif #endif gtkwave-3.3.66/src/helpers/fst/0000775000076400007640000000000012546303362015630 5ustar bybellbybellgtkwave-3.3.66/src/helpers/fst/Makefile.in0000664000076400007640000004007212261434733017701 0ustar bybellbybell# Makefile.in generated by automake 1.13.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 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__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } 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 = : subdir = src/helpers/fst DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LIBRARIES = $(noinst_LIBRARIES) AR = ar ARFLAGS = cru AM_V_AR = $(am__v_AR_@AM_V@) am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) am__v_AR_0 = @echo " AR " $@; am__v_AR_1 = libfst_a_AR = $(AR) $(ARFLAGS) libfst_a_LIBADD = am_libfst_a_OBJECTS = fastlz.$(OBJEXT) lz4.$(OBJEXT) fstapi.$(OBJEXT) libfst_a_OBJECTS = $(am_libfst_a_OBJECTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f 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 = $(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 = SOURCES = $(libfst_a_SOURCES) DIST_SOURCES = $(libfst_a_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)` ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AET2_CFLAGS = @AET2_CFLAGS@ AET2_LDADD = @AET2_LDADD@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COCOA_GTK_CFLAGS = @COCOA_GTK_CFLAGS@ COCOA_GTK_LDADD = @COCOA_GTK_LDADD@ COCOA_GTK_LDFLAGS = @COCOA_GTK_LDFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTDEBUG = @EXTDEBUG@ EXTDEBUG2 = @EXTDEBUG2@ EXTDEBUG3 = @EXTDEBUG3@ EXTDEBUG4 = @EXTDEBUG4@ EXTLOAD_CFLAGS = @EXTLOAD_CFLAGS@ FASTTREE_CFLAGS = @FASTTREE_CFLAGS@ FSDB_CFLAGS = @FSDB_CFLAGS@ FSDB_LDADD = @FSDB_LDADD@ GCONF_CFLAGS = @GCONF_CFLAGS@ GCONF_LIBS = @GCONF_LIBS@ GEDITTEST = @GEDITTEST@ GEDIT_CFLAGS = @GEDIT_CFLAGS@ GPERF = @GPERF@ GREP = @GREP@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_CONFIG = @GTK_CONFIG@ GTK_LIBS = @GTK_LIBS@ GTK_MAC_CFLAGS = @GTK_MAC_CFLAGS@ GTK_MAC_LIBS = @GTK_MAC_LIBS@ GTK_UNIX_PRINT_CFLAGS = @GTK_UNIX_PRINT_CFLAGS@ GTK_UNIX_PRINT_LIBS = @GTK_UNIX_PRINT_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBBZ2_CFLAGS = @LIBBZ2_CFLAGS@ LIBBZ2_DIR = @LIBBZ2_DIR@ LIBBZ2_LDADD = @LIBBZ2_LDADD@ LIBJUDY_CFLAGS = @LIBJUDY_CFLAGS@ LIBJUDY_LDADD = @LIBJUDY_LDADD@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBXZ_CFLAGS = @LIBXZ_CFLAGS@ LIBXZ_LDADD = @LIBXZ_LDADD@ LIBZ_CFLAGS = @LIBZ_CFLAGS@ LIBZ_DIR = @LIBZ_DIR@ LIBZ_LDADD = @LIBZ_LDADD@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MINGW_LDADD = @MINGW_LDADD@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ 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@ POW_LIB = @POW_LIB@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ STRUCT_PACK = @STRUCT_PACK@ TCL_DEFADD = @TCL_DEFADD@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LDADD = @TCL_LDADD@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_MAJOR_VERSION = @TCL_MAJOR_VERSION@ TCL_MINOR_VERSION = @TCL_MINOR_VERSION@ TK_INCLUDE_SPEC = @TK_INCLUDE_SPEC@ TK_LDADD = @TK_LDADD@ TK_LIB_SPEC = @TK_LIB_SPEC@ UPDATE_DESKTOP_DATABASE = @UPDATE_DESKTOP_DATABASE@ UPDATE_MIME_DATABASE = @UPDATE_MIME_DATABASE@ VERSION = @VERSION@ XDGDATADIR = @XDGDATADIR@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ 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_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ 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@ 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@ AM_CFLAGS = $(LIBZ_CFLAGS) $(LIBJUDY_CFLAGS) noinst_LIBRARIES = libfst.a libfst_a_SOURCES = fastlz.c fastlz.h lz4.c lz4.h fstapi.c fstapi.h EXTRA_DIST = block_format.txt all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(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) --foreign src/helpers/fst/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/helpers/fst/Makefile .PRECIOUS: 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__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-noinstLIBRARIES: -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) libfst.a: $(libfst_a_OBJECTS) $(libfst_a_DEPENDENCIES) $(EXTRA_libfst_a_DEPENDENCIES) $(AM_V_at)-rm -f libfst.a $(AM_V_AR)$(libfst_a_AR) libfst.a $(libfst_a_OBJECTS) $(libfst_a_LIBADD) $(AM_V_at)$(RANLIB) libfst.a mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fastlz.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstapi.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lz4.Po@am__quote@ .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 $< .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 `$(CYGPATH_W) '$<'` 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: $(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 $(LIBRARIES) installdirs: 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-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -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-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 -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-noinstLIBRARIES cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic 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 maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am # 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: gtkwave-3.3.66/src/helpers/fst/lz4.c0000664000076400007640000014034312447360476016523 0ustar bybellbybell/* LZ4 - Fast LZ compression algorithm Copyright (C) 2011-2015, Yann Collet. BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 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. 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. You can contact the author at : - LZ4 source repository : http://code.google.com/p/lz4 - LZ4 source mirror : https://github.com/Cyan4973/lz4 - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c */ /************************************** Tuning parameters **************************************/ /* * HEAPMODE : * Select how default compression functions will allocate memory for their hash table, * in memory stack (0:default, fastest), or in memory heap (1:requires malloc()). */ #define HEAPMODE 0 /* * CPU_HAS_EFFICIENT_UNALIGNED_MEMORY_ACCESS : * By default, the source code expects the compiler to correctly optimize * 4-bytes and 8-bytes read on architectures able to handle it efficiently. * This is not always the case. In some circumstances (ARM notably), * the compiler will issue cautious code even when target is able to correctly handle unaligned memory accesses. * * You can force the compiler to use unaligned memory access by uncommenting the line below. * One of the below scenarios will happen : * 1 - Your target CPU correctly handle unaligned access, and was not well optimized by compiler (good case). * You will witness large performance improvements (+50% and up). * Keep the line uncommented and send a word to upstream (https://groups.google.com/forum/#!forum/lz4c) * The goal is to automatically detect such situations by adding your target CPU within an exception list. * 2 - Your target CPU correctly handle unaligned access, and was already already optimized by compiler * No change will be experienced. * 3 - Your target CPU inefficiently handle unaligned access. * You will experience a performance loss. Comment back the line. * 4 - Your target CPU does not handle unaligned access. * Program will crash. * If uncommenting results in better performance (case 1) * please report your configuration to upstream (https://groups.google.com/forum/#!forum/lz4c) * An automatic detection macro will be added to match your case within future versions of the library. */ /* #define CPU_HAS_EFFICIENT_UNALIGNED_MEMORY_ACCESS 1 */ /************************************** CPU Feature Detection **************************************/ /* * Automated efficient unaligned memory access detection * Based on known hardware architectures * This list will be updated thanks to feedbacks */ #if defined(CPU_HAS_EFFICIENT_UNALIGNED_MEMORY_ACCESS) \ || defined(__ARM_FEATURE_UNALIGNED) \ || defined(__i386__) || defined(__x86_64__) \ || defined(_M_IX86) || defined(_M_X64) \ || defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_8__) \ || (defined(_M_ARM) && (_M_ARM >= 7)) # define LZ4_UNALIGNED_ACCESS 1 #else # define LZ4_UNALIGNED_ACCESS 0 #endif /* * LZ4_FORCE_SW_BITCOUNT * Define this parameter if your target system or compiler does not support hardware bit count */ #if defined(_MSC_VER) && defined(_WIN32_WCE) /* Visual Studio for Windows CE does not support Hardware bit count */ # define LZ4_FORCE_SW_BITCOUNT #endif /************************************** Compiler Options **************************************/ #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */ /* "restrict" is a known keyword */ #else # define restrict /* Disable restrict */ #endif #ifdef _MSC_VER /* Visual Studio */ # define FORCE_INLINE static __forceinline # include # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ # pragma warning(disable : 4293) /* disable: C4293: too large shift (32-bits) */ #else # if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */ # ifdef __GNUC__ # define FORCE_INLINE static inline __attribute__((always_inline)) # else # define FORCE_INLINE static inline # endif # else # define FORCE_INLINE static # endif /* __STDC_VERSION__ */ #endif /* _MSC_VER */ #define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) #if (GCC_VERSION >= 302) || (__INTEL_COMPILER >= 800) || defined(__clang__) # define expect(expr,value) (__builtin_expect ((expr),(value)) ) #else # define expect(expr,value) (expr) #endif #define likely(expr) expect((expr) != 0, 1) #define unlikely(expr) expect((expr) != 0, 0) /************************************** Memory routines **************************************/ #include /* malloc, calloc, free */ #define ALLOCATOR(n,s) calloc(n,s) #define FREEMEM free #include /* memset, memcpy */ #define MEM_INIT memset /************************************** Includes **************************************/ #include "lz4.h" /************************************** Basic Types **************************************/ #if defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */ # include typedef uint8_t BYTE; typedef uint16_t U16; typedef uint32_t U32; typedef int32_t S32; typedef uint64_t U64; #else typedef unsigned char BYTE; typedef unsigned short U16; typedef unsigned int U32; typedef signed int S32; typedef unsigned long long U64; #endif /************************************** Reading and writing into memory **************************************/ #define STEPSIZE sizeof(size_t) static unsigned LZ4_64bits(void) { return sizeof(void*)==8; } static unsigned LZ4_isLittleEndian(void) { const union { U32 i; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */ return one.c[0]; } static U16 LZ4_readLE16(const void* memPtr) { if ((LZ4_UNALIGNED_ACCESS) && (LZ4_isLittleEndian())) return *(U16*)memPtr; else { const BYTE* p = memPtr; return (U16)((U16)p[0] + (p[1]<<8)); } } static void LZ4_writeLE16(void* memPtr, U16 value) { if ((LZ4_UNALIGNED_ACCESS) && (LZ4_isLittleEndian())) { *(U16*)memPtr = value; return; } else { BYTE* p = memPtr; p[0] = (BYTE) value; p[1] = (BYTE)(value>>8); } } static U16 LZ4_read16(const void* memPtr) { if (LZ4_UNALIGNED_ACCESS) return *(U16*)memPtr; else { U16 val16; memcpy(&val16, memPtr, 2); return val16; } } static U32 LZ4_read32(const void* memPtr) { if (LZ4_UNALIGNED_ACCESS) return *(U32*)memPtr; else { U32 val32; memcpy(&val32, memPtr, 4); return val32; } } static U64 LZ4_read64(const void* memPtr) { if (LZ4_UNALIGNED_ACCESS) return *(U64*)memPtr; else { U64 val64; memcpy(&val64, memPtr, 8); return val64; } } static size_t LZ4_read_ARCH(const void* p) { if (LZ4_64bits()) return (size_t)LZ4_read64(p); else return (size_t)LZ4_read32(p); } static void LZ4_copy4(void* dstPtr, const void* srcPtr) { if (LZ4_UNALIGNED_ACCESS) { *(U32*)dstPtr = *(U32*)srcPtr; return; } memcpy(dstPtr, srcPtr, 4); } static void LZ4_copy8(void* dstPtr, const void* srcPtr) { #if GCC_VERSION!=409 /* disabled on GCC 4.9, as it generates invalid opcode (crash) */ if (LZ4_UNALIGNED_ACCESS) { if (LZ4_64bits()) *(U64*)dstPtr = *(U64*)srcPtr; else ((U32*)dstPtr)[0] = ((U32*)srcPtr)[0], ((U32*)dstPtr)[1] = ((U32*)srcPtr)[1]; return; } #endif memcpy(dstPtr, srcPtr, 8); } /* customized version of memcpy, which may overwrite up to 7 bytes beyond dstEnd */ static void LZ4_wildCopy(void* dstPtr, const void* srcPtr, void* dstEnd) { BYTE* d = dstPtr; const BYTE* s = srcPtr; BYTE* e = dstEnd; do { LZ4_copy8(d,s); d+=8; s+=8; } while (d>3); # elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) return (__builtin_ctzll((U64)val) >> 3); # else static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 }; return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58]; # endif } else /* 32 bits */ { # if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) unsigned long r; _BitScanForward( &r, (U32)val ); return (int)(r>>3); # elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) return (__builtin_ctz((U32)val) >> 3); # else static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 }; return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27]; # endif } } else /* Big Endian CPU */ { if (LZ4_64bits()) { # if defined(_MSC_VER) && defined(_WIN64) && !defined(LZ4_FORCE_SW_BITCOUNT) unsigned long r = 0; _BitScanReverse64( &r, val ); return (unsigned)(r>>3); # elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) return (__builtin_clzll(val) >> 3); # else unsigned r; if (!(val>>32)) { r=4; } else { r=0; val>>=32; } if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; } r += (!val); return r; # endif } else /* 32 bits */ { # if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) unsigned long r = 0; _BitScanReverse( &r, (unsigned long)val ); return (unsigned)(r>>3); # elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) return (__builtin_clz(val) >> 3); # else unsigned r; if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; } r += (!val); return r; # endif } } } static unsigned LZ4_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* pInLimit) { const BYTE* const pStart = pIn; while (likely(pIn compression run slower on incompressible data */ /************************************** Local Utils **************************************/ int LZ4_versionNumber (void) { return LZ4_VERSION_NUMBER; } int LZ4_compressBound(int isize) { return LZ4_COMPRESSBOUND(isize); } /************************************** Local Structures and types **************************************/ typedef struct { U32 hashTable[HASH_SIZE_U32]; U32 currentOffset; U32 initCheck; const BYTE* dictionary; const BYTE* bufferStart; U32 dictSize; } LZ4_stream_t_internal; typedef enum { notLimited = 0, limitedOutput = 1 } limitedOutput_directive; typedef enum { byPtr, byU32, byU16 } tableType_t; typedef enum { noDict = 0, withPrefix64k, usingExtDict } dict_directive; typedef enum { noDictIssue = 0, dictSmall } dictIssue_directive; typedef enum { endOnOutputSize = 0, endOnInputSize = 1 } endCondition_directive; typedef enum { full = 0, partial = 1 } earlyEnd_directive; /******************************** Compression functions ********************************/ static U32 LZ4_hashSequence(U32 sequence, tableType_t tableType) { if (tableType == byU16) return (((sequence) * 2654435761U) >> ((MINMATCH*8)-(LZ4_HASHLOG+1))); else return (((sequence) * 2654435761U) >> ((MINMATCH*8)-LZ4_HASHLOG)); } static U32 LZ4_hashPosition(const BYTE* p, tableType_t tableType) { return LZ4_hashSequence(LZ4_read32(p), tableType); } static void LZ4_putPositionOnHash(const BYTE* p, U32 h, void* tableBase, tableType_t tableType, const BYTE* srcBase) { switch (tableType) { case byPtr: { const BYTE** hashTable = (const BYTE**)tableBase; hashTable[h] = p; return; } case byU32: { U32* hashTable = (U32*) tableBase; hashTable[h] = (U32)(p-srcBase); return; } case byU16: { U16* hashTable = (U16*) tableBase; hashTable[h] = (U16)(p-srcBase); return; } } } static void LZ4_putPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase) { U32 h = LZ4_hashPosition(p, tableType); LZ4_putPositionOnHash(p, h, tableBase, tableType, srcBase); } static const BYTE* LZ4_getPositionOnHash(U32 h, void* tableBase, tableType_t tableType, const BYTE* srcBase) { if (tableType == byPtr) { const BYTE** hashTable = (const BYTE**) tableBase; return hashTable[h]; } if (tableType == byU32) { U32* hashTable = (U32*) tableBase; return hashTable[h] + srcBase; } { U16* hashTable = (U16*) tableBase; return hashTable[h] + srcBase; } /* default, to ensure a return */ } static const BYTE* LZ4_getPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase) { U32 h = LZ4_hashPosition(p, tableType); return LZ4_getPositionOnHash(h, tableBase, tableType, srcBase); } static int LZ4_compress_generic( void* ctx, const char* source, char* dest, int inputSize, int maxOutputSize, limitedOutput_directive outputLimited, tableType_t tableType, dict_directive dict, dictIssue_directive dictIssue) { LZ4_stream_t_internal* const dictPtr = (LZ4_stream_t_internal*)ctx; const BYTE* ip = (const BYTE*) source; const BYTE* base; const BYTE* lowLimit; const BYTE* const lowRefLimit = ip - dictPtr->dictSize; const BYTE* const dictionary = dictPtr->dictionary; const BYTE* const dictEnd = dictionary + dictPtr->dictSize; const size_t dictDelta = dictEnd - (const BYTE*)source; const BYTE* anchor = (const BYTE*) source; const BYTE* const iend = ip + inputSize; const BYTE* const mflimit = iend - MFLIMIT; const BYTE* const matchlimit = iend - LASTLITERALS; BYTE* op = (BYTE*) dest; BYTE* const olimit = op + maxOutputSize; U32 forwardH; size_t refDelta=0; /* Init conditions */ if ((U32)inputSize > (U32)LZ4_MAX_INPUT_SIZE) return 0; /* Unsupported input size, too large (or negative) */ switch(dict) { case noDict: default: base = (const BYTE*)source; lowLimit = (const BYTE*)source; break; case withPrefix64k: base = (const BYTE*)source - dictPtr->currentOffset; lowLimit = (const BYTE*)source - dictPtr->dictSize; break; case usingExtDict: base = (const BYTE*)source - dictPtr->currentOffset; lowLimit = (const BYTE*)source; break; } if ((tableType == byU16) && (inputSize>=LZ4_64Klimit)) return 0; /* Size too large (not within 64K limit) */ if (inputSize> LZ4_skipTrigger; if (unlikely(forwardIp > mflimit)) goto _last_literals; match = LZ4_getPositionOnHash(h, ctx, tableType, base); if (dict==usingExtDict) { if (match<(const BYTE*)source) { refDelta = dictDelta; lowLimit = dictionary; } else { refDelta = 0; lowLimit = (const BYTE*)source; } } forwardH = LZ4_hashPosition(forwardIp, tableType); LZ4_putPositionOnHash(ip, h, ctx, tableType, base); } while ( ((dictIssue==dictSmall) ? (match < lowRefLimit) : 0) || ((tableType==byU16) ? 0 : (match + MAX_DISTANCE < ip)) || (LZ4_read32(match+refDelta) != LZ4_read32(ip)) ); } /* Catch up */ while ((ip>anchor) && (match+refDelta > lowLimit) && (unlikely(ip[-1]==match[refDelta-1]))) { ip--; match--; } { /* Encode Literal length */ unsigned litLength = (unsigned)(ip - anchor); token = op++; if ((outputLimited) && (unlikely(op + litLength + (2 + 1 + LASTLITERALS) + (litLength/255) > olimit))) return 0; /* Check output limit */ if (litLength>=RUN_MASK) { int len = (int)litLength-RUN_MASK; *token=(RUN_MASK<= 255 ; len-=255) *op++ = 255; *op++ = (BYTE)len; } else *token = (BYTE)(litLength< matchlimit) limit = matchlimit; matchLength = LZ4_count(ip+MINMATCH, match+MINMATCH, limit); ip += MINMATCH + matchLength; if (ip==limit) { unsigned more = LZ4_count(ip, (const BYTE*)source, matchlimit); matchLength += more; ip += more; } } else { matchLength = LZ4_count(ip+MINMATCH, match+MINMATCH, matchlimit); ip += MINMATCH + matchLength; } if ((outputLimited) && (unlikely(op + (1 + LASTLITERALS) + (matchLength>>8) > olimit))) return 0; /* Check output limit */ if (matchLength>=ML_MASK) { *token += ML_MASK; matchLength -= ML_MASK; for (; matchLength >= 510 ; matchLength-=510) { *op++ = 255; *op++ = 255; } if (matchLength >= 255) { matchLength-=255; *op++ = 255; } *op++ = (BYTE)matchLength; } else *token += (BYTE)(matchLength); } anchor = ip; /* Test end of chunk */ if (ip > mflimit) break; /* Fill table */ LZ4_putPosition(ip-2, ctx, tableType, base); /* Test next position */ match = LZ4_getPosition(ip, ctx, tableType, base); if (dict==usingExtDict) { if (match<(const BYTE*)source) { refDelta = dictDelta; lowLimit = dictionary; } else { refDelta = 0; lowLimit = (const BYTE*)source; } } LZ4_putPosition(ip, ctx, tableType, base); if ( ((dictIssue==dictSmall) ? (match>=lowRefLimit) : 1) && (match+MAX_DISTANCE>=ip) && (LZ4_read32(match+refDelta)==LZ4_read32(ip)) ) { token=op++; *token=0; goto _next_match; } /* Prepare next loop */ forwardH = LZ4_hashPosition(++ip, tableType); } _last_literals: /* Encode Last Literals */ { int lastRun = (int)(iend - anchor); if ((outputLimited) && (((char*)op - dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize)) return 0; /* Check output limit */ if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<= 255 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; } else *op++ = (BYTE)(lastRun<= sizeof(LZ4_stream_t_internal)); /* A compilation error here means LZ4_STREAMSIZE is not large enough */ LZ4_resetStream(lz4s); return lz4s; } int LZ4_freeStream (LZ4_stream_t* LZ4_stream) { FREEMEM(LZ4_stream); return (0); } int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize) { LZ4_stream_t_internal* dict = (LZ4_stream_t_internal*) LZ4_dict; const BYTE* p = (const BYTE*)dictionary; const BYTE* const dictEnd = p + dictSize; const BYTE* base; if (dict->initCheck) LZ4_resetStream(LZ4_dict); /* Uninitialized structure detected */ if (dictSize < MINMATCH) { dict->dictionary = NULL; dict->dictSize = 0; return 0; } if (p <= dictEnd - 64 KB) p = dictEnd - 64 KB; base = p - dict->currentOffset; dict->dictionary = p; dict->dictSize = (U32)(dictEnd - p); dict->currentOffset += dict->dictSize; while (p <= dictEnd-MINMATCH) { LZ4_putPosition(p, dict, byU32, base); p+=3; } return dict->dictSize; } static void LZ4_renormDictT(LZ4_stream_t_internal* LZ4_dict, const BYTE* src) { if ((LZ4_dict->currentOffset > 0x80000000) || ((size_t)LZ4_dict->currentOffset > (size_t)src)) /* address space overflow */ { /* rescale hash table */ U32 delta = LZ4_dict->currentOffset - 64 KB; const BYTE* dictEnd = LZ4_dict->dictionary + LZ4_dict->dictSize; int i; for (i=0; ihashTable[i] < delta) LZ4_dict->hashTable[i]=0; else LZ4_dict->hashTable[i] -= delta; } LZ4_dict->currentOffset = 64 KB; if (LZ4_dict->dictSize > 64 KB) LZ4_dict->dictSize = 64 KB; LZ4_dict->dictionary = dictEnd - LZ4_dict->dictSize; } } FORCE_INLINE int LZ4_compress_continue_generic (void* LZ4_stream, const char* source, char* dest, int inputSize, int maxOutputSize, limitedOutput_directive limit) { LZ4_stream_t_internal* streamPtr = (LZ4_stream_t_internal*)LZ4_stream; const BYTE* const dictEnd = streamPtr->dictionary + streamPtr->dictSize; const BYTE* smallest = (const BYTE*) source; if (streamPtr->initCheck) return 0; /* Uninitialized structure detected */ if ((streamPtr->dictSize>0) && (smallest>dictEnd)) smallest = dictEnd; LZ4_renormDictT(streamPtr, smallest); /* Check overlapping input/dictionary space */ { const BYTE* sourceEnd = (const BYTE*) source + inputSize; if ((sourceEnd > streamPtr->dictionary) && (sourceEnd < dictEnd)) { streamPtr->dictSize = (U32)(dictEnd - sourceEnd); if (streamPtr->dictSize > 64 KB) streamPtr->dictSize = 64 KB; if (streamPtr->dictSize < 4) streamPtr->dictSize = 0; streamPtr->dictionary = dictEnd - streamPtr->dictSize; } } /* prefix mode : source data follows dictionary */ if (dictEnd == (const BYTE*)source) { int result; if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset)) result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limit, byU32, withPrefix64k, dictSmall); else result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limit, byU32, withPrefix64k, noDictIssue); streamPtr->dictSize += (U32)inputSize; streamPtr->currentOffset += (U32)inputSize; return result; } /* external dictionary mode */ { int result; if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset)) result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limit, byU32, usingExtDict, dictSmall); else result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limit, byU32, usingExtDict, noDictIssue); streamPtr->dictionary = (const BYTE*)source; streamPtr->dictSize = (U32)inputSize; streamPtr->currentOffset += (U32)inputSize; return result; } } int LZ4_compress_continue (LZ4_stream_t* LZ4_stream, const char* source, char* dest, int inputSize) { return LZ4_compress_continue_generic(LZ4_stream, source, dest, inputSize, 0, notLimited); } int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_stream, const char* source, char* dest, int inputSize, int maxOutputSize) { return LZ4_compress_continue_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limitedOutput); } /* Hidden debug function, to force separate dictionary mode */ int LZ4_compress_forceExtDict (LZ4_stream_t* LZ4_dict, const char* source, char* dest, int inputSize) { LZ4_stream_t_internal* streamPtr = (LZ4_stream_t_internal*)LZ4_dict; int result; const BYTE* const dictEnd = streamPtr->dictionary + streamPtr->dictSize; const BYTE* smallest = dictEnd; if (smallest > (const BYTE*) source) smallest = (const BYTE*) source; LZ4_renormDictT((LZ4_stream_t_internal*)LZ4_dict, smallest); result = LZ4_compress_generic(LZ4_dict, source, dest, inputSize, 0, notLimited, byU32, usingExtDict, noDictIssue); streamPtr->dictionary = (const BYTE*)source; streamPtr->dictSize = (U32)inputSize; streamPtr->currentOffset += (U32)inputSize; return result; } int LZ4_saveDict (LZ4_stream_t* LZ4_dict, char* safeBuffer, int dictSize) { LZ4_stream_t_internal* dict = (LZ4_stream_t_internal*) LZ4_dict; const BYTE* previousDictEnd = dict->dictionary + dict->dictSize; if ((U32)dictSize > 64 KB) dictSize = 64 KB; /* useless to define a dictionary > 64 KB */ if ((U32)dictSize > dict->dictSize) dictSize = dict->dictSize; memmove(safeBuffer, previousDictEnd - dictSize, dictSize); dict->dictionary = (const BYTE*)safeBuffer; dict->dictSize = (U32)dictSize; return dictSize; } /**************************** Decompression functions ****************************/ /* * This generic decompression function cover all use cases. * It shall be instantiated several times, using different sets of directives * Note that it is essential this generic function is really inlined, * in order to remove useless branches during compilation optimization. */ FORCE_INLINE int LZ4_decompress_generic( const char* const source, char* const dest, int inputSize, int outputSize, /* If endOnInput==endOnInputSize, this value is the max size of Output Buffer. */ int endOnInput, /* endOnOutputSize, endOnInputSize */ int partialDecoding, /* full, partial */ int targetOutputSize, /* only used if partialDecoding==partial */ int dict, /* noDict, withPrefix64k, usingExtDict */ const BYTE* const lowPrefix, /* == dest if dict == noDict */ const BYTE* const dictStart, /* only if dict==usingExtDict */ const size_t dictSize /* note : = 0 if noDict */ ) { /* Local Variables */ const BYTE* restrict ip = (const BYTE*) source; const BYTE* const iend = ip + inputSize; BYTE* op = (BYTE*) dest; BYTE* const oend = op + outputSize; BYTE* cpy; BYTE* oexit = op + targetOutputSize; const BYTE* const lowLimit = lowPrefix - dictSize; const BYTE* const dictEnd = (const BYTE*)dictStart + dictSize; const size_t dec32table[] = {4, 1, 2, 1, 4, 4, 4, 4}; const size_t dec64table[] = {0, 0, 0, (size_t)-1, 0, 1, 2, 3}; const int safeDecode = (endOnInput==endOnInputSize); const int checkOffset = ((safeDecode) && (dictSize < (int)(64 KB))); /* Special cases */ if ((partialDecoding) && (oexit> oend-MFLIMIT)) oexit = oend-MFLIMIT; /* targetOutputSize too high => decode everything */ if ((endOnInput) && (unlikely(outputSize==0))) return ((inputSize==1) && (*ip==0)) ? 0 : -1; /* Empty output buffer */ if ((!endOnInput) && (unlikely(outputSize==0))) return (*ip==0?1:-1); /* Main Loop */ while (1) { unsigned token; size_t length; const BYTE* match; /* get literal length */ token = *ip++; if ((length=(token>>ML_BITS)) == RUN_MASK) { unsigned s; do { s = *ip++; length += s; } while (likely((endOnInput)?ip(partialDecoding?oexit:oend-MFLIMIT)) || (ip+length>iend-(2+1+LASTLITERALS))) ) || ((!endOnInput) && (cpy>oend-COPYLENGTH))) { if (partialDecoding) { if (cpy > oend) goto _output_error; /* Error : write attempt beyond end of output buffer */ if ((endOnInput) && (ip+length > iend)) goto _output_error; /* Error : read attempt beyond end of input buffer */ } else { if ((!endOnInput) && (cpy != oend)) goto _output_error; /* Error : block decoding must stop exactly there */ if ((endOnInput) && ((ip+length != iend) || (cpy > oend))) goto _output_error; /* Error : input must be consumed */ } memcpy(op, ip, length); ip += length; op += length; break; /* Necessarily EOF, due to parsing restrictions */ } LZ4_wildCopy(op, ip, cpy); ip += length; op = cpy; /* get offset */ match = cpy - LZ4_readLE16(ip); ip+=2; if ((checkOffset) && (unlikely(match < lowLimit))) goto _output_error; /* Error : offset outside destination buffer */ /* get matchlength */ length = token & ML_MASK; if (length == ML_MASK) { unsigned s; do { if ((endOnInput) && (ip > iend-LASTLITERALS)) goto _output_error; s = *ip++; length += s; } while (s==255); if ((safeDecode) && unlikely((size_t)(op+length)<(size_t)op)) goto _output_error; /* overflow detection */ } length += MINMATCH; /* check external dictionary */ if ((dict==usingExtDict) && (match < lowPrefix)) { if (unlikely(op+length > oend-LASTLITERALS)) goto _output_error; /* doesn't respect parsing restriction */ if (length <= (size_t)(lowPrefix-match)) { /* match can be copied as a single segment from external dictionary */ match = dictEnd - (lowPrefix-match); memcpy(op, match, length); op += length; } else { /* match encompass external dictionary and current segment */ size_t copySize = (size_t)(lowPrefix-match); memcpy(op, dictEnd - copySize, copySize); op += copySize; copySize = length - copySize; if (copySize > (size_t)(op-lowPrefix)) /* overlap within current segment */ { BYTE* const endOfMatch = op + copySize; const BYTE* copyFrom = lowPrefix; while (op < endOfMatch) *op++ = *copyFrom++; } else { memcpy(op, lowPrefix, copySize); op += copySize; } } continue; } /* copy repeated sequence */ cpy = op + length; if (unlikely((op-match)<8)) { const size_t dec64 = dec64table[op-match]; op[0] = match[0]; op[1] = match[1]; op[2] = match[2]; op[3] = match[3]; match += dec32table[op-match]; LZ4_copy4(op+4, match); op += 8; match -= dec64; } else { LZ4_copy8(op, match); op+=8; match+=8; } if (unlikely(cpy>oend-12)) { if (cpy > oend-LASTLITERALS) goto _output_error; /* Error : last LASTLITERALS bytes must be literals */ if (op < oend-8) { LZ4_wildCopy(op, match, oend-8); match += (oend-8) - op; op = oend-8; } while (opprefixSize = (size_t) dictSize; lz4sd->prefixEnd = (BYTE*) dictionary + dictSize; lz4sd->externalDict = NULL; lz4sd->extDictSize = 0; return 1; } /* *_continue() : These decoding functions allow decompression of multiple blocks in "streaming" mode. Previously decoded blocks must still be available at the memory position where they were decoded. If it's not possible, save the relevant part of decoded data into a safe buffer, and indicate where it stands using LZ4_setStreamDecode() */ int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxOutputSize) { LZ4_streamDecode_t_internal* lz4sd = (LZ4_streamDecode_t_internal*) LZ4_streamDecode; int result; if (lz4sd->prefixEnd == (BYTE*)dest) { result = LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, usingExtDict, lz4sd->prefixEnd - lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize); if (result <= 0) return result; lz4sd->prefixSize += result; lz4sd->prefixEnd += result; } else { lz4sd->extDictSize = lz4sd->prefixSize; lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize; result = LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, usingExtDict, (BYTE*)dest, lz4sd->externalDict, lz4sd->extDictSize); if (result <= 0) return result; lz4sd->prefixSize = result; lz4sd->prefixEnd = (BYTE*)dest + result; } return result; } int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize) { LZ4_streamDecode_t_internal* lz4sd = (LZ4_streamDecode_t_internal*) LZ4_streamDecode; int result; if (lz4sd->prefixEnd == (BYTE*)dest) { result = LZ4_decompress_generic(source, dest, 0, originalSize, endOnOutputSize, full, 0, usingExtDict, lz4sd->prefixEnd - lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize); if (result <= 0) return result; lz4sd->prefixSize += originalSize; lz4sd->prefixEnd += originalSize; } else { lz4sd->extDictSize = lz4sd->prefixSize; lz4sd->externalDict = (BYTE*)dest - lz4sd->extDictSize; result = LZ4_decompress_generic(source, dest, 0, originalSize, endOnOutputSize, full, 0, usingExtDict, (BYTE*)dest, lz4sd->externalDict, lz4sd->extDictSize); if (result <= 0) return result; lz4sd->prefixSize = originalSize; lz4sd->prefixEnd = (BYTE*)dest + originalSize; } return result; } /* Advanced decoding functions : *_usingDict() : These decoding functions work the same as "_continue" ones, the dictionary must be explicitly provided within parameters */ FORCE_INLINE int LZ4_decompress_usingDict_generic(const char* source, char* dest, int compressedSize, int maxOutputSize, int safe, const char* dictStart, int dictSize) { if (dictSize==0) return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, noDict, (BYTE*)dest, NULL, 0); if (dictStart+dictSize == dest) { if (dictSize >= (int)(64 KB - 1)) return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, withPrefix64k, (BYTE*)dest-64 KB, NULL, 0); return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, noDict, (BYTE*)dest-dictSize, NULL, 0); } return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, usingExtDict, (BYTE*)dest, (BYTE*)dictStart, dictSize); } int LZ4_decompress_safe_usingDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const char* dictStart, int dictSize) { return LZ4_decompress_usingDict_generic(source, dest, compressedSize, maxOutputSize, 1, dictStart, dictSize); } int LZ4_decompress_fast_usingDict(const char* source, char* dest, int originalSize, const char* dictStart, int dictSize) { return LZ4_decompress_usingDict_generic(source, dest, 0, originalSize, 0, dictStart, dictSize); } /* debug function */ int LZ4_decompress_safe_forceExtDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const char* dictStart, int dictSize) { return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, usingExtDict, (BYTE*)dest, (BYTE*)dictStart, dictSize); } /*************************************************** Obsolete Functions ***************************************************/ /* These function names are deprecated and should no longer be used. They are only provided here for compatibility with older user programs. - LZ4_uncompress is totally equivalent to LZ4_decompress_fast - LZ4_uncompress_unknownOutputSize is totally equivalent to LZ4_decompress_safe */ int LZ4_uncompress (const char* source, char* dest, int outputSize) { return LZ4_decompress_fast(source, dest, outputSize); } int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize) { return LZ4_decompress_safe(source, dest, isize, maxOutputSize); } /* Obsolete Streaming functions */ int LZ4_sizeofStreamState() { return LZ4_STREAMSIZE; } static void LZ4_init(LZ4_stream_t_internal* lz4ds, const BYTE* base) { MEM_INIT(lz4ds, 0, LZ4_STREAMSIZE); lz4ds->bufferStart = base; } int LZ4_resetStreamState(void* state, const char* inputBuffer) { if ((((size_t)state) & 3) != 0) return 1; /* Error : pointer is not aligned on 4-bytes boundary */ LZ4_init((LZ4_stream_t_internal*)state, (const BYTE*)inputBuffer); return 0; } void* LZ4_create (const char* inputBuffer) { void* lz4ds = ALLOCATOR(8, LZ4_STREAMSIZE_U64); LZ4_init ((LZ4_stream_t_internal*)lz4ds, (const BYTE*)inputBuffer); return lz4ds; } char* LZ4_slideInputBuffer (void* LZ4_Data) { LZ4_stream_t_internal* ctx = (LZ4_stream_t_internal*)LZ4_Data; int dictSize = LZ4_saveDict((LZ4_stream_t*)ctx, (char*)ctx->bufferStart, 64 KB); return (char*)(ctx->bufferStart + dictSize); } /* Obsolete compresson functions using User-allocated state */ int LZ4_sizeofState() { return LZ4_STREAMSIZE; } int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize) { if (((size_t)(state)&3) != 0) return 0; /* Error : state is not aligned on 4-bytes boundary */ MEM_INIT(state, 0, LZ4_STREAMSIZE); if (inputSize < LZ4_64Klimit) return LZ4_compress_generic(state, source, dest, inputSize, 0, notLimited, byU16, noDict, noDictIssue); else return LZ4_compress_generic(state, source, dest, inputSize, 0, notLimited, LZ4_64bits() ? byU32 : byPtr, noDict, noDictIssue); } int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize) { if (((size_t)(state)&3) != 0) return 0; /* Error : state is not aligned on 4-bytes boundary */ MEM_INIT(state, 0, LZ4_STREAMSIZE); if (inputSize < LZ4_64Klimit) return LZ4_compress_generic(state, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue); else return LZ4_compress_generic(state, source, dest, inputSize, maxOutputSize, limitedOutput, LZ4_64bits() ? byU32 : byPtr, noDict, noDictIssue); } /* Obsolete streaming decompression functions */ int LZ4_decompress_safe_withPrefix64k(const char* source, char* dest, int compressedSize, int maxOutputSize) { return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, withPrefix64k, (BYTE*)dest - 64 KB, NULL, 64 KB); } int LZ4_decompress_fast_withPrefix64k(const char* source, char* dest, int originalSize) { return LZ4_decompress_generic(source, dest, 0, originalSize, endOnOutputSize, full, 0, withPrefix64k, (BYTE*)dest - 64 KB, NULL, 64 KB); } #endif /* LZ4_COMMONDEFS_ONLY */ gtkwave-3.3.66/src/helpers/fst/fstapi.h0000664000076400007640000004073012506713076017276 0ustar bybellbybell/* * Copyright (c) 2009-2015 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifndef FST_API_H #define FST_API_H #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include #include #include #include #define FST_RDLOAD "FSTLOAD | " typedef uint32_t fstHandle; enum fstWriterPackType { FST_WR_PT_ZLIB = 0, FST_WR_PT_FASTLZ = 1, FST_WR_PT_LZ4 = 2 }; enum fstFileType { FST_FT_MIN = 0, FST_FT_VERILOG = 0, FST_FT_VHDL = 1, FST_FT_VERILOG_VHDL = 2, FST_FT_MAX = 2 }; enum fstBlockType { FST_BL_HDR = 0, FST_BL_VCDATA = 1, FST_BL_BLACKOUT = 2, FST_BL_GEOM = 3, FST_BL_HIER = 4, FST_BL_VCDATA_DYN_ALIAS = 5, FST_BL_HIER_LZ4 = 6, FST_BL_HIER_LZ4DUO = 7, FST_BL_VCDATA_DYN_ALIAS2 = 8, FST_BL_ZWRAPPER = 254, /* indicates that whole trace is gz wrapped */ FST_BL_SKIP = 255 /* used while block is being written */ }; enum fstScopeType { FST_ST_MIN = 0, FST_ST_VCD_MODULE = 0, FST_ST_VCD_TASK = 1, FST_ST_VCD_FUNCTION = 2, FST_ST_VCD_BEGIN = 3, FST_ST_VCD_FORK = 4, FST_ST_VCD_GENERATE = 5, FST_ST_VCD_STRUCT = 6, FST_ST_VCD_UNION = 7, FST_ST_VCD_CLASS = 8, FST_ST_VCD_INTERFACE = 9, FST_ST_VCD_PACKAGE = 10, FST_ST_VCD_PROGRAM = 11, FST_ST_VHDL_ARCHITECTURE = 12, FST_ST_VHDL_PROCEDURE = 13, FST_ST_VHDL_FUNCTION = 14, FST_ST_VHDL_RECORD = 15, FST_ST_VHDL_PROCESS = 16, FST_ST_VHDL_BLOCK = 17, FST_ST_VHDL_FOR_GENERATE = 18, FST_ST_VHDL_IF_GENERATE = 19, FST_ST_VHDL_GENERATE = 20, FST_ST_VHDL_PACKAGE = 21, FST_ST_MAX = 21, FST_ST_GEN_ATTRBEGIN = 252, FST_ST_GEN_ATTREND = 253, FST_ST_VCD_SCOPE = 254, FST_ST_VCD_UPSCOPE = 255 }; enum fstVarType { FST_VT_MIN = 0, /* start of vartypes */ FST_VT_VCD_EVENT = 0, FST_VT_VCD_INTEGER = 1, FST_VT_VCD_PARAMETER = 2, FST_VT_VCD_REAL = 3, FST_VT_VCD_REAL_PARAMETER = 4, FST_VT_VCD_REG = 5, FST_VT_VCD_SUPPLY0 = 6, FST_VT_VCD_SUPPLY1 = 7, FST_VT_VCD_TIME = 8, FST_VT_VCD_TRI = 9, FST_VT_VCD_TRIAND = 10, FST_VT_VCD_TRIOR = 11, FST_VT_VCD_TRIREG = 12, FST_VT_VCD_TRI0 = 13, FST_VT_VCD_TRI1 = 14, FST_VT_VCD_WAND = 15, FST_VT_VCD_WIRE = 16, FST_VT_VCD_WOR = 17, FST_VT_VCD_PORT = 18, FST_VT_VCD_SPARRAY = 19, /* used to define the rownum (index) port for a sparse array */ FST_VT_VCD_REALTIME = 20, FST_VT_GEN_STRING = 21, /* generic string type (max len is defined dynamically via fstWriterEmitVariableLengthValueChange) */ FST_VT_SV_BIT = 22, FST_VT_SV_LOGIC = 23, FST_VT_SV_INT = 24, /* declare as size = 32 */ FST_VT_SV_SHORTINT = 25, /* declare as size = 16 */ FST_VT_SV_LONGINT = 26, /* declare as size = 64 */ FST_VT_SV_BYTE = 27, /* declare as size = 8 */ FST_VT_SV_ENUM = 28, /* declare as appropriate type range */ FST_VT_SV_SHORTREAL = 29, /* declare and emit same as FST_VT_VCD_REAL (needs to be emitted as double, not a float) */ FST_VT_MAX = 29 /* end of vartypes */ }; enum fstVarDir { FST_VD_MIN = 0, FST_VD_IMPLICIT = 0, FST_VD_INPUT = 1, FST_VD_OUTPUT = 2, FST_VD_INOUT = 3, FST_VD_BUFFER = 4, FST_VD_LINKAGE = 5, FST_VD_MAX = 5 }; enum fstHierType { FST_HT_MIN = 0, FST_HT_SCOPE = 0, FST_HT_UPSCOPE = 1, FST_HT_VAR = 2, FST_HT_ATTRBEGIN = 3, FST_HT_ATTREND = 4, FST_HT_MAX = 4 }; enum fstAttrType { FST_AT_MIN = 0, FST_AT_MISC = 0, /* self-contained: does not need matching FST_HT_ATTREND */ FST_AT_ARRAY = 1, FST_AT_ENUM = 2, FST_AT_PACK = 3, FST_AT_MAX = 3 }; enum fstMiscType { FST_MT_MIN = 0, FST_MT_COMMENT = 0, /* use fstWriterSetComment() to emit */ FST_MT_ENVVAR = 1, /* use fstWriterSetEnvVar() to emit */ FST_MT_SUPVAR = 2, /* use fstWriterCreateVar2() to emit */ FST_MT_PATHNAME = 3, /* reserved for fstWriterSetSourceStem() string -> number management */ FST_MT_SOURCESTEM = 4, /* use fstWriterSetSourceStem() to emit */ FST_MT_SOURCEISTEM = 5, /* use fstWriterSetSourceInstantiationStem() to emit */ FST_MT_VALUELIST = 6, /* use fstWriterSetValueList() to emit, followed by fstWriterCreateVar*() */ FST_MT_UNKNOWN = 7, FST_MT_MAX = 7 }; enum fstArrayType { FST_AR_MIN = 0, FST_AR_NONE = 0, FST_AR_UNPACKED = 1, FST_AR_PACKED = 2, FST_AR_SPARSE = 3, FST_AR_MAX = 3 }; enum fstEnumValueType { FST_EV_SV_INTEGER = 0, FST_EV_SV_BIT = 1, FST_EV_SV_LOGIC = 2, FST_EV_SV_INT = 3, FST_EV_SV_SHORTINT = 4, FST_EV_SV_LONGINT = 5, FST_EV_SV_BYTE = 6, FST_EV_SV_UNSIGNED_INTEGER = 7, FST_EV_SV_UNSIGNED_BIT = 8, FST_EV_SV_UNSIGNED_LOGIC = 9, FST_EV_SV_UNSIGNED_INT = 10, FST_EV_SV_UNSIGNED_SHORTINT = 11, FST_EV_SV_UNSIGNED_LONGINT = 12, FST_EV_SV_UNSIGNED_BYTE = 13, FST_EV_MAX = 13 }; enum fstPackType { FST_PT_NONE = 0, FST_PT_UNPACKED = 1, FST_PT_PACKED = 2, FST_PT_TAGGED_PACKED = 3, FST_PT_MAX = 3 }; enum fstSupplementalVarType { FST_SVT_MIN = 0, FST_SVT_NONE = 0, FST_SVT_VHDL_SIGNAL = 1, FST_SVT_VHDL_VARIABLE = 2, FST_SVT_VHDL_CONSTANT = 3, FST_SVT_VHDL_FILE = 4, FST_SVT_VHDL_MEMORY = 5, FST_SVT_MAX = 5 }; enum fstSupplementalDataType { FST_SDT_MIN = 0, FST_SDT_NONE = 0, FST_SDT_VHDL_BOOLEAN = 1, FST_SDT_VHDL_BIT = 2, FST_SDT_VHDL_BIT_VECTOR = 3, FST_SDT_VHDL_STD_ULOGIC = 4, FST_SDT_VHDL_STD_ULOGIC_VECTOR = 5, FST_SDT_VHDL_STD_LOGIC = 6, FST_SDT_VHDL_STD_LOGIC_VECTOR = 7, FST_SDT_VHDL_UNSIGNED = 8, FST_SDT_VHDL_SIGNED = 9, FST_SDT_VHDL_INTEGER = 10, FST_SDT_VHDL_REAL = 11, FST_SDT_VHDL_NATURAL = 12, FST_SDT_VHDL_POSITIVE = 13, FST_SDT_VHDL_TIME = 14, FST_SDT_VHDL_CHARACTER = 15, FST_SDT_VHDL_STRING = 16, FST_SDT_MAX = 16, FST_SDT_SVT_SHIFT_COUNT = 10, /* FST_SVT_* is ORed in by fstWriterCreateVar2() to the left after shifting FST_SDT_SVT_SHIFT_COUNT */ FST_SDT_ABS_MAX = ((1<<(FST_SDT_SVT_SHIFT_COUNT))-1) }; struct fstHier { unsigned char htyp; union { /* if htyp == FST_HT_SCOPE */ struct fstHierScope { unsigned char typ; /* FST_ST_MIN ... FST_ST_MAX */ const char *name; const char *component; uint32_t name_length; /* strlen(u.scope.name) */ uint32_t component_length; /* strlen(u.scope.component) */ } scope; /* if htyp == FST_HT_VAR */ struct fstHierVar { unsigned char typ; /* FST_VT_MIN ... FST_VT_MAX */ unsigned char direction; /* FST_VD_MIN ... FST_VD_MAX */ unsigned char svt_workspace; /* zeroed out by FST reader, for client code use */ unsigned char sdt_workspace; /* zeroed out by FST reader, for client code use */ unsigned int sxt_workspace; /* zeroed out by FST reader, for client code use */ const char *name; uint32_t length; fstHandle handle; uint32_t name_length; /* strlen(u.var.name) */ unsigned is_alias : 1; } var; /* if htyp == FST_HT_ATTRBEGIN */ struct fstHierAttr { unsigned char typ; /* FST_AT_MIN ... FST_AT_MAX */ unsigned char subtype; /* from fstMiscType, fstArrayType, fstEnumValueType, fstPackType */ const char *name; uint64_t arg; /* number of array elements, struct members, or some other payload (possibly ignored) */ uint64_t arg_from_name; /* for when name is overloaded as a variable-length integer (FST_AT_MISC + FST_MT_SOURCESTEM) */ uint32_t name_length; /* strlen(u.attr.name) */ } attr; } u; }; /* * writer functions */ void fstWriterClose(void *ctx); void * fstWriterCreate(const char *nam, int use_compressed_hier); /* used for Verilog/SV */ fstHandle fstWriterCreateVar(void *ctx, enum fstVarType vt, enum fstVarDir vd, uint32_t len, const char *nam, fstHandle aliasHandle); /* future expansion for VHDL and other languages. The variable type, data type, etc map onto the current Verilog/SV one. The "type" string is optional for a more verbose or custom description */ fstHandle fstWriterCreateVar2(void *ctx, enum fstVarType vt, enum fstVarDir vd, uint32_t len, const char *nam, fstHandle aliasHandle, const char *type, enum fstSupplementalVarType svt, enum fstSupplementalDataType sdt); void fstWriterEmitValueChange(void *ctx, fstHandle handle, const void *val); void fstWriterEmitVariableLengthValueChange(void *ctx, fstHandle handle, const void *val, uint32_t len); void fstWriterEmitDumpActive(void *ctx, int enable); void fstWriterEmitTimeChange(void *ctx, uint64_t tim); void fstWriterFlushContext(void *ctx); int fstWriterGetDumpSizeLimitReached(void *ctx); int fstWriterGetFseekFailed(void *ctx); void fstWriterSetAttrBegin(void *ctx, enum fstAttrType attrtype, int subtype, const char *attrname, uint64_t arg); void fstWriterSetAttrEnd(void *ctx); void fstWriterSetComment(void *ctx, const char *comm); void fstWriterSetDate(void *ctx, const char *dat); void fstWriterSetDumpSizeLimit(void *ctx, uint64_t numbytes); void fstWriterSetEnvVar(void *ctx, const char *envvar); void fstWriterSetFileType(void *ctx, enum fstFileType filetype); void fstWriterSetPackType(void *ctx, enum fstWriterPackType typ); void fstWriterSetParallelMode(void *ctx, int enable); void fstWriterSetRepackOnClose(void *ctx, int enable); /* type = 0 (none), 1 (libz) */ void fstWriterSetScope(void *ctx, enum fstScopeType scopetype, const char *scopename, const char *scopecomp); void fstWriterSetSourceInstantiationStem(void *ctx, const char *path, unsigned int line, unsigned int use_realpath); void fstWriterSetSourceStem(void *ctx, const char *path, unsigned int line, unsigned int use_realpath); void fstWriterSetTimescale(void *ctx, int ts); void fstWriterSetTimescaleFromString(void *ctx, const char *s); void fstWriterSetTimezero(void *ctx, int64_t tim); void fstWriterSetUpscope(void *ctx); void fstWriterSetValueList(void *ctx, const char *vl); void fstWriterSetVersion(void *ctx, const char *vers); /* * reader functions */ void fstReaderClose(void *ctx); void fstReaderClrFacProcessMask(void *ctx, fstHandle facidx); void fstReaderClrFacProcessMaskAll(void *ctx); uint64_t fstReaderGetAliasCount(void *ctx); const char * fstReaderGetCurrentFlatScope(void *ctx); void * fstReaderGetCurrentScopeUserInfo(void *ctx); int fstReaderGetCurrentScopeLen(void *ctx); const char * fstReaderGetDateString(void *ctx); int fstReaderGetDoubleEndianMatchState(void *ctx); uint64_t fstReaderGetDumpActivityChangeTime(void *ctx, uint32_t idx); unsigned char fstReaderGetDumpActivityChangeValue(void *ctx, uint32_t idx); uint64_t fstReaderGetEndTime(void *ctx); int fstReaderGetFacProcessMask(void *ctx, fstHandle facidx); int fstReaderGetFileType(void *ctx); int fstReaderGetFseekFailed(void *ctx); fstHandle fstReaderGetMaxHandle(void *ctx); uint64_t fstReaderGetMemoryUsedByWriter(void *ctx); uint32_t fstReaderGetNumberDumpActivityChanges(void *ctx); uint64_t fstReaderGetScopeCount(void *ctx); uint64_t fstReaderGetStartTime(void *ctx); signed char fstReaderGetTimescale(void *ctx); int64_t fstReaderGetTimezero(void *ctx); uint64_t fstReaderGetValueChangeSectionCount(void *ctx); char * fstReaderGetValueFromHandleAtTime(void *ctx, uint64_t tim, fstHandle facidx, char *buf); uint64_t fstReaderGetVarCount(void *ctx); const char * fstReaderGetVersionString(void *ctx); struct fstHier *fstReaderIterateHier(void *ctx); int fstReaderIterateHierRewind(void *ctx); int fstReaderIterBlocks(void *ctx, void (*value_change_callback)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value), void *user_callback_data_pointer, FILE *vcdhandle); int fstReaderIterBlocks2(void *ctx, void (*value_change_callback)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value), void (*value_change_callback_varlen)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value, uint32_t len), void *user_callback_data_pointer, FILE *vcdhandle); void fstReaderIterBlocksSetNativeDoublesOnCallback(void *ctx, int enable); void * fstReaderOpen(const char *nam); void * fstReaderOpenForUtilitiesOnly(void); const char * fstReaderPopScope(void *ctx); int fstReaderProcessHier(void *ctx, FILE *vcdhandle); const char * fstReaderPushScope(void *ctx, const char *nam, void *user_info); void fstReaderResetScope(void *ctx); void fstReaderSetFacProcessMask(void *ctx, fstHandle facidx); void fstReaderSetFacProcessMaskAll(void *ctx); void fstReaderSetLimitTimeRange(void *ctx, uint64_t start_time, uint64_t end_time); void fstReaderSetUnlimitedTimeRange(void *ctx); void fstReaderSetVcdExtensions(void *ctx, int enable); /* * utility functions */ int fstUtilityBinToEsc(unsigned char *d, unsigned char *s, int len); int fstUtilityEscToBin(unsigned char *d, unsigned char *s, int len); #ifdef __cplusplus } #endif #endif gtkwave-3.3.66/src/helpers/fst/fastlz.c0000664000076400007640000003233112341266475017307 0ustar bybellbybell/* FastLZ - lightning-fast lossless compression library Copyright (C) 2007 Ariya Hidayat (ariya@kde.org) Copyright (C) 2006 Ariya Hidayat (ariya@kde.org) Copyright (C) 2005 Ariya Hidayat (ariya@kde.org) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "fastlz.h" #if !defined(FASTLZ__COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) /* * Always check for bound when decompressing. * Generally it is best to leave it defined. */ #define FASTLZ_SAFE /* * Give hints to the compiler for branch prediction optimization. */ #if defined(__GNUC__) && (__GNUC__ > 2) #define FASTLZ_EXPECT_CONDITIONAL(c) (__builtin_expect((c), 1)) #define FASTLZ_UNEXPECT_CONDITIONAL(c) (__builtin_expect((c), 0)) #else #define FASTLZ_EXPECT_CONDITIONAL(c) (c) #define FASTLZ_UNEXPECT_CONDITIONAL(c) (c) #endif /* * Use inlined functions for supported systems. */ #if defined(__GNUC__) || defined(__DMC__) || defined(__POCC__) || defined(__WATCOMC__) || defined(__SUNPRO_C) #define FASTLZ_INLINE inline #elif defined(__BORLANDC__) || defined(_MSC_VER) || defined(__LCC__) #define FASTLZ_INLINE __inline #else #define FASTLZ_INLINE #endif /* * Prevent accessing more than 8-bit at once, except on x86 architectures. */ #if !defined(FASTLZ_STRICT_ALIGN) #define FASTLZ_STRICT_ALIGN #if defined(__i386__) || defined(__386) /* GNU C, Sun Studio */ #undef FASTLZ_STRICT_ALIGN #elif defined(__i486__) || defined(__i586__) || defined(__i686__) || defined(__amd64) /* GNU C */ #undef FASTLZ_STRICT_ALIGN #elif defined(_M_IX86) /* Intel, MSVC */ #undef FASTLZ_STRICT_ALIGN #elif defined(__386) #undef FASTLZ_STRICT_ALIGN #elif defined(_X86_) /* MinGW */ #undef FASTLZ_STRICT_ALIGN #elif defined(__I86__) /* Digital Mars */ #undef FASTLZ_STRICT_ALIGN #endif #endif /* prototypes */ int fastlz_compress(const void* input, int length, void* output); int fastlz_compress_level(int level, const void* input, int length, void* output); int fastlz_decompress(const void* input, int length, void* output, int maxout); #define MAX_COPY 32 #define MAX_LEN 264 /* 256 + 8 */ #define MAX_DISTANCE 8192 #if !defined(FASTLZ_STRICT_ALIGN) #define FASTLZ_READU16(p) *((const flzuint16*)(p)) #else #define FASTLZ_READU16(p) ((p)[0] | (p)[1]<<8) #endif #define HASH_LOG 13 #define HASH_SIZE (1<< HASH_LOG) #define HASH_MASK (HASH_SIZE-1) #define HASH_FUNCTION(v,p) { v = FASTLZ_READU16(p); v ^= FASTLZ_READU16(p+1)^(v>>(16-HASH_LOG));v &= HASH_MASK; } #undef FASTLZ_LEVEL #define FASTLZ_LEVEL 1 #undef FASTLZ_COMPRESSOR #undef FASTLZ_DECOMPRESSOR #define FASTLZ_COMPRESSOR fastlz1_compress #define FASTLZ_DECOMPRESSOR fastlz1_decompress static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output); static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout); #include "fastlz.c" #undef FASTLZ_LEVEL #define FASTLZ_LEVEL 2 #undef MAX_DISTANCE #define MAX_DISTANCE 8191 #define MAX_FARDISTANCE (65535+MAX_DISTANCE-1) #undef FASTLZ_COMPRESSOR #undef FASTLZ_DECOMPRESSOR #define FASTLZ_COMPRESSOR fastlz2_compress #define FASTLZ_DECOMPRESSOR fastlz2_decompress static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output); static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout); #include "fastlz.c" int fastlz_compress(const void* input, int length, void* output) { /* for short block, choose fastlz1 */ if(length < 65536) return fastlz1_compress(input, length, output); /* else... */ return fastlz2_compress(input, length, output); } int fastlz_decompress(const void* input, int length, void* output, int maxout) { /* magic identifier for compression level */ int level = ((*(const flzuint8*)input) >> 5) + 1; if(level == 1) return fastlz1_decompress(input, length, output, maxout); if(level == 2) return fastlz2_decompress(input, length, output, maxout); /* unknown level, trigger error */ return 0; } int fastlz_compress_level(int level, const void* input, int length, void* output) { if(level == 1) return fastlz1_compress(input, length, output); if(level == 2) return fastlz2_compress(input, length, output); return 0; } #else /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */ static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output) { const flzuint8* ip = (const flzuint8*) input; const flzuint8* ip_bound = ip + length - 2; const flzuint8* ip_limit = ip + length - 12; flzuint8* op = (flzuint8*) output; const flzuint8* htab[HASH_SIZE]; const flzuint8** hslot; flzuint32 hval; flzuint32 copy; /* sanity check */ if(FASTLZ_UNEXPECT_CONDITIONAL(length < 4)) { if(length) { /* create literal copy only */ *op++ = length-1; ip_bound++; while(ip <= ip_bound) *op++ = *ip++; return length+1; } else return 0; } /* initializes hash table */ for (hslot = htab; hslot < htab + HASH_SIZE; hslot++) *hslot = ip; /* we start with literal copy */ copy = 2; *op++ = MAX_COPY-1; *op++ = *ip++; *op++ = *ip++; /* main loop */ while(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit)) { const flzuint8* ref; flzuint32 distance; /* minimum match length */ flzuint32 len = 3; /* comparison starting-point */ const flzuint8* anchor = ip; /* check for a run */ #if FASTLZ_LEVEL==2 if(ip[0] == ip[-1] && FASTLZ_READU16(ip-1)==FASTLZ_READU16(ip+1)) { distance = 1; /* ip += 3; */ /* scan-build, never used */ ref = anchor - 1 + 3; goto match; } #endif /* find potential match */ HASH_FUNCTION(hval,ip); hslot = htab + hval; ref = htab[hval]; /* calculate distance to the match */ distance = anchor - ref; /* update hash table */ *hslot = anchor; /* is this a match? check the first 3 bytes */ if(distance==0 || #if FASTLZ_LEVEL==1 (distance >= MAX_DISTANCE) || #else (distance >= MAX_FARDISTANCE) || #endif *ref++ != *ip++ || *ref++!=*ip++ || *ref++!=*ip++) goto literal; #if FASTLZ_LEVEL==2 /* far, needs at least 5-byte match */ if(distance >= MAX_DISTANCE) { if(*ip++ != *ref++ || *ip++!= *ref++) goto literal; len += 2; } match: #endif /* last matched byte */ ip = anchor + len; /* distance is biased */ distance--; if(!distance) { /* zero distance means a run */ flzuint8 x = ip[-1]; while(ip < ip_bound) if(*ref++ != x) break; else ip++; } else for(;;) { /* safe because the outer check against ip limit */ if(*ref++ != *ip++) break; if(*ref++ != *ip++) break; if(*ref++ != *ip++) break; if(*ref++ != *ip++) break; if(*ref++ != *ip++) break; if(*ref++ != *ip++) break; if(*ref++ != *ip++) break; if(*ref++ != *ip++) break; while(ip < ip_bound) if(*ref++ != *ip++) break; break; } /* if we have copied something, adjust the copy count */ if(copy) /* copy is biased, '0' means 1 byte copy */ *(op-copy-1) = copy-1; else /* back, to overwrite the copy count */ op--; /* reset literal counter */ copy = 0; /* length is biased, '1' means a match of 3 bytes */ ip -= 3; len = ip - anchor; /* encode the match */ #if FASTLZ_LEVEL==2 if(distance < MAX_DISTANCE) { if(len < 7) { *op++ = (len << 5) + (distance >> 8); *op++ = (distance & 255); } else { *op++ = (7 << 5) + (distance >> 8); for(len-=7; len >= 255; len-= 255) *op++ = 255; *op++ = len; *op++ = (distance & 255); } } else { /* far away, but not yet in the another galaxy... */ if(len < 7) { distance -= MAX_DISTANCE; *op++ = (len << 5) + 31; *op++ = 255; *op++ = distance >> 8; *op++ = distance & 255; } else { distance -= MAX_DISTANCE; *op++ = (7 << 5) + 31; for(len-=7; len >= 255; len-= 255) *op++ = 255; *op++ = len; *op++ = 255; *op++ = distance >> 8; *op++ = distance & 255; } } #else if(FASTLZ_UNEXPECT_CONDITIONAL(len > MAX_LEN-2)) while(len > MAX_LEN-2) { *op++ = (7 << 5) + (distance >> 8); *op++ = MAX_LEN - 2 - 7 -2; *op++ = (distance & 255); len -= MAX_LEN-2; } if(len < 7) { *op++ = (len << 5) + (distance >> 8); *op++ = (distance & 255); } else { *op++ = (7 << 5) + (distance >> 8); *op++ = len - 7; *op++ = (distance & 255); } #endif /* update the hash at match boundary */ HASH_FUNCTION(hval,ip); htab[hval] = ip++; HASH_FUNCTION(hval,ip); htab[hval] = ip++; /* assuming literal copy */ *op++ = MAX_COPY-1; continue; literal: *op++ = *anchor++; ip = anchor; copy++; if(FASTLZ_UNEXPECT_CONDITIONAL(copy == MAX_COPY)) { copy = 0; *op++ = MAX_COPY-1; } } /* left-over as literal copy */ ip_bound++; while(ip <= ip_bound) { *op++ = *ip++; copy++; if(copy == MAX_COPY) { copy = 0; *op++ = MAX_COPY-1; } } /* if we have copied something, adjust the copy length */ if(copy) *(op-copy-1) = copy-1; else op--; #if FASTLZ_LEVEL==2 /* marker for fastlz2 */ *(flzuint8*)output |= (1 << 5); #endif return op - (flzuint8*)output; } static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout) { const flzuint8* ip = (const flzuint8*) input; const flzuint8* ip_limit = ip + length; flzuint8* op = (flzuint8*) output; flzuint8* op_limit = op + maxout; flzuint32 ctrl = (*ip++) & 31; int loop = 1; do { const flzuint8* ref = op; flzuint32 len = ctrl >> 5; flzuint32 ofs = (ctrl & 31) << 8; if(ctrl >= 32) { #if FASTLZ_LEVEL==2 flzuint8 code; #endif len--; ref -= ofs; if (len == 7-1) #if FASTLZ_LEVEL==1 len += *ip++; ref -= *ip++; #else do { code = *ip++; len += code; } while (code==255); code = *ip++; ref -= code; /* match from 16-bit distance */ if(FASTLZ_UNEXPECT_CONDITIONAL(code==255)) if(FASTLZ_EXPECT_CONDITIONAL(ofs==(31 << 8))) { ofs = (*ip++) << 8; ofs += *ip++; ref = op - ofs - MAX_DISTANCE; } #endif #ifdef FASTLZ_SAFE if (FASTLZ_UNEXPECT_CONDITIONAL(op + len + 3 > op_limit)) return 0; if (FASTLZ_UNEXPECT_CONDITIONAL(ref-1 < (flzuint8 *)output)) return 0; #endif if(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit)) ctrl = *ip++; else loop = 0; if(ref == op) { /* optimize copy for a run */ flzuint8 b = ref[-1]; *op++ = b; *op++ = b; *op++ = b; for(; len; --len) *op++ = b; } else { #if !defined(FASTLZ_STRICT_ALIGN) const flzuint16* p; flzuint16* q; #endif /* copy from reference */ ref--; *op++ = *ref++; *op++ = *ref++; *op++ = *ref++; #if !defined(FASTLZ_STRICT_ALIGN) /* copy a byte, so that now it's word aligned */ if(len & 1) { *op++ = *ref++; len--; } /* copy 16-bit at once */ q = (flzuint16*) op; op += len; p = (const flzuint16*) ref; for(len>>=1; len > 4; len-=4) { *q++ = *p++; *q++ = *p++; *q++ = *p++; *q++ = *p++; } for(; len; --len) *q++ = *p++; #else for(; len; --len) *op++ = *ref++; #endif } } else { ctrl++; #ifdef FASTLZ_SAFE if (FASTLZ_UNEXPECT_CONDITIONAL(op + ctrl > op_limit)) return 0; if (FASTLZ_UNEXPECT_CONDITIONAL(ip + ctrl > ip_limit)) return 0; #endif *op++ = *ip++; for(--ctrl; ctrl; ctrl--) *op++ = *ip++; loop = FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit); if(loop) ctrl = *ip++; } } while(FASTLZ_EXPECT_CONDITIONAL(loop)); return op - (flzuint8*)output; } #endif /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */ gtkwave-3.3.66/src/helpers/fst/fstapi.c0000664000076400007640000071045112523230072017262 0ustar bybellbybell/* * Copyright (c) 2009-2015 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ /* * possible disables: * * FST_DYNAMIC_ALIAS_DISABLE : dynamic aliases are not processed * FST_DYNAMIC_ALIAS2_DISABLE : new encoding for dynamic aliases is not generated * FST_WRITEX_DISABLE : fast write I/O routines are disabled * * possible enables: * * FST_DEBUG : not for production use, only enable for development * FST_REMOVE_DUPLICATE_VC : glitch removal (has writer performance impact) * HAVE_LIBPTHREAD -> FST_WRITER_PARALLEL : enables inclusion of parallel writer code * FST_DO_MISALIGNED_OPS (defined automatically for x86 and some others) : CPU architecture can handle misaligned loads/stores * _WAVE_HAVE_JUDY : use Judy arrays instead of Jenkins (undefine if LGPL is not acceptable) * */ #include #include "fstapi.h" #include "fastlz.h" #include "lz4.h" #ifndef HAVE_LIBPTHREAD #undef FST_WRITER_PARALLEL #endif #ifdef FST_WRITER_PARALLEL #include #endif #ifdef __MINGW32__ #include #endif #ifdef HAVE_ALLOCA_H #include #elif defined(__GNUC__) #ifndef __MINGW32__ #ifndef alloca #define alloca __builtin_alloca #endif #else #include #endif #elif defined(_MSC_VER) #include #define alloca _alloca #endif #ifndef PATH_MAX #define PATH_MAX (4096) #endif /* note that Judy versus Jenkins requires more experimentation: they are */ /* functionally equivalent though it appears Jenkins is slightly faster. */ /* in addition, Jenkins is not bound by the LGPL. */ #ifdef _WAVE_HAVE_JUDY #include #else /* should be more than enough for fstWriterSetSourceStem() */ #define FST_PATH_HASHMASK ((1UL << 16) - 1) typedef const void *Pcvoid_t; typedef void *Pvoid_t; typedef void **PPvoid_t; #define JudyHSIns(a,b,c,d) JenkinsIns((a),(b),(c),(hashmask)) #define JudyHSFreeArray(a,b) JenkinsFree((a),(hashmask)) void JenkinsFree(void *base_i, uint32_t hashmask); void **JenkinsIns(void *base_i, const unsigned char *mem, uint32_t length, uint32_t hashmask); #endif #ifndef FST_WRITEX_DISABLE #define FST_WRITEX_MAX (64 * 1024) #else #define fstWritex(a,b,c) fstFwrite((b), (c), 1, fv) #endif /* these defines have a large impact on writer speed when a model has a */ /* huge number of symbols. as a default, use 128MB and increment when */ /* every 1M signals are defined. */ #define FST_BREAK_SIZE (1UL << 27) #define FST_BREAK_ADD_SIZE (1UL << 22) #define FST_BREAK_SIZE_MAX (1UL << 31) #define FST_ACTIVATE_HUGE_BREAK (1000000) #define FST_ACTIVATE_HUGE_INC (1000000) #define FST_WRITER_STR "fstWriter" #define FST_ID_NAM_SIZ (512) #define FST_ID_NAM_ATTR_SIZ (65536+4096) #define FST_DOUBLE_ENDTEST (2.7182818284590452354) #define FST_HDR_SIM_VERSION_SIZE (128) #define FST_HDR_DATE_SIZE (119) #define FST_HDR_FILETYPE_SIZE (1) #define FST_HDR_TIMEZERO_SIZE (8) #define FST_GZIO_LEN (32768) #define FST_HDR_FOURPACK_DUO_SIZE (4*1024*1024) #if defined(__i386__) || defined(__x86_64__) || defined(_AIX) #define FST_DO_MISALIGNED_OPS #endif #if defined(__APPLE__) && defined(__MACH__) #define FST_MACOSX #include #endif /***********************/ /*** ***/ /*** common function ***/ /*** ***/ /***********************/ #ifdef __MINGW32__ #include #ifndef HAVE_FSEEKO #define ftello ftell #define fseeko fseek #endif #endif /* * the recoded "extra" values... * note that FST_RCV_Q is currently unused and is for future expansion. * its intended use is as another level of escape such that any arbitrary * value can be stored as the value: { time_delta, 8 bits, FST_RCV_Q }. * this is currently not implemented so that the branchless decode is: * uint32_t shcnt = 2 << (vli & 1); tdelta = vli >> shcnt; */ #define FST_RCV_X (1 | (0<<1)) #define FST_RCV_Z (1 | (1<<1)) #define FST_RCV_H (1 | (2<<1)) #define FST_RCV_U (1 | (3<<1)) #define FST_RCV_W (1 | (4<<1)) #define FST_RCV_L (1 | (5<<1)) #define FST_RCV_D (1 | (6<<1)) #define FST_RCV_Q (1 | (7<<1)) #define FST_RCV_STR "xzhuwl-?" /* 01234567 */ /* * prevent old file overwrite when currently being read */ static FILE *unlink_fopen(const char *nam, const char *mode) { unlink(nam); return(fopen(nam, mode)); } /* * system-specific temp file handling */ #ifdef __MINGW32__ static FILE* tmpfile_open(char **nam) { char *fname = NULL; TCHAR szTempFileName[MAX_PATH]; TCHAR lpTempPathBuffer[MAX_PATH]; DWORD dwRetVal = 0; UINT uRetVal = 0; FILE *fh = NULL; if(nam) /* cppcheck warning fix: nam is always defined, so this is not needed */ { dwRetVal = GetTempPath(MAX_PATH, lpTempPathBuffer); if((dwRetVal > MAX_PATH) || (dwRetVal == 0)) { fprintf(stderr, "GetTempPath() failed in "__FILE__" line %d, exiting.\n", __LINE__); exit(255); } else { uRetVal = GetTempFileName(lpTempPathBuffer, TEXT("FSTW"), 0, szTempFileName); if (uRetVal == 0) { fprintf(stderr, "GetTempFileName() failed in "__FILE__" line %d, exiting.\n", __LINE__); exit(255); } else { fname = strdup(szTempFileName); } } if(fname) { *nam = fname; fh = unlink_fopen(fname, "w+b"); } } return(fh); } #else static FILE* tmpfile_open(char **nam) { FILE *f = tmpfile(); /* replace with mkstemp() + fopen(), etc if this is not good enough */ if(nam) { *nam = NULL; } return(f); } #endif static void tmpfile_close(FILE **f, char **nam) { if(f) { if(*f) { fclose(*f); *f = NULL; } } if(nam) { if(*nam) { unlink(*nam); free(*nam); *nam = NULL; } } } /*****************************************/ /* * to remove warn_unused_result compile time messages * (in the future there needs to be results checking) */ static size_t fstFread(void *buf, size_t siz, size_t cnt, FILE *fp) { return(fread(buf, siz, cnt, fp)); } static size_t fstFwrite(const void *buf, size_t siz, size_t cnt, FILE *fp) { return(fwrite(buf, siz, cnt, fp)); } static int fstFtruncate(int fd, off_t length) { return(ftruncate(fd, length)); } /* * realpath compatibility */ static char *fstRealpath(const char *path, char *resolved_path) { #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED || defined __CYGWIN__ || defined HAVE_REALPATH #if (defined(__MACH__) && defined(__APPLE__)) if(!resolved_path) { resolved_path = malloc(PATH_MAX+1); /* fixes bug on Leopard when resolved_path == NULL */ } #endif return(realpath(path, resolved_path)); #else #ifdef __MINGW32__ if(!resolved_path) { resolved_path = malloc(PATH_MAX+1); } return(_fullpath(resolved_path, path, PATH_MAX)); #else return(NULL); #endif #endif } /* * mmap compatibility */ #if defined __CYGWIN__ || defined __MINGW32__ #include #define fstMmap(__addr,__len,__prot,__flags,__fd,__off) fstMmap2((__len), (__fd), (__off)) #define fstMunmap(__addr,__len) free(__addr) static void *fstMmap2(size_t __len, int __fd, off_t __off) { (void)__off; unsigned char *pnt = malloc(__len); off_t cur_offs = lseek(__fd, 0, SEEK_CUR); size_t i; lseek(__fd, 0, SEEK_SET); for(i=0;i<__len;i+=SSIZE_MAX) { read(__fd, pnt + i, ((__len - i) >= SSIZE_MAX) ? SSIZE_MAX : (__len - i)); } lseek(__fd, cur_offs, SEEK_SET); return(pnt); } #else #include #if defined(__SUNPRO_C) #define FST_CADDR_T_CAST (caddr_t) #else #define FST_CADDR_T_CAST #endif #define fstMmap(__addr,__len,__prot,__flags,__fd,__off) (void*)mmap(FST_CADDR_T_CAST (__addr),(__len),(__prot),(__flags),(__fd),(__off)) #define fstMunmap(__addr,__len) { if(__addr) munmap(FST_CADDR_T_CAST (__addr),(__len)); } #endif /* * regular and variable-length integer access functions */ #ifdef FST_DO_MISALIGNED_OPS #define fstGetUint32(x) (*(uint32_t *)(x)) #else static uint32_t fstGetUint32(unsigned char *mem) { uint32_t u32; unsigned char *buf = (unsigned char *)(&u32); buf[0] = mem[0]; buf[1] = mem[1]; buf[2] = mem[2]; buf[3] = mem[3]; return(*(uint32_t *)buf); } #endif static int fstWriterUint64(FILE *handle, uint64_t v) { unsigned char buf[8]; int i; for(i=7;i>=0;i--) { buf[i] = v & 0xff; v >>= 8; } fstFwrite(buf, 8, 1, handle); return(8); } static uint64_t fstReaderUint64(FILE *f) { uint64_t val = 0; unsigned char buf[sizeof(uint64_t)]; unsigned int i; fstFread(buf, sizeof(uint64_t), 1, f); for(i=0;i>7)) /* determine len to avoid temp buffer copying to cut down on load-hit-store */ { cnt++; } pnt -= cnt; spnt = pnt; cnt--; for(i=0;i>7; *(spnt++) = ((unsigned char)v) | 0x80; v = nxt; } *spnt = (unsigned char)v; return(pnt); } static unsigned char *fstCopyVarint64ToRight(unsigned char *pnt, uint64_t v) { uint64_t nxt; while((nxt = v>>7)) { *(pnt++) = ((unsigned char)v) | 0x80; v = nxt; } *(pnt++) = (unsigned char)v; return(pnt); } static uint64_t fstGetVarint64(unsigned char *mem, int *skiplen) { unsigned char *mem_orig = mem; uint64_t rc = 0; while(*mem & 0x80) { mem++; } *skiplen = mem - mem_orig + 1; for(;;) { rc <<= 7; rc |= (uint64_t)(*mem & 0x7f); if(mem == mem_orig) { break; } mem--; } return(rc); } static uint32_t fstReaderVarint32(FILE *f) { unsigned char buf[5]; unsigned char *mem = buf; uint32_t rc = 0; int ch; do { ch = fgetc(f); *(mem++) = ch; } while(ch & 0x80); mem--; for(;;) { rc <<= 7; rc |= (uint32_t)(*mem & 0x7f); if(mem == buf) { break; } mem--; } return(rc); } static uint32_t fstReaderVarint32WithSkip(FILE *f, uint32_t *skiplen) { unsigned char buf[5]; unsigned char *mem = buf; uint32_t rc = 0; int ch; do { ch = fgetc(f); *(mem++) = ch; } while(ch & 0x80); *skiplen = mem - buf; mem--; for(;;) { rc <<= 7; rc |= (uint32_t)(*mem & 0x7f); if(mem == buf) { break; } mem--; } return(rc); } static uint64_t fstReaderVarint64(FILE *f) { unsigned char buf[16]; unsigned char *mem = buf; uint64_t rc = 0; int ch; do { ch = fgetc(f); *(mem++) = ch; } while(ch & 0x80); mem--; for(;;) { rc <<= 7; rc |= (uint64_t)(*mem & 0x7f); if(mem == buf) { break; } mem--; } return(rc); } static int fstWriterVarint(FILE *handle, uint64_t v) { uint64_t nxt; unsigned char buf[10]; /* ceil(64/7) = 10 */ unsigned char *pnt = buf; int len; while((nxt = v>>7)) { *(pnt++) = ((unsigned char)v) | 0x80; v = nxt; } *(pnt++) = (unsigned char)v; len = pnt-buf; fstFwrite(buf, len, 1, handle); return(len); } /* signed integer read/write routines are currently unused */ static int64_t fstGetSVarint64(unsigned char *mem, int *skiplen) { unsigned char *mem_orig = mem; int64_t rc = 0; const int64_t one = 1; const int siz = sizeof(int64_t) * 8; int shift = 0; unsigned char byt; do { byt = *(mem++); rc |= ((int64_t)(byt & 0x7f)) << shift; shift += 7; } while(byt & 0x80); if((shift>= 7; if (((!v) && (!(byt & 0x40))) || ((v == -1) && (byt & 0x40))) { more = 0; byt &= 0x7f; } *(pnt++) = byt; } while(more); len = pnt-buf; fstFwrite(buf, len, 1, handle); return(len); } /***********************/ /*** ***/ /*** writer function ***/ /*** ***/ /***********************/ /* * private structs */ struct fstBlackoutChain { struct fstBlackoutChain *next; uint64_t tim; unsigned active : 1; }; struct fstWriterContext { FILE *handle; FILE *hier_handle; FILE *geom_handle; FILE *valpos_handle; FILE *curval_handle; FILE *tchn_handle; unsigned char *vchg_mem; off_t hier_file_len; uint32_t *valpos_mem; unsigned char *curval_mem; char *filename; fstHandle maxhandle; fstHandle numsigs; uint32_t maxvalpos; unsigned vc_emitted : 1; unsigned is_initial_time : 1; unsigned fourpack : 1; unsigned fastpack : 1; int64_t timezero; off_t section_header_truncpos; uint32_t tchn_cnt, tchn_idx; uint64_t curtime; uint64_t firsttime; uint32_t vchg_siz; uint32_t vchg_alloc_siz; uint32_t secnum; off_t section_start; uint32_t numscopes; double nan; /* nan value for uninitialized doubles */ struct fstBlackoutChain *blackout_head; struct fstBlackoutChain *blackout_curr; uint32_t num_blackouts; uint64_t dump_size_limit; unsigned char filetype; /* default is 0, FST_FT_VERILOG */ unsigned compress_hier : 1; unsigned repack_on_close : 1; unsigned skip_writing_section_hdr : 1; unsigned size_limit_locked : 1; unsigned section_header_only : 1; unsigned flush_context_pending : 1; unsigned parallel_enabled : 1; unsigned parallel_was_enabled : 1; /* should really be semaphores, but are bytes to cut down on read-modify-write window size */ unsigned char already_in_flush; /* in case control-c handlers interrupt */ unsigned char already_in_close; /* in case control-c handlers interrupt */ #ifdef FST_WRITER_PARALLEL pthread_mutex_t mutex; pthread_t thread; pthread_attr_t thread_attr; struct fstWriterContext *xc_parent; #endif size_t fst_orig_break_size; size_t fst_orig_break_add_size; size_t fst_break_size; size_t fst_break_add_size; size_t fst_huge_break_size; fstHandle next_huge_break; Pvoid_t path_array; uint32_t path_array_count; unsigned fseek_failed : 1; char *geom_handle_nam; char *valpos_handle_nam; char *curval_handle_nam; char *tchn_handle_nam; }; static int fstWriterFseeko(struct fstWriterContext *xc, FILE *stream, off_t offset, int whence) { int rc = fseeko(stream, offset, whence); if(rc<0) { xc->fseek_failed = 1; #ifdef FST_DEBUG fprintf(stderr, "Seek to #%"PRId64" (whence = %d) failed!\n", offset, whence); perror("Why"); #endif } return(rc); } static uint32_t fstWriterUint32WithVarint32(struct fstWriterContext *xc, uint32_t *u, uint32_t v, const void *dbuf, uint32_t siz) { unsigned char *buf = xc->vchg_mem + xc->vchg_siz; unsigned char *pnt = buf; uint32_t nxt; uint32_t len; #ifdef FST_DO_MISALIGNED_OPS (*(uint32_t *)(pnt)) = (*(uint32_t *)(u)); #else memcpy(pnt, u, sizeof(uint32_t)); #endif pnt += 4; while((nxt = v>>7)) { *(pnt++) = ((unsigned char)v) | 0x80; v = nxt; } *(pnt++) = (unsigned char)v; memcpy(pnt, dbuf, siz); len = pnt-buf + siz; return(len); } static uint32_t fstWriterUint32WithVarint32AndLength(struct fstWriterContext *xc, uint32_t *u, uint32_t v, const void *dbuf, uint32_t siz) { unsigned char *buf = xc->vchg_mem + xc->vchg_siz; unsigned char *pnt = buf; uint32_t nxt; uint32_t len; #ifdef FST_DO_MISALIGNED_OPS (*(uint32_t *)(pnt)) = (*(uint32_t *)(u)); #else memcpy(pnt, u, sizeof(uint32_t)); #endif pnt += 4; while((nxt = v>>7)) { *(pnt++) = ((unsigned char)v) | 0x80; v = nxt; } *(pnt++) = (unsigned char)v; v = siz; while((nxt = v>>7)) { *(pnt++) = ((unsigned char)v) | 0x80; v = nxt; } *(pnt++) = (unsigned char)v; memcpy(pnt, dbuf, siz); len = pnt-buf + siz; return(len); } /* * header bytes, write here so defines are set up before anything else * that needs to use them */ static void fstWriterEmitHdrBytes(struct fstWriterContext *xc) { char vbuf[FST_HDR_SIM_VERSION_SIZE]; char dbuf[FST_HDR_DATE_SIZE]; double endtest = FST_DOUBLE_ENDTEST; time_t walltime; #define FST_HDR_OFFS_TAG (0) fputc(FST_BL_HDR, xc->handle); /* +0 tag */ #define FST_HDR_OFFS_SECLEN (FST_HDR_OFFS_TAG + 1) fstWriterUint64(xc->handle, 329); /* +1 section length */ #define FST_HDR_OFFS_START_TIME (FST_HDR_OFFS_SECLEN + 8) fstWriterUint64(xc->handle, 0); /* +9 start time */ #define FST_HDR_OFFS_END_TIME (FST_HDR_OFFS_START_TIME + 8) fstWriterUint64(xc->handle, 0); /* +17 end time */ #define FST_HDR_OFFS_ENDIAN_TEST (FST_HDR_OFFS_END_TIME + 8) fstFwrite(&endtest, 8, 1, xc->handle); /* +25 endian test for reals */ #define FST_HDR_OFFS_MEM_USED (FST_HDR_OFFS_ENDIAN_TEST + 8) fstWriterUint64(xc->handle, xc->fst_break_size);/* +33 memory used by writer */ #define FST_HDR_OFFS_NUM_SCOPES (FST_HDR_OFFS_MEM_USED + 8) fstWriterUint64(xc->handle, 0); /* +41 scope creation count */ #define FST_HDR_OFFS_NUM_VARS (FST_HDR_OFFS_NUM_SCOPES + 8) fstWriterUint64(xc->handle, 0); /* +49 var creation count */ #define FST_HDR_OFFS_MAXHANDLE (FST_HDR_OFFS_NUM_VARS + 8) fstWriterUint64(xc->handle, 0); /* +57 max var idcode */ #define FST_HDR_OFFS_SECTION_CNT (FST_HDR_OFFS_MAXHANDLE + 8) fstWriterUint64(xc->handle, 0); /* +65 vc section count */ #define FST_HDR_OFFS_TIMESCALE (FST_HDR_OFFS_SECTION_CNT + 8) fputc((-9)&255, xc->handle); /* +73 timescale 1ns */ #define FST_HDR_OFFS_SIM_VERSION (FST_HDR_OFFS_TIMESCALE + 1) memset(vbuf, 0, FST_HDR_SIM_VERSION_SIZE); strcpy(vbuf, FST_WRITER_STR); fstFwrite(vbuf, FST_HDR_SIM_VERSION_SIZE, 1, xc->handle); /* +74 version */ #define FST_HDR_OFFS_DATE (FST_HDR_OFFS_SIM_VERSION + FST_HDR_SIM_VERSION_SIZE) memset(dbuf, 0, FST_HDR_DATE_SIZE); time(&walltime); strcpy(dbuf, asctime(localtime(&walltime))); fstFwrite(dbuf, FST_HDR_DATE_SIZE, 1, xc->handle); /* +202 date */ /* date size is deliberately overspecified at 119 bytes (originally 128) in order to provide backfill for new args */ #define FST_HDR_OFFS_FILETYPE (FST_HDR_OFFS_DATE + FST_HDR_DATE_SIZE) fputc(xc->filetype, xc->handle); /* +321 filetype */ #define FST_HDR_OFFS_TIMEZERO (FST_HDR_OFFS_FILETYPE + FST_HDR_FILETYPE_SIZE) fstWriterUint64(xc->handle, xc->timezero); /* +322 timezero */ #define FST_HDR_LENGTH (FST_HDR_OFFS_TIMEZERO + FST_HDR_TIMEZERO_SIZE) /* +330 next section starts here */ fflush(xc->handle); } /* * mmap functions */ static void fstWriterCreateMmaps(struct fstWriterContext *xc) { off_t curpos = ftello(xc->handle); fflush(xc->hier_handle); /* write out intermediate header */ fstWriterFseeko(xc, xc->handle, FST_HDR_OFFS_START_TIME, SEEK_SET); fstWriterUint64(xc->handle, xc->firsttime); fstWriterUint64(xc->handle, xc->curtime); fstWriterFseeko(xc, xc->handle, FST_HDR_OFFS_NUM_SCOPES, SEEK_SET); fstWriterUint64(xc->handle, xc->numscopes); fstWriterUint64(xc->handle, xc->numsigs); fstWriterUint64(xc->handle, xc->maxhandle); fstWriterUint64(xc->handle, xc->secnum); fstWriterFseeko(xc, xc->handle, curpos, SEEK_SET); fflush(xc->handle); /* do mappings */ if(!xc->valpos_mem) { fflush(xc->valpos_handle); xc->valpos_mem = fstMmap(NULL, xc->maxhandle * 4 * sizeof(uint32_t), PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->valpos_handle), 0); } if(!xc->curval_mem) { fflush(xc->curval_handle); xc->curval_mem = fstMmap(NULL, xc->maxvalpos, PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->curval_handle), 0); } } static void fstDestroyMmaps(struct fstWriterContext *xc, int is_closing) { (void)is_closing; fstMunmap(xc->valpos_mem, xc->maxhandle * 4 * sizeof(uint32_t)); xc->valpos_mem = NULL; #if defined __CYGWIN__ || defined __MINGW32__ if(xc->curval_mem) { if(!is_closing) /* need to flush out for next emulated mmap() read */ { unsigned char *pnt = xc->curval_mem; int __fd = fileno(xc->curval_handle); off_t cur_offs = lseek(__fd, 0, SEEK_CUR); size_t i; size_t __len = xc->maxvalpos; lseek(__fd, 0, SEEK_SET); for(i=0;i<__len;i+=SSIZE_MAX) { write(__fd, pnt + i, ((__len - i) >= SSIZE_MAX) ? SSIZE_MAX : (__len - i)); } lseek(__fd, cur_offs, SEEK_SET); } } #endif fstMunmap(xc->curval_mem, xc->maxvalpos); xc->curval_mem = NULL; } /* * set up large and small memory usages * crossover point in model is FST_ACTIVATE_HUGE_BREAK number of signals */ static void fstDetermineBreakSize(struct fstWriterContext *xc) { #if defined(__linux__) || defined(FST_MACOSX) int was_set = 0; #ifdef __linux__ FILE *f = fopen("/proc/meminfo", "rb"); if(f) { char buf[257]; char *s; while(!feof(f)) { buf[0] = 0; s = fgets(buf, 256, f); if(s && *s) { if(!strncmp(s, "MemTotal:", 9)) { size_t v = atol(s+10); v *= 1024; /* convert to bytes */ v /= 8; /* chop down to 1/8 physical memory */ if(v > FST_BREAK_SIZE) { if(v > FST_BREAK_SIZE_MAX) { v = FST_BREAK_SIZE_MAX; } xc->fst_huge_break_size = v; was_set = 1; break; } } } } fclose(f); } if(!was_set) { xc->fst_huge_break_size = FST_BREAK_SIZE; } #else int mib[2]; int64_t v; size_t length; mib[0] = CTL_HW; mib[1] = HW_MEMSIZE; length = sizeof(int64_t); if(!sysctl(mib, 2, &v, &length, NULL, 0)) { v /= 8; if(v > (int64_t)FST_BREAK_SIZE) { if(v > (int64_t)FST_BREAK_SIZE_MAX) { v = FST_BREAK_SIZE_MAX; } xc->fst_huge_break_size = v; was_set = 1; } } if(!was_set) { xc->fst_huge_break_size = FST_BREAK_SIZE; } #endif #else xc->fst_huge_break_size = FST_BREAK_SIZE; #endif xc->fst_break_size = xc->fst_orig_break_size = FST_BREAK_SIZE; xc->fst_break_add_size = xc->fst_orig_break_add_size = FST_BREAK_ADD_SIZE; xc->next_huge_break = FST_ACTIVATE_HUGE_BREAK; } /* * file creation and close */ void *fstWriterCreate(const char *nam, int use_compressed_hier) { struct fstWriterContext *xc = calloc(1, sizeof(struct fstWriterContext)); xc->compress_hier = use_compressed_hier; fstDetermineBreakSize(xc); if((!nam)|| (!(xc->handle=unlink_fopen(nam, "w+b")))) { free(xc); xc=NULL; } else { int flen = strlen(nam); char *hf = calloc(1, flen + 6); memcpy(hf, nam, flen); strcpy(hf + flen, ".hier"); xc->hier_handle = unlink_fopen(hf, "w+b"); xc->geom_handle = tmpfile_open(&xc->geom_handle_nam); /* .geom */ xc->valpos_handle = tmpfile_open(&xc->valpos_handle_nam); /* .offs */ xc->curval_handle = tmpfile_open(&xc->curval_handle_nam); /* .bits */ xc->tchn_handle = tmpfile_open(&xc->tchn_handle_nam); /* .tchn */ xc->vchg_alloc_siz = xc->fst_break_size + xc->fst_break_add_size; xc->vchg_mem = malloc(xc->vchg_alloc_siz); if(xc->hier_handle && xc->geom_handle && xc->valpos_handle && xc->curval_handle && xc->vchg_mem && xc->tchn_handle) { xc->filename = strdup(nam); xc->is_initial_time = 1; fstWriterEmitHdrBytes(xc); xc->nan = strtod("NaN", NULL); #ifdef FST_WRITER_PARALLEL pthread_mutex_init(&xc->mutex, NULL); pthread_attr_init(&xc->thread_attr); pthread_attr_setdetachstate(&xc->thread_attr, PTHREAD_CREATE_DETACHED); #endif } else { fclose(xc->handle); if(xc->hier_handle) { fclose(xc->hier_handle); unlink(hf); } tmpfile_close(&xc->geom_handle, &xc->geom_handle_nam); tmpfile_close(&xc->valpos_handle, &xc->valpos_handle_nam); tmpfile_close(&xc->curval_handle, &xc->curval_handle_nam); tmpfile_close(&xc->tchn_handle, &xc->tchn_handle_nam); free(xc->vchg_mem); free(xc); xc=NULL; } free(hf); } return(xc); } /* * generation and writing out of value change data sections */ static void fstWriterEmitSectionHeader(void *ctx) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { unsigned long destlen; unsigned char *dmem; int rc; destlen = xc->maxvalpos; dmem = malloc(compressBound(destlen)); rc = compress2(dmem, &destlen, xc->curval_mem, xc->maxvalpos, 4); /* was 9...which caused performance drag on traces with many signals */ fputc(FST_BL_SKIP, xc->handle); /* temporarily tag the section, use FST_BL_VCDATA on finalize */ xc->section_start = ftello(xc->handle); #ifdef FST_WRITER_PARALLEL if(xc->xc_parent) xc->xc_parent->section_start = xc->section_start; #endif xc->section_header_only = 1; /* indicates truncate might be needed */ fstWriterUint64(xc->handle, 0); /* placeholder = section length */ fstWriterUint64(xc->handle, xc->is_initial_time ? xc->firsttime : xc->curtime); /* begin time of section */ fstWriterUint64(xc->handle, xc->curtime); /* end time of section (placeholder) */ fstWriterUint64(xc->handle, 0); /* placeholder = amount of buffer memory required in reader for full vc traversal */ fstWriterVarint(xc->handle, xc->maxvalpos); /* maxvalpos = length of uncompressed data */ if((rc == Z_OK) && (destlen < xc->maxvalpos)) { fstWriterVarint(xc->handle, destlen); /* length of compressed data */ } else { fstWriterVarint(xc->handle, xc->maxvalpos); /* length of (unable to be) compressed data */ } fstWriterVarint(xc->handle, xc->maxhandle); /* max handle associated with this data (in case of dynamic facility adds) */ if((rc == Z_OK) && (destlen < xc->maxvalpos)) { fstFwrite(dmem, destlen, 1, xc->handle); } else /* comparison between compressed / decompressed len tells if compressed */ { fstFwrite(xc->curval_mem, xc->maxvalpos, 1, xc->handle); } free(dmem); } } /* * only to be called directly by fst code...otherwise must * be synced up with time changes */ #ifdef FST_WRITER_PARALLEL static void fstWriterFlushContextPrivate2(void *ctx) #else static void fstWriterFlushContextPrivate(void *ctx) #endif { #ifdef FST_DEBUG int cnt = 0; #endif unsigned int i; unsigned char *vchg_mem; FILE *f; off_t fpos, indxpos, endpos; uint32_t prevpos; int zerocnt; unsigned char *scratchpad; unsigned char *scratchpnt; unsigned char *tmem; off_t tlen; off_t unc_memreq = 0; /* for reader */ unsigned char *packmem; unsigned int packmemlen; uint32_t *vm4ip; struct fstWriterContext *xc = (struct fstWriterContext *)ctx; #ifdef FST_WRITER_PARALLEL struct fstWriterContext *xc2 = xc->xc_parent; #else struct fstWriterContext *xc2 = xc; #endif #ifndef FST_DYNAMIC_ALIAS_DISABLE Pvoid_t PJHSArray = (Pvoid_t) NULL; #ifndef _WAVE_HAVE_JUDY uint32_t hashmask = xc->maxhandle; hashmask |= hashmask >> 1; hashmask |= hashmask >> 2; hashmask |= hashmask >> 4; hashmask |= hashmask >> 8; hashmask |= hashmask >> 16; #endif #endif if((xc->vchg_siz <= 1)||(xc->already_in_flush)) return; xc->already_in_flush = 1; /* should really do this with a semaphore */ xc->section_header_only = 0; scratchpad = malloc(xc->vchg_siz); vchg_mem = xc->vchg_mem; f = xc->handle; fstWriterVarint(f, xc->maxhandle); /* emit current number of handles */ fputc(xc->fourpack ? '4' : (xc->fastpack ? 'F' : 'Z'), f); fpos = 1; packmemlen = 1024; /* maintain a running "longest" allocation to */ packmem = malloc(packmemlen); /* prevent continual malloc...free every loop iter */ for(i=0;imaxhandle;i++) { vm4ip = &(xc->valpos_mem[4*i]); if(vm4ip[2]) { uint32_t offs = vm4ip[2]; uint32_t next_offs; unsigned int wrlen; vm4ip[2] = fpos; scratchpnt = scratchpad + xc->vchg_siz; /* build this buffer backwards */ if(vm4ip[1] <= 1) { if(vm4ip[1] == 1) { wrlen = fstGetVarint32Length(vchg_mem + offs + 4); /* used to advance and determine wrlen */ #ifndef FST_REMOVE_DUPLICATE_VC xc->curval_mem[vm4ip[0]] = vchg_mem[offs + 4 + wrlen]; /* checkpoint variable */ #endif while(offs) { unsigned char val; uint32_t time_delta, rcv; next_offs = fstGetUint32(vchg_mem + offs); offs += 4; time_delta = fstGetVarint32(vchg_mem + offs, (int *)&wrlen); val = vchg_mem[offs+wrlen]; offs = next_offs; switch(val) { case '0': case '1': rcv = ((val&1)<<1) | (time_delta<<2); break; /* pack more delta bits in for 0/1 vchs */ case 'x': case 'X': rcv = FST_RCV_X | (time_delta<<4); break; case 'z': case 'Z': rcv = FST_RCV_Z | (time_delta<<4); break; case 'h': case 'H': rcv = FST_RCV_H | (time_delta<<4); break; case 'u': case 'U': rcv = FST_RCV_U | (time_delta<<4); break; case 'w': case 'W': rcv = FST_RCV_W | (time_delta<<4); break; case 'l': case 'L': rcv = FST_RCV_L | (time_delta<<4); break; default: rcv = FST_RCV_D | (time_delta<<4); break; } scratchpnt = fstCopyVarint32ToLeft(scratchpnt, rcv); } } else { /* variable length */ /* fstGetUint32 (next_offs) + fstGetVarint32 (time_delta) + fstGetVarint32 (len) + payload */ unsigned char *pnt; uint32_t record_len; uint32_t time_delta; while(offs) { next_offs = fstGetUint32(vchg_mem + offs); offs += 4; pnt = vchg_mem + offs; offs = next_offs; time_delta = fstGetVarint32(pnt, (int *)&wrlen); pnt += wrlen; record_len = fstGetVarint32(pnt, (int *)&wrlen); pnt += wrlen; scratchpnt -= record_len; memcpy(scratchpnt, pnt, record_len); scratchpnt = fstCopyVarint32ToLeft(scratchpnt, record_len); scratchpnt = fstCopyVarint32ToLeft(scratchpnt, (time_delta << 1)); /* reserve | 1 case for future expansion */ } } } else { wrlen = fstGetVarint32Length(vchg_mem + offs + 4); /* used to advance and determine wrlen */ #ifndef FST_REMOVE_DUPLICATE_VC memcpy(xc->curval_mem + vm4ip[0], vchg_mem + offs + 4 + wrlen, vm4ip[1]); /* checkpoint variable */ #endif while(offs) { unsigned int idx; char is_binary = 1; unsigned char *pnt; uint32_t time_delta; next_offs = fstGetUint32(vchg_mem + offs); offs += 4; time_delta = fstGetVarint32(vchg_mem + offs, (int *)&wrlen); pnt = vchg_mem+offs+wrlen; offs = next_offs; for(idx=0;idxvchg_siz - scratchpnt; unc_memreq += wrlen; if(wrlen > 32) { unsigned long destlen = wrlen; unsigned char *dmem; unsigned int rc; if(!xc->fastpack) { if(wrlen <= packmemlen) { dmem = packmem; } else { free(packmem); dmem = packmem = malloc(compressBound(packmemlen = wrlen)); } rc = compress2(dmem, &destlen, scratchpnt, wrlen, 4); if(rc == Z_OK) { #ifndef FST_DYNAMIC_ALIAS_DISABLE PPvoid_t pv = JudyHSIns(&PJHSArray, dmem, destlen, NULL); if(*pv) { uint32_t pvi = (intptr_t)(*pv); vm4ip[2] = -pvi; } else { *pv = (void *)(intptr_t)(i+1); #endif fpos += fstWriterVarint(f, wrlen); fpos += destlen; fstFwrite(dmem, destlen, 1, f); #ifndef FST_DYNAMIC_ALIAS_DISABLE } #endif } else { #ifndef FST_DYNAMIC_ALIAS_DISABLE PPvoid_t pv = JudyHSIns(&PJHSArray, scratchpnt, wrlen, NULL); if(*pv) { uint32_t pvi = (intptr_t)(*pv); vm4ip[2] = -pvi; } else { *pv = (void *)(intptr_t)(i+1); #endif fpos += fstWriterVarint(f, 0); fpos += wrlen; fstFwrite(scratchpnt, wrlen, 1, f); #ifndef FST_DYNAMIC_ALIAS_DISABLE } #endif } } else { /* this is extremely conservative: fastlz needs +5% for worst case, lz4 needs siz+(siz/255)+16 */ if(((wrlen * 2) + 2) <= packmemlen) { dmem = packmem; } else { free(packmem); dmem = packmem = malloc(packmemlen = (wrlen * 2) + 2); } rc = (xc->fourpack) ? LZ4_compress((char *)scratchpnt, (char *)dmem, wrlen) : fastlz_compress(scratchpnt, wrlen, dmem); if(rc < destlen) { #ifndef FST_DYNAMIC_ALIAS_DISABLE PPvoid_t pv = JudyHSIns(&PJHSArray, dmem, rc, NULL); if(*pv) { uint32_t pvi = (intptr_t)(*pv); vm4ip[2] = -pvi; } else { *pv = (void *)(intptr_t)(i+1); #endif fpos += fstWriterVarint(f, wrlen); fpos += rc; fstFwrite(dmem, rc, 1, f); #ifndef FST_DYNAMIC_ALIAS_DISABLE } #endif } else { #ifndef FST_DYNAMIC_ALIAS_DISABLE PPvoid_t pv = JudyHSIns(&PJHSArray, scratchpnt, wrlen, NULL); if(*pv) { uint32_t pvi = (intptr_t)(*pv); vm4ip[2] = -pvi; } else { *pv = (void *)(intptr_t)(i+1); #endif fpos += fstWriterVarint(f, 0); fpos += wrlen; fstFwrite(scratchpnt, wrlen, 1, f); #ifndef FST_DYNAMIC_ALIAS_DISABLE } #endif } } } else { #ifndef FST_DYNAMIC_ALIAS_DISABLE PPvoid_t pv = JudyHSIns(&PJHSArray, scratchpnt, wrlen, NULL); if(*pv) { uint32_t pvi = (intptr_t)(*pv); vm4ip[2] = -pvi; } else { *pv = (void *)(intptr_t)(i+1); #endif fpos += fstWriterVarint(f, 0); fpos += wrlen; fstFwrite(scratchpnt, wrlen, 1, f); #ifndef FST_DYNAMIC_ALIAS_DISABLE } #endif } /* vm4ip[3] = 0; ...redundant with clearing below */ #ifdef FST_DEBUG cnt++; #endif } } #ifndef FST_DYNAMIC_ALIAS_DISABLE JudyHSFreeArray(&PJHSArray, NULL); #endif free(packmem); packmem = NULL; /* packmemlen = 0; */ /* scan-build */ prevpos = 0; zerocnt = 0; free(scratchpad); scratchpad = NULL; indxpos = ftello(f); xc->secnum++; #ifndef FST_DYNAMIC_ALIAS2_DISABLE if(1) { uint32_t prev_alias = 0; for(i=0;imaxhandle;i++) { vm4ip = &(xc->valpos_mem[4*i]); if(vm4ip[2]) { if(zerocnt) { fpos += fstWriterVarint(f, (zerocnt << 1)); zerocnt = 0; } if(vm4ip[2] & 0x80000000) { if(vm4ip[2] != prev_alias) { fpos += fstWriterSVarint(f, (((int64_t)((int32_t)(prev_alias = vm4ip[2]))) << 1) | 1); } else { fpos += fstWriterSVarint(f, (0 << 1) | 1); } } else { fpos += fstWriterSVarint(f, ((vm4ip[2] - prevpos) << 1) | 1); prevpos = vm4ip[2]; } vm4ip[2] = 0; vm4ip[3] = 0; /* clear out tchn idx */ } else { zerocnt++; } } } else #endif { for(i=0;imaxhandle;i++) { vm4ip = &(xc->valpos_mem[4*i]); if(vm4ip[2]) { if(zerocnt) { fpos += fstWriterVarint(f, (zerocnt << 1)); zerocnt = 0; } if(vm4ip[2] & 0x80000000) { fpos += fstWriterVarint(f, 0); /* signal, note that using a *signed* varint would be more efficient than this byte escape! */ fpos += fstWriterVarint(f, (-(int32_t)vm4ip[2])); } else { fpos += fstWriterVarint(f, ((vm4ip[2] - prevpos) << 1) | 1); prevpos = vm4ip[2]; } vm4ip[2] = 0; vm4ip[3] = 0; /* clear out tchn idx */ } else { zerocnt++; } } } if(zerocnt) { /* fpos += */ fstWriterVarint(f, (zerocnt << 1)); /* scan-build */ } #ifdef FST_DEBUG fprintf(stderr, "value chains: %d\n", cnt); #endif xc->vchg_mem[0] = '!'; xc->vchg_siz = 1; endpos = ftello(xc->handle); fstWriterUint64(xc->handle, endpos-indxpos); /* write delta index position at very end of block */ /*emit time changes for block */ fflush(xc->tchn_handle); tlen = ftello(xc->tchn_handle); fstWriterFseeko(xc, xc->tchn_handle, 0, SEEK_SET); tmem = fstMmap(NULL, tlen, PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->tchn_handle), 0); if(tmem) { unsigned long destlen = tlen; unsigned char *dmem = malloc(compressBound(destlen)); int rc = compress2(dmem, &destlen, tmem, tlen, 9); if((rc == Z_OK) && (((off_t)destlen) < tlen)) { fstFwrite(dmem, destlen, 1, xc->handle); } else /* comparison between compressed / decompressed len tells if compressed */ { fstFwrite(tmem, tlen, 1, xc->handle); destlen = tlen; } free(dmem); fstMunmap(tmem, tlen); fstWriterUint64(xc->handle, tlen); /* uncompressed */ fstWriterUint64(xc->handle, destlen); /* compressed */ fstWriterUint64(xc->handle, xc->tchn_cnt); /* number of time items */ } xc->tchn_cnt = xc->tchn_idx = 0; fstWriterFseeko(xc, xc->tchn_handle, 0, SEEK_SET); fstFtruncate(fileno(xc->tchn_handle), 0); /* write block trailer */ endpos = ftello(xc->handle); fstWriterFseeko(xc, xc->handle, xc->section_start, SEEK_SET); fstWriterUint64(xc->handle, endpos - xc->section_start); /* write block length */ fstWriterFseeko(xc, xc->handle, 8, SEEK_CUR); /* skip begin time */ fstWriterUint64(xc->handle, xc->curtime); /* write end time for section */ fstWriterUint64(xc->handle, unc_memreq); /* amount of buffer memory required in reader for full traversal */ fflush(xc->handle); fstWriterFseeko(xc, xc->handle, xc->section_start-1, SEEK_SET); /* write out FST_BL_VCDATA over FST_BL_SKIP */ #ifndef FST_DYNAMIC_ALIAS_DISABLE #ifndef FST_DYNAMIC_ALIAS2_DISABLE fputc(FST_BL_VCDATA_DYN_ALIAS2, xc->handle); #else fputc(FST_BL_VCDATA_DYN_ALIAS, xc->handle); #endif #else fputc(FST_BL_VCDATA, xc->handle); #endif fflush(xc->handle); fstWriterFseeko(xc, xc->handle, endpos, SEEK_SET); /* seek to end of file */ xc2->section_header_truncpos = endpos; /* cache in case of need to truncate */ if(xc->dump_size_limit) { if(endpos >= ((off_t)xc->dump_size_limit)) { xc2->skip_writing_section_hdr = 1; xc2->size_limit_locked = 1; xc2->is_initial_time = 1; /* to trick emit value and emit time change */ #ifdef FST_DEBUG fprintf(stderr, "<< dump file size limit reached, stopping dumping >>\n"); #endif } } if(!xc2->skip_writing_section_hdr) { fstWriterEmitSectionHeader(xc); /* emit next section header */ } fflush(xc->handle); xc->already_in_flush = 0; } #ifdef FST_WRITER_PARALLEL static void *fstWriterFlushContextPrivate1(void *ctx) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; fstWriterFlushContextPrivate2(xc); pthread_mutex_unlock(&(xc->xc_parent->mutex)); #ifdef FST_REMOVE_DUPLICATE_VC free(xc->curval_mem); #endif free(xc->valpos_mem); free(xc->vchg_mem); tmpfile_close(&xc->tchn_handle, &xc->tchn_handle_nam); free(xc); return(NULL); } static void fstWriterFlushContextPrivate(void *ctx) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc->parallel_enabled) { struct fstWriterContext *xc2 = malloc(sizeof(struct fstWriterContext)); unsigned int i; pthread_mutex_lock(&xc->mutex); pthread_mutex_unlock(&xc->mutex); xc->xc_parent = xc; memcpy(xc2, xc, sizeof(struct fstWriterContext)); xc2->valpos_mem = malloc(xc->maxhandle * 4 * sizeof(uint32_t)); memcpy(xc2->valpos_mem, xc->valpos_mem, xc->maxhandle * 4 * sizeof(uint32_t)); /* curval mem is updated in the thread */ #ifdef FST_REMOVE_DUPLICATE_VC xc2->curval_mem = malloc(xc->maxvalpos); memcpy(xc2->curval_mem, xc->curval_mem, xc->maxvalpos); #endif xc->vchg_mem = malloc(xc->vchg_alloc_siz); xc->vchg_mem[0] = '!'; xc->vchg_siz = 1; for(i=0;imaxhandle;i++) { uint32_t *vm4ip = &(xc->valpos_mem[4*i]); vm4ip[2] = 0; /* zero out offset val */ vm4ip[3] = 0; /* zero out last time change val */ } xc->tchn_cnt = xc->tchn_idx = 0; xc->tchn_handle = tmpfile_open(&xc->tchn_handle_nam); /* child thread will deallocate file/name */ fstWriterFseeko(xc, xc->tchn_handle, 0, SEEK_SET); fstFtruncate(fileno(xc->tchn_handle), 0); xc->section_header_only = 0; xc->secnum++; pthread_mutex_lock(&xc->mutex); pthread_create(&xc->thread, &xc->thread_attr, fstWriterFlushContextPrivate1, xc2); } else { if(xc->parallel_was_enabled) /* conservatively block */ { pthread_mutex_lock(&xc->mutex); pthread_mutex_unlock(&xc->mutex); } xc->xc_parent = xc; fstWriterFlushContextPrivate2(xc); } } #endif /* * queues up a flush context operation */ void fstWriterFlushContext(void *ctx) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { if(xc->tchn_idx > 1) { xc->flush_context_pending = 1; } } } /* * close out FST file */ void fstWriterClose(void *ctx) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; #ifdef FST_WRITER_PARALLEL if(xc) { pthread_mutex_lock(&xc->mutex); pthread_mutex_unlock(&xc->mutex); } #endif if(xc && !xc->already_in_close && !xc->already_in_flush) { unsigned char *tmem; off_t fixup_offs, tlen, hlen; xc->already_in_close = 1; /* never need to zero this out as it is freed at bottom */ if(xc->section_header_only && xc->section_header_truncpos && (xc->vchg_siz <= 1) && (!xc->is_initial_time)) { fstFtruncate(fileno(xc->handle), xc->section_header_truncpos); fstWriterFseeko(xc, xc->handle, xc->section_header_truncpos, SEEK_SET); xc->section_header_only = 0; } else { xc->skip_writing_section_hdr = 1; if(!xc->size_limit_locked) { if(xc->is_initial_time) /* simulation time never advanced so mock up the changes as time zero ones */ { fstHandle dupe_idx; fstWriterEmitTimeChange(xc, 0); /* emit some time change just to have one */ for(dupe_idx = 0; dupe_idx < xc->maxhandle; dupe_idx++) /* now clone the values */ { fstWriterEmitValueChange(xc, dupe_idx+1, xc->curval_mem + xc->valpos_mem[4*dupe_idx]); } } fstWriterFlushContextPrivate(xc); #ifdef FST_WRITER_PARALLEL pthread_mutex_lock(&xc->mutex); pthread_mutex_unlock(&xc->mutex); #endif } } fstDestroyMmaps(xc, 1); /* write out geom section */ fflush(xc->geom_handle); tlen = ftello(xc->geom_handle); tmem = fstMmap(NULL, tlen, PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->geom_handle), 0); if(tmem) { unsigned long destlen = tlen; unsigned char *dmem = malloc(compressBound(destlen)); int rc = compress2(dmem, &destlen, tmem, tlen, 9); if((rc != Z_OK) || (((off_t)destlen) > tlen)) { destlen = tlen; } fixup_offs = ftello(xc->handle); fputc(FST_BL_SKIP, xc->handle); /* temporary tag */ fstWriterUint64(xc->handle, destlen + 24); /* section length */ fstWriterUint64(xc->handle, tlen); /* uncompressed */ /* compressed len is section length - 24 */ fstWriterUint64(xc->handle, xc->maxhandle); /* maxhandle */ fstFwrite((((off_t)destlen) != tlen) ? dmem : tmem, destlen, 1, xc->handle); fflush(xc->handle); fstWriterFseeko(xc, xc->handle, fixup_offs, SEEK_SET); fputc(FST_BL_GEOM, xc->handle); /* actual tag */ fstWriterFseeko(xc, xc->handle, 0, SEEK_END); /* move file pointer to end for any section adds */ fflush(xc->handle); free(dmem); fstMunmap(tmem, tlen); } if(xc->num_blackouts) { uint64_t cur_bl = 0; off_t bpos, eos; uint32_t i; fixup_offs = ftello(xc->handle); fputc(FST_BL_SKIP, xc->handle); /* temporary tag */ bpos = fixup_offs + 1; fstWriterUint64(xc->handle, 0); /* section length */ fstWriterVarint(xc->handle, xc->num_blackouts); for(i=0;inum_blackouts;i++) { fputc(xc->blackout_head->active, xc->handle); fstWriterVarint(xc->handle, xc->blackout_head->tim - cur_bl); cur_bl = xc->blackout_head->tim; xc->blackout_curr = xc->blackout_head->next; free(xc->blackout_head); xc->blackout_head = xc->blackout_curr; } eos = ftello(xc->handle); fstWriterFseeko(xc, xc->handle, bpos, SEEK_SET); fstWriterUint64(xc->handle, eos - bpos); fflush(xc->handle); fstWriterFseeko(xc, xc->handle, fixup_offs, SEEK_SET); fputc(FST_BL_BLACKOUT, xc->handle); /* actual tag */ fstWriterFseeko(xc, xc->handle, 0, SEEK_END); /* move file pointer to end for any section adds */ fflush(xc->handle); } if(xc->compress_hier) { off_t hl, eos; gzFile zhandle; int zfd; int fourpack_duo = 0; #ifndef __MINGW32__ char *fnam = malloc(strlen(xc->filename) + 5 + 1); #endif fixup_offs = ftello(xc->handle); fputc(FST_BL_SKIP, xc->handle); /* temporary tag */ hlen = ftello(xc->handle); fstWriterUint64(xc->handle, 0); /* section length */ fstWriterUint64(xc->handle, xc->hier_file_len); /* uncompressed length */ if(!xc->fourpack) { unsigned char *mem = malloc(FST_GZIO_LEN); zfd = dup(fileno(xc->handle)); fflush(xc->handle); zhandle = gzdopen(zfd, "wb4"); if(zhandle) { fstWriterFseeko(xc, xc->hier_handle, 0, SEEK_SET); for(hl = 0; hl < xc->hier_file_len; hl += FST_GZIO_LEN) { unsigned len = ((xc->hier_file_len - hl) > FST_GZIO_LEN) ? FST_GZIO_LEN : (xc->hier_file_len - hl); fstFread(mem, len, 1, xc->hier_handle); gzwrite(zhandle, mem, len); } gzclose(zhandle); } else { close(zfd); } free(mem); } else { int lz4_maxlen; unsigned char *mem; unsigned char *hmem; int packed_len; fflush(xc->handle); lz4_maxlen = LZ4_compressBound(xc->hier_file_len); mem = malloc(lz4_maxlen); hmem = fstMmap(NULL, xc->hier_file_len, PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->hier_handle), 0); packed_len = LZ4_compress((char *)hmem, (char *)mem, xc->hier_file_len); fstMunmap(hmem, xc->hier_file_len); fourpack_duo = (!xc->repack_on_close) && (xc->hier_file_len > FST_HDR_FOURPACK_DUO_SIZE); /* double pack when hierarchy is large */ if(fourpack_duo) /* double packing with LZ4 is faster than gzip */ { unsigned char *mem_duo; int lz4_maxlen_duo; int packed_len_duo; lz4_maxlen_duo = LZ4_compressBound(packed_len); mem_duo = malloc(lz4_maxlen_duo); packed_len_duo = LZ4_compress((char *)mem, (char *)mem_duo, packed_len); fstWriterVarint(xc->handle, packed_len); /* 1st round compressed length */ fstFwrite(mem_duo, packed_len_duo, 1, xc->handle); free(mem_duo); } else { fstFwrite(mem, packed_len, 1, xc->handle); } free(mem); } fstWriterFseeko(xc, xc->handle, 0, SEEK_END); eos = ftello(xc->handle); fstWriterFseeko(xc, xc->handle, hlen, SEEK_SET); fstWriterUint64(xc->handle, eos - hlen); fflush(xc->handle); fstWriterFseeko(xc, xc->handle, fixup_offs, SEEK_SET); fputc(xc->fourpack ? ( fourpack_duo ? FST_BL_HIER_LZ4DUO : FST_BL_HIER_LZ4) : FST_BL_HIER, xc->handle); /* actual tag now also == compression type */ fstWriterFseeko(xc, xc->handle, 0, SEEK_END); /* move file pointer to end for any section adds */ fflush(xc->handle); #ifndef __MINGW32__ sprintf(fnam, "%s.hier", xc->filename); unlink(fnam); free(fnam); #endif } /* finalize out header */ fstWriterFseeko(xc, xc->handle, FST_HDR_OFFS_START_TIME, SEEK_SET); fstWriterUint64(xc->handle, xc->firsttime); fstWriterUint64(xc->handle, xc->curtime); fstWriterFseeko(xc, xc->handle, FST_HDR_OFFS_NUM_SCOPES, SEEK_SET); fstWriterUint64(xc->handle, xc->numscopes); fstWriterUint64(xc->handle, xc->numsigs); fstWriterUint64(xc->handle, xc->maxhandle); fstWriterUint64(xc->handle, xc->secnum); fflush(xc->handle); tmpfile_close(&xc->tchn_handle, &xc->tchn_handle_nam); free(xc->vchg_mem); xc->vchg_mem = NULL; tmpfile_close(&xc->curval_handle, &xc->curval_handle_nam); tmpfile_close(&xc->valpos_handle, &xc->valpos_handle_nam); tmpfile_close(&xc->geom_handle, &xc->geom_handle_nam); if(xc->hier_handle) { fclose(xc->hier_handle); xc->hier_handle = NULL; } if(xc->handle) { if(xc->repack_on_close) { FILE *fp; off_t offpnt, uclen; int flen = strlen(xc->filename); char *hf = calloc(1, flen + 5); strcpy(hf, xc->filename); strcpy(hf+flen, ".pak"); fp = fopen(hf, "wb"); if(fp) { void *dsth; int zfd; char gz_membuf[FST_GZIO_LEN]; fstWriterFseeko(xc, xc->handle, 0, SEEK_END); uclen = ftello(xc->handle); fputc(FST_BL_ZWRAPPER, fp); fstWriterUint64(fp, 0); fstWriterUint64(fp, uclen); fflush(fp); fstWriterFseeko(xc, xc->handle, 0, SEEK_SET); zfd = dup(fileno(fp)); dsth = gzdopen(zfd, "wb4"); if(dsth) { for(offpnt = 0; offpnt < uclen; offpnt += FST_GZIO_LEN) { size_t this_len = ((uclen - offpnt) > FST_GZIO_LEN) ? FST_GZIO_LEN : (uclen - offpnt); fstFread(gz_membuf, this_len, 1, xc->handle); gzwrite(dsth, gz_membuf, this_len); } gzclose(dsth); } else { close(zfd); } fstWriterFseeko(xc, fp, 0, SEEK_END); offpnt = ftello(fp); fstWriterFseeko(xc, fp, 1, SEEK_SET); fstWriterUint64(fp, offpnt - 1); fclose(fp); fclose(xc->handle); xc->handle = NULL; unlink(xc->filename); rename(hf, xc->filename); } else { xc->repack_on_close = 0; fclose(xc->handle); xc->handle = NULL; } free(hf); } else { fclose(xc->handle); xc->handle = NULL; } } #ifdef __MINGW32__ { int flen = strlen(xc->filename); char *hf = calloc(1, flen + 6); strcpy(hf, xc->filename); if(xc->compress_hier) { strcpy(hf + flen, ".hier"); unlink(hf); /* no longer needed as a section now exists for this */ } free(hf); } #endif #ifdef FST_WRITER_PARALLEL pthread_mutex_destroy(&xc->mutex); pthread_attr_destroy(&xc->thread_attr); #endif if(xc->path_array) { #ifndef _WAVE_HAVE_JUDY const uint32_t hashmask = FST_PATH_HASHMASK; #endif JudyHSFreeArray(&(xc->path_array), NULL); } free(xc->filename); xc->filename = NULL; free(xc); } } /* * functions to set miscellaneous header/block information */ void fstWriterSetDate(void *ctx, const char *dat) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { char s[FST_HDR_DATE_SIZE]; off_t fpos = ftello(xc->handle); int len = strlen(dat); fstWriterFseeko(xc, xc->handle, FST_HDR_OFFS_DATE, SEEK_SET); memset(s, 0, FST_HDR_DATE_SIZE); memcpy(s, dat, (len < FST_HDR_DATE_SIZE) ? len : FST_HDR_DATE_SIZE); fstFwrite(s, FST_HDR_DATE_SIZE, 1, xc->handle); fflush(xc->handle); fstWriterFseeko(xc, xc->handle, fpos, SEEK_SET); } } void fstWriterSetVersion(void *ctx, const char *vers) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc && vers) { char s[FST_HDR_SIM_VERSION_SIZE]; off_t fpos = ftello(xc->handle); int len = strlen(vers); fstWriterFseeko(xc, xc->handle, FST_HDR_OFFS_SIM_VERSION, SEEK_SET); memset(s, 0, FST_HDR_SIM_VERSION_SIZE); memcpy(s, vers, (len < FST_HDR_SIM_VERSION_SIZE) ? len : FST_HDR_SIM_VERSION_SIZE); fstFwrite(s, FST_HDR_SIM_VERSION_SIZE, 1, xc->handle); fflush(xc->handle); fstWriterFseeko(xc, xc->handle, fpos, SEEK_SET); } } void fstWriterSetFileType(void *ctx, enum fstFileType filetype) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { if(/*(filetype >= FST_FT_MIN) &&*/ (filetype <= FST_FT_MAX)) { off_t fpos = ftello(xc->handle); xc->filetype = filetype; fstWriterFseeko(xc, xc->handle, FST_HDR_OFFS_FILETYPE, SEEK_SET); fputc(xc->filetype, xc->handle); fflush(xc->handle); fstWriterFseeko(xc, xc->handle, fpos, SEEK_SET); } } } static void fstWriterSetAttrDoubleArgGeneric(void *ctx, int typ, uint64_t arg1, uint64_t arg2) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { unsigned char buf[11]; /* ceil(64/7) = 10 + null term */ unsigned char *pnt = fstCopyVarint64ToRight(buf, arg1); if(arg1) { *pnt = 0; /* this converts any *nonzero* arg1 when made a varint into a null-term string */ } fstWriterSetAttrBegin(xc, FST_AT_MISC, typ, (char *)buf, arg2); } } static void fstWriterSetAttrGeneric(void *ctx, const char *comm, int typ, uint64_t arg) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc && comm) { char *s = strdup(comm); char *sf = s; while(*s) { if((*s == '\n') || (*s == '\r')) *s = ' '; s++; } fstWriterSetAttrBegin(xc, FST_AT_MISC, typ, sf, arg); free(sf); } } static void fstWriterSetSourceStem_2(void *ctx, const char *path, unsigned int line, unsigned int use_realpath, int typ) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc && path && path[0]) { uint64_t sidx = 0; int slen = strlen(path); #ifndef _WAVE_HAVE_JUDY const uint32_t hashmask = FST_PATH_HASHMASK; const unsigned char *path2 = (const unsigned char *)path; PPvoid_t pv; #else char *path2 = alloca(slen + 1); /* judy lacks const qualifier in its JudyHSIns definition */ PPvoid_t pv; strcpy(path2, path); #endif pv = JudyHSIns(&(xc->path_array), path2, slen, NULL); if(*pv) { sidx = (intptr_t)(*pv); } else { char *rp = NULL; sidx = ++xc->path_array_count; *pv = (void *)(intptr_t)(xc->path_array_count); if(use_realpath) { rp = fstRealpath( #ifndef _WAVE_HAVE_JUDY (const char *) #endif path2, NULL); } fstWriterSetAttrGeneric(xc, rp ? rp : #ifndef _WAVE_HAVE_JUDY (const char *) #endif path2, FST_MT_PATHNAME, sidx); if(rp) { free(rp); } } fstWriterSetAttrDoubleArgGeneric(xc, typ, sidx, line); } } void fstWriterSetSourceStem(void *ctx, const char *path, unsigned int line, unsigned int use_realpath) { fstWriterSetSourceStem_2(ctx, path, line, use_realpath, FST_MT_SOURCESTEM); } void fstWriterSetSourceInstantiationStem(void *ctx, const char *path, unsigned int line, unsigned int use_realpath) { fstWriterSetSourceStem_2(ctx, path, line, use_realpath, FST_MT_SOURCEISTEM); } void fstWriterSetComment(void *ctx, const char *comm) { fstWriterSetAttrGeneric(ctx, comm, FST_MT_COMMENT, 0); } void fstWriterSetValueList(void *ctx, const char *vl) { fstWriterSetAttrGeneric(ctx, vl, FST_MT_VALUELIST, 0); } void fstWriterSetEnvVar(void *ctx, const char *envvar) { fstWriterSetAttrGeneric(ctx, envvar, FST_MT_ENVVAR, 0); } void fstWriterSetTimescale(void *ctx, int ts) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { off_t fpos = ftello(xc->handle); fstWriterFseeko(xc, xc->handle, FST_HDR_OFFS_TIMESCALE, SEEK_SET); fputc(ts & 255, xc->handle); fflush(xc->handle); fstWriterFseeko(xc, xc->handle, fpos, SEEK_SET); } } void fstWriterSetTimescaleFromString(void *ctx, const char *s) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc && s) { int mat = 0; int seconds_exp = -9; int tv = atoi(s); const char *pnt = s; while(*pnt) { switch(*pnt) { case 'm': seconds_exp = -3; mat = 1; break; case 'u': seconds_exp = -6; mat = 1; break; case 'n': seconds_exp = -9; mat = 1; break; case 'p': seconds_exp = -12; mat = 1; break; case 'f': seconds_exp = -15; mat = 1; break; case 'a': seconds_exp = -18; mat = 1; break; case 'z': seconds_exp = -21; mat = 1; break; case 's': seconds_exp = 0; mat = 1; break; default: break; } if(mat) break; pnt++; } if(tv == 10) { seconds_exp++; } else if(tv == 100) { seconds_exp+=2; } fstWriterSetTimescale(ctx, seconds_exp); } } void fstWriterSetTimezero(void *ctx, int64_t tim) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { off_t fpos = ftello(xc->handle); fstWriterFseeko(xc, xc->handle, FST_HDR_OFFS_TIMEZERO, SEEK_SET); fstWriterUint64(xc->handle, (xc->timezero = tim)); fflush(xc->handle); fstWriterFseeko(xc, xc->handle, fpos, SEEK_SET); } } void fstWriterSetPackType(void *ctx, enum fstWriterPackType typ) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { xc->fastpack = (typ != FST_WR_PT_ZLIB); xc->fourpack = (typ == FST_WR_PT_LZ4); } } void fstWriterSetRepackOnClose(void *ctx, int enable) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { xc->repack_on_close = (enable != 0); } } void fstWriterSetParallelMode(void *ctx, int enable) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { xc->parallel_was_enabled |= xc->parallel_enabled; /* make sticky */ xc->parallel_enabled = (enable != 0); #ifndef FST_WRITER_PARALLEL if(xc->parallel_enabled) { fprintf(stderr, "ERROR: fstWriterSetParallelMode(), FST_WRITER_PARALLEL not enabled during compile, exiting.\n"); exit(255); } #endif } } void fstWriterSetDumpSizeLimit(void *ctx, uint64_t numbytes) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { xc->dump_size_limit = numbytes; } } int fstWriterGetDumpSizeLimitReached(void *ctx) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { return(xc->size_limit_locked != 0); } return(0); } int fstWriterGetFseekFailed(void *ctx) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { return(xc->fseek_failed != 0); } return(0); } /* * writer attr/scope/var creation: * fstWriterCreateVar2() is used to dump VHDL or other languages, but the * underlying variable needs to map to Verilog/SV via the proper fstVarType vt */ fstHandle fstWriterCreateVar2(void *ctx, enum fstVarType vt, enum fstVarDir vd, uint32_t len, const char *nam, fstHandle aliasHandle, const char *type, enum fstSupplementalVarType svt, enum fstSupplementalDataType sdt) { fstWriterSetAttrGeneric(ctx, type ? type : "", FST_MT_SUPVAR, (svt<valpos_mem) { fstDestroyMmaps(xc, 0); } fputc(vt, xc->hier_handle); fputc(vd, xc->hier_handle); nlen = strlen(nam); fstFwrite(nam, nlen, 1, xc->hier_handle); fputc(0, xc->hier_handle); xc->hier_file_len += (nlen+3); if((vt == FST_VT_VCD_REAL) || (vt == FST_VT_VCD_REAL_PARAMETER) || (vt == FST_VT_VCD_REALTIME) || (vt == FST_VT_SV_SHORTREAL)) { is_real = 1; len = 8; /* recast number of bytes to that of what a double is */ } else { is_real = 0; if(vt == FST_VT_GEN_STRING) { len = 0; } } xc->hier_file_len += fstWriterVarint(xc->hier_handle, len); if(aliasHandle > xc->maxhandle) aliasHandle = 0; xc->hier_file_len += fstWriterVarint(xc->hier_handle, aliasHandle); xc->numsigs++; if(xc->numsigs == xc->next_huge_break) { if(xc->fst_break_size < xc->fst_huge_break_size) { xc->next_huge_break += FST_ACTIVATE_HUGE_INC; xc->fst_break_size += xc->fst_orig_break_size; xc->fst_break_add_size += xc->fst_orig_break_add_size; xc->vchg_alloc_siz = xc->fst_break_size + xc->fst_break_add_size; if(xc->vchg_mem) { xc->vchg_mem = realloc(xc->vchg_mem, xc->vchg_alloc_siz); } } } if(!aliasHandle) { uint32_t zero = 0; if(len) { fstWriterVarint(xc->geom_handle, !is_real ? len : 0); /* geom section encodes reals as zero byte */ } else { fstWriterVarint(xc->geom_handle, 0xFFFFFFFF); /* geom section encodes zero len as 32b -1 */ } fstFwrite(&xc->maxvalpos, sizeof(uint32_t), 1, xc->valpos_handle); fstFwrite(&len, sizeof(uint32_t), 1, xc->valpos_handle); fstFwrite(&zero, sizeof(uint32_t), 1, xc->valpos_handle); fstFwrite(&zero, sizeof(uint32_t), 1, xc->valpos_handle); if(!is_real) { for(i=0;icurval_handle); } } else { fstFwrite(&xc->nan, 8, 1, xc->curval_handle); /* initialize doubles to NaN rather than x */ } xc->maxvalpos+=len; xc->maxhandle++; return(xc->maxhandle); } else { return(aliasHandle); } } return(0); } void fstWriterSetScope(void *ctx, enum fstScopeType scopetype, const char *scopename, const char *scopecomp) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { fputc(FST_ST_VCD_SCOPE, xc->hier_handle); if(/*(scopetype < FST_ST_VCD_MODULE) ||*/ (scopetype > FST_ST_MAX)) { scopetype = FST_ST_VCD_MODULE; } fputc(scopetype, xc->hier_handle); fprintf(xc->hier_handle, "%s%c%s%c", scopename ? scopename : "", 0, scopecomp ? scopecomp : "", 0); if(scopename) { xc->hier_file_len += strlen(scopename); } if(scopecomp) { xc->hier_file_len += strlen(scopecomp); } xc->hier_file_len += 4; /* FST_ST_VCD_SCOPE + scopetype + two string terminating zeros */ xc->numscopes++; } } void fstWriterSetUpscope(void *ctx) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { fputc(FST_ST_VCD_UPSCOPE, xc->hier_handle); xc->hier_file_len++; } } void fstWriterSetAttrBegin(void *ctx, enum fstAttrType attrtype, int subtype, const char *attrname, uint64_t arg) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { fputc(FST_ST_GEN_ATTRBEGIN, xc->hier_handle); if(/*(attrtype < FST_AT_MISC) ||*/ (attrtype > FST_AT_MAX)) { attrtype = FST_AT_MISC; subtype = FST_MT_UNKNOWN; } fputc(attrtype, xc->hier_handle); switch(attrtype) { case FST_AT_ARRAY: if((subtype < FST_AR_NONE) || (subtype > FST_AR_MAX)) subtype = FST_AR_NONE; break; case FST_AT_ENUM: if((subtype < FST_EV_SV_INTEGER) || (subtype > FST_EV_MAX)) subtype = FST_EV_SV_INTEGER; break; case FST_AT_PACK: if((subtype < FST_PT_NONE) || (subtype > FST_PT_MAX)) subtype = FST_PT_NONE; break; case FST_AT_MISC: default: break; } fputc(subtype, xc->hier_handle); fprintf(xc->hier_handle, "%s%c", attrname ? attrname : "", 0); if(attrname) { xc->hier_file_len += strlen(attrname); } xc->hier_file_len += 4; /* FST_ST_GEN_ATTRBEGIN + type + subtype + string terminating zero */ xc->hier_file_len += fstWriterVarint(xc->hier_handle, arg); } } void fstWriterSetAttrEnd(void *ctx) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { fputc(FST_ST_GEN_ATTREND, xc->hier_handle); xc->hier_file_len++; } } /* * value and time change emission */ void fstWriterEmitValueChange(void *ctx, fstHandle handle, const void *val) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; const unsigned char *buf = (const unsigned char *)val; uint32_t offs; int len; if((xc) && (handle <= xc->maxhandle)) { uint32_t fpos; uint32_t *vm4ip; if(!xc->valpos_mem) { xc->vc_emitted = 1; fstWriterCreateMmaps(xc); } handle--; /* move starting at 1 index to starting at 0 */ vm4ip = &(xc->valpos_mem[4*handle]); len = vm4ip[1]; if(len) /* len of zero = variable length, use fstWriterEmitVariableLengthValueChange */ { if(!xc->is_initial_time) { fpos = xc->vchg_siz; if((fpos + len + 10) > xc->vchg_alloc_siz) { xc->vchg_alloc_siz += (xc->fst_break_add_size + len); /* +len added in the case of extremely long vectors and small break add sizes */ xc->vchg_mem = realloc(xc->vchg_mem, xc->vchg_alloc_siz); if(!xc->vchg_mem) { fprintf(stderr, "FATAL ERROR, could not realloc() in fstWriterEmitValueChange, exiting.\n"); exit(255); } } #ifdef FST_REMOVE_DUPLICATE_VC offs = vm4ip[0]; if(len != 1) { if((vm4ip[3]==xc->tchn_idx)&&(vm4ip[2])) { unsigned char *old_value = xc->vchg_mem + vm4ip[2] + 4; /* the +4 skips old vm4ip[2] value */ while(*(old_value++) & 0x80) { /* skips over varint encoded "xc->tchn_idx - vm4ip[3]" */ } memcpy(old_value, buf, len); /* overlay new value */ memcpy(xc->curval_mem + offs, buf, len); return; } else { if(!memcmp(xc->curval_mem + offs, buf, len)) { if(!xc->curtime) { int i; for(i=0;icurval_mem + offs, buf, len); } else { if((vm4ip[3]==xc->tchn_idx)&&(vm4ip[2])) { unsigned char *old_value = xc->vchg_mem + vm4ip[2] + 4; /* the +4 skips old vm4ip[2] value */ while(*(old_value++) & 0x80) { /* skips over varint encoded "xc->tchn_idx - vm4ip[3]" */ } *old_value = *buf; /* overlay new value */ *(xc->curval_mem + offs) = *buf; return; } else { if((*(xc->curval_mem + offs)) == (*buf)) { if(!xc->curtime) { if(*buf != 'x') return; } else { return; } } } *(xc->curval_mem + offs) = *buf; } #endif xc->vchg_siz += fstWriterUint32WithVarint32(xc, &vm4ip[2], xc->tchn_idx - vm4ip[3], buf, len); /* do one fwrite op only */ vm4ip[3] = xc->tchn_idx; vm4ip[2] = fpos; } else { offs = vm4ip[0]; memcpy(xc->curval_mem + offs, buf, len); } } } } void fstWriterEmitVariableLengthValueChange(void *ctx, fstHandle handle, const void *val, uint32_t len) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; const unsigned char *buf = (const unsigned char *)val; if((xc) && (handle <= xc->maxhandle)) { uint32_t fpos; uint32_t *vm4ip; if(!xc->valpos_mem) { xc->vc_emitted = 1; fstWriterCreateMmaps(xc); } handle--; /* move starting at 1 index to starting at 0 */ vm4ip = &(xc->valpos_mem[4*handle]); /* there is no initial time dump for variable length value changes */ if(!vm4ip[1]) /* len of zero = variable length */ { fpos = xc->vchg_siz; if((fpos + len + 10 + 5) > xc->vchg_alloc_siz) { xc->vchg_alloc_siz += (xc->fst_break_add_size + len + 5); /* +len added in the case of extremely long vectors and small break add sizes */ xc->vchg_mem = realloc(xc->vchg_mem, xc->vchg_alloc_siz); if(!xc->vchg_mem) { fprintf(stderr, "FATAL ERROR, could not realloc() in fstWriterEmitVariableLengthValueChange, exiting.\n"); exit(255); } } xc->vchg_siz += fstWriterUint32WithVarint32AndLength(xc, &vm4ip[2], xc->tchn_idx - vm4ip[3], buf, len); /* do one fwrite op only */ vm4ip[3] = xc->tchn_idx; vm4ip[2] = fpos; } } } void fstWriterEmitTimeChange(void *ctx, uint64_t tim) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; unsigned int i; int skip = 0; if(xc) { if(xc->is_initial_time) { if(xc->size_limit_locked) /* this resets xc->is_initial_time to one */ { return; } if(!xc->valpos_mem) { fstWriterCreateMmaps(xc); } skip = 1; xc->firsttime = (xc->vc_emitted) ? 0: tim; xc->curtime = 0; xc->vchg_mem[0] = '!'; xc->vchg_siz = 1; fstWriterEmitSectionHeader(xc); for(i=0;imaxhandle;i++) { xc->valpos_mem[4*i+2] = 0; /* zero out offset val */ xc->valpos_mem[4*i+3] = 0; /* zero out last time change val */ } xc->is_initial_time = 0; } else { if((xc->vchg_siz >= xc->fst_break_size) || (xc->flush_context_pending)) { xc->flush_context_pending = 0; fstWriterFlushContextPrivate(xc); xc->tchn_cnt++; fstWriterVarint(xc->tchn_handle, xc->curtime); } } if(!skip) { xc->tchn_idx++; } fstWriterVarint(xc->tchn_handle, tim - xc->curtime); xc->tchn_cnt++; xc->curtime = tim; } } void fstWriterEmitDumpActive(void *ctx, int enable) { struct fstWriterContext *xc = (struct fstWriterContext *)ctx; if(xc) { struct fstBlackoutChain *b = calloc(1, sizeof(struct fstBlackoutChain)); b->tim = xc->curtime; b->active = (enable != 0); xc->num_blackouts++; if(xc->blackout_curr) { xc->blackout_curr->next = b; xc->blackout_curr = b; } else { xc->blackout_head = b; xc->blackout_curr = b; } } } /***********************/ /*** ***/ /*** reader function ***/ /*** ***/ /***********************/ /* * private structs */ static const char *vartypes[] = { "event", "integer", "parameter", "real", "real_parameter", "reg", "supply0", "supply1", "time", "tri", "triand", "trior", "trireg", "tri0", "tri1", "wand", "wire", "wor", "port", "sparray", "realtime", "string", "bit", "logic", "int", "shortint", "longint", "byte", "enum", "shortreal" }; static const char *modtypes[] = { "module", "task", "function", "begin", "fork", "generate", "struct", "union", "class", "interface", "package", "program", "vhdl_architecture", "vhdl_procedure", "vhdl_function", "vhdl_record", "vhdl_process", "vhdl_block", "vhdl_for_generate", "vhdl_if_generate", "vhdl_generate", "vhdl_package" }; static const char *attrtypes[] = { "misc", "array", "enum", "class" }; static const char *arraytypes[] = { "none", "unpacked", "packed", "sparse" }; static const char *enumvaluetypes[] = { "integer", "bit", "logic", "int", "shortint", "longint", "byte", "unsigned_integer", "unsigned_bit", "unsigned_logic", "unsigned_int", "unsigned_shortint", "unsigned_longint", "unsigned_byte" }; static const char *packtypes[] = { "none", "unpacked", "packed", "tagged_packed" }; struct fstCurrHier { struct fstCurrHier *prev; void *user_info; int len; }; struct fstReaderContext { /* common entries */ FILE *f, *fh; uint64_t start_time, end_time; uint64_t mem_used_by_writer; uint64_t scope_count; uint64_t var_count; fstHandle maxhandle; uint64_t num_alias; uint64_t vc_section_count; uint32_t *signal_lens; /* maxhandle sized */ unsigned char *signal_typs; /* maxhandle sized */ unsigned char *process_mask; /* maxhandle-based, bitwise sized */ uint32_t longest_signal_value_len; /* longest len value encountered */ unsigned char *temp_signal_value_buf; /* malloced for len in longest_signal_value_len */ signed char timescale; unsigned char filetype; unsigned use_vcd_extensions : 1; unsigned double_endian_match : 1; unsigned native_doubles_for_cb : 1; unsigned contains_geom_section : 1; unsigned contains_hier_section : 1; /* valid for hier_pos */ unsigned contains_hier_section_lz4duo : 1; /* valid for hier_pos (contains_hier_section_lz4 always also set) */ unsigned contains_hier_section_lz4 : 1; /* valid for hier_pos */ unsigned limit_range_valid : 1; /* valid for limit_range_start, limit_range_end */ char version[FST_HDR_SIM_VERSION_SIZE + 1]; char date[FST_HDR_DATE_SIZE + 1]; int64_t timezero; char *filename, *filename_unpacked; off_t hier_pos; uint32_t num_blackouts; uint64_t *blackout_times; unsigned char *blackout_activity; uint64_t limit_range_start, limit_range_end; /* entries specific to read value at time functions */ unsigned rvat_data_valid : 1; uint64_t *rvat_time_table; uint64_t rvat_beg_tim, rvat_end_tim; unsigned char *rvat_frame_data; uint64_t rvat_frame_maxhandle; off_t *rvat_chain_table; uint32_t *rvat_chain_table_lengths; uint64_t rvat_vc_maxhandle; off_t rvat_vc_start; uint32_t *rvat_sig_offs; uint32_t rvat_chain_len; unsigned char *rvat_chain_mem; fstHandle rvat_chain_facidx; uint32_t rvat_chain_pos_tidx; uint32_t rvat_chain_pos_idx; uint64_t rvat_chain_pos_time; unsigned rvat_chain_pos_valid : 1; /* entries specific to hierarchy traversal */ struct fstHier hier; struct fstCurrHier *curr_hier; fstHandle current_handle; char *curr_flat_hier_nam; int flat_hier_alloc_len; unsigned do_rewind : 1; char str_scope_nam[FST_ID_NAM_SIZ+1]; char str_scope_comp[FST_ID_NAM_SIZ+1]; unsigned fseek_failed : 1; /* self-buffered I/O for writes */ #ifndef FST_WRITEX_DISABLE int writex_pos; int writex_fd; unsigned char writex_buf[FST_WRITEX_MAX]; #endif char *f_nam; char *fh_nam; }; int fstReaderFseeko(struct fstReaderContext *xc, FILE *stream, off_t offset, int whence) { int rc = fseeko(stream, offset, whence); if(rc<0) { xc->fseek_failed = 1; #ifdef FST_DEBUG fprintf(stderr, "Seek to #%"PRId64" (whence = %d) failed!\n", offset, whence); perror("Why"); #endif } return(rc); } #ifndef FST_WRITEX_DISABLE static void fstWritex(struct fstReaderContext *xc, void *v, int len) { unsigned char *s = (unsigned char *)v; if(len) { if(len < FST_WRITEX_MAX) { if(xc->writex_pos + len >= FST_WRITEX_MAX) { fstWritex(xc, NULL, 0); } memcpy(xc->writex_buf + xc->writex_pos, s, len); xc->writex_pos += len; } else { fstWritex(xc, NULL, 0); if (write(xc->writex_fd, s, len)) { }; } } else { if(xc->writex_pos) { if(write(xc->writex_fd, xc->writex_buf, xc->writex_pos)) { }; xc->writex_pos = 0; } } } #endif /* * scope -> flat name handling */ static void fstReaderDeallocateScopeData(struct fstReaderContext *xc) { struct fstCurrHier *chp; free(xc->curr_flat_hier_nam); xc->curr_flat_hier_nam = NULL; while(xc->curr_hier) { chp = xc->curr_hier->prev; free(xc->curr_hier); xc->curr_hier = chp; } } const char *fstReaderGetCurrentFlatScope(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc) { return(xc->curr_flat_hier_nam ? xc->curr_flat_hier_nam : ""); } else { return(NULL); } } void *fstReaderGetCurrentScopeUserInfo(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc) { return(xc->curr_hier ? xc->curr_hier->user_info : NULL); } else { return(NULL); } } const char *fstReaderPopScope(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc && xc->curr_hier) { struct fstCurrHier *ch = xc->curr_hier; if(xc->curr_hier->prev) { xc->curr_flat_hier_nam[xc->curr_hier->prev->len] = 0; } else { *xc->curr_flat_hier_nam = 0; } xc->curr_hier = xc->curr_hier->prev; free(ch); return(xc->curr_flat_hier_nam ? xc->curr_flat_hier_nam : ""); } return(NULL); } void fstReaderResetScope(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc) { while(fstReaderPopScope(xc)); /* remove any already-built scoping info */ } } const char *fstReaderPushScope(void *ctx, const char *nam, void *user_info) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc) { struct fstCurrHier *ch = malloc(sizeof(struct fstCurrHier)); int chl = xc->curr_hier ? xc->curr_hier->len : 0; int len = chl + 1 + strlen(nam); if(len >= xc->flat_hier_alloc_len) { xc->curr_flat_hier_nam = xc->curr_flat_hier_nam ? realloc(xc->curr_flat_hier_nam, len+1) : malloc(len+1); } if(chl) { xc->curr_flat_hier_nam[chl] = '.'; strcpy(xc->curr_flat_hier_nam + chl + 1, nam); } else { strcpy(xc->curr_flat_hier_nam, nam); len--; } ch->len = len; ch->prev = xc->curr_hier; ch->user_info = user_info; xc->curr_hier = ch; return(xc->curr_flat_hier_nam); } return(NULL); } int fstReaderGetCurrentScopeLen(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc && xc->curr_hier) { return(xc->curr_hier->len); } return(0); } int fstReaderGetFseekFailed(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc) { return(xc->fseek_failed != 0); } return(0); } /* * iter mask manipulation util functions */ int fstReaderGetFacProcessMask(void *ctx, fstHandle facidx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc) { facidx--; if(facidxmaxhandle) { int process_idx = facidx/8; int process_bit = facidx&7; return( (xc->process_mask[process_idx]&(1<maxhandle) { int idx = facidx/8; int bitpos = facidx&7; xc->process_mask[idx] |= (1<maxhandle) { int idx = facidx/8; int bitpos = facidx&7; xc->process_mask[idx] &= (~(1<process_mask, 0xff, (xc->maxhandle+7)/8); } } void fstReaderClrFacProcessMaskAll(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc) { memset(xc->process_mask, 0x00, (xc->maxhandle+7)/8); } } /* * various utility read/write functions */ signed char fstReaderGetTimescale(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; return(xc ? xc->timescale : 0); } uint64_t fstReaderGetStartTime(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; return(xc ? xc->start_time : 0); } uint64_t fstReaderGetEndTime(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; return(xc ? xc->end_time : 0); } uint64_t fstReaderGetMemoryUsedByWriter(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; return(xc ? xc->mem_used_by_writer : 0); } uint64_t fstReaderGetScopeCount(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; return(xc ? xc->scope_count : 0); } uint64_t fstReaderGetVarCount(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; return(xc ? xc->var_count : 0); } fstHandle fstReaderGetMaxHandle(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; return(xc ? xc->maxhandle : 0); } uint64_t fstReaderGetAliasCount(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; return(xc ? xc->num_alias : 0); } uint64_t fstReaderGetValueChangeSectionCount(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; return(xc ? xc->vc_section_count : 0); } int fstReaderGetDoubleEndianMatchState(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; return(xc ? xc->double_endian_match : 0); } const char *fstReaderGetVersionString(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; return(xc ? xc->version : NULL); } const char *fstReaderGetDateString(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; return(xc ? xc->date : NULL); } int fstReaderGetFileType(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; return(xc ? xc->filetype : FST_FT_VERILOG); } int64_t fstReaderGetTimezero(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; return(xc ? xc->timezero : 0); } uint32_t fstReaderGetNumberDumpActivityChanges(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; return(xc ? xc->num_blackouts : 0); } uint64_t fstReaderGetDumpActivityChangeTime(void *ctx, uint32_t idx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc && (idx < xc->num_blackouts) && (xc->blackout_times)) { return(xc->blackout_times[idx]); } else { return(0); } } unsigned char fstReaderGetDumpActivityChangeValue(void *ctx, uint32_t idx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc && (idx < xc->num_blackouts) && (xc->blackout_activity)) { return(xc->blackout_activity[idx]); } else { return(0); } } void fstReaderSetLimitTimeRange(void *ctx, uint64_t start_time, uint64_t end_time) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc) { xc->limit_range_valid = 1; xc->limit_range_start = start_time; xc->limit_range_end = end_time; } } void fstReaderSetUnlimitedTimeRange(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc) { xc->limit_range_valid = 0; } } void fstReaderSetVcdExtensions(void *ctx, int enable) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc) { xc->use_vcd_extensions = (enable != 0); } } void fstReaderIterBlocksSetNativeDoublesOnCallback(void *ctx, int enable) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc) { xc->native_doubles_for_cb = (enable != 0); } } /* * hierarchy processing */ static void fstVcdID(char *buf, unsigned int value) { char *pnt = buf; /* zero is illegal for a value...it is assumed they start at one */ while (value) { value--; *(pnt++) = (char)('!' + value % 94); value = value / 94; } *pnt = 0; } static int fstVcdIDForFwrite(char *buf, unsigned int value) { char *pnt = buf; /* zero is illegal for a value...it is assumed they start at one */ while (value) { value--; *(pnt++) = (char)('!' + value % 94); value = value / 94; } return(pnt - buf); } static int fstReaderRecreateHierFile(struct fstReaderContext *xc) { int pass_status = 1; if(!xc->fh) { off_t offs_cache = ftello(xc->f); char *fnam = malloc(strlen(xc->filename) + 6 + 16 + 32 + 1); unsigned char *mem = malloc(FST_GZIO_LEN); off_t hl, uclen; off_t clen = 0; gzFile zhandle = NULL; int zfd; int htyp = FST_BL_SKIP; /* can't handle both set at once should never happen in a real file */ if(!xc->contains_hier_section_lz4 && xc->contains_hier_section) { htyp = FST_BL_HIER; } else if(xc->contains_hier_section_lz4 && !xc->contains_hier_section) { htyp = xc->contains_hier_section_lz4duo ? FST_BL_HIER_LZ4DUO : FST_BL_HIER_LZ4; } sprintf(fnam, "%s.hier_%d_%p", xc->filename, getpid(), (void *)xc); fstReaderFseeko(xc, xc->f, xc->hier_pos, SEEK_SET); uclen = fstReaderUint64(xc->f); #ifndef __MINGW32__ fflush(xc->f); #endif if(htyp == FST_BL_HIER) { fstReaderFseeko(xc, xc->f, xc->hier_pos, SEEK_SET); uclen = fstReaderUint64(xc->f); #ifndef __MINGW32__ fflush(xc->f); #endif zfd = dup(fileno(xc->f)); zhandle = gzdopen(zfd, "rb"); if(!zhandle) { close(zfd); free(mem); free(fnam); return(0); } } else if((htyp == FST_BL_HIER_LZ4) || (htyp == FST_BL_HIER_LZ4DUO)) { fstReaderFseeko(xc, xc->f, xc->hier_pos - 8, SEEK_SET); /* get section len */ clen = fstReaderUint64(xc->f) - 16; uclen = fstReaderUint64(xc->f); #ifndef __MINGW32__ fflush(xc->f); #endif } #ifndef __MINGW32__ xc->fh = fopen(fnam, "w+b"); if(!xc->fh) #endif { xc->fh = tmpfile_open(&xc->fh_nam); free(fnam); fnam = NULL; if(!xc->fh) { tmpfile_close(&xc->fh, &xc->fh_nam); free(mem); return(0); } } #ifndef __MINGW32__ if(fnam) unlink(fnam); #endif if(htyp == FST_BL_HIER) { for(hl = 0; hl < uclen; hl += FST_GZIO_LEN) { size_t len = ((uclen - hl) > FST_GZIO_LEN) ? FST_GZIO_LEN : (uclen - hl); size_t gzreadlen = gzread(zhandle, mem, len); /* rc should equal len... */ size_t fwlen; if(gzreadlen != len) { pass_status = 0; break; } fwlen = fstFwrite(mem, len, 1, xc->fh); if(fwlen != 1) { pass_status = 0; break; } } gzclose(zhandle); } else if(htyp == FST_BL_HIER_LZ4DUO) { unsigned char *lz4_cmem = malloc(clen); unsigned char *lz4_ucmem = malloc(uclen); unsigned char *lz4_ucmem2; uint64_t uclen2; int skiplen2 = 0; fstFread(lz4_cmem, clen, 1, xc->f); uclen2 = fstGetVarint64(lz4_cmem, &skiplen2); lz4_ucmem2 = malloc(uclen2); pass_status = (uclen2 == (uint64_t)LZ4_decompress_safe_partial ((char *)lz4_cmem + skiplen2, (char *)lz4_ucmem2, clen - skiplen2, uclen2, uclen2)); if(pass_status) { pass_status = (uclen == LZ4_decompress_safe_partial ((char *)lz4_ucmem2, (char *)lz4_ucmem, uclen2, uclen, uclen)); if(fstFwrite(lz4_ucmem, uclen, 1, xc->fh) != 1) { pass_status = 0; } } free(lz4_ucmem2); free(lz4_ucmem); free(lz4_cmem); } else if(htyp == FST_BL_HIER_LZ4) { unsigned char *lz4_cmem = malloc(clen); unsigned char *lz4_ucmem = malloc(uclen); fstFread(lz4_cmem, clen, 1, xc->f); pass_status = (uclen == LZ4_decompress_safe_partial ((char *)lz4_cmem, (char *)lz4_ucmem, clen, uclen, uclen)); if(fstFwrite(lz4_ucmem, uclen, 1, xc->fh) != 1) { pass_status = 0; } free(lz4_ucmem); free(lz4_cmem); } else /* FST_BL_SKIP */ { pass_status = 0; } free(mem); free(fnam); fstReaderFseeko(xc, xc->f, offs_cache, SEEK_SET); } return(pass_status); } int fstReaderIterateHierRewind(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; int pass_status = 0; if(xc) { pass_status = 1; if(!xc->fh) { pass_status = fstReaderRecreateHierFile(xc); } xc->do_rewind = 1; } return(pass_status); } struct fstHier *fstReaderIterateHier(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; int isfeof; fstHandle alias; char *pnt; int ch; if(!xc) return(NULL); if(!xc->fh) { if(!fstReaderRecreateHierFile(xc)) { return(NULL); } } if(xc->do_rewind) { xc->do_rewind = 0; xc->current_handle = 0; fstReaderFseeko(xc, xc->fh, 0, SEEK_SET); clearerr(xc->fh); } if(!(isfeof=feof(xc->fh))) { int tag = fgetc(xc->fh); switch(tag) { case FST_ST_VCD_SCOPE: xc->hier.htyp = FST_HT_SCOPE; xc->hier.u.scope.typ = fgetc(xc->fh); xc->hier.u.scope.name = pnt = xc->str_scope_nam; while((ch = fgetc(xc->fh))) { *(pnt++) = ch; }; /* scopename */ *pnt = 0; xc->hier.u.scope.name_length = pnt - xc->hier.u.scope.name; xc->hier.u.scope.component = pnt = xc->str_scope_comp; while((ch = fgetc(xc->fh))) { *(pnt++) = ch; }; /* scopecomp */ *pnt = 0; xc->hier.u.scope.component_length = pnt - xc->hier.u.scope.component; break; case FST_ST_VCD_UPSCOPE: xc->hier.htyp = FST_HT_UPSCOPE; break; case FST_ST_GEN_ATTRBEGIN: xc->hier.htyp = FST_HT_ATTRBEGIN; xc->hier.u.attr.typ = fgetc(xc->fh); xc->hier.u.attr.subtype = fgetc(xc->fh); xc->hier.u.attr.name = pnt = xc->str_scope_nam; while((ch = fgetc(xc->fh))) { *(pnt++) = ch; }; /* scopename */ *pnt = 0; xc->hier.u.attr.name_length = pnt - xc->hier.u.scope.name; xc->hier.u.attr.arg = fstReaderVarint64(xc->fh); if(xc->hier.u.attr.typ == FST_AT_MISC) { if((xc->hier.u.attr.subtype == FST_MT_SOURCESTEM)||(xc->hier.u.attr.subtype == FST_MT_SOURCEISTEM)) { int sidx_skiplen_dummy = 0; xc->hier.u.attr.arg_from_name = fstGetVarint64((unsigned char *)xc->str_scope_nam, &sidx_skiplen_dummy); } } break; case FST_ST_GEN_ATTREND: xc->hier.htyp = FST_HT_ATTREND; break; case FST_VT_VCD_EVENT: case FST_VT_VCD_INTEGER: case FST_VT_VCD_PARAMETER: case FST_VT_VCD_REAL: case FST_VT_VCD_REAL_PARAMETER: case FST_VT_VCD_REG: case FST_VT_VCD_SUPPLY0: case FST_VT_VCD_SUPPLY1: case FST_VT_VCD_TIME: case FST_VT_VCD_TRI: case FST_VT_VCD_TRIAND: case FST_VT_VCD_TRIOR: case FST_VT_VCD_TRIREG: case FST_VT_VCD_TRI0: case FST_VT_VCD_TRI1: case FST_VT_VCD_WAND: case FST_VT_VCD_WIRE: case FST_VT_VCD_WOR: case FST_VT_VCD_PORT: case FST_VT_VCD_SPARRAY: case FST_VT_VCD_REALTIME: case FST_VT_GEN_STRING: case FST_VT_SV_BIT: case FST_VT_SV_LOGIC: case FST_VT_SV_INT: case FST_VT_SV_SHORTINT: case FST_VT_SV_LONGINT: case FST_VT_SV_BYTE: case FST_VT_SV_ENUM: case FST_VT_SV_SHORTREAL: xc->hier.htyp = FST_HT_VAR; xc->hier.u.var.svt_workspace = FST_SVT_NONE; xc->hier.u.var.sdt_workspace = FST_SDT_NONE; xc->hier.u.var.sxt_workspace = 0; xc->hier.u.var.typ = tag; xc->hier.u.var.direction = fgetc(xc->fh); xc->hier.u.var.name = pnt = xc->str_scope_nam; while((ch = fgetc(xc->fh))) { *(pnt++) = ch; }; /* varname */ *pnt = 0; xc->hier.u.var.name_length = pnt - xc->hier.u.var.name; xc->hier.u.var.length = fstReaderVarint32(xc->fh); if(tag == FST_VT_VCD_PORT) { xc->hier.u.var.length -= 2; /* removal of delimiting spaces */ xc->hier.u.var.length /= 3; /* port -> signal size adjust */ } alias = fstReaderVarint32(xc->fh); if(!alias) { xc->current_handle++; xc->hier.u.var.handle = xc->current_handle; xc->hier.u.var.is_alias = 0; } else { xc->hier.u.var.handle = alias; xc->hier.u.var.is_alias = 1; } break; default: isfeof = 1; break; } } return(!isfeof ? &xc->hier : NULL); } int fstReaderProcessHier(void *ctx, FILE *fv) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; char *str; char *pnt; int ch, scopetype; int vartype; uint32_t len, alias; /* uint32_t maxvalpos=0; */ unsigned int num_signal_dyn = 65536; int attrtype, subtype; uint64_t attrarg; fstHandle maxhandle_scanbuild; if(!xc) return(0); xc->longest_signal_value_len = 32; /* arbitrarily set at 32...this is much longer than an expanded double */ if(!xc->fh) { if(!fstReaderRecreateHierFile(xc)) { return(0); } } str = malloc(FST_ID_NAM_ATTR_SIZ+1); if(fv) { char time_dimension[2] = {0, 0}; int time_scale = 1; fprintf(fv, "$date\n\t%s\n$end\n", xc->date); fprintf(fv, "$version\n\t%s\n$end\n", xc->version); if(xc->timezero) fprintf(fv, "$timezero\n\t%"PRId64"\n$end\n", xc->timezero); switch(xc->timescale) { case 2: time_scale = 100; time_dimension[0] = 0; break; case 1: time_scale = 10; case 0: time_dimension[0] = 0; break; case -1: time_scale = 100; time_dimension[0] = 'm'; break; case -2: time_scale = 10; case -3: time_dimension[0] = 'm'; break; case -4: time_scale = 100; time_dimension[0] = 'u'; break; case -5: time_scale = 10; case -6: time_dimension[0] = 'u'; break; case -10: time_scale = 100; time_dimension[0] = 'p'; break; case -11: time_scale = 10; case -12: time_dimension[0] = 'p'; break; case -13: time_scale = 100; time_dimension[0] = 'f'; break; case -14: time_scale = 10; case -15: time_dimension[0] = 'f'; break; case -16: time_scale = 100; time_dimension[0] = 'a'; break; case -17: time_scale = 10; case -18: time_dimension[0] = 'a'; break; case -19: time_scale = 100; time_dimension[0] = 'z'; break; case -20: time_scale = 10; case -21: time_dimension[0] = 'z'; break; case -7: time_scale = 100; time_dimension[0] = 'n'; break; case -8: time_scale = 10; case -9: default: time_dimension[0] = 'n'; break; } if(fv) fprintf(fv, "$timescale\n\t%d%ss\n$end\n", time_scale, time_dimension); } xc->maxhandle = 0; xc->num_alias = 0; free(xc->signal_lens); xc->signal_lens = malloc(num_signal_dyn*sizeof(uint32_t)); free(xc->signal_typs); xc->signal_typs = malloc(num_signal_dyn*sizeof(unsigned char)); fstReaderFseeko(xc, xc->fh, 0, SEEK_SET); while(!feof(xc->fh)) { int tag = fgetc(xc->fh); switch(tag) { case FST_ST_VCD_SCOPE: scopetype = fgetc(xc->fh); if((scopetype < FST_ST_MIN) || (scopetype > FST_ST_MAX)) scopetype = FST_ST_VCD_MODULE; pnt = str; while((ch = fgetc(xc->fh))) { *(pnt++) = ch; }; /* scopename */ *pnt = 0; while(fgetc(xc->fh)) { }; /* scopecomp */ if(fv) fprintf(fv, "$scope %s %s $end\n", modtypes[scopetype], str); break; case FST_ST_VCD_UPSCOPE: if(fv) fprintf(fv, "$upscope $end\n"); break; case FST_ST_GEN_ATTRBEGIN: attrtype = fgetc(xc->fh); subtype = fgetc(xc->fh); pnt = str; while((ch = fgetc(xc->fh))) { *(pnt++) = ch; }; /* attrname */ *pnt = 0; if(!str[0]) { strcpy(str, "\"\""); } attrarg = fstReaderVarint64(xc->fh); if(fv && xc->use_vcd_extensions) { switch(attrtype) { case FST_AT_ARRAY: if((subtype < FST_AR_NONE) || (subtype > FST_AR_MAX)) subtype = FST_AR_NONE; fprintf(fv, "$attrbegin %s %s %s %"PRId64" $end\n", attrtypes[attrtype], arraytypes[subtype], str, attrarg); break; case FST_AT_ENUM: if((subtype < FST_EV_SV_INTEGER) || (subtype > FST_EV_MAX)) subtype = FST_EV_SV_INTEGER; fprintf(fv, "$attrbegin %s %s %s %"PRId64" $end\n", attrtypes[attrtype], enumvaluetypes[subtype], str, attrarg); break; case FST_AT_PACK: if((subtype < FST_PT_NONE) || (subtype > FST_PT_MAX)) subtype = FST_PT_NONE; fprintf(fv, "$attrbegin %s %s %s %"PRId64" $end\n", attrtypes[attrtype], packtypes[subtype], str, attrarg); break; case FST_AT_MISC: default: attrtype = FST_AT_MISC; if(subtype == FST_MT_COMMENT) { fprintf(fv, "$comment\n\t%s\n$end\n", str); } else { if((subtype == FST_MT_SOURCESTEM)||(subtype == FST_MT_SOURCEISTEM)) { int sidx_skiplen_dummy = 0; uint64_t sidx = fstGetVarint64((unsigned char *)str, &sidx_skiplen_dummy); fprintf(fv, "$attrbegin %s %02x %"PRId64" %"PRId64" $end\n", attrtypes[attrtype], subtype, sidx, attrarg); } else { fprintf(fv, "$attrbegin %s %02x %s %"PRId64" $end\n", attrtypes[attrtype], subtype, str, attrarg); } } break; } } break; case FST_ST_GEN_ATTREND: if(fv && xc->use_vcd_extensions) fprintf(fv, "$attrend $end\n"); break; case FST_VT_VCD_EVENT: case FST_VT_VCD_INTEGER: case FST_VT_VCD_PARAMETER: case FST_VT_VCD_REAL: case FST_VT_VCD_REAL_PARAMETER: case FST_VT_VCD_REG: case FST_VT_VCD_SUPPLY0: case FST_VT_VCD_SUPPLY1: case FST_VT_VCD_TIME: case FST_VT_VCD_TRI: case FST_VT_VCD_TRIAND: case FST_VT_VCD_TRIOR: case FST_VT_VCD_TRIREG: case FST_VT_VCD_TRI0: case FST_VT_VCD_TRI1: case FST_VT_VCD_WAND: case FST_VT_VCD_WIRE: case FST_VT_VCD_WOR: case FST_VT_VCD_PORT: case FST_VT_VCD_SPARRAY: case FST_VT_VCD_REALTIME: case FST_VT_GEN_STRING: case FST_VT_SV_BIT: case FST_VT_SV_LOGIC: case FST_VT_SV_INT: case FST_VT_SV_SHORTINT: case FST_VT_SV_LONGINT: case FST_VT_SV_BYTE: case FST_VT_SV_ENUM: case FST_VT_SV_SHORTREAL: vartype = tag; /* vardir = */ fgetc(xc->fh); /* unused in VCD reader, but need to advance read pointer */ pnt = str; while((ch = fgetc(xc->fh))) { *(pnt++) = ch; }; /* varname */ *pnt = 0; len = fstReaderVarint32(xc->fh); alias = fstReaderVarint32(xc->fh); if(!alias) { if(xc->maxhandle == num_signal_dyn) { num_signal_dyn *= 2; xc->signal_lens = realloc(xc->signal_lens, num_signal_dyn*sizeof(uint32_t)); xc->signal_typs = realloc(xc->signal_typs, num_signal_dyn*sizeof(unsigned char)); } xc->signal_lens[xc->maxhandle] = len; xc->signal_typs[xc->maxhandle] = vartype; /* maxvalpos+=len; */ if(len > xc->longest_signal_value_len) { xc->longest_signal_value_len = len; } if((vartype == FST_VT_VCD_REAL) || (vartype == FST_VT_VCD_REAL_PARAMETER) || (vartype == FST_VT_VCD_REALTIME) || (vartype == FST_VT_SV_SHORTREAL)) { len = (vartype != FST_VT_SV_SHORTREAL) ? 64 : 32; xc->signal_typs[xc->maxhandle] = FST_VT_VCD_REAL; } if(fv) { char vcdid_buf[16]; uint32_t modlen = (vartype != FST_VT_VCD_PORT) ? len : ((len - 2) / 3); fstVcdID(vcdid_buf, xc->maxhandle+1); fprintf(fv, "$var %s %"PRIu32" %s %s $end\n", vartypes[vartype], modlen, vcdid_buf, str); } xc->maxhandle++; } else { if((vartype == FST_VT_VCD_REAL) || (vartype == FST_VT_VCD_REAL_PARAMETER) || (vartype == FST_VT_VCD_REALTIME) || (vartype == FST_VT_SV_SHORTREAL)) { len = (vartype != FST_VT_SV_SHORTREAL) ? 64 : 32; xc->signal_typs[xc->maxhandle] = FST_VT_VCD_REAL; } if(fv) { char vcdid_buf[16]; uint32_t modlen = (vartype != FST_VT_VCD_PORT) ? len : ((len - 2) / 3); fstVcdID(vcdid_buf, alias); fprintf(fv, "$var %s %"PRIu32" %s %s $end\n", vartypes[vartype], modlen, vcdid_buf, str); } xc->num_alias++; } break; default: break; } } if(fv) fprintf(fv, "$enddefinitions $end\n"); maxhandle_scanbuild = xc->maxhandle ? xc->maxhandle : 1; /*scan-build warning suppression, in reality we have at least one signal */ xc->signal_lens = realloc(xc->signal_lens, maxhandle_scanbuild*sizeof(uint32_t)); xc->signal_typs = realloc(xc->signal_typs, maxhandle_scanbuild*sizeof(unsigned char)); free(xc->process_mask); xc->process_mask = calloc(1, (maxhandle_scanbuild+7)/8); free(xc->temp_signal_value_buf); xc->temp_signal_value_buf = malloc(xc->longest_signal_value_len + 1); xc->var_count = xc->maxhandle + xc->num_alias; free(str); return(1); } /* * reader file open/close functions */ int fstReaderInit(struct fstReaderContext *xc) { off_t blkpos = 0; off_t endfile; uint64_t seclen; int sectype; uint64_t vc_section_count_actual = 0; int hdr_incomplete = 0; int hdr_seen = 0; int gzread_pass_status = 1; sectype = fgetc(xc->f); if(sectype == FST_BL_ZWRAPPER) { FILE *fcomp; off_t offpnt, uclen; char gz_membuf[FST_GZIO_LEN]; void *zhandle; int zfd; int flen = strlen(xc->filename); char *hf; seclen = fstReaderUint64(xc->f); uclen = fstReaderUint64(xc->f); if(!seclen) return(0); /* not finished compressing, this is a failed read */ hf = calloc(1, flen + 16 + 32 + 1); sprintf(hf, "%s.upk_%d_%p", xc->filename, getpid(), (void *)xc); fcomp = fopen(hf, "w+b"); if(!fcomp) { fcomp = tmpfile_open(&xc->f_nam); free(hf); hf = NULL; if(!fcomp) { tmpfile_close(&fcomp, &xc->f_nam); return(0); } } #if defined(FST_MACOSX) setvbuf(fcomp, (char *)NULL, _IONBF, 0); /* keeps gzip from acting weird in tandem with fopen */ #endif #ifdef __MINGW32__ setvbuf(fcomp, (char *)NULL, _IONBF, 0); /* keeps gzip from acting weird in tandem with fopen */ xc->filename_unpacked = hf; #else if(hf) { unlink(hf); free(hf); } #endif fstReaderFseeko(xc, xc->f, 1+8+8, SEEK_SET); #ifndef __MINGW32__ fflush(xc->f); #endif zfd = dup(fileno(xc->f)); zhandle = gzdopen(zfd, "rb"); if(zhandle) { for(offpnt = 0; offpnt < uclen; offpnt += FST_GZIO_LEN) { size_t this_len = ((uclen - offpnt) > FST_GZIO_LEN) ? FST_GZIO_LEN : (uclen - offpnt); size_t gzreadlen = gzread(zhandle, gz_membuf, this_len); size_t fwlen; if(gzreadlen != this_len) { gzread_pass_status = 0; break; } fwlen = fstFwrite(gz_membuf, this_len, 1, fcomp); if(fwlen != 1) { gzread_pass_status = 0; break; } } gzclose(zhandle); } else { close(zfd); } fflush(fcomp); fclose(xc->f); xc->f = fcomp; } if(gzread_pass_status) { fstReaderFseeko(xc, xc->f, 0, SEEK_END); endfile = ftello(xc->f); while(blkpos < endfile) { fstReaderFseeko(xc, xc->f, blkpos, SEEK_SET); sectype = fgetc(xc->f); seclen = fstReaderUint64(xc->f); if(sectype == EOF) { break; } if((hdr_incomplete) && (!seclen)) { break; } if(!hdr_seen && (sectype != FST_BL_HDR)) { break; } blkpos++; if(sectype == FST_BL_HDR) { if(!hdr_seen) { int ch; double dcheck; xc->start_time = fstReaderUint64(xc->f); xc->end_time = fstReaderUint64(xc->f); hdr_incomplete = (xc->start_time == 0) && (xc->end_time == 0); fstFread(&dcheck, 8, 1, xc->f); xc->double_endian_match = (dcheck == FST_DOUBLE_ENDTEST); if(!xc->double_endian_match) { union { unsigned char rvs_buf[8]; double d; } vu; unsigned char *dcheck_alias = (unsigned char *)&dcheck; int rvs_idx; for(rvs_idx=0;rvs_idx<8;rvs_idx++) { vu.rvs_buf[rvs_idx] = dcheck_alias[7-rvs_idx]; } if(vu.d != FST_DOUBLE_ENDTEST) { break; /* either corrupt file or wrong architecture (offset +33 also functions as matchword) */ } } hdr_seen = 1; xc->mem_used_by_writer = fstReaderUint64(xc->f); xc->scope_count = fstReaderUint64(xc->f); xc->var_count = fstReaderUint64(xc->f); xc->maxhandle = fstReaderUint64(xc->f); xc->num_alias = xc->var_count - xc->maxhandle; xc->vc_section_count = fstReaderUint64(xc->f); ch = fgetc(xc->f); xc->timescale = (signed char)ch; fstFread(xc->version, FST_HDR_SIM_VERSION_SIZE, 1, xc->f); xc->version[FST_HDR_SIM_VERSION_SIZE] = 0; fstFread(xc->date, FST_HDR_DATE_SIZE, 1, xc->f); xc->date[FST_HDR_DATE_SIZE] = 0; ch = fgetc(xc->f); xc->filetype = (unsigned char)ch; xc->timezero = fstReaderUint64(xc->f); } } else if((sectype == FST_BL_VCDATA) || (sectype == FST_BL_VCDATA_DYN_ALIAS) || (sectype == FST_BL_VCDATA_DYN_ALIAS2)) { if(hdr_incomplete) { uint64_t bt = fstReaderUint64(xc->f); xc->end_time = fstReaderUint64(xc->f); if(!vc_section_count_actual) { xc->start_time = bt; } } vc_section_count_actual++; } else if(sectype == FST_BL_GEOM) { if(!hdr_incomplete) { uint64_t clen = seclen - 24; uint64_t uclen = fstReaderUint64(xc->f); unsigned char *ucdata = malloc(uclen); unsigned char *pnt = ucdata; unsigned int i; xc->contains_geom_section = 1; xc->maxhandle = fstReaderUint64(xc->f); xc->longest_signal_value_len = 32; /* arbitrarily set at 32...this is much longer than an expanded double */ free(xc->process_mask); xc->process_mask = calloc(1, (xc->maxhandle+7)/8); if(clen != uclen) { unsigned char *cdata = malloc(clen); unsigned long destlen = uclen; unsigned long sourcelen = clen; int rc; fstFread(cdata, clen, 1, xc->f); rc = uncompress(ucdata, &destlen, cdata, sourcelen); if(rc != Z_OK) { printf("geom uncompress rc = %d\n", rc); exit(255); } free(cdata); } else { fstFread(ucdata, uclen, 1, xc->f); } free(xc->signal_lens); xc->signal_lens = malloc(sizeof(uint32_t) * xc->maxhandle); free(xc->signal_typs); xc->signal_typs = malloc(sizeof(unsigned char) * xc->maxhandle); for(i=0;imaxhandle;i++) { int skiplen; uint64_t val = fstGetVarint32(pnt, &skiplen); pnt += skiplen; if(val) { xc->signal_lens[i] = (val != 0xFFFFFFFF) ? val : 0; xc->signal_typs[i] = FST_VT_VCD_WIRE; if(xc->signal_lens[i] > xc->longest_signal_value_len) { xc->longest_signal_value_len = xc->signal_lens[i]; } } else { xc->signal_lens[i] = 8; /* backpatch in real */ xc->signal_typs[i] = FST_VT_VCD_REAL; /* xc->longest_signal_value_len handled above by overly large init size */ } } free(xc->temp_signal_value_buf); xc->temp_signal_value_buf = malloc(xc->longest_signal_value_len + 1); free(ucdata); } } else if(sectype == FST_BL_HIER) { xc->contains_hier_section = 1; xc->hier_pos = ftello(xc->f); } else if(sectype == FST_BL_HIER_LZ4DUO) { xc->contains_hier_section_lz4 = 1; xc->contains_hier_section_lz4duo = 1; xc->hier_pos = ftello(xc->f); } else if(sectype == FST_BL_HIER_LZ4) { xc->contains_hier_section_lz4 = 1; xc->hier_pos = ftello(xc->f); } else if(sectype == FST_BL_BLACKOUT) { uint32_t i; uint64_t cur_bl = 0; uint64_t delta; xc->num_blackouts = fstReaderVarint32(xc->f); free(xc->blackout_times); xc->blackout_times = calloc(xc->num_blackouts, sizeof(uint64_t)); free(xc->blackout_activity); xc->blackout_activity = calloc(xc->num_blackouts, sizeof(unsigned char)); for(i=0;inum_blackouts;i++) { xc->blackout_activity[i] = fgetc(xc->f) != 0; delta = fstReaderVarint64(xc->f); cur_bl += delta; xc->blackout_times[i] = cur_bl; } } blkpos += seclen; if(!hdr_seen) break; } if(hdr_seen) { if(xc->vc_section_count != vc_section_count_actual) { xc->vc_section_count = vc_section_count_actual; } if(!xc->contains_geom_section) { fstReaderProcessHier(xc, NULL); /* recreate signal_lens/signal_typs info */ } } } return(hdr_seen); } void *fstReaderOpenForUtilitiesOnly(void) { struct fstReaderContext *xc = calloc(1, sizeof(struct fstReaderContext)); return(xc); } void *fstReaderOpen(const char *nam) { struct fstReaderContext *xc = calloc(1, sizeof(struct fstReaderContext)); if((!nam)||(!(xc->f=fopen(nam, "rb")))) { free(xc); xc=NULL; } else { int flen = strlen(nam); char *hf = calloc(1, flen + 6); int rc; #if defined(__MINGW32__) || defined(FST_MACOSX) setvbuf(xc->f, (char *)NULL, _IONBF, 0); /* keeps gzip from acting weird in tandem with fopen */ #endif memcpy(hf, nam, flen); strcpy(hf + flen, ".hier"); xc->fh = fopen(hf, "rb"); free(hf); xc->filename = strdup(nam); rc = fstReaderInit(xc); if((rc) && (xc->vc_section_count) && (xc->maxhandle) && ((xc->fh)||(xc->contains_hier_section||(xc->contains_hier_section_lz4)))) { /* more init */ xc->do_rewind = 1; } else { fstReaderClose(xc); xc = NULL; } } return(xc); } static void fstReaderDeallocateRvatData(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc) { free(xc->rvat_chain_mem); xc->rvat_chain_mem = NULL; free(xc->rvat_frame_data); xc->rvat_frame_data = NULL; free(xc->rvat_time_table); xc->rvat_time_table = NULL; free(xc->rvat_chain_table); xc->rvat_chain_table = NULL; free(xc->rvat_chain_table_lengths); xc->rvat_chain_table_lengths = NULL; xc->rvat_data_valid = 0; } } void fstReaderClose(void *ctx) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; if(xc) { fstReaderDeallocateScopeData(xc); fstReaderDeallocateRvatData(xc); free(xc->rvat_sig_offs); xc->rvat_sig_offs = NULL; free(xc->process_mask); xc->process_mask = NULL; free(xc->blackout_times); xc->blackout_times = NULL; free(xc->blackout_activity); xc->blackout_activity = NULL; free(xc->temp_signal_value_buf); xc->temp_signal_value_buf = NULL; free(xc->signal_typs); xc->signal_typs = NULL; free(xc->signal_lens); xc->signal_lens = NULL; free(xc->filename); xc->filename = NULL; if(xc->fh) { tmpfile_close(&xc->fh, &xc->fh_nam); } if(xc->f) { tmpfile_close(&xc->f, &xc->f_nam); if(xc->filename_unpacked) { unlink(xc->filename_unpacked); free(xc->filename_unpacked); } } free(xc); } } /* * read processing */ /* normal read which re-interleaves the value change data */ int fstReaderIterBlocks(void *ctx, void (*value_change_callback)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value), void *user_callback_data_pointer, FILE *fv) { return(fstReaderIterBlocks2(ctx, value_change_callback, NULL, user_callback_data_pointer, fv)); } int fstReaderIterBlocks2(void *ctx, void (*value_change_callback)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value), void (*value_change_callback_varlen)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value, uint32_t len), void *user_callback_data_pointer, FILE *fv) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; uint64_t previous_time = UINT64_MAX; uint64_t *time_table = NULL; uint64_t tsec_nitems; unsigned int secnum = 0; int blocks_skipped = 0; off_t blkpos = 0; uint64_t seclen, beg_tim; #ifdef FST_DEBUG uint64_t end_tim; #endif uint64_t frame_uclen, frame_clen, frame_maxhandle, vc_maxhandle; off_t vc_start; off_t indx_pntr, indx_pos; off_t *chain_table = NULL; uint32_t *chain_table_lengths = NULL; unsigned char *chain_cmem; unsigned char *pnt; long chain_clen; fstHandle idx, pidx=0, i; uint64_t pval; uint64_t vc_maxhandle_largest = 0; uint64_t tsec_uclen = 0, tsec_clen = 0; int sectype; uint64_t mem_required_for_traversal; unsigned char *mem_for_traversal = NULL; uint32_t traversal_mem_offs; uint32_t *scatterptr, *headptr, *length_remaining; uint32_t cur_blackout = 0; int packtype; unsigned char *mc_mem = NULL; uint32_t mc_mem_len; /* corresponds to largest value encountered in chain_table_lengths[i] */ if(!xc) return(0); scatterptr = calloc(xc->maxhandle, sizeof(uint32_t)); headptr = calloc(xc->maxhandle, sizeof(uint32_t)); length_remaining = calloc(xc->maxhandle, sizeof(uint32_t)); if(fv) { fprintf(fv, "$dumpvars\n"); #ifndef FST_WRITEX_DISABLE fflush(fv); setvbuf(fv, (char *) NULL, _IONBF, 0); /* even buffered IO is slow so disable it and use our own routines that don't need seeking */ xc->writex_fd = fileno(fv); #endif } for(;;) { uint32_t *tc_head = NULL; traversal_mem_offs = 0; fstReaderFseeko(xc, xc->f, blkpos, SEEK_SET); sectype = fgetc(xc->f); seclen = fstReaderUint64(xc->f); if((sectype == EOF) || (sectype == FST_BL_SKIP)) { #ifdef FST_DEBUG fprintf(stderr, "<< EOF >>\n"); #endif break; } blkpos++; if((sectype != FST_BL_VCDATA) && (sectype != FST_BL_VCDATA_DYN_ALIAS) && (sectype != FST_BL_VCDATA_DYN_ALIAS2)) { blkpos += seclen; continue; } if(!seclen) break; beg_tim = fstReaderUint64(xc->f); #ifdef FST_DEBUG end_tim = #endif fstReaderUint64(xc->f); if(xc->limit_range_valid) { if(beg_tim < xc->limit_range_start) { blocks_skipped++; blkpos += seclen; continue; } if(beg_tim > xc->limit_range_end) /* likely the compare in for(i=0;if); mem_for_traversal = malloc(mem_required_for_traversal + 66); /* add in potential fastlz overhead */ #ifdef FST_DEBUG fprintf(stderr, "sec: %u seclen: %d begtim: %d endtim: %d\n", secnum, (int)seclen, (int)beg_tim, (int)end_tim); fprintf(stderr, "\tmem_required_for_traversal: %d\n", (int)mem_required_for_traversal); #endif /* process time block */ { unsigned char *ucdata; unsigned char *cdata; unsigned long destlen /* = tsec_uclen */; /* scan-build */ unsigned long sourcelen /*= tsec_clen */; /* scan-build */ int rc; unsigned char *tpnt; uint64_t tpval; unsigned int ti; if(fstReaderFseeko(xc, xc->f, blkpos + seclen - 24, SEEK_SET) != 0) break; tsec_uclen = fstReaderUint64(xc->f); tsec_clen = fstReaderUint64(xc->f); tsec_nitems = fstReaderUint64(xc->f); #ifdef FST_DEBUG fprintf(stderr, "\ttime section unc: %d, com: %d (%d items)\n", (int)tsec_uclen, (int)tsec_clen, (int)tsec_nitems); #endif if(tsec_clen > seclen) break; /* corrupted tsec_clen: by definition it can't be larger than size of section */ ucdata = malloc(tsec_uclen); if(!ucdata) break; /* malloc fail as tsec_uclen out of range from corrupted file */ destlen = tsec_uclen; sourcelen = tsec_clen; fstReaderFseeko(xc, xc->f, -24 - ((off_t)tsec_clen), SEEK_CUR); if(tsec_uclen != tsec_clen) { cdata = malloc(tsec_clen); fstFread(cdata, tsec_clen, 1, xc->f); rc = uncompress(ucdata, &destlen, cdata, sourcelen); if(rc != Z_OK) { printf("tsec uncompress rc = %d\n", rc); exit(255); } free(cdata); } else { fstFread(ucdata, tsec_uclen, 1, xc->f); } free(time_table); time_table = calloc(tsec_nitems, sizeof(uint64_t)); tpnt = ucdata; tpval = 0; for(ti=0;tif, blkpos+32, SEEK_SET); frame_uclen = fstReaderVarint64(xc->f); frame_clen = fstReaderVarint64(xc->f); frame_maxhandle = fstReaderVarint64(xc->f); if(secnum == 0) { if((beg_tim != time_table[0]) || (blocks_skipped)) { unsigned char *mu = malloc(frame_uclen); uint32_t sig_offs = 0; if(fv) { char wx_buf[32]; int wx_len; if(beg_tim) { wx_len = sprintf(wx_buf, "#%"PRIu64"\n", beg_tim); fstWritex(xc, wx_buf, wx_len); } if((xc->num_blackouts)&&(cur_blackout != xc->num_blackouts)) { if(beg_tim == xc->blackout_times[cur_blackout]) { wx_len = sprintf(wx_buf, "$dump%s $end\n", (xc->blackout_activity[cur_blackout++]) ? "on" : "off"); fstWritex(xc, wx_buf, wx_len); } } } if(frame_uclen == frame_clen) { fstFread(mu, frame_uclen, 1, xc->f); } else { unsigned char *mc = malloc(frame_clen); int rc; unsigned long destlen = frame_uclen; unsigned long sourcelen = frame_clen; fstFread(mc, sourcelen, 1, xc->f); rc = uncompress(mu, &destlen, mc, sourcelen); if(rc != Z_OK) { printf("rc: %d\n", rc); exit(255); } free(mc); } for(idx=0;idxprocess_mask[process_idx]&(1<signal_lens[idx] <= 1) { if(xc->signal_lens[idx] == 1) { unsigned char val = mu[sig_offs]; if(value_change_callback) { xc->temp_signal_value_buf[0] = val; xc->temp_signal_value_buf[1] = 0; value_change_callback(user_callback_data_pointer, beg_tim, idx+1, xc->temp_signal_value_buf); } else { if(fv) { char vcd_id[16]; int vcdid_len = fstVcdIDForFwrite(vcd_id+1, idx+1); vcd_id[0] = val; /* collapse 3 writes into one I/O call */ vcd_id[vcdid_len + 1] = '\n'; fstWritex(xc, vcd_id, vcdid_len + 2); } } } else { /* variable-length ("0" length) records have no initial state */ } } else { if(xc->signal_typs[idx] != FST_VT_VCD_REAL) { if(value_change_callback) { memcpy(xc->temp_signal_value_buf, mu+sig_offs, xc->signal_lens[idx]); xc->temp_signal_value_buf[xc->signal_lens[idx]] = 0; value_change_callback(user_callback_data_pointer, beg_tim, idx+1, xc->temp_signal_value_buf); } else { if(fv) { char vcd_id[16]; int vcdid_len = fstVcdIDForFwrite(vcd_id+1, idx+1); vcd_id[0] = (xc->signal_typs[idx] != FST_VT_VCD_PORT) ? 'b' : 'p'; fstWritex(xc, vcd_id, 1); fstWritex(xc,mu+sig_offs, xc->signal_lens[idx]); vcd_id[0] = ' '; /* collapse 3 writes into one I/O call */ vcd_id[vcdid_len + 1] = '\n'; fstWritex(xc, vcd_id, vcdid_len + 2); } } } else { double d; unsigned char *clone_d; unsigned char *srcdata = mu+sig_offs; if(value_change_callback) { if(xc->native_doubles_for_cb) { if(xc->double_endian_match) { clone_d = srcdata; } else { int j; clone_d = (unsigned char *)&d; for(j=0;j<8;j++) { clone_d[j] = srcdata[7-j]; } } value_change_callback(user_callback_data_pointer, beg_tim, idx+1, clone_d); } else { clone_d = (unsigned char *)&d; if(xc->double_endian_match) { memcpy(clone_d, srcdata, 8); } else { int j; for(j=0;j<8;j++) { clone_d[j] = srcdata[7-j]; } } sprintf((char *)xc->temp_signal_value_buf, "%.16g", d); value_change_callback(user_callback_data_pointer, beg_tim, idx+1, xc->temp_signal_value_buf); } } else { if(fv) { char vcdid_buf[16]; char wx_buf[64]; int wx_len; clone_d = (unsigned char *)&d; if(xc->double_endian_match) { memcpy(clone_d, srcdata, 8); } else { int j; for(j=0;j<8;j++) { clone_d[j] = srcdata[7-j]; } } fstVcdID(vcdid_buf, idx+1); wx_len = sprintf(wx_buf, "r%.16g %s\n", d, vcdid_buf); fstWritex(xc, wx_buf, wx_len); } } } } } sig_offs += xc->signal_lens[idx]; } free(mu); fstReaderFseeko(xc, xc->f, -((off_t)frame_clen), SEEK_CUR); } } fstReaderFseeko(xc, xc->f, (off_t)frame_clen, SEEK_CUR); /* skip past compressed data */ vc_maxhandle = fstReaderVarint64(xc->f); vc_start = ftello(xc->f); /* points to '!' character */ packtype = fgetc(xc->f); #ifdef FST_DEBUG fprintf(stderr, "\tframe_uclen: %d, frame_clen: %d, frame_maxhandle: %d\n", (int)frame_uclen, (int)frame_clen, (int)frame_maxhandle); fprintf(stderr, "\tvc_maxhandle: %d, packtype: %c\n", (int)vc_maxhandle, packtype); #endif indx_pntr = blkpos + seclen - 24 -tsec_clen -8; fstReaderFseeko(xc, xc->f, indx_pntr, SEEK_SET); chain_clen = fstReaderUint64(xc->f); indx_pos = indx_pntr - chain_clen; #ifdef FST_DEBUG fprintf(stderr, "\tindx_pos: %d (%d bytes)\n", (int)indx_pos, (int)chain_clen); #endif chain_cmem = malloc(chain_clen); if(!chain_cmem) goto block_err; fstReaderFseeko(xc, xc->f, indx_pos, SEEK_SET); fstFread(chain_cmem, chain_clen, 1, xc->f); if(vc_maxhandle > vc_maxhandle_largest) { free(chain_table); free(chain_table_lengths); vc_maxhandle_largest = vc_maxhandle; chain_table = calloc((vc_maxhandle+1), sizeof(off_t)); chain_table_lengths = calloc((vc_maxhandle+1), sizeof(uint32_t)); } if(!chain_table || !chain_table_lengths) goto block_err; pnt = chain_cmem; idx = 0; pval = 0; if(sectype == FST_BL_VCDATA_DYN_ALIAS2) { uint32_t prev_alias = 0; do { int skiplen; if(*pnt & 0x01) { int64_t shval = fstGetSVarint64(pnt, &skiplen) >> 1; if(shval > 0) { pval = chain_table[idx] = pval + shval; if(idx) { chain_table_lengths[pidx] = pval - chain_table[pidx]; } pidx = idx++; } else if(shval < 0) { chain_table[idx] = 0; /* need to explicitly zero as calloc above might not run */ chain_table_lengths[idx] = prev_alias = shval; /* because during this loop iter would give stale data! */ idx++; } else { chain_table[idx] = 0; /* need to explicitly zero as calloc above might not run */ chain_table_lengths[idx] = prev_alias; /* because during this loop iter would give stale data! */ idx++; } } else { uint64_t val = fstGetVarint32(pnt, &skiplen); fstHandle loopcnt = val >> 1; for(i=0;i> 1); if(idx) { chain_table_lengths[pidx] = pval - chain_table[pidx]; } pidx = idx++; } else { fstHandle loopcnt = val >> 1; for(i=0;i xc->maxhandle) idx = xc->maxhandle; for(i=0;iprocess_mask[process_idx]&(1<f, vc_start + chain_table[i], SEEK_SET); val = fstReaderVarint32WithSkip(xc->f, &skiplen); if(val) { unsigned char *mu = mem_for_traversal + traversal_mem_offs; /* uncomp: dst */ unsigned char *mc; /* comp: src */ unsigned long destlen = val; unsigned long sourcelen = chain_table_lengths[i]; if(mc_mem_len < chain_table_lengths[i]) { free(mc_mem); mc_mem = malloc(mc_mem_len = chain_table_lengths[i]); } mc = mc_mem; fstFread(mc, chain_table_lengths[i], 1, xc->f); switch(packtype) { case '4': rc = (destlen == (unsigned long)LZ4_decompress_safe_partial((char *)mc, (char *)mu, sourcelen, destlen, destlen)) ? Z_OK : Z_DATA_ERROR; break; case 'F': fastlz_decompress(mc, sourcelen, mu, destlen); /* rc appears unreliable */ break; default: rc = uncompress(mu, &destlen, mc, sourcelen); break; } /* data to process is for(j=0;jf); /* data to process is for(j=0;jsignal_lens[i] == 1) { uint32_t vli = fstGetVarint32NoSkip(mem_for_traversal + headptr[i]); uint32_t shcnt = 2 << (vli & 1); tdelta = vli >> shcnt; } else { uint32_t vli = fstGetVarint32NoSkip(mem_for_traversal + headptr[i]); tdelta = vli >> 1; } scatterptr[i] = tc_head[tdelta]; tc_head[tdelta] = i+1; } } } free(mc_mem); /* there is no usage below for this, no real need to clear out mc_mem or mc_mem_len */ for(i=0;ilimit_range_valid) { if(time_table[i] > xc->limit_range_end) { break; } } wx_len = sprintf(wx_buf, "#%"PRIu64"\n", time_table[i]); fstWritex(xc, wx_buf, wx_len); if((xc->num_blackouts)&&(cur_blackout != xc->num_blackouts)) { if(time_table[i] == xc->blackout_times[cur_blackout]) { wx_len = sprintf(wx_buf, "$dump%s $end\n", (xc->blackout_activity[cur_blackout++]) ? "on" : "off"); fstWritex(xc, wx_buf, wx_len); } } previous_time = time_table[i]; } } while(tc_head[i]) { idx = tc_head[i] - 1; vli = fstGetVarint32(mem_for_traversal + headptr[idx], &skiplen); if(xc->signal_lens[idx] <= 1) { if(xc->signal_lens[idx] == 1) { unsigned char val; if(!(vli & 1)) { /* tdelta = vli >> 2; */ /* scan-build */ val = ((vli >> 1) & 1) | '0'; } else { /* tdelta = vli >> 4; */ /* scan-build */ val = FST_RCV_STR[((vli >> 1) & 7)]; } if(value_change_callback) { xc->temp_signal_value_buf[0] = val; xc->temp_signal_value_buf[1] = 0; value_change_callback(user_callback_data_pointer, time_table[i], idx+1, xc->temp_signal_value_buf); } else { if(fv) { char vcd_id[16]; int vcdid_len = fstVcdIDForFwrite(vcd_id+1, idx+1); vcd_id[0] = val; vcd_id[vcdid_len+1] = '\n'; fstWritex(xc, vcd_id, vcdid_len+2); } } headptr[idx] += skiplen; length_remaining[idx] -= skiplen; tc_head[i] = scatterptr[idx]; scatterptr[idx] = 0; if(length_remaining[idx]) { int shamt; vli = fstGetVarint32NoSkip(mem_for_traversal + headptr[idx]); shamt = 2 << (vli & 1); tdelta = vli >> shamt; scatterptr[idx] = tc_head[i+tdelta]; tc_head[i+tdelta] = idx+1; } } else { unsigned char *vdata; uint32_t len; vli = fstGetVarint32(mem_for_traversal + headptr[idx], &skiplen); len = fstGetVarint32(mem_for_traversal + headptr[idx] + skiplen, &skiplen2); /* tdelta = vli >> 1; */ /* scan-build */ skiplen += skiplen2; vdata = mem_for_traversal + headptr[idx] + skiplen; if(!(vli & 1)) { if(value_change_callback_varlen) { value_change_callback_varlen(user_callback_data_pointer, time_table[i], idx+1, vdata, len); } else { if(fv) { char vcd_id[16]; int vcdid_len; vcd_id[0] = 's'; fstWritex(xc, vcd_id, 1); vcdid_len = fstVcdIDForFwrite(vcd_id+1, idx+1); { unsigned char *vesc = malloc(len*4 + 1); int vlen = fstUtilityBinToEsc(vesc, vdata, len); fstWritex(xc, vesc, vlen); free(vesc); } vcd_id[0] = ' '; vcd_id[vcdid_len + 1] = '\n'; fstWritex(xc, vcd_id, vcdid_len+2); } } } skiplen += len; headptr[idx] += skiplen; length_remaining[idx] -= skiplen; tc_head[i] = scatterptr[idx]; scatterptr[idx] = 0; if(length_remaining[idx]) { vli = fstGetVarint32NoSkip(mem_for_traversal + headptr[idx]); tdelta = vli >> 1; scatterptr[idx] = tc_head[i+tdelta]; tc_head[i+tdelta] = idx+1; } } } else { uint32_t len = xc->signal_lens[idx]; unsigned char *vdata; vli = fstGetVarint32(mem_for_traversal + headptr[idx], &skiplen); /* tdelta = vli >> 1; */ /* scan-build */ vdata = mem_for_traversal + headptr[idx] + skiplen; if(xc->signal_typs[idx] != FST_VT_VCD_REAL) { if(!(vli & 1)) { int byte = 0; int bit; unsigned int j; for(j=0;j> bit) & 1) | '0'; xc->temp_signal_value_buf[j] = ch; } xc->temp_signal_value_buf[j] = 0; if(value_change_callback) { value_change_callback(user_callback_data_pointer, time_table[i], idx+1, xc->temp_signal_value_buf); } else { if(fv) { unsigned char ch_bp = (xc->signal_typs[idx] != FST_VT_VCD_PORT) ? 'b' : 'p'; fstWritex(xc, &ch_bp, 1); fstWritex(xc, xc->temp_signal_value_buf, len); } } len = byte+1; } else { if(value_change_callback) { memcpy(xc->temp_signal_value_buf, vdata, len); xc->temp_signal_value_buf[len] = 0; value_change_callback(user_callback_data_pointer, time_table[i], idx+1, xc->temp_signal_value_buf); } else { if(fv) { unsigned char ch_bp = (xc->signal_typs[idx] != FST_VT_VCD_PORT) ? 'b' : 'p'; fstWritex(xc, &ch_bp, 1); fstWritex(xc, vdata, len); } } } } else { double d; unsigned char *clone_d /*= (unsigned char *)&d */; /* scan-build */ unsigned char buf[8]; unsigned char *srcdata; if(!(vli & 1)) /* very rare case, but possible */ { int bit; int j; for(j=0;j<8;j++) { unsigned char ch; bit = 7 - (j & 7); ch = ((vdata[0] >> bit) & 1) | '0'; buf[j] = ch; } len = 1; srcdata = buf; } else { srcdata = vdata; } if(value_change_callback) { if(xc->native_doubles_for_cb) { if(xc->double_endian_match) { clone_d = srcdata; } else { int j; clone_d = (unsigned char *)&d; for(j=0;j<8;j++) { clone_d[j] = srcdata[7-j]; } } value_change_callback(user_callback_data_pointer, time_table[i], idx+1, clone_d); } else { clone_d = (unsigned char *)&d; if(xc->double_endian_match) { memcpy(clone_d, srcdata, 8); } else { int j; for(j=0;j<8;j++) { clone_d[j] = srcdata[7-j]; } } sprintf((char *)xc->temp_signal_value_buf, "%.16g", d); value_change_callback(user_callback_data_pointer, time_table[i], idx+1, xc->temp_signal_value_buf); } } else { if(fv) { char wx_buf[32]; int wx_len; clone_d = (unsigned char *)&d; if(xc->double_endian_match) { memcpy(clone_d, srcdata, 8); } else { int j; for(j=0;j<8;j++) { clone_d[j] = srcdata[7-j]; } } wx_len = sprintf(wx_buf, "r%.16g", d); fstWritex(xc, wx_buf, wx_len); } } } if(fv) { char vcd_id[16]; int vcdid_len = fstVcdIDForFwrite(vcd_id+1, idx+1); vcd_id[0] = ' '; vcd_id[vcdid_len+1] = '\n'; fstWritex(xc, vcd_id, vcdid_len+2); } skiplen += len; headptr[idx] += skiplen; length_remaining[idx] -= skiplen; tc_head[i] = scatterptr[idx]; scatterptr[idx] = 0; if(length_remaining[idx]) { vli = fstGetVarint32NoSkip(mem_for_traversal + headptr[idx]); tdelta = vli >> 1; scatterptr[idx] = tc_head[i+tdelta]; tc_head[i+tdelta] = idx+1; } } } } block_err: free(tc_head); free(chain_cmem); free(mem_for_traversal); mem_for_traversal = NULL; secnum++; if(secnum == xc->vc_section_count) break; /* in case file is growing, keep with original block count */ blkpos += seclen; } if(mem_for_traversal) free(mem_for_traversal); /* scan-build */ free(length_remaining); free(headptr); free(scatterptr); if(chain_table) free(chain_table); if(chain_table_lengths) free(chain_table_lengths); free(time_table); #ifndef FST_WRITEX_DISABLE if(fv) { fstWritex(xc, NULL, 0); } #endif return(1); } /* rvat functions */ static char *fstExtractRvatDataFromFrame(struct fstReaderContext *xc, fstHandle facidx, char *buf) { if(facidx >= xc->rvat_frame_maxhandle) { return(NULL); } if(xc->signal_lens[facidx] == 1) { buf[0] = (char)xc->rvat_frame_data[xc->rvat_sig_offs[facidx]]; buf[1] = 0; } else { if(xc->signal_typs[facidx] != FST_VT_VCD_REAL) { memcpy(buf, xc->rvat_frame_data + xc->rvat_sig_offs[facidx], xc->signal_lens[facidx]); buf[xc->signal_lens[facidx]] = 0; } else { double d; unsigned char *clone_d = (unsigned char *)&d; unsigned char *srcdata = xc->rvat_frame_data + xc->rvat_sig_offs[facidx]; if(xc->double_endian_match) { memcpy(clone_d, srcdata, 8); } else { int j; for(j=0;j<8;j++) { clone_d[j] = srcdata[7-j]; } } sprintf((char *)buf, "%.16g", d); } } return(buf); } char *fstReaderGetValueFromHandleAtTime(void *ctx, uint64_t tim, fstHandle facidx, char *buf) { struct fstReaderContext *xc = (struct fstReaderContext *)ctx; off_t blkpos = 0, prev_blkpos; uint64_t beg_tim, end_tim, beg_tim2, end_tim2; int sectype; unsigned int secnum = 0; uint64_t seclen; uint64_t tsec_uclen = 0, tsec_clen = 0; uint64_t tsec_nitems; uint64_t frame_uclen, frame_clen; #ifdef FST_DEBUG uint64_t mem_required_for_traversal; #endif off_t indx_pntr, indx_pos; long chain_clen; unsigned char *chain_cmem; unsigned char *pnt; fstHandle idx, pidx=0, i; uint64_t pval; if((!xc) || (!facidx) || (facidx > xc->maxhandle) || (!buf) || (!xc->signal_lens[facidx-1])) { return(NULL); } if(!xc->rvat_sig_offs) { uint32_t cur_offs = 0; xc->rvat_sig_offs = calloc(xc->maxhandle, sizeof(uint32_t)); for(i=0;imaxhandle;i++) { xc->rvat_sig_offs[i] = cur_offs; cur_offs += xc->signal_lens[i]; } } if(xc->rvat_data_valid) { if((xc->rvat_beg_tim <= tim) && (tim <= xc->rvat_end_tim)) { goto process_value; } fstReaderDeallocateRvatData(xc); } xc->rvat_chain_pos_valid = 0; for(;;) { fstReaderFseeko(xc, xc->f, (prev_blkpos = blkpos), SEEK_SET); sectype = fgetc(xc->f); seclen = fstReaderUint64(xc->f); if((sectype == EOF) || (sectype == FST_BL_SKIP) || (!seclen)) { return(NULL); /* if this loop exits on break, it's successful */ } blkpos++; if((sectype != FST_BL_VCDATA) && (sectype != FST_BL_VCDATA_DYN_ALIAS) && (sectype != FST_BL_VCDATA_DYN_ALIAS2)) { blkpos += seclen; continue; } beg_tim = fstReaderUint64(xc->f); end_tim = fstReaderUint64(xc->f); if((beg_tim <= tim) && (tim <= end_tim)) { if((tim == end_tim) && (tim != xc->end_time)) { off_t cached_pos = ftello(xc->f); fstReaderFseeko(xc, xc->f, blkpos, SEEK_SET); sectype = fgetc(xc->f); seclen = fstReaderUint64(xc->f); beg_tim2 = fstReaderUint64(xc->f); end_tim2 = fstReaderUint64(xc->f); if(((sectype != FST_BL_VCDATA)&&(sectype != FST_BL_VCDATA_DYN_ALIAS)&&(sectype != FST_BL_VCDATA_DYN_ALIAS2)) || (!seclen) || (beg_tim2 != tim)) { blkpos = prev_blkpos; break; } beg_tim = beg_tim2; end_tim = end_tim2; fstReaderFseeko(xc, xc->f, cached_pos, SEEK_SET); } break; } blkpos += seclen; secnum++; } xc->rvat_beg_tim = beg_tim; xc->rvat_end_tim = end_tim; #ifdef FST_DEBUG mem_required_for_traversal = #endif fstReaderUint64(xc->f); #ifdef FST_DEBUG fprintf(stderr, "rvat sec: %u seclen: %d begtim: %d endtim: %d\n", secnum, (int)seclen, (int)beg_tim, (int)end_tim); fprintf(stderr, "\tmem_required_for_traversal: %d\n", (int)mem_required_for_traversal); #endif /* process time block */ { unsigned char *ucdata; unsigned char *cdata; unsigned long destlen /* = tsec_uclen */; /* scan-build */ unsigned long sourcelen /* = tsec_clen */; /* scan-build */ int rc; unsigned char *tpnt; uint64_t tpval; unsigned int ti; fstReaderFseeko(xc, xc->f, blkpos + seclen - 24, SEEK_SET); tsec_uclen = fstReaderUint64(xc->f); tsec_clen = fstReaderUint64(xc->f); tsec_nitems = fstReaderUint64(xc->f); #ifdef FST_DEBUG fprintf(stderr, "\ttime section unc: %d, com: %d (%d items)\n", (int)tsec_uclen, (int)tsec_clen, (int)tsec_nitems); #endif ucdata = malloc(tsec_uclen); destlen = tsec_uclen; sourcelen = tsec_clen; fstReaderFseeko(xc, xc->f, -24 - ((off_t)tsec_clen), SEEK_CUR); if(tsec_uclen != tsec_clen) { cdata = malloc(tsec_clen); fstFread(cdata, tsec_clen, 1, xc->f); rc = uncompress(ucdata, &destlen, cdata, sourcelen); if(rc != Z_OK) { printf("tsec uncompress rc = %d\n", rc); exit(255); } free(cdata); } else { fstFread(ucdata, tsec_uclen, 1, xc->f); } xc->rvat_time_table = calloc(tsec_nitems, sizeof(uint64_t)); tpnt = ucdata; tpval = 0; for(ti=0;tirvat_time_table[ti] = tpval + val; tpnt += skiplen; } free(ucdata); } fstReaderFseeko(xc, xc->f, blkpos+32, SEEK_SET); frame_uclen = fstReaderVarint64(xc->f); frame_clen = fstReaderVarint64(xc->f); xc->rvat_frame_maxhandle = fstReaderVarint64(xc->f); xc->rvat_frame_data = malloc(frame_uclen); if(frame_uclen == frame_clen) { fstFread(xc->rvat_frame_data, frame_uclen, 1, xc->f); } else { unsigned char *mc = malloc(frame_clen); int rc; unsigned long destlen = frame_uclen; unsigned long sourcelen = frame_clen; fstFread(mc, sourcelen, 1, xc->f); rc = uncompress(xc->rvat_frame_data, &destlen, mc, sourcelen); if(rc != Z_OK) { printf("decompress rc: %d\n", rc); exit(255); } free(mc); } xc->rvat_vc_maxhandle = fstReaderVarint64(xc->f); xc->rvat_vc_start = ftello(xc->f); /* points to '!' character */ #ifdef FST_DEBUG fprintf(stderr, "\tframe_uclen: %d, frame_clen: %d, frame_maxhandle: %d\n", (int)frame_uclen, (int)frame_clen, (int)xc->rvat_frame_maxhandle); fprintf(stderr, "\tvc_maxhandle: %d\n", (int)xc->rvat_vc_maxhandle); #endif indx_pntr = blkpos + seclen - 24 -tsec_clen -8; fstReaderFseeko(xc, xc->f, indx_pntr, SEEK_SET); chain_clen = fstReaderUint64(xc->f); indx_pos = indx_pntr - chain_clen; #ifdef FST_DEBUG fprintf(stderr, "\tindx_pos: %d (%d bytes)\n", (int)indx_pos, (int)chain_clen); #endif chain_cmem = malloc(chain_clen); fstReaderFseeko(xc, xc->f, indx_pos, SEEK_SET); fstFread(chain_cmem, chain_clen, 1, xc->f); xc->rvat_chain_table = calloc((xc->rvat_vc_maxhandle+1), sizeof(off_t)); xc->rvat_chain_table_lengths = calloc((xc->rvat_vc_maxhandle+1), sizeof(uint32_t)); pnt = chain_cmem; idx = 0; pval = 0; do { int skiplen; uint64_t val = fstGetVarint32(pnt, &skiplen); if(!val) { pnt += skiplen; val = fstGetVarint32(pnt, &skiplen); xc->rvat_chain_table[idx] = 0; xc->rvat_chain_table_lengths[idx] = -val; idx++; } else if(val&1) { pval = xc->rvat_chain_table[idx] = pval + (val >> 1); if(idx) { xc->rvat_chain_table_lengths[pidx] = pval - xc->rvat_chain_table[pidx]; } pidx = idx++; } else { fstHandle loopcnt = val >> 1; for(i=0;irvat_chain_table[idx++] = 0; } } pnt += skiplen; } while (pnt != (chain_cmem + chain_clen)); free(chain_cmem); xc->rvat_chain_table[idx] = indx_pos - xc->rvat_vc_start; xc->rvat_chain_table_lengths[pidx] = xc->rvat_chain_table[idx] - xc->rvat_chain_table[pidx]; for(i=0;irvat_chain_table_lengths[i]; if((v32 < 0) && (!xc->rvat_chain_table[i])) { v32 = -v32; v32--; if(((uint32_t)v32) < i) /* sanity check */ { xc->rvat_chain_table[i] = xc->rvat_chain_table[v32]; xc->rvat_chain_table_lengths[i] = xc->rvat_chain_table_lengths[v32]; } } } #ifdef FST_DEBUG fprintf(stderr, "\tdecompressed chain idx len: %"PRIu32"\n", idx); #endif xc->rvat_data_valid = 1; /* all data at this point is loaded or resident in fst cache, process and return appropriate value */ process_value: if(facidx > xc->rvat_vc_maxhandle) { return(NULL); } facidx--; /* scale down for array which starts at zero */ if(((tim == xc->rvat_beg_tim)&&(!xc->rvat_chain_table[facidx])) || (!xc->rvat_chain_table[facidx])) { return(fstExtractRvatDataFromFrame(xc, facidx, buf)); } if(facidx != xc->rvat_chain_facidx) { if(xc->rvat_chain_mem) { free(xc->rvat_chain_mem); xc->rvat_chain_mem = NULL; xc->rvat_chain_pos_valid = 0; } } if(!xc->rvat_chain_mem) { uint32_t skiplen; fstReaderFseeko(xc, xc->f, xc->rvat_vc_start + xc->rvat_chain_table[facidx], SEEK_SET); xc->rvat_chain_len = fstReaderVarint32WithSkip(xc->f, &skiplen); if(xc->rvat_chain_len) { unsigned char *mu = malloc(xc->rvat_chain_len); unsigned char *mc = malloc(xc->rvat_chain_table_lengths[facidx]); unsigned long destlen = xc->rvat_chain_len; unsigned long sourcelen = xc->rvat_chain_table_lengths[facidx]; int rc; fstFread(mc, xc->rvat_chain_table_lengths[facidx], 1, xc->f); rc = uncompress(mu, &destlen, mc, sourcelen); free(mc); if(rc != Z_OK) { printf("\tclen: %d (rc=%d)\n", (int)xc->rvat_chain_len, rc); exit(255); } /* data to process is for(j=0;jrvat_chain_mem = mu; } else { int destlen = xc->rvat_chain_table_lengths[facidx] - skiplen; unsigned char *mu = malloc(xc->rvat_chain_len = destlen); fstFread(mu, destlen, 1, xc->f); /* data to process is for(j=0;jrvat_chain_mem = mu; } xc->rvat_chain_facidx = facidx; } /* process value chain here */ { uint32_t tidx = 0, ptidx = 0; uint32_t tdelta; int skiplen; unsigned int iprev = xc->rvat_chain_len; uint32_t pvli = 0; int pskip = 0; if((xc->rvat_chain_pos_valid)&&(tim >= xc->rvat_chain_pos_time)) { i = xc->rvat_chain_pos_idx; tidx = xc->rvat_chain_pos_tidx; } else { i = 0; tidx = 0; xc->rvat_chain_pos_time = xc->rvat_beg_tim; } if(xc->signal_lens[facidx] == 1) { while(irvat_chain_len) { uint32_t vli = fstGetVarint32(xc->rvat_chain_mem + i, &skiplen); uint32_t shcnt = 2 << (vli & 1); tdelta = vli >> shcnt; if(xc->rvat_time_table[tidx + tdelta] <= tim) { iprev = i; pvli = vli; ptidx = tidx; /* pskip = skiplen; */ /* scan-build */ tidx += tdelta; i+=skiplen; } else { break; } } if(iprev != xc->rvat_chain_len) { xc->rvat_chain_pos_tidx = ptidx; xc->rvat_chain_pos_idx = iprev; xc->rvat_chain_pos_time = tim; xc->rvat_chain_pos_valid = 1; if(!(pvli & 1)) { buf[0] = ((pvli >> 1) & 1) | '0'; } else { buf[0] = FST_RCV_STR[((pvli >> 1) & 7)]; } buf[1] = 0; return(buf); } else { return(fstExtractRvatDataFromFrame(xc, facidx, buf)); } } else { while(irvat_chain_len) { uint32_t vli = fstGetVarint32(xc->rvat_chain_mem + i, &skiplen); tdelta = vli >> 1; if(xc->rvat_time_table[tidx + tdelta] <= tim) { iprev = i; pvli = vli; ptidx = tidx; pskip = skiplen; tidx += tdelta; i+=skiplen; if(!(pvli & 1)) { i+=((xc->signal_lens[facidx]+7)/8); } else { i+=xc->signal_lens[facidx]; } } else { break; } } if(iprev != xc->rvat_chain_len) { unsigned char *vdata = xc->rvat_chain_mem + iprev + pskip; xc->rvat_chain_pos_tidx = ptidx; xc->rvat_chain_pos_idx = iprev; xc->rvat_chain_pos_time = tim; xc->rvat_chain_pos_valid = 1; if(xc->signal_typs[facidx] != FST_VT_VCD_REAL) { if(!(pvli & 1)) { int byte = 0; int bit; unsigned int j; for(j=0;jsignal_lens[facidx];j++) { unsigned char ch; byte = j/8; bit = 7 - (j & 7); ch = ((vdata[byte] >> bit) & 1) | '0'; buf[j] = ch; } buf[j] = 0; return(buf); } else { memcpy(buf, vdata, xc->signal_lens[facidx]); buf[xc->signal_lens[facidx]] = 0; return(buf); } } else { double d; unsigned char *clone_d = (unsigned char *)&d; unsigned char bufd[8]; unsigned char *srcdata; if(!(pvli & 1)) /* very rare case, but possible */ { int bit; int j; for(j=0;j<8;j++) { unsigned char ch; bit = 7 - (j & 7); ch = ((vdata[0] >> bit) & 1) | '0'; bufd[j] = ch; } srcdata = bufd; } else { srcdata = vdata; } if(xc->double_endian_match) { memcpy(clone_d, srcdata, 8); } else { int j; for(j=0;j<8;j++) { clone_d[j] = srcdata[7-j]; } } sprintf(buf, "r%.16g", d); return(buf); } } else { return(fstExtractRvatDataFromFrame(xc, facidx, buf)); } } } /* return(NULL); */ } /**********************************************************************/ #ifndef _WAVE_HAVE_JUDY /***********************/ /*** ***/ /*** jenkins hash ***/ /*** ***/ /***********************/ /* -------------------------------------------------------------------- mix -- mix 3 32-bit values reversibly. For every delta with one or two bits set, and the deltas of all three high bits or all three low bits, whether the original value of a,b,c is almost all zero or is uniformly distributed, * If mix() is run forward or backward, at least 32 bits in a,b,c have at least 1/4 probability of changing. * If mix() is run forward, every bit of c will change between 1/3 and 2/3 of the time. (Well, 22/100 and 78/100 for some 2-bit deltas.) mix() was built out of 36 single-cycle latency instructions in a structure that could supported 2x parallelism, like so: a -= b; a -= c; x = (c>>13); b -= c; a ^= x; b -= a; x = (a<<8); c -= a; b ^= x; c -= b; x = (b>>13); ... Unfortunately, superscalar Pentiums and Sparcs can't take advantage of that parallelism. They've also turned some of those single-cycle latency instructions into multi-cycle latency instructions. Still, this is the fastest good hash I could find. There were about 2^^68 to choose from. I only looked at a billion or so. -------------------------------------------------------------------- */ #define mix(a,b,c) \ { \ a -= b; a -= c; a ^= (c>>13); \ b -= c; b -= a; b ^= (a<<8); \ c -= a; c -= b; c ^= (b>>13); \ a -= b; a -= c; a ^= (c>>12); \ b -= c; b -= a; b ^= (a<<16); \ c -= a; c -= b; c ^= (b>>5); \ a -= b; a -= c; a ^= (c>>3); \ b -= c; b -= a; b ^= (a<<10); \ c -= a; c -= b; c ^= (b>>15); \ } /* -------------------------------------------------------------------- j_hash() -- hash a variable-length key into a 32-bit value k : the key (the unaligned variable-length array of bytes) len : the length of the key, counting by bytes initval : can be any 4-byte value Returns a 32-bit value. Every bit of the key affects every bit of the return value. Every 1-bit and 2-bit delta achieves avalanche. About 6*len+35 instructions. The best hash table sizes are powers of 2. There is no need to do mod a prime (mod is sooo slow!). If you need less than 32 bits, use a bitmask. For example, if you need only 10 bits, do h = (h & hashmask(10)); In which case, the hash table should have hashsize(10) elements. If you are hashing n strings (uint8_t **)k, do it like this: for (i=0, h=0; i= 12) { a += (k[0] +((uint32_t)k[1]<<8) +((uint32_t)k[2]<<16) +((uint32_t)k[3]<<24)); b += (k[4] +((uint32_t)k[5]<<8) +((uint32_t)k[6]<<16) +((uint32_t)k[7]<<24)); c += (k[8] +((uint32_t)k[9]<<8) +((uint32_t)k[10]<<16)+((uint32_t)k[11]<<24)); mix(a,b,c); k += 12; len -= 12; } /*------------------------------------- handle the last 11 bytes */ c += length; switch(len) /* all the case statements fall through */ { case 11: c+=((uint32_t)k[10]<<24); case 10: c+=((uint32_t)k[9]<<16); case 9 : c+=((uint32_t)k[8]<<8); /* the first byte of c is reserved for the length */ case 8 : b+=((uint32_t)k[7]<<24); case 7 : b+=((uint32_t)k[6]<<16); case 6 : b+=((uint32_t)k[5]<<8); case 5 : b+=k[4]; case 4 : a+=((uint32_t)k[3]<<24); case 3 : a+=((uint32_t)k[2]<<16); case 2 : a+=((uint32_t)k[1]<<8); case 1 : a+=k[0]; /* case 0: nothing left to add */ } mix(a,b,c); /*-------------------------------------------- report the result */ return(c); } /********************************************************************/ /***************************/ /*** ***/ /*** judy HS emulation ***/ /*** ***/ /***************************/ struct collchain_t { struct collchain_t *next; void *payload; uint32_t fullhash, length; unsigned char mem[1]; }; void **JenkinsIns(void *base_i, const unsigned char *mem, uint32_t length, uint32_t hashmask) { struct collchain_t ***base = (struct collchain_t ***)base_i; uint32_t hf, h; struct collchain_t **ar; struct collchain_t *chain, *pchain; if(!*base) { *base = calloc(1, (hashmask + 1) * sizeof(void *)); } ar = *base; h = (hf = j_hash(mem, length, length)) & hashmask; pchain = chain = ar[h]; while(chain) { if((chain->fullhash == hf) && (chain->length == length) && !memcmp(chain->mem, mem, length)) { if(pchain != chain) /* move hit to front */ { pchain->next = chain->next; chain->next = ar[h]; ar[h] = chain; } return(&(chain->payload)); } pchain = chain; chain = chain->next; } chain = calloc(1, sizeof(struct collchain_t) + length - 1); memcpy(chain->mem, mem, length); chain->fullhash = hf; chain->length = length; chain->next = ar[h]; ar[h] = chain; return(&(chain->payload)); } void JenkinsFree(void *base_i, uint32_t hashmask) { struct collchain_t ***base = (struct collchain_t ***)base_i; uint32_t h; struct collchain_t **ar; struct collchain_t *chain, *chain_next; if(base && *base) { ar = *base; for(h=0;h<=hashmask;h++) { chain = ar[h]; while(chain) { chain_next = chain->next; free(chain); chain = chain_next; } } free(*base); *base = NULL; } } #endif /**********************************************************************/ /************************/ /*** ***/ /*** utility function ***/ /*** ***/ /************************/ int fstUtilityBinToEsc(unsigned char *d, unsigned char *s, int len) { unsigned char *src = s; unsigned char *dst = d; unsigned char val; int i; for(i=0;i ' ') && (src[i] <= '~')) /* no white spaces in output */ { *(dst++) = src[i]; } else { val = src[i]; *(dst++) = '\\'; *(dst++) = (val/64) + '0'; val = val & 63; *(dst++) = (val/8) + '0'; val = val & 7; *(dst++) = (val) + '0'; } break; } } return(dst - d); } /* * this overwrites the original string if the destination pointer is NULL */ int fstUtilityEscToBin(unsigned char *d, unsigned char *s, int len) { unsigned char *src = s; unsigned char *dst = (!d) ? s : (s = d); unsigned char val[3]; int i; for(i=0;i='A')&&(val[0]<='F')) ? (val[0] - 'A' + 10) : (val[0] - '0'); val[1] = ((val[1]>='A')&&(val[1]<='F')) ? (val[1] - 'A' + 10) : (val[1] - '0'); *(dst++) = val[0] * 16 + val[1]; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': val[0] = src[ i] - '0'; val[1] = src[++i] - '0'; val[2] = src[++i] - '0'; *(dst++) = val[0] * 64 + val[1] * 8 + val[2]; break; default: *(dst++) = src[i]; break; } } } return(dst - s); } gtkwave-3.3.66/src/helpers/fst/Makefile.am0000664000076400007640000000032012237305031017647 0ustar bybellbybell## -*- makefile -*- ## AM_CFLAGS= $(LIBZ_CFLAGS) $(LIBJUDY_CFLAGS) noinst_LIBRARIES= libfst.a libfst_a_SOURCES= fastlz.c fastlz.h lz4.c lz4.h fstapi.c fstapi.h EXTRA_DIST= block_format.txt gtkwave-3.3.66/src/helpers/fst/block_format.txt0000664000076400007640000000625012254655057021045 0ustar bybellbybellSee fstapi.h for the values for the FST_BL_XXX enums. =========================================================================== compressed wrapper (typically over whole file) uint8_t FST_BL_ZWRAPPER uint64_t section length uint64_t length of uncompressed data [zlib compressed data] =========================================================================== header block uint8_t FST_BL_HDR uint64_t section length uint64_t start time uint64_t end time double endian test for "e" uint64_t memory used by writer uint64_t scope creation count uint64_t var creation count uint64_t max var idcode uint64_t vc section count int8_t timescale exponent [128 bytes] version [128 bytes] date =========================================================================== geometry block uint8_t FST_BL_GEOM uint64_t section length uint64_t length of uncompressed geometry data uint64_t maxhandle [compressed data] (length of compressed data is section length - 24) =========================================================================== hierarchy block uint8_t FST_BL_HIER uint64_t section length uint64_t length of uncompressed hier data [zlib compressed data] or uint8_t FST_BL_HIER_LZ4 uint64_t section length uint64_t length of uncompressed hier data [lz4 compressed data] uint8_t FST_BL_HIER_LZ4DUO uint64_t section length uint64_t length of uncompressed hier data varint length of hier data compressed once with lz4 [lz4 double compressed data] =========================================================================== dumpon/off block uint8_t FST_BL_BLACKOUT uint64_t section length varint num blackouts (section below is repeated this # times) [ uint8_t on/off (nonzero = on) varint delta time ] =========================================================================== 1..n value change blocks: // header uint8_t FST_BL_VCDATA (or FST_BL_VCDATA_DYN_ALIAS) uint64_t section length uint64_t begin time of section uint64_t end time of section uint64_t amount of buffer memory required in reader for full vc traversal varint maxvalpos (length of uncompressed data) varint length of compressed data varint maxhandle associated with this checkpoint data [compressed data] --- // value changes varint maxhandle associated with the value change data uint8_t pack type ('F' is fastlz, '4' is lz4, others ['Z'/'!'] are zlib) varint chain 0 compressed data length (0 = uncompressed) [compressed data] ... varint chain n compressed data length (0 = uncompressed) [compressed data] --- // index: chain pointer table (from 0..maxhandle-1) varint if &1 == 1, this is <<1 literal delta if &1 == 0, this is <<1 RLE count of zeros if == 0, next varint is handle of prev chain to use, bit only if FST_BL_VCDATA_DYN_ALIAS or later VCDATA format --- uint64_t index length (subtract from here to get index position) --- [compressed data for time section] uint64_t uncompressed data length in bytes uint64_t compressed data length in bytes uint64_t number of time items // end of section =========================================================================== gtkwave-3.3.66/src/helpers/fst/lz4.h0000664000076400007640000003505212447360476016530 0ustar bybellbybell/* LZ4 - Fast LZ compression algorithm Header File Copyright (C) 2011-2014, Yann Collet. BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 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. 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. You can contact the author at : - LZ4 source repository : http://code.google.com/p/lz4/ - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c */ #pragma once #if defined (__cplusplus) extern "C" { #endif /* * lz4.h provides raw compression format functions, for optimal performance and integration into programs. * If you need to generate data using an inter-operable format (respecting the framing specification), * please use lz4frame.h instead. */ /************************************** Version **************************************/ #define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */ #define LZ4_VERSION_MINOR 5 /* for new (non-breaking) interface capabilities */ #define LZ4_VERSION_RELEASE 0 /* for tweaks, bug-fixes, or development */ #define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE) int LZ4_versionNumber (void); /************************************** Tuning parameter **************************************/ /* * LZ4_MEMORY_USAGE : * Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.) * Increasing memory usage improves compression ratio * Reduced memory usage can improve speed, due to cache effect * Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache */ #define LZ4_MEMORY_USAGE 14 /************************************** Simple Functions **************************************/ int LZ4_compress (const char* source, char* dest, int sourceSize); int LZ4_decompress_safe (const char* source, char* dest, int compressedSize, int maxDecompressedSize); /* LZ4_compress() : Compresses 'sourceSize' bytes from 'source' into 'dest'. Destination buffer must be already allocated, and must be sized to handle worst cases situations (input data not compressible) Worst case size evaluation is provided by function LZ4_compressBound() inputSize : Max supported value is LZ4_MAX_INPUT_SIZE return : the number of bytes written in buffer dest or 0 if the compression fails LZ4_decompress_safe() : compressedSize : is obviously the source size maxDecompressedSize : is the size of the destination buffer, which must be already allocated. return : the number of bytes decompressed into the destination buffer (necessarily <= maxDecompressedSize) If the destination buffer is not large enough, decoding will stop and output an error code (<0). If the source stream is detected malformed, the function will stop decoding and return a negative result. This function is protected against buffer overflow exploits, and never writes outside of output buffer, nor reads outside of input buffer. It is also protected against malicious data packets. */ /************************************** Advanced Functions **************************************/ #define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */ #define LZ4_COMPRESSBOUND(isize) ((unsigned int)(isize) > (unsigned int)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16) /* LZ4_compressBound() : Provides the maximum size that LZ4 compression may output in a "worst case" scenario (input data not compressible) This function is primarily useful for memory allocation purposes (output buffer size). Macro LZ4_COMPRESSBOUND() is also provided for compilation-time evaluation (stack memory allocation for example). isize : is the input size. Max supported value is LZ4_MAX_INPUT_SIZE return : maximum output size in a "worst case" scenario or 0, if input size is too large ( > LZ4_MAX_INPUT_SIZE) */ int LZ4_compressBound(int isize); /* LZ4_compress_limitedOutput() : Compress 'sourceSize' bytes from 'source' into an output buffer 'dest' of maximum size 'maxOutputSize'. If it cannot achieve it, compression will stop, and result of the function will be zero. This saves time and memory on detecting non-compressible (or barely compressible) data. This function never writes outside of provided output buffer. sourceSize : Max supported value is LZ4_MAX_INPUT_VALUE maxOutputSize : is the size of the destination buffer (which must be already allocated) return : the number of bytes written in buffer 'dest' or 0 if compression fails */ int LZ4_compress_limitedOutput (const char* source, char* dest, int sourceSize, int maxOutputSize); /* LZ4_compress_withState() : Same compression functions, but using an externally allocated memory space to store compression state. Use LZ4_sizeofState() to know how much memory must be allocated, and then, provide it as 'void* state' to compression functions. */ int LZ4_sizeofState(void); int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize); int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize); /* LZ4_decompress_fast() : originalSize : is the original and therefore uncompressed size return : the number of bytes read from the source buffer (in other words, the compressed size) If the source stream is detected malformed, the function will stop decoding and return a negative result. Destination buffer must be already allocated. Its size must be a minimum of 'originalSize' bytes. note : This function fully respect memory boundaries for properly formed compressed data. It is a bit faster than LZ4_decompress_safe(). However, it does not provide any protection against intentionally modified data stream (malicious input). Use this function in trusted environment only (data to decode comes from a trusted source). */ int LZ4_decompress_fast (const char* source, char* dest, int originalSize); /* LZ4_decompress_safe_partial() : This function decompress a compressed block of size 'compressedSize' at position 'source' into destination buffer 'dest' of size 'maxDecompressedSize'. The function tries to stop decompressing operation as soon as 'targetOutputSize' has been reached, reducing decompression time. return : the number of bytes decoded in the destination buffer (necessarily <= maxDecompressedSize) Note : this number can be < 'targetOutputSize' should the compressed block to decode be smaller. Always control how many bytes were decoded. If the source stream is detected malformed, the function will stop decoding and return a negative result. This function never writes outside of output buffer, and never reads outside of input buffer. It is therefore protected against malicious data packets */ int LZ4_decompress_safe_partial (const char* source, char* dest, int compressedSize, int targetOutputSize, int maxDecompressedSize); /*********************************************** Streaming Compression Functions ***********************************************/ #define LZ4_STREAMSIZE_U64 ((1 << (LZ4_MEMORY_USAGE-3)) + 4) #define LZ4_STREAMSIZE (LZ4_STREAMSIZE_U64 * sizeof(long long)) /* * LZ4_stream_t * information structure to track an LZ4 stream. * important : init this structure content before first use ! * note : only allocated directly the structure if you are statically linking LZ4 * If you are using liblz4 as a DLL, please use below construction methods instead. */ typedef struct { long long table[LZ4_STREAMSIZE_U64]; } LZ4_stream_t; /* * LZ4_resetStream * Use this function to init an allocated LZ4_stream_t structure */ void LZ4_resetStream (LZ4_stream_t* LZ4_streamPtr); /* * LZ4_createStream will allocate and initialize an LZ4_stream_t structure * LZ4_freeStream releases its memory. * In the context of a DLL (liblz4), please use these methods rather than the static struct. * They are more future proof, in case of a change of LZ4_stream_t size. */ LZ4_stream_t* LZ4_createStream(void); int LZ4_freeStream (LZ4_stream_t* LZ4_streamPtr); /* * LZ4_loadDict * Use this function to load a static dictionary into LZ4_stream. * Any previous data will be forgotten, only 'dictionary' will remain in memory. * Loading a size of 0 is allowed. * Return : dictionary size, in bytes (necessarily <= 64 KB) */ int LZ4_loadDict (LZ4_stream_t* LZ4_streamPtr, const char* dictionary, int dictSize); /* * LZ4_compress_continue * Compress data block 'source', using blocks compressed before as dictionary to improve compression ratio * Previous data blocks are assumed to still be present at their previous location. */ int LZ4_compress_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize); /* * LZ4_compress_limitedOutput_continue * Same as before, but also specify a maximum target compressed size (maxOutputSize) * If objective cannot be met, compression exits, and returns a zero. */ int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize, int maxOutputSize); /* * LZ4_saveDict * If previously compressed data block is not guaranteed to remain available at its memory location * save it into a safer place (char* safeBuffer) * Note : you don't need to call LZ4_loadDict() afterwards, * dictionary is immediately usable, you can therefore call again LZ4_compress_continue() * Return : dictionary size in bytes, or 0 if error * Note : any dictSize > 64 KB will be interpreted as 64KB. */ int LZ4_saveDict (LZ4_stream_t* LZ4_streamPtr, char* safeBuffer, int dictSize); /************************************************ Streaming Decompression Functions ************************************************/ #define LZ4_STREAMDECODESIZE_U64 4 #define LZ4_STREAMDECODESIZE (LZ4_STREAMDECODESIZE_U64 * sizeof(unsigned long long)) typedef struct { unsigned long long table[LZ4_STREAMDECODESIZE_U64]; } LZ4_streamDecode_t; /* * LZ4_streamDecode_t * information structure to track an LZ4 stream. * init this structure content using LZ4_setStreamDecode or memset() before first use ! * * In the context of a DLL (liblz4) please prefer usage of construction methods below. * They are more future proof, in case of a change of LZ4_streamDecode_t size in the future. * LZ4_createStreamDecode will allocate and initialize an LZ4_streamDecode_t structure * LZ4_freeStreamDecode releases its memory. */ LZ4_streamDecode_t* LZ4_createStreamDecode(void); int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream); /* * LZ4_setStreamDecode * Use this function to instruct where to find the dictionary. * Setting a size of 0 is allowed (same effect as reset). * Return : 1 if OK, 0 if error */ int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize); /* *_continue() : These decoding functions allow decompression of multiple blocks in "streaming" mode. Previously decoded blocks *must* remain available at the memory position where they were decoded (up to 64 KB) If this condition is not possible, save the relevant part of decoded data into a safe buffer, and indicate where is its new address using LZ4_setStreamDecode() */ int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxDecompressedSize); int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize); /* Advanced decoding functions : *_usingDict() : These decoding functions work the same as a combination of LZ4_setDictDecode() followed by LZ4_decompress_x_continue() They are stand-alone and don't use nor update an LZ4_streamDecode_t structure. */ int LZ4_decompress_safe_usingDict (const char* source, char* dest, int compressedSize, int maxDecompressedSize, const char* dictStart, int dictSize); int LZ4_decompress_fast_usingDict (const char* source, char* dest, int originalSize, const char* dictStart, int dictSize); /************************************** Obsolete Functions **************************************/ /* Obsolete decompression functions These function names are deprecated and should no longer be used. They are only provided here for compatibility with older user programs. - LZ4_uncompress is the same as LZ4_decompress_fast - LZ4_uncompress_unknownOutputSize is the same as LZ4_decompress_safe These function prototypes are now disabled; uncomment them if you really need them. It is highly recommended to stop using these functions and migrate to newer ones */ /* int LZ4_uncompress (const char* source, char* dest, int outputSize); */ /* int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize); */ /* Obsolete streaming functions; use new streaming interface whenever possible */ void* LZ4_create (const char* inputBuffer); int LZ4_sizeofStreamState(void); int LZ4_resetStreamState(void* state, const char* inputBuffer); char* LZ4_slideInputBuffer (void* state); /* Obsolete streaming decoding functions */ int LZ4_decompress_safe_withPrefix64k (const char* source, char* dest, int compressedSize, int maxOutputSize); int LZ4_decompress_fast_withPrefix64k (const char* source, char* dest, int originalSize); #if defined (__cplusplus) } #endif gtkwave-3.3.66/src/helpers/fst/fastlz.h0000664000076400007640000000710512341266475017315 0ustar bybellbybell/* FastLZ - lightning-fast lossless compression library Copyright (C) 2007 Ariya Hidayat (ariya@kde.org) Copyright (C) 2006 Ariya Hidayat (ariya@kde.org) Copyright (C) 2005 Ariya Hidayat (ariya@kde.org) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef FASTLZ_H #define FASTLZ_H #include #define flzuint8 uint8_t #define flzuint16 uint16_t #define flzuint32 uint32_t #define FASTLZ_VERSION 0x000100 #define FASTLZ_VERSION_MAJOR 0 #define FASTLZ_VERSION_MINOR 0 #define FASTLZ_VERSION_REVISION 0 #define FASTLZ_VERSION_STRING "0.1.0" #if defined (__cplusplus) extern "C" { #endif /** Compress a block of data in the input buffer and returns the size of compressed block. The size of input buffer is specified by length. The minimum input buffer size is 16. The output buffer must be at least 5% larger than the input buffer and can not be smaller than 66 bytes. If the input is not compressible, the return value might be larger than length (input buffer size). The input buffer and the output buffer can not overlap. */ int fastlz_compress(const void* input, int length, void* output); /** Decompress a block of compressed data and returns the size of the decompressed block. If error occurs, e.g. the compressed data is corrupted or the output buffer is not large enough, then 0 (zero) will be returned instead. The input buffer and the output buffer can not overlap. Decompression is memory safe and guaranteed not to write the output buffer more than what is specified in maxout. */ int fastlz_decompress(const void* input, int length, void* output, int maxout); /** Compress a block of data in the input buffer and returns the size of compressed block. The size of input buffer is specified by length. The minimum input buffer size is 16. The output buffer must be at least 5% larger than the input buffer and can not be smaller than 66 bytes. If the input is not compressible, the return value might be larger than length (input buffer size). The input buffer and the output buffer can not overlap. Compression level can be specified in parameter level. At the moment, only level 1 and level 2 are supported. Level 1 is the fastest compression and generally useful for short data. Level 2 is slightly slower but it gives better compression ratio. Note that the compressed data, regardless of the level, can always be decompressed using the function fastlz_decompress above. */ int fastlz_compress_level(int level, const void* input, int length, void* output); #if defined (__cplusplus) } #endif #endif /* FASTLZ_H */ gtkwave-3.3.66/src/helpers/v2l_analyzer_lxt2.h0000664000076400007640000000717112341266475020602 0ustar bybellbybell/* * Copyright (c) 2001 Tony Bybell. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #ifndef L2V_ANALYZER_H #define L2V_ANALYZER_H #include #include #include #include #include #include #include #include #ifdef HAVE_INTTYPES_H #include #endif #ifndef _AIX #if HAVE_GETOPT_H #include #endif #endif #include "v2l_debug_lxt2.h" #ifndef _MSC_VER #include #endif #define SYMPRIME 500009 #define WAVE_DECOMPRESSOR "gzip -cd " /* zcat alone doesn't cut it for AIX */ typedef struct Node *nptr; typedef struct HistEnt *hptr; typedef struct HistEnt { hptr next; /* next transition in history */ TimeType time; /* time of transition */ TimeType previous_width; /* to avoid thrashing */ union { unsigned char val; /* value: "0XU1"[val] */ char *vector; /* pointer to a whole vector */ } v; } HistEnt; typedef struct ExtNode { int msi, lsi; } ExtNode; struct Node { char *nname; /* ascii name of node */ ExtNode *ext; /* extension to node for vectors */ HistEnt head; /* first entry in transition history */ hptr curr; /* ptr. to current history entry */ hptr *harray; /* fill this in when we make a trace.. contains */ /* a ptr to an array of histents for bsearching */ int numhist; /* number of elements in the harray */ char notdead; /* indicates if this node gets a non-x value */ int numtrans; /* number of transitions */ struct Node *substnode; /* pointer to substitutions on buses */ struct Node *substhead; /* pointer to substitution head (originator) on buses */ }; struct symbol { struct symbol *nextinaet;/* for aet node chaining */ struct HistEnt *h; /* points to previous one */ struct symbol *next; /* for hash chain */ char *name; char selected; /* for the clist object */ struct Node *n; }; struct slist { struct slist *next; char *str; int len; }; struct vcdsymbol { struct vcdsymbol *next; void *ltsym; char *name; char *id; char *value; struct queuedevent *ev; /* only if vartype==V_EVENT */ struct Node **narray; unsigned int nid; int msi, lsi; int size; unsigned char vartype; }; struct queuedevent { struct queuedevent *next; struct vcdsymbol *sym; TimeType last_event_time; /* make +1 == 0 if there's not an event there too */ }; struct symbol *symfind(char *); struct symbol *symadd(char *, int); int hash(char *s); int sigcmp(char *, char *); void quicksort(struct symbol **, int, int); TimeType vcd_main(char *fname, char *lxname); void append_vcd_slisthier(char *str); #endif gtkwave-3.3.66/src/fonts.h0000664000076400007640000000230412341266475014701 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2008 * * 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. */ #ifndef WAVEFONTENGINE_H #define WAVEFONTENGINE_H #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) #include #endif #include struct font_engine_font_t { #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN) PangoFontDescription *desc; PangoFont *font; PangoFontMetrics *metrics; #endif int ascent, descent; int mono_width; GdkFont *gdkfont; unsigned is_pango : 1; unsigned is_mono : 1; }; void load_all_fonts(void); void font_engine_draw_string (GdkDrawable *drawable, struct font_engine_font_t *font, GdkGC *gc, gint x, gint y, const gchar *string); gint font_engine_string_measure (struct font_engine_font_t *font, const gchar *string); #endif gtkwave-3.3.66/src/gnu_regex.c0000664000076400007640000055742211775670340015546 0ustar bybellbybell/* Extended regular expression matching and search library, version 0.12. (Implements POSIX draft P1003.2/D11.2, except for some of the internationalization features.) Copyright (C) 1993, 94, 95, 96, 97, 98, 99 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA. */ /* AIX requires this to be the first thing in the file. */ #if defined _AIX && !defined REGEX_MALLOC #pragma alloca #endif #ifdef REGEX_MAY_COMPILE #undef _GNU_SOURCE #define _GNU_SOURCE #ifdef HAVE_CONFIG_H # include #endif /* fix for 64-bit OSX compiles */ #define GR_INT int #ifndef PARAMS # if defined __GNUC__ || (defined __STDC__ && __STDC__) # define PARAMS(args) args # else # define PARAMS(args) () # endif /* GCC. */ #endif /* Not PARAMS. */ #if defined STDC_HEADERS && !defined emacs # include #else /* We need this for `regex.h', and perhaps for the Emacs include files. */ # include #endif #ifdef __osf__ #include #endif #define WIDE_CHAR_SUPPORT (HAVE_WCTYPE_H && HAVE_WCHAR_H && HAVE_BTOWC) /* For platform which support the ISO C amendement 1 functionality we support user defined character classes. */ #if defined _LIBC || WIDE_CHAR_SUPPORT /* Solaris 2.5 has a bug: must be included before . */ # include # include #endif #ifdef _LIBC /* We have to keep the namespace clean. */ # define regfree(preg) __regfree (preg) # define regexec(pr, st, nm, pm, ef) __regexec (pr, st, nm, pm, ef) # define regcomp(preg, pattern, cflags) __regcomp (preg, pattern, cflags) # define regerror(errcode, preg, errbuf, errbuf_size) \ __regerror(errcode, preg, errbuf, errbuf_size) # define re_set_registers(bu, re, nu, st, en) \ __re_set_registers (bu, re, nu, st, en) # define re_match_2(bufp, string1, size1, string2, size2, pos, regs, stop) \ __re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop) # define re_match(bufp, string, size, pos, regs) \ __re_match (bufp, string, size, pos, regs) # define re_search(bufp, string, size, startpos, range, regs) \ __re_search (bufp, string, size, startpos, range, regs) # define re_compile_pattern(pattern, length, bufp) \ __re_compile_pattern (pattern, length, bufp) # define re_set_syntax(syntax) __re_set_syntax (syntax) # define re_search_2(bufp, st1, s1, st2, s2, startpos, range, regs, stop) \ __re_search_2 (bufp, st1, s1, st2, s2, startpos, range, regs, stop) # define re_compile_fastmap(bufp) __re_compile_fastmap (bufp) #define btowc __btowc #endif /* This is for other GNU distributions with internationalized messages. */ #if HAVE_LIBINTL_H || defined _LIBC # include #else # define gettext(msgid) (msgid) #endif #ifndef gettext_noop /* This define is so xgettext can find the internationalizable strings. */ # define gettext_noop(String) String #endif /* The `emacs' switch turns on certain matching commands that make sense only in Emacs. */ #ifdef emacs # include "lisp.h" # include "buffer.h" # include "syntax.h" #else /* not emacs */ /* If we are not linking with Emacs proper, we can't use the relocating allocator even if config.h says that we can. */ # undef REL_ALLOC # if defined STDC_HEADERS || defined _LIBC # include # else char *malloc (); char *realloc (); # endif /* When used in Emacs's lib-src, we need to get bzero and bcopy somehow. If nothing else has been done, use the method below. */ # ifdef INHIBIT_STRING_HEADER # if !(defined HAVE_BZERO && defined HAVE_BCOPY) # if !defined bzero && !defined bcopy # undef INHIBIT_STRING_HEADER # endif # endif # endif /* This is the normal way of making sure we have a bcopy and a bzero. This is used in most programs--a few other programs avoid this by defining INHIBIT_STRING_HEADER. */ # ifndef INHIBIT_STRING_HEADER # if defined HAVE_STRING_H || defined STDC_HEADERS || defined _LIBC # include # ifndef bzero # ifndef _LIBC # define bzero(s, n) (memset (s, '\0', n), (s)) # else # define bzero(s, n) __bzero (s, n) # endif # endif # else # include # ifndef memcmp # define memcmp(s1, s2, n) bcmp (s1, s2, n) # endif # ifndef memcpy # define memcpy(d, s, n) (bcopy (s, d, n), (d)) # endif # endif # endif /* Define the syntax stuff for \<, \>, etc. */ /* This must be nonzero for the wordchar and notwordchar pattern commands in re_match_2. */ # ifndef Sword # define Sword 1 # endif # ifdef SWITCH_ENUM_BUG # define SWITCH_ENUM_CAST(x) ((int)(x)) # else # define SWITCH_ENUM_CAST(x) (x) # endif /* How many characters in the character set. */ # define CHAR_SET_SIZE 256 # ifdef SYNTAX_TABLE extern char *re_syntax_table; # else /* not SYNTAX_TABLE */ static char re_syntax_table[CHAR_SET_SIZE]; static void init_syntax_once () { register int c; static int done; if (done) return; bzero (re_syntax_table, sizeof re_syntax_table); for (c = 'a'; c <= 'z'; c++) re_syntax_table[c] = Sword; for (c = 'A'; c <= 'Z'; c++) re_syntax_table[c] = Sword; for (c = '0'; c <= '9'; c++) re_syntax_table[c] = Sword; re_syntax_table['_'] = Sword; done = 1; } # endif /* not SYNTAX_TABLE */ # define SYNTAX(c) re_syntax_table[c] #endif /* not emacs */ /* Get the interface, including the syntax bits. */ #include "gnu_regex.h" /* isalpha etc. are used for the character classes. */ #include /* Jim Meyering writes: "... Some ctype macros are valid only for character codes that isascii says are ASCII (SGI's IRIX-4.0.5 is one such system --when using /bin/cc or gcc but without giving an ansi option). So, all ctype uses should be through macros like ISPRINT... If STDC_HEADERS is defined, then autoconf has verified that the ctype macros don't need to be guarded with references to isascii. ... Defining isascii to 1 should let any compiler worth its salt eliminate the && through constant folding." Solaris defines some of these symbols so we must undefine them first. */ #undef ISASCII #if defined STDC_HEADERS || (!defined isascii && !defined HAVE_ISASCII) # define ISASCII(c) 1 #else # define ISASCII(c) isascii(c) #endif #ifdef isblank # define ISBLANK(c) (ISASCII (c) && isblank (c)) #else # define ISBLANK(c) ((c) == ' ' || (c) == '\t') #endif #ifdef isgraph # define ISGRAPH(c) (ISASCII (c) && isgraph (c)) #else # define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c)) #endif #undef ISPRINT #define ISPRINT(c) (ISASCII (c) && isprint (c)) #define ISDIGIT(c) (ISASCII (c) && isdigit (c)) #define ISALNUM(c) (ISASCII (c) && isalnum (c)) #define ISALPHA(c) (ISASCII (c) && isalpha (c)) #define ISCNTRL(c) (ISASCII (c) && iscntrl (c)) #define ISLOWER(c) (ISASCII (c) && islower (c)) #define ISPUNCT(c) (ISASCII (c) && ispunct (c)) #define ISSPACE(c) (ISASCII (c) && isspace (c)) #define ISUPPER(c) (ISASCII (c) && isupper (c)) #define ISXDIGIT(c) (ISASCII (c) && isxdigit (c)) #ifdef _tolower # define TOLOWER(c) _tolower(c) #else # define TOLOWER(c) tolower(c) #endif #ifndef NULL # define NULL (void *)0 #endif /* We remove any previous definition of `SIGN_EXTEND_CHAR', since ours (we hope) works properly with all combinations of machines, compilers, `char' and `unsigned char' argument types. (Per Bothner suggested the basic approach.) */ #undef SIGN_EXTEND_CHAR #if __STDC__ # define SIGN_EXTEND_CHAR(c) ((signed char) (c)) #else /* not __STDC__ */ /* As in Harbison and Steele. */ # define SIGN_EXTEND_CHAR(c) ((((unsigned char) (c)) ^ 128) - 128) #endif /* Should we use malloc or alloca? If REGEX_MALLOC is not defined, we use `alloca' instead of `malloc'. This is because using malloc in re_search* or re_match* could cause memory leaks when C-g is used in Emacs; also, malloc is slower and causes storage fragmentation. On the other hand, malloc is more portable, and easier to debug. Because we sometimes use alloca, some routines have to be macros, not functions -- `alloca'-allocated space disappears at the end of the function it is called in. */ #ifdef REGEX_MALLOC # define REGEX_ALLOCATE malloc # define REGEX_REALLOCATE(source, osize, nsize) realloc (source, nsize) # define REGEX_FREE free #else /* not REGEX_MALLOC */ /* Emacs already defines alloca, sometimes. */ # ifndef alloca /* Make alloca work the best possible way. */ # ifdef __GNUC__ # define alloca __builtin_alloca # else /* not __GNUC__ */ # if HAVE_ALLOCA_H # include # endif /* HAVE_ALLOCA_H */ # endif /* not __GNUC__ */ # endif /* not alloca */ # define REGEX_ALLOCATE alloca /* Assumes a `char *destination' variable. */ # define REGEX_REALLOCATE(source, osize, nsize) \ (destination = (char *) alloca (nsize), \ memcpy (destination, source, osize)) /* No need to do anything to free, after alloca. */ # define REGEX_FREE(arg) ((void)0) /* Do nothing! But inhibit gcc warning. */ #endif /* not REGEX_MALLOC */ /* Define how to allocate the failure stack. */ #if defined REL_ALLOC && defined REGEX_MALLOC # define REGEX_ALLOCATE_STACK(size) \ r_alloc (&failure_stack_ptr, (size)) # define REGEX_REALLOCATE_STACK(source, osize, nsize) \ r_re_alloc (&failure_stack_ptr, (nsize)) # define REGEX_FREE_STACK(ptr) \ r_alloc_free (&failure_stack_ptr) #else /* not using relocating allocator */ # ifdef REGEX_MALLOC # define REGEX_ALLOCATE_STACK malloc # define REGEX_REALLOCATE_STACK(source, osize, nsize) realloc (source, nsize) # define REGEX_FREE_STACK free # else /* not REGEX_MALLOC */ # define REGEX_ALLOCATE_STACK alloca # define REGEX_REALLOCATE_STACK(source, osize, nsize) \ REGEX_REALLOCATE (source, osize, nsize) /* No need to explicitly free anything. */ # define REGEX_FREE_STACK(arg) # endif /* not REGEX_MALLOC */ #endif /* not using relocating allocator */ /* True if `size1' is non-NULL and PTR is pointing anywhere inside `string1' or just past its end. This works if PTR is NULL, which is a good thing. */ #define FIRST_STRING_P(ptr) \ (size1 && string1 <= (ptr) && (ptr) <= string1 + size1) /* (Re)Allocate N items of type T using malloc, or fail. */ #define TALLOC(n, t) ((t *) malloc ((n) * sizeof (t))) #define RETALLOC(addr, n, t) ((addr) = (t *) realloc (addr, (n) * sizeof (t))) #define RETALLOC_IF(addr, n, t) \ if (addr) RETALLOC((addr), (n), t); else (addr) = TALLOC ((n), t) #define REGEX_TALLOC(n, t) ((t *) REGEX_ALLOCATE ((n) * sizeof (t))) #define BYTEWIDTH 8 /* In bits. */ #define STREQ(s1, s2) ((strcmp (s1, s2) == 0)) #undef MAX #undef MIN #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define false 0 #define true 1 static int re_match_2_internal PARAMS ((struct re_pattern_buffer *bufp, const char *string1, int size1, const char *string2, int size2, int pos, struct re_registers *regs, int stop)); /* These are the command codes that appear in compiled regular expressions. Some opcodes are followed by argument bytes. A command code can specify any interpretation whatsoever for its arguments. Zero bytes may appear in the compiled regular expression. */ typedef enum { no_op = 0, /* Succeed right away--no more backtracking. */ succeed, /* Followed by one byte giving n, then by n literal bytes. */ exactn, /* Matches any (more or less) character. */ anychar, /* Matches any one char belonging to specified set. First following byte is number of bitmap bytes. Then come bytes for a bitmap saying which chars are in. Bits in each byte are ordered low-bit-first. A character is in the set if its bit is 1. A character too large to have a bit in the map is automatically not in the set. */ charset, /* Same parameters as charset, but match any character that is not one of those specified. */ charset_not, /* Start remembering the text that is matched, for storing in a register. Followed by one byte with the register number, in the range 0 to one less than the pattern buffer's re_nsub field. Then followed by one byte with the number of groups inner to this one. (This last has to be part of the start_memory only because we need it in the on_failure_jump of re_match_2.) */ start_memory, /* Stop remembering the text that is matched and store it in a memory register. Followed by one byte with the register number, in the range 0 to one less than `re_nsub' in the pattern buffer, and one byte with the number of inner groups, just like `start_memory'. (We need the number of inner groups here because we don't have any easy way of finding the corresponding start_memory when we're at a stop_memory.) */ stop_memory, /* Match a duplicate of something remembered. Followed by one byte containing the register number. */ duplicate, /* Fail unless at beginning of line. */ begline, /* Fail unless at end of line. */ endline, /* Succeeds if at beginning of buffer (if emacs) or at beginning of string to be matched (if not). */ begbuf, /* Analogously, for end of buffer/string. */ endbuf, /* Followed by two byte relative address to which to jump. */ jump, /* Same as jump, but marks the end of an alternative. */ jump_past_alt, /* Followed by two-byte relative address of place to resume at in case of failure. */ on_failure_jump, /* Like on_failure_jump, but pushes a placeholder instead of the current string position when executed. */ on_failure_keep_string_jump, /* Throw away latest failure point and then jump to following two-byte relative address. */ pop_failure_jump, /* Change to pop_failure_jump if know won't have to backtrack to match; otherwise change to jump. This is used to jump back to the beginning of a repeat. If what follows this jump clearly won't match what the repeat does, such that we can be sure that there is no use backtracking out of repetitions already matched, then we change it to a pop_failure_jump. Followed by two-byte address. */ maybe_pop_jump, /* Jump to following two-byte address, and push a dummy failure point. This failure point will be thrown away if an attempt is made to use it for a failure. A `+' construct makes this before the first repeat. Also used as an intermediary kind of jump when compiling an alternative. */ dummy_failure_jump, /* Push a dummy failure point and continue. Used at the end of alternatives. */ push_dummy_failure, /* Followed by two-byte relative address and two-byte number n. After matching N times, jump to the address upon failure. */ succeed_n, /* Followed by two-byte relative address, and two-byte number n. Jump to the address N times, then fail. */ jump_n, /* Set the following two-byte relative address to the subsequent two-byte number. The address *includes* the two bytes of number. */ set_number_at, wordchar, /* Matches any word-constituent character. */ notwordchar, /* Matches any char that is not a word-constituent. */ wordbeg, /* Succeeds if at word beginning. */ wordend, /* Succeeds if at word end. */ wordbound, /* Succeeds if at a word boundary. */ notwordbound /* Succeeds if not at a word boundary. */ #ifdef emacs ,before_dot, /* Succeeds if before point. */ at_dot, /* Succeeds if at point. */ after_dot, /* Succeeds if after point. */ /* Matches any character whose syntax is specified. Followed by a byte which contains a syntax code, e.g., Sword. */ syntaxspec, /* Matches any character whose syntax is not that specified. */ notsyntaxspec #endif /* emacs */ } re_opcode_t; /* Common operations on the compiled pattern. */ /* Store NUMBER in two contiguous bytes starting at DESTINATION. */ #define STORE_NUMBER(destination, number) \ do { \ (destination)[0] = (number) & 0377; \ (destination)[1] = (number) >> 8; \ } while (0) /* Same as STORE_NUMBER, except increment DESTINATION to the byte after where the number is stored. Therefore, DESTINATION must be an lvalue. */ #define STORE_NUMBER_AND_INCR(destination, number) \ do { \ STORE_NUMBER (destination, number); \ (destination) += 2; \ } while (0) /* Put into DESTINATION a number stored in two contiguous bytes starting at SOURCE. */ #define EXTRACT_NUMBER(destination, source) \ do { \ (destination) = *(source) & 0377; \ (destination) += SIGN_EXTEND_CHAR (*((source) + 1)) << 8; \ } while (0) #ifdef DEBUG static void extract_number _RE_ARGS ((int *dest, unsigned char *source)); static void extract_number (dest, source) int *dest; unsigned char *source; { int temp = SIGN_EXTEND_CHAR (*(source + 1)); *dest = *source & 0377; *dest += temp << 8; } # ifndef EXTRACT_MACROS /* To debug the macros. */ # undef EXTRACT_NUMBER # define EXTRACT_NUMBER(dest, src) extract_number (&dest, src) # endif /* not EXTRACT_MACROS */ #endif /* DEBUG */ /* Same as EXTRACT_NUMBER, except increment SOURCE to after the number. SOURCE must be an lvalue. */ #define EXTRACT_NUMBER_AND_INCR(destination, source) \ do { \ EXTRACT_NUMBER (destination, source); \ (source) += 2; \ } while (0) #ifdef DEBUG static void extract_number_and_incr _RE_ARGS ((int *destination, unsigned char **source)); static void extract_number_and_incr (destination, source) int *destination; unsigned char **source; { extract_number (destination, *source); *source += 2; } # ifndef EXTRACT_MACROS # undef EXTRACT_NUMBER_AND_INCR # define EXTRACT_NUMBER_AND_INCR(dest, src) \ extract_number_and_incr (&dest, &src) # endif /* not EXTRACT_MACROS */ #endif /* DEBUG */ /* If DEBUG is defined, Regex prints many voluminous messages about what it is doing (if the variable `debug' is nonzero). If linked with the main program in `iregex.c', you can enter patterns and strings interactively. And if linked with the main program in `main.c' and the other test files, you can run the already-written tests. */ #ifdef DEBUG /* We use standard I/O for debugging. */ # include /* It is useful to test things that ``must'' be true when debugging. */ # include static int debug; # define DEBUG_STATEMENT(e) e # define DEBUG_PRINT1(x) if (debug) printf (x) # define DEBUG_PRINT2(x1, x2) if (debug) printf (x1, x2) # define DEBUG_PRINT3(x1, x2, x3) if (debug) printf (x1, x2, x3) # define DEBUG_PRINT4(x1, x2, x3, x4) if (debug) printf (x1, x2, x3, x4) # define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) \ if (debug) print_partial_compiled_pattern (s, e) # define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) \ if (debug) print_double_string (w, s1, sz1, s2, sz2) /* Print the fastmap in human-readable form. */ void print_fastmap (fastmap) char *fastmap; { unsigned was_a_range = 0; unsigned i = 0; while (i < (1 << BYTEWIDTH)) { if (fastmap[i++]) { was_a_range = 0; putchar (i - 1); while (i < (1 << BYTEWIDTH) && fastmap[i]) { was_a_range = 1; i++; } if (was_a_range) { printf ("-"); putchar (i - 1); } } } putchar ('\n'); } /* Print a compiled pattern string in human-readable form, starting at the START pointer into it and ending just before the pointer END. */ void print_partial_compiled_pattern (start, end) unsigned char *start; unsigned char *end; { int mcnt, mcnt2; unsigned char *p1; unsigned char *p = start; unsigned char *pend = end; if (start == NULL) { printf ("(null)\n"); return; } /* Loop over pattern commands. */ while (p < pend) { printf ("%d:\t", (GR_INT)(p - start)); switch ((re_opcode_t) *p++) { case no_op: printf ("/no_op"); break; case exactn: mcnt = *p++; printf ("/exactn/%d", mcnt); do { putchar ('/'); putchar (*p++); } while (--mcnt); break; case start_memory: mcnt = *p++; printf ("/start_memory/%d/%d", mcnt, *p++); break; case stop_memory: mcnt = *p++; printf ("/stop_memory/%d/%d", mcnt, *p++); break; case duplicate: printf ("/duplicate/%d", *p++); break; case anychar: printf ("/anychar"); break; case charset: case charset_not: { register int c, last = -100; register int in_range = 0; printf ("/charset [%s", (re_opcode_t) *(p - 1) == charset_not ? "^" : ""); assert (p + *p < pend); for (c = 0; c < 256; c++) if (c / 8 < *p && (p[1 + (c/8)] & (1 << (c % 8)))) { /* Are we starting a range? */ if (last + 1 == c && ! in_range) { putchar ('-'); in_range = 1; } /* Have we broken a range? */ else if (last + 1 != c && in_range) { putchar (last); in_range = 0; } if (! in_range) putchar (c); last = c; } if (in_range) putchar (last); putchar (']'); p += 1 + *p; } break; case begline: printf ("/begline"); break; case endline: printf ("/endline"); break; case on_failure_jump: extract_number_and_incr (&mcnt, &p); printf ("/on_failure_jump to %d", (GR_INT)(p + mcnt - start)); break; case on_failure_keep_string_jump: extract_number_and_incr (&mcnt, &p); printf ("/on_failure_keep_string_jump to %d", (GR_INT)(p + mcnt - start)); break; case dummy_failure_jump: extract_number_and_incr (&mcnt, &p); printf ("/dummy_failure_jump to %d", (GR_INT)(p + mcnt - start)); break; case push_dummy_failure: printf ("/push_dummy_failure"); break; case maybe_pop_jump: extract_number_and_incr (&mcnt, &p); printf ("/maybe_pop_jump to %d", (GR_INT)(p + mcnt - start)); break; case pop_failure_jump: extract_number_and_incr (&mcnt, &p); printf ("/pop_failure_jump to %d", (GR_INT)(p + mcnt - start)); break; case jump_past_alt: extract_number_and_incr (&mcnt, &p); printf ("/jump_past_alt to %d", (GR_INT)(p + mcnt - start)); break; case jump: extract_number_and_incr (&mcnt, &p); printf ("/jump to %d", (GR_INT)(p + mcnt - start)); break; case succeed_n: extract_number_and_incr (&mcnt, &p); p1 = p + mcnt; extract_number_and_incr (&mcnt2, &p); printf ("/succeed_n to %d, %d times", (GR_INT)(p1 - start), mcnt2); break; case jump_n: extract_number_and_incr (&mcnt, &p); p1 = p + mcnt; extract_number_and_incr (&mcnt2, &p); printf ("/jump_n to %d, %d times", (GR_INT)(p1 - start), mcnt2); break; case set_number_at: extract_number_and_incr (&mcnt, &p); p1 = p + mcnt; extract_number_and_incr (&mcnt2, &p); printf ("/set_number_at location %d to %d", (GR_INT)(p1 - start), mcnt2); break; case wordbound: printf ("/wordbound"); break; case notwordbound: printf ("/notwordbound"); break; case wordbeg: printf ("/wordbeg"); break; case wordend: printf ("/wordend"); # ifdef emacs case before_dot: printf ("/before_dot"); break; case at_dot: printf ("/at_dot"); break; case after_dot: printf ("/after_dot"); break; case syntaxspec: printf ("/syntaxspec"); mcnt = *p++; printf ("/%d", mcnt); break; case notsyntaxspec: printf ("/notsyntaxspec"); mcnt = *p++; printf ("/%d", mcnt); break; # endif /* emacs */ case wordchar: printf ("/wordchar"); break; case notwordchar: printf ("/notwordchar"); break; case begbuf: printf ("/begbuf"); break; case endbuf: printf ("/endbuf"); break; default: printf ("?%d", *(p-1)); } putchar ('\n'); } printf ("%d:\tend of pattern.\n", (GR_INT)(p - start)); } void print_compiled_pattern (bufp) struct re_pattern_buffer *bufp; { unsigned char *buffer = bufp->buffer; print_partial_compiled_pattern (buffer, buffer + bufp->used); printf ("%ld bytes used/%ld bytes allocated.\n", bufp->used, bufp->allocated); if (bufp->fastmap_accurate && bufp->fastmap) { printf ("fastmap: "); print_fastmap (bufp->fastmap); } printf ("re_nsub: %d\t", (GR_INT)(bufp->re_nsub)); printf ("regs_alloc: %d\t", bufp->regs_allocated); printf ("can_be_null: %d\t", bufp->can_be_null); printf ("newline_anchor: %d\n", bufp->newline_anchor); printf ("no_sub: %d\t", bufp->no_sub); printf ("not_bol: %d\t", bufp->not_bol); printf ("not_eol: %d\t", bufp->not_eol); printf ("syntax: %lx\n", bufp->syntax); /* Perhaps we should print the translate table? */ } void print_double_string (where, string1, size1, string2, size2) const char *where; const char *string1; const char *string2; int size1; int size2; { int this_char; if (where == NULL) printf ("(null)"); else { if (FIRST_STRING_P (where)) { for (this_char = where - string1; this_char < size1; this_char++) putchar (string1[this_char]); where = string2; } for (this_char = where - string2; this_char < size2; this_char++) putchar (string2[this_char]); } } void printchar (c) int c; { putc (c, stderr); } #else /* not DEBUG */ # undef assert # define assert(e) # define DEBUG_STATEMENT(e) # define DEBUG_PRINT1(x) # define DEBUG_PRINT2(x1, x2) # define DEBUG_PRINT3(x1, x2, x3) # define DEBUG_PRINT4(x1, x2, x3, x4) # define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) # define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) #endif /* not DEBUG */ /* Set by `re_set_syntax' to the current regexp syntax to recognize. Can also be assigned to arbitrarily: each pattern buffer stores its own syntax, so it can be changed between regex compilations. */ /* This has no initializer because initialized variables in Emacs become read-only after dumping. */ reg_syntax_t re_syntax_options; /* Specify the precise syntax of regexps for compilation. This provides for compatibility for various utilities which historically have different, incompatible syntaxes. The argument SYNTAX is a bit mask comprised of the various bits defined in regex.h. We return the old syntax. */ reg_syntax_t re_set_syntax (syntax) reg_syntax_t syntax; { reg_syntax_t ret = re_syntax_options; re_syntax_options = syntax; #ifdef DEBUG if (syntax & RE_DEBUG) debug = 1; else if (debug) /* was on but now is not */ debug = 0; #endif /* DEBUG */ return ret; } #ifdef _LIBC weak_alias (__re_set_syntax, re_set_syntax) #endif /* This table gives an error message for each of the error codes listed in regex.h. Obviously the order here has to be same as there. POSIX doesn't require that we do anything for REG_NOERROR, but why not be nice? */ static const char re_error_msgid[] = { #define REG_NOERROR_IDX 0 gettext_noop ("Success") /* REG_NOERROR */ "\0" #define REG_NOMATCH_IDX (REG_NOERROR_IDX + sizeof "Success") gettext_noop ("No match") /* REG_NOMATCH */ "\0" #define REG_BADPAT_IDX (REG_NOMATCH_IDX + sizeof "No match") gettext_noop ("Invalid regular expression") /* REG_BADPAT */ "\0" #define REG_ECOLLATE_IDX (REG_BADPAT_IDX + sizeof "Invalid regular expression") gettext_noop ("Invalid collation character") /* REG_ECOLLATE */ "\0" #define REG_ECTYPE_IDX (REG_ECOLLATE_IDX + sizeof "Invalid collation character") gettext_noop ("Invalid character class name") /* REG_ECTYPE */ "\0" #define REG_EESCAPE_IDX (REG_ECTYPE_IDX + sizeof "Invalid character class name") gettext_noop ("Trailing backslash") /* REG_EESCAPE */ "\0" #define REG_ESUBREG_IDX (REG_EESCAPE_IDX + sizeof "Trailing backslash") gettext_noop ("Invalid back reference") /* REG_ESUBREG */ "\0" #define REG_EBRACK_IDX (REG_ESUBREG_IDX + sizeof "Invalid back reference") gettext_noop ("Unmatched [ or [^") /* REG_EBRACK */ "\0" #define REG_EPAREN_IDX (REG_EBRACK_IDX + sizeof "Unmatched [ or [^") gettext_noop ("Unmatched ( or \\(") /* REG_EPAREN */ "\0" #define REG_EBRACE_IDX (REG_EPAREN_IDX + sizeof "Unmatched ( or \\(") gettext_noop ("Unmatched \\{") /* REG_EBRACE */ "\0" #define REG_BADBR_IDX (REG_EBRACE_IDX + sizeof "Unmatched \\{") gettext_noop ("Invalid content of \\{\\}") /* REG_BADBR */ "\0" #define REG_ERANGE_IDX (REG_BADBR_IDX + sizeof "Invalid content of \\{\\}") gettext_noop ("Invalid range end") /* REG_ERANGE */ "\0" #define REG_ESPACE_IDX (REG_ERANGE_IDX + sizeof "Invalid range end") gettext_noop ("Memory exhausted") /* REG_ESPACE */ "\0" #define REG_BADRPT_IDX (REG_ESPACE_IDX + sizeof "Memory exhausted") gettext_noop ("Invalid preceding regular expression") /* REG_BADRPT */ "\0" #define REG_EEND_IDX (REG_BADRPT_IDX + sizeof "Invalid preceding regular expression") gettext_noop ("Premature end of regular expression") /* REG_EEND */ "\0" #define REG_ESIZE_IDX (REG_EEND_IDX + sizeof "Premature end of regular expression") gettext_noop ("Regular expression too big") /* REG_ESIZE */ "\0" #define REG_ERPAREN_IDX (REG_ESIZE_IDX + sizeof "Regular expression too big") gettext_noop ("Unmatched ) or \\)") /* REG_ERPAREN */ }; static const size_t re_error_msgid_idx[] = { REG_NOERROR_IDX, REG_NOMATCH_IDX, REG_BADPAT_IDX, REG_ECOLLATE_IDX, REG_ECTYPE_IDX, REG_EESCAPE_IDX, REG_ESUBREG_IDX, REG_EBRACK_IDX, REG_EPAREN_IDX, REG_EBRACE_IDX, REG_BADBR_IDX, REG_ERANGE_IDX, REG_ESPACE_IDX, REG_BADRPT_IDX, REG_EEND_IDX, REG_ESIZE_IDX, REG_ERPAREN_IDX }; /* Avoiding alloca during matching, to placate r_alloc. */ /* Define MATCH_MAY_ALLOCATE unless we need to make sure that the searching and matching functions should not call alloca. On some systems, alloca is implemented in terms of malloc, and if we're using the relocating allocator routines, then malloc could cause a relocation, which might (if the strings being searched are in the ralloc heap) shift the data out from underneath the regexp routines. Here's another reason to avoid allocation: Emacs processes input from X in a signal handler; processing X input may call malloc; if input arrives while a matching routine is calling malloc, then we're scrod. But Emacs can't just block input while calling matching routines; then we don't notice interrupts when they come in. So, Emacs blocks input around all regexp calls except the matching calls, which it leaves unprotected, in the faith that they will not malloc. */ /* Normally, this is fine. */ #define MATCH_MAY_ALLOCATE /* When using GNU C, we are not REALLY using the C alloca, no matter what config.h may say. So don't take precautions for it. */ #ifdef __GNUC__ # undef C_ALLOCA #endif /* The match routines may not allocate if (1) they would do it with malloc and (2) it's not safe for them to use malloc. Note that if REL_ALLOC is defined, matching would not use malloc for the failure stack, but we would still use it for the register vectors; so REL_ALLOC should not affect this. */ #if (defined C_ALLOCA || defined REGEX_MALLOC) && defined emacs # undef MATCH_MAY_ALLOCATE #endif /* Failure stack declarations and macros; both re_compile_fastmap and re_match_2 use a failure stack. These have to be macros because of REGEX_ALLOCATE_STACK. */ /* Number of failure points for which to initially allocate space when matching. If this number is exceeded, we allocate more space, so it is not a hard limit. */ #ifndef INIT_FAILURE_ALLOC # define INIT_FAILURE_ALLOC 5 #endif /* Roughly the maximum number of failure points on the stack. Would be exactly that if always used MAX_FAILURE_ITEMS items each time we failed. This is a variable only so users of regex can assign to it; we never change it ourselves. */ #ifdef INT_IS_16BIT # if defined MATCH_MAY_ALLOCATE /* 4400 was enough to cause a crash on Alpha OSF/1, whose default stack limit is 2mb. */ long int re_max_failures = 4000; # else long int re_max_failures = 2000; # endif union fail_stack_elt { unsigned char *pointer; long int integer; }; typedef union fail_stack_elt fail_stack_elt_t; typedef struct { fail_stack_elt_t *stack; unsigned long int size; unsigned long int avail; /* Offset of next open position. */ } fail_stack_type; #else /* not INT_IS_16BIT */ # if defined MATCH_MAY_ALLOCATE /* 4400 was enough to cause a crash on Alpha OSF/1, whose default stack limit is 2mb. */ int re_max_failures = 20000; # else int re_max_failures = 2000; # endif union fail_stack_elt { unsigned char *pointer; int integer; }; typedef union fail_stack_elt fail_stack_elt_t; typedef struct { fail_stack_elt_t *stack; unsigned size; unsigned avail; /* Offset of next open position. */ } fail_stack_type; #endif /* INT_IS_16BIT */ #define FAIL_STACK_EMPTY() (fail_stack.avail == 0) #define FAIL_STACK_PTR_EMPTY() (fail_stack_ptr->avail == 0) #define FAIL_STACK_FULL() (fail_stack.avail == fail_stack.size) /* Define macros to initialize and free the failure stack. Do `return -2' if the alloc fails. */ #ifdef MATCH_MAY_ALLOCATE # define INIT_FAIL_STACK() \ do { \ fail_stack.stack = (fail_stack_elt_t *) \ REGEX_ALLOCATE_STACK (INIT_FAILURE_ALLOC * sizeof (fail_stack_elt_t)); \ \ if (fail_stack.stack == NULL) \ return -2; \ \ fail_stack.size = INIT_FAILURE_ALLOC; \ fail_stack.avail = 0; \ } while (0) # define RESET_FAIL_STACK() REGEX_FREE_STACK (fail_stack.stack) #else # define INIT_FAIL_STACK() \ do { \ fail_stack.avail = 0; \ } while (0) # define RESET_FAIL_STACK() #endif /* Double the size of FAIL_STACK, up to approximately `re_max_failures' items. Return 1 if succeeds, and 0 if either ran out of memory allocating space for it or it was already too large. REGEX_REALLOCATE_STACK requires `destination' be declared. */ #define DOUBLE_FAIL_STACK(fail_stack) \ ((fail_stack).size > (unsigned) (re_max_failures * MAX_FAILURE_ITEMS) \ ? 0 \ : ((fail_stack).stack = (fail_stack_elt_t *) \ REGEX_REALLOCATE_STACK ((fail_stack).stack, \ (fail_stack).size * sizeof (fail_stack_elt_t), \ ((fail_stack).size << 1) * sizeof (fail_stack_elt_t)), \ \ (fail_stack).stack == NULL \ ? 0 \ : ((fail_stack).size <<= 1, \ 1))) /* Push pointer POINTER on FAIL_STACK. Return 1 if was able to do so and 0 if ran out of memory allocating space to do so. */ #define PUSH_PATTERN_OP(POINTER, FAIL_STACK) \ ((FAIL_STACK_FULL () \ && !DOUBLE_FAIL_STACK (FAIL_STACK)) \ ? 0 \ : ((FAIL_STACK).stack[(FAIL_STACK).avail++].pointer = POINTER, \ 1)) /* Push a pointer value onto the failure stack. Assumes the variable `fail_stack'. Probably should only be called from within `PUSH_FAILURE_POINT'. */ #define PUSH_FAILURE_POINTER(item) \ fail_stack.stack[fail_stack.avail++].pointer = (unsigned char *) (item) /* This pushes an integer-valued item onto the failure stack. Assumes the variable `fail_stack'. Probably should only be called from within `PUSH_FAILURE_POINT'. */ #define PUSH_FAILURE_INT(item) \ fail_stack.stack[fail_stack.avail++].integer = (item) /* Push a fail_stack_elt_t value onto the failure stack. Assumes the variable `fail_stack'. Probably should only be called from within `PUSH_FAILURE_POINT'. */ #define PUSH_FAILURE_ELT(item) \ fail_stack.stack[fail_stack.avail++] = (item) /* These three POP... operations complement the three PUSH... operations. All assume that `fail_stack' is nonempty. */ #define POP_FAILURE_POINTER() fail_stack.stack[--fail_stack.avail].pointer #define POP_FAILURE_INT() fail_stack.stack[--fail_stack.avail].integer #define POP_FAILURE_ELT() fail_stack.stack[--fail_stack.avail] /* Used to omit pushing failure point id's when we're not debugging. */ #ifdef DEBUG # define DEBUG_PUSH PUSH_FAILURE_INT # define DEBUG_POP(item_addr) *(item_addr) = POP_FAILURE_INT () #else # define DEBUG_PUSH(item) # define DEBUG_POP(item_addr) #endif /* Push the information about the state we will need if we ever fail back to it. Requires variables fail_stack, regstart, regend, reg_info, and num_regs_pushed be declared. DOUBLE_FAIL_STACK requires `destination' be declared. Does `return FAILURE_CODE' if runs out of memory. */ #define PUSH_FAILURE_POINT(pattern_place, string_place, failure_code) \ do { \ char *destination; \ /* Must be int, so when we don't save any registers, the arithmetic \ of 0 + -1 isn't done as unsigned. */ \ /* Can't be int, since there is not a shred of a guarantee that int \ is wide enough to hold a value of something to which pointer can \ be assigned */ \ active_reg_t this_reg; \ \ DEBUG_STATEMENT (failure_id++); \ DEBUG_STATEMENT (nfailure_points_pushed++); \ DEBUG_PRINT2 ("\nPUSH_FAILURE_POINT #%u:\n", failure_id); \ DEBUG_PRINT2 (" Before push, next avail: %d\n", (fail_stack).avail);\ DEBUG_PRINT2 (" size: %d\n", (fail_stack).size);\ \ DEBUG_PRINT2 (" slots needed: %ld\n", NUM_FAILURE_ITEMS); \ DEBUG_PRINT2 (" available: %d\n", REMAINING_AVAIL_SLOTS); \ \ /* Ensure we have enough space allocated for what we will push. */ \ while (REMAINING_AVAIL_SLOTS < NUM_FAILURE_ITEMS) \ { \ if (!DOUBLE_FAIL_STACK (fail_stack)) \ return failure_code; \ \ DEBUG_PRINT2 ("\n Doubled stack; size now: %d\n", \ (fail_stack).size); \ DEBUG_PRINT2 (" slots available: %d\n", REMAINING_AVAIL_SLOTS);\ } \ \ /* Push the info, starting with the registers. */ \ DEBUG_PRINT1 ("\n"); \ \ if (1) \ for (this_reg = lowest_active_reg; this_reg <= highest_active_reg; \ this_reg++) \ { \ DEBUG_PRINT2 (" Pushing reg: %lu\n", this_reg); \ DEBUG_STATEMENT (num_regs_pushed++); \ \ DEBUG_PRINT2 (" start: %p\n", regstart[this_reg]); \ PUSH_FAILURE_POINTER (regstart[this_reg]); \ \ DEBUG_PRINT2 (" end: %p\n", regend[this_reg]); \ PUSH_FAILURE_POINTER (regend[this_reg]); \ \ DEBUG_PRINT2 (" info: %p\n ", \ reg_info[this_reg].word.pointer); \ DEBUG_PRINT2 (" match_null=%d", \ REG_MATCH_NULL_STRING_P (reg_info[this_reg])); \ DEBUG_PRINT2 (" active=%d", IS_ACTIVE (reg_info[this_reg])); \ DEBUG_PRINT2 (" matched_something=%d", \ MATCHED_SOMETHING (reg_info[this_reg])); \ DEBUG_PRINT2 (" ever_matched=%d", \ EVER_MATCHED_SOMETHING (reg_info[this_reg])); \ DEBUG_PRINT1 ("\n"); \ PUSH_FAILURE_ELT (reg_info[this_reg].word); \ } \ \ DEBUG_PRINT2 (" Pushing low active reg: %ld\n", lowest_active_reg);\ PUSH_FAILURE_INT (lowest_active_reg); \ \ DEBUG_PRINT2 (" Pushing high active reg: %ld\n", highest_active_reg);\ PUSH_FAILURE_INT (highest_active_reg); \ \ DEBUG_PRINT2 (" Pushing pattern %p:\n", pattern_place); \ DEBUG_PRINT_COMPILED_PATTERN (bufp, pattern_place, pend); \ PUSH_FAILURE_POINTER (pattern_place); \ \ DEBUG_PRINT2 (" Pushing string %p: `", string_place); \ DEBUG_PRINT_DOUBLE_STRING (string_place, string1, size1, string2, \ size2); \ DEBUG_PRINT1 ("'\n"); \ PUSH_FAILURE_POINTER (string_place); \ \ DEBUG_PRINT2 (" Pushing failure id: %u\n", failure_id); \ DEBUG_PUSH (failure_id); \ } while (0) /* This is the number of items that are pushed and popped on the stack for each register. */ #define NUM_REG_ITEMS 3 /* Individual items aside from the registers. */ #ifdef DEBUG # define NUM_NONREG_ITEMS 5 /* Includes failure point id. */ #else # define NUM_NONREG_ITEMS 4 #endif /* We push at most this many items on the stack. */ /* We used to use (num_regs - 1), which is the number of registers this regexp will save; but that was changed to 5 to avoid stack overflow for a regexp with lots of parens. */ #define MAX_FAILURE_ITEMS (5 * NUM_REG_ITEMS + NUM_NONREG_ITEMS) /* We actually push this many items. */ #define NUM_FAILURE_ITEMS \ (((0 \ ? 0 : highest_active_reg - lowest_active_reg + 1) \ * NUM_REG_ITEMS) \ + NUM_NONREG_ITEMS) /* How many items can still be added to the stack without overflowing it. */ #define REMAINING_AVAIL_SLOTS ((fail_stack).size - (fail_stack).avail) /* Pops what PUSH_FAIL_STACK pushes. We restore into the parameters, all of which should be lvalues: STR -- the saved data position. PAT -- the saved pattern position. LOW_REG, HIGH_REG -- the highest and lowest active registers. REGSTART, REGEND -- arrays of string positions. REG_INFO -- array of information about each subexpression. Also assumes the variables `fail_stack' and (if debugging), `bufp', `pend', `string1', `size1', `string2', and `size2'. */ #define POP_FAILURE_POINT(str, pat, low_reg, high_reg, regstart, regend, reg_info)\ { \ DEBUG_STATEMENT (unsigned failure_id;) \ active_reg_t this_reg; \ const unsigned char *string_temp; \ \ assert (!FAIL_STACK_EMPTY ()); \ \ /* Remove failure points and point to how many regs pushed. */ \ DEBUG_PRINT1 ("POP_FAILURE_POINT:\n"); \ DEBUG_PRINT2 (" Before pop, next avail: %d\n", fail_stack.avail); \ DEBUG_PRINT2 (" size: %d\n", fail_stack.size); \ \ assert (fail_stack.avail >= NUM_NONREG_ITEMS); \ \ DEBUG_POP (&failure_id); \ DEBUG_PRINT2 (" Popping failure id: %u\n", failure_id); \ \ /* If the saved string location is NULL, it came from an \ on_failure_keep_string_jump opcode, and we want to throw away the \ saved NULL, thus retaining our current position in the string. */ \ string_temp = POP_FAILURE_POINTER (); \ if (string_temp != NULL) \ str = (const char *) string_temp; \ \ DEBUG_PRINT2 (" Popping string %p: `", str); \ DEBUG_PRINT_DOUBLE_STRING (str, string1, size1, string2, size2); \ DEBUG_PRINT1 ("'\n"); \ \ pat = (unsigned char *) POP_FAILURE_POINTER (); \ DEBUG_PRINT2 (" Popping pattern %p:\n", pat); \ DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend); \ \ /* Restore register info. */ \ high_reg = (active_reg_t) POP_FAILURE_INT (); \ DEBUG_PRINT2 (" Popping high active reg: %ld\n", high_reg); \ \ low_reg = (active_reg_t) POP_FAILURE_INT (); \ DEBUG_PRINT2 (" Popping low active reg: %ld\n", low_reg); \ \ if (1) \ for (this_reg = high_reg; this_reg >= low_reg; this_reg--) \ { \ DEBUG_PRINT2 (" Popping reg: %ld\n", this_reg); \ \ reg_info[this_reg].word = POP_FAILURE_ELT (); \ DEBUG_PRINT2 (" info: %p\n", \ reg_info[this_reg].word.pointer); \ \ regend[this_reg] = (const char *) POP_FAILURE_POINTER (); \ DEBUG_PRINT2 (" end: %p\n", regend[this_reg]); \ \ regstart[this_reg] = (const char *) POP_FAILURE_POINTER (); \ DEBUG_PRINT2 (" start: %p\n", regstart[this_reg]); \ } \ else \ { \ for (this_reg = highest_active_reg; this_reg > high_reg; this_reg--) \ { \ reg_info[this_reg].word.integer = 0; \ regend[this_reg] = 0; \ regstart[this_reg] = 0; \ } \ highest_active_reg = high_reg; \ } \ \ set_regs_matched_done = 0; \ DEBUG_STATEMENT (nfailure_points_popped++); \ } /* POP_FAILURE_POINT */ /* Structure for per-register (a.k.a. per-group) information. Other register information, such as the starting and ending positions (which are addresses), and the list of inner groups (which is a bits list) are maintained in separate variables. We are making a (strictly speaking) nonportable assumption here: that the compiler will pack our bit fields into something that fits into the type of `word', i.e., is something that fits into one item on the failure stack. */ /* Declarations and macros for re_match_2. */ typedef union { fail_stack_elt_t word; struct { /* This field is one if this group can match the empty string, zero if not. If not yet determined, `MATCH_NULL_UNSET_VALUE'. */ #define MATCH_NULL_UNSET_VALUE 3 unsigned match_null_string_p : 2; unsigned is_active : 1; unsigned matched_something : 1; unsigned ever_matched_something : 1; } bits; } register_info_type; #define REG_MATCH_NULL_STRING_P(R) ((R).bits.match_null_string_p) #define IS_ACTIVE(R) ((R).bits.is_active) #define MATCHED_SOMETHING(R) ((R).bits.matched_something) #define EVER_MATCHED_SOMETHING(R) ((R).bits.ever_matched_something) /* Call this when have matched a real character; it sets `matched' flags for the subexpressions which we are currently inside. Also records that those subexprs have matched. */ #define SET_REGS_MATCHED() \ do \ { \ if (!set_regs_matched_done) \ { \ active_reg_t r; \ set_regs_matched_done = 1; \ for (r = lowest_active_reg; r <= highest_active_reg; r++) \ { \ MATCHED_SOMETHING (reg_info[r]) \ = EVER_MATCHED_SOMETHING (reg_info[r]) \ = 1; \ } \ } \ } \ while (0) /* Registers are set to a sentinel when they haven't yet matched. */ static char reg_unset_dummy; #define REG_UNSET_VALUE (®_unset_dummy) #define REG_UNSET(e) ((e) == REG_UNSET_VALUE) /* Subroutine declarations and macros for regex_compile. */ static reg_errcode_t regex_compile _RE_ARGS ((const char *pattern, size_t size, reg_syntax_t syntax, struct re_pattern_buffer *bufp)); static void store_op1 _RE_ARGS ((re_opcode_t op, unsigned char *loc, int arg)); static void store_op2 _RE_ARGS ((re_opcode_t op, unsigned char *loc, int arg1, int arg2)); static void insert_op1 _RE_ARGS ((re_opcode_t op, unsigned char *loc, int arg, unsigned char *end)); static void insert_op2 _RE_ARGS ((re_opcode_t op, unsigned char *loc, int arg1, int arg2, unsigned char *end)); static char at_begline_loc_p _RE_ARGS ((const char *pattern, const char *p, reg_syntax_t syntax)); static char at_endline_loc_p _RE_ARGS ((const char *p, const char *pend, reg_syntax_t syntax)); static reg_errcode_t compile_range _RE_ARGS ((const char **p_ptr, const char *pend, char *translate, reg_syntax_t syntax, unsigned char *b)); /* Fetch the next character in the uncompiled pattern---translating it if necessary. Also cast from a signed character in the constant string passed to us by the user to an unsigned char that we can use as an array index (in, e.g., `translate'). */ #ifndef PATFETCH # define PATFETCH(c) \ do {if (p == pend) return REG_EEND; \ c = (unsigned char) *p++; \ if (translate) c = (unsigned char) translate[c]; \ } while (0) #endif /* Fetch the next character in the uncompiled pattern, with no translation. */ #define PATFETCH_RAW(c) \ do {if (p == pend) return REG_EEND; \ c = (unsigned char) *p++; \ } while (0) /* Go backwards one character in the pattern. */ #define PATUNFETCH p-- /* If `translate' is non-null, return translate[D], else just D. We cast the subscript to translate because some data is declared as `char *', to avoid warnings when a string constant is passed. But when we use a character as a subscript we must make it unsigned. */ #ifndef TRANSLATE # define TRANSLATE(d) \ (translate ? (char) translate[(unsigned char) (d)] : (d)) #endif /* Macros for outputting the compiled pattern into `buffer'. */ /* If the buffer isn't allocated when it comes in, use this. */ #define INIT_BUF_SIZE 32 /* Make sure we have at least N more bytes of space in buffer. */ #define GET_BUFFER_SPACE(n) \ while ((unsigned long) (b - bufp->buffer + (n)) > bufp->allocated) \ EXTEND_BUFFER () /* Make sure we have one more byte of buffer space and then add C to it. */ #define BUF_PUSH(c) \ do { \ GET_BUFFER_SPACE (1); \ *b++ = (unsigned char) (c); \ } while (0) /* Ensure we have two more bytes of buffer space and then append C1 and C2. */ #define BUF_PUSH_2(c1, c2) \ do { \ GET_BUFFER_SPACE (2); \ *b++ = (unsigned char) (c1); \ *b++ = (unsigned char) (c2); \ } while (0) /* As with BUF_PUSH_2, except for three bytes. */ #define BUF_PUSH_3(c1, c2, c3) \ do { \ GET_BUFFER_SPACE (3); \ *b++ = (unsigned char) (c1); \ *b++ = (unsigned char) (c2); \ *b++ = (unsigned char) (c3); \ } while (0) /* Store a jump with opcode OP at LOC to location TO. We store a relative address offset by the three bytes the jump itself occupies. */ #define STORE_JUMP(op, loc, to) \ store_op1 (op, loc, (int) ((to) - (loc) - 3)) /* Likewise, for a two-argument jump. */ #define STORE_JUMP2(op, loc, to, arg) \ store_op2 (op, loc, (int) ((to) - (loc) - 3), arg) /* Like `STORE_JUMP', but for inserting. Assume `b' is the buffer end. */ #define INSERT_JUMP(op, loc, to) \ insert_op1 (op, loc, (int) ((to) - (loc) - 3), b) /* Like `STORE_JUMP2', but for inserting. Assume `b' is the buffer end. */ #define INSERT_JUMP2(op, loc, to, arg) \ insert_op2 (op, loc, (int) ((to) - (loc) - 3), arg, b) /* This is not an arbitrary limit: the arguments which represent offsets into the pattern are two bytes long. So if 2^16 bytes turns out to be too small, many things would have to change. */ /* Any other compiler which, like MSC, has allocation limit below 2^16 bytes will have to use approach similar to what was done below for MSC and drop MAX_BUF_SIZE a bit. Otherwise you may end up reallocating to 0 bytes. Such thing is not going to work too well. You have been warned!! */ #if defined _MSC_VER && !defined WIN32 /* Microsoft C 16-bit versions limit malloc to approx 65512 bytes. The REALLOC define eliminates a flurry of conversion warnings, but is not required. */ # define MAX_BUF_SIZE 65500L # define REALLOC(p,s) realloc ((p), (size_t) (s)) #else # define MAX_BUF_SIZE (1L << 16) # define REALLOC(p,s) realloc ((p), (s)) #endif /* Extend the buffer by twice its current size via realloc and reset the pointers that pointed into the old block to point to the correct places in the new one. If extending the buffer results in it being larger than MAX_BUF_SIZE, then flag memory exhausted. */ #define EXTEND_BUFFER() \ do { \ unsigned char *old_buffer = bufp->buffer; \ if (bufp->allocated == MAX_BUF_SIZE) \ return REG_ESIZE; \ bufp->allocated <<= 1; \ if (bufp->allocated > MAX_BUF_SIZE) \ bufp->allocated = MAX_BUF_SIZE; \ bufp->buffer = (unsigned char *) REALLOC (bufp->buffer, bufp->allocated);\ if (bufp->buffer == NULL) \ return REG_ESPACE; \ /* If the buffer moved, move all the pointers into it. */ \ if (old_buffer != bufp->buffer) \ { \ b = (b - old_buffer) + bufp->buffer; \ begalt = (begalt - old_buffer) + bufp->buffer; \ if (fixup_alt_jump) \ fixup_alt_jump = (fixup_alt_jump - old_buffer) + bufp->buffer;\ if (laststart) \ laststart = (laststart - old_buffer) + bufp->buffer; \ if (pending_exact) \ pending_exact = (pending_exact - old_buffer) + bufp->buffer; \ } \ } while (0) /* Since we have one byte reserved for the register number argument to {start,stop}_memory, the maximum number of groups we can report things about is what fits in that byte. */ #define MAX_REGNUM 255 /* But patterns can have more than `MAX_REGNUM' registers. We just ignore the excess. */ typedef unsigned regnum_t; /* Macros for the compile stack. */ /* Since offsets can go either forwards or backwards, this type needs to be able to hold values from -(MAX_BUF_SIZE - 1) to MAX_BUF_SIZE - 1. */ /* int may be not enough when sizeof(int) == 2. */ typedef long pattern_offset_t; typedef struct { pattern_offset_t begalt_offset; pattern_offset_t fixup_alt_jump; pattern_offset_t inner_group_offset; pattern_offset_t laststart_offset; regnum_t regnum; } compile_stack_elt_t; typedef struct { compile_stack_elt_t *stack; unsigned size; unsigned avail; /* Offset of next open position. */ } compile_stack_type; #define INIT_COMPILE_STACK_SIZE 32 #define COMPILE_STACK_EMPTY (compile_stack.avail == 0) #define COMPILE_STACK_FULL (compile_stack.avail == compile_stack.size) /* The next available element. */ #define COMPILE_STACK_TOP (compile_stack.stack[compile_stack.avail]) /* Set the bit for character C in a list. */ #define SET_LIST_BIT(c) \ (b[((unsigned char) (c)) / BYTEWIDTH] \ |= 1 << (((unsigned char) c) % BYTEWIDTH)) /* Get the next unsigned number in the uncompiled pattern. */ #define GET_UNSIGNED_NUMBER(num) \ { if (p != pend) \ { \ PATFETCH (c); \ while (ISDIGIT (c)) \ { \ if (num < 0) \ num = 0; \ num = num * 10 + c - '0'; \ if (p == pend) \ break; \ PATFETCH (c); \ } \ } \ } #if defined _LIBC || WIDE_CHAR_SUPPORT /* The GNU C library provides support for user-defined character classes and the functions from ISO C amendement 1. */ # ifdef CHARCLASS_NAME_MAX # define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX # else /* This shouldn't happen but some implementation might still have this problem. Use a reasonable default value. */ # define CHAR_CLASS_MAX_LENGTH 256 # endif # ifdef _LIBC # define IS_CHAR_CLASS(string) __wctype (string) # else # define IS_CHAR_CLASS(string) wctype (string) # endif #else # define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */ # define IS_CHAR_CLASS(string) \ (STREQ (string, "alpha") || STREQ (string, "upper") \ || STREQ (string, "lower") || STREQ (string, "digit") \ || STREQ (string, "alnum") || STREQ (string, "xdigit") \ || STREQ (string, "space") || STREQ (string, "print") \ || STREQ (string, "punct") || STREQ (string, "graph") \ || STREQ (string, "cntrl") || STREQ (string, "blank")) #endif #ifndef MATCH_MAY_ALLOCATE /* If we cannot allocate large objects within re_match_2_internal, we make the fail stack and register vectors global. The fail stack, we grow to the maximum size when a regexp is compiled. The register vectors, we adjust in size each time we compile a regexp, according to the number of registers it needs. */ static fail_stack_type fail_stack; /* Size with which the following vectors are currently allocated. That is so we can make them bigger as needed, but never make them smaller. */ static int regs_allocated_size; static const char ** regstart, ** regend; static const char ** old_regstart, ** old_regend; static const char **best_regstart, **best_regend; static register_info_type *reg_info; static const char **reg_dummy; static register_info_type *reg_info_dummy; /* Make the register vectors big enough for NUM_REGS registers, but don't make them smaller. */ static regex_grow_registers (num_regs) int num_regs; { if (num_regs > regs_allocated_size) { RETALLOC_IF (regstart, num_regs, const char *); RETALLOC_IF (regend, num_regs, const char *); RETALLOC_IF (old_regstart, num_regs, const char *); RETALLOC_IF (old_regend, num_regs, const char *); RETALLOC_IF (best_regstart, num_regs, const char *); RETALLOC_IF (best_regend, num_regs, const char *); RETALLOC_IF (reg_info, num_regs, register_info_type); RETALLOC_IF (reg_dummy, num_regs, const char *); RETALLOC_IF (reg_info_dummy, num_regs, register_info_type); regs_allocated_size = num_regs; } } #endif /* not MATCH_MAY_ALLOCATE */ static char group_in_compile_stack _RE_ARGS ((compile_stack_type compile_stack, regnum_t regnum)); /* `regex_compile' compiles PATTERN (of length SIZE) according to SYNTAX. Returns one of error codes defined in `regex.h', or zero for success. Assumes the `allocated' (and perhaps `buffer') and `translate' fields are set in BUFP on entry. If it succeeds, results are put in BUFP (if it returns an error, the contents of BUFP are undefined): `buffer' is the compiled pattern; `syntax' is set to SYNTAX; `used' is set to the length of the compiled pattern; `fastmap_accurate' is zero; `re_nsub' is the number of subexpressions in PATTERN; `not_bol' and `not_eol' are zero; The `fastmap' and `newline_anchor' fields are neither examined nor set. */ /* Return, freeing storage we allocated. */ #define FREE_STACK_RETURN(value) \ return (free (compile_stack.stack), value) static reg_errcode_t regex_compile (pattern, size, syntax, bufp) const char *pattern; size_t size; reg_syntax_t syntax; struct re_pattern_buffer *bufp; { /* We fetch characters from PATTERN here. Even though PATTERN is `char *' (i.e., signed), we declare these variables as unsigned, so they can be reliably used as array indices. */ register unsigned char c, c1; /* A random temporary spot in PATTERN. */ const char *p1; /* Points to the end of the buffer, where we should append. */ register unsigned char *b; /* Keeps track of unclosed groups. */ compile_stack_type compile_stack; /* Points to the current (ending) position in the pattern. */ const char *p = pattern; const char *pend = pattern + size; /* How to translate the characters in the pattern. */ RE_TRANSLATE_TYPE translate = bufp->translate; /* Address of the count-byte of the most recently inserted `exactn' command. This makes it possible to tell if a new exact-match character can be added to that command or if the character requires a new `exactn' command. */ unsigned char *pending_exact = 0; /* Address of start of the most recently finished expression. This tells, e.g., postfix * where to find the start of its operand. Reset at the beginning of groups and alternatives. */ unsigned char *laststart = 0; /* Address of beginning of regexp, or inside of last group. */ unsigned char *begalt; /* Place in the uncompiled pattern (i.e., the {) to which to go back if the interval is invalid. */ const char *beg_interval; /* Address of the place where a forward jump should go to the end of the containing expression. Each alternative of an `or' -- except the last -- ends with a forward jump of this sort. */ unsigned char *fixup_alt_jump = 0; /* Counts open-groups as they are encountered. Remembered for the matching close-group on the compile stack, so the same register number is put in the stop_memory as the start_memory. */ regnum_t regnum = 0; #ifdef DEBUG DEBUG_PRINT1 ("\nCompiling pattern: "); if (debug) { unsigned debug_count; for (debug_count = 0; debug_count < size; debug_count++) putchar (pattern[debug_count]); putchar ('\n'); } #endif /* DEBUG */ /* Initialize the compile stack. */ compile_stack.stack = TALLOC (INIT_COMPILE_STACK_SIZE, compile_stack_elt_t); if (compile_stack.stack == NULL) return REG_ESPACE; compile_stack.size = INIT_COMPILE_STACK_SIZE; compile_stack.avail = 0; /* Initialize the pattern buffer. */ bufp->syntax = syntax; bufp->fastmap_accurate = 0; bufp->not_bol = bufp->not_eol = 0; /* Set `used' to zero, so that if we return an error, the pattern printer (for debugging) will think there's no pattern. We reset it at the end. */ bufp->used = 0; /* Always count groups, whether or not bufp->no_sub is set. */ bufp->re_nsub = 0; #if !defined emacs && !defined SYNTAX_TABLE /* Initialize the syntax table. */ init_syntax_once (); #endif if (bufp->allocated == 0) { if (bufp->buffer) { /* If zero allocated, but buffer is non-null, try to realloc enough space. This loses if buffer's address is bogus, but that is the user's responsibility. */ RETALLOC (bufp->buffer, INIT_BUF_SIZE, unsigned char); } else { /* Caller did not allocate a buffer. Do it for them. */ bufp->buffer = TALLOC (INIT_BUF_SIZE, unsigned char); } if (!bufp->buffer) FREE_STACK_RETURN (REG_ESPACE); bufp->allocated = INIT_BUF_SIZE; } begalt = b = bufp->buffer; /* Loop through the uncompiled pattern until we're at the end. */ while (p != pend) { PATFETCH (c); switch (c) { case '^': { if ( /* If at start of pattern, it's an operator. */ p == pattern + 1 /* If context independent, it's an operator. */ || syntax & RE_CONTEXT_INDEP_ANCHORS /* Otherwise, depends on what's come before. */ || at_begline_loc_p (pattern, p, syntax)) BUF_PUSH (begline); else goto normal_char; } break; case '$': { if ( /* If at end of pattern, it's an operator. */ p == pend /* If context independent, it's an operator. */ || syntax & RE_CONTEXT_INDEP_ANCHORS /* Otherwise, depends on what's next. */ || at_endline_loc_p (p, pend, syntax)) BUF_PUSH (endline); else goto normal_char; } break; case '+': case '?': if ((syntax & RE_BK_PLUS_QM) || (syntax & RE_LIMITED_OPS)) goto normal_char; handle_plus: case '*': /* If there is no previous pattern... */ if (!laststart) { if (syntax & RE_CONTEXT_INVALID_OPS) FREE_STACK_RETURN (REG_BADRPT); else if (!(syntax & RE_CONTEXT_INDEP_OPS)) goto normal_char; } { /* Are we optimizing this jump? */ char keep_string_p = false; /* 1 means zero (many) matches is allowed. */ char zero_times_ok = 0, many_times_ok = 0; /* If there is a sequence of repetition chars, collapse it down to just one (the right one). We can't combine interval operators with these because of, e.g., `a{2}*', which should only match an even number of `a's. */ for (;;) { zero_times_ok |= c != '+'; many_times_ok |= c != '?'; if (p == pend) break; PATFETCH (c); if (c == '*' || (!(syntax & RE_BK_PLUS_QM) && (c == '+' || c == '?'))) ; else if (syntax & RE_BK_PLUS_QM && c == '\\') { if (p == pend) FREE_STACK_RETURN (REG_EESCAPE); PATFETCH (c1); if (!(c1 == '+' || c1 == '?')) { PATUNFETCH; PATUNFETCH; break; } c = c1; } else { PATUNFETCH; break; } /* If we get here, we found another repeat character. */ } /* Star, etc. applied to an empty pattern is equivalent to an empty pattern. */ if (!laststart) break; /* Now we know whether or not zero matches is allowed and also whether or not two or more matches is allowed. */ if (many_times_ok) { /* More than one repetition is allowed, so put in at the end a backward relative jump from `b' to before the next jump we're going to put in below (which jumps from laststart to after this jump). But if we are at the `*' in the exact sequence `.*\n', insert an unconditional jump backwards to the ., instead of the beginning of the loop. This way we only push a failure point once, instead of every time through the loop. */ assert (p - 1 > pattern); /* Allocate the space for the jump. */ GET_BUFFER_SPACE (3); /* We know we are not at the first character of the pattern, because laststart was nonzero. And we've already incremented `p', by the way, to be the character after the `*'. Do we have to do something analogous here for null bytes, because of RE_DOT_NOT_NULL? */ if (TRANSLATE (*(p - 2)) == TRANSLATE ('.') && zero_times_ok && p < pend && TRANSLATE (*p) == TRANSLATE ('\n') && !(syntax & RE_DOT_NEWLINE)) { /* We have .*\n. */ STORE_JUMP (jump, b, laststart); keep_string_p = true; } else /* Anything else. */ STORE_JUMP (maybe_pop_jump, b, laststart - 3); /* We've added more stuff to the buffer. */ b += 3; } /* On failure, jump from laststart to b + 3, which will be the end of the buffer after this jump is inserted. */ GET_BUFFER_SPACE (3); INSERT_JUMP (keep_string_p ? on_failure_keep_string_jump : on_failure_jump, laststart, b + 3); pending_exact = 0; b += 3; if (!zero_times_ok) { /* At least one repetition is required, so insert a `dummy_failure_jump' before the initial `on_failure_jump' instruction of the loop. This effects a skip over that instruction the first time we hit that loop. */ GET_BUFFER_SPACE (3); INSERT_JUMP (dummy_failure_jump, laststart, laststart + 6); b += 3; } } break; case '.': laststart = b; BUF_PUSH (anychar); break; case '[': { char had_char_class = false; if (p == pend) FREE_STACK_RETURN (REG_EBRACK); /* Ensure that we have enough space to push a charset: the opcode, the length count, and the bitset; 34 bytes in all. */ GET_BUFFER_SPACE (34); laststart = b; /* We test `*p == '^' twice, instead of using an if statement, so we only need one BUF_PUSH. */ BUF_PUSH (*p == '^' ? charset_not : charset); if (*p == '^') p++; /* Remember the first position in the bracket expression. */ p1 = p; /* Push the number of bytes in the bitmap. */ BUF_PUSH ((1 << BYTEWIDTH) / BYTEWIDTH); /* Clear the whole map. */ bzero (b, (1 << BYTEWIDTH) / BYTEWIDTH); /* charset_not matches newline according to a syntax bit. */ if ((re_opcode_t) b[-2] == charset_not && (syntax & RE_HAT_LISTS_NOT_NEWLINE)) SET_LIST_BIT ('\n'); /* Read in characters and ranges, setting map bits. */ for (;;) { if (p == pend) FREE_STACK_RETURN (REG_EBRACK); PATFETCH (c); /* \ might escape characters inside [...] and [^...]. */ if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\') { if (p == pend) FREE_STACK_RETURN (REG_EESCAPE); PATFETCH (c1); SET_LIST_BIT (c1); continue; } /* Could be the end of the bracket expression. If it's not (i.e., when the bracket expression is `[]' so far), the ']' character bit gets set way below. */ if (c == ']' && p != p1 + 1) break; /* Look ahead to see if it's a range when the last thing was a character class. */ if (had_char_class && c == '-' && *p != ']') FREE_STACK_RETURN (REG_ERANGE); /* Look ahead to see if it's a range when the last thing was a character: if this is a hyphen not at the beginning or the end of a list, then it's the range operator. */ if (c == '-' && !(p - 2 >= pattern && p[-2] == '[') && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^') && *p != ']') { reg_errcode_t ret = compile_range (&p, pend, translate, syntax, b); if (ret != REG_NOERROR) FREE_STACK_RETURN (ret); } else if (p[0] == '-' && p[1] != ']') { /* This handles ranges made up of characters only. */ reg_errcode_t ret; /* Move past the `-'. */ PATFETCH (c1); ret = compile_range (&p, pend, translate, syntax, b); if (ret != REG_NOERROR) FREE_STACK_RETURN (ret); } /* See if we're at the beginning of a possible character class. */ else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == ':') { /* Leave room for the null. */ char str[CHAR_CLASS_MAX_LENGTH + 1]; PATFETCH (c); c1 = 0; /* If pattern is `[[:'. */ if (p == pend) FREE_STACK_RETURN (REG_EBRACK); for (;;) { PATFETCH (c); if ((c == ':' && *p == ']') || p == pend) break; if (c1 < CHAR_CLASS_MAX_LENGTH) str[c1++] = c; else /* This is in any case an invalid class name. */ str[0] = '\0'; } str[c1] = '\0'; /* If isn't a word bracketed by `[:' and `:]': undo the ending character, the letters, and leave the leading `:' and `[' (but set bits for them). */ if (c == ':' && *p == ']') { #if defined _LIBC || WIDE_CHAR_SUPPORT char is_lower = STREQ (str, "lower"); char is_upper = STREQ (str, "upper"); wctype_t wt; int ch; wt = IS_CHAR_CLASS (str); if (wt == 0) FREE_STACK_RETURN (REG_ECTYPE); /* Throw away the ] at the end of the character class. */ PATFETCH (c); if (p == pend) FREE_STACK_RETURN (REG_EBRACK); for (ch = 0; ch < 1 << BYTEWIDTH; ++ch) { # ifdef _LIBC if (__iswctype (__btowc (ch), wt)) SET_LIST_BIT (ch); # else if (iswctype (btowc (ch), wt)) SET_LIST_BIT (ch); # endif if (translate && (is_upper || is_lower) && (ISUPPER (ch) || ISLOWER (ch))) SET_LIST_BIT (ch); } had_char_class = true; #else int ch; char is_alnum = STREQ (str, "alnum"); char is_alpha = STREQ (str, "alpha"); char is_blank = STREQ (str, "blank"); char is_cntrl = STREQ (str, "cntrl"); char is_digit = STREQ (str, "digit"); char is_graph = STREQ (str, "graph"); char is_lower = STREQ (str, "lower"); char is_print = STREQ (str, "print"); char is_punct = STREQ (str, "punct"); char is_space = STREQ (str, "space"); char is_upper = STREQ (str, "upper"); char is_xdigit = STREQ (str, "xdigit"); if (!IS_CHAR_CLASS (str)) FREE_STACK_RETURN (REG_ECTYPE); /* Throw away the ] at the end of the character class. */ PATFETCH (c); if (p == pend) FREE_STACK_RETURN (REG_EBRACK); for (ch = 0; ch < 1 << BYTEWIDTH; ch++) { /* This was split into 3 if's to avoid an arbitrary limit in some compiler. */ if ( (is_alnum && ISALNUM (ch)) || (is_alpha && ISALPHA (ch)) || (is_blank && ISBLANK (ch)) || (is_cntrl && ISCNTRL (ch))) SET_LIST_BIT (ch); if ( (is_digit && ISDIGIT (ch)) || (is_graph && ISGRAPH (ch)) || (is_lower && ISLOWER (ch)) || (is_print && ISPRINT (ch))) SET_LIST_BIT (ch); if ( (is_punct && ISPUNCT (ch)) || (is_space && ISSPACE (ch)) || (is_upper && ISUPPER (ch)) || (is_xdigit && ISXDIGIT (ch))) SET_LIST_BIT (ch); if ( translate && (is_upper || is_lower) && (ISUPPER (ch) || ISLOWER (ch))) SET_LIST_BIT (ch); } had_char_class = true; #endif /* libc || wctype.h */ } else { c1++; while (c1--) PATUNFETCH; SET_LIST_BIT ('['); SET_LIST_BIT (':'); had_char_class = false; } } else { had_char_class = false; SET_LIST_BIT (c); } } /* Discard any (non)matching list bytes that are all 0 at the end of the map. Decrease the map-length byte too. */ while ((int) b[-1] > 0 && b[b[-1] - 1] == 0) b[-1]--; b += b[-1]; } break; case '(': if (syntax & RE_NO_BK_PARENS) goto handle_open; else goto normal_char; case ')': if (syntax & RE_NO_BK_PARENS) goto handle_close; else goto normal_char; case '\n': if (syntax & RE_NEWLINE_ALT) goto handle_alt; else goto normal_char; case '|': if (syntax & RE_NO_BK_VBAR) goto handle_alt; else goto normal_char; case '{': if (syntax & RE_INTERVALS && syntax & RE_NO_BK_BRACES) goto handle_interval; else goto normal_char; case '\\': if (p == pend) FREE_STACK_RETURN (REG_EESCAPE); /* Do not translate the character after the \, so that we can distinguish, e.g., \B from \b, even if we normally would translate, e.g., B to b. */ PATFETCH_RAW (c); switch (c) { case '(': if (syntax & RE_NO_BK_PARENS) goto normal_backslash; handle_open: bufp->re_nsub++; regnum++; if (COMPILE_STACK_FULL) { RETALLOC (compile_stack.stack, compile_stack.size << 1, compile_stack_elt_t); if (compile_stack.stack == NULL) return REG_ESPACE; compile_stack.size <<= 1; } /* These are the values to restore when we hit end of this group. They are all relative offsets, so that if the whole pattern moves because of realloc, they will still be valid. */ COMPILE_STACK_TOP.begalt_offset = begalt - bufp->buffer; COMPILE_STACK_TOP.fixup_alt_jump = fixup_alt_jump ? fixup_alt_jump - bufp->buffer + 1 : 0; COMPILE_STACK_TOP.laststart_offset = b - bufp->buffer; COMPILE_STACK_TOP.regnum = regnum; /* We will eventually replace the 0 with the number of groups inner to this one. But do not push a start_memory for groups beyond the last one we can represent in the compiled pattern. */ if (regnum <= MAX_REGNUM) { COMPILE_STACK_TOP.inner_group_offset = b - bufp->buffer + 2; BUF_PUSH_3 (start_memory, regnum, 0); } compile_stack.avail++; fixup_alt_jump = 0; laststart = 0; begalt = b; /* If we've reached MAX_REGNUM groups, then this open won't actually generate any code, so we'll have to clear pending_exact explicitly. */ pending_exact = 0; break; case ')': if (syntax & RE_NO_BK_PARENS) goto normal_backslash; if (COMPILE_STACK_EMPTY) { if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD) goto normal_backslash; else FREE_STACK_RETURN (REG_ERPAREN); } handle_close: if (fixup_alt_jump) { /* Push a dummy failure point at the end of the alternative for a possible future `pop_failure_jump' to pop. See comments at `push_dummy_failure' in `re_match_2'. */ BUF_PUSH (push_dummy_failure); /* We allocated space for this jump when we assigned to `fixup_alt_jump', in the `handle_alt' case below. */ STORE_JUMP (jump_past_alt, fixup_alt_jump, b - 1); } /* See similar code for backslashed left paren above. */ if (COMPILE_STACK_EMPTY) { if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD) goto normal_char; else FREE_STACK_RETURN (REG_ERPAREN); } /* Since we just checked for an empty stack above, this ``can't happen''. */ assert (compile_stack.avail != 0); { /* We don't just want to restore into `regnum', because later groups should continue to be numbered higher, as in `(ab)c(de)' -- the second group is #2. */ regnum_t this_group_regnum; compile_stack.avail--; begalt = bufp->buffer + COMPILE_STACK_TOP.begalt_offset; fixup_alt_jump = COMPILE_STACK_TOP.fixup_alt_jump ? bufp->buffer + COMPILE_STACK_TOP.fixup_alt_jump - 1 : 0; laststart = bufp->buffer + COMPILE_STACK_TOP.laststart_offset; this_group_regnum = COMPILE_STACK_TOP.regnum; /* If we've reached MAX_REGNUM groups, then this open won't actually generate any code, so we'll have to clear pending_exact explicitly. */ pending_exact = 0; /* We're at the end of the group, so now we know how many groups were inside this one. */ if (this_group_regnum <= MAX_REGNUM) { unsigned char *inner_group_loc = bufp->buffer + COMPILE_STACK_TOP.inner_group_offset; *inner_group_loc = regnum - this_group_regnum; BUF_PUSH_3 (stop_memory, this_group_regnum, regnum - this_group_regnum); } } break; case '|': /* `\|'. */ if (syntax & RE_LIMITED_OPS || syntax & RE_NO_BK_VBAR) goto normal_backslash; handle_alt: if (syntax & RE_LIMITED_OPS) goto normal_char; /* Insert before the previous alternative a jump which jumps to this alternative if the former fails. */ GET_BUFFER_SPACE (3); INSERT_JUMP (on_failure_jump, begalt, b + 6); pending_exact = 0; b += 3; /* The alternative before this one has a jump after it which gets executed if it gets matched. Adjust that jump so it will jump to this alternative's analogous jump (put in below, which in turn will jump to the next (if any) alternative's such jump, etc.). The last such jump jumps to the correct final destination. A picture: _____ _____ | | | | | v | v a | b | c If we are at `b', then fixup_alt_jump right now points to a three-byte space after `a'. We'll put in the jump, set fixup_alt_jump to right after `b', and leave behind three bytes which we'll fill in when we get to after `c'. */ if (fixup_alt_jump) STORE_JUMP (jump_past_alt, fixup_alt_jump, b); /* Mark and leave space for a jump after this alternative, to be filled in later either by next alternative or when know we're at the end of a series of alternatives. */ fixup_alt_jump = b; GET_BUFFER_SPACE (3); b += 3; laststart = 0; begalt = b; break; case '{': /* If \{ is a literal. */ if (!(syntax & RE_INTERVALS) /* If we're at `\{' and it's not the open-interval operator. */ || ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES)) || (p - 2 == pattern && p == pend)) goto normal_backslash; handle_interval: { /* If got here, then the syntax allows intervals. */ /* At least (most) this many matches must be made. */ int lower_bound = -1, upper_bound = -1; beg_interval = p - 1; if (p == pend) { if (syntax & RE_NO_BK_BRACES) goto unfetch_interval; else FREE_STACK_RETURN (REG_EBRACE); } GET_UNSIGNED_NUMBER (lower_bound); if (c == ',') { GET_UNSIGNED_NUMBER (upper_bound); if (upper_bound < 0) upper_bound = RE_DUP_MAX; } else /* Interval such as `{1}' => match exactly once. */ upper_bound = lower_bound; if (lower_bound < 0 || upper_bound > RE_DUP_MAX || lower_bound > upper_bound) { if (syntax & RE_NO_BK_BRACES) goto unfetch_interval; else FREE_STACK_RETURN (REG_BADBR); } if (!(syntax & RE_NO_BK_BRACES)) { if (c != '\\') FREE_STACK_RETURN (REG_EBRACE); PATFETCH (c); } if (c != '}') { if (syntax & RE_NO_BK_BRACES) goto unfetch_interval; else FREE_STACK_RETURN (REG_BADBR); } /* We just parsed a valid interval. */ /* If it's invalid to have no preceding re. */ if (!laststart) { if (syntax & RE_CONTEXT_INVALID_OPS) FREE_STACK_RETURN (REG_BADRPT); else if (syntax & RE_CONTEXT_INDEP_OPS) laststart = b; else goto unfetch_interval; } /* If the upper bound is zero, don't want to succeed at all; jump from `laststart' to `b + 3', which will be the end of the buffer after we insert the jump. */ if (upper_bound == 0) { GET_BUFFER_SPACE (3); INSERT_JUMP (jump, laststart, b + 3); b += 3; } /* Otherwise, we have a nontrivial interval. When we're all done, the pattern will look like: set_number_at set_number_at succeed_n jump_n (The upper bound and `jump_n' are omitted if `upper_bound' is 1, though.) */ else { /* If the upper bound is > 1, we need to insert more at the end of the loop. */ unsigned nbytes = 10 + (upper_bound > 1) * 10; GET_BUFFER_SPACE (nbytes); /* Initialize lower bound of the `succeed_n', even though it will be set during matching by its attendant `set_number_at' (inserted next), because `re_compile_fastmap' needs to know. Jump to the `jump_n' we might insert below. */ INSERT_JUMP2 (succeed_n, laststart, b + 5 + (upper_bound > 1) * 5, lower_bound); b += 5; /* Code to initialize the lower bound. Insert before the `succeed_n'. The `5' is the last two bytes of this `set_number_at', plus 3 bytes of the following `succeed_n'. */ insert_op2 (set_number_at, laststart, 5, lower_bound, b); b += 5; if (upper_bound > 1) { /* More than one repetition is allowed, so append a backward jump to the `succeed_n' that starts this interval. When we've reached this during matching, we'll have matched the interval once, so jump back only `upper_bound - 1' times. */ STORE_JUMP2 (jump_n, b, laststart + 5, upper_bound - 1); b += 5; /* The location we want to set is the second parameter of the `jump_n'; that is `b-2' as an absolute address. `laststart' will be the `set_number_at' we're about to insert; `laststart+3' the number to set, the source for the relative address. But we are inserting into the middle of the pattern -- so everything is getting moved up by 5. Conclusion: (b - 2) - (laststart + 3) + 5, i.e., b - laststart. We insert this at the beginning of the loop so that if we fail during matching, we'll reinitialize the bounds. */ insert_op2 (set_number_at, laststart, b - laststart, upper_bound - 1, b); b += 5; } } pending_exact = 0; beg_interval = NULL; } break; unfetch_interval: /* If an invalid interval, match the characters as literals. */ assert (beg_interval); p = beg_interval; beg_interval = NULL; /* normal_char and normal_backslash need `c'. */ PATFETCH (c); if (!(syntax & RE_NO_BK_BRACES)) { if (p > pattern && p[-1] == '\\') goto normal_backslash; } goto normal_char; #ifdef emacs /* There is no way to specify the before_dot and after_dot operators. rms says this is ok. --karl */ case '=': BUF_PUSH (at_dot); break; case 's': laststart = b; PATFETCH (c); BUF_PUSH_2 (syntaxspec, syntax_spec_code[c]); break; case 'S': laststart = b; PATFETCH (c); BUF_PUSH_2 (notsyntaxspec, syntax_spec_code[c]); break; #endif /* emacs */ case 'w': if (syntax & RE_NO_GNU_OPS) goto normal_char; laststart = b; BUF_PUSH (wordchar); break; case 'W': if (syntax & RE_NO_GNU_OPS) goto normal_char; laststart = b; BUF_PUSH (notwordchar); break; case '<': if (syntax & RE_NO_GNU_OPS) goto normal_char; BUF_PUSH (wordbeg); break; case '>': if (syntax & RE_NO_GNU_OPS) goto normal_char; BUF_PUSH (wordend); break; case 'b': if (syntax & RE_NO_GNU_OPS) goto normal_char; BUF_PUSH (wordbound); break; case 'B': if (syntax & RE_NO_GNU_OPS) goto normal_char; BUF_PUSH (notwordbound); break; case '`': if (syntax & RE_NO_GNU_OPS) goto normal_char; BUF_PUSH (begbuf); break; case '\'': if (syntax & RE_NO_GNU_OPS) goto normal_char; BUF_PUSH (endbuf); break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (syntax & RE_NO_BK_REFS) goto normal_char; c1 = c - '0'; if (c1 > regnum) FREE_STACK_RETURN (REG_ESUBREG); /* Can't back reference to a subexpression if inside of it. */ if (group_in_compile_stack (compile_stack, (regnum_t) c1)) goto normal_char; laststart = b; BUF_PUSH_2 (duplicate, c1); break; case '+': case '?': if (syntax & RE_BK_PLUS_QM) goto handle_plus; else goto normal_backslash; default: normal_backslash: /* You might think it would be useful for \ to mean not to translate; but if we don't translate it it will never match anything. */ c = TRANSLATE (c); goto normal_char; } break; default: /* Expects the character in `c'. */ normal_char: /* If no exactn currently being built. */ if (!pending_exact /* If last exactn not at current position. */ || pending_exact + *pending_exact + 1 != b /* We have only one byte following the exactn for the count. */ || *pending_exact == (1 << BYTEWIDTH) - 1 /* If followed by a repetition operator. */ || *p == '*' || *p == '^' || ((syntax & RE_BK_PLUS_QM) ? *p == '\\' && (p[1] == '+' || p[1] == '?') : (*p == '+' || *p == '?')) || ((syntax & RE_INTERVALS) && ((syntax & RE_NO_BK_BRACES) ? *p == '{' : (p[0] == '\\' && p[1] == '{')))) { /* Start building a new exactn. */ laststart = b; BUF_PUSH_2 (exactn, 0); pending_exact = b - 1; } BUF_PUSH (c); (*pending_exact)++; break; } /* switch (c) */ } /* while p != pend */ /* Through the pattern now. */ if (fixup_alt_jump) STORE_JUMP (jump_past_alt, fixup_alt_jump, b); if (!COMPILE_STACK_EMPTY) FREE_STACK_RETURN (REG_EPAREN); /* If we don't want backtracking, force success the first time we reach the end of the compiled pattern. */ if (syntax & RE_NO_POSIX_BACKTRACKING) BUF_PUSH (succeed); free (compile_stack.stack); /* We have succeeded; set the length of the buffer. */ bufp->used = b - bufp->buffer; #ifdef DEBUG if (debug) { DEBUG_PRINT1 ("\nCompiled pattern: \n"); print_compiled_pattern (bufp); } #endif /* DEBUG */ #ifndef MATCH_MAY_ALLOCATE /* Initialize the failure stack to the largest possible stack. This isn't necessary unless we're trying to avoid calling alloca in the search and match routines. */ { int num_regs = bufp->re_nsub + 1; /* Since DOUBLE_FAIL_STACK refuses to double only if the current size is strictly greater than re_max_failures, the largest possible stack is 2 * re_max_failures failure points. */ if (fail_stack.size < (2 * re_max_failures * MAX_FAILURE_ITEMS)) { fail_stack.size = (2 * re_max_failures * MAX_FAILURE_ITEMS); # ifdef emacs if (! fail_stack.stack) fail_stack.stack = (fail_stack_elt_t *) xmalloc (fail_stack.size * sizeof (fail_stack_elt_t)); else fail_stack.stack = (fail_stack_elt_t *) xrealloc (fail_stack.stack, (fail_stack.size * sizeof (fail_stack_elt_t))); # else /* not emacs */ if (! fail_stack.stack) fail_stack.stack = (fail_stack_elt_t *) malloc (fail_stack.size * sizeof (fail_stack_elt_t)); else fail_stack.stack = (fail_stack_elt_t *) realloc (fail_stack.stack, (fail_stack.size * sizeof (fail_stack_elt_t))); # endif /* not emacs */ } regex_grow_registers (num_regs); } #endif /* not MATCH_MAY_ALLOCATE */ return REG_NOERROR; } /* regex_compile */ /* Subroutines for `regex_compile'. */ /* Store OP at LOC followed by two-byte integer parameter ARG. */ static void store_op1 (op, loc, arg) re_opcode_t op; unsigned char *loc; int arg; { *loc = (unsigned char) op; STORE_NUMBER (loc + 1, arg); } /* Like `store_op1', but for two two-byte parameters ARG1 and ARG2. */ static void store_op2 (op, loc, arg1, arg2) re_opcode_t op; unsigned char *loc; int arg1, arg2; { *loc = (unsigned char) op; STORE_NUMBER (loc + 1, arg1); STORE_NUMBER (loc + 3, arg2); } /* Copy the bytes from LOC to END to open up three bytes of space at LOC for OP followed by two-byte integer parameter ARG. */ static void insert_op1 (op, loc, arg, end) re_opcode_t op; unsigned char *loc; int arg; unsigned char *end; { register unsigned char *pfrom = end; register unsigned char *pto = end + 3; while (pfrom != loc) *--pto = *--pfrom; store_op1 (op, loc, arg); } /* Like `insert_op1', but for two two-byte parameters ARG1 and ARG2. */ static void insert_op2 (op, loc, arg1, arg2, end) re_opcode_t op; unsigned char *loc; int arg1, arg2; unsigned char *end; { register unsigned char *pfrom = end; register unsigned char *pto = end + 5; while (pfrom != loc) *--pto = *--pfrom; store_op2 (op, loc, arg1, arg2); } /* P points to just after a ^ in PATTERN. Return true if that ^ comes after an alternative or a begin-subexpression. We assume there is at least one character before the ^. */ static char at_begline_loc_p (pattern, p, syntax) const char *pattern, *p; reg_syntax_t syntax; { const char *prev = p - 2; char prev_prev_backslash = prev > pattern && prev[-1] == '\\'; return /* After a subexpression? */ (*prev == '(' && (syntax & RE_NO_BK_PARENS || prev_prev_backslash)) /* After an alternative? */ || (*prev == '|' && (syntax & RE_NO_BK_VBAR || prev_prev_backslash)); } /* The dual of at_begline_loc_p. This one is for $. We assume there is at least one character after the $, i.e., `P < PEND'. */ static char at_endline_loc_p (p, pend, syntax) const char *p, *pend; reg_syntax_t syntax; { const char *next = p; char next_backslash = *next == '\\'; const char *next_next = p + 1 < pend ? p + 1 : 0; return /* Before a subexpression? */ (syntax & RE_NO_BK_PARENS ? *next == ')' : next_backslash && next_next && *next_next == ')') /* Before an alternative? */ || (syntax & RE_NO_BK_VBAR ? *next == '|' : next_backslash && next_next && *next_next == '|'); } /* Returns true if REGNUM is in one of COMPILE_STACK's elements and false if it's not. */ static char group_in_compile_stack (compile_stack, regnum) compile_stack_type compile_stack; regnum_t regnum; { int this_element; for (this_element = compile_stack.avail - 1; this_element >= 0; this_element--) if (compile_stack.stack[this_element].regnum == regnum) return true; return false; } /* Read the ending character of a range (in a bracket expression) from the uncompiled pattern *P_PTR (which ends at PEND). We assume the starting character is in `P[-2]'. (`P[-1]' is the character `-'.) Then we set the translation of all bits between the starting and ending characters (inclusive) in the compiled pattern B. Return an error code. We use these short variable names so we can use the same macros as `regex_compile' itself. */ static reg_errcode_t compile_range (p_ptr, pend, translate, syntax, b) const char **p_ptr, *pend; RE_TRANSLATE_TYPE translate; reg_syntax_t syntax; unsigned char *b; { unsigned this_char; const char *p = *p_ptr; unsigned int range_start, range_end; if (p == pend) return REG_ERANGE; /* Even though the pattern is a signed `char *', we need to fetch with unsigned char *'s; if the high bit of the pattern character is set, the range endpoints will be negative if we fetch using a signed char *. We also want to fetch the endpoints without translating them; the appropriate translation is done in the bit-setting loop below. */ /* The SVR4 compiler on the 3B2 had trouble with unsigned const char *. */ range_start = ((const unsigned char *) p)[-2]; range_end = ((const unsigned char *) p)[0]; /* Have to increment the pointer into the pattern string, so the caller isn't still at the ending character. */ (*p_ptr)++; /* If the start is after the end, the range is empty. */ if (range_start > range_end) return syntax & RE_NO_EMPTY_RANGES ? REG_ERANGE : REG_NOERROR; /* Here we see why `this_char' has to be larger than an `unsigned char' -- the range is inclusive, so if `range_end' == 0xff (assuming 8-bit characters), we would otherwise go into an infinite loop, since all characters <= 0xff. */ for (this_char = range_start; this_char <= range_end; this_char++) { SET_LIST_BIT (TRANSLATE (this_char)); } return REG_NOERROR; } /* re_compile_fastmap computes a ``fastmap'' for the compiled pattern in BUFP. A fastmap records which of the (1 << BYTEWIDTH) possible characters can start a string that matches the pattern. This fastmap is used by re_search to skip quickly over impossible starting points. The caller must supply the address of a (1 << BYTEWIDTH)-byte data area as BUFP->fastmap. We set the `fastmap', `fastmap_accurate', and `can_be_null' fields in the pattern buffer. Returns 0 if we succeed, -2 if an internal error. */ int re_compile_fastmap (bufp) struct re_pattern_buffer *bufp; { int j, k; #ifdef MATCH_MAY_ALLOCATE fail_stack_type fail_stack; #endif #ifndef REGEX_MALLOC char *destination; #endif register char *fastmap = bufp->fastmap; unsigned char *pattern = bufp->buffer; unsigned char *p = pattern; register unsigned char *pend = pattern + bufp->used; #ifdef REL_ALLOC /* This holds the pointer to the failure stack, when it is allocated relocatably. */ fail_stack_elt_t *failure_stack_ptr; #endif /* Assume that each path through the pattern can be null until proven otherwise. We set this false at the bottom of switch statement, to which we get only if a particular path doesn't match the empty string. */ char path_can_be_null = true; /* We aren't doing a `succeed_n' to begin with. */ char succeed_n_p = false; assert (fastmap != NULL && p != NULL); INIT_FAIL_STACK (); bzero (fastmap, 1 << BYTEWIDTH); /* Assume nothing's valid. */ bufp->fastmap_accurate = 1; /* It will be when we're done. */ bufp->can_be_null = 0; while (1) { if (p == pend || *p == succeed) { /* We have reached the (effective) end of pattern. */ if (!FAIL_STACK_EMPTY ()) { bufp->can_be_null |= path_can_be_null; /* Reset for next path. */ path_can_be_null = true; p = fail_stack.stack[--fail_stack.avail].pointer; continue; } else break; } /* We should never be about to go beyond the end of the pattern. */ assert (p < pend); switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++)) { /* I guess the idea here is to simply not bother with a fastmap if a backreference is used, since it's too hard to figure out the fastmap for the corresponding group. Setting `can_be_null' stops `re_search_2' from using the fastmap, so that is all we do. */ case duplicate: bufp->can_be_null = 1; goto done; /* Following are the cases which match a character. These end with `break'. */ case exactn: fastmap[p[1]] = 1; break; case charset: for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--) if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))) fastmap[j] = 1; break; case charset_not: /* Chars beyond end of map must be allowed. */ for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++) fastmap[j] = 1; for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--) if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))) fastmap[j] = 1; break; case wordchar: for (j = 0; j < (1 << BYTEWIDTH); j++) if (SYNTAX (j) == Sword) fastmap[j] = 1; break; case notwordchar: for (j = 0; j < (1 << BYTEWIDTH); j++) if (SYNTAX (j) != Sword) fastmap[j] = 1; break; case anychar: { int fastmap_newline = fastmap['\n']; /* `.' matches anything ... */ for (j = 0; j < (1 << BYTEWIDTH); j++) fastmap[j] = 1; /* ... except perhaps newline. */ if (!(bufp->syntax & RE_DOT_NEWLINE)) fastmap['\n'] = fastmap_newline; /* Return if we have already set `can_be_null'; if we have, then the fastmap is irrelevant. Something's wrong here. */ else if (bufp->can_be_null) goto done; /* Otherwise, have to check alternative paths. */ break; } #ifdef emacs case syntaxspec: k = *p++; for (j = 0; j < (1 << BYTEWIDTH); j++) if (SYNTAX (j) == (enum syntaxcode) k) fastmap[j] = 1; break; case notsyntaxspec: k = *p++; for (j = 0; j < (1 << BYTEWIDTH); j++) if (SYNTAX (j) != (enum syntaxcode) k) fastmap[j] = 1; break; /* All cases after this match the empty string. These end with `continue'. */ case before_dot: case at_dot: case after_dot: continue; #endif /* emacs */ case no_op: case begline: case endline: case begbuf: case endbuf: case wordbound: case notwordbound: case wordbeg: case wordend: case push_dummy_failure: continue; case jump_n: case pop_failure_jump: case maybe_pop_jump: case jump: case jump_past_alt: case dummy_failure_jump: EXTRACT_NUMBER_AND_INCR (j, p); p += j; if (j > 0) continue; /* Jump backward implies we just went through the body of a loop and matched nothing. Opcode jumped to should be `on_failure_jump' or `succeed_n'. Just treat it like an ordinary jump. For a * loop, it has pushed its failure point already; if so, discard that as redundant. */ if ((re_opcode_t) *p != on_failure_jump && (re_opcode_t) *p != succeed_n) continue; p++; EXTRACT_NUMBER_AND_INCR (j, p); p += j; /* If what's on the stack is where we are now, pop it. */ if (!FAIL_STACK_EMPTY () && fail_stack.stack[fail_stack.avail - 1].pointer == p) fail_stack.avail--; continue; case on_failure_jump: case on_failure_keep_string_jump: handle_on_failure_jump: EXTRACT_NUMBER_AND_INCR (j, p); /* For some patterns, e.g., `(a?)?', `p+j' here points to the end of the pattern. We don't want to push such a point, since when we restore it above, entering the switch will increment `p' past the end of the pattern. We don't need to push such a point since we obviously won't find any more fastmap entries beyond `pend'. Such a pattern can match the null string, though. */ if (p + j < pend) { if (!PUSH_PATTERN_OP (p + j, fail_stack)) { RESET_FAIL_STACK (); return -2; } } else bufp->can_be_null = 1; if (succeed_n_p) { EXTRACT_NUMBER_AND_INCR (k, p); /* Skip the n. */ succeed_n_p = false; } continue; case succeed_n: /* Get to the number of times to succeed. */ p += 2; /* Increment p past the n for when k != 0. */ EXTRACT_NUMBER_AND_INCR (k, p); if (k == 0) { p -= 4; succeed_n_p = true; /* Spaghetti code alert. */ goto handle_on_failure_jump; } continue; case set_number_at: p += 4; continue; case start_memory: case stop_memory: p += 2; continue; default: abort (); /* We have listed all the cases. */ } /* switch *p++ */ /* Getting here means we have found the possible starting characters for one path of the pattern -- and that the empty string does not match. We need not follow this path further. Instead, look at the next alternative (remembered on the stack), or quit if no more. The test at the top of the loop does these things. */ path_can_be_null = false; p = pend; } /* while p */ /* Set `can_be_null' for the last path (also the first path, if the pattern is empty). */ bufp->can_be_null |= path_can_be_null; done: RESET_FAIL_STACK (); return 0; } /* re_compile_fastmap */ #ifdef _LIBC weak_alias (__re_compile_fastmap, re_compile_fastmap) #endif /* Set REGS to hold NUM_REGS registers, storing them in STARTS and ENDS. Subsequent matches using PATTERN_BUFFER and REGS will use this memory for recording register information. STARTS and ENDS must be allocated using the malloc library routine, and must each be at least NUM_REGS * sizeof (regoff_t) bytes long. If NUM_REGS == 0, then subsequent matches should allocate their own register data. Unless this function is called, the first search or match using PATTERN_BUFFER will allocate its own register data, without freeing the old data. */ void re_set_registers (bufp, regs, num_regs, starts, ends) struct re_pattern_buffer *bufp; struct re_registers *regs; unsigned num_regs; regoff_t *starts, *ends; { if (num_regs) { bufp->regs_allocated = REGS_REALLOCATE; regs->num_regs = num_regs; regs->start = starts; regs->end = ends; } else { bufp->regs_allocated = REGS_UNALLOCATED; regs->num_regs = 0; regs->start = regs->end = (regoff_t *) 0; } } #ifdef _LIBC weak_alias (__re_set_registers, re_set_registers) #endif /* Searching routines. */ /* Like re_search_2, below, but only one string is specified, and doesn't let you say where to stop matching. */ int re_search (bufp, string, size, startpos, range, regs) struct re_pattern_buffer *bufp; const char *string; int size, startpos, range; struct re_registers *regs; { return re_search_2 (bufp, NULL, 0, string, size, startpos, range, regs, size); } #ifdef _LIBC weak_alias (__re_search, re_search) #endif /* Using the compiled pattern in BUFP->buffer, first tries to match the virtual concatenation of STRING1 and STRING2, starting first at index STARTPOS, then at STARTPOS + 1, and so on. STRING1 and STRING2 have length SIZE1 and SIZE2, respectively. RANGE is how far to scan while trying to match. RANGE = 0 means try only at STARTPOS; in general, the last start tried is STARTPOS + RANGE. In REGS, return the indices of the virtual concatenation of STRING1 and STRING2 that matched the entire BUFP->buffer and its contained subexpressions. Do not consider matching one past the index STOP in the virtual concatenation of STRING1 and STRING2. We return either the position in the strings at which the match was found, -1 if no match, or -2 if error (such as failure stack overflow). */ int re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop) struct re_pattern_buffer *bufp; const char *string1, *string2; int size1, size2; int startpos; int range; struct re_registers *regs; int stop; { int val; register char *fastmap = bufp->fastmap; register RE_TRANSLATE_TYPE translate = bufp->translate; int total_size = size1 + size2; int endpos = startpos + range; /* Check for out-of-range STARTPOS. */ if (startpos < 0 || startpos > total_size) return -1; /* Fix up RANGE if it might eventually take us outside the virtual concatenation of STRING1 and STRING2. Make sure we won't move STARTPOS below 0 or above TOTAL_SIZE. */ if (endpos < 0) range = 0 - startpos; else if (endpos > total_size) range = total_size - startpos; /* If the search isn't to be a backwards one, don't waste time in a search for a pattern that must be anchored. */ if (bufp->used > 0 && range > 0 && ((re_opcode_t) bufp->buffer[0] == begbuf /* `begline' is like `begbuf' if it cannot match at newlines. */ || ((re_opcode_t) bufp->buffer[0] == begline && !bufp->newline_anchor))) { if (startpos > 0) return -1; else range = 1; } #ifdef emacs /* In a forward search for something that starts with \=. don't keep searching past point. */ if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == at_dot && range > 0) { range = PT - startpos; if (range <= 0) return -1; } #endif /* emacs */ /* Update the fastmap now if not correct already. */ if (fastmap && !bufp->fastmap_accurate) if (re_compile_fastmap (bufp) == -2) return -2; /* Loop through the string, looking for a place to start matching. */ for (;;) { /* If a fastmap is supplied, skip quickly over characters that cannot be the start of a match. If the pattern can match the null string, however, we don't need to skip characters; we want the first null string. */ if (fastmap && startpos < total_size && !bufp->can_be_null) { if (range > 0) /* Searching forwards. */ { register const char *d; register int lim = 0; int irange = range; if (startpos < size1 && startpos + range >= size1) lim = range - (size1 - startpos); d = (startpos >= size1 ? string2 - size1 : string1) + startpos; /* Written out as an if-else to avoid testing `translate' inside the loop. */ if (translate) while (range > lim && !fastmap[(unsigned char) translate[(unsigned char) *d++]]) range--; else while (range > lim && !fastmap[(unsigned char) *d++]) range--; startpos += irange - range; } else /* Searching backwards. */ { register char c = (size1 == 0 || startpos >= size1 ? string2[startpos - size1] : string1[startpos]); if (!fastmap[(unsigned char) TRANSLATE (c)]) goto advance; } } /* If can't match the null string, and that's all we have left, fail. */ if (range >= 0 && startpos == total_size && fastmap && !bufp->can_be_null) return -1; val = re_match_2_internal (bufp, string1, size1, string2, size2, startpos, regs, stop); #ifndef REGEX_MALLOC # ifdef C_ALLOCA alloca (0); # endif #endif if (val >= 0) return startpos; if (val == -2) return -2; advance: if (!range) break; else if (range > 0) { range--; startpos++; } else { range++; startpos--; } } return -1; } /* re_search_2 */ #ifdef _LIBC weak_alias (__re_search_2, re_search_2) #endif /* This converts PTR, a pointer into one of the search strings `string1' and `string2' into an offset from the beginning of that string. */ #define POINTER_TO_OFFSET(ptr) \ (FIRST_STRING_P (ptr) \ ? ((regoff_t) ((ptr) - string1)) \ : ((regoff_t) ((ptr) - string2 + size1))) /* Macros for dealing with the split strings in re_match_2. */ #define MATCHING_IN_FIRST_STRING (dend == end_match_1) /* Call before fetching a character with *d. This switches over to string2 if necessary. */ #define PREFETCH() \ while (d == dend) \ { \ /* End of string2 => fail. */ \ if (dend == end_match_2) \ goto fail; \ /* End of string1 => advance to string2. */ \ d = string2; \ dend = end_match_2; \ } /* Test if at very beginning or at very end of the virtual concatenation of `string1' and `string2'. If only one string, it's `string2'. */ #define AT_STRINGS_BEG(d) ((d) == (size1 ? string1 : string2) || !size2) #define AT_STRINGS_END(d) ((d) == end2) /* Test if D points to a character which is word-constituent. We have two special cases to check for: if past the end of string1, look at the first character in string2; and if before the beginning of string2, look at the last character in string1. */ #define WORDCHAR_P(d) \ (SYNTAX ((d) == end1 ? *string2 \ : (d) == string2 - 1 ? *(end1 - 1) : *(d)) \ == Sword) /* Disabled due to a compiler bug -- see comment at case wordbound */ #if 0 /* Test if the character before D and the one at D differ with respect to being word-constituent. */ #define AT_WORD_BOUNDARY(d) \ (AT_STRINGS_BEG (d) || AT_STRINGS_END (d) \ || WORDCHAR_P (d - 1) != WORDCHAR_P (d)) #endif /* Free everything we malloc. */ #ifdef MATCH_MAY_ALLOCATE # define FREE_VAR(var) if (var) REGEX_FREE (var); var = NULL # define FREE_VARIABLES() \ do { \ REGEX_FREE_STACK (fail_stack.stack); \ FREE_VAR (regstart); \ FREE_VAR (regend); \ FREE_VAR (old_regstart); \ FREE_VAR (old_regend); \ FREE_VAR (best_regstart); \ FREE_VAR (best_regend); \ FREE_VAR (reg_info); \ FREE_VAR (reg_dummy); \ FREE_VAR (reg_info_dummy); \ } while (0) #else # define FREE_VARIABLES() ((void)0) /* Do nothing! But inhibit gcc warning. */ #endif /* not MATCH_MAY_ALLOCATE */ /* These values must meet several constraints. They must not be valid register values; since we have a limit of 255 registers (because we use only one byte in the pattern for the register number), we can use numbers larger than 255. They must differ by 1, because of NUM_FAILURE_ITEMS above. And the value for the lowest register must be larger than the value for the highest register, so we do not try to actually save any registers when none are active. */ #define NO_HIGHEST_ACTIVE_REG (1 << BYTEWIDTH) #define NO_LOWEST_ACTIVE_REG (NO_HIGHEST_ACTIVE_REG + 1) /* Matching routines. */ #ifndef emacs /* Emacs never uses this. */ /* re_match is like re_match_2 except it takes only a single string. */ int re_match (bufp, string, size, pos, regs) struct re_pattern_buffer *bufp; const char *string; int size, pos; struct re_registers *regs; { int result = re_match_2_internal (bufp, NULL, 0, string, size, pos, regs, size); # ifndef REGEX_MALLOC # ifdef C_ALLOCA alloca (0); # endif # endif return result; } # ifdef _LIBC weak_alias (__re_match, re_match) # endif #endif /* not emacs */ static char group_match_null_string_p _RE_ARGS ((unsigned char **p, unsigned char *end, register_info_type *reg_info)); static char alt_match_null_string_p _RE_ARGS ((unsigned char *p, unsigned char *end, register_info_type *reg_info)); static char common_op_match_null_string_p _RE_ARGS ((unsigned char **p, unsigned char *end, register_info_type *reg_info)); static int bcmp_translate _RE_ARGS ((const char *s1, const char *s2, int len, char *translate)); /* re_match_2 matches the compiled pattern in BUFP against the the (virtual) concatenation of STRING1 and STRING2 (of length SIZE1 and SIZE2, respectively). We start matching at POS, and stop matching at STOP. If REGS is non-null and the `no_sub' field of BUFP is nonzero, we store offsets for the substring each group matched in REGS. See the documentation for exactly how many groups we fill. We return -1 if no match, -2 if an internal error (such as the failure stack overflowing). Otherwise, we return the length of the matched substring. */ int re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop) struct re_pattern_buffer *bufp; const char *string1, *string2; int size1, size2; int pos; struct re_registers *regs; int stop; { int result = re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop); #ifndef REGEX_MALLOC # ifdef C_ALLOCA alloca (0); # endif #endif return result; } #ifdef _LIBC weak_alias (__re_match_2, re_match_2) #endif /* This is a separate function so that we can force an alloca cleanup afterwards. */ static int re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop) struct re_pattern_buffer *bufp; const char *string1, *string2; int size1, size2; int pos; struct re_registers *regs; int stop; { /* General temporaries. */ int mcnt; unsigned char *p1; /* Just past the end of the corresponding string. */ const char *end1, *end2; /* Pointers into string1 and string2, just past the last characters in each to consider matching. */ const char *end_match_1, *end_match_2; /* Where we are in the data, and the end of the current string. */ const char *d, *dend; /* Where we are in the pattern, and the end of the pattern. */ unsigned char *p = bufp->buffer; register unsigned char *pend = p + bufp->used; /* Mark the opcode just after a start_memory, so we can test for an empty subpattern when we get to the stop_memory. */ unsigned char *just_past_start_mem = 0; /* We use this to map every character in the string. */ RE_TRANSLATE_TYPE translate = bufp->translate; /* Failure point stack. Each place that can handle a failure further down the line pushes a failure point on this stack. It consists of restart, regend, and reg_info for all registers corresponding to the subexpressions we're currently inside, plus the number of such registers, and, finally, two char *'s. The first char * is where to resume scanning the pattern; the second one is where to resume scanning the strings. If the latter is zero, the failure point is a ``dummy''; if a failure happens and the failure point is a dummy, it gets discarded and the next next one is tried. */ #ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */ fail_stack_type fail_stack; #endif #ifdef DEBUG static unsigned failure_id; unsigned nfailure_points_pushed = 0, nfailure_points_popped = 0; #endif #ifdef REL_ALLOC /* This holds the pointer to the failure stack, when it is allocated relocatably. */ fail_stack_elt_t *failure_stack_ptr; #endif /* We fill all the registers internally, independent of what we return, for use in backreferences. The number here includes an element for register zero. */ size_t num_regs = bufp->re_nsub + 1; /* The currently active registers. */ active_reg_t lowest_active_reg = NO_LOWEST_ACTIVE_REG; active_reg_t highest_active_reg = NO_HIGHEST_ACTIVE_REG; /* Information on the contents of registers. These are pointers into the input strings; they record just what was matched (on this attempt) by a subexpression part of the pattern, that is, the regnum-th regstart pointer points to where in the pattern we began matching and the regnum-th regend points to right after where we stopped matching the regnum-th subexpression. (The zeroth register keeps track of what the whole pattern matches.) */ #ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */ const char **regstart, **regend; #endif /* If a group that's operated upon by a repetition operator fails to match anything, then the register for its start will need to be restored because it will have been set to wherever in the string we are when we last see its open-group operator. Similarly for a register's end. */ #ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */ const char **old_regstart, **old_regend; #endif /* The is_active field of reg_info helps us keep track of which (possibly nested) subexpressions we are currently in. The matched_something field of reg_info[reg_num] helps us tell whether or not we have matched any of the pattern so far this time through the reg_num-th subexpression. These two fields get reset each time through any loop their register is in. */ #ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */ register_info_type *reg_info; #endif /* The following record the register info as found in the above variables when we find a match better than any we've seen before. This happens as we backtrack through the failure points, which in turn happens only if we have not yet matched the entire string. */ unsigned best_regs_set = false; #ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */ const char **best_regstart, **best_regend; #endif /* Logically, this is `best_regend[0]'. But we don't want to have to allocate space for that if we're not allocating space for anything else (see below). Also, we never need info about register 0 for any of the other register vectors, and it seems rather a kludge to treat `best_regend' differently than the rest. So we keep track of the end of the best match so far in a separate variable. We initialize this to NULL so that when we backtrack the first time and need to test it, it's not garbage. */ const char *match_end = NULL; /* This helps SET_REGS_MATCHED avoid doing redundant work. */ int set_regs_matched_done = 0; /* Used when we pop values we don't care about. */ #ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */ const char **reg_dummy; register_info_type *reg_info_dummy; #endif #ifdef DEBUG /* Counts the total number of registers pushed. */ unsigned num_regs_pushed = 0; #endif DEBUG_PRINT1 ("\n\nEntering re_match_2.\n"); INIT_FAIL_STACK (); #ifdef MATCH_MAY_ALLOCATE /* Do not bother to initialize all the register variables if there are no groups in the pattern, as it takes a fair amount of time. If there are groups, we include space for register 0 (the whole pattern), even though we never use it, since it simplifies the array indexing. We should fix this. */ if (bufp->re_nsub) { regstart = REGEX_TALLOC (num_regs, const char *); regend = REGEX_TALLOC (num_regs, const char *); old_regstart = REGEX_TALLOC (num_regs, const char *); old_regend = REGEX_TALLOC (num_regs, const char *); best_regstart = REGEX_TALLOC (num_regs, const char *); best_regend = REGEX_TALLOC (num_regs, const char *); reg_info = REGEX_TALLOC (num_regs, register_info_type); reg_dummy = REGEX_TALLOC (num_regs, const char *); reg_info_dummy = REGEX_TALLOC (num_regs, register_info_type); if (!(regstart && regend && old_regstart && old_regend && reg_info && best_regstart && best_regend && reg_dummy && reg_info_dummy)) { FREE_VARIABLES (); return -2; } } else { /* We must initialize all our variables to NULL, so that `FREE_VARIABLES' doesn't try to free them. */ regstart = regend = old_regstart = old_regend = best_regstart = best_regend = reg_dummy = NULL; reg_info = reg_info_dummy = (register_info_type *) NULL; } #endif /* MATCH_MAY_ALLOCATE */ /* The starting position is bogus. */ if (pos < 0 || pos > size1 + size2) { FREE_VARIABLES (); return -1; } /* Initialize subexpression text positions to -1 to mark ones that no start_memory/stop_memory has been seen for. Also initialize the register information struct. */ for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++) { regstart[mcnt] = regend[mcnt] = old_regstart[mcnt] = old_regend[mcnt] = REG_UNSET_VALUE; REG_MATCH_NULL_STRING_P (reg_info[mcnt]) = MATCH_NULL_UNSET_VALUE; IS_ACTIVE (reg_info[mcnt]) = 0; MATCHED_SOMETHING (reg_info[mcnt]) = 0; EVER_MATCHED_SOMETHING (reg_info[mcnt]) = 0; } /* We move `string1' into `string2' if the latter's empty -- but not if `string1' is null. */ if (size2 == 0 && string1 != NULL) { string2 = string1; size2 = size1; string1 = 0; size1 = 0; } end1 = string1 + size1; end2 = string2 + size2; /* Compute where to stop matching, within the two strings. */ if (stop <= size1) { end_match_1 = string1 + stop; end_match_2 = string2; } else { end_match_1 = end1; end_match_2 = string2 + stop - size1; } /* `p' scans through the pattern as `d' scans through the data. `dend' is the end of the input string that `d' points within. `d' is advanced into the following input string whenever necessary, but this happens before fetching; therefore, at the beginning of the loop, `d' can be pointing at the end of a string, but it cannot equal `string2'. */ if (size1 > 0 && pos <= size1) { d = string1 + pos; dend = end_match_1; } else { d = string2 + pos - size1; dend = end_match_2; } DEBUG_PRINT1 ("The compiled pattern is:\n"); DEBUG_PRINT_COMPILED_PATTERN (bufp, p, pend); DEBUG_PRINT1 ("The string to match is: `"); DEBUG_PRINT_DOUBLE_STRING (d, string1, size1, string2, size2); DEBUG_PRINT1 ("'\n"); /* This loops over pattern commands. It exits by returning from the function if the match is complete, or it drops through if the match fails at this starting point in the input data. */ for (;;) { DEBUG_PRINT2 ("\n%p: ", p); if (p == pend) { /* End of pattern means we might have succeeded. */ DEBUG_PRINT1 ("end of pattern ... "); /* If we haven't matched the entire string, and we want the longest match, try backtracking. */ if (d != end_match_2) { /* 1 if this match ends in the same string (string1 or string2) as the best previous match. */ char same_str_p = (FIRST_STRING_P (match_end) == MATCHING_IN_FIRST_STRING); /* 1 if this match is the best seen so far. */ char best_match_p; /* AIX compiler got confused when this was combined with the previous declaration. */ if (same_str_p) best_match_p = d > match_end; else best_match_p = !MATCHING_IN_FIRST_STRING; DEBUG_PRINT1 ("backtracking.\n"); if (!FAIL_STACK_EMPTY ()) { /* More failure points to try. */ /* If exceeds best match so far, save it. */ if (!best_regs_set || best_match_p) { best_regs_set = true; match_end = d; DEBUG_PRINT1 ("\nSAVING match as best so far.\n"); for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++) { best_regstart[mcnt] = regstart[mcnt]; best_regend[mcnt] = regend[mcnt]; } } goto fail; } /* If no failure points, don't restore garbage. And if last match is real best match, don't restore second best one. */ else if (best_regs_set && !best_match_p) { restore_best_regs: /* Restore best match. It may happen that `dend == end_match_1' while the restored d is in string2. For example, the pattern `x.*y.*z' against the strings `x-' and `y-z-', if the two strings are not consecutive in memory. */ DEBUG_PRINT1 ("Restoring best registers.\n"); d = match_end; dend = ((d >= string1 && d <= end1) ? end_match_1 : end_match_2); for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++) { regstart[mcnt] = best_regstart[mcnt]; regend[mcnt] = best_regend[mcnt]; } } } /* d != end_match_2 */ succeed_label: DEBUG_PRINT1 ("Accepting match.\n"); /* If caller wants register contents data back, do it. */ if (regs && !bufp->no_sub) { /* Have the register data arrays been allocated? */ if (bufp->regs_allocated == REGS_UNALLOCATED) { /* No. So allocate them with malloc. We need one extra element beyond `num_regs' for the `-1' marker GNU code uses. */ regs->num_regs = MAX (RE_NREGS, num_regs + 1); regs->start = TALLOC (regs->num_regs, regoff_t); regs->end = TALLOC (regs->num_regs, regoff_t); if (regs->start == NULL || regs->end == NULL) { FREE_VARIABLES (); return -2; } bufp->regs_allocated = REGS_REALLOCATE; } else if (bufp->regs_allocated == REGS_REALLOCATE) { /* Yes. If we need more elements than were already allocated, reallocate them. If we need fewer, just leave it alone. */ if (regs->num_regs < num_regs + 1) { regs->num_regs = num_regs + 1; RETALLOC (regs->start, regs->num_regs, regoff_t); RETALLOC (regs->end, regs->num_regs, regoff_t); if (regs->start == NULL || regs->end == NULL) { FREE_VARIABLES (); return -2; } } } else { /* These braces fend off a "empty body in an else-statement" warning under GCC when assert expands to nothing. */ assert (bufp->regs_allocated == REGS_FIXED); } /* Convert the pointer data in `regstart' and `regend' to indices. Register zero has to be set differently, since we haven't kept track of any info for it. */ if (regs->num_regs > 0) { regs->start[0] = pos; regs->end[0] = (MATCHING_IN_FIRST_STRING ? ((regoff_t) (d - string1)) : ((regoff_t) (d - string2 + size1))); } /* Go through the first `min (num_regs, regs->num_regs)' registers, since that is all we initialized. */ for (mcnt = 1; (unsigned) mcnt < MIN (num_regs, regs->num_regs); mcnt++) { if (REG_UNSET (regstart[mcnt]) || REG_UNSET (regend[mcnt])) regs->start[mcnt] = regs->end[mcnt] = -1; else { regs->start[mcnt] = (regoff_t) POINTER_TO_OFFSET (regstart[mcnt]); regs->end[mcnt] = (regoff_t) POINTER_TO_OFFSET (regend[mcnt]); } } /* If the regs structure we return has more elements than were in the pattern, set the extra elements to -1. If we (re)allocated the registers, this is the case, because we always allocate enough to have at least one -1 at the end. */ for (mcnt = num_regs; (unsigned) mcnt < regs->num_regs; mcnt++) regs->start[mcnt] = regs->end[mcnt] = -1; } /* regs && !bufp->no_sub */ DEBUG_PRINT4 ("%u failure points pushed, %u popped (%u remain).\n", nfailure_points_pushed, nfailure_points_popped, nfailure_points_pushed - nfailure_points_popped); DEBUG_PRINT2 ("%u registers pushed.\n", num_regs_pushed); mcnt = d - pos - (MATCHING_IN_FIRST_STRING ? string1 : string2 - size1); DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt); FREE_VARIABLES (); return mcnt; } /* Otherwise match next pattern command. */ switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++)) { /* Ignore these. Used to ignore the n of succeed_n's which currently have n == 0. */ case no_op: DEBUG_PRINT1 ("EXECUTING no_op.\n"); break; case succeed: DEBUG_PRINT1 ("EXECUTING succeed.\n"); goto succeed_label; /* Match the next n pattern characters exactly. The following byte in the pattern defines n, and the n bytes after that are the characters to match. */ case exactn: mcnt = *p++; DEBUG_PRINT2 ("EXECUTING exactn %d.\n", mcnt); /* This is written out as an if-else so we don't waste time testing `translate' inside the loop. */ if (translate) { do { PREFETCH (); if ((unsigned char) translate[(unsigned char) *d++] != (unsigned char) *p++) goto fail; } while (--mcnt); } else { do { PREFETCH (); if (*d++ != (char) *p++) goto fail; } while (--mcnt); } SET_REGS_MATCHED (); break; /* Match any character except possibly a newline or a null. */ case anychar: DEBUG_PRINT1 ("EXECUTING anychar.\n"); PREFETCH (); if ((!(bufp->syntax & RE_DOT_NEWLINE) && TRANSLATE (*d) == '\n') || (bufp->syntax & RE_DOT_NOT_NULL && TRANSLATE (*d) == '\000')) goto fail; SET_REGS_MATCHED (); DEBUG_PRINT2 (" Matched `%d'.\n", *d); d++; break; case charset: case charset_not: { register unsigned char c; char not = (re_opcode_t) *(p - 1) == charset_not; DEBUG_PRINT2 ("EXECUTING charset%s.\n", not ? "_not" : ""); PREFETCH (); c = TRANSLATE (*d); /* The character to match. */ /* Cast to `unsigned' instead of `unsigned char' in case the bit list is a full 32 bytes long. */ if (c < (unsigned) (*p * BYTEWIDTH) && p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH))) not = !not; p += 1 + *p; if (!not) goto fail; SET_REGS_MATCHED (); d++; break; } /* The beginning of a group is represented by start_memory. The arguments are the register number in the next byte, and the number of groups inner to this one in the next. The text matched within the group is recorded (in the internal registers data structure) under the register number. */ case start_memory: DEBUG_PRINT3 ("EXECUTING start_memory %d (%d):\n", *p, p[1]); /* Find out if this group can match the empty string. */ p1 = p; /* To send to group_match_null_string_p. */ if (REG_MATCH_NULL_STRING_P (reg_info[*p]) == MATCH_NULL_UNSET_VALUE) REG_MATCH_NULL_STRING_P (reg_info[*p]) = group_match_null_string_p (&p1, pend, reg_info); /* Save the position in the string where we were the last time we were at this open-group operator in case the group is operated upon by a repetition operator, e.g., with `(a*)*b' against `ab'; then we want to ignore where we are now in the string in case this attempt to match fails. */ old_regstart[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p]) ? REG_UNSET (regstart[*p]) ? d : regstart[*p] : regstart[*p]; DEBUG_PRINT2 (" old_regstart: %d\n", POINTER_TO_OFFSET (old_regstart[*p])); regstart[*p] = d; DEBUG_PRINT2 (" regstart: %d\n", POINTER_TO_OFFSET (regstart[*p])); IS_ACTIVE (reg_info[*p]) = 1; MATCHED_SOMETHING (reg_info[*p]) = 0; /* Clear this whenever we change the register activity status. */ set_regs_matched_done = 0; /* This is the new highest active register. */ highest_active_reg = *p; /* If nothing was active before, this is the new lowest active register. */ if (lowest_active_reg == NO_LOWEST_ACTIVE_REG) lowest_active_reg = *p; /* Move past the register number and inner group count. */ p += 2; just_past_start_mem = p; break; /* The stop_memory opcode represents the end of a group. Its arguments are the same as start_memory's: the register number, and the number of inner groups. */ case stop_memory: DEBUG_PRINT3 ("EXECUTING stop_memory %d (%d):\n", *p, p[1]); /* We need to save the string position the last time we were at this close-group operator in case the group is operated upon by a repetition operator, e.g., with `((a*)*(b*)*)*' against `aba'; then we want to ignore where we are now in the string in case this attempt to match fails. */ old_regend[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p]) ? REG_UNSET (regend[*p]) ? d : regend[*p] : regend[*p]; DEBUG_PRINT2 (" old_regend: %d\n", POINTER_TO_OFFSET (old_regend[*p])); regend[*p] = d; DEBUG_PRINT2 (" regend: %d\n", POINTER_TO_OFFSET (regend[*p])); /* This register isn't active anymore. */ IS_ACTIVE (reg_info[*p]) = 0; /* Clear this whenever we change the register activity status. */ set_regs_matched_done = 0; /* If this was the only register active, nothing is active anymore. */ if (lowest_active_reg == highest_active_reg) { lowest_active_reg = NO_LOWEST_ACTIVE_REG; highest_active_reg = NO_HIGHEST_ACTIVE_REG; } else { /* We must scan for the new highest active register, since it isn't necessarily one less than now: consider (a(b)c(d(e)f)g). When group 3 ends, after the f), the new highest active register is 1. */ unsigned char r = *p - 1; while (r > 0 && !IS_ACTIVE (reg_info[r])) r--; /* If we end up at register zero, that means that we saved the registers as the result of an `on_failure_jump', not a `start_memory', and we jumped to past the innermost `stop_memory'. For example, in ((.)*) we save registers 1 and 2 as a result of the *, but when we pop back to the second ), we are at the stop_memory 1. Thus, nothing is active. */ if (r == 0) { lowest_active_reg = NO_LOWEST_ACTIVE_REG; highest_active_reg = NO_HIGHEST_ACTIVE_REG; } else highest_active_reg = r; } /* If just failed to match something this time around with a group that's operated on by a repetition operator, try to force exit from the ``loop'', and restore the register information for this group that we had before trying this last match. */ if ((!MATCHED_SOMETHING (reg_info[*p]) || just_past_start_mem == p - 1) && (p + 2) < pend) { char is_a_jump_n = false; p1 = p + 2; mcnt = 0; switch ((re_opcode_t) *p1++) { case jump_n: is_a_jump_n = true; case pop_failure_jump: case maybe_pop_jump: case jump: case dummy_failure_jump: EXTRACT_NUMBER_AND_INCR (mcnt, p1); if (is_a_jump_n) p1 += 2; break; default: /* do nothing */ ; } p1 += mcnt; /* If the next operation is a jump backwards in the pattern to an on_failure_jump right before the start_memory corresponding to this stop_memory, exit from the loop by forcing a failure after pushing on the stack the on_failure_jump's jump in the pattern, and d. */ if (mcnt < 0 && (re_opcode_t) *p1 == on_failure_jump && (re_opcode_t) p1[3] == start_memory && p1[4] == *p) { /* If this group ever matched anything, then restore what its registers were before trying this last failed match, e.g., with `(a*)*b' against `ab' for regstart[1], and, e.g., with `((a*)*(b*)*)*' against `aba' for regend[3]. Also restore the registers for inner groups for, e.g., `((a*)(b*))*' against `aba' (register 3 would otherwise get trashed). */ if (EVER_MATCHED_SOMETHING (reg_info[*p])) { unsigned r; EVER_MATCHED_SOMETHING (reg_info[*p]) = 0; /* Restore this and inner groups' (if any) registers. */ for (r = *p; r < (unsigned) *p + (unsigned) *(p + 1); r++) { regstart[r] = old_regstart[r]; /* xx why this test? */ if (old_regend[r] >= regstart[r]) regend[r] = old_regend[r]; } } p1++; EXTRACT_NUMBER_AND_INCR (mcnt, p1); PUSH_FAILURE_POINT (p1 + mcnt, d, -2); goto fail; } } /* Move past the register number and the inner group count. */ p += 2; break; /* \ has been turned into a `duplicate' command which is followed by the numeric value of as the register number. */ case duplicate: { register const char *d2, *dend2; int regno = *p++; /* Get which register to match against. */ DEBUG_PRINT2 ("EXECUTING duplicate %d.\n", regno); /* Can't back reference a group which we've never matched. */ if (REG_UNSET (regstart[regno]) || REG_UNSET (regend[regno])) goto fail; /* Where in input to try to start matching. */ d2 = regstart[regno]; /* Where to stop matching; if both the place to start and the place to stop matching are in the same string, then set to the place to stop, otherwise, for now have to use the end of the first string. */ dend2 = ((FIRST_STRING_P (regstart[regno]) == FIRST_STRING_P (regend[regno])) ? regend[regno] : end_match_1); for (;;) { /* If necessary, advance to next segment in register contents. */ while (d2 == dend2) { if (dend2 == end_match_2) break; if (dend2 == regend[regno]) break; /* End of string1 => advance to string2. */ d2 = string2; dend2 = regend[regno]; } /* At end of register contents => success */ if (d2 == dend2) break; /* If necessary, advance to next segment in data. */ PREFETCH (); /* How many characters left in this segment to match. */ mcnt = dend - d; /* Want how many consecutive characters we can match in one shot, so, if necessary, adjust the count. */ if (mcnt > dend2 - d2) mcnt = dend2 - d2; /* Compare that many; failure if mismatch, else move past them. */ if (translate ? bcmp_translate (d, d2, mcnt, translate) : memcmp (d, d2, mcnt)) goto fail; d += mcnt, d2 += mcnt; /* Do this because we've match some characters. */ SET_REGS_MATCHED (); } } break; /* begline matches the empty string at the beginning of the string (unless `not_bol' is set in `bufp'), and, if `newline_anchor' is set, after newlines. */ case begline: DEBUG_PRINT1 ("EXECUTING begline.\n"); if (AT_STRINGS_BEG (d)) { if (!bufp->not_bol) break; } else if (d[-1] == '\n' && bufp->newline_anchor) { break; } /* In all other cases, we fail. */ goto fail; /* endline is the dual of begline. */ case endline: DEBUG_PRINT1 ("EXECUTING endline.\n"); if (AT_STRINGS_END (d)) { if (!bufp->not_eol) break; } /* We have to ``prefetch'' the next character. */ else if ((d == end1 ? *string2 : *d) == '\n' && bufp->newline_anchor) { break; } goto fail; /* Match at the very beginning of the data. */ case begbuf: DEBUG_PRINT1 ("EXECUTING begbuf.\n"); if (AT_STRINGS_BEG (d)) break; goto fail; /* Match at the very end of the data. */ case endbuf: DEBUG_PRINT1 ("EXECUTING endbuf.\n"); if (AT_STRINGS_END (d)) break; goto fail; /* on_failure_keep_string_jump is used to optimize `.*\n'. It pushes NULL as the value for the string on the stack. Then `pop_failure_point' will keep the current value for the string, instead of restoring it. To see why, consider matching `foo\nbar' against `.*\n'. The .* matches the foo; then the . fails against the \n. But the next thing we want to do is match the \n against the \n; if we restored the string value, we would be back at the foo. Because this is used only in specific cases, we don't need to check all the things that `on_failure_jump' does, to make sure the right things get saved on the stack. Hence we don't share its code. The only reason to push anything on the stack at all is that otherwise we would have to change `anychar's code to do something besides goto fail in this case; that seems worse than this. */ case on_failure_keep_string_jump: DEBUG_PRINT1 ("EXECUTING on_failure_keep_string_jump"); EXTRACT_NUMBER_AND_INCR (mcnt, p); DEBUG_PRINT3 (" %d (to %p):\n", mcnt, p + mcnt); PUSH_FAILURE_POINT (p + mcnt, NULL, -2); break; /* Uses of on_failure_jump: Each alternative starts with an on_failure_jump that points to the beginning of the next alternative. Each alternative except the last ends with a jump that in effect jumps past the rest of the alternatives. (They really jump to the ending jump of the following alternative, because tensioning these jumps is a hassle.) Repeats start with an on_failure_jump that points past both the repetition text and either the following jump or pop_failure_jump back to this on_failure_jump. */ case on_failure_jump: on_failure: DEBUG_PRINT1 ("EXECUTING on_failure_jump"); EXTRACT_NUMBER_AND_INCR (mcnt, p); DEBUG_PRINT3 (" %d (to %p)", mcnt, p + mcnt); /* If this on_failure_jump comes right before a group (i.e., the original * applied to a group), save the information for that group and all inner ones, so that if we fail back to this point, the group's information will be correct. For example, in \(a*\)*\1, we need the preceding group, and in \(zz\(a*\)b*\)\2, we need the inner group. */ /* We can't use `p' to check ahead because we push a failure point to `p + mcnt' after we do this. */ p1 = p; /* We need to skip no_op's before we look for the start_memory in case this on_failure_jump is happening as the result of a completed succeed_n, as in \(a\)\{1,3\}b\1 against aba. */ while (p1 < pend && (re_opcode_t) *p1 == no_op) p1++; if (p1 < pend && (re_opcode_t) *p1 == start_memory) { /* We have a new highest active register now. This will get reset at the start_memory we are about to get to, but we will have saved all the registers relevant to this repetition op, as described above. */ highest_active_reg = *(p1 + 1) + *(p1 + 2); if (lowest_active_reg == NO_LOWEST_ACTIVE_REG) lowest_active_reg = *(p1 + 1); } DEBUG_PRINT1 (":\n"); PUSH_FAILURE_POINT (p + mcnt, d, -2); break; /* A smart repeat ends with `maybe_pop_jump'. We change it to either `pop_failure_jump' or `jump'. */ case maybe_pop_jump: EXTRACT_NUMBER_AND_INCR (mcnt, p); DEBUG_PRINT2 ("EXECUTING maybe_pop_jump %d.\n", mcnt); { register unsigned char *p2 = p; /* Compare the beginning of the repeat with what in the pattern follows its end. If we can establish that there is nothing that they would both match, i.e., that we would have to backtrack because of (as in, e.g., `a*a') then we can change to pop_failure_jump, because we'll never have to backtrack. This is not true in the case of alternatives: in `(a|ab)*' we do need to backtrack to the `ab' alternative (e.g., if the string was `ab'). But instead of trying to detect that here, the alternative has put on a dummy failure point which is what we will end up popping. */ /* Skip over open/close-group commands. If what follows this loop is a ...+ construct, look at what begins its body, since we will have to match at least one of that. */ while (1) { if (p2 + 2 < pend && ((re_opcode_t) *p2 == stop_memory || (re_opcode_t) *p2 == start_memory)) p2 += 3; else if (p2 + 6 < pend && (re_opcode_t) *p2 == dummy_failure_jump) p2 += 6; else break; } p1 = p + mcnt; /* p1[0] ... p1[2] are the `on_failure_jump' corresponding to the `maybe_finalize_jump' of this case. Examine what follows. */ /* If we're at the end of the pattern, we can change. */ if (p2 == pend) { /* Consider what happens when matching ":\(.*\)" against ":/". I don't really understand this code yet. */ p[-3] = (unsigned char) pop_failure_jump; DEBUG_PRINT1 (" End of pattern: change to `pop_failure_jump'.\n"); } else if ((re_opcode_t) *p2 == exactn || (bufp->newline_anchor && (re_opcode_t) *p2 == endline)) { register unsigned char c = *p2 == (unsigned char) endline ? '\n' : p2[2]; if ((re_opcode_t) p1[3] == exactn && p1[5] != c) { p[-3] = (unsigned char) pop_failure_jump; DEBUG_PRINT3 (" %c != %c => pop_failure_jump.\n", c, p1[5]); } else if ((re_opcode_t) p1[3] == charset || (re_opcode_t) p1[3] == charset_not) { int not = (re_opcode_t) p1[3] == charset_not; if (c < (unsigned char) (p1[4] * BYTEWIDTH) && p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH))) not = !not; /* `not' is equal to 1 if c would match, which means that we can't change to pop_failure_jump. */ if (!not) { p[-3] = (unsigned char) pop_failure_jump; DEBUG_PRINT1 (" No match => pop_failure_jump.\n"); } } } else if ((re_opcode_t) *p2 == charset) { /* We win if the first character of the loop is not part of the charset. */ if ((re_opcode_t) p1[3] == exactn && ! ((int) p2[1] * BYTEWIDTH > (int) p1[5] && (p2[2 + p1[5] / BYTEWIDTH] & (1 << (p1[5] % BYTEWIDTH))))) { p[-3] = (unsigned char) pop_failure_jump; DEBUG_PRINT1 (" No match => pop_failure_jump.\n"); } else if ((re_opcode_t) p1[3] == charset_not) { int idx; /* We win if the charset_not inside the loop lists every character listed in the charset after. */ for (idx = 0; idx < (int) p2[1]; idx++) if (! (p2[2 + idx] == 0 || (idx < (int) p1[4] && ((p2[2 + idx] & ~ p1[5 + idx]) == 0)))) break; if (idx == p2[1]) { p[-3] = (unsigned char) pop_failure_jump; DEBUG_PRINT1 (" No match => pop_failure_jump.\n"); } } else if ((re_opcode_t) p1[3] == charset) { int idx; /* We win if the charset inside the loop has no overlap with the one after the loop. */ for (idx = 0; idx < (int) p2[1] && idx < (int) p1[4]; idx++) if ((p2[2 + idx] & p1[5 + idx]) != 0) break; if (idx == p2[1] || idx == p1[4]) { p[-3] = (unsigned char) pop_failure_jump; DEBUG_PRINT1 (" No match => pop_failure_jump.\n"); } } } } p -= 2; /* Point at relative address again. */ if ((re_opcode_t) p[-1] != pop_failure_jump) { p[-1] = (unsigned char) jump; DEBUG_PRINT1 (" Match => jump.\n"); goto unconditional_jump; } /* Note fall through. */ /* The end of a simple repeat has a pop_failure_jump back to its matching on_failure_jump, where the latter will push a failure point. The pop_failure_jump takes off failure points put on by this pop_failure_jump's matching on_failure_jump; we got through the pattern to here from the matching on_failure_jump, so didn't fail. */ case pop_failure_jump: { /* We need to pass separate storage for the lowest and highest registers, even though we don't care about the actual values. Otherwise, we will restore only one register from the stack, since lowest will == highest in `pop_failure_point'. */ active_reg_t dummy_low_reg, dummy_high_reg; unsigned char *pdummy; const char *sdummy; DEBUG_PRINT1 ("EXECUTING pop_failure_jump.\n"); POP_FAILURE_POINT (sdummy, pdummy, dummy_low_reg, dummy_high_reg, reg_dummy, reg_dummy, reg_info_dummy); } /* Note fall through. */ unconditional_jump: DEBUG_PRINT2 ("\n%p: ", p); /* Note fall through. */ /* Unconditionally jump (without popping any failure points). */ case jump: EXTRACT_NUMBER_AND_INCR (mcnt, p); /* Get the amount to jump. */ DEBUG_PRINT2 ("EXECUTING jump %d ", mcnt); p += mcnt; /* Do the jump. */ DEBUG_PRINT2 ("(to %p).\n", p); break; /* We need this opcode so we can detect where alternatives end in `group_match_null_string_p' et al. */ case jump_past_alt: DEBUG_PRINT1 ("EXECUTING jump_past_alt.\n"); goto unconditional_jump; /* Normally, the on_failure_jump pushes a failure point, which then gets popped at pop_failure_jump. We will end up at pop_failure_jump, also, and with a pattern of, say, `a+', we are skipping over the on_failure_jump, so we have to push something meaningless for pop_failure_jump to pop. */ case dummy_failure_jump: DEBUG_PRINT1 ("EXECUTING dummy_failure_jump.\n"); /* It doesn't matter what we push for the string here. What the code at `fail' tests is the value for the pattern. */ PUSH_FAILURE_POINT (NULL, NULL, -2); goto unconditional_jump; /* At the end of an alternative, we need to push a dummy failure point in case we are followed by a `pop_failure_jump', because we don't want the failure point for the alternative to be popped. For example, matching `(a|ab)*' against `aab' requires that we match the `ab' alternative. */ case push_dummy_failure: DEBUG_PRINT1 ("EXECUTING push_dummy_failure.\n"); /* See comments just above at `dummy_failure_jump' about the two zeroes. */ PUSH_FAILURE_POINT (NULL, NULL, -2); break; /* Have to succeed matching what follows at least n times. After that, handle like `on_failure_jump'. */ case succeed_n: EXTRACT_NUMBER (mcnt, p + 2); DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt); assert (mcnt >= 0); /* Originally, this is how many times we HAVE to succeed. */ if (mcnt > 0) { mcnt--; p += 2; STORE_NUMBER_AND_INCR (p, mcnt); DEBUG_PRINT3 (" Setting %p to %d.\n", p - 2, mcnt); } else if (mcnt == 0) { DEBUG_PRINT2 (" Setting two bytes from %p to no_op.\n", p+2); p[2] = (unsigned char) no_op; p[3] = (unsigned char) no_op; goto on_failure; } break; case jump_n: EXTRACT_NUMBER (mcnt, p + 2); DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt); /* Originally, this is how many times we CAN jump. */ if (mcnt) { mcnt--; STORE_NUMBER (p + 2, mcnt); DEBUG_PRINT3 (" Setting %p to %d.\n", p + 2, mcnt); goto unconditional_jump; } /* If don't have to jump any more, skip over the rest of command. */ else p += 4; break; case set_number_at: { DEBUG_PRINT1 ("EXECUTING set_number_at.\n"); EXTRACT_NUMBER_AND_INCR (mcnt, p); p1 = p + mcnt; EXTRACT_NUMBER_AND_INCR (mcnt, p); DEBUG_PRINT3 (" Setting %p to %d.\n", p1, mcnt); STORE_NUMBER (p1, mcnt); break; } #if 0 /* The DEC Alpha C compiler 3.x generates incorrect code for the test WORDCHAR_P (d - 1) != WORDCHAR_P (d) in the expansion of AT_WORD_BOUNDARY, so this code is disabled. Expanding the macro and introducing temporary variables works around the bug. */ case wordbound: DEBUG_PRINT1 ("EXECUTING wordbound.\n"); if (AT_WORD_BOUNDARY (d)) break; goto fail; case notwordbound: DEBUG_PRINT1 ("EXECUTING notwordbound.\n"); if (AT_WORD_BOUNDARY (d)) goto fail; break; #else case wordbound: { char prevchar, thischar; DEBUG_PRINT1 ("EXECUTING wordbound.\n"); if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d)) break; prevchar = WORDCHAR_P (d - 1); thischar = WORDCHAR_P (d); if (prevchar != thischar) break; goto fail; } case notwordbound: { char prevchar, thischar; DEBUG_PRINT1 ("EXECUTING notwordbound.\n"); if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d)) goto fail; prevchar = WORDCHAR_P (d - 1); thischar = WORDCHAR_P (d); if (prevchar != thischar) goto fail; break; } #endif case wordbeg: DEBUG_PRINT1 ("EXECUTING wordbeg.\n"); if (WORDCHAR_P (d) && (AT_STRINGS_BEG (d) || !WORDCHAR_P (d - 1))) break; goto fail; case wordend: DEBUG_PRINT1 ("EXECUTING wordend.\n"); if (!AT_STRINGS_BEG (d) && WORDCHAR_P (d - 1) && (!WORDCHAR_P (d) || AT_STRINGS_END (d))) break; goto fail; #ifdef emacs case before_dot: DEBUG_PRINT1 ("EXECUTING before_dot.\n"); if (PTR_CHAR_POS ((unsigned char *) d) >= point) goto fail; break; case at_dot: DEBUG_PRINT1 ("EXECUTING at_dot.\n"); if (PTR_CHAR_POS ((unsigned char *) d) != point) goto fail; break; case after_dot: DEBUG_PRINT1 ("EXECUTING after_dot.\n"); if (PTR_CHAR_POS ((unsigned char *) d) <= point) goto fail; break; case syntaxspec: DEBUG_PRINT2 ("EXECUTING syntaxspec %d.\n", mcnt); mcnt = *p++; goto matchsyntax; case wordchar: DEBUG_PRINT1 ("EXECUTING Emacs wordchar.\n"); mcnt = (int) Sword; matchsyntax: PREFETCH (); /* Can't use *d++ here; SYNTAX may be an unsafe macro. */ d++; if (SYNTAX (d[-1]) != (enum syntaxcode) mcnt) goto fail; SET_REGS_MATCHED (); break; case notsyntaxspec: DEBUG_PRINT2 ("EXECUTING notsyntaxspec %d.\n", mcnt); mcnt = *p++; goto matchnotsyntax; case notwordchar: DEBUG_PRINT1 ("EXECUTING Emacs notwordchar.\n"); mcnt = (int) Sword; matchnotsyntax: PREFETCH (); /* Can't use *d++ here; SYNTAX may be an unsafe macro. */ d++; if (SYNTAX (d[-1]) == (enum syntaxcode) mcnt) goto fail; SET_REGS_MATCHED (); break; #else /* not emacs */ case wordchar: DEBUG_PRINT1 ("EXECUTING non-Emacs wordchar.\n"); PREFETCH (); if (!WORDCHAR_P (d)) goto fail; SET_REGS_MATCHED (); d++; break; case notwordchar: DEBUG_PRINT1 ("EXECUTING non-Emacs notwordchar.\n"); PREFETCH (); if (WORDCHAR_P (d)) goto fail; SET_REGS_MATCHED (); d++; break; #endif /* not emacs */ default: abort (); } continue; /* Successfully executed one pattern command; keep going. */ /* We goto here if a matching operation fails. */ fail: if (!FAIL_STACK_EMPTY ()) { /* A restart point is known. Restore to that state. */ DEBUG_PRINT1 ("\nFAIL:\n"); POP_FAILURE_POINT (d, p, lowest_active_reg, highest_active_reg, regstart, regend, reg_info); /* If this failure point is a dummy, try the next one. */ if (!p) goto fail; /* If we failed to the end of the pattern, don't examine *p. */ assert (p <= pend); if (p < pend) { char is_a_jump_n = false; /* If failed to a backwards jump that's part of a repetition loop, need to pop this failure point and use the next one. */ switch ((re_opcode_t) *p) { case jump_n: is_a_jump_n = true; case maybe_pop_jump: case pop_failure_jump: case jump: p1 = p + 1; EXTRACT_NUMBER_AND_INCR (mcnt, p1); p1 += mcnt; if ((is_a_jump_n && (re_opcode_t) *p1 == succeed_n) || (!is_a_jump_n && (re_opcode_t) *p1 == on_failure_jump)) goto fail; break; default: /* do nothing */ ; } } if (d >= string1 && d <= end1) dend = end_match_1; } else break; /* Matching at this starting point really fails. */ } /* for (;;) */ if (best_regs_set) goto restore_best_regs; FREE_VARIABLES (); return -1; /* Failure to match. */ } /* re_match_2 */ /* Subroutine definitions for re_match_2. */ /* We are passed P pointing to a register number after a start_memory. Return true if the pattern up to the corresponding stop_memory can match the empty string, and false otherwise. If we find the matching stop_memory, sets P to point to one past its number. Otherwise, sets P to an undefined byte less than or equal to END. We don't handle duplicates properly (yet). */ static char group_match_null_string_p (p, end, reg_info) unsigned char **p, *end; register_info_type *reg_info; { int mcnt; /* Point to after the args to the start_memory. */ unsigned char *p1 = *p + 2; while (p1 < end) { /* Skip over opcodes that can match nothing, and return true or false, as appropriate, when we get to one that can't, or to the matching stop_memory. */ switch ((re_opcode_t) *p1) { /* Could be either a loop or a series of alternatives. */ case on_failure_jump: p1++; EXTRACT_NUMBER_AND_INCR (mcnt, p1); /* If the next operation is not a jump backwards in the pattern. */ if (mcnt >= 0) { /* Go through the on_failure_jumps of the alternatives, seeing if any of the alternatives cannot match nothing. The last alternative starts with only a jump, whereas the rest start with on_failure_jump and end with a jump, e.g., here is the pattern for `a|b|c': /on_failure_jump/0/6/exactn/1/a/jump_past_alt/0/6 /on_failure_jump/0/6/exactn/1/b/jump_past_alt/0/3 /exactn/1/c So, we have to first go through the first (n-1) alternatives and then deal with the last one separately. */ /* Deal with the first (n-1) alternatives, which start with an on_failure_jump (see above) that jumps to right past a jump_past_alt. */ while ((re_opcode_t) p1[mcnt-3] == jump_past_alt) { /* `mcnt' holds how many bytes long the alternative is, including the ending `jump_past_alt' and its number. */ if (!alt_match_null_string_p (p1, p1 + mcnt - 3, reg_info)) return false; /* Move to right after this alternative, including the jump_past_alt. */ p1 += mcnt; /* Break if it's the beginning of an n-th alternative that doesn't begin with an on_failure_jump. */ if ((re_opcode_t) *p1 != on_failure_jump) break; /* Still have to check that it's not an n-th alternative that starts with an on_failure_jump. */ p1++; EXTRACT_NUMBER_AND_INCR (mcnt, p1); if ((re_opcode_t) p1[mcnt-3] != jump_past_alt) { /* Get to the beginning of the n-th alternative. */ p1 -= 3; break; } } /* Deal with the last alternative: go back and get number of the `jump_past_alt' just before it. `mcnt' contains the length of the alternative. */ EXTRACT_NUMBER (mcnt, p1 - 2); if (!alt_match_null_string_p (p1, p1 + mcnt, reg_info)) return false; p1 += mcnt; /* Get past the n-th alternative. */ } /* if mcnt > 0 */ break; case stop_memory: assert (p1[1] == **p); *p = p1 + 2; return true; default: if (!common_op_match_null_string_p (&p1, end, reg_info)) return false; } } /* while p1 < end */ return false; } /* group_match_null_string_p */ /* Similar to group_match_null_string_p, but doesn't deal with alternatives: It expects P to be the first byte of a single alternative and END one byte past the last. The alternative can contain groups. */ static char alt_match_null_string_p (p, end, reg_info) unsigned char *p, *end; register_info_type *reg_info; { int mcnt; unsigned char *p1 = p; while (p1 < end) { /* Skip over opcodes that can match nothing, and break when we get to one that can't. */ switch ((re_opcode_t) *p1) { /* It's a loop. */ case on_failure_jump: p1++; EXTRACT_NUMBER_AND_INCR (mcnt, p1); p1 += mcnt; break; default: if (!common_op_match_null_string_p (&p1, end, reg_info)) return false; } } /* while p1 < end */ return true; } /* alt_match_null_string_p */ /* Deals with the ops common to group_match_null_string_p and alt_match_null_string_p. Sets P to one after the op and its arguments, if any. */ static char common_op_match_null_string_p (p, end, reg_info) unsigned char **p, *end; register_info_type *reg_info; { int mcnt; char ret; int reg_no; unsigned char *p1 = *p; switch ((re_opcode_t) *p1++) { case no_op: case begline: case endline: case begbuf: case endbuf: case wordbeg: case wordend: case wordbound: case notwordbound: #ifdef emacs case before_dot: case at_dot: case after_dot: #endif break; case start_memory: reg_no = *p1; assert (reg_no > 0 && reg_no <= MAX_REGNUM); ret = group_match_null_string_p (&p1, end, reg_info); /* Have to set this here in case we're checking a group which contains a group and a back reference to it. */ if (REG_MATCH_NULL_STRING_P (reg_info[reg_no]) == MATCH_NULL_UNSET_VALUE) REG_MATCH_NULL_STRING_P (reg_info[reg_no]) = ret; if (!ret) return false; break; /* If this is an optimized succeed_n for zero times, make the jump. */ case jump: EXTRACT_NUMBER_AND_INCR (mcnt, p1); if (mcnt >= 0) p1 += mcnt; else return false; break; case succeed_n: /* Get to the number of times to succeed. */ p1 += 2; EXTRACT_NUMBER_AND_INCR (mcnt, p1); if (mcnt == 0) { p1 -= 4; EXTRACT_NUMBER_AND_INCR (mcnt, p1); p1 += mcnt; } else return false; break; case duplicate: if (!REG_MATCH_NULL_STRING_P (reg_info[*p1])) return false; break; case set_number_at: p1 += 4; default: /* All other opcodes mean we cannot match the empty string. */ return false; } *p = p1; return true; } /* common_op_match_null_string_p */ /* Return zero if TRANSLATE[S1] and TRANSLATE[S2] are identical for LEN bytes; nonzero otherwise. */ static int bcmp_translate (s1, s2, len, translate) const char *s1, *s2; register int len; RE_TRANSLATE_TYPE translate; { register const unsigned char *p1 = (const unsigned char *) s1; register const unsigned char *p2 = (const unsigned char *) s2; while (len) { if (translate[*p1++] != translate[*p2++]) return 1; len--; } return 0; } /* Entry points for GNU code. */ /* re_compile_pattern is the GNU regular expression compiler: it compiles PATTERN (of length SIZE) and puts the result in BUFP. Returns 0 if the pattern was valid, otherwise an error string. Assumes the `allocated' (and perhaps `buffer') and `translate' fields are set in BUFP on entry. We call regex_compile to do the actual compilation. */ const char * re_compile_pattern (pattern, length, bufp) const char *pattern; size_t length; struct re_pattern_buffer *bufp; { reg_errcode_t ret; /* GNU code is written to assume at least RE_NREGS registers will be set (and at least one extra will be -1). */ bufp->regs_allocated = REGS_UNALLOCATED; /* And GNU code determines whether or not to get register information by passing null for the REGS argument to re_match, etc., not by setting no_sub. */ bufp->no_sub = 0; /* Match anchors at newline. */ bufp->newline_anchor = 1; ret = regex_compile (pattern, length, re_syntax_options, bufp); if (!ret) return NULL; return gettext (re_error_msgid + re_error_msgid_idx[(int) ret]); } #ifdef _LIBC weak_alias (__re_compile_pattern, re_compile_pattern) #endif /* Entry points compatible with 4.2 BSD regex library. We don't define them unless specifically requested. */ #if defined _REGEX_RE_COMP || defined _LIBC /* BSD has one and only one pattern buffer. */ static struct re_pattern_buffer re_comp_buf; char * #ifdef _LIBC /* Make these definitions weak in libc, so POSIX programs can redefine these names if they don't use our functions, and still use regcomp/regexec below without link errors. */ weak_function #endif re_comp (s) const char *s; { reg_errcode_t ret; if (!s) { if (!re_comp_buf.buffer) return gettext ("No previous regular expression"); return 0; } if (!re_comp_buf.buffer) { re_comp_buf.buffer = (unsigned char *) malloc (200); if (re_comp_buf.buffer == NULL) return (char *) gettext (re_error_msgid + re_error_msgid_idx[(int) REG_ESPACE]); re_comp_buf.allocated = 200; re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH); if (re_comp_buf.fastmap == NULL) return (char *) gettext (re_error_msgid + re_error_msgid_idx[(int) REG_ESPACE]); } /* Since `re_exec' always passes NULL for the `regs' argument, we don't need to initialize the pattern buffer fields which affect it. */ /* Match anchors at newlines. */ re_comp_buf.newline_anchor = 1; ret = regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf); if (!ret) return NULL; /* Yes, we're discarding `const' here if !HAVE_LIBINTL. */ return (char *) gettext (re_error_msgid + re_error_msgid_idx[(int) ret]); } int #ifdef _LIBC weak_function #endif re_exec (s) const char *s; { const int len = strlen (s); return 0 <= re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0); } #endif /* _REGEX_RE_COMP */ /* POSIX.2 functions. Don't define these for Emacs. */ #ifndef emacs /* regcomp takes a regular expression as a string and compiles it. PREG is a regex_t *. We do not expect any fields to be initialized, since POSIX says we shouldn't. Thus, we set `buffer' to the compiled pattern; `used' to the length of the compiled pattern; `syntax' to RE_SYNTAX_POSIX_EXTENDED if the REG_EXTENDED bit in CFLAGS is set; otherwise, to RE_SYNTAX_POSIX_BASIC; `newline_anchor' to REG_NEWLINE being set in CFLAGS; `fastmap' to an allocated space for the fastmap; `fastmap_accurate' to zero; `re_nsub' to the number of subexpressions in PATTERN. PATTERN is the address of the pattern string. CFLAGS is a series of bits which affect compilation. If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we use POSIX basic syntax. If REG_NEWLINE is set, then . and [^...] don't match newline. Also, regexec will try a match beginning after every newline. If REG_ICASE is set, then we considers upper- and lowercase versions of letters to be equivalent when matching. If REG_NOSUB is set, then when PREG is passed to regexec, that routine will report only success or failure, and nothing about the registers. It returns 0 if it succeeds, nonzero if it doesn't. (See regex.h for the return codes and their meanings.) */ int regcomp (preg, pattern, cflags) regex_t *preg; const char *pattern; int cflags; { reg_errcode_t ret; reg_syntax_t syntax = (cflags & REG_EXTENDED) ? RE_SYNTAX_POSIX_EXTENDED : RE_SYNTAX_POSIX_BASIC; /* regex_compile will allocate the space for the compiled pattern. */ preg->buffer = 0; preg->allocated = 0; preg->used = 0; /* Try to allocate space for the fastmap. */ preg->fastmap = (char *) malloc (1 << BYTEWIDTH); if (cflags & REG_ICASE) { unsigned i; preg->translate = (RE_TRANSLATE_TYPE) malloc (CHAR_SET_SIZE * sizeof (*(RE_TRANSLATE_TYPE)0)); if (preg->translate == NULL) return (int) REG_ESPACE; /* Map uppercase characters to corresponding lowercase ones. */ for (i = 0; i < CHAR_SET_SIZE; i++) preg->translate[i] = ISUPPER (i) ? TOLOWER (i) : i; } else preg->translate = NULL; /* If REG_NEWLINE is set, newlines are treated differently. */ if (cflags & REG_NEWLINE) { /* REG_NEWLINE implies neither . nor [^...] match newline. */ syntax &= ~RE_DOT_NEWLINE; syntax |= RE_HAT_LISTS_NOT_NEWLINE; /* It also changes the matching behavior. */ preg->newline_anchor = 1; } else preg->newline_anchor = 0; preg->no_sub = !!(cflags & REG_NOSUB); /* POSIX says a null character in the pattern terminates it, so we can use strlen here in compiling the pattern. */ ret = regex_compile (pattern, strlen (pattern), syntax, preg); /* POSIX doesn't distinguish between an unmatched open-group and an unmatched close-group: both are REG_EPAREN. */ if (ret == REG_ERPAREN) ret = REG_EPAREN; if (ret == REG_NOERROR && preg->fastmap) { /* Compute the fastmap now, since regexec cannot modify the pattern buffer. */ if (re_compile_fastmap (preg) == -2) { /* Some error occured while computing the fastmap, just forget about it. */ free (preg->fastmap); preg->fastmap = NULL; } } return (int) ret; } #ifdef _LIBC weak_alias (__regcomp, regcomp) #endif /* regexec searches for a given pattern, specified by PREG, in the string STRING. If NMATCH is zero or REG_NOSUB was set in the cflags argument to `regcomp', we ignore PMATCH. Otherwise, we assume PMATCH has at least NMATCH elements, and we set them to the offsets of the corresponding matched substrings. EFLAGS specifies `execution flags' which affect matching: if REG_NOTBOL is set, then ^ does not match at the beginning of the string; if REG_NOTEOL is set, then $ does not match at the end. We return 0 if we find a match and REG_NOMATCH if not. */ int regexec (preg, string, nmatch, pmatch, eflags) const regex_t *preg; const char *string; size_t nmatch; regmatch_t pmatch[]; int eflags; { int ret; struct re_registers regs; regex_t private_preg; int len = strlen (string); char want_reg_info = !preg->no_sub && nmatch > 0; private_preg = *preg; private_preg.not_bol = !!(eflags & REG_NOTBOL); private_preg.not_eol = !!(eflags & REG_NOTEOL); /* The user has told us exactly how many registers to return information about, via `nmatch'. We have to pass that on to the matching routines. */ private_preg.regs_allocated = REGS_FIXED; if (want_reg_info) { regs.num_regs = nmatch; regs.start = TALLOC (nmatch * 2, regoff_t); if (regs.start == NULL) return (int) REG_NOMATCH; regs.end = regs.start + nmatch; } /* Perform the searching operation. */ ret = re_search (&private_preg, string, len, /* start: */ 0, /* range: */ len, want_reg_info ? ®s : (struct re_registers *) 0); /* Copy the register information to the POSIX structure. */ if (want_reg_info) { if (ret >= 0) { unsigned r; for (r = 0; r < nmatch; r++) { pmatch[r].rm_so = regs.start[r]; pmatch[r].rm_eo = regs.end[r]; } } /* If we needed the temporary register info, free the space now. */ free (regs.start); } /* We want zero return to mean success, unlike `re_search'. */ return ret >= 0 ? (int) REG_NOERROR : (int) REG_NOMATCH; } #ifdef _LIBC weak_alias (__regexec, regexec) #endif /* Returns a message corresponding to an error code, ERRCODE, returned from either regcomp or regexec. We don't use PREG here. */ size_t regerror (int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size) /* gcc 4.7.0 om MinGW stumbles on the K&R declaration here */ /* int errcode; */ /* const regex_t *preg; */ /* char *errbuf; */ /* size_t errbuf_size; */ { const char *msg; size_t msg_size; if (errcode < 0 || errcode >= (int) (sizeof (re_error_msgid_idx) / sizeof (re_error_msgid_idx[0]))) /* Only error codes returned by the rest of the code should be passed to this routine. If we are given anything else, or if other regex code generates an invalid error code, then the program has a bug. Dump core so we can fix it. */ abort (); msg = gettext (re_error_msgid + re_error_msgid_idx[errcode]); msg_size = strlen (msg) + 1; /* Includes the null. */ if (errbuf_size != 0) { if (msg_size > errbuf_size) { #if defined HAVE_MEMPCPY || defined _LIBC *((char *) __mempcpy (errbuf, msg, errbuf_size - 1)) = '\0'; #else memcpy (errbuf, msg, errbuf_size - 1); errbuf[errbuf_size - 1] = 0; #endif } else memcpy (errbuf, msg, msg_size); } return msg_size; } #ifdef _LIBC weak_alias (__regerror, regerror) #endif /* Free dynamically allocated space used by PREG. */ void regfree (preg) regex_t *preg; { if (preg->buffer != NULL) free (preg->buffer); preg->buffer = NULL; preg->allocated = 0; preg->used = 0; if (preg->fastmap != NULL) free (preg->fastmap); preg->fastmap = NULL; preg->fastmap_accurate = 0; if (preg->translate != NULL) free (preg->translate); preg->translate = NULL; } #ifdef _LIBC weak_alias (__regfree, regfree) #endif #endif /* not emacs */ #endif /* for win32 */ static void dummy_compilation_unit(void) { /* nothing */ } gtkwave-3.3.66/src/timeentry.h0000664000076400007640000000077111523063250015561 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2010 * * 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. */ #ifndef WAVE_TIMEENTRY_H #define WAVE_TIMEENTRY_H void time_update(void); void from_entry_callback(GtkWidget *widget, GtkWidget *entry); void to_entry_callback(GtkWidget *widget, GtkWidget *entry); #endif gtkwave-3.3.66/src/wavealloca.h0000664000076400007640000000120312341266475015663 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999. * * 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. */ #ifndef WAVE_ALLOCA_H #define WAVE_ALLOCA_H #include #ifdef HAVE_ALLOCA_H #include #elif defined(__GNUC__) #ifndef __MINGW32__ #ifndef alloca #define alloca __builtin_alloca #endif #else #include #endif #elif defined(_MSC_VER) #include #define alloca _alloca #endif #define wave_alloca alloca #endif gtkwave-3.3.66/src/entry.c0000664000076400007640000001352012362030630014667 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2013. * * 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. */ #include "globals.h" #include #include #include "gtk12compat.h" #include "menu.h" #include "debug.h" #include #include #ifdef MAC_INTEGRATION /* disabled for now as we can't get it to auto enable when it comes up */ #define WAVE_MAC_USE_ENTRY #endif #ifndef WAVE_MAC_USE_ENTRY static gint keypress_local(GtkWidget *widget, GdkEventKey *event, gpointer data) { (void)widget; (void)event; (void)data; if(GLOBALS->window_entry_c_1) { gdk_window_raise(GLOBALS->window_entry_c_1->window); } return(FALSE); } #endif #ifndef WAVE_MAC_USE_ENTRY static void enter_callback(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; G_CONST_RETURN gchar *entry_text; int len; entry_text = gtk_entry_get_text(GTK_ENTRY(GLOBALS->entry_entry_c_1)); entry_text = entry_text ? entry_text : ""; DEBUG(printf("Entry contents: %s\n", entry_text)); if(!(len=strlen(entry_text))) GLOBALS->entrybox_text=NULL; else strcpy((GLOBALS->entrybox_text=(char *)malloc_2(len+1)),entry_text); wave_gtk_grab_remove(GLOBALS->window_entry_c_1); gtk_widget_destroy(GLOBALS->window_entry_c_1); GLOBALS->window_entry_c_1 = NULL; GLOBALS->cleanup_entry_c_1(); } static void destroy_callback(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; DEBUG(printf("Entry Cancel\n")); GLOBALS->entrybox_text=NULL; wave_gtk_grab_remove(GLOBALS->window_entry_c_1); gtk_widget_destroy(GLOBALS->window_entry_c_1); GLOBALS->window_entry_c_1 = NULL; } #endif void entrybox(char *title, int width, char *dflt_text, char *comment, int maxch, GtkSignalFunc func) { #ifndef WAVE_MAC_USE_ENTRY GtkWidget *vbox, *hbox; GtkWidget *button1, *button2; int height = (comment) ? 75 : 60; #endif GLOBALS->cleanup_entry_c_1=func; /* fix problem where ungrab doesn't occur if button pressed + simultaneous accelerator key occurs */ if(GLOBALS->in_button_press_wavewindow_c_1) { gdk_pointer_ungrab(GDK_CURRENT_TIME); } if(GLOBALS->wave_script_args) { char *s = NULL; while((!s)&&(GLOBALS->wave_script_args->curr)) s = wave_script_args_fgetmalloc_stripspaces(GLOBALS->wave_script_args); if(s) { fprintf(stderr, "GTKWAVE | Entry '%s'\n", s); GLOBALS->entrybox_text = s; GLOBALS->cleanup_entry_c_1(); } else { GLOBALS->entrybox_text = NULL; } return; } #ifdef WAVE_MAC_USE_ENTRY { char *out_text_entry = NULL; entrybox_req_bridge(title, width, dflt_text, comment, maxch, &out_text_entry); if(out_text_entry) { int len=strlen(out_text_entry); if(!len) GLOBALS->entrybox_text=NULL; else strcpy((GLOBALS->entrybox_text=(char *)malloc_2(len+1)),out_text_entry); free(out_text_entry); GLOBALS->cleanup_entry_c_1(); } else { GLOBALS->entrybox_text = NULL; } return; } #else /* create a new modal window */ GLOBALS->window_entry_c_1 = gtk_window_new(GLOBALS->disable_window_manager ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL); install_focus_cb(GLOBALS->window_entry_c_1, ((char *)&GLOBALS->window_entry_c_1) - ((char *)GLOBALS)); gtk_widget_set_usize( GTK_WIDGET (GLOBALS->window_entry_c_1), width, height); gtk_window_set_title(GTK_WINDOW (GLOBALS->window_entry_c_1), title); gtkwave_signal_connect(GTK_OBJECT (GLOBALS->window_entry_c_1), "delete_event",(GtkSignalFunc) destroy_callback, NULL); gtk_window_set_policy(GTK_WINDOW(GLOBALS->window_entry_c_1), FALSE, FALSE, FALSE); vbox = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (GLOBALS->window_entry_c_1), vbox); gtk_widget_show (vbox); if (comment) { GtkWidget *label, *cbox; cbox = gtk_hbox_new (FALSE, 1); gtk_box_pack_start (GTK_BOX (vbox), cbox, FALSE, FALSE, 0); gtk_widget_show (cbox); label = gtk_label_new(comment); gtk_widget_show (label); gtk_container_add (GTK_CONTAINER (cbox), label); GTK_WIDGET_SET_FLAGS (label, GTK_CAN_DEFAULT); } GLOBALS->entry_entry_c_1 = gtk_entry_new_with_max_length (maxch); gtkwave_signal_connect(GTK_OBJECT(GLOBALS->entry_entry_c_1), "activate",GTK_SIGNAL_FUNC(enter_callback),GLOBALS->entry_entry_c_1); gtk_entry_set_text (GTK_ENTRY (GLOBALS->entry_entry_c_1), dflt_text); gtk_entry_select_region (GTK_ENTRY (GLOBALS->entry_entry_c_1),0, GTK_ENTRY(GLOBALS->entry_entry_c_1)->text_length); gtk_box_pack_start (GTK_BOX (vbox), GLOBALS->entry_entry_c_1, FALSE, FALSE, 0); gtk_widget_show (GLOBALS->entry_entry_c_1); hbox = gtk_hbox_new (FALSE, 1); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_widget_show (hbox); button1 = gtk_button_new_with_label ("OK"); gtk_widget_set_usize(button1, 100, -1); gtkwave_signal_connect(GTK_OBJECT (button1), "clicked", GTK_SIGNAL_FUNC(enter_callback), NULL); gtk_widget_show (button1); gtk_container_add (GTK_CONTAINER (hbox), button1); GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT); gtkwave_signal_connect_object (GTK_OBJECT (button1), "realize", (GtkSignalFunc) gtk_widget_grab_default, GTK_OBJECT (button1)); button2 = gtk_button_new_with_label ("Cancel"); gtk_widget_set_usize(button2, 100, -1); gtkwave_signal_connect(GTK_OBJECT (button2), "clicked", GTK_SIGNAL_FUNC(destroy_callback), NULL); GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT); gtk_widget_show (button2); gtk_container_add (GTK_CONTAINER (hbox), button2); gtk_widget_show(GLOBALS->window_entry_c_1); wave_gtk_grab_add(GLOBALS->window_entry_c_1); gdk_window_raise(GLOBALS->window_entry_c_1->window); gtk_signal_connect(GTK_OBJECT(GLOBALS->window_entry_c_1), "key_press_event",GTK_SIGNAL_FUNC(keypress_local), NULL); #endif } gtkwave-3.3.66/src/ttranslate.h0000664000076400007640000000130312341266475015727 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2010. * * 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. */ #include "globals.h" #ifndef WAVE_TTRANSLATE_H #define WAVE_TTRANSLATE_H #include #include #include #include "fgetdynamic.h" #include "debug.h" #define TTRANS_FILTER_MAX (128) void ttrans_searchbox(char *title); void init_ttrans_data(void); int install_ttrans_filter(int which); void set_current_translate_ttrans(char *name); void remove_all_ttrans_filters(void); #endif gtkwave-3.3.66/src/tree_component.c0000664000076400007640000000553012341266475016570 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2011. * * 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. */ #include #include "globals.h" #include "tree_component.h" #ifdef _WAVE_HAVE_JUDY /* Judy version */ void iter_through_comp_name_table(void) { Pvoid_t PJArray = GLOBALS->comp_name_judy; PPvoid_t PPValue; if(GLOBALS->comp_name_judy) { char *mem = malloc_2(GLOBALS->comp_name_total_stringmem); char **idx = GLOBALS->comp_name_idx = calloc_2(GLOBALS->comp_name_serial, sizeof(char *)); char *Index = calloc_2(GLOBALS->comp_name_longest + 1, sizeof(char)); char *pnt = mem; for (PPValue = JudySLFirst (PJArray, (uint8_t *)Index, PJE0); PPValue != (PPvoid_t) NULL; PPValue = JudySLNext (PJArray, (uint8_t *)Index, PJE0)) { int slen = strlen(Index); memcpy(pnt, Index, slen+1); idx[(*(char **)PPValue) - ((char *)NULL)] = pnt; pnt += (slen + 1); } free_2(Index); JudySLFreeArray(&GLOBALS->comp_name_judy, PJE0); GLOBALS->comp_name_judy = NULL; } } int add_to_comp_name_table(const char *s, int slen) { PPvoid_t PPValue = JudySLGet(GLOBALS->comp_name_judy, (uint8_t *)s, PJE0); if(PPValue) { return((*(char **)PPValue) - ((char *)NULL) + 1); } GLOBALS->comp_name_total_stringmem += (slen + 1); if(slen > GLOBALS->comp_name_longest) { GLOBALS->comp_name_longest = slen; } PPValue = JudySLIns(&GLOBALS->comp_name_judy, (uint8_t *)s, PJE0); *((char **)PPValue) = ((char *)NULL) + GLOBALS->comp_name_serial; return(++GLOBALS->comp_name_serial); /* always nonzero */ } #else /* JRB alternate (not as memory efficient initially) */ void iter_through_comp_name_table(void) { if(GLOBALS->comp_name_jrb) { char *mem = malloc_2(GLOBALS->comp_name_total_stringmem); char **idx = GLOBALS->comp_name_idx = calloc_2(GLOBALS->comp_name_serial, sizeof(char *)); char *Index; char *pnt = mem; JRB node; jrb_traverse(node, GLOBALS->comp_name_jrb) { Index = node->key.s; int slen = strlen(Index); memcpy(pnt, Index, slen+1); free_2(Index); idx[node->val.i] = pnt; pnt += (slen + 1); } jrb_free_tree(GLOBALS->comp_name_jrb); GLOBALS->comp_name_jrb = NULL; } } int add_to_comp_name_table(const char *s, int slen) { JRB str; Jval jv; if(!GLOBALS->comp_name_jrb) { GLOBALS->comp_name_jrb = make_jrb(); } str = jrb_find_str(GLOBALS->comp_name_jrb, s); if(str) { return(str->val.i + 1); } GLOBALS->comp_name_total_stringmem += (slen + 1); if(slen > GLOBALS->comp_name_longest) { GLOBALS->comp_name_longest = slen; } jv.i = GLOBALS->comp_name_serial; jrb_insert_str(GLOBALS->comp_name_jrb, strdup_2(s), jv); return(++GLOBALS->comp_name_serial); /* always nonzero */ } #endif gtkwave-3.3.66/src/jrb.c0000664000076400007640000003026512341266475014327 0ustar bybellbybell/* * Libraries for fields, doubly-linked lists and red-black trees. * Copyright (C) 2001 James S. Plank * * This library 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 2.1 of the License, or (at your option) any later version. */ /* Revision 1.2. Jim Plank */ /* Original code by Jim Plank (plank@cs.utk.edu) */ /* modified for THINK C 6.0 for Macintosh by Chris Bartley */ #include #include #include #include #include "jrb.h" static void mk_new_int(JRB l, JRB r, JRB p, int il); static JRB lprev(JRB n); static JRB rprev(JRB n); static void recolor(JRB n); static void single_rotate(JRB y, int l); #define isred(n) (n->red) #define isblack(n) (!isred(n)) #define isleft(n) (n->left) #define isright(n) (!isleft(n)) #define isint(n) (n->internal) #define isext(n) (!isint(n)) #define ishead(n) (n->roothead & 2) #define isroot(n) (n->roothead & 1) #define getlext(n) ((struct jrb_node *)(n->key.v)) #define setlext(node, val) node->key.v = (void *) (val) #define getrext(n) ((struct jrb_node *)(n->val.v)) #define setrext(node, value) node->val.v = (void *) (value) #define setred(n) n->red = 1 #define setblack(n) n->red = 0 #define setleft(n) n->left = 1 #define setright(n) n->left = 0 #define sethead(n) (n->roothead |= 2) #define setroot(n) (n->roothead |= 1) #define setint(n) n->internal = 1 #define setext(n) n->internal = 0 #define setnormal(n) n->roothead = 0 #define sibling(n) ((isleft(n)) ? n->parent->blink : n->parent->flink) static void insert(JRB item, JRB list) /* Inserts to the end of a list */ { JRB last_node; last_node = list->blink; list->blink = item; last_node->flink = item; item->blink = last_node; item->flink = list; } static void delete_item(JRB item) /* Deletes an arbitrary iterm */ { item->flink->blink = item->blink; item->blink->flink = item->flink; } #define mk_new_ext(new, kkkey, vvval) {\ new = (JRB) calloc(1, sizeof(struct jrb_node));\ new->val = vvval;\ new->key = kkkey;\ setext(new);\ setblack(new);\ setnormal(new);\ } static void mk_new_int(JRB l, JRB r, JRB p, int il) { JRB newnode; newnode = (JRB) calloc(1, sizeof(struct jrb_node)); setint(newnode); setred(newnode); setnormal(newnode); newnode->flink = l; newnode->blink = r; newnode->parent = p; setlext(newnode, l); setrext(newnode, r); l->parent = newnode; r->parent = newnode; setleft(l); setright(r); if (ishead(p)) { p->parent = newnode; setroot(newnode); } else if (il) { setleft(newnode); p->flink = newnode; } else { setright(newnode); p->blink = newnode; } recolor(newnode); } JRB lprev(JRB n) { if (ishead(n)) return n; while (!isroot(n)) { if (isright(n)) return n->parent; n = n->parent; } return n->parent; } JRB rprev(JRB n) { if (ishead(n)) return n; while (!isroot(n)) { if (isleft(n)) return n->parent; n = n->parent; } return n->parent; } JRB make_jrb(void) { JRB head; head = (JRB) calloc (1, sizeof(struct jrb_node)); head->flink = head; head->blink = head; head->parent = head; head->key.s = ""; sethead(head); return head; } JRB jrb_find_gte_str(JRB n, const char *key, int *fnd) { int cmp; *fnd = 0; if (!ishead(n)) { fprintf(stderr, "jrb_find_gte_str called on non-head 0x%p\n", (void *)n); exit(1); } if (n->parent == n) return n; cmp = strcmp(key, n->blink->key.s); if (cmp == 0) { *fnd = 1; return n->blink; } if (cmp > 0) return n; else n = n->parent; while (1) { if (isext(n)) return n; cmp = strcmp(key, getlext(n)->key.s); if (cmp == 0) { *fnd = 1; return getlext(n); } if (cmp < 0) n = n->flink ; else n = n->blink; } } JRB jrb_find_str(JRB n, const char *key) { int fnd; JRB j; j = jrb_find_gte_str(n, key, &fnd); if (fnd) return j; else return NULL; } JRB jrb_find_gte_int(JRB n, int ikey, int *fnd) { *fnd = 0; if (!ishead(n)) { fprintf(stderr, "jrb_find_gte_int called on non-head 0x%p\n", (void *)n); exit(1); } if (n->parent == n) return n; if (ikey == n->blink->key.i) { *fnd = 1; return n->blink; } if (ikey > n->blink->key.i) return n; else n = n->parent; while (1) { if (isext(n)) return n; if (ikey == getlext(n)->key.i) { *fnd = 1; return getlext(n); } n = (ikey < getlext(n)->key.i) ? n->flink : n->blink; } } JRB jrb_find_int(JRB n, int ikey) { int fnd; JRB j; j = jrb_find_gte_int(n, ikey, &fnd); if (fnd) return j; else return NULL; } JRB jrb_find_gte_vptr(JRB n, void *vkey, int *fnd) { *fnd = 0; if (!ishead(n)) { fprintf(stderr, "jrb_find_gte_int called on non-head 0x%p\n", (void *)n); exit(1); } if (n->parent == n) return n; if ((char *)vkey == (char *)n->blink->key.v) { *fnd = 1; return n->blink; } if ((char *)vkey > (char *)n->blink->key.v) return n; else n = n->parent; while (1) { if (isext(n)) return n; if ((char *)vkey == (char *)getlext(n)->key.v) { *fnd = 1; return getlext(n); } n = ((char *)vkey < (char *)getlext(n)->key.v) ? n->flink : n->blink; } } JRB jrb_find_vptr(JRB n, void *vkey) { int fnd; JRB j; j = jrb_find_gte_vptr(n, vkey, &fnd); if (fnd) return j; else return NULL; } JRB jrb_find_gte_gen(JRB n, Jval key,int (*fxn)(Jval, Jval), int *fnd) { int cmp; *fnd = 0; if (!ishead(n)) { fprintf(stderr, "jrb_find_gte_str called on non-head 0x%p\n", (void *)n); exit(1); } if (n->parent == n) return n; cmp = (*fxn)(key, n->blink->key); if (cmp == 0) { *fnd = 1; return n->blink; } if (cmp > 0) return n; else n = n->parent; while (1) { if (isext(n)) return n; cmp = (*fxn)(key, getlext(n)->key); if (cmp == 0) { *fnd = 1; return getlext(n); } if (cmp < 0) n = n->flink ; else n = n->blink; } } JRB jrb_find_gen(JRB n, Jval key, int (*fxn)(Jval, Jval)) { int fnd; JRB j; j = jrb_find_gte_gen(n, key, fxn, &fnd); if (fnd) return j; else return NULL; } static JRB jrb_insert_b(JRB n, Jval key, Jval val) { JRB newleft, newright, newnode, p; if (ishead(n)) { if (n->parent == n) { /* Tree is empty */ mk_new_ext(newnode, key, val); insert(newnode, n); n->parent = newnode; newnode->parent = n; setroot(newnode); return newnode; } else { mk_new_ext(newright, key, val); insert(newright, n); newleft = newright->blink; setnormal(newleft); mk_new_int(newleft, newright, newleft->parent, isleft(newleft)); p = rprev(newright); if (!ishead(p)) setlext(p, newright); return newright; } } else { mk_new_ext(newleft, key, val); insert(newleft, n); setnormal(n); mk_new_int(newleft, n, n->parent, isleft(n)); p = lprev(newleft); if (!ishead(p)) setrext(p, newleft); return newleft; } } static void recolor(JRB n) { JRB p, gp, s; int done = 0; while(!done) { if (isroot(n)) { setblack(n); return; } p = n->parent; if (isblack(p)) return; if (isroot(p)) { setblack(p); return; } gp = p->parent; s = sibling(p); if (isred(s)) { setblack(p); setred(gp); setblack(s); n = gp; } else { done = 1; } } /* p's sibling is black, p is red, gp is black */ if ((isleft(n) == 0) == (isleft(p) == 0)) { single_rotate(gp, isleft(n)); setblack(p); setred(gp); } else { single_rotate(p, isleft(n)); single_rotate(gp, isleft(n)); setblack(n); setred(gp); } } static void single_rotate(JRB y, int l) { int rl = 0, ir; JRB x, yp; ir = isroot(y); yp = y->parent; if (!ir) { rl = isleft(y); } if (l) { x = y->flink; y->flink = x->blink; setleft(y->flink); y->flink->parent = y; x->blink = y; setright(y); } else { x = y->blink; y->blink = x->flink; setright(y->blink); y->blink->parent = y; x->flink = y; setleft(y); } x->parent = yp; y->parent = x; if (ir) { yp->parent = x; setnormal(y); setroot(x); } else { if (rl) { yp->flink = x; setleft(x); } else { yp->blink = x; setright(x); } } } void jrb_delete_node(JRB n) { JRB s, p, gp; char ir; if (isint(n)) { fprintf(stderr, "Cannot delete an internal node: 0x%p\n", (void *)n); exit(1); } if (ishead(n)) { fprintf(stderr, "Cannot delete the head of an jrb_tree: 0x%p\n", (void *)n); exit(1); } delete_item(n); /* Delete it from the list */ p = n->parent; /* The only node */ if (isroot(n)) { p->parent = p; free(n); return; } s = sibling(n); /* The only node after deletion */ if (isroot(p)) { s->parent = p->parent; s->parent->parent = s; setroot(s); free(p); free(n); return; } gp = p->parent; /* Set parent to sibling */ s->parent = gp; if (isleft(p)) { gp->flink = s; setleft(s); } else { gp->blink = s; setright(s); } ir = isred(p); free(p); free(n); if (isext(s)) { /* Update proper rext and lext values */ p = lprev(s); if (!ishead(p)) setrext(p, s); p = rprev(s); if (!ishead(p)) setlext(p, s); } else if (isblack(s)) { fprintf(stderr, "DELETION PROB -- sib is black, internal\n"); exit(1); } else { p = lprev(s); if (!ishead(p)) setrext(p, s->flink); p = rprev(s); if (!ishead(p)) setlext(p, s->blink); setblack(s); return; } if (ir) return; /* Recolor */ n = s; p = n->parent; s = sibling(n); while(isblack(p) && isblack(s) && isint(s) && isblack(s->flink) && isblack(s->blink)) { setred(s); n = p; if (isroot(n)) return; p = n->parent; s = sibling(n); } if (isblack(p) && isred(s)) { /* Rotation 2.3b */ single_rotate(p, isright(n)); setred(p); setblack(s); s = sibling(n); } { JRB x, z; char il; if (isext(s)) { fprintf(stderr, "DELETION ERROR: sibling not internal\n"); exit(1); } il = isleft(n); x = il ? s->flink : s->blink ; z = sibling(x); if (isred(z)) { /* Rotation 2.3f */ single_rotate(p, !il); setblack(z); if (isred(p)) setred(s); else setblack(s); setblack(p); } else if (isblack(x)) { /* Recoloring only (2.3c) */ if (isred(s) || isblack(p)) { fprintf(stderr, "DELETION ERROR: 2.3c not quite right\n"); exit(1); } setblack(p); setred(s); return; } else if (isred(p)) { /* 2.3d */ single_rotate(s, il); single_rotate(p, !il); setblack(x); setred(s); return; } else { /* 2.3e */ single_rotate(s, il); single_rotate(p, !il); setblack(x); return; } } } int jrb_nblack(JRB n) { int nb; if (ishead(n) || isint(n)) { fprintf(stderr, "ERROR: jrb_nblack called on a non-external node 0x%p\n", (void *)n); exit(1); } nb = 0; while(!ishead(n)) { if (isblack(n)) nb++; n = n->parent; } return nb; } int jrb_plength(JRB n) { int pl; if (ishead(n) || isint(n)) { fprintf(stderr, "ERROR: jrb_plength called on a non-external node 0x%p\n", (void *)n); exit(1); } pl = 0; while(!ishead(n)) { pl++; n = n->parent; } return pl; } void jrb_free_tree(JRB n) { if (!ishead(n)) { fprintf(stderr, "ERROR: Rb_free_tree called on a non-head node\n"); exit(1); } while(jrb_first(n) != jrb_nil(n)) { jrb_delete_node(jrb_first(n)); } free(n); } Jval jrb_val(JRB n) { return n->val; } JRB jrb_insert_str(JRB tree, char *key, Jval val) { Jval k; int fnd; k.s = key; return jrb_insert_b(jrb_find_gte_str(tree, key, &fnd), k, val); } JRB jrb_insert_int(JRB tree, int ikey, Jval val) { Jval k; int fnd; k.i = ikey; return jrb_insert_b(jrb_find_gte_int(tree, ikey, &fnd), k, val); } JRB jrb_insert_vptr(JRB tree, void *vkey, Jval val) { Jval k; int fnd; k.v = vkey; return jrb_insert_b(jrb_find_gte_vptr(tree, vkey, &fnd), k, val); } JRB jrb_insert_gen(JRB tree, Jval key, Jval val, int (*func)(Jval, Jval)) { int fnd; return jrb_insert_b(jrb_find_gte_gen(tree, key, func, &fnd), key, val); } gtkwave-3.3.66/src/strace.c0000664000076400007640000012755512523241774015041 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2013. * * 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. */ #include #include "globals.h" #include #include "gtk12compat.h" #include "strace.h" #include "currenttime.h" #include "hierpack.h" #define WV_STRACE_CTX "strace_ctx" /* need to do this every time you connect a signal */ #ifdef WAVE_USE_GTK2 #define WV_STRACE_CURWIN(x) g_object_set_data(G_OBJECT(x), WV_STRACE_CTX, (gpointer)GLOBALS->strace_ctx) #else #define WV_STRACE_CURWIN(x) do { } while(0 && (x)) #endif /* need to do this at top of every entry point function where a signal is connected */ #ifdef WAVE_USE_GTK2 #define GET_WV_STRACE_CURWIN(x) GLOBALS->strace_ctx=g_object_get_data(G_OBJECT(x), WV_STRACE_CTX) #else #define GET_WV_STRACE_CURWIN(x) do { } while(0 && (x)) #endif static char *logical[]= {"AND", "OR", "XOR", "NAND", "NOR", "XNOR"}; static char *stype[WAVE_STYPE_COUNT]= {"Don't Care", "High", "Z (Mid)", "X", "Low", "String", "Rising Edge", "Falling Edge", "Any Edge"}; static struct item_mark_string item_mark_start_strings[]= { { "Start of Time", 0 }, { "Named Marker A", 0 }, { "Named Marker B", 0 }, { "Named Marker C", 0 }, { "Named Marker D", 0 }, { "Named Marker E", 0 }, { "Named Marker F", 0 }, { "Named Marker G", 0 }, { "Named Marker H", 0 }, { "Named Marker I", 0 }, { "Named Marker J", 0 }, { "Named Marker K", 0 }, { "Named Marker L", 0 }, { "Named Marker M", 0 }, { "Named Marker N", 0 }, { "Named Marker O", 0 }, { "Named Marker P", 0 }, { "Named Marker Q", 0 }, { "Named Marker R", 0 }, { "Named Marker S", 0 }, { "Named Marker T", 0 }, { "Named Marker U", 0 }, { "Named Marker V", 0 }, { "Named Marker W", 0 }, { "Named Marker X", 0 }, { "Named Marker Y", 0 }, { "Named Marker Z", 0 } }; static struct item_mark_string item_mark_end_strings[]= { { "End of Time", 0 }, { "Named Marker A", 0 }, { "Named Marker B", 0 }, { "Named Marker C", 0 }, { "Named Marker D", 0 }, { "Named Marker E", 0 }, { "Named Marker F", 0 }, { "Named Marker G", 0 }, { "Named Marker H", 0 }, { "Named Marker I", 0 }, { "Named Marker J", 0 }, { "Named Marker K", 0 }, { "Named Marker L", 0 }, { "Named Marker M", 0 }, { "Named Marker N", 0 }, { "Named Marker O", 0 }, { "Named Marker P", 0 }, { "Named Marker Q", 0 }, { "Named Marker R", 0 }, { "Named Marker S", 0 }, { "Named Marker T", 0 }, { "Named Marker U", 0 }, { "Named Marker V", 0 }, { "Named Marker W", 0 }, { "Named Marker X", 0 }, { "Named Marker Y", 0 }, { "Named Marker Z", 0 } }; /* * naive nonoptimized case insensitive strstr */ char *strstr_i(char *hay, char *needle) { char *ht, *nt; while (*hay) { int offs = 0; ht = hay; nt = needle; while(*nt) { if(toupper((int)(unsigned char)*(ht+offs)) != toupper((int)(unsigned char)*nt)) break; offs++; nt++; } if(!*nt) return(hay); hay++; } return(*hay ? hay : NULL); } /* * trap timescale overflows */ TimeType strace_adjust(TimeType a, TimeType b) { TimeType res=a+b; if((b>LLDescriptor(0))&&(resstrace_ctx->straces; while(s) { for(i=0;iback[i]) free_2(s->back[i]); } if(s->string) free_2(s->string); skill=s; s=s->next; free_2(skill); } GLOBALS->strace_ctx->straces=NULL; sd = GLOBALS->strace_ctx->strace_defer_free_head; while(sd) { FreeTrace(sd->defer); sd2 = sd->next; free_2(sd); sd = sd2; } GLOBALS->strace_ctx->strace_defer_free_head = NULL; } /* * button/menu/entry activations.. */ static void logical_clicked(GtkWidget *widget, gpointer which) { int i; char *which_char; GET_WV_STRACE_CURWIN(widget); for(i=0;i<6;i++) GLOBALS->strace_ctx->logical_mutex[i]=0; which_char=(char *)which; *which_char=1; /* mark our choice */ } static void stype_clicked(GtkWidget *widget, gpointer back) { struct strace_back *b; struct strace *s; GET_WV_STRACE_CURWIN(widget); b=(struct strace_back *)back; s=b->parent; s->value=b->which; DEBUG(printf("Trace %s Search Type: %s\n", s->trace->name, stype[(int)s->value])); } static void start_clicked(GtkWidget *widget, gpointer which) { GET_WV_STRACE_CURWIN(widget); GLOBALS->strace_ctx->mark_idx_start=((struct item_mark_string*)which)->idx; if (GLOBALS->strace_ctx->mark_idx_start<0 || GLOBALS->strace_ctx->mark_idx_start>=(int)(sizeof(item_mark_start_strings)/sizeof(struct item_mark_string))) { fprintf(stderr, "Internal error: GLOBALS->mark_idx_start out of range %d\n", GLOBALS->strace_ctx->mark_idx_start); exit(255); } DEBUG(printf("start: %s\n", ((struct item_mark_string*)which)->str)); } static void end_clicked(GtkWidget *widget, gpointer which) { GET_WV_STRACE_CURWIN(widget); GLOBALS->strace_ctx->mark_idx_end=((struct item_mark_string*)which)->idx; if (GLOBALS->strace_ctx->mark_idx_end<0 || GLOBALS->strace_ctx->mark_idx_end>=(int)(sizeof(item_mark_end_strings)/sizeof(struct item_mark_string))) { fprintf(stderr, "Internal error: GLOBALS->mark_idx_end out of range %d\n",GLOBALS->strace_ctx->mark_idx_end); exit(255); } DEBUG(printf("end: %s\n", ((struct item_mark_string*)which)->str)); } static void enter_callback(GtkWidget *widget, gpointer strace_tmp) { G_CONST_RETURN gchar *entry_text; struct strace *s; int i, len; GET_WV_STRACE_CURWIN(widget); s=(struct strace *)strace_tmp; if(s->string) { free_2(s->string); s->string=NULL; } entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); entry_text = entry_text ? entry_text : ""; DEBUG(printf("Trace %s Entry contents: %s\n", s->trace->name, entry_text)); if(!(len=strlen(entry_text))) return; gtk_entry_select_region (GTK_ENTRY (widget), 0, GTK_ENTRY(widget)->text_length); strcpy((s->string=(char *)malloc_2(len+1)),entry_text); for(i=0;istring[i]; if((ch>='a')&&(ch<='z')) s->string[i]=ch-('a'-'A'); } } static void forwards_callback(GtkWidget *widget, GtkWidget *nothing) { (void)nothing; GET_WV_STRACE_CURWIN(widget); /* no cleanup necessary, but do real search */ DEBUG(printf("Searching Forward..\n")); strace_search(STRACE_FORWARD); } static void backwards_callback(GtkWidget *widget, GtkWidget *nothing) { (void)nothing; GET_WV_STRACE_CURWIN(widget); /* no cleanup necessary, but do real search */ DEBUG(printf("Searching Backward..\n")); strace_search(STRACE_BACKWARD); } static void mark_callback(GtkWidget *widget, GtkWidget *nothing) { (void)nothing; GET_WV_STRACE_CURWIN(widget); DEBUG(printf("Marking..\n")); if(GLOBALS->strace_ctx->shadow_straces) { delete_strace_context(); } strace_maketimetrace(1); cache_actual_pattern_mark_traces(); MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } static void clear_callback(GtkWidget *widget, GtkWidget *nothing) { (void)nothing; GET_WV_STRACE_CURWIN(widget); DEBUG(printf("Clearing..\n")); if(GLOBALS->strace_ctx->shadow_straces) { delete_strace_context(); } strace_maketimetrace(0); MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } static void destroy_callback(GtkWidget *widget, GtkWidget *nothing) { (void)nothing; GET_WV_STRACE_CURWIN(widget); free_straces(); GLOBALS->strace_ctx->ptr_mark_count_label_strace_c_1=NULL; gtk_widget_destroy(GLOBALS->strace_ctx->window_strace_c_10); GLOBALS->strace_ctx->window_strace_c_10 = NULL; } /* update mark count label on pattern search dialog */ static void update_mark_count_label(void) { if(GLOBALS->strace_ctx->ptr_mark_count_label_strace_c_1) { char mark_count_buf[64]; sprintf (mark_count_buf, "Mark Count: %d", GLOBALS->strace_ctx->timearray_size); gtk_label_set_text (GTK_LABEL(GLOBALS->strace_ctx->ptr_mark_count_label_strace_c_1), mark_count_buf); } } void tracesearchbox(const char *title, GtkSignalFunc func, gpointer data) { GtkWidget *menu, *menuitem, *optionmenu; GSList *group; GtkWidget *entry; GtkWidget *vbox, *hbox, *small_hbox, *vbox_g, *label; GtkWidget *button1, *button1a, *button1b, *button1c, *button2, *scrolled_win, *frame, *separator; Trptr t; int i; int numtraces; GLOBALS->strace_current_window = (int)(intptr_t)data; /* arg for which search box going in */ GLOBALS->strace_ctx = &GLOBALS->strace_windows[GLOBALS->strace_current_window]; /* fix problem where ungrab doesn't occur if button pressed + simultaneous accelerator key occurs */ if(GLOBALS->in_button_press_wavewindow_c_1) { gdk_pointer_ungrab(GDK_CURRENT_TIME); } if(GLOBALS->strace_ctx->straces) { gdk_window_raise(GLOBALS->strace_ctx->window_strace_c_10->window); return; /* is already active */ } GLOBALS->strace_ctx->cleanup_strace_c_7=func; numtraces=0; /* create a new window */ GLOBALS->strace_ctx->window_strace_c_10 = gtk_window_new(GLOBALS->disable_window_manager ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL); GLOBALS->strace_windows[GLOBALS->strace_current_window].window_strace_c_10 = gtk_window_new(GLOBALS->disable_window_manager ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL); install_focus_cb(GLOBALS->strace_windows[GLOBALS->strace_current_window].window_strace_c_10, ((char *)&GLOBALS->strace_windows[GLOBALS->strace_current_window].window_strace_c_10) - ((char *)GLOBALS)); gtk_window_set_title(GTK_WINDOW (GLOBALS->strace_ctx->window_strace_c_10), title); gtk_widget_set_usize( GTK_WIDGET (GLOBALS->strace_ctx->window_strace_c_10), 420, -1); gtkwave_signal_connect(GTK_OBJECT (GLOBALS->strace_ctx->window_strace_c_10), "delete_event",(GtkSignalFunc) destroy_callback, NULL); WV_STRACE_CURWIN(GLOBALS->strace_ctx->window_strace_c_10); vbox = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (GLOBALS->strace_ctx->window_strace_c_10), vbox); gtk_widget_show (vbox); vbox_g = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox_g); frame = gtk_frame_new (NULL); gtk_container_border_width (GTK_CONTAINER (frame), 3); gtk_widget_show(frame); small_hbox = gtk_hbox_new (TRUE, 0); gtk_widget_show (small_hbox); label=gtk_label_new("Logical Operation"); gtk_widget_show (label); gtk_box_pack_start (GTK_BOX (small_hbox), label, TRUE, FALSE, 0); menu = gtk_menu_new (); group=NULL; for(i=0;i<6;i++) { menuitem = gtk_radio_menu_item_new_with_label (group, logical[i]); group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem)); gtk_menu_append (GTK_MENU (menu), menuitem); gtk_widget_show (menuitem); gtkwave_signal_connect(GTK_OBJECT (menuitem), "activate", GTK_SIGNAL_FUNC(logical_clicked), &GLOBALS->strace_ctx->logical_mutex[i]); WV_STRACE_CURWIN(menuitem); GLOBALS->strace_ctx->logical_mutex[i]=0; } GLOBALS->strace_ctx->logical_mutex[0]=1; /* "and" */ optionmenu = gtk_option_menu_new (); gtk_option_menu_set_menu (GTK_OPTION_MENU (optionmenu), menu); gtk_box_pack_start (GTK_BOX (small_hbox), optionmenu, TRUE, FALSE, 0); gtk_widget_show (optionmenu); gtk_box_pack_start (GTK_BOX (vbox), small_hbox, FALSE, FALSE, 0); scrolled_win = gtk_scrolled_window_new (NULL, NULL); gtk_widget_set_usize( GTK_WIDGET (scrolled_win), -1, 300); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_widget_show(scrolled_win); gtk_container_add (GTK_CONTAINER (frame), scrolled_win); gtk_container_add (GTK_CONTAINER (vbox), frame); for(t=GLOBALS->traces.first;t;t=t->t_next) { struct strace *s; if ((t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH))||(!(t->flags&TR_HIGHLIGHT))||(!(t->name))) continue; numtraces++; if(numtraces==500) { status_text("Limiting waveform display search to 500 traces.\n"); break; } s=(struct strace *)calloc_2(1,sizeof(struct strace)); s->next=GLOBALS->strace_ctx->straces; GLOBALS->strace_ctx->straces=s; s->trace=t; if(t!=GLOBALS->traces.first) { separator = gtk_hseparator_new (); gtk_widget_show (separator); gtk_box_pack_start (GTK_BOX (vbox_g), separator, FALSE, FALSE, 0); } small_hbox = gtk_hbox_new (TRUE, 0); gtk_widget_show (small_hbox); label=gtk_label_new(t->name); gtk_widget_show (label); gtk_box_pack_start (GTK_BOX (vbox_g), label, FALSE, FALSE, 0); menu = gtk_menu_new (); group=NULL; for(i=0;iparent=s; b->which=i; s->back[i]=b; menuitem = gtk_radio_menu_item_new_with_label (group, stype[i]); group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem)); gtk_menu_append (GTK_MENU (menu), menuitem); gtk_widget_show (menuitem); gtkwave_signal_connect(GTK_OBJECT (menuitem), "activate", GTK_SIGNAL_FUNC(stype_clicked), b); WV_STRACE_CURWIN(menuitem); } optionmenu = gtk_option_menu_new (); gtk_option_menu_set_menu (GTK_OPTION_MENU (optionmenu), menu); gtk_box_pack_start (GTK_BOX (small_hbox), optionmenu, TRUE, FALSE, 0); gtk_widget_show (optionmenu); entry = gtk_entry_new_with_max_length (257); /* %+256ch */ gtkwave_signal_connect(GTK_OBJECT(entry), "activate", GTK_SIGNAL_FUNC(enter_callback), s); gtkwave_signal_connect(GTK_OBJECT(entry), "changed", GTK_SIGNAL_FUNC(enter_callback), s); WV_STRACE_CURWIN(entry); gtk_box_pack_start (GTK_BOX (small_hbox), entry, TRUE, FALSE, 0); gtk_widget_show (entry); gtk_box_pack_start (GTK_BOX (vbox_g), small_hbox, FALSE, FALSE, 0); } gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_win), vbox_g); do /* add GUI elements for displaying mark count and mark count start/end */ { unsigned int idx; GtkWidget *ptr_mark_start_label, *ptr_mark_end_label; GtkWidget *mark_count_hbox_start, *mark_count_hbox_end; GtkWidget *count_vbox_left, *count_vbox_right, *count_vbox, *count_hbox; GtkWidget *ptr_mark_count_start, *ptr_mark_count_end; count_hbox=gtk_hbox_new (TRUE, 0); gtk_widget_show (count_hbox); gtk_box_pack_start (GTK_BOX(vbox),count_hbox,FALSE,FALSE,0); /* add a vertical box to display the mark count GUI elements */ count_vbox_left=gtk_vbox_new (TRUE, 0); gtk_widget_show (count_vbox_left); gtk_box_pack_start (GTK_BOX(count_hbox),count_vbox_left,FALSE,FALSE,0); count_vbox=gtk_vbox_new (TRUE, 0); gtk_widget_show (count_vbox); gtk_box_pack_start (GTK_BOX(count_hbox),count_vbox,FALSE,FALSE,0); count_vbox_right=gtk_vbox_new (TRUE, 0); gtk_widget_show (count_vbox_right); gtk_box_pack_start (GTK_BOX(count_hbox),count_vbox_right,FALSE,FALSE,0); /* add mark start GUI element */ mark_count_hbox_start=gtk_hbox_new (TRUE, 0); gtk_widget_show (mark_count_hbox_start); gtk_box_pack_start (GTK_BOX(count_vbox),mark_count_hbox_start,FALSE,FALSE,0); ptr_mark_start_label=gtk_label_new ("Marking Begins at:"); gtk_widget_show (ptr_mark_start_label); gtk_box_pack_start (GTK_BOX (mark_count_hbox_start),ptr_mark_start_label,TRUE,FALSE,0); ptr_mark_count_start = gtk_menu_new (); group=NULL; for(idx=0; idxstrace_ctx->mark_idx_start); /* add mark end GUI element */ mark_count_hbox_end=gtk_hbox_new (TRUE, 0); gtk_widget_show (mark_count_hbox_end); gtk_box_pack_start (GTK_BOX(count_vbox),mark_count_hbox_end,FALSE,FALSE,0); ptr_mark_end_label=gtk_label_new ("Marking Stops at:"); gtk_widget_show (ptr_mark_end_label); gtk_box_pack_start (GTK_BOX (mark_count_hbox_end),ptr_mark_end_label,TRUE,FALSE,0); ptr_mark_count_end = gtk_menu_new (); group=NULL; for(idx=0; idxstrace_ctx->mark_idx_end); /* add mark count GUI element */ GLOBALS->strace_ctx->ptr_mark_count_label_strace_c_1=gtk_label_new (""); gtk_widget_show (GLOBALS->strace_ctx->ptr_mark_count_label_strace_c_1); gtk_box_pack_start (GTK_BOX (count_vbox),GLOBALS->strace_ctx->ptr_mark_count_label_strace_c_1,TRUE,FALSE,0); update_mark_count_label (); } while (0); hbox = gtk_hbox_new (FALSE, 1); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_widget_show (hbox); button1 = gtk_button_new_with_label ("Fwd"); gtk_widget_set_usize(button1, 75, -1); gtkwave_signal_connect(GTK_OBJECT (button1), "clicked", GTK_SIGNAL_FUNC(forwards_callback), NULL); WV_STRACE_CURWIN(button1); gtk_widget_show (button1); gtk_container_add (GTK_CONTAINER (hbox), button1); GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT); gtkwave_signal_connect_object (GTK_OBJECT (button1), "realize", (GtkSignalFunc) gtk_widget_grab_default, GTK_OBJECT (button1)); button1a = gtk_button_new_with_label ("Bkwd"); gtk_widget_set_usize(button1a, 75, -1); gtkwave_signal_connect(GTK_OBJECT (button1a), "clicked", GTK_SIGNAL_FUNC(backwards_callback), NULL); WV_STRACE_CURWIN(button1a); gtk_widget_show (button1a); gtk_container_add (GTK_CONTAINER (hbox), button1a); GTK_WIDGET_SET_FLAGS (button1a, GTK_CAN_DEFAULT); button1b = gtk_button_new_with_label ("Mark"); gtk_widget_set_usize(button1b, 75, -1); gtkwave_signal_connect(GTK_OBJECT (button1b), "clicked", GTK_SIGNAL_FUNC(mark_callback), NULL); WV_STRACE_CURWIN(button1b); gtk_widget_show (button1b); gtk_container_add (GTK_CONTAINER (hbox), button1b); GTK_WIDGET_SET_FLAGS (button1b, GTK_CAN_DEFAULT); button1c = gtk_button_new_with_label ("Clear"); gtk_widget_set_usize(button1c, 75, -1); gtkwave_signal_connect(GTK_OBJECT (button1c), "clicked", GTK_SIGNAL_FUNC(clear_callback), NULL); WV_STRACE_CURWIN(button1c); gtk_widget_show (button1c); gtk_container_add (GTK_CONTAINER (hbox), button1c); GTK_WIDGET_SET_FLAGS (button1c, GTK_CAN_DEFAULT); button2 = gtk_button_new_with_label ("Exit"); gtk_widget_set_usize(button2, 75, -1); gtkwave_signal_connect(GTK_OBJECT (button2), "clicked", GTK_SIGNAL_FUNC(destroy_callback), NULL); WV_STRACE_CURWIN(button2); GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT); gtk_widget_show (button2); gtk_container_add (GTK_CONTAINER (hbox), button2); gtk_widget_show(GLOBALS->strace_ctx->window_strace_c_10); } /* * strace backward or forward.. */ static void strace_search_2(int direction, int is_last_iteration) { struct strace *s; TimeType basetime, maxbase, sttim, fintim; Trptr t; int totaltraces, passcount; int whichpass; TimeType middle=0, width; if(direction==STRACE_BACKWARD) /* backwards */ { if(GLOBALS->tims.marker<0) { basetime=MAX_HISTENT_TIME; } else { basetime=GLOBALS->tims.marker; } } else /* go forwards */ { if(GLOBALS->tims.marker<0) { basetime=GLOBALS->tims.first; } else { basetime=GLOBALS->tims.marker; } } sttim=GLOBALS->tims.first; fintim=GLOBALS->tims.last; for(whichpass=0;;whichpass++) { if(direction==STRACE_BACKWARD) /* backwards */ { maxbase=-1; s=GLOBALS->strace_ctx->straces; while(s) { t=s->trace; GLOBALS->shift_timebase=t->shift; if(!(t->vector)) { hptr h; hptr *hp; UTimeType utt; TimeType tt; /* h= */ bsearch_node(t->n.nd, basetime - t->shift); /* scan-build */ hp=GLOBALS->max_compare_index; if((hp==&(t->n.nd->harray[1]))||(hp==&(t->n.nd->harray[0]))) return; if(basetime == ((*hp)->time+GLOBALS->shift_timebase)) hp--; h=*hp; s->his.h=h; utt=strace_adjust(h->time,GLOBALS->shift_timebase); tt=utt; if(tt > maxbase) maxbase=tt; } else { vptr v; vptr *vp; UTimeType utt; TimeType tt; /* v= */ bsearch_vector(t->n.vec, basetime - t->shift); /* scan-build */ vp=GLOBALS->vmax_compare_index; if((vp==&(t->n.vec->vectors[1]))||(vp==&(t->n.vec->vectors[0]))) return; if(basetime == ((*vp)->time+GLOBALS->shift_timebase)) vp--; v=*vp; s->his.v=v; utt=strace_adjust(v->time,GLOBALS->shift_timebase); tt=utt; if(tt > maxbase) maxbase=tt; } s=s->next; } } else /* go forward */ { maxbase=MAX_HISTENT_TIME; s=GLOBALS->strace_ctx->straces; while(s) { t=s->trace; GLOBALS->shift_timebase=t->shift; if(!(t->vector)) { hptr h; UTimeType utt; TimeType tt; h=bsearch_node(t->n.nd, basetime - t->shift); while(h->next && h->time==h->next->time) h=h->next; if((whichpass)||(GLOBALS->tims.marker>=0)) h=h->next; if(!h) return; s->his.h=h; utt=strace_adjust(h->time,GLOBALS->shift_timebase); tt=utt; if(tt < maxbase) maxbase=tt; } else { vptr v; UTimeType utt; TimeType tt; v=bsearch_vector(t->n.vec, basetime - t->shift); while(v->next && v->time==v->next->time) v=v->next; if((whichpass)||(GLOBALS->tims.marker>=0)) v=v->next; if(!v) return; s->his.v=v; utt=strace_adjust(v->time,GLOBALS->shift_timebase); tt=utt; if(tt < maxbase) maxbase=tt; } s=s->next; } } s=GLOBALS->strace_ctx->straces; totaltraces=0; /* increment when not don't care */ while(s) { char str[2]; t=s->trace; s->search_result=0; /* explicitly must set this */ GLOBALS->shift_timebase=t->shift; if((!t->vector)&&(!(t->n.nd->extvals))) { if(strace_adjust(s->his.h->time,GLOBALS->shift_timebase)!=maxbase) { s->his.h=bsearch_node(t->n.nd, maxbase - t->shift); while(s->his.h->next && s->his.h->time==s->his.h->next->time) s->his.h=s->his.h->next; } if(t->flags&TR_INVERT) { str[0]=AN_STR_INV[s->his.h->v.h_val]; } else { str[0]=AN_STR[s->his.h->v.h_val]; } str[1]=0x00; switch(s->value) { case ST_DC: break; case ST_HIGH: totaltraces++; if((str[0]=='1')||(str[0]=='h')||(str[0]=='H')) s->search_result=1; break; case ST_RISE: if((str[0]=='1')||(str[0]=='h')||(str[0]=='H')) s->search_result=1; totaltraces++; break; case ST_LOW: totaltraces++; if((str[0]=='0')||(str[0]=='l')||(str[0]=='L')) s->search_result=1; break; case ST_FALL: totaltraces++; if((str[0]=='0')||(str[0]=='l')||(str[0]=='L')) s->search_result=1; break; case ST_MID: totaltraces++; if((str[0]=='z')||(str[0]=='Z')) s->search_result=1; break; case ST_X: totaltraces++; if((str[0]=='x')||(str[0]=='X')) s->search_result=1; break; case ST_ANY: totaltraces++; s->search_result=1; break; case ST_STRING: totaltraces++; if(s->string) if(strstr_i(s->string,str)) s->search_result=1; break; default: fprintf(stderr, "Internal error: st_type of %d\n",s->value); exit(255); } } else { char *chval, *chval2; char ch; if(t->vector) { if(strace_adjust(s->his.v->time,GLOBALS->shift_timebase)!=maxbase) { s->his.v=bsearch_vector(t->n.vec, maxbase - t->shift); while(s->his.v->next && s->his.v->time==s->his.v->next->time) s->his.v=s->his.v->next; } chval=convert_ascii(t,s->his.v); } else { if(strace_adjust(s->his.h->time,GLOBALS->shift_timebase)!=maxbase) { s->his.h=bsearch_node(t->n.nd, maxbase - t->shift); while(s->his.h->next && s->his.h->time==s->his.h->next->time) s->his.h=s->his.h->next; } if(s->his.h->flags&HIST_REAL) { if(!(s->his.h->flags&HIST_STRING)) { #ifdef WAVE_HAS_H_DOUBLE chval=convert_ascii_real(t, &s->his.h->v.h_double); #else chval=convert_ascii_real(t, (double *)s->his.h->v.h_vector); #endif } else { chval=convert_ascii_string((char *)s->his.h->v.h_vector); chval2=chval; while((ch=*chval2)) /* toupper() the string */ { if((ch>='a')&&(ch<='z')) { *chval2= ch-('a'-'A'); } chval2++; } } } else { chval=convert_ascii_vec(t,s->his.h->v.h_vector); } } switch(s->value) { case ST_DC: break; case ST_RISE: case ST_FALL: totaltraces++; break; case ST_HIGH: totaltraces++; if((chval2=chval)) while((ch=*(chval2++))) { if(((ch>='1')&&(ch<='9'))||(ch=='h')||(ch=='H')||((ch>='A')&&(ch<='F'))) { s->search_result=1; break; } } break; case ST_LOW: totaltraces++; if((chval2=chval)) { s->search_result=1; while((ch=*(chval2++))) { if((ch!='0')&&(ch!='l')&&(ch!='L')) { s->search_result=0; break; } } } break; case ST_MID: totaltraces++; if((chval2=chval)) { s->search_result=1; while((ch=*(chval2++))) { if((ch!='z')&&(ch!='Z')) { s->search_result=0; break; } } } break; case ST_X: totaltraces++; if((chval2=chval)) { s->search_result=1; while((ch=*(chval2++))) { if((ch!='x')&&(ch!='w')&&(ch!='X')&&(ch!='W')) { s->search_result=0; break; } } } break; case ST_ANY: totaltraces++; s->search_result=1; break; case ST_STRING: totaltraces++; if(s->string) if(strstr_i(chval, s->string)) s->search_result=1; break; default: fprintf(stderr, "Internal error: st_type of %d\n",s->value); exit(255); } free_2(chval); } s=s->next; } if((maxbasefintim)) return; DEBUG(printf("Maxbase: "TTFormat", total traces: %d\n",maxbase, totaltraces)); s=GLOBALS->strace_ctx->straces; passcount=0; while(s) { DEBUG(printf("\tPass: %d, Name: %s\n",s->search_result, s->trace->name)); if(s->search_result) passcount++; s=s->next; } if(totaltraces) { if(GLOBALS->strace_ctx->logical_mutex[0]) /* and */ { if(totaltraces==passcount) break; } else if(GLOBALS->strace_ctx->logical_mutex[1]) /* or */ { if(passcount) break; } else if(GLOBALS->strace_ctx->logical_mutex[2]) /* xor */ { if(passcount&1) break; } else if(GLOBALS->strace_ctx->logical_mutex[3]) /* nand */ { if(totaltraces!=passcount) break; } else if(GLOBALS->strace_ctx->logical_mutex[4]) /* nor */ { if(!passcount) break; } else if(GLOBALS->strace_ctx->logical_mutex[5]) /* xnor */ { if(!(passcount&1)) break; } } basetime=maxbase; } GLOBALS->tims.marker=maxbase; if(is_last_iteration) { update_markertime(GLOBALS->tims.marker); width=(TimeType)(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx); if((GLOBALS->tims.markertims.start)||(GLOBALS->tims.marker>=GLOBALS->tims.start+width)) { if((GLOBALS->tims.marker<0)||(GLOBALS->tims.markertims.first)||(GLOBALS->tims.marker>GLOBALS->tims.last)) { if(GLOBALS->tims.end>GLOBALS->tims.last) GLOBALS->tims.end=GLOBALS->tims.last; middle=(GLOBALS->tims.start/2)+(GLOBALS->tims.end/2); if((GLOBALS->tims.start&1)&&(GLOBALS->tims.end&1)) middle++; } else { middle=GLOBALS->tims.marker; } GLOBALS->tims.start=time_trunc(middle-(width/2)); if(GLOBALS->tims.start+width>GLOBALS->tims.last) GLOBALS->tims.start=GLOBALS->tims.last-width; if(GLOBALS->tims.starttims.first) GLOBALS->tims.start=GLOBALS->tims.first; GTK_ADJUSTMENT(GLOBALS->wave_hslider)->value=GLOBALS->tims.timecache=GLOBALS->tims.start; } MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } void strace_search(int direction) { int i; int i_high_cnt = ((GLOBALS->strace_repeat_count > 0) ? GLOBALS->strace_repeat_count : 1) - 1; for(i=0;i<=i_high_cnt;i++) { strace_search_2(direction, (i == i_high_cnt)); } } /*********************************************/ /* * strace forward to make the timetrace */ TimeType strace_timetrace(TimeType basetime, int notfirst) { struct strace *s; TimeType maxbase, fintim; Trptr t; int totaltraces, passcount; int whichpass; fintim=GLOBALS->tims.last; for(whichpass=0;;whichpass++) { maxbase=MAX_HISTENT_TIME; s=GLOBALS->strace_ctx->straces; while(s) { t=s->trace; GLOBALS->shift_timebase=t->shift; if(!(t->vector)) { hptr h; UTimeType utt; TimeType tt; h=bsearch_node(t->n.nd, basetime - t->shift); s->his.h=h; while(h->time==h->next->time) h=h->next; if((whichpass)||(notfirst)) h=h->next; if(!h) return(MAX_HISTENT_TIME); utt=strace_adjust(h->time,GLOBALS->shift_timebase); tt=utt; if(tt < maxbase) maxbase=tt; } else { vptr v; UTimeType utt; TimeType tt; v=bsearch_vector(t->n.vec, basetime - t->shift); if((whichpass)||(notfirst)) v=v->next; if(!v) return(MAX_HISTENT_TIME); s->his.v=v; utt=strace_adjust(v->time,GLOBALS->shift_timebase); tt=utt; if(tt < maxbase) maxbase=tt; } s=s->next; } s=GLOBALS->strace_ctx->straces; totaltraces=0; /* increment when not don't care */ while(s) { char str[2]; t=s->trace; s->search_result=0; /* explicitly must set this */ GLOBALS->shift_timebase=t->shift; if((!t->vector)&&(!(t->n.nd->extvals))) { if(strace_adjust(s->his.h->time,GLOBALS->shift_timebase)!=maxbase) { s->his.h=bsearch_node(t->n.nd, maxbase - t->shift); while(s->his.h->next && s->his.h->time==s->his.h->next->time) s->his.h=s->his.h->next; } if(t->flags&TR_INVERT) { str[0]=AN_STR_INV[s->his.h->v.h_val]; } else { str[0]=AN_STR[s->his.h->v.h_val]; } str[1]=0x00; switch(s->value) { case ST_DC: break; case ST_HIGH: totaltraces++; if((str[0]=='1')||(str[0]=='h')||(str[0]=='H')) s->search_result=1; break; case ST_RISE: totaltraces++; if(((str[0]=='1')||(str[0]=='h')||(str[0]=='H'))&&(strace_adjust(s->his.h->time,GLOBALS->shift_timebase)==maxbase)) s->search_result=1; break; case ST_LOW: totaltraces++; if((str[0]=='0')||(str[0]=='l')||(str[0]=='L')) s->search_result=1; break; case ST_FALL: totaltraces++; if(((str[0]=='0')||(str[0]=='l')||(str[0]=='L'))&&(strace_adjust(s->his.h->time,GLOBALS->shift_timebase)==maxbase)) s->search_result=1; break; case ST_MID: totaltraces++; if((str[0]=='z')||(str[0]=='Z')) s->search_result=1; break; case ST_X: totaltraces++; if((str[0]=='x')||(str[0]=='X')) s->search_result=1; break; case ST_ANY: totaltraces++; if(strace_adjust(s->his.h->time,GLOBALS->shift_timebase)==maxbase)s->search_result=1; break; case ST_STRING: totaltraces++; if(s->string) if(strstr_i(s->string,str)) s->search_result=1; break; default: fprintf(stderr, "Internal error: st_type of %d\n",s->value); exit(255); } } else { char *chval, *chval2; char ch; if(t->vector) { if(strace_adjust(s->his.v->time,GLOBALS->shift_timebase)!=maxbase) { s->his.v=bsearch_vector(t->n.vec, maxbase - t->shift); while(s->his.v->next && s->his.v->time==s->his.v->next->time) s->his.v=s->his.v->next; } chval=convert_ascii(t,s->his.v); } else { if(strace_adjust(s->his.h->time,GLOBALS->shift_timebase)!=maxbase) { s->his.h=bsearch_node(t->n.nd, maxbase - t->shift); while(s->his.h->next && s->his.h->time==s->his.h->next->time) s->his.h=s->his.h->next; } if(s->his.h->flags&HIST_REAL) { if(!(s->his.h->flags&HIST_STRING)) { #ifdef WAVE_HAS_H_DOUBLE chval=convert_ascii_real(t, &s->his.h->v.h_double); #else chval=convert_ascii_real(t, (double *)s->his.h->v.h_vector); #endif } else { chval=convert_ascii_string((char *)s->his.h->v.h_vector); chval2=chval; while((ch=*chval2)) /* toupper() the string */ { if((ch>='a')&&(ch<='z')) { *chval2= ch-('a'-'A'); } chval2++; } } } else { chval=convert_ascii_vec(t,s->his.h->v.h_vector); } } switch(s->value) { case ST_DC: break; case ST_RISE: case ST_FALL: totaltraces++; break; case ST_HIGH: totaltraces++; if((chval2=chval)) while((ch=*(chval2++))) { if(((ch>='1')&&(ch<='9'))||(ch=='h')||(ch=='H')||((ch>='A')&&(ch<='F'))) { s->search_result=1; break; } } break; case ST_LOW: totaltraces++; if((chval2=chval)) { s->search_result=1; while((ch=*(chval2++))) { if((ch!='0')&&(ch!='l')&&(ch!='L')) { s->search_result=0; break; } } } break; case ST_MID: totaltraces++; if((chval2=chval)) { s->search_result=1; while((ch=*(chval2++))) { if((ch!='z')&&(ch!='Z')) { s->search_result=0; break; } } } break; case ST_X: totaltraces++; if((chval2=chval)) { s->search_result=1; while((ch=*(chval2++))) { if((ch!='x')&&(ch!='w')&&(ch!='X')&&(ch!='W')) { s->search_result=0; break; } } } break; case ST_ANY: totaltraces++; if(strace_adjust(s->his.v->time,GLOBALS->shift_timebase)==maxbase) s->search_result=1; break; case ST_STRING: totaltraces++; if(s->string) if(strstr_i(chval, s->string)) s->search_result=1; break; default: fprintf(stderr, "Internal error: st_type of %d\n",s->value); exit(255); } free_2(chval); } s=s->next; } if(maxbase>fintim) return(MAX_HISTENT_TIME); DEBUG(printf("Maxbase: "TTFormat", total traces: %d\n",maxbase, totaltraces)); s=GLOBALS->strace_ctx->straces; passcount=0; while(s) { DEBUG(printf("\tPass: %d, Name: %s\n",s->search_result, s->trace->name)); if(s->search_result) passcount++; s=s->next; } if(totaltraces) { if(GLOBALS->strace_ctx->logical_mutex[0]) /* and */ { if(totaltraces==passcount) break; } else if(GLOBALS->strace_ctx->logical_mutex[1]) /* or */ { if(passcount) break; } else if(GLOBALS->strace_ctx->logical_mutex[2]) /* xor */ { if(passcount&1) break; } else if(GLOBALS->strace_ctx->logical_mutex[3]) /* nand */ { if(totaltraces!=passcount) break; } else if(GLOBALS->strace_ctx->logical_mutex[4]) /* nor */ { if(!passcount) break; } else if(GLOBALS->strace_ctx->logical_mutex[5]) /* xnor */ { if(!(passcount&1)) break; } } basetime=maxbase; } return(maxbase); } void strace_maketimetrace(int mode) { TimeType basetime=GLOBALS->tims.first; TimeType endtime =MAX_HISTENT_TIME; int notfirst=0; TimeType *t; int t_allocated; if(GLOBALS->strace_ctx->timearray) { free_2(GLOBALS->strace_ctx->timearray); GLOBALS->strace_ctx->timearray=NULL; } GLOBALS->strace_ctx->timearray_size=0; if((!mode)&&(!GLOBALS->strace_ctx->shadow_active)) { update_mark_count_label(); delete_mprintf(); return; /* merely free stuff up */ } if(GLOBALS->strace_ctx->mark_idx_start>0) { if(GLOBALS->named_markers[GLOBALS->strace_ctx->mark_idx_start-1]>=0) basetime=GLOBALS->named_markers[GLOBALS->strace_ctx->mark_idx_start-1]; else { char notused[129]; sprintf(notused, "%s not in use.\n", item_mark_start_strings[(unsigned int)GLOBALS->strace_ctx->mark_idx_start].str); status_text(notused); } } if(GLOBALS->strace_ctx->mark_idx_end>0) { if(GLOBALS->named_markers[GLOBALS->strace_ctx->mark_idx_end-1]>=0) endtime=GLOBALS->named_markers[GLOBALS->strace_ctx->mark_idx_end-1]; else { char notused[129]; sprintf(notused, "%s not in use.\n", item_mark_end_strings[(unsigned int)GLOBALS->strace_ctx->mark_idx_end].str); status_text(notused); } } if(basetime>endtime) { TimeType tmp=basetime; basetime =endtime; endtime =tmp; } t_allocated = 1; t = malloc_2(sizeof(TimeType) * t_allocated); while(1) { basetime=strace_timetrace(basetime, notfirst); notfirst=1; if(endtime==MAX_HISTENT_TIME) { if(basetime==MAX_HISTENT_TIME) break; } else { if(basetime>endtime) break; /* formerly was >= which didn't mark the endpoint if true which is incorrect */ } /* i.e., if start is markable, end should be also */ t[GLOBALS->strace_ctx->timearray_size] = basetime; GLOBALS->strace_ctx->timearray_size++; if(GLOBALS->strace_ctx->timearray_size == t_allocated) { t_allocated *= 2; t = realloc_2(t, sizeof(TimeType) * t_allocated); } } if(GLOBALS->strace_ctx->timearray_size) { GLOBALS->strace_ctx->timearray = realloc_2(t, sizeof(TimeType) * GLOBALS->strace_ctx->timearray_size); } else { free_2(t); GLOBALS->strace_ctx->timearray = NULL; } if(!GLOBALS->strace_ctx->shadow_active) update_mark_count_label(); } /* * swap context for mark during trace load... */ void swap_strace_contexts(void) { struct strace *stemp; char logical_mutex_temp[6]; char mark_idx_start_temp, mark_idx_end_temp; stemp = GLOBALS->strace_ctx->straces; GLOBALS->strace_ctx->straces = GLOBALS->strace_ctx->shadow_straces; GLOBALS->strace_ctx->shadow_straces = stemp; memcpy(logical_mutex_temp, GLOBALS->strace_ctx->logical_mutex, 6); memcpy(GLOBALS->strace_ctx->logical_mutex, GLOBALS->strace_ctx->shadow_logical_mutex, 6); memcpy(GLOBALS->strace_ctx->shadow_logical_mutex, logical_mutex_temp, 6); mark_idx_start_temp = GLOBALS->strace_ctx->mark_idx_start; GLOBALS->strace_ctx->mark_idx_start = GLOBALS->strace_ctx->shadow_mark_idx_start; GLOBALS->strace_ctx->shadow_mark_idx_start = mark_idx_start_temp; mark_idx_end_temp = GLOBALS->strace_ctx->mark_idx_end; GLOBALS->strace_ctx->mark_idx_end = GLOBALS->strace_ctx->shadow_mark_idx_end; GLOBALS->strace_ctx->shadow_mark_idx_end = mark_idx_end_temp; } /* * delete context */ void delete_strace_context(void) { int i; struct strace *stemp; struct strace *strace_cache; for(i=0;i<6;i++) { GLOBALS->strace_ctx->shadow_logical_mutex[i] = 0; } GLOBALS->strace_ctx->shadow_mark_idx_start = 0; GLOBALS->strace_ctx->shadow_mark_idx_end = 0; strace_cache = GLOBALS->strace_ctx->straces; /* so the trace actually deletes */ GLOBALS->strace_ctx->straces=NULL; stemp = GLOBALS->strace_ctx->shadow_straces; while(stemp) { GLOBALS->strace_ctx->shadow_straces = stemp->next; if(stemp->string) free_2(stemp->string); FreeTrace(stemp->trace); free_2(stemp); stemp = GLOBALS->strace_ctx->shadow_straces; } if(GLOBALS->strace_ctx->shadow_string) { free_2(GLOBALS->strace_ctx->shadow_string); GLOBALS->strace_ctx->shadow_string = NULL; } GLOBALS->strace_ctx->straces = strace_cache; } /*************************************************************************/ /* * printf to memory.. */ int mprintf(const char *fmt, ... ) { int len; int rc; va_list args; struct mprintf_buff_t *bt = (struct mprintf_buff_t *)calloc_2(1, sizeof(struct mprintf_buff_t)); char buff[65537]; va_start(args, fmt); rc=vsprintf(buff, fmt, args); len = strlen(buff); bt->str = malloc_2(len+1); strcpy(bt->str, buff); if(!GLOBALS->strace_ctx->mprintf_buff_current) { GLOBALS->strace_ctx->mprintf_buff_head = GLOBALS->strace_ctx->mprintf_buff_current = bt; } else { GLOBALS->strace_ctx->mprintf_buff_current->next = bt; GLOBALS->strace_ctx->mprintf_buff_current = bt; } va_end(args); return(rc); } /* * kill mprint buffer */ void delete_mprintf(void) { if(GLOBALS->strace_ctx->mprintf_buff_head) { struct mprintf_buff_t *mb = GLOBALS->strace_ctx->mprintf_buff_head; struct mprintf_buff_t *mbt; while(mb) { free_2(mb->str); mbt = mb->next; free_2(mb); mb = mbt; } GLOBALS->strace_ctx->mprintf_buff_head = GLOBALS->strace_ctx->mprintf_buff_current = NULL; } } /* * so we can (later) write out the traces which are actually marked... */ void cache_actual_pattern_mark_traces(void) { Trptr t; unsigned int def=0; TimeType prevshift=LLDescriptor(0); struct strace *st; delete_mprintf(); if(GLOBALS->strace_ctx->timearray) { mprintf("!%d%d%d%d%d%d%c%c\n", GLOBALS->strace_ctx->logical_mutex[0], GLOBALS->strace_ctx->logical_mutex[1], GLOBALS->strace_ctx->logical_mutex[2], GLOBALS->strace_ctx->logical_mutex[3], GLOBALS->strace_ctx->logical_mutex[4], GLOBALS->strace_ctx->logical_mutex[5], '@'+GLOBALS->strace_ctx->mark_idx_start, '@'+GLOBALS->strace_ctx->mark_idx_end); st=GLOBALS->strace_ctx->straces; while(st) { if(st->value==ST_STRING) { mprintf("?\"%s\n", st->string ? st->string : ""); /* search type for this trace is string.. */ } else { mprintf("?%02x\n", (unsigned char)st->value); /* else search type for this trace.. */ } t=st->trace; if((t->flags!=def)||(st==GLOBALS->strace_ctx->straces)) { mprintf("@%x\n",def=t->flags); } if((t->shift)||((prevshift)&&(!t->shift))) { mprintf(">"TTFormat"\n", t->shift); } prevshift=t->shift; if(!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH))) { if(t->vector) { int i; nptr *nodes; if(HasAlias(t)) { mprintf("+{%s} ",t->name_full); } mprintf("#{%s}",t->name); nodes=t->n.vec->bits->nodes; for(i=0;in.vec->bits->nnbits;i++) { int was_packed = HIER_DEPACK_STATIC; char *namex; if(nodes[i]->expansion) { namex = hier_decompress_flagged(nodes[i]->expansion->parent->nname, &was_packed); mprintf(" (%d)%s",nodes[i]->expansion->parentbit, namex); /* if(was_packed) free_2(namex); ...not needed for HIER_DEPACK_STATIC */ } else { /* namex = */ hier_decompress_flagged(nodes[i]->nname, &was_packed); /* scan-build */ mprintf(" %s",nodes[i]->nname); /* if(was_packed) free_2(namex); ...not needed for HIER_DEPACK_STATIC */ } } mprintf("\n"); } else { int was_packed = HIER_DEPACK_STATIC; char *namex; if(HasAlias(t)) { if(t->n.nd->expansion) { namex = hier_decompress_flagged(t->n.nd->expansion->parent->nname, &was_packed); mprintf("+{%s} (%d)%s\n",t->name+2,t->n.nd->expansion->parentbit, namex); /* if(was_packed) free_2(namex); ...not needed for HIER_DEPACK_STATIC */ } else { namex = hier_decompress_flagged(t->n.nd->nname, &was_packed); mprintf("+{%s} %s\n",t->name+2,namex); /* if(was_packed) free_2(namex); ...not needed for HIER_DEPACK_STATIC */ } } else { if(t->n.nd->expansion) { namex = hier_decompress_flagged(t->n.nd->expansion->parent->nname, &was_packed); mprintf("(%d)%s\n",t->n.nd->expansion->parentbit, namex); /* if(was_packed) free_2(namex); ...not needed for HIER_DEPACK_STATIC */ } else { namex = hier_decompress_flagged(t->n.nd->nname, &was_packed); mprintf("%s\n",namex); /* if(was_packed) free_2(namex); ...not needed for HIER_DEPACK_STATIC*/ } } } } st=st->next; } /* while(st)... */ mprintf("!!\n"); /* mark end of strace region */ } } gtkwave-3.3.66/src/wavewindow.h0000664000076400007640000000146112341266475015745 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2010 * * 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. */ #ifndef WAVE_WAVEWINDOW_H #define WAVE_WAVEWINDOW_H void button_press_release_common(void); void UpdateSigValue(Trptr t); void MaxSignalLength(void); void RenderSigs(int trtarget, int update_waves); int RenderSig(Trptr t, int i, int dobackground); void populateBuffer(Trptr t, char *altname, char* buf); void calczoom(double z0); void make_sigarea_gcs(GtkWidget *widget); void force_screengrab_gcs(void); void force_normal_gcs(void); gint wavearea_configure_event(GtkWidget *widget, GdkEventConfigure *event); #endif gtkwave-3.3.66/src/ttranslate.c0000664000076400007640000005556112360623564015736 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2010-2014. * * 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. */ #include "globals.h" #include #include #include "gtk12compat.h" #include "symbol.h" #include "ttranslate.h" #include "pipeio.h" #include "debug.h" #ifdef _MSC_VER #define strcasecmp _stricmp #endif static void args_entry_callback(GtkWidget *widget, GtkWidget *entry) { (void)widget; G_CONST_RETURN gchar *entry_text; entry_text=gtk_entry_get_text(GTK_ENTRY(entry)); entry_text = entry_text ? entry_text : ""; if(GLOBALS->ttranslate_args) { free_2(GLOBALS->ttranslate_args); } GLOBALS->ttranslate_args = strdup_2(entry_text); DEBUG(printf("Args Entry contents: %s\n",entry_text)); } void init_ttrans_data(void) { int i; if(!GLOBALS->ttranssel_filter) { GLOBALS->ttranssel_filter = calloc_2(TTRANS_FILTER_MAX+1, sizeof(char *)); } if(!GLOBALS->ttrans_filter) { GLOBALS->ttrans_filter = calloc_2(TTRANS_FILTER_MAX+1, sizeof(struct pipe_ctx *)); } for(i=0;ittranssel_filter[i] = NULL; GLOBALS->ttrans_filter[i] = NULL; } } void remove_all_ttrans_filters(void) { struct Global *GLOBALS_cache = GLOBALS; unsigned int i, j; for(j=0;jnum_notebook_pages;j++) { GLOBALS = (*GLOBALS->contexts)[j]; for(i=1;ittrans_filter[i]) { pipeio_destroy(GLOBALS->ttrans_filter[i]); GLOBALS->ttrans_filter[i] = NULL; } if(GLOBALS->ttranssel_filter[i]) { free_2(GLOBALS->ttranssel_filter[i]); GLOBALS->ttranssel_filter[i] = NULL; } } GLOBALS = GLOBALS_cache; } } int traverse_vector_nodes(Trptr t); static void regen_display(void) { if(GLOBALS->signalarea && GLOBALS->wavearea) { GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } /* * this is likely obsolete */ #if 0 static void remove_ttrans_filter(int which, int regen) { if(GLOBALS->ttrans_filter[which]) { pipeio_destroy(GLOBALS->ttrans_filter[which]); GLOBALS->ttrans_filter[which] = NULL; if(regen) { regen_display(); } } } #endif static void load_ttrans_filter(int which, char *name) { FILE *stream; char *cmd; char exec_name[1025]; char abs_path [1025]; char* arg, end; int result; exec_name[0] = 0; abs_path[0] = 0; /* if name has arguments grab only the first word (the name of the executable)*/ sscanf(name, "%s ", exec_name); arg = name + strlen(exec_name); /* remove leading spaces from argument */ while (isspace((int)(unsigned char)arg[0])) { arg++; } /* remove trailing spaces from argument */ if (strlen(arg) > 0) { end = strlen(arg) - 1; while (arg[(int)end] == ' ') { arg[(int)end] = 0; end--; } } /* turn the exec_name into an absolute path */ #if !defined __MINGW32__ && !defined _MSC_VER cmd = (char *)malloc_2(strlen(exec_name)+6+1); sprintf(cmd, "which %s", exec_name); stream = popen(cmd, "r"); result = fscanf(stream, "%s", abs_path); if((strlen(abs_path) == 0)||(!result)) { status_text("Could not find transaction filter process!\n"); pclose(stream); /* cppcheck */ return; } pclose(stream); free_2(cmd); #else strcpy(abs_path, exec_name); #endif /* remove_ttrans_filter(which, 0); ... should never happen from GUI, but perhaps possible from save files or other weirdness */ if(!GLOBALS->ttrans_filter[which]) { GLOBALS->ttrans_filter[which] = pipeio_create(abs_path, arg); } } int install_ttrans_filter(int which) { int found = 0; if((which<0)||(which>=(PROC_FILTER_MAX+1))) { which = 0; } if(GLOBALS->traces.first) { Trptr t = GLOBALS->traces.first; while(t) { if(t->flags&TR_HIGHLIGHT) { if((!t->vector) && (which)) { bvptr v = combine_traces(1, t); /* down: make single signal a vector */ if(v) { v->transaction_nd = t->n.nd; /* cache for savefile, disable */ t->vector = 1; t->n.vec = v; /* splice in */ } } if((t->vector) && (!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH)))) { t->t_filter = which; t->t_filter_converted = 0; /* back out allocation to revert (if any) */ if(t->n.vec->transaction_cache) { int i; bvptr bv = t->n.vec; bvptr bv2; nptr ndcache = NULL; t->n.vec = bv->transaction_cache; if((t->n.vec->transaction_nd) && (!which)) { ndcache = t->n.vec->transaction_nd; } while(bv) { bv2 = bv->transaction_chain; if(bv->bvname) { free_2(bv->bvname); } for(i=0;inumregions;i++) { free_2(bv->vectors[i]); } free_2(bv); bv = bv2; } t->name = t->n.vec->bvname; if(GLOBALS->hier_max_level) t->name = hier_extract(t->name, GLOBALS->hier_max_level); if(ndcache) { t->n.nd = ndcache; t->vector = 0; /* still need to deallocate old t->n.vec! */ } } if(!which) { t->flags &= (~(TR_TTRANSLATED|TR_ANALOGMASK)); } else { t->flags &= (~(TR_ANALOGMASK)); t->flags |= TR_TTRANSLATED; if(t->transaction_args) free_2(t->transaction_args); if(GLOBALS->ttranslate_args) { t->transaction_args = strdup_2(GLOBALS->ttranslate_args); } else { t->transaction_args = NULL; } traverse_vector_nodes(t); } found++; if(t->t_match) { Trptr curr_trace = t; t = t->t_next; while(t && (t->t_match != curr_trace)) { t = t->t_next; } } } } t=GiveNextTrace(t); } } if(found) { regen_display(); } return(found); } /************************************************************************/ static void destroy_callback(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; GLOBALS->is_active_ttranslate_c_2=0; gtk_widget_destroy(GLOBALS->window_ttranslate_c_5); GLOBALS->window_ttranslate_c_5 = NULL; } static void ok_callback(GtkWidget *widget, GtkWidget *nothing) { install_ttrans_filter(GLOBALS->current_filter_ttranslate_c_1); destroy_callback(widget, nothing); } static void select_row_callback(GtkWidget *widget, gint row, gint column, GdkEventButton *event, gpointer data) { (void)widget; (void)column; (void)event; (void)data; GLOBALS->current_filter_ttranslate_c_1 = row + 1; } static void unselect_row_callback(GtkWidget *widget, gint row, gint column, GdkEventButton *event, gpointer data) { (void)widget; (void)row; (void)column; (void)event; (void)data; GLOBALS->current_filter_ttranslate_c_1 = 0; /* none */ } static void add_filter_callback_2(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; int i; GtkCList *cl; if(!GLOBALS->filesel_ok) { return; } if(*GLOBALS->fileselbox_text) { for(i=0;inum_ttrans_filters;i++) { if(GLOBALS->ttranssel_filter[i]) { if(!strcmp(GLOBALS->ttranssel_filter[i], *GLOBALS->fileselbox_text)) { status_text("Filter already imported.\n"); if(GLOBALS->is_active_ttranslate_c_2) gdk_window_raise(GLOBALS->window_ttranslate_c_5->window); return; } } } } GLOBALS->num_ttrans_filters++; load_ttrans_filter(GLOBALS->num_ttrans_filters, *GLOBALS->fileselbox_text); if(GLOBALS->ttrans_filter[GLOBALS->num_ttrans_filters]) { if(GLOBALS->ttranssel_filter[GLOBALS->num_ttrans_filters]) free_2(GLOBALS->ttranssel_filter[GLOBALS->num_ttrans_filters]); GLOBALS->ttranssel_filter[GLOBALS->num_ttrans_filters] = malloc_2(strlen(*GLOBALS->fileselbox_text) + 1); strcpy(GLOBALS->ttranssel_filter[GLOBALS->num_ttrans_filters], *GLOBALS->fileselbox_text); cl=GTK_CLIST(GLOBALS->clist_ttranslate_c_2); gtk_clist_freeze(cl); gtk_clist_append(cl,(gchar **)&(GLOBALS->ttranssel_filter[GLOBALS->num_ttrans_filters])); gtk_clist_set_column_width(cl,0,gtk_clist_optimal_column_width(cl,0)); gtk_clist_thaw(cl); } else { GLOBALS->num_ttrans_filters--; } if(GLOBALS->is_active_ttranslate_c_2) gdk_window_raise(GLOBALS->window_ttranslate_c_5->window); } static void add_filter_callback(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; if(GLOBALS->num_ttrans_filters == TTRANS_FILTER_MAX) { status_text("Max number of transaction filters processes installed already.\n"); return; } fileselbox("Select Transaction Filter Process",&GLOBALS->fcurr_ttranslate_c_1,GTK_SIGNAL_FUNC(add_filter_callback_2), GTK_SIGNAL_FUNC(NULL),"*", 0); } /* * mainline.. */ void ttrans_searchbox(char *title) { int i; GtkWidget *scrolled_win; GtkWidget *vbox1, *hbox, *hbox0; GtkWidget *button1, *button5, *button6; gchar *titles[]={"Transaction Process Filter Select"}; GtkWidget *frame2, *frameh, *frameh0; GtkWidget *table; GtkTooltips *tooltips; GtkWidget *label; GtkWidget *entry; if(GLOBALS->is_active_ttranslate_c_2) { gdk_window_raise(GLOBALS->window_ttranslate_c_5->window); return; } GLOBALS->is_active_ttranslate_c_2=1; GLOBALS->current_filter_ttranslate_c_1 = 0; /* create a new modal window */ GLOBALS->window_ttranslate_c_5 = gtk_window_new(GLOBALS->disable_window_manager ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL); install_focus_cb(GLOBALS->window_ttranslate_c_5, ((char *)&GLOBALS->window_ttranslate_c_5) - ((char *)GLOBALS)); gtk_window_set_title(GTK_WINDOW (GLOBALS->window_ttranslate_c_5), title); gtkwave_signal_connect(GTK_OBJECT (GLOBALS->window_ttranslate_c_5), "delete_event",(GtkSignalFunc) destroy_callback, NULL); tooltips=gtk_tooltips_new_2(); table = gtk_table_new (256, 1, FALSE); gtk_widget_show (table); vbox1 = gtk_vbox_new (FALSE, 0); gtk_container_border_width (GTK_CONTAINER (vbox1), 3); gtk_widget_show (vbox1); frame2 = gtk_frame_new (NULL); gtk_container_border_width (GTK_CONTAINER (frame2), 3); gtk_widget_show(frame2); gtk_table_attach (GTK_TABLE (table), frame2, 0, 1, 0, 253, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); GLOBALS->clist_ttranslate_c_2=gtk_clist_new_with_titles(1,titles); gtk_clist_column_titles_passive(GTK_CLIST(GLOBALS->clist_ttranslate_c_2)); gtk_clist_set_selection_mode(GTK_CLIST(GLOBALS->clist_ttranslate_c_2), GTK_SELECTION_EXTENDED); gtkwave_signal_connect_object (GTK_OBJECT (GLOBALS->clist_ttranslate_c_2), "select_row",GTK_SIGNAL_FUNC(select_row_callback),NULL); gtkwave_signal_connect_object (GTK_OBJECT (GLOBALS->clist_ttranslate_c_2), "unselect_row",GTK_SIGNAL_FUNC(unselect_row_callback),NULL); for(i=0;inum_ttrans_filters;i++) { gtk_clist_append(GTK_CLIST(GLOBALS->clist_ttranslate_c_2),(gchar **)&(GLOBALS->ttranssel_filter[i+1])); } gtk_clist_set_column_width(GTK_CLIST(GLOBALS->clist_ttranslate_c_2),0,gtk_clist_optimal_column_width(GTK_CLIST(GLOBALS->clist_ttranslate_c_2),0)); gtk_widget_show (GLOBALS->clist_ttranslate_c_2); scrolled_win = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_widget_set_usize( GTK_WIDGET (scrolled_win), -1, 300); gtk_widget_show(scrolled_win); /* gtk_scrolled_window_add_with_viewport doesn't seen to work right here.. */ gtk_container_add (GTK_CONTAINER (scrolled_win), GLOBALS->clist_ttranslate_c_2); gtk_container_add (GTK_CONTAINER (frame2), scrolled_win); frameh0 = gtk_frame_new (NULL); gtk_container_border_width (GTK_CONTAINER (frameh0), 3); gtk_widget_show(frameh0); gtk_table_attach (GTK_TABLE (table), frameh0, 0, 1, 253, 254, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); hbox0 = gtk_hbox_new (FALSE, 1); gtk_widget_show (hbox0); button6 = gtk_button_new_with_label (" Add Trans Filter to List "); gtk_container_border_width (GTK_CONTAINER (button6), 3); gtkwave_signal_connect_object (GTK_OBJECT (button6), "clicked",GTK_SIGNAL_FUNC(add_filter_callback),GTK_OBJECT (GLOBALS->window_ttranslate_c_5)); gtk_widget_show (button6); gtk_tooltips_set_tip_2(tooltips, button6, "Bring up a file requester to add a transaction process filter to the filter select window.",NULL); gtk_box_pack_start (GTK_BOX (hbox0), button6, TRUE, FALSE, 0); gtk_container_add (GTK_CONTAINER (frameh0), hbox0); /* args entry box */ { Trptr t=GLOBALS->traces.first; while(t) { if(t->flags&TR_HIGHLIGHT) { if(t->transaction_args) { if(GLOBALS->ttranslate_args) free_2(GLOBALS->ttranslate_args); GLOBALS->ttranslate_args = strdup_2(t->transaction_args); break; } } t=t->t_next; } frameh0 = gtk_frame_new (NULL); gtk_container_border_width (GTK_CONTAINER (frameh0), 3); gtk_widget_show(frameh0); gtk_table_attach (GTK_TABLE (table), frameh0, 0, 1, 254, 255, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); label=gtk_label_new("Args:"); entry=gtk_entry_new_with_max_length(1025); gtk_entry_set_text(GTK_ENTRY(entry), GLOBALS->ttranslate_args ? GLOBALS->ttranslate_args : ""); gtk_signal_connect (GTK_OBJECT (entry), "activate",GTK_SIGNAL_FUNC (args_entry_callback), entry); gtk_signal_connect (GTK_OBJECT (entry), "changed",GTK_SIGNAL_FUNC (args_entry_callback), entry); hbox0=gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox0), label, FALSE, FALSE, 0); gtk_widget_show(label); gtk_box_pack_start(GTK_BOX(hbox0), entry, TRUE, TRUE, 0); gtk_widget_show(entry); gtk_widget_show(hbox0); gtk_container_add (GTK_CONTAINER (frameh0), hbox0); } /* bottom OK/Cancel part */ frameh = gtk_frame_new (NULL); gtk_container_border_width (GTK_CONTAINER (frameh), 3); gtk_widget_show(frameh); gtk_table_attach (GTK_TABLE (table), frameh, 0, 1, 255, 256, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); hbox = gtk_hbox_new (FALSE, 1); gtk_widget_show (hbox); button1 = gtk_button_new_with_label (" OK "); gtk_container_border_width (GTK_CONTAINER (button1), 3); gtkwave_signal_connect_object (GTK_OBJECT (button1), "clicked",GTK_SIGNAL_FUNC(ok_callback),GTK_OBJECT (GLOBALS->window_ttranslate_c_5)); gtk_widget_show (button1); gtk_tooltips_set_tip_2(tooltips, button1, "Add selected signals to end of the display on the main window.",NULL); gtk_box_pack_start (GTK_BOX (hbox), button1, TRUE, FALSE, 0); button5 = gtk_button_new_with_label (" Cancel "); gtk_container_border_width (GTK_CONTAINER (button5), 3); gtkwave_signal_connect_object (GTK_OBJECT (button5), "clicked",GTK_SIGNAL_FUNC(destroy_callback),GTK_OBJECT (GLOBALS->window_ttranslate_c_5)); gtk_tooltips_set_tip_2(tooltips, button5, "Do nothing and return to the main window.",NULL); gtk_widget_show (button5); gtk_box_pack_start (GTK_BOX (hbox), button5, TRUE, FALSE, 0); gtk_container_add (GTK_CONTAINER (frameh), hbox); gtk_container_add (GTK_CONTAINER (GLOBALS->window_ttranslate_c_5), table); gtk_widget_set_usize(GTK_WIDGET(GLOBALS->window_ttranslate_c_5), 400, 400); gtk_widget_show(GLOBALS->window_ttranslate_c_5); } /* * currently only called by parsewavline */ void set_current_translate_ttrans(char *name) { int i; for(i=1;inum_ttrans_filters+1;i++) { if(!strcmp(GLOBALS->ttranssel_filter[i], name)) { GLOBALS->current_translate_ttrans = i; return; } } if(GLOBALS->num_ttrans_filters < TTRANS_FILTER_MAX) { GLOBALS->num_ttrans_filters++; load_ttrans_filter(GLOBALS->num_ttrans_filters, name); if(!GLOBALS->ttrans_filter[GLOBALS->num_ttrans_filters]) { GLOBALS->num_ttrans_filters--; GLOBALS->current_translate_ttrans = 0; } else { if(GLOBALS->ttranssel_filter[GLOBALS->num_ttrans_filters]) free_2(GLOBALS->ttranssel_filter[GLOBALS->num_ttrans_filters]); GLOBALS->ttranssel_filter[GLOBALS->num_ttrans_filters] = malloc_2(strlen(name) + 1); strcpy(GLOBALS->ttranssel_filter[GLOBALS->num_ttrans_filters], name); GLOBALS->current_translate_ttrans = GLOBALS->num_ttrans_filters; } } } int traverse_vector_nodes(Trptr t) { int i; int cvt_ok = 0; if((t->t_filter) && (t->flags & TR_TTRANSLATED) && (t->vector) && (!t->t_filter_converted)) { #if !defined _MSC_VER && !defined __MINGW32__ int rc = save_nodes_to_trans(GLOBALS->ttrans_filter[t->t_filter]->sout, t); #else int rc = save_nodes_to_trans((FILE *)(GLOBALS->ttrans_filter[t->t_filter]->g_hChildStd_IN_Wr), t); #endif if(rc == VCDSAV_OK) { int is_finish = 0; bvptr prev_transaction_trace = NULL; while(!is_finish) { struct VectorEnt *vt_head = NULL, *vt_curr = NULL; struct VectorEnt *vt; struct VectorEnt *vprev; bvptr bv; int regions = 2; TimeType prev_tim = LLDescriptor(-1); char *trace_name = NULL; char *orig_name = t->n.vec->bvname; cvt_ok = 1; vt_head = vt_curr = vt = calloc_2(1, sizeof(struct VectorEnt) + 1); vt->time = LLDescriptor(-2); vprev = vt; /* for duplicate removal */ vt_curr = vt_curr->next = vt = calloc_2(1, sizeof(struct VectorEnt) + 1); vt->time = LLDescriptor(-1); for(;;) { char buf[1025]; char *pnt, *rtn; #if !defined _MSC_VER && !defined __MINGW32__ if(feof(GLOBALS->ttrans_filter[t->t_filter]->sin)) break; /* should never happen */ buf[0] = 0; pnt = fgets(buf, 1024, GLOBALS->ttrans_filter[t->t_filter]->sin); if(!pnt) break; rtn = pnt; while(*rtn) { if((*rtn == '\n') || (*rtn == '\r')) { *rtn = 0; break; } rtn++; } #else { BOOL bSuccess; DWORD dwRead; int n; for(n=0;n<1024;n++) { do { bSuccess = ReadFile(GLOBALS->ttrans_filter[t->t_filter]->g_hChildStd_OUT_Rd, buf+n, 1, &dwRead, NULL); if((!bSuccess)||(buf[n]=='\n')) { goto ex; } } while(buf[n]=='\r'); } ex: buf[n] = 0; pnt = buf; } #endif while(*pnt) { if(isspace((int)(unsigned char)*pnt)) pnt++; else break;} if(*pnt=='#') { TimeType tim = atoi_64(pnt+1) * GLOBALS->time_scale; int slen; char *sp; while(*pnt) { if(!isspace((int)(unsigned char)*pnt)) pnt++; else break; } while(*pnt) { if(isspace((int)(unsigned char)*pnt)) pnt++; else break; } sp = pnt; slen = strlen(sp); if(slen) { pnt = sp + slen - 1; do { if(isspace((int)(unsigned char)*pnt)) { *pnt = 0; pnt--; slen--; } else { break; } } while(pnt != (sp-1)); } vt = calloc_2(1, sizeof(struct VectorEnt) + slen + 1); if(sp) strcpy((char *)vt->v, sp); if(tim > prev_tim) { prev_tim = vt->time = tim; vt_curr->next = vt; vt_curr = vt; vprev = vprev->next; /* bump forward the -2 node pointer */ regions++; } else if(tim == prev_tim) { vt->time = prev_tim; free_2(vt_curr); vt_curr = vprev->next = vt; /* splice new one in -1 node place */ } else { free_2(vt); /* throw it away */ } continue; } else if((*pnt=='M')||(*pnt=='m')) { int mlen; pnt++; mlen = bijective_marker_id_string_len(pnt); if(mlen) { int which_marker = bijective_marker_id_string_hash(pnt); if((which_marker >= 0) && (which_marker < WAVE_NUM_NAMED_MARKERS)) { TimeType tim = atoi_64(pnt+mlen) * GLOBALS->time_scale; int slen; char *sp; if(tim < LLDescriptor(0)) tim = LLDescriptor(-1); GLOBALS->named_markers[which_marker] = tim; while(*pnt) { if(!isspace((int)(unsigned char)*pnt)) pnt++; else break; } while(*pnt) { if(isspace((int)(unsigned char)*pnt)) pnt++; else break; } sp = pnt; slen = strlen(sp); if(slen) { pnt = sp + slen - 1; do { if(isspace((int)(unsigned char)*pnt)) { *pnt = 0; pnt--; slen--; } else { break; } } while(pnt != (sp-1)); } if(GLOBALS->marker_names[which_marker]) free_2(GLOBALS->marker_names[which_marker]); GLOBALS->marker_names[which_marker] = (sp && (*sp) && (tim >= LLDescriptor(0))) ? strdup_2(sp) : NULL; } } continue; } else if(*pnt == '$') { if(!strncmp(pnt+1, "finish", 6)) { is_finish = 1; break; } else if(!strncmp(pnt+1, "next", 4)) { break; } else if(!strncmp(pnt+1, "name", 4)) { int slen; char *sp; pnt+=5; while(*pnt) { if(isspace((int)(unsigned char)*pnt)) pnt++; else break; } sp = pnt; slen = strlen(sp); if(slen) { pnt = sp + slen - 1; do { if(isspace((int)(unsigned char)*pnt)) { *pnt = 0; pnt--; slen--; } else { break; } } while(pnt != (sp-1)); } if(sp && *sp) { if(trace_name) free_2(trace_name); trace_name = strdup_2(sp); } } } } vt_curr = vt_curr->next = vt = calloc_2(1, sizeof(struct VectorEnt) + 1); vt->time = MAX_HISTENT_TIME - 1; regions++; /* vt_curr = */ vt_curr->next = vt = calloc_2(1, sizeof(struct VectorEnt) + 1); /* scan-build */ vt->time = MAX_HISTENT_TIME; regions++; bv = calloc_2(1, sizeof(struct BitVector) + (sizeof(vptr) * (regions))); bv->bvname = strdup_2(trace_name ? trace_name : orig_name); bv->nbits = 1; bv->numregions = regions; bv->bits = t->n.vec->bits; vt = vt_head; for(i=0;ivectors[i] = vt; vt = vt->next; } if(!prev_transaction_trace) { prev_transaction_trace = bv; bv->transaction_cache = t->n.vec; /* for possible restore later */ t->n.vec = bv; t->t_filter_converted = 1; if(trace_name) /* if NULL, no need to regen display as trace name didn't change */ { t->name = t->n.vec->bvname; if(GLOBALS->hier_max_level) t->name = hier_extract(t->name, GLOBALS->hier_max_level); regen_display(); } } else { prev_transaction_trace->transaction_chain = bv; prev_transaction_trace = bv; } } } else { /* failed */ t->flags &= ~(TR_TTRANSLATED|TR_ANALOGMASK); } } return(cvt_ok); } gtkwave-3.3.66/src/symbol.c0000664000076400007640000001456412360623564015060 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2001-2010 * * 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. */ #include #include "globals.h" #include #ifndef _MSC_VER #include #ifndef __MINGW32__ #include #endif #else #include #endif #include #include #include #include #include #include "symbol.h" #include "vcd.h" #include "lxt.h" #include "bsearch.h" #include "hierpack.h" #ifdef _WAVE_HAVE_JUDY #include #endif /* * s_selected accessors */ #ifdef _WAVE_HAVE_JUDY char get_s_selected(struct symbol *s) { int rc = Judy1Test(GLOBALS->s_selected, (Word_t)s, PJE0); return(rc); } char set_s_selected(struct symbol *s, char value) { if(value) { Judy1Set ((Pvoid_t)&GLOBALS->s_selected, (Word_t)s, PJE0); } else { Judy1Unset ((Pvoid_t)&GLOBALS->s_selected, (Word_t)s, PJE0); } return(value); } void destroy_s_selected(void) { Judy1FreeArray(&GLOBALS->s_selected, PJE0); GLOBALS->s_selected = NULL; } #else char get_s_selected(struct symbol *s) { return(s->s_selected); } char set_s_selected(struct symbol *s, char value) { return((s->s_selected = value)); } void destroy_s_selected(void) { /* nothing */ } #endif /* * hash create/destroy */ void sym_hash_initialize(void *g) { #ifdef _WAVE_HAVE_JUDY ((struct Global *)g)->sym_judy = NULL; #else ((struct Global *)g)->sym_hash=(struct symbol **)calloc_2(SYMPRIME,sizeof(struct symbol *)); #endif } void sym_hash_destroy(void *g) { struct Global *gg = (struct Global *)g; #ifdef _WAVE_HAVE_JUDY JudySLFreeArray(&gg->sym_judy, PJE0); gg->sym_judy = NULL; #else if(gg->sym_hash) { free_2(gg->sym_hash); gg->sym_hash = NULL; } #endif } /* * Generic hash function for symbol names... */ int hash(char *s) { #ifndef _WAVE_HAVE_JUDY char *p; char ch; unsigned int h=0, h2=0, pos=0, g; for(p=s;*p;p++) { ch=*p; h2<<=3; h2-=((unsigned int)ch+(pos++)); /* this handles stranded vectors quite well.. */ h=(h<<4)+ch; if((g=h&0xf0000000)) { h=h^(g>>24); h=h^g; } } h^=h2; /* combine the two hashes */ GLOBALS->hashcache=h%SYMPRIME; #else (void)s; #endif return(GLOBALS->hashcache); } /* * add symbol to table. no duplicate checking * is necessary as aet's are "correct." */ struct symbol *symadd(char *name, int hv) { struct symbol *s=(struct symbol *)calloc_2(1,sizeof(struct symbol)); #ifdef _WAVE_HAVE_JUDY (void)hv; PPvoid_t PPValue = JudySLIns(&GLOBALS->sym_judy, (uint8_t *)name, PJE0); *((struct symbol **)PPValue) = s; #else strcpy(s->name=(char *)malloc_2(strlen(name)+1),name); s->sym_next=GLOBALS->sym_hash[hv]; GLOBALS->sym_hash[hv]=s; #endif return(s); } struct symbol *symadd_name_exists(char *name, int hv) { struct symbol *s=(struct symbol *)calloc_2(1,sizeof(struct symbol)); #ifdef _WAVE_HAVE_JUDY (void)hv; PPvoid_t PPValue = JudySLIns(&GLOBALS->sym_judy, (uint8_t *)name, PJE0); *((struct symbol **)PPValue) = s; s->name = name; /* redundant for now */ #else s->name = name; s->sym_next=GLOBALS->sym_hash[hv]; GLOBALS->sym_hash[hv]=s; #endif return(s); } /* * find a slot already in the table... */ static struct symbol *symfind_2(char *s, unsigned int *rows_return) { #ifndef _WAVE_HAVE_JUDY int hv; struct symbol *temp; #endif if(!GLOBALS->facs_are_sorted) { #ifdef _WAVE_HAVE_JUDY PPvoid_t PPValue = JudySLGet(GLOBALS->sym_judy, (uint8_t *)s, PJE0); if(PPValue) { return(*(struct symbol **)PPValue); } #else hv=hash(s); if(!(temp=GLOBALS->sym_hash[hv])) return(NULL); /* no hash entry, add here wanted to add */ while(temp) { if(!strcmp(temp->name,s)) { return(temp); /* in table already */ } if(!temp->sym_next) break; temp=temp->sym_next; } #endif return(NULL); /* not found, add here if you want to add*/ } else /* no sense hashing if the facs table is built */ { struct symbol *sr; DEBUG(printf("BSEARCH: %s\n",s)); sr = bsearch_facs(s, rows_return); if(sr) { } else { /* this is because . is > in ascii than chars like $ but . was converted to 0x1 on sort */ char *s2; int i; int mat; #ifndef WAVE_HIERFIX if(!GLOBALS->escaped_names_found_vcd_c_1) { return(sr); } #endif if(GLOBALS->facs_have_symbols_state_machine == 0) { if(GLOBALS->escaped_names_found_vcd_c_1) { mat = 1; } else { mat = 0; for(i=0;inumfacs;i++) { int was_packed = HIER_DEPACK_STATIC; char *hfacname = NULL; hfacname = hier_decompress_flagged(GLOBALS->facs[i]->name, &was_packed); s2 = hfacname; while(*s2) { if(*s2 < GLOBALS->hier_delimeter) { mat = 1; break; } s2++; } /* if(was_packed) { free_2(hfacname); } ...not needed with HIER_DEPACK_STATIC */ if(mat) { break; } } } if(mat) { GLOBALS->facs_have_symbols_state_machine = 1; } else { GLOBALS->facs_have_symbols_state_machine = 2; } /* prevent code below from executing */ } if(GLOBALS->facs_have_symbols_state_machine == 1) { mat = 0; for(i=0;inumfacs;i++) { int was_packed = HIER_DEPACK_STATIC; char *hfacname = NULL; hfacname = hier_decompress_flagged(GLOBALS->facs[i]->name, &was_packed); if(!strcmp(hfacname, s)) { mat = 1; } /* if(was_packed) { free_2(hfacname); } ...not needed with HIER_DEPACK_STATIC */ if(mat) { sr = GLOBALS->facs[i]; break; } } } } return(sr); } } struct symbol *symfind(char *s, unsigned int *rows_return) { struct symbol *s_pnt = symfind_2(s, rows_return); if(!s_pnt) { int len = strlen(s); if(len) { char ch = s[len-1]; if((ch != ']') && (ch != '}')) { char *s2 = wave_alloca(len + 4); memcpy(s2, s, len); strcpy(s2+len, "[0]"); /* bluespec vs modelsim */ s_pnt = symfind_2(s2, rows_return); } } } return(s_pnt); } gtkwave-3.3.66/NEWS0000664000076400007640000000000012124357656013277 0ustar bybellbybellgtkwave-3.3.66/INSTALL0000664000076400007640000003660512202251476013643 0ustar bybellbybellInstallation Instructions ************************* Copyright (C) 1994-1996, 1999-2002, 2004-2012 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 commands `./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 time stamps 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. gtkwave-3.3.66/ylwrap0000775000076400007640000001553612124357656014070 0ustar bybellbybell#! /bin/sh # ylwrap - wrapper for lex/yacc invocations. scriptversion=2012-12-21.17; # UTC # Copyright (C) 1996-2013 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 # . get_dirname () { case $1 in */*|*\\*) printf '%s\n' "$1" | sed -e 's|\([\\/]\)[^\\/]*$|\1|';; # Otherwise, we want the empty string (not "."). esac } # guard FILE # ---------- # The CPP macro used to guard inclusion of FILE. guard() { printf '%s\n' "$1" \ | sed \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \ -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g' \ -e 's/__*/_/g' } # quote_for_sed [STRING] # ---------------------- # Return STRING (or stdin) quoted to be used as a sed pattern. quote_for_sed () { case $# in 0) cat;; 1) printf '%s\n' "$1";; esac \ | sed -e 's|[][\\.*]|\\&|g' } case "$1" in '') echo "$0: No files given. Try '$0 --help' for more information." 1>&2 exit 1 ;; --basedir) basedir=$2 shift 2 ;; -h|--h*) cat <<\EOF Usage: ylwrap [--help|--version] INPUT [OUTPUT DESIRED]... -- PROGRAM [ARGS]... Wrapper for lex/yacc invocations, renaming files as desired. INPUT is the input file OUTPUT is one file PROG generates DESIRED is the file we actually want instead of OUTPUT PROGRAM is program to run ARGS are passed to PROG Any number of OUTPUT,DESIRED pairs may be used. Report bugs to . EOF exit $? ;; -v|--v*) echo "ylwrap $scriptversion" exit $? ;; esac # The input. input="$1" shift # We'll later need for a correct munging of "#line" directives. input_sub_rx=`get_dirname "$input" | quote_for_sed` case "$input" in [\\/]* | ?:[\\/]*) # Absolute path; do nothing. ;; *) # Relative path. Make it absolute. input="`pwd`/$input" ;; esac input_rx=`get_dirname "$input" | quote_for_sed` # Since DOS filename conventions don't allow two dots, # the DOS version of Bison writes out y_tab.c instead of y.tab.c # and y_tab.h instead of y.tab.h. Test to see if this is the case. y_tab_nodot=false if test -f y_tab.c || test -f y_tab.h; then y_tab_nodot=true fi # The parser itself, the first file, is the destination of the .y.c # rule in the Makefile. parser=$1 # A sed program to s/FROM/TO/g for all the FROM/TO so that, for # instance, we rename #include "y.tab.h" into #include "parse.h" # during the conversion from y.tab.c to parse.c. sed_fix_filenames= # Also rename header guards, as Bison 2.7 for instance uses its header # guard in its implementation file. sed_fix_header_guards= while test "$#" -ne 0; do if test "$1" = "--"; then shift break fi from=$1 # Handle y_tab.c and y_tab.h output by DOS if $y_tab_nodot; then case $from in "y.tab.c") from=y_tab.c;; "y.tab.h") from=y_tab.h;; esac fi shift to=$1 shift sed_fix_filenames="${sed_fix_filenames}s|"`quote_for_sed "$from"`"|$to|g;" sed_fix_header_guards="${sed_fix_header_guards}s|"`guard "$from"`"|"`guard "$to"`"|g;" done # The program to run. prog="$1" shift # Make any relative path in $prog absolute. case "$prog" in [\\/]* | ?:[\\/]*) ;; *[\\/]*) prog="`pwd`/$prog" ;; esac # FIXME: add hostname here for parallel makes that run commands on # other machines. But that might take us over the 14-char limit. dirname=ylwrap$$ do_exit="cd '`pwd`' && rm -rf $dirname > /dev/null 2>&1;"' (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 mkdir $dirname || exit 1 cd $dirname case $# in 0) "$prog" "$input" ;; *) "$prog" "$@" "$input" ;; esac ret=$? if test $ret -eq 0; then for from in * do to=`printf '%s\n' "$from" | sed "$sed_fix_filenames"` if test -f "$from"; then # If $2 is an absolute path name, then just use that, # otherwise prepend '../'. case $to in [\\/]* | ?:[\\/]*) target=$to;; *) target="../$to";; esac # Do not overwrite unchanged header files to avoid useless # recompilations. Always update the parser itself: it is the # destination of the .y.c rule in the Makefile. Divert the # output of all other files to a temporary file so we can # compare them to existing versions. if test $from != $parser; then realtarget="$target" target=tmp-`printf '%s\n' "$target" | sed 's|.*[\\/]||g'` fi # Munge "#line" or "#" directives. Don't let the resulting # debug information point at an absolute srcdir. Use the real # output file name, not yy.lex.c for instance. Adjust the # include guards too. sed -e "/^#/!b" \ -e "s|$input_rx|$input_sub_rx|" \ -e "$sed_fix_filenames" \ -e "$sed_fix_header_guards" \ "$from" >"$target" || ret=$? # Check whether files must be updated. if test "$from" != "$parser"; then if test -f "$realtarget" && cmp -s "$realtarget" "$target"; then echo "$to is unchanged" rm -f "$target" else echo "updating $to" mv -f "$target" "$realtarget" fi fi else # A missing file is only an error for the parser. This is a # blatant hack to let us support using "yacc -d". If -d is not # specified, don't fail when the header file is "missing". if test "$from" = "$parser"; then ret=1 fi fi done fi # Remove the directory. cd .. rm -rf $dirname exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: gtkwave-3.3.66/README0000664000076400007640000001246712124357656013504 0ustar bybellbybell1) Type ./configure 2) make 3) make install (as root) Make sure you copy the .gtkwaverc file to your home directory or to your VCD project directory. It contains the prefs for a good configuration that most people find ergonomic. It is not strictly necessary however. [Note: for mingw builds with gtk+-1, you might need a fake gtk-config file like the following..] <> #!/bin/sh if [ "$1" == "--libs" ] then echo -L/home/bybell/libs -lgck -lgdk-1.3 -lgimp-1.2 -lgimpi -lgimpui-1.2 -lglib-1.3 -lgmodule-1.3 -lgnu-intl -lgobject-1.3 -lgthread-1.3 -lgtk-1.3 -liconv-1.3 -ljpeg -llibgplugin_a -llibgplugin_b -lpng -lpthread32 -ltiff-lzw -ltiff-nolzw -ltiff fi if [ "$1" == "--cflags" ] then echo " -mms-bitfields -I/home/bybell/src/glib -I/home/bybell/src/gtk+/gtk -I/home/bybell/src/gtk+/gdk -I/home/bybell/src/gtk+ " fi <> [Note2: for mingw with gtk+-2, you don't need to do anything except have pkg-config in your PATH however the following note is from Thomas Uhle.] Important to know is to compile with CFLAGS=-mms-bitfields in Windows in order to link correctly to the GTK+ dlls. This is how I did configure GTKWave with additional optimisation switches: ./configure CFLAGS='-Wall -O3 -mcpu=i686 -mms-bitfields -ffast-math -fstrict-aliasing' After that you may just call make the usual way. Note that Ver Structural Verilog Compiler AET files are no longer supported. They have been superceded by LXT. Also note that the AMULET group will be taking over maintenance of the viewer effective immediately. -251201ajb bybell@nc.rr.com AMULET has ceased development of the 2.x branch of the viewer. 1.3 apparently is the only active version currently. -150405ajb bybell@nc.rr.com The 1.3 series has been promoted to 3.x in order to prevent confusion over what version of the viewer is the latest. Starting with 3.x, the viewer supports source code annotation. -030406ajb bybell@nc.rr.com Add these flags to your compile for new warnings on AMD64: -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic on i386: -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i386 -mtune=generic -fasynchronous-unwind-tables -150407ajb For cvs access to the experimental, pre-release sourcetree on Sourceforge: cvs -d:pserver:anonymous@gtkwave.cvs.sourceforge.net:/cvsroot/gtkwave login [press enter] cvs -z3 -d:pserver:anonymous@gtkwave.cvs.sourceforge.net:/cvsroot/gtkwave co -P gtkwave3 -191208ajb bybell@nc.rr.com CVS is no longer being updated, for SVN access: svn co https://gtkwave.svn.sourceforge.net/svnroot/gtkwave gtkwave -310511ajb =============================================================================== Note (1) For Ubuntu users: I had to do the following to get it to install directly. Please include in INSTALL .txt as an option for ubuntu users. Other linux distributions might have other things to do. sudo apt-get install libgtk2.0-dev ./configure --with-tcl=/usr/lib/tcl8.4 --with-tk=/usr/lib/tk8.4 -030109ajb bybell@nc.rr.com Note (2) For Ubuntu users: If your compile fails because gzopen64 cannot be found, you will either have to fix your Ubuntu install or use the version of libz in gtkwave: ./configure --enable-local-libz -140409ajb bybell@nc.rr.com Note (3) For Ubuntu users (version 11.10): sudo apt-get install libjudy-dev sudo apt-get install libbz2-dev sudo apt-get install liblzma-dev sudo apt-get install libgconf2-dev sudo apt-get install libgtk2.0-dev sudo apt-get install tcl-dev sudo apt-get install tk-dev sudo apt-get install gperf sudo apt-get install gtk2-engines-pixbuf Configure then as: ./configure --enable-judy --enable-struct-pack --with-gconf -010212ajb bybell@nc.rr.com =============================================================================== Notes for Mac OSX users: Install MacPorts then sudo port -v selfupdate sudo port install Judy tcl tk xz-devel gtk2 If Quartz is used: sudo port install gtk-osx-application ./configure --prefix=/opt/local --enable-judy --enable-struct-pack "CFLAGS=-I/opt/local/include -O2 -g" LDFLAGS=-L/opt/local/lib --no-create --no-recursion Tcl works in the OSX version of gtkwave starting with version 3.3.26. At this point all features working on Linux should be functional on the Mac, except that twinwave does not render to a single window when Quartz is used instead of X11. If you wish to use llvm, also add "CC=llvm-gcc" and change the "-O2" in CFLAGS to "-O4". At the current time Quartz support is experimental. Please report any bugs encountered as compared to X11 function. === Note that the preferred environment for Quartz builds is jhbuild. To build gtkwave as an app bundle (while in jhbuild shell): ./configure --enable-judy --enable-struct-pack --prefix=/Users/$USER/gtk/inst make make install cd contrib/bundle_for_osx ./make_bundle.sh This assumes that Judy arrays and XZ were both already compiled and installed. If Judy arrays are not installed, do not add --enable-judy. If XZ is not installed, add --disable-xz. The current environment used is modulesets. Bug 664894 has an interim fix in the binary distribution by applying patches using the contrib/bundle_for_osx/gtk_diff_against_modulesets.patch file. -311211ajb bybell@nc.rr.com =============================================================================== gtkwave-3.3.66/autogen.sh0000775000076400007640000000131711523063250014577 0ustar bybellbybell#! /bin/sh # # $Id: autogen.sh,v 1.2 2008/11/23 06:38:55 gtkwave Exp $ # # Run the various GNU autotools to bootstrap the build # system. Should only need to be done once. # for now avoid using bash as not everyone has that installed CONFIG_SHELL=/bin/sh export CONFIG_SHELL echo "Running aclocal..." aclocal $ACLOCAL_FLAGS || exit 1 echo "Done with aclocal" echo "Running autoheader..." autoheader || exit 1 echo "Done with autoheader" echo "Running automake..." automake -a -c --foreign || exit 1 echo "Done with automake" echo "builtin(include,./tcl.m4)" >>aclocal.m4 echo "Running autoconf..." autoconf || exit 1 echo "Done with autoconf" echo "You must now run configure" echo "All done with autogen.sh" gtkwave-3.3.66/man/0000775000076400007640000000000012546303362013356 5ustar bybellbybellgtkwave-3.3.66/man/Makefile.in0000664000076400007640000004042212261434733015426 0ustar bybellbybell# Makefile.in generated by automake 1.13.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 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__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } 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 = : subdir = man DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(dist_man_MANS) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.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 = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac 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; }; \ } man1dir = $(mandir)/man1 am__installdirs = "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" man5dir = $(mandir)/man5 NROFF = nroff MANS = $(dist_man_MANS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AET2_CFLAGS = @AET2_CFLAGS@ AET2_LDADD = @AET2_LDADD@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COCOA_GTK_CFLAGS = @COCOA_GTK_CFLAGS@ COCOA_GTK_LDADD = @COCOA_GTK_LDADD@ COCOA_GTK_LDFLAGS = @COCOA_GTK_LDFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTDEBUG = @EXTDEBUG@ EXTDEBUG2 = @EXTDEBUG2@ EXTDEBUG3 = @EXTDEBUG3@ EXTDEBUG4 = @EXTDEBUG4@ EXTLOAD_CFLAGS = @EXTLOAD_CFLAGS@ FASTTREE_CFLAGS = @FASTTREE_CFLAGS@ FSDB_CFLAGS = @FSDB_CFLAGS@ FSDB_LDADD = @FSDB_LDADD@ GCONF_CFLAGS = @GCONF_CFLAGS@ GCONF_LIBS = @GCONF_LIBS@ GEDITTEST = @GEDITTEST@ GEDIT_CFLAGS = @GEDIT_CFLAGS@ GPERF = @GPERF@ GREP = @GREP@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_CONFIG = @GTK_CONFIG@ GTK_LIBS = @GTK_LIBS@ GTK_MAC_CFLAGS = @GTK_MAC_CFLAGS@ GTK_MAC_LIBS = @GTK_MAC_LIBS@ GTK_UNIX_PRINT_CFLAGS = @GTK_UNIX_PRINT_CFLAGS@ GTK_UNIX_PRINT_LIBS = @GTK_UNIX_PRINT_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBBZ2_CFLAGS = @LIBBZ2_CFLAGS@ LIBBZ2_DIR = @LIBBZ2_DIR@ LIBBZ2_LDADD = @LIBBZ2_LDADD@ LIBJUDY_CFLAGS = @LIBJUDY_CFLAGS@ LIBJUDY_LDADD = @LIBJUDY_LDADD@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBXZ_CFLAGS = @LIBXZ_CFLAGS@ LIBXZ_LDADD = @LIBXZ_LDADD@ LIBZ_CFLAGS = @LIBZ_CFLAGS@ LIBZ_DIR = @LIBZ_DIR@ LIBZ_LDADD = @LIBZ_LDADD@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MINGW_LDADD = @MINGW_LDADD@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ 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@ POW_LIB = @POW_LIB@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ STRUCT_PACK = @STRUCT_PACK@ TCL_DEFADD = @TCL_DEFADD@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LDADD = @TCL_LDADD@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_MAJOR_VERSION = @TCL_MAJOR_VERSION@ TCL_MINOR_VERSION = @TCL_MINOR_VERSION@ TK_INCLUDE_SPEC = @TK_INCLUDE_SPEC@ TK_LDADD = @TK_LDADD@ TK_LIB_SPEC = @TK_LIB_SPEC@ UPDATE_DESKTOP_DATABASE = @UPDATE_DESKTOP_DATABASE@ UPDATE_MIME_DATABASE = @UPDATE_MIME_DATABASE@ VERSION = @VERSION@ XDGDATADIR = @XDGDATADIR@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ 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_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ 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@ 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@ dist_man_MANS = evcd2vcd.1 fst2vcd.1 ghwdump.1 gtkwave.1 gtkwaverc.5 lxt2miner.1 \ lxt2vcd.1 rtlbrowse.1 shmidcat.1 \ twinwave.1 vcd2fst.1 vcd2lxt.1 vcd2lxt2.1 \ vcd2vzt.1 vermin.1 vzt2vcd.1 vztminer.1 fstminer.1 all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(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) --foreign man/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign man/Makefile .PRECIOUS: 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__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-man1: $(dist_man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(dist_man_MANS)'; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) install-man5: $(dist_man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(dist_man_MANS)'; \ test -n "$(man5dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man5dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man5dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.5[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man5dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man5dir)" || exit $$?; }; \ done; } uninstall-man5: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man5dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.5[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man5dir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(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 $(MANS) installdirs: for dir in "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)"; 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 mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-man5 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 Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-man uninstall-man: uninstall-man1 uninstall-man5 .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic cscopelist-am \ ctags-am distclean distclean-generic 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-man1 install-man5 \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic pdf pdf-am ps ps-am tags-am uninstall \ uninstall-am uninstall-man uninstall-man1 uninstall-man5 # 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: gtkwave-3.3.66/man/gtkwave.10000664000076400007640000002540012325464415015113 0ustar bybellbybell.TH "GTKWAVE" "1" "3.3.59" "Anthony Bybell" "Simulation Wave Viewer" .SH "NAME" .LP gtkwave \- Visualization tool for VCD, LXT, LXT2, VZT, FST, and GHW files .SH "SYNTAX" .LP gtkwave [\fIoption\fP]... [\fIDUMPFILE\fP] [\fISAVEFILE\fP] [\fIRCFILE\fP] .SH "DESCRIPTION" .LP Visualization tool for VCD, LXT, LXT2, VZT, FST, and GHW. VCD is an industry standard simulation dump format. LXT, LXT2, VZT, and FST have been designed specifically for use with gtkwave. GHW is the native VHDL format generated by GHDL. Native dumpers exist in Icarus Verilog and the open source version of VeriWell for the LXT formats so conversion with \fIvcd2lxt\fP(1) or \fIvcd2lxt2\fP(1) is not necessary to take direct advantage of LXT with those simulators. AET2 files can also be processed provided that libae2rw is available but this is only of interest to people who use IBM EDA toolsets. .SH "OPTIONS" .LP .TP \fB\-n\fR,\fB\-\-nocli\fR <\fIdirectory name\fP> Use file requester for dumpfile name. .TP \fB\-f\fR,\fB\-\-dump\fR <\fIfilename\fP> Specify dumpfile name. .TP \fB\-F\fR,\fB\-\-fastload\fR generate/use VCD recoder fastload files. This is similar to the \fB\-g\fR,\fB\-\-giga\fR option, however the spill file generated is not deleted. Reloading the VCD file another time (either through pressing the reload button or by re-invoking gtkwave at a later time) will use this generated spill file rather than read the value change section of the VCD file. This will speed up reloads on large files greatly as only the variable declaration section needs to be parsed. Note that the spill file contains the file size and modification date of the VCD file in order to detect if it is stale and needs to be regenerated. .TP \fB\-o\fR,\fB\-\-optimize\fR optimize VCD to FST. This will automatically call \fIvcd2fst\fP(1) to perform the file conversion. This option is highly recommended with large VCD files in order to cut down on the memory usage required for file viewing. Can be used in conjunction with \fB\-v\fR,\fB\-\-vcd\fR. .TP \fB\-a\fR,\fB\-\-save\fR <\fIfilename\fP> Specify savefile name. Useful suffixes for desktop integration are .gtkw and .sav (deprecated). .TP \fB\-A\fR,\fB\-\-autosavename\fR Assume savefile is suffix modified dumpfile name (i.e., remove and replace with ".gtkw"). .TP \fB\-r\fR,\fB\-\-rcfile\fR <\fIfilename\fP> Specify override \fI.gtkwaverc\fP filename. .TP \fB\-l\fR,\fB\-\-logfile\fR <\fIfilename\fP> Specify simulation logfile name. Multiple logfiles may be specified by preceding each with the command flag. By selecting the numbers in the text widget, the marker will immediately zoom to the specific time value. .TP \fB\-d\fR,\fB\-\-defaultskip\fR If there is not a \fI.gtkwaverc\fP file in the home directory or current directory and it is not explicitly specified on the command line, when this option is enabled, do not use an implicit configuration file and instead default to the old "whitescreen" behavior. .TP \fB\-D\fR,\fB\-\-dualid\fR <\fIwhich\fP> Specify multisession identifier information. The format of "which" is m+nnnnnnnn where m is the session number 0 or 1 and nnnnnnnn is a hexadecimal value indicating the shared memory ID of an array of two gtkwave_dual_ipc_t data structures. The intended use of this flag is for front ends such as \fItwinwave\fP(1). .TP \fB\-s\fR,\fB\-\-start\fR <\fItime\fP> Specify start time for LXT2/VZT block skip. .TP \fB\-e\fR,\fB\-\-end\fR <\fItime\fP> Specify end time for LXT2/VZT block skip. .TP \fB\-t\fR,\fB\-\-stems\fR <\fIfilename\fP> Specify stems file for source code annotation. This will automatically launch the \fIrtlbrowse\fP(1) helper process. See \fIvermin\fP(1) for information on stems file generation. .TP \fB\-c\fR,\fB\-\-cpu\fR <\fInumcpus\fP> Specify number of CPUs available for parallelizable ops (e.g., block prefetching on VZT reads). .TP \fB\-N\fR,\fB\-\-nowm\fR Disable window manager for most windows. The intended use of this is to be used in conjunction with the \fB\-\-script\fR option, however this also can be used to reparent into an alternate window manager. .TP \fB\-M\fR,\fB\-\-nomenus\fR Do not render menubar. This is mainly used for making a restricted applet that cannot initiate file I/O on its own, however it also can be used as a workaround in earlier versions of GTK+ that do not handle GTKSocket/GTKPlug focus interactions properly. .TP \fB\-S\fR,\fB\-\-script\fR <\fIfilename\fP> Specify Tcl command script file for execution. .TP \fB\-T\fR,\fB\-\-tcl_init\fR <\fIfilename\fP> Specify Tcl command script to be loaded on startup. Implies \-\-wish command flag. .TP \fB\-W\fR,\fB\-\-wish\fR Enable Tcl command line on stdio. All script commands can be typed in on stdin. .TP \fB\-R\fR,\fB\-\-repscript\fR <\fIfilename\fP> Specify Tcl command script for periodic execution. .TP \fB\-P\fR,\fB\-\-repperiod\fR <\fIvalue\fP> Specifies delay in milliseconds between successive executions of the repscript. Default is 500. .TP \fB\-X\fR,\fB\-\-xid\fR <\fIXID\fP> Specify XID (in hexadecimal) of window for a GtkPlug to connect to. GTKWave does not directly render to a window but instead renders into a GtkPlug expecting a GtkSocket at the other end. Note that there are issues with accelerators working properly so menus are disabled in the componentized version of GTKWave when it functions as a plug-in. .TP \fB\-1\fR,\fB\-\-rpcid\fR <\fIRPCID\fP> Specify RPCID of GConf session. This is a decimal value zero or greater and is the identifier used by GConf to know what update data to listen to. This option only works if \fB\-\-with-gconf\fR was specified during \fI./configure\fP. .TP \fB\-2\fR,\fB\-\-chdir\fR <\fIDIRNAME\fP> Specify new current working directory. This is typically used in OSX to run gtkwave if it was compiled and placed in an .app bundle. Note that if the environment variable GTKWAVE_CHDIR is defined, the argument is a dummy argument. This is to support OSX in that the open command has difficulty in passing spaces as command line arguments and it is possible for \fIpwd\fP(1) to return spaces. .TP \fB\-3\fR,\fB\-\-restore\fR Restore previous default (0) or \fB\-\-rpcid\fR RPCID numbered session. This only works for one dumpfile, savefile, rcfile, and current working directory so it has the effect of restoring the most recently loaded file. If used in conjunction with the \fB\-\-rpcid\fR option, that option must be specified earlier in the command line than the \fB\-\-restore\fR option. If RPCID is not specified, then the default of 0 is used. This option only works if \fB\-\-with-gconf\fR was specified during \fI./configure\fP. .TP \fB\-I\fR,\fB\-\-interactive\fR Specifies that "interactive" VCD mode is to be used which allows a viewer to navigate a VCD trace while GTKWave is processing the VCD file. When this option is used, the filename is overloaded such that it is the hexadecimal value for the shared memory ID of a writer. Note that the shared memory ID can be passed straight from stdin by using the \fB\-\-vcd\fR option; see the manpage for \fIshmidcat\fP(1) for more details. .TP \fB\-L\fR,\fB\-\-legacy\fR Specifies that the viewer should use legacy VCD mode rather than the VCD recoder. Note that using legacy mode will require considerably more memory than the recoder and its use is discouraged for very large traces. .TP \fB\-g\fR,\fB\-\-giga\fR Specifies that the viewer should use gigabyte mempacking when recoding (possibly slower). This is equivalent to setting the vlist_spill and vlist_prepack flags in the rc file. .TP \fB\-C\fR,\fB\-\-comphier\fR Specifies that the viewer should use compressed hierarchy names when loading the dumpfile (available for VCD recoder, LXT, LXT2, and VZT). This will use less memory at the expense of compression/decompression delay. .TP \fB\-v\fR,\fB\-\-vcd\fR Use stdin as a VCD dumpfile. .TP \fB-O,\fB\-\-output\fR <\fIfilename\fP> Specify filename for stdout/stderr redirect. To disable messages to the console, use /dev/null as the filename. .TP \fB\-z\fR,\fB\-\-slider-zoom\fR Enable slider stretch zoom for the horizontal time slider. Clicking then dragging the very left or right edge of the slider can be used to provide fine-grained real-time zooming. .TP \fB\-V\fR,\fB\-\-version\fR Display version banner then exit. .TP \fB\-h\fR,\fB\-\-help\fR Display help then exit. .TP \fB\-x\fR,\fB\-\-exit\fR Exit after loading trace (for loader benchmarking). .SH "FILES" .LP \fI~/.gtkwaverc\fP (see manpage \fIgtkwaverc\fP(5)) .SH "EXAMPLES" .TP To run this program the standard way type: gtkwave dumpfile.vcd .TP Alternatively you can run it with a save file as: gtkwave dumpfile.vcd dumpfile.gtkw .TP To run interactively using shared memory handle 0x00050003: gtkwave \-I 00050003 dumpfile.gtkw .TP To pick up a dumpfile automatically from a save file (e.g., when launching from an icon): gtkwave \-\-save dumpfile.gtkw .TP To run from the app bundle gtkwave.app in OSX using /bin/sh: GTKWAVE_CHDIR=\`pwd\`;export GTKWAVE_CHDIR;open \-n \-W \-a gtkwave \-\-args \-\-chdir dummy \-\-dump des.vzt \-\-save des.gtkw .TP Alternatively, run the following Perl script gtkwave.app/Contents/Resources/bin/gtkwave to process command line arguments from OSX shell scripts. .TP Note that to pass non-flag items which start with a dash, that it is required to specify \-\- in order to turn off flag parsing. A second \-\- will disable parsing of any following arguments such that they can be passed on to Tcl scripts and retrieved via gtkwave::getArgv. .LP Command line options are not necessary for representing the dumpfile, savefile, and rcfile names. They are merely provided to allow specifying them out of order. .SH "BUGS" .TP AIX requires \-bmaxdata:0x80000000 (\-bmaxdata:0xd0000000/dsa for AIX 5.3) to be added to your list of compiler flags for xlc if you want GTKWave to be able to access more than 256MB of virtual memory. The value shown allows the VMM to use up to 2GB (3.25GB AIX5.3). This may be necessary for very large traces. .TP Shift and Page operations using the wave window hscrollbar may be nonfunctional as you move away from the dump start for very large traces. A trace that goes out to 45 billion ticks has been known to exhibit this problem. This stems from using the gfloat element of the horizontal slider to encode the time value for the left margin. The result is a loss of precision for very large values. Use the hotkeys or buttons at the top of the screen if this is a problem. .TP When running under Cygwin, it is required to enable Cygserver if shared memory IPC is being used. Specifically, this occurs when \fIrtlbrowse\fP(1) is launched as a helper process. See the Cygwin documentation for more information on how to enable Cygserver. .SH "AUTHORS" .LP Anthony Bybell .SH "SEE ALSO" .LP \fIgtkwaverc\fP(5) \fIlxt2vcd\fP(1) \fIvcd2lxt\fP(1) \fIvcd2lxt2\fP(1) \fIvzt2vcd\fP(1) \fIvcd2vzt\fP(1) \fIvermin\fP(1) \fIrtlbrowse\fP(1) \fItwinwave\fP(1) \fIshmidcat\fP(1) gtkwave-3.3.66/man/rtlbrowse.10000664000076400007640000000330712245773613015474 0ustar bybellbybell.TH "RTLBROWSE" "1" "3.3.28" "Anthony Bybell" "File Viewing" .SH "NAME" .LP rtlbrowse \- Allows hierarchical browsing of Verilog HDL source code and library design files. .SH "SYNTAX" .LP rtlbrowse <\fIstemsfilename\fP> .SH "DESCRIPTION" .LP Allows hierarchical browsing of Verilog HDL source code and library design files. Navigation through the hierarchy may be done by clicking open areas of the tree widget and clicking on the individual levels of hierarchy. Inside the source code, selecting the module instantiation name by double clicking or selecting part of the name through drag-clicking will descend deeper into the RTL hierarchy. Note that it performs optional source code annotation when called as a helper application by \fIgtkwave\fP(1) and when the primary marker is set. Source code annotation is not available for all supported dumpfile types. It is directly available for LXT2, VZT, FST, and AET2. For VCD, use the \fB\-o\fR,\fB\-\-optimize\fR option of \fIgtkwave\fP(1) in order to optimize the VCD file into FST. All other dumpfile types (LXT, GHW) are unsupported at this time. .SH "EXAMPLES" .LP To run this program the standard way type: .TP rtlbrowse stemsfile The RTL is then brought up in a GTK tree viewer. Stems must have been previously generated with \fIvermin\fP(1) or some other tool capable of generating compatible stemsfiles. Note that \fIgtkwave\fP(1) will bring up this program as a client application for source code annotation. It does that by bringing up the viewer with the shared memory ID of a segment of memory in the viewer rather than using a stems filename. .SH "AUTHORS" .LP Anthony Bybell .SH "SEE ALSO" .LP \fIvermin\fP(1) \fIgtkwave\fP(1) gtkwave-3.3.66/man/vcd2lxt2.10000664000076400007640000000374211733422265015117 0ustar bybellbybell.TH "VCD2LXT2" "1" "1.3.42" "Anthony Bybell" "Filetype Conversion" .SH "NAME" .LP vcd2lxt2 \- Converts VCD files to LXT2 files .SH "SYNTAX" .LP vcd2lxt2 [\fIoption\fP]... [\fIVCDFILE\fP] [\fILXTFILE\fP] .SH "DESCRIPTION" .LP Converts VCD files to LXT2 files. .SH "OPTIONS" .LP .TP \fB\-v,\-\-vcdname\fR <\fIfilename\fP> Specify VCD input filename. .TP \fB\-l,\-\-lxtname\fR <\fIfilename\fP> Specify LXT2 output filename. .TP \fB\-d,\-\-depth\fR <\fIvalue\fP> Specify 0..9 gzip compression depth, default is 4. .TP \fB\-m,\-\-maxgranule\fR <\fIvalue\fP> Specify number of granules per section, default is 8. One granule is equal to 32 timsteps. .TP \fB\-b,\-\-break\fR <\fIvalue\fP> Specify break size (default = 0 = off). When the break size is exceeded, the LXT2 dumper will dump all state information at the next convenient granule plus dictionary boundary. .TP \fB\-p,\-\-partialmode\fR <\fImode\fP> Specify partial zip mode 0 = monolithic, 1 = separation. Using a value of 1 expands LXT2 filesize but provides fast access for very large traces. Note that the default mode is neither monolithic nor separation: partial zip is disabled. .TP \fB\-c,\-\-checkpoint\fR <\fImode\fP> Specify checkpoint mode. 0 is on which is default, and 1 is off. This is disabled when the break size is active. .TP \fB\-h,\-\-help\fR Show help screen. .TP .SH "EXAMPLES" .LP Note that you should specify dumpfile.vcd directly or use "\-" for stdin. .TP vcd2lxt dumpfile.vcd dumpfile.lxt \-\-depth 9 \-\-break 1073741824 This sets the compression level to 9 and sets the break size to 1GB. .TP vcd2lxt dumpfile.vcd dumpfile.lxt \-\-depth 9 \-\-maxgranule 256 Allows more granules per section which allows for greater compression. .SH "LIMITATIONS" \fIvcd2lxt2\fP does not store glitches as these are coalesced together into one value change during the writing of the LXT2 file. .LP .SH "AUTHORS" .LP Anthony Bybell .SH "SEE ALSO" .LP \fIlxt2vcd\fP(1) \fIvcd2lxt2\fP(1) \fIgtkwave\fP(1) gtkwave-3.3.66/man/gtkwaverc.50000664000076400007640000005246312232572565015460 0ustar bybellbybell.TH "GTKWAVERC" "5" "3.3.51" "Anthony Bybell" "GTKWave Configuration File" .SH "NAME" .LP gtkwaverc \- GTKWave Configuration File .SH "SYNTAX" .LP option <\fIvalue\fP> .TP The configuration file is a series of option and value pairs. Comment lines marked with an initial '#' character are permissible. Blank lines are ignored. .SH "DESCRIPTION" .LP Configuration file for \fIgtkwave\fP(1). The search path for the configuration file (if unspecified) is the current working directory followed by the user's home directory. .SH "OPTIONS" .LP .TP \fBaccel\fR <\fI"pathvalue" accelerator\fP> This allows replacement of menu accelerator keys. See the .gtkwaverc file in the source distribution for examples on pathvalue and accelerator syntax. The special accelerator value of \fI(null)\fP means that no accelerator is bound to the menu item. .TP \fBalt_hier_delimeter\fR <\fIvalue\fP> This allows another character in addition to the hier_delimeter to be used to delimit levels in the hierarchy for VCD. Only the first character in the value is significant. Note that this is normally off. The intended use is to resolve the hierarchies of netlist based models that often contain slashes to delimit hierarchy inside of $var statements. .TP \fBalt_wheel_mode\fR <\fIvalue\fP> Default is on. Scrollwheel alone pans along a quarter at a time rather than a full page, so you don't get lost. Ctrl+wheel zooms in/out around the mouse cursor position, not the marker position. Alt+wheel edges left/right based on the currently selected signal. This makes measuring deltas easier. .TP \fBanalog_redraw_skip_count\fR <\fIvalue\fP> Specifies how many overlapping analog segments can be drawn for a given X position onscreen. (Default: 20) If there are gaps in analog traces, this value is too low. .TP \fBappend_vcd_hier\fR <\fIvalue\fP> Allows the specification of a prefix hierarchy for VCD files. This can be done in "pieces," so that multiple layers of hierarchy are prepended to symbol names with the most significant addition occurring first (see .gtkwaverc in the examples/vcd directory). The intended use of this is to have the ability to add "project" prefixes which allow easier selection of everything from the tree hierarchy. .TP \fBatomic_vectors\fR <\fIvalue\fP> Speeds up vcd loading and takes up less memory. This option is deprecated; it is currently the default. .TP \fBautocoalesce\fR <\fIvalue\fP> A nonzero value enables autocoalescing of VCD vectors when applicable. This may be toggled dynamically during wave viewer usage. .TP \fBautocoalesce_reversal\fR <\fIvalue\fP> causes split vectors to be reconstructed in reverse order (only if autocoalesce is also active). .TP \fBautoname_bundles\fR <\fIvalue\fP> A nonzero value indicates that GTKWave will create its own bundle names rather than prompting the user for them. .TP \fBcolor_0\fR <\fIvalue\fP> trace color when 0. .TP \fBcolor_1\fR <\fIvalue\fP> trace color when 1. .TP \fBcolor_back\fR <\fIvalue\fP> background color. .TP \fBcolor_baseline\fR <\fIvalue\fP> middle mouse button marker color. .TP \fBcolor_black\fR <\fIvalue\fP> color value for "black" in signal window. .TP \fBcolor_brkred\fE <\fIvalue\fP> brick red color for comments. .TP \fBcolor_dash\fR <\fIvalue\fP> trace color when don't care ("-"). .TP \fBcolor_dashfill\fR <\fIvalue\fP> trace color (inside of box) when don't care ("-"). .TP \fBcolor_dkblue\fR <\fIvalue\fP> color value for "dark blue" in signal window. .TP \fBcolor_dkgray\fR <\fIvalue\fP> color value for "dark gray" in signal window. .TP \fBcolor_gmstrd\fR <\fIvalue\fP> color value for trace groupings. .TP \fBcolor_grid\fR <\fIvalue\fP> grid color (use Alt-G/Shift-Alt-G to show/hide grid). This is also the color used for \fBhighlight_wavewindow\fR when enabled. .TP \fBcolor_grid2\fR <\fIvalue\fP> grid color for secondary pattern search. .TP \fBcolor_high\fR <\fIvalue\fP> trace color when high ("H"). .TP \fBcolor_low\fR <\fIvalue\fP> trace color when low ("L"). .TP \fBcolor_ltblue\fR <\fIvalue\fP> color for shadowed traces. .TP \fBcolor_ltgray\fR <\fIvalue\fP> color value for "light gray" in signal window. .TP \fBcolor_mark\fR <\fIvalue\fP> color of the named markers. .TP \fBcolor_mdgray\fR <\fIvalue\fP> color value for "medium gray" in signal window. .TP \fBcolor_mid\fR <\fIvalue\fP> trace color when floating ("Z"). .TP \fBcolor_normal\fR <\fIvalue\fP> color value for "normal" GTK state in signal window. .TP \fBcolor_time\fR <\fIvalue\fP> text color for timebar. .TP \fBcolor_timeb\fR <\fIvalue\fP> text color for timebar's background. .TP \fBcolor_trans\fR <\fIvalue\fP> trace color when transitioning. .TP \fBcolor_u\fR <\fIvalue\fP> trace color when undefined ("U"). .TP \fBcolor_ufill\fR <\fIvalue\fP> trace color (inside of box) when undefined ("U"). .TP \fBcolor_umark\fR <\fIvalue\fP> color of the unnamed (primary) marker. .TP \fBcolor_value\fR <\fIvalue\fP> text color for vector values. .TP \fBcolor_vbox\fR <\fIvalue\fP> vector color (horizontal). .TP \fBcolor_vtrans\fR <\fIvalue\fP> vector color (verticals/transitions). .TP \fBcolor_w\fR <\fIvalue\fP> trace color when weak ("W"). .TP \fBcolor_wfill\fR <\fIvalue\fP> trace color (inside of box) when weak ("W"). .TP \fBcolor_white\fR <\fIvalue\fP> color value for "white" in signal window. .TP \fBcolor_x\fR <\fIvalue\fP> trace color when undefined ("X") (collision for VHDL). .TP \fBcolor_xfill\fR <\fIvalue\fP> trace color (inside of box) when undefined ("X") (collision for VHDL). .TP \fBconstant_marker_update\fR <\fIvalue\fP> A nonzero value indicates that the values for traces listed in the signal window are to be updated constantly when the left mouse button is being held down rather than only when it is first pressed then when released (which is the default). .TP \fBcontext_tabposition\fR <\fIvalue\fP> Use zero for tabbed viewing with named tabs at the top. Nonzero places numerically indexed tabs at the left. .TP \fBconvert_to_reals\fR <\fIvalue\fP> Converts all integer and parameter VCD declarations to real-valued ones when set to a nonzero/yes value. The positive aspect of this is that integers and parameters will take up less space in memory and will automatically display in decimal format. The negative aspect of this is that integers and parameters will only be displayable as decimals and can't be bit reversed, inverted, etc. .TP \fBcursor_snap\fR <\fIvalue\fP> A nonzero value indicates the number of pixels the marker should snap to for the nearest signal transition. .TP \fBdisable_ae2_alias\fR <\fIvalue\fP> A nonzero value indicates that the AE2 loader is to ignore the aliasdb keyword and is not to construct facility aliases. .TP \fBdisable_empty_gui\fR <\fIvalue\fP> A nonzero value indicates that if gtkwave is invoked without a dumpfile name, then an empty gtkwave session is to be suppressed. Default is a zero value: to bring up an empty session which needs a file loaded or dragged into it. .TP \fBdisable_mouseover\fR <\fIvalue\fP> A nonzero value indicates that signal/value tooltip pop up bubbles on mouse button presses should be disabled in the value window. A zero value indicates that value tooltips should be active (default is disabled). .TP \fBdisable_tooltips\fR <\fIvalue\fP> A nonzero value indicates that tooltip pop up bubbles should be disabled. A zero value indicates that tooltips should be active (default). .TP \fBdo_initial_zoom_fit\fR <\fIvalue\fP> A nonzero value indicates that the trace should initially be crunched to fit the screen. A zero value indicates that the initial zoom should be zero (default). .TP \fBdynamic_resizing\fR <\fIvalue\fP> A nonzero value indicates that dynamic resizing should be initially enabled (default). A zero value indicates that dynamic resizing should be initially disabled. .TP \fBeditor\fR <\fI"value"\fP> This is used to specify a string (quotes mandatory) for when gtkwave invokes a text editor (e.g., Open Source Definition). Examples are: editor "vimx -g +%d %s", editor "gedit +%d %s", editor "emacs +%d %s", and for OSX, editor "mate -l %d %s". The %d may be combined with other characters in a string such as +, etc. The %s argument must stand by itself. Note that if this rc variable is not set, then the environment variable GTKWAVE_EDITOR will be consulted next, then finally gedit will be used (if found). .TP \fBenable_fast_exit\fR <\fIvalue\fP> Allows exit without bringing up a confirmation requester. The default is nonzero/yes. .TP \fBenable_ghost_marker\fR <\fIvalue\fP> lets the user turn on/off the ghost marker during primary marker dragging. Default is enabled. .TP \fBenable_horiz_grid\fR <\fIvalue\fP> A nonzero value indicates that when grid drawing is enabled, horizontal lines are to be drawn. This is the default. .TP \fBenable_vcd_autosave\fR <\fIvalue\fP> causes the vcd loader to automatically generate a .sav file (vcd_autosave.sav ) in the cwd if a save file is not specified on the command line. Note that this mirrors the VCD $var defs and no attempt is made to coalesce split bitvectors back together. .TP \fBenable_vert_grid\fR <\fIvalue\fP> A nonzero value indicates that when grid drawing is enabled, vertical lines are to be drawn. This is the default. Note that all possible combinations of enable_horiz_grid and enable_vert_grid values are acceptable. .TP \fBfontname_logfile\fR <\fIvalue\fP> When followed by an argument, this indicates the name of the X11 font that you wish to use for the logfile browser. You may generate appropriate fontnames using the xfontsel program. .TP \fBfontname_signals\fR <\fIvalue\fP> When followed by an argument, this indicates the name of the X11 font that you wish to use for signals. You may generate appropriate fontnames using the xfontsel program. .TP \fBfontname_waves\fR <\fIvalue\fP> When followed by an argument, this indicates the name of the X11 font that you wish to use for waves. You may generate appropriate fontnames using the xfontsel program. Note that the signal font must be taller than the wave font or the viewer will complain then terminate. .TP \fBforce_toolbars\fR <\fIvalue\fP> When enabled, this forces everything above the signal and wave windows to be rendered as toolbars. This allows for them to be detached which allows for more usable wave viewer space. By default this is off. .TP \fBhide_sst\fR <\fIvalue\fP> Hides the Signal Search Tree widget for GTK2.4 and greater such that it is not embedded into the main viewer window. It is still reachable as an external widget through the menus. .TP \fBhier_delimeter\fR <\fIvalue\fP> This allows characters other than '/' to be used to delimit levels in the hierarchy. Only the first character in the value is significant. .TP \fBhier_grouping\fR <\fIvalue\fP> For the tree widgets, this allows the hierarchies to be grouped in a single place rather than spread among the netnames. .TP \fBhier_max_level\fR <\fIvalue\fP> Sets the maximum hierarchy depth (from the right side) to display for trace names. Note that a value of zero displays the full hierarchy name. .TP \fBhighlight_wavewindow\fR <\fIvalue\fP> When enabled, this causes traces highlighted in the signal window also to be highlighted in the wave window. .TP \fBhpane_pack\fR <\fIvalue\fP> A nonzero value indicates that the horizontal pane should be constructed using the gtk_paned_pack functions (default and recommended). A zero value indicates that gtk_paned_add will be used instead. .TP \fBignore_savefile_pane_pos\fR <\fIvalue\fP> If nonzero, specifies that the pane position attributes (i.e., signal window width size, SST is expanded, etc.) are to be ignored during savefile loading and is to be skipped during saving. Default is that the attribute is used. .TP \fBignore_savefile_pos\fR <\fIvalue\fP> If nonzero, specifies that the window position attribute is to be ignored during savefile loading and is to be skipped during saving. Default is that the position attribute is used. .TP \fBignore_savefile_size\fR <\fIvalue\fP> If nonzero, specifies that the window size attribute is to be ignored during savefile loading and is to be skipped during saving. Default is that the size attribute is used. .TP \fBinitial_signal_window_width\fR <\fIvalue\fP> Sets the creation width for the signal pane on GUI initialization. Also sets another potential minimum value for dynamic resizing. .TP \fBinitial_window_x\fR <\fIvalue\fP> Sets the size of the initial width of the wave viewer window. Values less than or equal to zero will set the initial width equal to \-1 which will let GTK determine the minimum size. .TP \fBinitial_window_xpos\fR <\fIvalue\fP> Sets the size of the initial x coordinate of the wave viewer window. \-1 will let the window manager determine the position. .TP \fBinitial_window_y\fR <\fIvalue\fP> Sets the size of the initial height of the wave viewer window. Values less than or equal to zero will set the initial width equal to \-1 which will let GTK determine the minimum size. .TP \fBinitial_window_ypos\fR <\fIvalue\fP> Sets the size of the initial y coordinate of the wave viewer window. \-1 will let the window manager determine the position. .TP \fBkeep_xz_colors\fR <\fIvalue\fP> When nonzero, indicates that the original color scheme for non 0/1 signal values is to be used when Color Format overrides are in effect. Default is off. .TP \fBleft_justify_sigs\fR <\fIvalue\fP> When nonzero, indicates that the signal window signal name justification should default to left, else the justification is to the right (default). .TP \fBlxt_clock_compress_to_z\fR <\fIvalue\fP> For LXT (not LXT2) allows clocks to compress to a 'z' value so that regular/periodic value changes may be noted. .TP \fBpage_divisor\fR <\fIvalue\fP> Sets the scroll amount for page left and right operations. (The buttons, not the hscrollbar.) Values over 1.0 are taken as 1/x and values equal to and less than 1.0 are taken literally. (i.e., 2 gives a half-page scroll and .67 gives 2/3). The default is 1.0. .TP \fBps_maxveclen\fR <\fIvalue\fP> sets the maximum number of characters that can be printed for a value in the signal window portion of a postscript file (not including the net name itself). Legal values are 4 through 66 (default). .TP \fBruler_origin\fR <\fIvalue\fP> sets the zero origin for alternate time tick marks. .TP \fBruler_step\fR <\fIvalue\fP> sets the left/right step value for the alternate time tick marks from the origin. When this value is zero, alternate time tick marks are disabled. .TP \fBscale_to_time_dimension\fR <\fIvalue\fP> The value can be any of the characters m, u, n, f, p, or s, which indicates which time dimension to convert the time values to. The default for this is * which means that time dimension conversion is disabled. .TP \fBshow_base_symbols\fR <\fIvalue\fP> A nonzero value (default) indicates that the numeric base symbols for hexadecimal ('$'), binary ('%'), and octal ('#') should be rendered. Otherwise they will be omitted. .TP \fBshow_grid\fR <\fIvalue\fP> A nonzero value (default) indicates that a grid should be drawn behind the traces. A zero indicates that no grid should be drawn. .TP \fBsplash_disable\fR <\fIvalue\fP> Turning this off enables the splash screen with the GTKWave mascot when loading a trace. Default is on. .TP \fBsst_dynamic_filter\fR <\fIvalue\fP> When true (default) allows the SST dialog signal filter to filter signals while keys are being pressed, otherwise enter must be pressed to cause the filter to go active. .TP \fBsst_expanded\fR <\fIvalue\fP> When true allows the SST dialog (when not hidden) to come up already expanded. .TP \fBstrace_repeat_count\fR <\fIvalue\fP> Determines how many times that edge search and pattern search will iterate on a search. This allows, for example, skipping ahead 10 clock edges instead of 1. .TP \fBuse_big_fonts\fR <\fIvalue\fP> A nonzero value indicates that any text rendered into the wave window will use fonts that are four points larger in size than normal. This can enhance readability. A zero value indicates that normal font sizes should be used. .TP \fBuse_frequency_delta\fR <\fIvalue\fP> allows you to switch between the delta time and frequency display in the upper right corner of the main window when measuring distances between markers. Default behavior is that the delta time is displayed (off). .TP \fBuse_full_precision\fR <\fIvalue\fP> does not round time values when the number of ticks per pixel onscreen is greater than 10 when active. The default is that this feature is disabled. .TP \fBuse_maxtime_display\fR <\fIvalue\fP> A nonzero value indicates that the maximum time will be displayed in the upper right corner of the screen. Otherwise, the current primary (unnamed) marker time will be displayed. This can be toggled at any time with the Toggle Max-Marker menu option. .TP \fBuse_nonprop_fonts\fR <\fIvalue\fP> Allows accelerated redraws of the signalwindow that can be done because the font width is constant. Default is off. .TP \fBuse_pango_fonts\fR <\fIvalue\fP> Uses anti-aliased pango fonts (GTK2) rather than bitmapped X11 ones. Default is on. .TP \fBuse_roundcaps\fR <\fIvalue\fP> A nonzero value indicates that vector traces should be drawn with rounded caps rather than perpendicular ones. The default for this is zero. .TP \fBuse_scrollbar_only\fR <\fIvalue\fP> A nonzero value indicates that the page, shift, fetch, and discard buttons should not be drawn (i.e., time manipulations should be through the scrollbar only rather than front panel buttons). The default for this is zero. .TP \fBuse_scrollwheel_as_y\fR <\fIvalue\fP> A nonzero value indicates that the scroll wheel on the mouse should be used to scroll the signals up and down rather than scrolling the time value from left to right. .TP \fBuse_standard_clicking\fR <\fIvalue\fP> This option no longer has any effect in gtkwave: normal GTK click semantics are used in the signalwindow. .TP \fBuse_standard_trace_select\fR <\fIvalue\fP> A nonzero value keeps the currently selected traces from deselecting on mouse button press. This allows drag and drop to function more smoothly. As this behavior is not how GTK normally functions, it is by default disabled. .TP \fBuse_toolbutton_interface\fR <\fIvalue\fP> A nonzero value indicates that a toolbar with buttons should be at the top of the screen instead of the traditional style gtkwave button groups. Default is on. .TP \fBvcd_explicit_zero_subscripts\fR <\fIvalue\fP> indicates that signal names should be stored internally as name.bitnumber when enabled. When disabled, a more "normal" ordering of name[bitnumber] is used. Note that when disabled, the Bundle Up and Bundle Down options are disabled in the Signal Search Regexp, Signal Search Hierarchy, and Signal Search Tree options. This is necessary as the internal data structures for signals are represented with one "less" level of hierarchy than when enabled and those functions would not work properly. This should not be an issue if atomic_vectors are enabled. Default for vcd_explicit_zero_subscripts is disabled. .TP \fBvcd_preserve_glitches\fR <\fIvalue\fP> indicates that any repeat equal values for a net spanning different time values in the VCD/FST file are not to be compressed into a single value change but should remain in order to allow glitches to be present for this case. Default for vcd_preserve_glitches is disabled. .TP \fBvcd_preserve_glitches_real\fR <\fIvalue\fP> indicates that any repeat equal values for a real net spanning different time values in the VCD/FST file are not to be compressed into a single value change but should remain for this case. Default for vcd_preserve_glitches is disabled. The intended use is for when viewing analog interpolated data such that removing duplicate values would incorrectly deform the interpolation. .TP \fBvcd_warning_filesize\fR <\fIvalue\fP> produces a warning message if the VCD filesize is greater than the argument's size in MB. Set to zero to disable this. .TP \fBvector_padding\fR <\fIvalue\fP> indicates the number of pixels of extra whitespace that should be added to any strings for the purpose of calculating text in vectors. Permissible values are 0 to 16 with the default being 4. .TP \fBvlist_compression\fR <\fIvalue\fP> indicates the value to pass to zlib during vlist processing (which is used in the VCD recoder). \-1 disables compression, 0-9 correspond to the value zlib expects. 4 is default. .TP \fBvlist_prepack\fR <\fIvalue\fP> indicates that the VCD recoder should pre-compress data going into the value change vlists in order to reduce memory usage. This is done before potential zlib packing. Default is off. .TP \fBvlist_spill\fR <\fIvalue\fP> indicates that the VCD recoder should spill all generated vlists to a tempfile on disk in order to reduce memory usage. Default is off. .TP \fBwave_scrolling\fR <\fIvalue\fP> a nonzero value enables scrolling by dragging the marker off the left or right sides of the wave window. A zero value disables it. .TP \fBzoom_base\fR <\fIvalue\fP> allows setting of the zoom base with a value between 1.5 and 10.0. Default is 2.0. .TP \fBzoom_center\fR <\fIvalue\fP> a nonzero value enables center zooming, a zero value disables it. .TP \fBzoom_dynamic\fR <\fIvalue\fP> a nonzero value enables dynamic full zooming when using the partial VCD (incremental) loader, a zero value disables it. .TP \fBzoom_dynamic_end\fR <\fIvalue\fP> a nonzero value enables dynamic zoom to the end when using the partial VCD (incremental) loader, a zero value disables it. .TP \fBzoom_pow10_snap\fR <\fIvalue\fP> corresponds to the Zoom Pow10 Snap menu option. Default for this is disabled (zero). .SH "AUTHORS" .LP Anthony Bybell .SH "SEE ALSO" .LP \fIgtkwave\fP(1) gtkwave-3.3.66/man/fst2vcd.10000664000076400007640000000174612236025750015021 0ustar bybellbybell.TH "FST2VCD" "1" "3.3.52" "Anthony Bybell" "Filetype Conversion" .SH "NAME" .LP fst2vcd \- Converts FST files to VCD .SH "SYNTAX" .LP fst2vcd [\fIoption\fP]... [\fIFSTFILE\fP] .SH "DESCRIPTION" .LP Converts FST files to VCD files. If an output filename is not specified, the VCD is emitted to stdout. .SH "OPTIONS" .LP .TP \fB\-f,\-\-fstname\fR <\fIfilename\fP> Specify FST input filename. .TP \fB\-o,\-\-output\fR <\fIfilename\fP> Specify optional VCD output filename. .TP \fB\-e,\-\-extensions\Fr Emit FST extensions to VCD. Enabling this may create VCD files unreadable by other tools. This is generally intended to be used as a debugging tool when developing FST writer interfaces to simulators. .TP \fB\-h,\-\-help\fR Display help then exit. .SH "EXAMPLES" .LP To run this program the standard way type: .TP fst2vcd filename.fst The VCD conversion is emitted to stdout. .SH "AUTHORS" .LP Anthony Bybell .SH "SEE ALSO" .LP \fIvcd2fst\fP(1) \fIgtkwave\fP(1) gtkwave-3.3.66/man/vzt2vcd.10000664000076400007640000000246612001322733015037 0ustar bybellbybell.TH "VZT2VCD" "1" "3.3.39" "Anthony Bybell" "Filetype Conversion" .SH "NAME" .LP vzt2vcd \- Converts VZT files to VCD .SH "SYNTAX" .LP vzt2vcd [\fIoption\fP]... [\fIVZTFILE\fP] .SH "DESCRIPTION" .LP Converts VZT files to VCD files. If an output filename is not specified, the VCD is emitted to stdout. .SH "OPTIONS" .LP .TP \fB\-v,\-\-vztname\fR <\fIfilename\fP> Specify VZT input filename. .TP \fB\-o,\-\-output\fR <\fIfilename\fP> Specify optional VCD output filename. .TP \fB\-f,\-\-flatearth\fR Emit flattened hierarchies. .TP \fB\-c,\-\-coalesce\fR Coalesce bitblasted vectors. .TP \fB\-n,\-\-notruncate\fR Do not shorten bitvectors. This disables binary value compression as described in the IEEE-1364 specification. (i.e., all values except for '1' left propagate as a sign bit on vectors which do not fill up their entire declared width) .TP \fB\-h,\-\-help\fR Display help then exit. .SH "EXAMPLES" .LP To run this program the standard way type: .TP vzt2vcd filename.vzt The VCD conversion is emitted to stdout. .SH "LIMITATIONS" \fIvzt2vcd\fP does not re-create glitches as these are coalesced together into one value change during the writing of the VZT file. .LP .SH "AUTHORS" .LP Anthony Bybell .SH "SEE ALSO" .LP \fIvcd2lxt2\fP(1) \fIvcd2lxt\fP(1) \fIlxt2vcd\fP(1) \fIgtkwave\fP(1) gtkwave-3.3.66/man/twinwave.10000664000076400007640000000275412010360431015276 0ustar bybellbybell.TH "TWINWAVE" "1" "3.3.39" "Anthony Bybell" "Simulation Wave Viewer Multiplexer" .SH "NAME" .LP twinwave \- Wraps multiple GTKWave sessions in one window or two synchronized windows .SH "SYNTAX" .LP twinwave <\fIarglist1\fP> <\fIseparator\fP> <\fIarglist2\fP> .SH "DESCRIPTION" .LP Wraps multiple GTKWave sessions with synchronized markers, horizontal scrolling, and zooming. .SH "EXAMPLES" .LP To run this program the standard way type: .TP twinwave filename1.vcd filename1.sav + filename2.vcd filename2.sav Two synchronized viewers are then opened in one window. .TP twinwave filename1.vcd filename1.sav ++ filename2.vcd filename2.sav Two synchronized viewers are then opened in two windows. .SH "LIMITATIONS" \fItwinwave\fP uses the GtkSocket/GtkPlug mechanism to embed two \fIgtkwave\fP(1) sessions into one window. The amount of coupling is currently limited to communication of temporal information. Other than that, the two gtkwave processes are isolated from each other as if the viewers were spawned separately. Keep in mind that using the same save file for each session may cause unintended behavior problems if the save file is written back to disk: only the session written last will be saved. (i.e., the save file isn't cloned and made unique to each session.) Note that \fItwinwave\fP compiled against Quartz (not X11) on OSX as well as MinGW does not place both sessions in a single window. .LP .SH "AUTHORS" .LP Anthony Bybell .SH "SEE ALSO" .LP \fIgtkwave\fP(1) gtkwave-3.3.66/man/vcd2fst.10000664000076400007640000000330312242757437015023 0ustar bybellbybell.TH "VCD2FST" "1" "3.3.53" "Anthony Bybell" "Filetype Conversion" .SH "NAME" .LP vcd2fst \- Converts VCD files to FST files .SH "SYNTAX" .LP vcd2fst [\fIoption\fP]... [\fIVCDFILE\fP] [\fIFSTFILE\fP] .SH "DESCRIPTION" .LP Converts VCD files to FST files. .SH "OPTIONS" .LP .TP \fB\-v,\-\-vcdname\fR <\fIfilename\fP> Specify VCD/FSDB/VPD/WLF input filename. Processing of filetypes other than VCD requires that the appropriate 2vcd converter was found during ./configure. .TP \fB\-f,\-\-fstname\fR <\fIfilename\fP> Specify FST output filename. .TP \fB\-4,\-\-fourpack\fR Indicates that LZ4 should be used for value change data (default). .TP \fB\-F,\-\-fastpack\fR Indicates that fastlz should be used instead of LZ4 for value change data. .TP \fB\-4,\-\-zlibpack\fR Indicates that zlib should be used instead of LZ4 for value change data. .TP \fB\-c,\-\-compress\fR Indicates that the entire file should be run through gzip on close. This results in much smaller files at the expense of a one-time decompression penalty on file open during reads. .TP \fB\-p,\-\-parallel\fR Indicates that parallel mode should be enabled. This spawns a worker thread to continue with FST block processing while conversion continues on the main thread for new FST block data. .TP \fB\-h,\-\-help\fR Show help screen. .TP .SH "EXAMPLES" .LP Note that you should specify dumpfile.vcd directly or use "\-" for stdin. .TP vcd2fst dumpfile.vcd dumpfile.fst \-\-compress This indicates that the FST file should be post-compressed on close. .SH "AUTHORS" .LP Anthony Bybell .SH "SEE ALSO" .LP \fIfst2vcd\fP(1) \fIvcd2lxt\fP(1) \fIvcd2lxt2\fP(1) \fIlxt2vcd\fP(1) \fIvcd2vzt\fP(1) \fIvzt2vcd\fP(1) \fIgtkwave\fP(1) gtkwave-3.3.66/man/lxt2vcd.10000664000076400007640000000310012001322733015005 0ustar bybellbybell.TH "LXT2VCD" "1" "3.3.39" "Anthony Bybell" "Filetype Conversion" .SH "NAME" .LP lxt2vcd \- Converts LXT2 files to VCD .SH "SYNTAX" .LP lxt2vcd [\fIoption\fP]... [\fILXT2FILE\fP] .SH "DESCRIPTION" .LP Converts LXT2 files to VCD files on stdout. If an output filename is not specified, the VCD is emitted to stdout. Note that "regular" LXT2 files will convert to VCD files with monotonically increasing time values. LXT2 files which are dumped with the "partial" option (to speed up access in wave viewers) will dump with monotonically increasing time values per 2k block of nets. This may be fixed in later versions of \fIlxt2vcd\fP. .SH "OPTIONS" .LP .TP \fB\-l,\-\-lxtname\fR <\fIfilename\fP> Specify LXT2 input filename. .TP \fB\-o,\-\-output\fR <\fIfilename\fP> Specify optional VCD output filename. .TP \fB\-f,\-\-flatearth\fR Emit flattened hierarchies. .TP .TP \fB\-n,\-\-notruncate\fR Do not shorten bitvectors. This disables binary value compression as described in the IEEE-1364 specification. (i.e., all values except for '1' left propagate as a sign bit on vectors which do not fill up their entire declared width) .TP \fB\-h,\-\-help\fR Display help then exit. .SH "EXAMPLES" .LP To run this program the standard way type: .TP lxt2vcd filename.lxt The VCD conversion is emitted to stdout. .SH "LIMITATIONS" \fIlxt2vcd\fP does not re-create glitches as these are coalesced together into one value change during the writing of the LXT2 file. .LP .SH "AUTHORS" .LP Anthony Bybell .SH "SEE ALSO" .LP \fIvcd2lxt2\fP(1) \fIvcd2lxt\fP(1) \fIgtkwave\fP(1) gtkwave-3.3.66/man/vermin.10000664000076400007640000000367311733422265014752 0ustar bybellbybell.TH "VERMIN" "1" "0.1.1" "Anthony Bybell" "Verilog Compilation" .SH "NAME" .LP vermin \- Parses and processes Verilog HDL files .SH "SYNTAX" .LP vermin [\fIVERILOGFILE\fP]... [\fIoption\fP]... .SH "DESCRIPTION" .LP Parses Verilog HDL files for use by other tools. The Verilog grammar used is 1364-1995. .SH "OPTIONS" .LP .TP \fB\-h[elp]\fR Prints out help screen. .TP \fB\-emitmono \fIfname\fP\fR Emit monolithic (parser view of) file to \fIfname\fP. .TP \fB\-emitstems\fR Emit source code stems to stdout. .TP \fB\-emitvars\fR Emit source code variables to stdout. .TP \fB\-D\fIx\fP=\fIy\fP Equivalent to `define \fIX Y\fP in source. .TP \fB\+define+\fIx\fP=\fIy\fP\fR Equivalent to `define \fIX Y\fP in source. .TP \fB\+incdir+\fIdirname\fP\fR Add \fIdirname\fP to include search path. .TP \fB\+libext+\fIext\fP\fR Add \fIext\fP to filename when searching for files. .TP \fB\-pragma \fIname\fP\fR Add \fIname\fP (synopsys, verilint, vertex) to accepted pragmas. Note that "vertex" is for legacy reasons; the executable name has since changed to avoid name clashes with an existing 3D modeling program. .TP \fB\-y \fIdirname\fP\fR Add directory \fIdirname\fP to source input path. .TP \fB\-yi \fIdirname\fP\fR Add directory \fIdirname\fP to source input path (case insensitive search). .TP \fB\-f \fIfilename\fP\fR Insert args from filename. Does not work recursively. .SH "EXAMPLES" .LP The following indicates that the library extension is .v and that the include directory is the current working directory and that the library directory is also the current working directory. Stems generation is enabled to generate a stems file for use with other tools. Various compile-time defines are also defined on the command line. .TP vermin XYZ450AC6V1.v \-emitstems \-y . \+incdir+. \+libext+.v \-DUTLB_OutputData=0 \-D__PORTALS_VERILOG__ .SH "AUTHORS" .LP Anthony Bybell .SH "SEE ALSO" .LP \fIrtlbrowse\fP(1) \fIgtkwave\fP(1) gtkwave-3.3.66/man/Makefile.am0000664000076400007640000000036011774746555015432 0ustar bybellbybell## -*- makefile -*- ## dist_man_MANS= evcd2vcd.1 fst2vcd.1 ghwdump.1 gtkwave.1 gtkwaverc.5 lxt2miner.1 \ lxt2vcd.1 rtlbrowse.1 shmidcat.1 \ twinwave.1 vcd2fst.1 vcd2lxt.1 vcd2lxt2.1 \ vcd2vzt.1 vermin.1 vzt2vcd.1 vztminer.1 fstminer.1 gtkwave-3.3.66/man/lxt2miner.10000664000076400007640000000327011733422265015367 0ustar bybellbybell.TH "LXT2MINER" "1" "3.2.1" "Anthony Bybell" "Dumpfile Data Mining" .SH "NAME" .LP lxt2miner \- Data mining of LXT2 files .SH "SYNTAX" .LP lxt2miner [\fIoption\fP]... [\fILXT2FILE\fP] .SH "DESCRIPTION" .LP Mines LXT2 files for specific data values and generates gtkwave save files to stdout for future reload. .SH "OPTIONS" .LP .TP \fB\-d,\-\-dumpfile\fR <\fIfilename\fP> Specify LXT2 input dumpfile. .TP \fB\-m,\-\-match\fR <\fIvalue\fP> Specifies "bitwise" match data (binary, real, string) .TP \fB\-x,\-\-hex\fR <\fIvalue\fP> Specifies hexadecimal match data that will automatically be converted to binary for searches .TP \fB\-n,\-\-namesonly\fR Indicates that only facnames should be printed in a gtkwave savefile compatible format. By doing this, the file can be used to specify which traces are to be imported into gtkwave. .TP \fB\-c,\-\-comprehensive\fR Indicates that results are not to stop after the first match. This can be used to extract all the matching values in the trace. .TP \fB\-h,\-\-help\fR Show help screen. .SH "EXAMPLES" .LP lxt2miner dumpfile.lxt2 \-\-hex 20470000 \-n .TP This attempts to match the hex value 20470000 across all facilities and when the value is encountered, the facname only is printed to stdout in order to generate a gtkwave compatible save file. .SH "LIMITATIONS" \fIlxt2miner\fP only prints the first time a value is encountered for a specific net. This is done in order to cut down on the size of output files and to aid in following data such as addresses through a simulation model. .LP .SH "AUTHORS" .LP Anthony Bybell .SH "SEE ALSO" .LP \fIvztminer\fP(1) \fIvzt2vcd\fP(1) \fIlxt2vcd\fP(1) \fIvcd2lxt2\fP(1) \fIgtkwave\fP(1) gtkwave-3.3.66/man/shmidcat.10000664000076400007640000000235211733422265015237 0ustar bybellbybell.TH "SHMIDCAT" "1" "3.0.8" "Anthony Bybell" "Shared Memory Trampoline" .SH "NAME" .LP shmidcat \- Copies stdin/file to a shared memory block for \fIgtkwave\fP(1) .SH "SYNTAX" .LP shmidcat [\fIVCDFILE\fP] .SH "DESCRIPTION" .LP Copies either the file specified at the command line or stdin (if no file specified) line by line to a shared memory block. stdout will contain a shared memory ID which should be passed on to \fIgtkwave\fP(1). .SH "EXAMPLES" .LP To run this program the standard way type: .TP cat whatever.vcd | shmidcat The shared memory ID is emitted to stdout. .TP shmidcat whatever.vcd | gtkwave \-v \-I whatever.sav GTKWave directly grabs the ID from stdin. .SH "LIMITATIONS" This program is mainly for illustrative and testing purposes only. Its primary use is for people who wish to write interactive VCD dumpers for \fIgtkwave\fP(1) as its source code may be examined, particularly the emit_string() function. It can also be used to test if an existing VCD file will load properly in interactive mode. Note that it can also be used to redirect VCD files which are written into a pipe to \fIgtkwave\fP(1) in a non-blocking fashion. .LP .SH "AUTHORS" .LP Anthony Bybell .SH "SEE ALSO" .LP \fIgtkwave\fP(1) gtkwave-3.3.66/man/vcd2lxt.10000664000076400007640000000366611733422265015042 0ustar bybellbybell.TH "VCD2LXT" "1" "1.3.34" "Anthony Bybell" "Filetype Conversion" .SH "NAME" .LP vcd2lxt \- Converts VCD files to interlaced or linear LXT files .SH "SYNTAX" .LP vcd2lxt [\fIVCDFILE\fP] [\fILXTFILE\fP] [\fIoption\fP]... .SH "DESCRIPTION" .LP Converts VCD files to interlaced or linear LXT files. Noncompressed interlaced files will provide the fastest access, linear files will provide the slowest yet have the greatest compression ratios. .SH "OPTIONS" .LP .TP \fB\-stats\fR Prints out statistics on all nets in VCD file in addition to performing the conversion. .TP \fB\-clockpack\fR Apply two\-way subtraction algorithm in order to identify nets whose value changes by a constant XOR or whose value increases/decreases by a constant amount per constant unit of time. This option can reduce dumpfile size dramatically as value changes can be represented by an equation rather than explicitly as a triple of time, net, and value. .TP \fB\-chgpack\fR Emit data to file after being filtered through zlib (gzip). .TP \fB\-linear\fR Write out LXT in "linear" format with no backpointers. These are re\-generated during initialization in \fIgtkwave\fP. Additionally, use libbz2 (bzip2) as the compression filter. .TP \fB\-dictpack\fR <\fIsize\fP> Store value changes greater than or equal to \fIsize\fP bits as an index into a dictionary. Experimentation shows that a value of 18 is optimal for most cases. .SH "EXAMPLES" .LP Note that you should specify dumpfile.vcd directly or use "\-" for stdin. .TP vcd2lxt dumpfile.vcd dumpfile.lxt \-clockpack \-chgpack \-dictpack 18 This turns on clock packing, zlib compression, and enables the dictionary encoding. Note that using no options writes out a normal LXT file. .TP vcd2lxt dumpfile.vcd dumpfile.lxt \-clockpack \-linear \-dictpack 18 Uses linear mode for even smaller files. .SH "AUTHORS" .LP Anthony Bybell .SH "SEE ALSO" .LP \fIlxt2vcd\fP(1) \fIvcd2lxt2\fP(1) \fIgtkwave\fP(1) gtkwave-3.3.66/man/fstminer.10000664000076400007640000000326211774746555015313 0ustar bybellbybell.TH "FSTMINER" "1" "3.3.38" "Anthony Bybell" "Dumpfile Data Mining" .SH "NAME" .LP fst2miner \- Data mining of FST files .SH "SYNTAX" .LP fstminer [\fIoption\fP]... [\fIFSTFILE\fP] .SH "DESCRIPTION" .LP Mines FST files for specific data values and generates gtkwave save files to stdout for future reload. .SH "OPTIONS" .LP .TP \fB\-d,\-\-dumpfile\fR <\fIfilename\fP> Specify FST input dumpfile. .TP \fB\-m,\-\-match\fR <\fIvalue\fP> Specifies "bitwise" match data (binary, real, string) .TP \fB\-x,\-\-hex\fR <\fIvalue\fP> Specifies hexadecimal match data that will automatically be converted to binary for searches .TP \fB\-n,\-\-namesonly\fR Indicates that only facnames should be printed in a gtkwave savefile compatible format. By doing this, the file can be used to specify which traces are to be imported into gtkwave. .TP \fB\-c,\-\-comprehensive\fR Indicates that results are not to stop after the first match. This can be used to extract all the matching values in the trace. .TP \fB\-h,\-\-help\fR Show help screen. .SH "EXAMPLES" .LP fstminer dumpfile.fst \-\-hex 20470000 \-n .TP This attempts to match the hex value 20470000 across all facilities and when the value is encountered, the facname only is printed to stdout in order to generate a gtkwave compatible save file. .SH "LIMITATIONS" \fIfstminer\fP only prints the first time a value is encountered for a specific net. This is done in order to cut down on the size of output files and to aid in following data such as addresses through a simulation model. .LP .SH "AUTHORS" .LP Anthony Bybell .SH "SEE ALSO" .LP \fIvztminer\fP(1) \fIlxt2miner\fP(1) \fIfst2vcd\fP(1) \fIvcd2fst2\fP(1) \fIgtkwave\fP(1) gtkwave-3.3.66/man/vztminer.10000664000076400007640000000363611733422265015327 0ustar bybellbybell.TH "VZTMINER" "1" "3.2.1" "Anthony Bybell" "Dumpfile Data Mining" .SH "NAME" .LP vztminer \- Data mining of VZT files .SH "SYNTAX" .LP vztminer [\fIoption\fP]... [\fIVZTFILE\fP] .SH "DESCRIPTION" .LP Mines VZT files for specific data values and generates gtkwave save files to stdout for future reload. .SH "OPTIONS" .LP .TP \fB\-d,\-\-dumpfile\fR <\fIfilename\fP> Specify VZT input dumpfile. .TP \fB\-m,\-\-match\fR <\fIvalue\fP> Specifies "bitwise" match data (binary, real, string) .TP \fB\-x,\-\-hex\fR <\fIvalue\fP> Specifies hexadecimal match data that will automatically be converted to binary for searches .TP \fB\-n,\-\-namesonly\fR Indicates that only facnames should be printed in a gtkwave savefile compatible format. By doing this, the file can be used to specify which traces are to be imported into gtkwave. .TP \fB\-c,\-\-comprehensive\fR Indicates that results are not to stop after the first match. This can be used to extract all the matching values in the trace. .TP \fB\-h,\-\-help\fR Show help screen. .SH "EXAMPLES" .LP vztminer dumpfile.vzt \-\-hex 20470000 \-n .TP This attempts to match the hex value 20470000 across all facilities and when the value is encountered, the facname only is printed to stdout in order to generate a gtkwave compatible save file. .SH "LIMITATIONS" \fIvztminer\fP only prints the first time a value is encountered for a specific net. This is done in order to cut down on the size of output files and to aid in following data such as addresses through a simulation model. Note also that the reader algorithm attempts to reconstruct bitblasted nets back into their original vectors but this is not always successful, specifically in the case where the individual bitstrands are dumped in non-sequential order. .LP .SH "AUTHORS" .LP Anthony Bybell .SH "SEE ALSO" .LP \fIlxt2miner\fP(1) \fIvzt2vcd\fP(1) \fIlxt2vcd\fP(1) \fIvcd2lxt2\fP(1) \fIgtkwave\fP(1) gtkwave-3.3.66/man/evcd2vcd.10000664000076400007640000000146111733422265015143 0ustar bybellbybell.TH "EVCD2VCD" "1" "3.2.2" "Anthony Bybell" "Filetype Conversion" .SH "NAME" .LP evcd2vcd \- Converts EVCD files to VCD files .SH "SYNTAX" .LP evcd2vcd [\fIoption\fP]... [\fIEVCDFILE\fP] .SH "DESCRIPTION" .LP Converts EVCD files with bidirectional port definitions to VCD files with separate in and out ports. .SH "OPTIONS" .LP .TP \fB\-f,\-\-filename\fR <\fIfilename\fP> Specify EVCD input filename. .TP \fB\-h,\-\-help\fR Show help screen. .TP .SH "EXAMPLES" .LP Note that you should specify dumpfile.vcd directly or use "\-" for stdin. .TP evcd2vcd dumpfile.evcd VCD is emitted to stdout. .SH "AUTHORS" .LP Anthony Bybell .SH "SEE ALSO" .LP \fIvcd2fst\fP(1) \fIfst2vcd\fP(1) \fIvcd2lxt\fP(1) \fIvcd2lxt2\fP(1) \fIlxt2vcd\fP(1) \fIvcd2vzt\fP(1) \fIvzt2vcd\fP(1) \fIgtkwave\fP(1) gtkwave-3.3.66/man/vcd2vzt.10000664000076400007640000000463111733422265015047 0ustar bybellbybell.TH "VCD2VZT" "1" "3.1.21" "Anthony Bybell" "Filetype Conversion" .SH "NAME" .LP vcd2vzt \- Converts VCD files to VZT files .SH "SYNTAX" .LP vcd2vzt [\fIoption\fP]... [\fIVCDFILE\fP] [\fIVZTFILE\fP] .SH "DESCRIPTION" .LP Converts VCD files to VZT files. .SH "OPTIONS" .LP .TP \fB\-v,\-\-vcdname\fR <\fIfilename\fP> Specify VCD input filename. .TP \fB\-l,\-\-vztname\fR <\fIfilename\fP> Specify VZT output filename. .TP \fB\-d,\-\-depth\fR <\fIvalue\fP> Specify 0..9 gzip compression depth, default is 4. .TP \fB\-m,\-\-maxgranule\fR <\fIvalue\fP> Specify number of granules per section, default is 8. One granule is equal to 32 timesteps. .TP \fB\-b,\-\-break\fR <\fIvalue\fP> Specify break size (default = 0 = off). When the break size is exceeded, the VZT dumper will dump all state information at the next convenient granule plus dictionary boundary. .TP \fB\-z,\-\-ziptype\fR <\fIvalue\fP> Specify zip type (default = 0 gzip, 1 = bzip2, 2 = lzma). This allows you to override the default compression algorithm to use a more effective one at the expense of greater runtime. Note that bzip2 does not decompress as fast as gzip so the viewer will be about two times slower when decompressing blocks. .TP \fB\-t,\-\-twostate\fR Forces MVL2 twostate mode (default is MVL4). When enabled, the trace will only store 0/1 values for binary facilities. This is useful for functional simulation and will speed up dumping as well as make traces somewhat smaller. .TP \fB\-r, \-\-rle\fR Uses an bitwise RLE compression on the value table. Default is off. When enabled, this causes the trace data table to be stored using an alternate representation which can improve compression in many cases. .TP \fB\-h,\-\-help\fR Show help screen. .TP .SH "EXAMPLES" .LP Note that you should specify dumpfile.vcd directly or use "\-" for stdin. .TP vcd2vzt dumpfile.vcd dumpfile.lxt \-\-depth 9 \-\-break 1073741824 This sets the compression level to 9 and sets the break size to 1GB. .TP vcd2vzt dumpfile.vcd dumpfile.lxt \-\-depth 9 \-\-maxgranule 512 Allows more granules per section which allows for greater compression at the expense of memory usage. .SH "LIMITATIONS" \fIvcd2vzt\fP does not store glitches as these are coalesced together into one value change during the writing of the VZT file. .LP .SH "AUTHORS" .LP Anthony Bybell .SH "SEE ALSO" .LP \fIvzt2vcd\fP(1) \fIlxt2vcd\fP(1) \fIvcd2lxt2\fP(1) \fIgtkwave\fP(1) gtkwave-3.3.66/man/ghwdump.10000664000076400007640000000111311523063250015100 0ustar bybellbybell.TH "GHWDUMP" "1" "1.0" "Tristan Gingold" "GHW File Debugging Information" .SH "NAME" .LP ghwdump \- Dumps info contained in GHW files .SH "SYNTAX" .LP ghwdump [\fIoption\fP]... \fIGHWFILE\fP [[\fIGHWFILE\fP]...] .SH "DESCRIPTION" .LP Dumps information contained in GHW files for debugging purposes. .SH "OPTIONS" .LP .TP \fB\-t\fR Display types .TP \fB\-h\fR Display hierarchy .TP \fB\-T\fR Display time .TP \fB\-s\fR Display signals (and time) .TP \fB\-l\fR Display list of sections .TP \fB\-v\fR Verbose .SH "AUTHORS" .LP Tristan Gingold .SH "SEE ALSO" .LP \fIgtkwave\fP(1) gtkwave-3.3.66/config.h.in0000664000076400007640000002162312124357656014641 0ustar bybellbybell/* config.h.in. Generated from configure.ac by autoheader. */ /* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP systems. This function is required for `alloca.c' support on those systems. */ #undef CRAY_STACKSEG_END /* Define to 1 if using `alloca.c'. */ #undef C_ALLOCA /* Define to 1 if you have `alloca', as a function or macro. */ #undef HAVE_ALLOCA /* Define to 1 if you have and it should be used (not on Ultrix). */ #undef HAVE_ALLOCA_H /* Define to 1 if you have the `atexit' function. */ #undef HAVE_ATEXIT /* Define to 1 if you have the `btowc' function. */ #undef HAVE_BTOWC /* Define to 1 if you have the `bzero' function. */ #undef HAVE_BZERO /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_DIRENT_H /* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ #undef HAVE_DOPRNT /* Define to 1 if you have the `dup2' function. */ #undef HAVE_DUP2 /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H /* Define to 1 if you have the `fork' function. */ #undef HAVE_FORK /* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ #undef HAVE_FSEEKO /* Define to 1 if you have the header file. */ #undef HAVE_GETOPT_H /* Define to 1 if you have the `getopt_long' function. */ #undef HAVE_GETOPT_LONG /* Define to 1 if you have the `getpagesize' function. */ #undef HAVE_GETPAGESIZE /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `dl' library (-ldl). */ #undef HAVE_LIBDL /* Define to 1 if you have the header file. */ #undef HAVE_LIBINTL_H /* Define to 1 if you have the `m' library (-lm). */ #undef HAVE_LIBM /* Define to 1 if you have the `nsl' library (-lnsl). */ #undef HAVE_LIBNSL /* Define to 1 if you have the `pthread' library (-lpthread). */ #undef HAVE_LIBPTHREAD /* Define to 1 if you have the `rpc' library (-lrpc). */ #undef HAVE_LIBRPC /* Define to 1 if you have the header file. */ #undef HAVE_LIMITS_H /* Define to 1 if you have the header file. */ #undef HAVE_MALLOC_H /* Define to 1 if you have the `memmove' function. */ #undef HAVE_MEMMOVE /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the `memset' function. */ #undef HAVE_MEMSET /* Define to 1 if you have a working `mmap' system call. */ #undef HAVE_MMAP /* Define to 1 if you have the `munmap' function. */ #undef HAVE_MUNMAP /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_NDIR_H /* Define to 1 if you have the `pow' function. */ #undef HAVE_POW /* Define to 1 if the system has the type `ptrdiff_t'. */ #undef HAVE_PTRDIFF_T /* Define to 1 if you have the `putenv' function. */ #undef HAVE_PUTENV /* Define to 1 if you have the `realpath' function. */ #undef HAVE_REALPATH /* Define to 1 if you have the `regcomp' function. */ #undef HAVE_REGCOMP /* Define to 1 if you have the `re_comp' function. */ #undef HAVE_RE_COMP /* Define to 1 if you have the header file. */ #undef HAVE_RPC_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_RPC_XDR_H /* Define to 1 if you have the `select' function. */ #undef HAVE_SELECT /* Define to 1 if you have the `setenv' function. */ #undef HAVE_SETENV /* Define to 1 if `stat' has the bug that it succeeds when given the zero-length file name argument. */ #undef HAVE_STAT_EMPTY_STRING_BUG /* Define to 1 if stdbool.h conforms to C99. */ #undef HAVE_STDBOOL_H /* Define to 1 if you have the header file. */ #undef HAVE_STDDEF_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strcasecmp' function. */ #undef HAVE_STRCASECMP /* Define to 1 if you have the `strchr' function. */ #undef HAVE_STRCHR /* Define to 1 if you have the `strdup' function. */ #undef HAVE_STRDUP /* Define to 1 if you have the `strerror' function. */ #undef HAVE_STRERROR /* 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 `strncasecmp' function. */ #undef HAVE_STRNCASECMP /* Define to 1 if you have the `strrchr' function. */ #undef HAVE_STRRCHR /* Define to 1 if you have the `strstr' function. */ #undef HAVE_STRSTR /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_SYS_DIR_H /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_SYS_NDIR_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PARAM_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SELECT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKET_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_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have that is POSIX.1 compatible. */ #undef HAVE_SYS_WAIT_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the `unsetenv' function. */ #undef HAVE_UNSETENV /* Define to 1 if you have the `vfork' function. */ #undef HAVE_VFORK /* Define to 1 if you have the header file. */ #undef HAVE_VFORK_H /* Define to 1 if you have the `vprintf' function. */ #undef HAVE_VPRINTF /* Define to 1 if you have the header file. */ #undef HAVE_WCHAR_H /* Define to 1 if you have the header file. */ #undef HAVE_WCTYPE_H /* Define to 1 if `fork' works. */ #undef HAVE_WORKING_FORK /* Define to 1 if `vfork' works. */ #undef HAVE_WORKING_VFORK /* Define to 1 if the system has the type `_Bool'. */ #undef HAVE__BOOL /* Define to 1 if `lstat' dereferences a symlink specified with a trailing slash. */ #undef LSTAT_FOLLOWS_SLASHED_SYMLINK /* Define to 1 if your C compiler doesn't accept -c and -o together. */ #undef NO_MINUS_C_MINUS_O /* 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 the type of arg 1 for `select'. */ #undef SELECT_TYPE_ARG1 /* Define to the type of args 2, 3 and 4 for `select'. */ #undef SELECT_TYPE_ARG234 /* Define to the type of arg 5 for `select'. */ #undef SELECT_TYPE_ARG5 /* The size of `double', as computed by sizeof. */ #undef SIZEOF_DOUBLE /* The size of `int', as computed by sizeof. */ #undef SIZEOF_INT /* The size of `long', as computed by sizeof. */ #undef SIZEOF_LONG /* The size of `void *', as computed by sizeof. */ #undef SIZEOF_VOID_P /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at runtime. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ #undef STACK_DIRECTION /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define to 1 if you can safely include both and . */ #undef TIME_WITH_SYS_TIME /* Define to 1 if your declares `struct tm'. */ #undef TM_IN_SYS_TIME /* Version number of package */ #undef VERSION /* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a `char[]'. */ #undef YYTEXT_POINTER /* Enable large inode numbers on Mac OS X 10.5. */ #ifndef _DARWIN_USE_64_BIT_INODE # define _DARWIN_USE_64_BIT_INODE 1 #endif /* Number of bits in a file offset, on hosts where this is settable. */ #undef _FILE_OFFSET_BITS /* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */ #undef _LARGEFILE_SOURCE /* Define for large files, on AIX-style hosts. */ #undef _LARGE_FILES /* Define to empty if `const' does not conform to ANSI C. */ #undef const /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus #undef inline #endif /* Define to `long int' if does not define. */ #undef off_t /* Define to `int' if does not define. */ #undef pid_t /* Define to `unsigned int' if does not define. */ #undef size_t /* Define as `fork' if `vfork' does not work. */ #undef vfork gtkwave-3.3.66/doc/0000775000076400007640000000000012546303362013350 5ustar bybellbybellgtkwave-3.3.66/doc/Makefile.in0000664000076400007640000003310212261434733015415 0ustar bybellbybell# Makefile.in generated by automake 1.13.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2012 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__make_dryrun = \ { \ am__dry=no; \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ *) \ for am__flg in $$MAKEFLAGS; do \ case $$am__flg in \ *=*|--*) ;; \ *n*) am__dry=yes; break;; \ esac; \ done;; \ esac; \ test $$am__dry = yes; \ } 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 = : subdir = doc DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(dist_pkgdata_DATA) ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.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 = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac 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)$(pkgdatadir)" DATA = $(dist_pkgdata_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AET2_CFLAGS = @AET2_CFLAGS@ AET2_LDADD = @AET2_LDADD@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COCOA_GTK_CFLAGS = @COCOA_GTK_CFLAGS@ COCOA_GTK_LDADD = @COCOA_GTK_LDADD@ COCOA_GTK_LDFLAGS = @COCOA_GTK_LDFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ EXTDEBUG = @EXTDEBUG@ EXTDEBUG2 = @EXTDEBUG2@ EXTDEBUG3 = @EXTDEBUG3@ EXTDEBUG4 = @EXTDEBUG4@ EXTLOAD_CFLAGS = @EXTLOAD_CFLAGS@ FASTTREE_CFLAGS = @FASTTREE_CFLAGS@ FSDB_CFLAGS = @FSDB_CFLAGS@ FSDB_LDADD = @FSDB_LDADD@ GCONF_CFLAGS = @GCONF_CFLAGS@ GCONF_LIBS = @GCONF_LIBS@ GEDITTEST = @GEDITTEST@ GEDIT_CFLAGS = @GEDIT_CFLAGS@ GPERF = @GPERF@ GREP = @GREP@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_CONFIG = @GTK_CONFIG@ GTK_LIBS = @GTK_LIBS@ GTK_MAC_CFLAGS = @GTK_MAC_CFLAGS@ GTK_MAC_LIBS = @GTK_MAC_LIBS@ GTK_UNIX_PRINT_CFLAGS = @GTK_UNIX_PRINT_CFLAGS@ GTK_UNIX_PRINT_LIBS = @GTK_UNIX_PRINT_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ LIBBZ2_CFLAGS = @LIBBZ2_CFLAGS@ LIBBZ2_DIR = @LIBBZ2_DIR@ LIBBZ2_LDADD = @LIBBZ2_LDADD@ LIBJUDY_CFLAGS = @LIBJUDY_CFLAGS@ LIBJUDY_LDADD = @LIBJUDY_LDADD@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBXZ_CFLAGS = @LIBXZ_CFLAGS@ LIBXZ_LDADD = @LIBXZ_LDADD@ LIBZ_CFLAGS = @LIBZ_CFLAGS@ LIBZ_DIR = @LIBZ_DIR@ LIBZ_LDADD = @LIBZ_LDADD@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MINGW_LDADD = @MINGW_LDADD@ MKDIR_P = @MKDIR_P@ OBJEXT = @OBJEXT@ 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@ POW_LIB = @POW_LIB@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ STRUCT_PACK = @STRUCT_PACK@ TCL_DEFADD = @TCL_DEFADD@ TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@ TCL_LDADD = @TCL_LDADD@ TCL_LIB_SPEC = @TCL_LIB_SPEC@ TCL_MAJOR_VERSION = @TCL_MAJOR_VERSION@ TCL_MINOR_VERSION = @TCL_MINOR_VERSION@ TK_INCLUDE_SPEC = @TK_INCLUDE_SPEC@ TK_LDADD = @TK_LDADD@ TK_LIB_SPEC = @TK_LIB_SPEC@ UPDATE_DESKTOP_DATABASE = @UPDATE_DESKTOP_DATABASE@ UPDATE_MIME_DATABASE = @UPDATE_MIME_DATABASE@ VERSION = @VERSION@ XDGDATADIR = @XDGDATADIR@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ 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_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ 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@ 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@ dist_pkgdata_DATA = gtkwave.odt all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(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) --foreign doc/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign doc/Makefile .PRECIOUS: 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__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-dist_pkgdataDATA: $(dist_pkgdata_DATA) @$(NORMAL_INSTALL) @list='$(dist_pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgdatadir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgdatadir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgdatadir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgdatadir)" || exit $$?; \ done uninstall-dist_pkgdataDATA: @$(NORMAL_UNINSTALL) @list='$(dist_pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgdatadir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(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 $(DATA) installdirs: for dir in "$(DESTDIR)$(pkgdatadir)"; 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 mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dist_pkgdataDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: 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 Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-dist_pkgdataDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic cscopelist-am \ ctags-am distclean distclean-generic distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dist_pkgdataDATA 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 \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic pdf pdf-am ps ps-am tags-am uninstall \ uninstall-am uninstall-dist_pkgdataDATA # 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: gtkwave-3.3.66/doc/gtkwave.odt0000664000076400007640000524453312450332437015547 0ustar bybellbybellPKE^2 ''mimetypeapplication/vnd.oasis.opendocument.textPKE-Pictures/100000000000033E000001ABB5303525.gif@GIF87a> (”(E[zWF:J ̌7 &/db\LcEDLyu #l CF$٧47$hTeD3 $[.Ǫ\zT236ɦ DDF_Qiܻk-iUSTDI[ףD0+mddF54FKQܾ .L|Թ|jialRѩĈiϴcKLIylevD*:<;ȡ(DU3}d3w/-80Yi:$olltvtdߠddDr4ߺV, #%(cdhXvLEBڴH=R5<44wRCքjMX\´,n(@LM[H;6p~< S2}>!W;{Lr\ԗ T^JYjЙfk,|4'T'+˩UxjiW0˜C\r]$^[d\ʄδٮɕ$,DXܫL{WLTeTf\sLG$S{YYwW=1h켮{ulYMy"תj4¼з-.,DZ.ƙZL gr\Y v=<$޸h$"t$ETjD+KԽ`blxl^TcмLbtLz\\<44EV|xx\^\4a&*40aÅ#BD/jǍ;)dȓ$QLrK0[|)&͛3sԉsϞ@y 944HôSK>UӨwB:VRrvkYY5l[_=+mܵh[ܷy7]+0ǎ#̷˄-gzH ) Eh_N8>9!Z衈vX"asq6xݍЎAX$CxIhd>FHȤT^)$RB9e\~)dYh>iiV٦j`Ygx'zt极I~:hڨv zcpݸ[RA 2if*ꕡ6ǩx`,vZЧ8ұJk*k ;쫪ȶj +*+,Z;>[ق m.;.[{Z/.J@4G,Wlgw ,$l(,0,%|4ά<@-DmH'paJG-TWmXg+`R=vhݰ_S4lqmx|7R֣qӄNk K021R :.z顣~˦^1Sߴn3B@ _g/=?R2EOFrDJ䎈h:sקa3#Ƕ)-bi9hFsc<6n*펕\ģdJ y?"aLC 8'&J성;!#IiNR|$@yFPґdA-͆:uYosr%Xx9̢̞1Bs)1Vb"iiF@ Piڣɒ $(Ax,У;,FGB. & R(TI7A~^1A?)N*C\; x:oZ<1!rTL1[uZ/X:5+VR?yq[#KҚVw@rYxj&ض#СZֵ"%o2JmMr;:mt rͮv]8raB2򊷼Mzk^wM/|׾콯~wzL_7o|;6a O~p+a { Eb&NW΀Bχ4 hC3ы'hIWҍ41K{={ZԦSSxn%=tϻw{Nx ?;^`OzCs5O5K=S$5,oWF=魮zޭ|{OէGzr_l}+G>Q-?̟}sO臿?ǿ~oO?GjIjgFd_6{qa3kZvuzy}ׁ聺jrxrPuess+u/-r%H,X8w:3 v 2j1rNʤP OXxXJ0*VڥMJ^4:\fhW3znl SڦsuJ_{ZwJwuwgقYIӗ )4B}=VFX /g{TlAVxeJWZc:c\ƚ{ g diCez @uf{iǫ;W: ^6q=fcyrgzNv(slcJqanvf(8dfIx*Cv9گڮj+fʬzj˯˰[[ڰ˩jfkJozI"L<8yEz:@M@ `y[pm)cv >`MPO>ɰ : Ԑ  PP%0'NJ @`TV|y ; p W+W[?h { Q@ M Pz^`05 ] *˟Q1ljPɖԸ+Khŋͫȼ (Kk׫y|TI=vH%WN0ڟ% ?C :wJ^%z0jygV^:p3[c@j:ް?@qފ$$L\qij; *  W@6Ѝ?p<`"Zl-ڢzƢ)[y}H}lfmDȈȍ;=*Ƀ|ɕ<ɚ `ɇɂ\ʠLzlʆʩ|ʮ<ʰ uepe=@С 0fyHهM0MLJJ}c:&;{LOT`L  l\Hݖڷ܍*}iYrmmlޢ\\mM-M.m j1A;dul̬JʃNfN|^i[J[0y8e ` pWɀཚxhPh@ &MX` ikО+ JP8=hpSYϞ9y}iPi @ & vk_gg.JN[Pxmʚ )PƔsJChף+[zy괌非ꠞ^n~.ޥ>볮nľ.ɾ2_z<)V^]ȫ鑷fKtk Fs ̲u -g=' H>.j㕫|< j~ᵺnX.܍9Og# ml6V~Xf)㺴2/5f,?8d6:<>/f@B!j1.·/l2hTHf!({ʅv7/x_w hzϻz ?tJfޅA磮,H ^̍u.j~( (J&≐Lg/u/?Io6WOofo:MP>̷_R#gQi̖xJ:<(׎{sc:vZ:H6󿘿|qÇd L60d A#L&p`Ą7ؑEC@RB,2K*^ Sfˎ5cs'˞/g=Ԩ͠"RgæBU:*ͥ?|*dWQ2z+Vm'}HufC=it.˘wJzw.UYM4.YMcA[$` oyɔ$øoye)}K6\dKEMW5m_b~boL9-8;m5<ߜFYD|;q?u9~Y+?(쫭nk&3Ԯ<9[NBRH]lx\+'s9/sC\WW]]w}'O}vqW=u7}vލtc_֑ǝy}g^uԫ]ݹGK{ПWg)o?7{_>x^9 z+'vͫ1ҨǼ8H %WBa Oo0=T hnAav&C`?aSTp7:Sd.qT-M!mxu5)<z(k3'i^3F5G ucY'P~#7'&o5E@>d[GC%I̼Tm`} FJ+}l2I4ls2dOu3'<t:wQA+PAC] rD:j!75X(1R,)iT)Jw)PNx&7 yD% G>ܤDtXr־!`3sQS4QlYeĎZbI#ҵQ+\aUⅮD]US ϹMH ȂNKv OMQ% l<PКudDڷU^(d 'j]|x8.IiהeYN4V\?mT(k0LR|EB1wp9d+Uz TRfQ%gjUbݛvQmLYaY/"rtG~-3|Aq9)RLh2?y bh:&迥В-hL n })Fbp#{,7LhL'1(;A u_6lb[V _366mj'{ nrC[ͽe~= oy]+xCs/p~41[lfMz47,sS0OgZpU̺)Cٸ<;ΙʼOǩuri}ř[<"wʙ"cƤQU2ǹUzPGm'F`s}^>ns}Z_.n;h{ݩmPjO8&-]blI?,ai}YJ1Aܙ/.UGyыTe=]zkgtl߳>֧=~sL M@R6ux;: $ Q cl5=] qȺڅ ~j]N[-i N?5 #;;-؂[Hxbp)gC&󓂹H0/+.qRer\r3y ٬5#3,y:64+ Ac9,'_J$ Q&2!<:s0YXBHێdS&^f^5Oh5'`bsj??)pDijDoY;E;D5K rV?ULkDcS, zٙn21",/Fz. QV OھۂIṔCc[zd[K_#ES,7H,;K6{6ɛE$EIpIncŞ ɤt;d}ق4舥ʲDSõW; hJ$ ^*Y?Hht@x&ř-{h(`L0l]&HH8LdJ9W1$)ACԩAl`LrLT*'-ږ4,8 3g `` TC)H:i[g.m90;HE:E6h(8_;L:&h;9h(H5hX;h(RPR^UU䍃@_+M^P_ ЀL>F Y{@[, .<5a)`m,H68wbH6Ў&hm``b%Ё&L`,.-`^ Fhg?PZM{> 82U ق FGW*p)Y86D c˝i5!dO1!A X)AbHY8W?̀V;U`-z8 DhZMdfl.50_ۆ 5mPTDCu-g<_x>5 ţ\vK?#H\ u~]bL?&|>I+٧5H89M&[0.??@`6F,`ۨ5̻i悓} ,aꉦ,e'QȂU㒕`RR8Z #is*^\,TjaLH``Lpl j(3ӉF&nbBV)Rl]k-Q@yj#BV>;0y@ H@T )c|hnb&& S4 =$=)(&;X_&x\pR]_ADy%7GכW~@P5 ![o 7\N C- XT<]%H%VbpSTuLjL8XSmhT^qUj,~"j:vj-+[X륹T,9)H]>?6#_-*7O88nmL@ר[rZd+eTf2qn3gmꐺ \ 1HIcHa.-rӥ|9vq zxp~߼a^h~Jq7l G`|[K퐌BQ-đ%u(+ D ڗ݇ }b ?5jg uP9 {ᶙHJ1є4w0! 6[]ŕbeXU_rb_v&bc&f&bW]Zf'zSfEF_iJgBAQ_v%sFmŅ\Dt<C),Y-BU|א4m]N5 +sXCJvҲڈx69#IYĭݡJ;rH F:t>%Th~лcMt4gfߧIps: CjRTY8uGTSWޕCu/x9X|af\XZbEMb&{uuܦ^^=)84P/cPcUgK\;5][}^[]e{-vhqaFrc;d=nύw[8f_ݴQxw9SDDp5EJ{$LdJ;jI{i&PH9t-Q``h~ #FM.)[>JQ5TZ23HP 89=a1 r*VfʙW@hN$Д;i0c_37sLcP v<qA+D5 =|lh4P,Y'bNWi j6 襒TdjH:Tkb˝(?ZkcAb2ΰĐCAdLZV@|DV]zPI[H!~74@ C4 &4RRH Xqh4!?l P Xq;āwE dCKuM8*V(ø;hg4Sj>`l2Go76GK_sL#Cs5p^팋9'h;enr`WU1jk, oCTy%U$+ՇWPɲh+ix7VU]cHK ]'?J}]Ǫ &T&ɻPJ%vix #PT~ynOȅx@ J32ͮ8ЄWhTr08 fK )!$4VmXT9U]TCSL7Iɖ܂.QgXyհ)IDӾ5B5D۹V?j >anR[+nOy?IpwYf?F3|hJe;B:Pf @qŭ9NkxZ%(HY:_ӣe$5cikt W!ͤw y1],}2atI&=ݝX5߫: `2ɝ,$Y8nef^0n@єtbʬou$"Sl P ?_JdHAdCWTPI7m$UPӹ&$˜TdEuB=ԁ@2QAƱJwz4`@SN0^ݨTQeF4$j(RGY bfPȫ9qW9,Ơn`IJ>Q,(Z4!ne*U+[=fjF ,C:8BH-@48BpAB2ADE RX XlB5k@jokr+  uPvUT`C |}jP {Cm `@ ߂CI@Bad9m"ub&oOTH l*b)-N[M+.K pˊTJk0KCdz_ɥW(Qk &u- ɛ([E `lV"bƀq\k\f\_^ GЀ=1|9@BЁ7$GBHhgmD2Oc lP®@@ D*خm<@6E}b'C~d:)IF-0pܲp4HC~tZn7&æb6|BA["ӊ^fd@W4F枥Nz4H'hdmHDtE`e%_aHͪ8m fNW(gR&nY(U(Ni GrK ʖD00$/Dɖ,G p&|Ai+CfblLC( 'O&A5(4!4Ճrm܉QT7ݣ`6S`P繘FK^ ['AHwd 0ض{VH oAW-4\<h(= <0A lBhwNuuv]Mf{I|[7|owr4I$!D 77}t[`VܪE$:AVHҧ|wp*kwkE5e6a_55xB< @$tH0x-*^@<D| \=(lm!S=`9/)* 6P6%FE02o5{]䠲E`KHd]AP$6ح@9E'@ QyD?t:x:AAOAOeBC.DcC,@J.^Gw(v_~D&+a]u2O95+jE'jq'F)ET`ɡg ,%r$4Ҫ9 UDKDB0-=dAD l=:`  HJ(2b-f;Ԁ6&WmY1@Ċ l]nnAl W CtrA9to@Ep1ӻVmsM=7Z@/Ұ+;s@+q+K9@֊鑨wU |ByʞCCzV*I܃B4g4V>T@Bj25dCbYބ~˾JRrW ;`e%BPCQnC @ծ/5 \8) ai*L*02R22$.RkeM"@$A? &!3E{R6 b"$Oud9Yt`Z W^&̜ É?0Gsq9sJ'{3lE3~N붓@<5 Qƻ[M {N U 6@Xa:oF  39XneL|+D7XX+ 5QmCI %A>Vjqh=pj. HaoZ=<502jX>)E!%x&c18ԧ^ ޒ9"83vjuWZץ@ʅQ{:JLh_Z`0*R}IdQ*1Єe`m6ml[`ZGHqABRm yd-tp;2Naa*RqԚ64-^3YHֹṅl6iv-̖վ.n@=ExX6.KIv0,ںC@T2b+N>~;(@]{ޗVq)C2#kIOhD!Vе6܈"Np!0j )e$(O{fl$%uMVM^DrK`"$=M>̒& 1j=SSk]2"$s1l0bD'/3TEq> H2X ,%qe55dHh4]<}`$O# !^Ynq)GZm1XZ$l' Kd(S:ՃYpC2+;5Wt?^fMao~co Iw8=M$ߗ_fhB&sa7uR<:PԄA1c[@a kJi Ik"vK`ԣxFjv59ggP=B1׆TǪ>`L_;I'K]S:`̭|n3jy .^[cR ] r6ZgA[$nudTQhRú"ë5#a-l#D^f ;W)ׇ0>E6ygA%#ct-d2ʘx2h f\<pI t X); -ir 0"ȩK+lkC pȦmZ-mGG<K9i{J9+ P4"LrdRFp#Rn|˪ψЪpJǚĊ t$@b``P* `@*O$>n" #S%RB#)ݱ@{>}GUH qD IO0L鈐^e올dkl'On &P"nj (bdB#Hr@50nDbFƹfMbtE"@ hg!|Oikn(w2QB2zX*'\J &B< #| ʎ!",Rү# nQp'* *v+J>,d(Sr$GSrLђBHZF,̉n&C^S 8 fTT0UVBk/p C &2u! i"Maj¨Ҡb4:!;p9Qn(3 jl,iK0!ˆ^qQ B$qkBQ'?@qKNI\Az&GN$Hf[psh0I|30j0 ?y{'1"*;I|tFmtj5 #d傭xo;Lve)%S֓RN38PB%sKO/KR/ 49-ǔ[ $42&aQk<1_' ,e2!pG#Mj:Бm Q ND2RȂ4U(D@Um T͜" 2 ^聎TR"DF3 HyT%nON"VAo)|~O-Iuf#4Ii !",)DX$mle8I gD JbH_T_utTIg>"h>utБҀ?bC90Gb#P=#9i'B-D=i`(m3FBa6.N.grJ #uf2uL3h_oj)aâ-KNu#ʕ|~hS.uFg[ jNFmGG.; !|V [T# <$VPZ"EOϺ4D!DBt/tk)8&(a]=K4[Y%g4BvYs'崳vyVSNS#ærPi%RV}Wg텚$Ex4C,My/*3-&>#UJUw"ڲI4҅ҎWK/wKRF4gngPtimMN22&Rv=帇SxUSW"E54vFP`F@݂|QJL66jD҆D^_lDstP}5PbD :[[vQoPwl81Pjfç|hCb릟ZTS"$)R7I-9! 42b ڈ3ʇFj$kXZҠ0! @0x؏XyY遐Y†LrT#M~ zȸClK51Z Z[ghfA=v鯎1f?na@(-B@&uD#UVq]Lsw}1r74a8/ C M" ހ6BnmɵnU?')dTZ);$Ain5À9C44ZlgYÊ$l8U[n]UCyUAI6gvU3TḺQ=:xKNCpur{] P0QXpoB30Jlkf,EqLBOCF"TWn%^a_$WLKX _)RӬJ2I#sgnKӎC^c_v5#_Ȇl [4c_ٍG2M|m?z38PSvT55цp9)Q ոL~!~)+UN*ú1[Cl+v3Elu,H ԕ=uzhփ@ f:!D ֎<:!VM7vJLM'ʺÔ]bx?˾ j% پ/jFʾ'>ѾWJپ _@l^ ߳~͞3Ӿ1{pwYTԓL0Ȩr0'SIQ v6XG75sa15 :\Z}gm@ BdIkjm{wFHT}H6sA07TOiX6כH` &@ևd!2$l2qbƅ JLA Ai*'V1E'2dȲ Ku:.!Eia'%$B 222IGR,d!K1~n#!xTrg|$M*op`Y[lVyD1GgX*63P%5(%FǬ&y[IYڤNkCZG@H&m[tN✼PBH C.%Ax8tse4)QZtS ,$g@ra2Iz2 Gj@y /OvOW*#sL 3R$‘D P0ى0H 2a<SED#mH[XYjR -sChQboRQ-CGCʳGgb B-WKx]@ ;ץET"6S |SHkI i0W, )H\¹S?Tux!8~)H܂Ź[)I"wPQ'j]\E{Xu5 U9b:|ca+bPHKn P s)@cz$uYv'Tfq$S[F\76(bg0k(=xZB6Xz3F($DN6L=(W_S'%?5"w :qNAnuvpa lP hwo 'ƄB%`5bc,0-p[` @q݇}6"rq7*a@^ň#2M7+(>wP+2tQQEhSr3x]]ňHS4͸tJB{"#I^ Hwj[x$%Žyi68 8W._'(`'-Ry$O7mqt^o76!Qxz%4QBIɀp PazTfrP\Y{̘\.6c[!@fVBsLe:@ s@v~ ܰwt6h@}`3Z`M0?>&|Q3ǔUOYrjs5r*j,+1ht%uēe&Q%Xciy@=Ehb e`(rVx,7f%BY7[p%p-Kl!Y7f6<yWpV!q]f1RE*o`q۳.k)4%e%e@ MPm`gpX0 MM rQR7ynp6WYwF鈸UCq5BHer3(or6RLcWi8XB^T#ygkrx(I +ߡØE, (ZhHFDFt13BmF24s10@=_*bfJ7!~f wg#צ0d1w ( (Upf^Rn f죦-J^FI Fa{6pOfc]1Ecut~AXJ5&6!\~MnF"K5vyAPX|c[YYOx#fZٚg.G?,WX\c9ƙ&@3R%tX=U 1P=b"Y):lW)5*:P8הaR#%)+M*zA=4IsP Z"jZ&s)i 7 ()8 y&kk#FdS&3{*_6ٰbM0Eh=d hUҨwwHZN{vj6nS%|ҭ\T#Z^YN"lƷl.m=:\@Z%b1S%iڤy-,Rק%sPK)oSE)1]&ʦuupCi*C8*[0$ũmÏ|x [ "%|F51;RX6wS)s oVV:2&i˔ qȤ h;cDJ3k MwyL-GA@f 2`$h5 vԍ6]L8+W{+G@We1{4K06olX( ^qAP"hiҺu`R캗p} pRp[ -pJP;%^(>.L` pݻ2 }-0 ;d(/uV2~< ,J88#`#wǀȏlmQx jbA&Q[ zodAZp`҈\'u%6T,˅&"B6x[yURsiDqC$ ET8uuFsLAL?3LN.(S(!Շ5H1 @ S z:w ѱ##@-+ϟ{'C`؀  wp{v|@g/ͽ$27}Ӽ뵨%?6m5-sͬ 5 m)T 0W"\&V'\XmVy\?(m4AgGrX@xcˡ(}gm"/1-nR{å8b-X1ӘنluIڤi*M g aybz,Ml c/۹[ӡ1-Cp[wx~[:23' !o &s08 k0mly~wv:K2{ۗzxP!NX^yCΏNfM@o.>.^N^~^N ѫqHQk6HZh|"aa1iAO#i4֢w; -, 92lQٞلhEEfhuA(geKHCq* Gp҃Z<*@9;O>*P¯Q t* 9RV@<η+/[UV<ZB a>%%Rto",uwRxB$'A sݽ77šz?_ҢLٰ N#.)ʛB+?_T+PiFBK(W-'GhuU Zqn_S@Zf?lDL Beʁ$@_.@e*N X;ճ0}fNJE]2AH#1jn}Hd[0"Mʖٻd4H8 ?blabE)-nw"K,R'& %D?,\hӖ[*tSVW:H+VZ*ʒ+б8VժtaЧ8ؐnկv6{mROK!Kft:8n,St 3rBgϟE=ΩQ9-6iҸv'6-wHݛoy]/oN~|s̝zʩ[.=c}{;5Z^,^Ƌlɼǀ5 ˋz-k-F&e@ rp z ! !'@\zo&0D[`$Aa >P2CC,(>2GdA 10!) S0@̗AT&t4ƍ%{ifʼ1bIGYmTf'8(N}ZSVA1&)1pgԡ6CJTA12;\ Ƙt \,,i&\˝nXZZ]ŻrAYϊ!5< GuIzQ$J@3L0z MhЃpĆ &0̛Z0jyj !WIia$aL'H$܊]ŃJc!~E(FaBνЪPp2gעDqD,a!bZͭ|:6hD#WDefo*0P[8ВMpMQq6Ҹ@Ǻr99w#BT\=#ulٍk Q{8SjU*YPC `%Р zLf#LEl RD^ $zRLyP.J WC'Z",WYTb\J$jF O*iXLPz-" V]&OU[јвDA cX09щRY\鞒ªT6Qz[2*(T\)m bK(*:hAikPVuR(ACWI;',ݔ0P=t! b_>a6`ebnffFhi6fYf&fjdFilf^fro&g#pFhpfoxm怓 F(L 5WWНUGR 9y* ieg_߈LMc=qT0[67T%jbS`Af9itt3mkw>idμmվB5(S!IuBb?x鞏7QoT^](H -wt|2ͮXi9k.sO7n=-Օi_DR;1'SWEɧU.V'!lz>,x'-"LG6C\B~C-+O-Jcؒ[>$37p  ?r C >Ä 21A`Ò(!N<)@5 ᭐YRxPœmNlxG%>ݨq^$(m+ҤHs3b#̇ND0Y-\5IK65Yȶ-%5ҩڔ)ɓoIu˧ B9*^D1hi 4.KxqW.66nO%%#اfY;oQ9Uo픇5ئAU{4ڮ_YS7ڛ9,kf_B|4S Qg=9CwllI݂4Lt%[IM&CC@aQ e &q!diz-UO1SkU!MeMˁG5zHx١uҎ5(ܑjI;EՓ阡ɶe>^~h5XDopIdYas{=yFp{:)DPRN.ܦ6ZimlNF)/wGW&ExUنg"9))PW}gyɐ#Z@bh~v:BC橁ocáWф6"ZvZ*ApK H8r %ad#5N݃KhWG ѐ{>0y>]闣ȵ 1oȞ `.ԞT5ʇ 3}NVv$zxBnޥ<$Eb٣ 'hI]cJ#luBH8DtL̸NiAP =dd i3Bo:Nb$nz꤃z鬟޺.^Ǟ'IpK$dEpay2xO8ym8{︃;c`;{;>꺳O~c_ǧ>;w?ݽ[@!~{ -?n0_W Ưaw~^'AvR06&-lҊN /@5dt`tlHVU%lQ2 EĈR(h1i<#xF6oT(;юq#F:_!0@FQBEDD8?>~ "†qqXGRRGJ@c[ K>uLewJ]җ%.W"ܥ0G61$e4 Kk2\&1GWʄ)be9׉lSg0oϴ !lZ[aWsdt3J>dΡ0 8FdYx TL(ANH:R N!QJHx*ILr~GAQH nHd! \F9 hJ#VD4_V=ZVQ5'Qm0֮2i[JVMH:)BׯJWE+TAVrxZ+bj%yVQnByXm[jXV#5JkQcH6+XG2#)b4S-R8IAMi)ҖʸiH {R Cɐ#a R[`) r^-oF7(7ɥ_c@@PsNB  gQ t2m9d۲W2$Xf}|>^NmIՖZE{էXIsHkaT׸8Z08)?Di!D{CF-KvdIxF/$bl'IQQ%z6D tDbb8J3&dĠ @ j.L 3glmiRD dacl~'WWv8M9dhEnZ#FVXMl -(KKDLJ͡D6RpլA\8׶K>͹KԔ#Y:u߈I76T lپdl }3a& sYZS3utgt[oΑPv`Y}.i("gzd,6kJ6nlJbkJdZ]_20-\%bmwmxNl떥T.gN,.YnF*g.Zv:'oVʨ]/ҮmA5ooe3u:?gKqR0v Z2PPCHD-^:d/Np ̆hҦrr(oINkdb$V\^fK1^Rqc[jqʠ-BPv*NôQPb kd /  ׯ7.$B?&/ Gz(kj+nn_`+8Pr%[%cr&k&sr'{'sr6(r))(*r+2%+,%r-r.-r'{so2x|"&*A1d .'nfJN֯&(*:.hrv[xA\0G=/=3>+%?'%>>@?7?#%@tA'4C7t@;Q"C/4DW4E_Q*4Fk@[tFKtDGsHI?4|Z5lKOl,/@"j~g~35ӱ o"dGBQ{g7d)#cF,[={I//XnG4JXuXDuI[5\[Hu\u]u^]^5`] \u_#vboa'vyB)13oEE<7!0klG^ s7{nT$rhV5Uq!t8~Wcb5]o7q5_qvr3vq s?q6s7t6rSt/6v[wvkwpW7xthIj1>&sU$k w57O0~k^.i: o:힪fS֟)o+wowwC7rot[gu7qsx7oxxww7v0`BK) kut~W3RRs~ee 9Nhk";mGTnvoc=rO?y8Gwys9Sd =\7mf z{z~+k,.h_m~^WGyu:8kxzz:98|''zB2i(^6&r6&J&+oO3⩅nk:d:tQP:ߺ;:|z: Xjić=iUW A>:#kcGZS{gV:6wwTtB#~ "GDA2 Q h{>>w~~{~~{D& > 4xaB-tbD)Vx1ɒ}Fs?l=0HLiY`#MI)ᄔ9z(G& TТE0:4Ч["j+ѯRm)WZnjѝ=_$i[o` -,@Ê3N,p1Ǝ?̚1wּrhʣI.ٴd˞9.H3kѪg j׵e}7mm~<3I[\s疔?n) iwI1ץǩ^5m׷Rֿ}zl`&UW)=O@3/?أ=:?$N: v C2nC+8;69,Dc#]p/ 9ev[$b#0x˕r;F.a<][|( @EoO N_>Cv@lB%\N0,lh)t1ZI 2ZWS[Q|k}i\_#ƵOy BMf ud#:MiXURYa`NjR9C0&-I*LRfI: Z>i[3IB=`CԼ:ql$"ٵp&?Z{!#!d<)cH  >iRmd)KpOB ?hH2/ڌfұÒ2\3oǧivl Chbͤbi:R0LXɨ$(4|v~3pDqEU{joP*8V1QV>:+G(ի%X#ZʶJf?SLwWĒ6͂Z`L@9 -s4a][Zֺv.NSJtӋ uFO>[[ZX8[>eBʱCAY&#H*zCxs~_CW(Ws)u-%_j$:?X1PQ !/0+3ޠF߫%B;ڠ=CMZubCV]\[-o$IJaɟl# 6l:^2yL SBh:ViBeYxv(>dҌke{ٸ\p,)ppa7νesf0P Zeܚ mZ91&k ?rIbp\@#WG6u2i~tw67Er@Y]Xsh&(,嗤`.Fk/#8-a;Ϲ/3n6Kd5{\0GJ`⺤t҈20LFRV'lB첊R%[SEDž4MG(&! ,Z}6jk3{s*!:_+FiDLag·Ḝ\q`C֌Qi-@H՛ukTA0+}Ao50WZ2qcp0*Ko!_6?rWpy)50Rsx9%KwHʌ =[DIK}¨ի~=ڙHgy7s5$W/l8yū̮V4s7nKh,%s$~@2-FO~{ <{3$I\N(mt;J^ʥ,f HOD, !h-0.& >)Bp.oo:p_0u$gGqQO-b r#$0r4fFg&À% (Ģ_n̎Ovh&AH, ,mA P.RQ؎*PQz1Co1hGQѫp3pAp`$#Jspn'hhZl&w +l^:H uǬ):HNK9MH z8B&/ ="q #mkpq%%g/VR%$ q$~0Ble-H;`L& 2i+M klj2->ޞ?>bOtAj$P"Nr[ #RZP$#1d00Q0UCES0_0'N.#ALk#H̆"%iYdըɛ@(+؍DȰP3[b* idtVJLȭ147"rhS9#yo//Q13_22373<1c1 r1r:8bj&d:B`(Y#C_Fqw ux OB jb,PФ4_p<+hI,%%1b>29Y+:Q/g:'3L<#<=3<3%xF h'0"j;LwADq5FLV!SPz.@"İr^"#YODMDSI'P:=:K& :2s4RדRqR'HtH3R #7tSCG72TIarIpV>BfBfFK$QY@Ymh2doOA.4t6PߜNV˻EA2LԥB@k ƴ<o16DP: QQ+SRk]Ou1GuG݇T=6>UD_T`dHnA0 ;z&Km(5pQ _(POMdMd1$IԾ)b`KC<_ g{E55F;[^4u/R6V=gEiG&\YEU6/hQ63^^v_OwjVkVU"cgUuYw¾UPo[cWPuT3~(gڠ(TiZ^O B,+NЛPd;DHi(-6*d}cOEOsOT$`\PyE.5TC2dt^vl7kiw~gj-ׁk3+vV'SWv4Hnjֆh^`s@ꌤfT{ ]$))u\,jDoXLH+dC ]ZopD:iu6w56R8sx2<9uuöتx-840/ϘF%x”_S15HvfNl&%#/`mb#w +XeO!XszC?dlHpOrhBZ.T ¯,rSxgpDdawqdFUKtXux9~7x-ٍ{.dAi:-BVHbzW~p _ |7+-HK^ yWrxX#oY;s-{9~Eovz;ڙ阎8sUp&#vp1tU#pn'=uBH|o,O|19MH12՞ɝfjPO8:g[PUᘡ{֡zs 'ڷuς2yrsMz˺5%(Bh:~ЦM"NYge]fR KV&[**ȧ҃ $V/ɠ}C~.9w;sF1լYIUs{eyګYSfhf0Op,qY0jκzN;}=ʛn;;.$3h&\{1vE\Xuo>ᕂ67n[S{{UmY.00:A'hdZf\nSeUQ0{Hg|_5V%5FZحY|3ڃiv9y#\UUrVII9$;;dL`hה:*ױ-Ƨ|Nf+CC}hvJ08Pj|x  ހ }]R~wo8Mecˋ ]g-t s|},j3}u7G^=S#9?^1C@a]_n49OKWX{d %uLF\>\jz`83qyWSW=ٞCK}=)廽Q3C"_+gͦ=Ywk+!-h_Ȼ~%pL~׷pt登d %'-m5BWI! 6$CiDՙffxYYlu\9eVb%!fvQa%[viF[ZX&. E_Fy_2tX|=8ц[mQlo6piGWwcʧh"%浗E75ɦfޞg'ӑTW0S1h6wl RI"ً5`cHc|]f?eu]V)zc?ƪYt%*`5Uج]e_i9ɐa6l]Y[i m~W^4l֙BtG꾻n*oi?pǢ慀E2"(TIr)`nu-JYżވf:b8dUlب6Έr:&NAuTQGT=mR9-DWY-qan弃{'W;ЖbMݵK@W gS6f͓F 5<7ړ-8UXm̀]u*j*˰zX]oʖM6,ةR_/hjquR6yCIK;%ӼeIoN{u>}o :mMd/VWm4Q,:31fYMو!CI[PPN6t! Uhe;a)JT^Tӣ|,5 K~?EI԰>G i?[V 8WfX(sLN!eFq>SqcMQ(o'8NGAQ^\IXOg(JVJoz&׵:t?)Rjph I)m%bk(X{grS~)i8Pٳue쌆Fw d>dn~ <eQ@ĴhCVRk .+\ud> o=(^oúN4 *%VY3 *6P{[._@dl[dYWS-dF~&3OQTmLV ™S E#U;F`XI]{#45ҠIEhm}^[ݱ ZtJs. _ _{E:GymJD7 XQ)(հ,wH|5di3L99ovsg:~sf9 ͆FC;v\:^nburry9;jØ'wRw$O M +÷ʺ5}''G$((l+LJA3~ ѵ-mc{vmtnq_: ?VB7,5I[vn_V"#e멯Zۇs_Wd6{ᣬ ~ZlJGܶs"ky?OfA{^<-d)ĻPBsFc|[u> P/5vuG"-fBpJLß&˾p({ +'3v>F239Gεv&3EjjofhBK1%St 0*kG4;LNzCz{du7{Vjcu7{v%6-q|$kWRX|w$bi@GrHB  25mU>`sAT&@?6'F1@o!sF,RySt}q"*E s"yc0e n#T苾؋h':mv((Twu̇y8[ЇGr4L擈nݧɰ?1`MZ+'1sG9*r"4NJy`#!GId\XbY YWjÑs مזoy1=0wvbSQt!f9,s`7 bhyBՄxv?G98{!y6($ߣ_rIHY `8-jŐPcvrX6$Ռs'IC*PErWrHNY?392a37n~X~h2t{nz>k(jzJI{cʴ{ Tt { kE70=q 3$ Y4GF6"~7U87z h?YF_ Dz9{9\:5)b%uɸ.F\zj]ٴ*빈˳ u䫰9s:Y-@zǍG@Uu!H9sd&[+@#MxHbn-F'y}QaL lb;;:5|K%) 0.Q[\R;nl')\/( Zq>çp[yXsEusKyT9uk"x~To37sk,f$@ml ;٫‹,¢ꛛ k4L7g 3fU&n6@3Gۦ[DzMif\8j͠[Mk?~hDl˹ X'H,īx%SZJ2s6ZNN)U~r֭eD*2zs!>KAn Nm͌+̴L]]сlc-Ѽe;K-ȉ n)RXngN;[[.[twt5+!4MU'h-KOՍTՖ̠fM|l˦]}xwDGqR>#ҠYҀ5`0]?Z Z#xVzg9Eʶ?x*KΛlQD޸Mڀ٘Qm] ٝ b/LmMggӷq10DM>2HΘ LYDSu#ҭR9/~c7-ء5!(͟Ǯ'ЗػR b I=w(I=ON$f 麬99EMr.UHlxv"?)' 93X0,nMt~m;nm]}1>{^Eaõ3,ɮHY 44Ta1d[an@jF1;T?5bbl!/x͜b2^㩭c-zLK @ L'F>&ZFxKF"cBM@íQn~I(绒!n" n ⧺ワl- |=x.d5fCL~CF#kڴ!$ث%YM>v}zLS$;#$n吝 ZݸZ u?ڂREH?ezԈM!r)xtz+ݙ!3S2{姲xNr[L^zhN2YNѤܽ-)JmM?}>*9<,_O3 F>hnə,W+./ O9*+:MOIq!i|aˋ;N>t JYHC`n"1Rr̥+7nܹ}뷮uX\NJ\2b) =,sflaWfHdj;Rݽq#eha![yN˕6۹PJyܺtګv˓^4djiɜ:5:C #"-KS0KB@ Al4!K4E 93qE K*zJ<|:CR84% '.J*D.SJ"2G+dj21qd?\++8۫CXвXpkXs O 32T3D73B-CS︄Ưˈ)YͮdUW#}ŮX}Way-V|E6r*<5+/^ S@sa? :iX3pRI\%DQP;t,TAFT-.פ>ڪGed(c]Ev(["]co`C.9f+f9ebW9p)5oRkB̺ʮKGPI!h {LikpO #T={BF㽌FlgeWAyf7c8׸6ʿ\Gꖱ!?IuG MMPP3=2~-Di 1E2 :>T!gf^Hw蓇LOWam4*׾jq><[i;/g;((Aw/ƅt g 0`!@!}/|a6`C5!ihP1a!І?%&J8E&RщF"X-rыW"ňD2pMD"!~3fet88Vc(8t#BMdzT;A?;^2h$&iINJS$'c$q,ڰ>H{ ,>}y-_Rp.m$6h5lrb! Ф0:%c+ehERe&0@R,^P/S];9OR]ryJ4vv_ӟ,deE/oO"4=4)[cO\~iPaFBce Jޕ/S%4Bt˃R)" tPUOyR1 ӡhSQBuODjr*DUV)}\!lMF#b HA[؈jk^WJw xF3/NKF^%Pi(|TE&=IڌdmhE;ZҖv+Y Vv%X[ի%(nuc*S$7'Nt x(^R;ꋝ]F$T%l7E]ʖ_ID*P2JڐpmJ귪כmk۽ᗿ_-%^E[Й=+.lU~P6XĞw}gy7*._2cW)kc\R )U1|<:ɴ o.VdV\mX%OY\SohNišCt5D06l]urW'ț '2L h*{B=V9CϾA6r<$Y{^XhMse5kccHDr ܒF\-D ΟiK82]lflA#f.yƙb%~u|Ė[h[( ɝn*i&{=RU&ڄkVǩ-cr$Ę*͙)J؁ί@i-cȅ H wA~aԵB&hOOۿE{nrȬq vv6 \Ub0MNs:5ր]I^Lc/7E̬X{qQn|7̏\癶w/e[qO2Y99>34Q:OA;N~)9Yi7+x!//6 ; Φ6 w,~;=]KdvXU->qVLjzzlSjscbνs_'NqM<Ͼ$g ?F6R7-19C3>㛹MӶ;(rrh:ia 3C)o2a C=va  =3d{=[!7!@X)"˻Hs>@@ )gq02Ikhkj~;P[s?` `Di2;g+;>#;4.Y PdY5ɶ*2 -)=%DdL;,/ Dؐ๭ȲEApA5׈ߩ5)! &P캺FQ 1P:BXٸ3ft;TZ/I2ėc@OkJ9p|EPd>'GtL @&S&7=7 kr`=FT6lrxKzLL] U{DsWDNoDX+LB$Rlj8ŭ-` ڸ7iĆCnrwaAM /[zBIjy`c);J2q\@sFoN BCs+Ӓch;54C:xCEIF:tëQ30+>D=Y%kGHIb/ϝ\;}>4-T195jھjb;I@Ue+/r 3RɪJ~AHG۵Ɍ140c Y%KEh$\YYչvDŪ`$/Cԛ@LMS^V%^@0r`uj\-"LT S$ơL3, ]A!_pQ:H:ZA#[JAST!ǡG~ـ,W$P!ъ`]+ޥrni$ AHM+'5roVp i5d ]|޻:$%.d-)}U%b&~MFB[U?5}۱( h1_*`]NmaHI֌>R+ÌQ)${ *^ƒ[vdF6`E<lK&|kV0&¢Hx/)E8\X<S%)J,YN.E)Yc<|5/\v4hfOaB*>ffU'URc֫xQ[B5TYT2uA8e+X>CU aFV1L݉dJ. M~f0ٖĭIj.*f&x T溂QniWH W]31My͛0ZZRAJ:oxhၜ"{}jNef5{hmdCACNޱK4II9kUn:R,Y5$c[t 9C`UZ.Y6lhg&Yefv8 bdېM]MowDNw~y +]yte 9I<:hnj7W+8 eqfLufHώo)`#tixEX'?`bw`7yyG>b_wcmZ]&p$j {P`DI8B;a;{gu燤 oF_y=pą7lVqjױ7Jd€KRjɁ )RN X`1 $ Cs2\XPA V܈ Ȍ-JA1'rDY$ESTC3O|HAn}Y4=0e iӧPHZ5TY:UXrJVlWfÞm-ܴq[7ڱs˖+W/~[ح`Bj j_6^tvas~Vg}'S9!Jge]u螐&jjzEQ#c#=%6#`ã4w ltJ(yFEuUwr̕G^]7ǵ$\ vJyR}?I-Z"V N.T 6˨΋.YG9шJ#Ĺ+~[(M`sԷ$4Sv)F9kH.qy͎7["GfWvMdva;PzԐ!T2"\p;ԅlTaWS 5U}/ؚRPX#ݤ%QJê[д*{, Ds1-  xH/lh^+2y8HQ4pO-hꃺ^"z7%6] .`{tQ=*ݥVKSOn#xt2OAءid3>o>MN΄qDHܑ2z+lflDnwi k]3~1x`1AmCDQ"&oC6v1ȧ'͢d%|Z32UiZS9rXHG8P I.V,qAJ]qu`E NpA,c;"|*b˛Q4pHc?Q}b_Cg?&Zjr%eXlEAjC$Ö"(qt)ߘABmpx*'ũmjb*qi0rfGQHiInXܠna VF%rND"$ct,2dj:F֙w% =. OR(EusKT:p%F1RK-iO3>6qn˳}L>>J$LID yL~NR$z$M"P!m⨯r\"rB!?M{hC QQA;Rl M*Er[QiQbKƫX=/~VKI;fEvⲟo :X戨H;= oilRب6Ve%eU(Q*Z7PوJ msH> kMRuNh>M7dzߊ[1M !s+nI'[g|  }jh:ڬ:uZ4/Q!cgc3c9{L <6s,d +Cv2)KV~򕣜d*oXìe1?. e!gPV3ż9qs|g=r^>ۺjGG6|Xm-LD֥wq[k jPoԘ֨&5KY/xTX+T}Κ׺5 "Ss#Jh=@z0=3Ů39@z֒pmyBm/59%S-Z{'XF읮^MOYwXza0c|zMcQROin!2|]"+=#Lm:m}NOѓEi ߃;ֺvśt|@'X[2F7jkOp ؃Hu"\6Emn>3<"EVAg"eW&[+or.un~VU||^4TQ*=QP hxSZ;{qC:̸n$gI oQIג Bތ1m:)@ m~z!?tV>>ֱ^QOJ)fMumvMN[LC "&蟈D@_TPu `~,%޾)I19_՚a`x1jPUPɖaQII Ɍ]5QJDN]KSh@0ܹ ѨNaCEQ"0آI葀wG/Dv^Maى޵p5\MU1͜m<ީKF * ; <*ZU%,Y }ȊvhJHUi%.%ȭM Cz& b ܴIkGj)ڤNlɱFկBSQ!ZĩmPϏ"l(y$5^aarx)SA EewTAA P,m[+L쎲dP] 5,ݔkHD.OX G)X|^؅um؀؁emA֞e֒-}؈-bXڂ($wl;bV*j]~H)*IV% q͍ ŎD+6jZꨉn 2n"}.H|#@.kꮄ"-] gbPFF)䆣Ǧ^I3$_]Qgvzhi\y/6AVotJU.RnU,o{)-. aW`e8i۷\q&脏J"pt [Yz !͵ (p~K*°moIʥTT ܡ"L8ԇX2L5!ucƢGq$'vN&w&1Q Vͧ)m}h/SQPΦ_T.E8\p)ܩ`"F%@GDRd_ ( Qqװ2n,* r{(0QnNmFZQ ń^!EfjuiCt\trx'8 ] V뙔Z1Y1*1%7-';o!h9\YբF*.15suD #}SME1s sN"ڝ]LOtD&DHkMr,qf8@wy` jӱg&S#5t/u*^ #K&ДSvcLh8җ[Hoj'ڊ|?^BfoIM2X},DsS2\0`Oܝp .:_6siwouz\o:;ҩ>qX,3"KYFӰTEy(c4v9T6% +qu2ɯOv}$Er=[JWRU+sx |\z-9H'l4P@iq#qګ^嫿Lt~a .Mut %uYMu+X{6]}w9jӰ*k_6]o]Ж e0 ]TUȣ8MRzu4e^ʧ5l?V'B|7;=MѤ#*:C:'"! Z P}$&E4W" ۟6e 0fxDGϓ|z38Ӿk(mõa[ !Ŭؚ׎ݭJۖ؄=-u7mgR+-zWs?YͿ? @M`DxB BLÅ+ZlxƎAFlHcȉMfD-*Ye͞Uk.-ڲokZs{Zr0ćbUtد0c9f7ǁ#OQ1߾< Ѹ TH$dһ%.;'qdJ*!$IIJMzLꪬJd܄V<ä`+>-嫰 T1-KBWQE t,F"JK.YU0|0U]UWZcMJ"mVa{ K^EX&KfhZso(2*&jlF0* D!}u-M\Ol^海^z97u eŀBwOWa A0-ޘc18cYKFdINe]8CfI^gaY>f.Z}~Y奇Ngsv槛Z髩fBk[h.N;6蟓&{gnV{1Fz\*ڤ艘T>t,@MP]v)A>;T^TAR):ݼJPG_/x߿ZSSWU1O33pz食>?{>>}_o_w_|U~뿿@{ğw/ 0*<} \ l EJ~Ÿ({R0,]*DΨ3"0 3 s%3sڵi4a!WlT@"t`?*jqYt-^qE.Q_ژF4bF:bcǂӕ9I XR LQnQ gW) v`*:`f0SŔܦtx,[DrAT0Ea1e &192*3g4eNS{c4XjfNm7GN R,N]QTDC%$sx r| rPvݡ/aEէSB1rvӜ\cIcS#MIjR>~4ғdNR´l`h-=oTӭ;|NzPjuu Wc %35Z/SΎPaM)Xjs5+)e "Ȕ;$ER LL`qzӠt$K|  @fTcTp3c0Yg1CswQP_py0o}Pp  o P p p P 0~ Ӑ p  p P0 p0 0b$,A RE!`+j?zM ~v8,A0΢%݂lȕlFG;NZ/CQ ,%YJdqYr%#wI4~HQYq%ǒ JPǼ`,2bʌ(o@11qr! R! !D 2AH+(#A2$Er$I$M$Q2%Ur%Y%]%a2&a0B&m&q2'ur'unGe**2ўґ(1$%12*L*r#+R+2F2Ƥ)1-XrIԲӲ-#.E-R..Kd 1[A2Zg(rMײ;?DD\hB@m=ALB@44?3`Jn5AF33b$Fْ7/8#0w7e,V28S/S88Ѐ:(.N)@0.R $=-nD=).p1R-%WT섮iG_0D*(Ҷs9S:3Ay:T9B3/X"t)4/=C҉ sIP;Snj>4( N)Mw.,6M_BkΎ0-A6SA^S!eL69%D}CJJ3B9BKtKKTCŴW:uRNBNǂIitB+ɎF#=7'ź<'#C>mGBTO7K9SQKEA7/t8CtAWU]1Fr1e*253JI-”TFeO uoT_ڶJĒ~*L O=UT.7.A/SU]TS.ɔU5UU<\~ E.)!D$P247R?>eA(6^"U$Z -|h?uO4 a gxNS=]QU\94^u]Gu/TCf;u\?^[vf]։nAVcDe? NQW?[(eG 0u4=eG-kL6wT<mɓtH󒂭a>82Te^ag{Vfgf7gvo]oT=Ttd_M[DDD83>vDlQ]e= aOsO1bGZ]b^MceYgwUg_pkvBww/ݕwWo4p}x[#eGyΑ*Cqij2?6dZ; 6w^nt%u4緶Rs:ZAQ.lvIKyop4]nxwpXM:G$xE̼* ~+PELl=R")G`PWau+E4.}^Bl,r Nv)7muwo}XUX^Kr7xX'b2pM2N$qB1L%&Ln8*>B_pȘ(t 8'2Tj˄(LFl2$c2~R%yV)k3y7Y/ٓCْ9טAGQYUSy[yYMMٕcYy{ٖW;C9ayqYewyyY٘ٛqŘEQ%<#kDr`YhSvװhUpdي Sِ yyG6G ٌC7=:X?hIMzU:Yڣ[WeKz97^Owq{uڦZڨmiZcg:}Zy:Z%z ˣXoNW!szil\ƒwhS6:ڤa(uw Lڊ_(7r(-e'a&;);q[1e35;/[-AAM;GW;Y7G[m;o9yy{۳go۷۸[u];{;{;;G T贃Xt2xYV:2Tezo(0p92 ӽoi:!W yKz#«[ub[V {z5|+3eĿUU9gg<1<DžydA*)$Gvv [vi٘-PcT32E&Y-%TB( VcR6Qqy'1מ|} (9hV:Zh|U"J(NJiVioYVݩTzR J*jY ઇ6zkrJܥZ=)aJuVZ5Um^ascR~ mUN&(F.%m *v:R: E.ţgOb29 uP4 Nvt0ɔ:Pgn>[gAD#Eh2"G,0Cabp򸔪3Tj̦Fy>ߔ(2 'S؊%MuKHI(`@'u@'IPuV*3تȕ%71}\'%$nE$T&(IqVPu@kM󷧤եR5Ԯ׹`ժphկ>n[Y5Wa uIe~&*RM% m[PI%ڔL:%Zy+8{Օ:\4WL-anL\(ǹ1VbW"4rt]>8$[ ]L˛V0E  Ua2 C9éC%.U~NHAeHC.]4\+/4tMahTk=M^ڦ6Um?K7@4y[=ePW\N)~25A\fk? Ŷ.ZS&!{ m"Њ_-o?&T,s+@H vzW@SN%KǤ@_LP"%WKD_)|S/8@Yǝ|1"Rɩ;W ɟVzwA53%ukғ&:z6Nǝ+Nlq5.%A"~}N.B^P9:@GP6. %.ENo^^`nv6?R_!^iއX~#`.\aG\ݜH]~].~^瞾ߦq^j>N䦞~nNx<>#f>l-N뺉Ҟ E.~魮e~-x^ǎ/ > ^^ P3 ?e>㤾n_C+^پ .|fN>EV_@R_~LE/~޷iM\Z?q=/n^]b?f,l_0N+.vo8=O^J>d>Q?oZG=/or_!oa]sObj/@~8_ހ\@\۟ׯֿY_??O_?\d!!p` f0C\81"(:XQ!B?Nd0"GrLx*%\ّƉ9 ^ɒeł1c̩Q=ODM.F)RƖ%Ҕ'QT2ę4gӤC#.-cH43ZxU N?}uZgu*X.WXW+H[R`dlS]<2 СE&]iԩUfkرeϦ]mܹuo'^x;PKAuwPKE-Pictures/100000000000004C0000004CB55E472B.gif}GIF87aLL,LLڋsؼ|fji V\ҏ=O| qg"Bs/e;rqư=1M׭z3 Ƿ'W4X&7ו$ٷYGRD6*g9%ZCj CFw+KSXK[{k9a kž*\\,luK48 |=܈辻..<Ϩo{|-1HmCm{q.u 8A9Y˝bL~De@\D2=y0m>%RH&ʛ䡎XJ,BEDDwč9VQgD '5䇎KOzjbI$"tTe˩RdB4F,h-.,0 ǪmddDDZ/ɤ279$B|jջTF?|tvt 1עNj0D20ϳoU3DFNxt215䨴Ĉ\,l\zTgUTnlm3WKT$<̤֨l|xx~lK=0hҼه[P\^\wi4Dd<>DԒ]׫;ك;Tσœ7=AϫW.~ٻo~w_^X~!蟃 .h  (aN(r_Z#f VH&z""aθbc0x-c4#=Y;HLO* _y %<.՘-Dff&%CgvBkfdAtʉh&ni{ڧ"Zֹ需I2)J饚Z'&izꤣZjj멲ZkI&wyF+Vkfv+k覫+܁ITxͫ,lg{wsxG,WlKwT $l]z@4l83T@dfc?;t(\G sm TSMm z2l ^wM-o;l6 si)F4x7A=7wtǷe@VmY-"-b(;޵_f砇.륛!fxzy}wmިӮ,ܽ0w*O =v'?vd7<^hm[w_^W@vwXeeƒ7A t)O]^x5@ kC29Q.sh9 OZt mv8+Yqi}ޏK@mz <"r/TD%x3xZX̢լjuꓓZ1v #jpqXNΎx QDF:[T,?i-&IA DbWl5#-GeLX X_3t WG;z3e9G\Ʊ\w9rb %;P~L)[X-{`L1h>Xpo܆;Vxv3k(>AX6qi|hA3Zш~t_LHҎt)DOӋ43 Pҧ&59=jVZҦ^5Q-kXӺӶV5Ej^zשv[=k];¾}^6kli{ nsΟs{{ nrWN7םgpsl I[6wo9w?8Np7xpG /8'.wGEqo'y!n/|//yS\.ǹes|9g9w<7Us\POԟ>G2?[`,뙼@]Xn1!-wݼvw1}Gt>xyGx7{W|1yk'=ч7EOգ'x}u_OOd$v6uVI<YZ|xћ#}7?~~˽'Gg~WȀ h(X(Hh8*8whGnb*6gclV^;qw%dvuow~ogEI~GuuńQKU8~OƧWx']_ȅSahkehyT؆j8Ev؄u8q8l؇xLJiho;Fy((8臒؈h hX_8ow(r2bg|eB(c7^P%cvbd x~օ2,&_ȅH^pbsF8ii،Ҙdȸp188X؎(88hc(Hh;x ِIvbZ}}Zȑk&a^xb<& L@^bnz< mm" ^@}D9c1ה*Vg*,OI-5Wpi2ؓ6]3xF ! ] [9iΨ[ؘ d~RwuIL9Y}QW8I8Xv_iy9əkxYG(w8jhnƅ680SgVpׂfxj|ߗb|i˙ 90 ϵŊ0ț↜՗')%7 0^P_7f@vb g)wX^yvIbnz*[)gQH?|jɡbp!t֡69z%:+:_& 2*J9z<ʢ*Z&>]isvC^O wnw~9^İlP1Y{P?0 M W X  P p&u )P|mȡ nU*` j U &pZh =pm`x P )SWzj8`&@ yKX m b mx0ɐlʘҩs:^UZ P ɦrF^&}ui]i]Z[ cj暭[\*J xzz׊jlF:슰ڭZzYh/ؔǡ*zy']iqo@ ѐ `K*)g&Hp0 o%&`n,u^9p`^4v <ɵmP,/0g8^/ ΐ P@X@Xɓ~ ,0PX $*Y= X` H˷1 PΰuVcP0PJCh5Hf8HǺ4Ȟg)jkvk_zv\چ;[˻k|ۺ]̫%iynvUa^tY `l`|Bb1)ҹ~ `Ș[0du2ۅ>[l o[9p U Š+g$e q8L@f Ԡ V pab' (qk{Ŧo[qYWL]lc pa_^j`bsuLe,on,p}|,+Ƅ قKxHYn.w?R&(`kPHs-`1<{vM @^ɟɒմ) uX[KZg\LKƈz^JK uΙ\@ V cOI^@rDzA=`ZНI ڠ5v< ˹ڟܘ\܂[z=h gN8 < } =Ѣl -}]$&(Y~|,h؆e"bg}!-t&"pŹ\Pvbb@m`ܠp*:8}zQőbMp-xdgւx}Xp<`A(]p:Y myؘ10ip(jLih5i}T˱[~۹K'g͝og{۷ɽ0pvMͭнݍ❱y78[:XB13oH< Zvc7nL7l-ʤƙn>]:}9rmzׂgKk+&..ޡ|d _4W=5]r6^8.[xvA^@B~DCH0ㆸ58V;[&ꄏgըf2nu1xj4xʰ5wVҠw {~ݐC&>޴yvl( NkI ӧH9W꟞꤮>l릶.밞K =~gv^g|}ۤFy3ʞ(>pJ4=>'jFj::Zh *!}N\  ķyyy"!/#Zw$Z>5lr>-Y985F5&/Pޜ}txxl{˝M/͕1|_x䍣< N ins_qigK.ӯ~_ ?xokĹ}hS_> wx],,֤ԕ/q vj5ü}UyGl9ߝ? t`@ {1ak.]]&{ s-wcjzN8\-YkVw:qdF$dXܺ6W `TEFbQȂʭmMXV4A䘋' 'ƚss #G屎{ciGܸя^I=Dll 8rzYlnnKX(3gl ^n=7THl1WilNu@HYKUB<(+˗7;PR*nz%kkch]b4-A]ogiO}5?O>3'A:Ѓ,r&NeP S5 [`[)wH2!eԥXJeRT0]Me S޴?KcӡԦ0)Qg:S,iNԥBUESҞ4BVԟթI<0uouBHFOC52aT4qb)awT㛳EWC\7e~سeA[,f->7ͬq6 ZՊ6t?&hhimhhL%Cs@nrK΁U.t\NɥnsKj׺ͮt{].t^Wunz;^7nt0vٛUb'*ք%qdi-vۡ9E9[DT4c1beɉC[bź؋X  Nr*Yn4I!C@0/w+J.{;_ѕ;e)5s^(c3g:냿 [`ő0+³Pp0 :.6SKOW:'R^jl~q j'^M3jԜ:sj55Uzl\ Rd0.A:i|16{l^0aɽ]kwΝvxj3wk6r,nu÷vw k3 X}S 0/ǩ/K2ev.2=\/䁒:"D9 16\rq+/ͱڡ=R}؜ (=;o"JNSڰ k̵s0tT:ungz]v{׭vӻnz6;y֕w᥻y&3yyblq7QpNdY#xsK |*؃F,x`;DaYns g <b,JҼ61Ag(Fx_c7HOw7RdHńuᢰP:j;cy#@1ۺ@z @j; D $/J@/Ke9>6x(cjݢYn bi+R:1Qooy{y( c^bh`-TK0d$t(3t)¥9~0&=-Cg٭wr&($SR!]2Fi'\@:;;# ;ETT LXDWT;<`@£b.(9 ȳP&8r"{Hm$3m ~0G,h* q9 ?ɓ`b"h# ?hX?V 8˜Xk 63 GF $ 8ǂ6dS3p6(r GyhrŽ"H29#1,$p5ӳy設M ؋[%wJ*=H&BᙥtM<8.,;Ӻm[Ŵ@YEc[Y([lLʜdO\aD;d4;Ь$3K99> Fy; kHdeJP|B8l\N*dNNt褀8 pN3yqT M$Q3c5C߻B\0`0YB%HD a"Q2pdx6 ERD;[O[6WVDE EX[L4D3a;L`d.83 hMIԂ̈*O{P`BoPOjZJ3jB"HVE-CO@QǬ hdh- a PBa-dxvPCV0Qd 6rQnykUC<3P!|肀|C=IŒŠ a0(9"ʖk E%xb؆1v2& "h]&!řʁqai\_\\A@AERTAL_lscAϤ6Fc@҄AdiڐMdUb؃MLvxõm sR 'c ;hɶ6O곁 Q@QB(\=^ЉWp%ռ Иh'RqЁ6xK۳[~a -K\ E; U=C;ҽӿ 襒σKo&e XXhb¸gy6^ES̯_SԱ@%TEŜ/.3AvTEU`+7/KMI+(XF=F V)4R/4)O}\'n0bH\ փWp<~dyx8"HFr`OU 6UW˫W`BOM]pS ]@#J33괶ԜҢk/3@ @dxMHco؀C`R聍ŀwJ0 `dN -yh[pe[xp`RX߹erAeY>E Ya[dL;LZdEVEm@\tjLĔT/U;oV<4FEFJ;,L\k9T5ܑ*VѨ'ͅbDPQ3hDW= +w]gpK늅U|\z.s[e)DQ(È;Lb2A3yMpdX}ddM06؄hhqxUNU6jiNXH,X"s )9ӯsbtr` L'CKTUq>2.Ͱ@ݣKh@ #!([IR:nșQu. x ѹ\>–) ZAJ\?jq.TC,DV1, SٹRZ$))|6ȁND؂y`QP`o`B뽔=of"5(_&t2x;Po_6y;ov+go.fL6Z}p } 2)m) Ӻd^9+m~5 Mb(lU O[~ ^\K(zFDgg'Ѡ!,#q_ҡxd:hd_́LV0+ Xr!^fs4O&h9:c9*q:p߻VF;1[tHEot6vkOg//2BuVSSoV_Su"Yuubu];YXVbō3^v[ve bWwu]Od_v!GfGn]PWvruog6`(^^o76W%qاM4 tfCk t3N.k_p DuAj@pe23/5+`6/v2KzJG/YU1K3>lc_Ƭ_k1M?v-tw2wZU22Ơu0!E"G: -'qxq0?9(Hޑ߽RQ6j:V<ŪKTeUOfAXTuO?Fͮ3<7g3ug~<>>P //tƉb|_d*mQI`&d†$C;i`!#pb8=2nx0"d#L؆aD}RbDM!{lCT&7E*4̦+4jTK tӡLE-;tңitYW2WVPj:.۹armTmJ\xw\3Gd s|ݙiϟWfݚ4lTT,5ܴ[߾M5ձ]8nā/E/3%ёGu&ӘWTct+v܃: w+#yɋ55NmXdww]v|$SsECӃZ{iWW/qAd]7aDQ0@L_: uWw5&bp1Z%Y\_ŗV;"`9*#4aZhY`*fZu`W5rDT6fFYo@ڠڡui kj)k~JZr&ry*j*UބS{ 8!^qZ[.>w*@Z]Hw(*]e%}2HJQkGg%e/E!hY[""U%T%VfSy5$?9f_UaU^&%]rIXj=yuTTP#ewٝ9mm3j֨ζsvik~ iӶzuq*פAꩦm9kckٗ̇cX"5cHefQe9LRX}WҌ8Lc{جIws|ݗOzH~уlc7wRh%_پnTMnavs5yyefZ<:cCުxf:TwrZs2|浢]mO'j}թ-,E?}; XMU LOqm^3$5WIʌ`^Ib+Ġ2hr3xtaePaTlE-l(tK20+йW&<VVl $#9Be-k%JEzez%(vR*-ۑHز<4+Բ;%&+WPFgǑ%,)#R>1u+dH S.1dRBiSͨȢ~#hBv@L/i3(a9 R՜!]1,R2uKL"^2bQz 9PC, ^8 GDu#Ą6Oh_ #&؁ K` )@뚃|'ġ/#̱.%|61[9BecːK[җ4.)Le Ӛt-)K{ӛ1)O:TtJTQ^1;)^g#ђC={d1;fGπ 7L 0j+ԐvW jżoPQtfY*FsL5M r~1 h)@@ JH1!>DKZqRY,ʸX"A6 6Zi쎴JηK!e]m%G!Q$1ssūf]zrJ~'6a /}{_}_x%pL/xc=epT2JQs$!󽐔;jUɕM(_5jҒƿ¤T"&l1/^MkQA/ d=CV\@%,qCAy0aIU}$,Dh3Lnk'Jha]0΄S]"td0K,}x$|ӈ62]Z8 (QᶤQ:qD@*Q#^ XчC8ޮ}K(l#${^9>dQ%q)y9?ji#2mQ5Z%9E1؀&1/XLMЁAUȮ;i,W;vʄ [ q;}(ڪ b0` R xsŜMѹj2!(-:׊) wFOAرA}az; YIbN' ^& Ͻ'Z3f5 3,$  mكP q@[O2Xc  R mHLVN aUDNE\6y[ sISpH1pAC1h X 4-S2$)R܌Y]$^HH酙L[*dZ^Mm^e r-iP՝RHHE>$ĭ9>(Q8qau0q@!"K VLPXH΅$h"x>\I'⮌"崄ɐR,΢P}GuX,ZZXUۄu!J|c# 23F:1яiN\ՈL u=L N=ddAe [^C 1 !bI1%uʼnX5A:SM%J \׆~TA @ABМZ]Y2āxAxAzYUTDBQQeS*I?%\YOYZZ>" nY%`B]̆x:">" }(=V ֞e`'Ŵ] ̓b:Ld&Bd^gxuR +ũi\dtEMtѣeAםaɗ'xxxḀ=a'XQAM\r\\G_pQ~g30QPHO3P5ÎlX5[ @`aJjnچɚ0MEͦ ɖ,,&bJ)ռʤcO؇tq܂Q|Y %T(PNbJrݗQU((V ̂@Q SP_:hل D:|XAm-mB@%|Э­Z򄐶 G}䊮-dLD:Ct&DrBG`6sڞ4e޷VQD8 4Tu aR;NTN| O q aX8Mj< pTTM֢+oJʛde@Y<,RLJD(Q 2A'AOXWat(0 װS XZK Zxp-0Þ ʰ jVCifI*:%g1 [.bB)#x wC;qH0,4pF2A ; x L 7+7aJg JoBs16OD Q5BdB4eMj^ fèԘmn98\Mͣ\yoo-0a  `\ Md50J0W2l xA0 A|'VG.ZxnFqIvU1( v{xBaOH(=ưpFpxua oF AGwWv%vUzF L!C2$/$L2bQo JԖmFj(@!A('t6PDFoxز\uED ȑQMӂT l+p@7MGXceo5f*U +\V< G/J1dr/fi05a]3Pg,ӑBڲháC"f}xn老MNYM@AF,\7vbm0bĠ^>`O+3 [wdvRG4}[{4,w_y3[wDK|7Tp((7@C2oU8J| $S7P|̆kLп)ؤ;O8%Qr@(4#T@+r8@OK?D7aRW!-[ ֣r`%.MsА]2S SХ,U4jn/i))ƀ2Ph}K)^q֥4%iD+ .z]1{iW< c:(x)YYZGˠ[L$4$1uŐ.H!ԝhpP1C$;y#oF;׀u)!aO[ptq@[\ CC28X0HmbNI`tFh0 plG|`|fߛ1/ v$f5 ~c]t x@;̌ȂXY ,lq8r|W:w-csJ'h 0NƫԢ"R !lIЅzyyꊫ"1.킚;j( .̤T3̒K*Lڶ 3K*'kb u03"GLej˭>J+fBJn4RG8*;ǃ;8H\ZYdžZLkA&< -t#̼erl;úrZS41VJǟvkxpd{}mzjCpFL9Z--6f5>'wO.;JMP #AmqEНBqQ.Ss]: *PM6"N)Y$UtOm8$YS*:} ?Z%'qWK5 ȐCT<%o^9ÉvU=/*lF*DarYT]ɌA9#k{[:M6$z@(5c.*;n$h؋uL2^I~C6^Ya8D'lxt` AIK|ZʷL4@nm6VbHEhu:9`fJuU.1X -c^قҿɐVBᛀg&Ёr&Hu-DeVH z6hCش*L W! B򢦅*C Vl"7TtS6&YuZbOtN0P,2m1UN(Amū-`7U PX} EM2ug>sf,BݎbR ֚S+ Yv*DA6c–vcW_ : Iٶ:(._g!#h*B3HR71OŚW;ʤUP׃e n:Qn75x]=oy we/yZTrm#Է6mQ]5̑qW#q3O)bѩ[yЃ )O`Jʜf ~ -wN̩TP#lnWUȼE16}Px,dKdi0*Ցצ'AJJ'6[1Py)AL2LYñ:G5(Ύ} x0oاG|}TXjC#l~)9 Pu<oJ#äf`bf'iiH&q!Z5pR'/*(mU'ke)bR(dJ$D)y|(d)2- q'}' )s*rR,'%&K*M,2'2,2&դܐrQ0OR*YB0@h6JJi* @n\$Ziܭ3 gL kIն@8.#l0ѯ%`GG%9'N0Ѝ)˘9'n#n9S:9-R : -H S Ӡ6PƠB,XHQj;MLQjdA?632tAˌ,!7ȪYj 7N2Ghb:e*<&"k0O0AS"}6#Ć\$sh24`0,peT "eQH/ IIoq.IOb8II/CQJTJ+Z(TK4N OґO~Ijh:3 ʠC,&B鲫ΰ Ei g S#?5$1 Omd-F# svbЏQl Kn@e .CEУACZT=>X5H/Pzr$kZe8vXoBb}ɌL0"&TAw fd4*?٦vĎbcD%"vUktU10FO ps\Q5B&ɺBP+r).b-mh+IzU*oRhJ)Vf6,&a)fu+)V*g$Mfǒiv,M0f'V-+V#R0Qqdw35GV7FXr3&DB U6`p2ޤT`x ,u|PD"wH$l復qNTWJ64dS̓I#pn$ T7-N{:%+>z@0L:9˚ڌlLhz:}:#N:z}7;_v&fs#zs0mx`*CX. fvtu7vn3_%` a HaV!@D7 _>S~EqjrncqT?RTk3WSuA D,5 ^0i, 6Qw E2d7iM }, -~iZ乜x}<&EhR`VJNl]`V5/3 $`6!JtEdvU1mލ :JaD 6B!6 :4#n䡕ߠlAj*6oaiQpsYT5c _9ȞdSE$UtUO0z3։K(s7Bj*PI@ jB!{ " D4fG_z"z^@sm"kxOuOx#6$]3A:RF󠻴l"x@ A|IK49~ :J;p cb+a:; b87 -{!a#HR~!=N= |KeyVkd` !0J`aL `bZ2r@(C  aU {U~˜*.:j`"jab _\)_ῑrܰWW%IS3 A)TQr qA*cS֜ԑMa+N:@ |b`.PD UNyo H8ݬ* 8 2Y*Kɶp #mL;y~)Fnd]FB&4d໩T^7w6X X (at @Kr@Vf(Kd&d@ a + dΩd@A9,^$0N=",`3g΂ pS$K<ذS2_05V%*kNVlpB o n 'Mg]@N 'n`ܘl 'D'TפW(D`"5:iWF^8bwŷf X[91b? 2@ꇇc{5P aD `'$ bf؈m4IÑU6ܮuӾ>E* S,$wO\` 8 `(A)Pwf.xJ~Dž[x&a`|m` Oro0Үѧs ?݂1vPo j!B:rEc"\gλ؀a'D!Hz T! [;>Ka1`!8~u穝8%b9jV5޺x<(z nb"6wy Μ;%[6ʜ%Z89@0nQǑ;RI2F,CrlQK"WҌYHGC9㓌>-3 X] =8po^dMrڦqrpGڢAÎI4[@iWn[mʵ{[LM&NQ0Zr"VJ_PEA8s 7mZԀ(l*Ac zWD[yΫ/ksqD&sΛ.a4I~,^z%\g.z6mP;[mYGWWF`BB@#Lݕ^N9"F$e7bz'X",Hbd#sT1h< =XdG2 0qcAZ&-PW eq=@ VXGiC!Yܡ<@%~ɩyԐF{1_xf|uTR@ȥTs poMZiA'c&|kEjtl){E-K۱]٭HN5hcJ‚DpV\'|m0ny)^Z5[m~Vځe)ĐC28N[" ʊM+61R:~ޙDDDE=,eme(.+AGaVZ f΃9!f\bŎ]#H>KC>^p:ZyYS< ]T dqhP_O*Mܪ)a )F&j{]LvDvySL^r9ޫ贮>}r[-_%ڂm{%-U^>o(#9軿?[#l03Lfgbdq- ,E`h&WUd` ;bu@X'sP}L׃AQ=Z2Ҕ :|/ bO_a)iB_ppfDA8 S(ʅA{@4̆),"t*o%`IHh$95+`)Y%6M.*ж-m+cD)C&^pFX@c bYH=.z܉S
7 1%h@W"%ʡ0C _ %-a ,ߘb@\C+Hw)Z_fǸ2qF&t՚G͂x Df 2^5p\c+~\1RaWdmcvɋY iV*c5qלA`decUt}CZЄNGhGz҈4)iK+ t5iF_窛tNmNg \SMn@*4zB3+q2c\C\:o)t kVmFh(W{q.JG,;GNZ:cיaCTE2r߽?.'FÐ*[G$pfV+LBC6 O2dԭ1aP/ٔAR^o!|/P`l-1C<K$N22[tK RD߳  bh3(/%}^W\8x,_8Bi#ful5k6jB9{-+:Rr?j'kXR*$ G9542w!Ė<\Tml9=H[dH\w'`3Rawy(%.c(D&8%Y@@NcHc~Y5  ڡ7+@uSp {":{H^“7[ y+hoG  P o &@Pم~.evg5˃w>{QRTDqؘh7kAb%dW &ЮtN}a?Dp-^'DB́:#i:*E#vqjw3u.2ʹ) bTt y ԉRBC]Ɲj7-"(; |ŠNxg7 m Žz$xC[qŒm@qT0Ҽ IQm8xUlEH`uV3CHbֈgd!zxjZG#H{ZװzRJ'_{ե}QrXW3Tq 9$w6jrVC:Z X^p})t{F#7rD+Ԩ0a &`` ɀjsxk16!Iˋmv<ѵ0si>'q%a7bCg7mk\!*N$s.@5l׊)O\A=c޻l#;8{} Ƕ:8=n>u \=L&K+b[A! A]EkKGzAZ)ۊZxµ9o۴EQ(K4s\>Nf[/S‚ץlF7,Эm>g= nA`E9]ގg!w ףj<]xsn&qnRU"m~ bώjODώM4oϡR /5N1oxBȋ9^ɯ- < ]>)?QA (Dtb:u!i!ςų,{Im^ƳwQ#d "7  2q'bĸQcǏ R̨1dG&=LFAF1Wr4QANJ顓ě07v Zǎ(1GE*-<>[}@5;WyVu_ ](Mhh;( ZjZkV[mvk[rw\q jmZ'\jŕvm[yw[Uwuw v\^8 {Ҍ9fM,6"d>/05s@^-?3lQ3̄>f #u;YWcoX]5>zzctc<=<ԗ1e`Eu#\B,] $NŚJI SDUIdPT+=Bv3}M7?oVKs egϖ]*nPPWfnЊM 4c>봴1!-el%McD.9NSPjb|t%=ۧRϿ'1+Bqdh6TLH&wqJtR;.}}`ަ|g5%J5thݞ_,ۖf1gq֦ uOKYROBK HG\Q4Ο(zf-$mf̢ ŬVR7~MdP:>z} 9TII *_Y>msZAȆ-WSYa5je)0 6vCqd.'yNgY]l[\:F]=LUͽqf*>ѷNt(YrbjTv49pi* i9ҹLgPঢhv/ ۍ(L)Z =)2mefk)omhvH`=OzWv6 |NZ[M)k7JsoU5\63Ԫ6[NN%x+ y fMh獷*eJ%5W{ʞ.qp 53໦h獎ڜ}ppbP{|ij&>weKWi7vܤL"|={XmWuʲł&3r}e&R1^>kD2 &HωN,m@}41){` Psޛ-esx8"JxB6ގz7I^x^"&.˳gCO.e\6t>39u 7;3: b+.2Le۷S0`a+1z/j->8H8j>Fᭇk.l1yh ;c0 ~HOpr@dІ387(mu|y{.j!C/C/dHEhv؃'$Hkqd" V0+B-h1C qaD/̗2\DtHsEFtiyDDE.G| E1BJćaE4lQDSL/DXŃAEiEDHyQENEkJDCtDKr-|KTFbDvaĀEpHa4ma|d flT\LCh󩃀Iqhp }O,5B;/z O2ECH x BKH^P#€D>0*q@t2?(Ӌ'8S>l L\hRH0"%bp |+.cc?կE0rTI@:7ҙb+NU93 TS8UK4;8f 92'›e8TڰNy/D'C$l@ AМь"pyy$Ln0,R+8?QP3DS;UFKH)S-q aKqm'PȾ~L8`Wċњ';C@˶:9-/ڬ569.T⤼;Z)K=AYE! fN22K$%-U¥b]:=1YxbO+H.>{B-#$ȿW]B:ucdU iDe$" IB{6cL2J&" <t4aUU3 5 PZ8AUͲX֣[-3nj%UU*m!.K.JQ\8 s@yτߚ]"V;AM,){_S-5="] V3N3\.Ͻ@)&ʧ)=Z=|_N39Z׊B:&v]? 60 ܵ{بFuט0XtճS\I)^:㰿OŢВY -~PSVbS} T/Lޅ-Dn B*8P\Rҷl]¿$[նmTp>&/o+P<TbՈR.[.US:B~8Gb$1Q1 Z;#T*8{0K+*u dp:}T^ KVX)3 "VCݔ!3풵c}Q'k4O,M]I z3ĭ+T:RNjM=%]OS,I.C1M?b(!1CQJ1QF)*@**{ǰfD䓺X]yI2>;*+]q:@N [,1]Gw."~ijffjjd];ajkk.k>kNk>j Xkkk>jkkk lNl^캞 d1ci 89jmvjNmԦ^mFj؉ 5m xlmVkpk*n^.fn^.n.nȮnfnڌs\;0<m(mvjvNnmF֮m}fj,jCNoOnp9p p/0_q&qgq.nk/q(%R(f YrȰ/pv՞&7+m(r)r.GVܚq4'^w8Owqplw9;gs9q? @p&tAlEWޤ @8SWM>j0WmoS/mQ/.,> eKֹCuvquDsq _cvm0fWvd`GGlw= 3_`-wrx_uN)r,grԆwgj1wQ-䉖vj?5q<\ggDgx_xx=ox @x3?w q>#K-t%*) 1pSgT|oS/oW?G/y40ylv?Gvlgq7v {O@jH)޽x[wwOw(Rw! xu {e?}u_[o}קsN1 mx逇L/~ky'zwG|?vuoteX4ُ}~Oq/pgnt-1 }) \E^C ڠzЧ @P_ )@9(p E'NQF#jQ#8bG+{ܡ儚6o̩s'Ϟ> *F"MTiNBJT*ժV]MΛ͆'MgC2Mށw<;6$I1b`"N8aE(':/2䐏g`۽T䚬 ߖ&L:5ծ[^ ;vٴmߦkݬ}[6Ň.yp̛~8έ_=;sk/xw=6dĂ>kٞBqPqRJ AĘBA_GUtd%EZ-VL'!ʭ^l-"F#q.c:cr8hCdcGiqN>#tKVWɄe}e%ZE"_st3;fVi3IVeuC)&XGE6die~ZmybgkL0RQN:YZ)")dfLꨡڪSʪ*+vXaAz~(}vkhfy$E-w.8af f^!Ed +[mx꭪j~*oڻ/o̩+0~1ǰ,)Lg .Ȗ@nwb`jќ]4'>EzQ蚫MFtKCuJOtOcZ7,uÛ~=bp{Р9EUfTWW%.fɭߚi}H|T([iaS^)cWN`c9[oN]^y枾{s:~W4t1ȶlc4{̈́x͘{b C:Kuסop?o9[hwd)pgmxa-)6<$ˈ -qAp\и6(h(Fw! >y/|VZ ?u{zJỹ8!qy,'\H,3sX"&:Q|9AQE/j\b˸D3~eZZx+"h;1#?q$! ):C"2T"WgL#к Pm-T@R<%+MJT’t,SYᕦ.{ K^r%+Ճ]j ggМ&5jb&7En% h"vr~vW i`Q3'>wYLVӞ%p= U@ P2Ԕ%BЯz+n )Iђ'M)K-7M!-c]AfX=(&d$@qƶW}(oWUSSݪRQOgUJܭnD#1Ab7DqL owk޽7Mn Wʉo{{_/[`rIXܨt-K\52}eL] C{y\*ut%zwTM1SS6W=ˁ8ۅ%.&"ӆI/;d%/ɫleAe(;2+u%,CKղd Н'^:բͪC9P5(TTH_T 4D_Yy/?dW3R3s̢ui1^>uVԥ_-Zú TuA>D1S +1eWzժε_<~BAZt0>eĞ/;4v}k]ۚFn-:m{[ߴ^5 ftO]kWن oOؗcmeErZx]1J]~vR},w/1 &`ؕ<НuM_~Iz+9ѓUa:LeICK~xFx^"y~T[~VĻԧkN\T1,Glzm1-tS=?uث__}z>ocӣ{tL1KMONݘp9V]sْ)!Uء)TIR\Š_ `!`` ҭӰdFϹMM[,LD_q=ma ݶW՜uXl΁ƍ=  _!ҡ_a…_g4X%ŁUX]Ѝa2SXڝ VpB͝R*"AU+qٰ _aj_)"/&b/!1 _12c2`Zh(X}_{Ж д`nmT8?]1>ߩ\j ^TbN"":!."m ?32 b3$@"cD2$p#FJ㩓W\!J\b@LIp"(V5%D](ZW)A⁜XmW /.$0C6dA"DE:$R12CcE`4K5n[^;U!KL'6i!A-ZZ}"9~Ge$A`_f`x fa%xa"fb&a2&`djeX]ap顪F"jyzNS:3Aj]  IS̈́\ht4bljrכĎS^p*%)riaU xkr.WurҤjwcqxq^Q>m!-% 2֛nNN-& +w)I&рIHKܠc DQ@ퟝ;j>1L -z~!P.][].ymL@Z|eW皮Q I#۔x@gIr:$a s`%.'GBoD<.Duo͍~/r/o[Yyk/*NnAojXQwpj/#0.Z~ׯk/nno/p(pqpp c)4eZ,zh$KiNβp_d:$"⇡y(UAi_@܎B2ՐUWIc1Sg1w11kc11/.Y˱RQ3(rx pn/qR!1!O2/0q$kqC%qVp%w57prG2'r,1uo!q+%4QW>3#s@3Q$2[s=4Ak0B3oBr?/=2E34GCs?gtHtGGtJK)3pbGHsM4EsL3k4*"k4C1D UXS\VgKr ɣ+vߟ%9.. ^8ZLFNMO_u``6``ݱ)\raKpOc/)Gߵc߲#3^WqbB{j+6i6sBvie2hgkrf 'ic0rSvm[4 G 5yZi6 `"Ymusq6#6ǁ7kwLWylȸ[pJcM@/tQtO_;#>'8AtM#xj,KO8{YZxIS5LQtCڀ_tDwxPBO DwrExLwH_+M49id NP[cߡ<*q%Zp2Z<oy g2'_q9nyACAr2ts&9&:2 C鶢zqw sznXyg/r^6lgz:_3`:jsbz2#0wk'&Y!i9[b++(67{:~[8Osw7*)ոQL{=_2f{pcawo+hFjoW[òKr0K<; d۸vçOroe&Wv|fA{)67<ۻ(Cw0aj EKٚVJ4+VVgy˩v[Up,3_ eQ.nnn=n=뒎J 35H:'sȥ*)m7Ϥk8*5Wjm3|}=N0ʽ}>=SWQ r,} eg܄e kTLhY_9SY6[id_>zmzmSr?ͿU m_ע4xaB 6t)"L#͛sqc6=8r7/cls<́NdC'P*CDhҤA5РIB*ҡW R9 ըPwt;TF0n\sXo^{KP߼ s/[1cȑH9nc̃4Sy2fˊA|ujիH#*ɦMk9&1slkr^"u(RνR\C}=ySoo7Y.})b|ׇX~~#| <0tHF9X c&x`Ò(Bd昃 O\]TWUsuܱFOL C`Dܚ&|(*,,-0S1<4,D6|8i$-f;!7vdn#6t7+;I($4N;24;:utH@e"hWb͕\wu#?{ $ /bi՘dnI Zj,%U4o%ԟj]r@ZՑ^[+a7@[x@ >>^"imXM_ ѭHn  k+ɋ %J]IV)X6u]R5+UafHࡍ(裕(饍nA:iN S" 7eyZoi fGO=WS;ƓTo[IQf5d wWN[/#4 2)ܴq-s5/C\4sNp2j³ x!+Im;Nm1M]oevS6^'V'HLȏҟo}HΧ_'M璘~ >!_?2}C`!X Y0R#{֚p`ݥ*0c W B$nZ OA宮mB`CQp!!81~LL !(> "8'O`bx1_,Bh5*oLHSD@Dmrci 8Y@d CE:?1>e32rY-nBÈ]TRZ~*Uy'ES9UҌ,w)VTe/K8Ҙ$,-Ӗ<&4K62$+KmN&Nsr<'0YqS7ItS'Bh}ӟ,fls'݀$-${R zp;_EwCM2O,l wУ9alZyKh 'i3t?i4Ӝ?eQˡԞFujSUʏRjR@h)U֥zdYUZ_Z֫\j[U~S+SZX1bj^{X2v{]bbيĚ+d1KrBYL0yvCJXbId"⍆׉$&CFgbz 5F @KK޲-Huw]jjtZ]rӻŮN[¤7m^|v_7=N.XxkC0E{ߜXq_g6z΅3AЋFt)HҔγ5-S&͘p7=Fԗ~;Y՜>uC{yx4%D7TR?m69 TW s ޞ:q eUG: /ЛʘCb;/~n»vpavMo/ o wp}'\w9n 7:r3<'yq;);oH4w8IN2"J\i6ިJ\ըG)qzɚbWIIs9ʢWzE6/YۗeY\ַVio3`+ֺz{u~]ýw;_ʶf;W7^/8|"E=*#$T8FZbB4lP)Z*T*vkɪ9K"-\F~pjHU(Ȉ HP }ȕP  } p Ͱ|Ȱ 6J7l #TKPpc^+-lTR,Rp,)p ;o9BB~vhoA  1p Ő7~.1? Eq3ԈM}HqTQ RBhG %HQ.Bx8$l& nQ:p%T\ޅzXM%oJQt#$~&ȁQ( ݧ0dQQƑ1쑀qH>&UDBr$zcVeP c" -l\fZ d&C)en͑JR\-\NapZuRsfqlqtT&y'k''uLG&/$(]q&w(Rs))BhAb$rxJZdpV,yLobn0lF%ߥTÄxb#ih0&0 00D_$2K'tlBʭwb^`=bdF83HXdFHGn3uFxGR5[+'$+a6kNLlS7wL؄78$78s|8mUIr1a<$Ș' hQ$;撒ö0jmGn:tA01XR>&>W?oE?c\BbZrYh6V wP ,d=d8 ;",&tTfچ %GoM(=NxNs?e>StaPEE_`fbAxv&CBl6T%.:B3n@rplj'Fe4`thKKT?”>*Db$|VKقvFEz z ڡq=w%恐p|&n[΃,ۨ;Vշfe4ykOG:" S%4YYZ@x6YLA3%pir/ i\usqt{R*jUci@!1Ktl{osw <-^\rA&WJm, 2Z ڳ6Z1G[!XP#ravztbiP-Ї;yt(^Al;:Jd5jV˒kMvVÄqvbSS#ۺ[.S]C0B'6rg2gpxMEk?ņbRO̷;)C23%yC{ |L >"%#b FU*Nqbgڢ5U3;Gl34=GD54ϹvbjIuK^\gkoyӿi[ tOvyi=F_K'l8<'^CQCRTQmTy](e|/>\ ̡CTp&ak7zl~ ȔQP%dgFyXX;;-Ԉ:[,1|u#WE6imx t\0$0jnvg~\z"FY6}G9j -dS* ێʭ֬{L7@R'av닷XSW^eZp o_sEͅiY6T^qgM"cF819i:{L:dMھ9z8]N&3wBTLmSyn_ A^L7Xzkzz_ H*\Ȱd= rlޜ6&q>>!GwsxhCc*@rMs d H@zѝNTZ@F23'ׄ79҄ Gc#:0 [mʍKݹwݫo޿|:<È+^̸Ɛ#Km՜fϝ, gӠQ>:u՞Z,,!+v2}6A3b2<4&É3'u_8(wU_i:Sn7JQSY{ijbqk@s$`e * 6!JhaF m  l"h$6@ "CaH5h<裌XFgAdQH%$#JT J,LwY\FyUEETW]GfObƇNbVERa2M?%SGD9d5fE \:(\"x袄"(6 i饕a馉!HHjꫮꐧ&So6D%C%LʹsQ!ݚq|ngg{}T^{&*QґdmhZƖ٨6λ0ڻ[ %VZӊ–*؊.Ƣ1Fl/N|wLpBs[oepfymm,1NJZuuTgRjI&SCMf0tf{}:ۑY2쵥-%m6deVg6;E9gD;DmLyGTĬVO4fŞw]ߞ%>E]{ܭyLQjDq铅ꝲbo7 nH|uI ݱURG~NN.`jռuQ{| Ji~^Yۑ›d:w ~'5 q}q$%J X颂F3[׊OpN{e}0qn<(rAkH W0 gHPw@ H"kFLAIUȂ5ItȔwa+AY ,aa'!jJr7ib_q-ݎ'Ovӛ(Us d?^*݉Hx)ofbq䪴~8,QT] ou,<$$.J y ;~d,g:΃-oCIi$dNI2}+ީ!< VflJğd,y*6jzFѐ]^Ej|wYdoy-i_wvf=ΙŹ#V!<;]ŢI! IipLNk@|S#z_~b'-^Gg tnhW›s|mnf9x%"zDWfaB; iDӵ];hɰ=YY U9 ɑ'\Jݡ;;k$o|ESc0g cZd)"$ {=38sH|bY#n/d~zH_oy"SGXzkld9>;{}xNiO6S}%}GΕz$Z1~*7%(q3581w8(}ԀqXБ7@r=Sl%i|)&u ]Me[RfEEwIz017Q&X\=6GiePPh'='rsrw|dXԆ!g(g6:z$;f$a)530kPU&F#fu+h'sCby5Z4e5=v=!BG aRDdd=0O6ru0GܘbdVbmdb%5ȍi<~72pՂz8Hz9H#Y?ۇ5 x?5m/@I!%98iUXTY'=y PF(˰2Y!9w%iQIwC;qq7+i'.d",2,l[bDb&vwZ-9MqVWIS9tU>>`m?EE-8SxT<fF[v|^#B`$yQ d>jhaN͘V1qS1%pÐՄHAy7y^rPZyI;tI;:w7Bt]Y6>3@33a=b9Wmtl5Ł>ybrF7}R`3XYp j}F!V2OG'8v8)hrV[æ]<;AQ :m-:1QHB̈#T,7qSn{%v,ǖE x^3?h-FOq'v gY 3JY%Հ6P5kwfћʒx9bJxiF\VuQZUwC~ٚ/m]ZY_Z37 $QXIuhafhbnO55|-zw4>#yQp=[gj6mzY[+wDH6ya]n|~'[La-tFmPRHs-g iBG석[n3ʈ5x7]%h?Z^X*PvWVSUoˉ|:>3Y醭_cƯ_Ӡq;DrV8ǫZ%UoaDAT(vPCWQ5 %[Sښ :O"*G~7,0UbVW HIy**x(+^;]T;jj@ўa^ʜoi!KxFSԕrYꯧƴ V 'K\k|u-FxSyz8Yƪk-PGdͨPYr[jt;YW]T,{Ɂ~[*#cGǦ9_H;j{0)$z?+IcIk*S9BJH=_"jcq2u\j >hED3R4A%(9GIigeY'e;( oƾbUt?,mmmOcY'sz*C-I_nL3ɓh",|GjPu:pEr74IZ6 UqQKS{awcA[x jybs)pIfXP"/WZ1i3VY۠,,J+f H|[EFBaR&8U88Zy\&GF -]Flπ/_/N" v$7ttt_\{l׸{e;V'p_Y醶Ha~ERǂ풄[ivz|KM㌿e)l~ad݁;s!,B=Qc P#%CrIIqZnRcʖKd &Gm,R3El3RM>UTU^ZPV]~ ViXe͞:Zmu˕h=i3nC1hPw`H去;DH3e'A)qȎ(%ϔ9N̠3ܬRfJ-rHޡ#[7ۭ}&pTGxr_'7g(t[A AxQ |ۨhcN1J?לlcN9#"k(lL7m9'\KB / .:,; 1x`(pv,X&B/$,1= Ԁ-"h p@ 12+)2-s/n@kzט,(<@#ث&^?F>--?!)Ȑ F +3)L;SP/57;ċ ;;c/B]q?^۵3F2m|FM Tn[.6<<BeBe6ohg(/d#_r˲r.4@NeۥeE' GPu\Δn2طH'km2ܫɓ'yr.5=xRYU퇄4W`{-m))XgM]#Hc\|<&ZE/ʊҹUZUV)tu;LMdg$ hk > 'f2޵=?Flku ė; A<)jF(,~tžm u ) *ƁBDK{(1*IR4r`DxDP60『n[TMnaorDب,/U2X7,, *ʦsҖw$|Pxh EH6*%}$0L-5V2 6EMTs)H@b'Bb㘈ϋH34c4"a#(Ϣu(*w;}KK0-F}N_ 1P>TH ]vf s)U~\&7@!!DH!|MBj%iJ{4L *H WvYzyĶڱI`S>a3ts"TyWA z?K@Z@l@h5WB#U!-ȥ;*ȫ ûӋ׉-{"p&dé 8%Y%X v b>b4~Y-;/JB,4X2ᓽA II.sӎ@y)8Xª>10lRħʸ b03tH r#}L Ʉlj\zh&"5ۑx3~JME2XJXLJnm 9J>yNp\rKHБ9{+L!yKм.t JMmMJΚ L9xw yc-$-4,2C ց,NlĦdI#qB (4AH43 At4;:D-CMe o$¼ P9Q8?jJܠp!ҌBJ≂Ŀ@٨i RqMżQЯH8iv4H/7˓cͧ11Dky@@;lZ1*Re2$Aڢڶ13Dm C#Wm Y I ]I -cj%T퀌*MB'ڻ[Q*K-$ ֳX+ICBk @WtJ+"JS.cR2ya1q0H ,k WU!JXR ]WKt#~;· ֣Z@es*Gc-gͭ1 Lj TBĖoE7y4 1 <,R܂$0lEAZ\].8ܥKQM&*萎UUz jy!HQC҅aK°bλj"R$I5Vhf臖>苆茞h莞>i&.6B>Viv阦i5gU()(dzg -ӯ#T l+" u#-Ff/&kv,>k.6kk붦k;z&l.FlVf켾ollv6N~̦˞^vk>3|KPu2됮ȭD$^6j1j$sƝ"DRj|v%^nfnnY.jݞnnnNn^ƭf&n^ooTnoo&/ouF4qizkp>d7}g-5mf7 4zq@6Fewgqqqoqqqjm"q##W$OjBxq!_r)O*+q+r,-g$).'s/G03Ws.77n  OZn2[u #$9z:cix6!׊gy6AkhiD&#'Qt?笅t#QRtv,q}i rFRupٞ\>eL#StMPvNGuR'T/fgg/qS_veGjOlmnvo?op'wU_8Fy 0-``tzM{W`|^tX_Y(xGx7xO?xYNw.mG멊w~xWx_7O_y/yy'xxy?yy/OyzyzOzGoyyyyzz{'zozYyz?w{x{{{|/|~w>s&ÞFťepdOd'/}'y ؗا׏}}GPO>@7d5 g}}_O}_yܿگ~}~~ܧx}7_oٟؿ (C` T ą%FX1EbQ#Ž!?IdG*KD9eJ2]fI;'yz$㐬M=2%jԩdIR" ;\6EPAagj堏Ϝi%*un[zk"`#10Q}VUjnJγZeņ/s^wgEBtԨWc`צE 6ۺ_o:l/N9wn;7tqK]}y#Vط{?O?9 R; 2mJ} r䮣hj .sS\d]&qE!^`)v;]R'.w!6@eL&׽zM@/L 'qF,"D$"G$%[08<݂R:&OE&>XR. N۔6=D0-(oQӔMTQ`X >i!Q&;∉\"$)Ho<mJʚ8桻X+CBhO4*s TR}1éPbjD:nc JO I4E.|&%)h&|d.Ǡ,/N*LU"qw9,B!`Mې3UVn=?wť{LE*0pҬ)kNE3 SUJs@)LF)<L|p1K6奉uS$lk2 cjNu6e8С!*4:bTUW&M&Ҟw/'W1-b*cJVz:u|x C7 ,/[.A6LY*no~χ{Vy0b:VtA.d]fS&S:S>uS}VȳvaoxtK|pLInu1Uw9K xj7=~І̫S~F U˚րC[`0-R&BVx):R<#;c;֣=ң;#;#<:<ޣ> d@#=df$lB*dB6$HREj$HN$@@$;fG@N$JdIIޤMIdLA&>dHd=$Bd?QdOL6NZ$GO%LndT*$O$SdJbdQ$M*RV%RL:J~X$K%[z%TQB[JeMe?$=2U&dEV yڥ楖7uI 2_ϕGgaa^A vh\^]8yӞ_z\AaUby &qކR%ЃWdEyh"S}^ڕ*i5iH]\j1pM- I^(jF&tN*I- jMAy꫄׭^-9k_8˦Q2 D=xj5I "".S )XI|5* 5JUY +l=(l+k&,l+k+k® 6l k+2,z,FVzJ,~ʂ,Zn,ʶɆ̪lNl:ln,ƶ(,>m:NRZmlԒljVlъmfՒ-vmՆm6,,r-,šffY}Y !n.SRnVn#l_fnBNr,n.ZƇ:}.y..nVnޮJ.Zνz"&onrYr.nj-on^/>n"Vޟ//Nՠ./n:o/^nO/뮮Bo~.pgspJcf־n*/0 sn xo0>,np,B /l/ 0z+n71 00 1qkzp^o¯#m1GVq c1qV [00l ".Ѫ!1+G01 "31!7P"qc1mvG&g)(_r* '/ @1 231;17345/5;2K133/77363734g4s7738Ws1_6w<:_9s5s8s>dz:3;[>t5S3BsB?<@??#s@3?'3E3>93E3s63C3IH;FEJ39GsK;42oFKMt1+s>tMt:?tA˴AN۳P3:GQKEGPGN7D/4L'uTw4HϴVGGg3UKsJ[V7IS3[5\ǵ\5]׵]5^^5__5``6aa6b'b/6c7c?6dGv];PKyAPKE-Pictures/100000000000029F000001A144C44A43.jpgiXY6!N I9"bJYH)"ieRd! DD P 1<BrRU9ׁ_^{^ZW@A>[d D `kw=zlmP .d!/laAGLn~6L6o% Ą(~|v\!!2_6^x)eْ,۰D+^ |-YlVY@_[dٲ˗X|1ÖoXqǁ+^Xꦃ7>^؋ΝC\V]cVM=z{[>byIS.\=<._GDGފOHL}/~zF<-|VT\^QI~Yhd75M_ 8efV2}E%eSA˗-_^KFa;x Wvzӱ_4u|ZZݦ]~So^u˖(l e({:vAGExZSOka!~K?Yi3IKjC܃k"6ljJl J@+{cr'-\%kNBxE$9L?ZEHm} uoR ]ң@;˵{X'm?ts4+>w$sQa&,c02XWfcMkR'2_U\Jz52B=ƼrȲ<9l)[94S\.a-&n@t!,0k rY8E[Y8 J4a\Vo{TiDZQųVQ8&:b8E}9~ mMDR#X\]Tvev)Ȝ#,"'c_gU/AaaTrlU!ߩA[/(k~uR4XM?QR6:Or8O7nbrXٿ)?Ga&_P}9R@,6\peo/ݡHy9)v:[KQCɑEJzˌ,f6⑃rIIGt|L )b0ט ݘoÉS_MX?ϛ揸? Uoy1o^8J/f)QGs%EtcD׬dͱ> T:X-ȋ(uί$_CtxNvfBXt7+B:jC* !9Ag!phPCh-> b\ٜAЮGj*. Ge9 41\YK.Fe%+d@KYZ6˸W<y^wRBR#Ac 96՘ K2܎/iGXv X4{sl*񬤃5hWG//=e Չ_u69Qͱ6{|v3~v*QLIHA\B4l; X\s >? n-d 면Q/8UˣڱtWq[ &[;`N$dٔ hM \g >)`[nG!Fia-;O]w|swf&3)@{{QZK~BV ЮHv(=6 Б TjIUokmX'̿]?[Z 6]^OB(ZpU }(Tp}OI :9O;Sgj!rT5us:l'1x W~}#xZA3|Ot#{2 fZP7\$@@"T<\[L[)d9aޠYͱʱ8Jl $9_v:RfinOee]]eD8[H'wJ-pԅd/t6&4< Fd-+7sBSLϢI7ta%^&9lP@b ޞwQoȇs硫Ń^pmcخp'0t6zd *Z\5EI| gbUem0Sj\ۂh>A˰nC!ݢ3>~!Xw8:&*_#2?= 3P1u2QU1%>pأ:X՜% * \9B&E5aIIa&­>xNX:.U:|̷)yiͽ߄֬Yv=cY &V3 c:ռ ~]F.@@zol6z84=*}9䛼P$0 ~ lH7~]g F,㨦9@Km3+mgmk88)N2q>fՙĂV3mY9isWFJL?Pm0A%Br'1FϧS/fz 1EoN{܏ V~WiͮStdGL4,CA{\u64,>R9 d3i||lSŕ\mfo6W5玳MH8v,ȷ#h%+(HO0!0L  9d5vNepkU@[43iqtO lm#6 (lB ~ZQ-39GxF&٠w:,Zn! ʨ`*WHJ֪ 5bLw!puPwP+gic\,\baN]O鼢fKKP$x9/IDMDЭ(, ,)n3'n]lZ@2mctdoY(Q9F acr3l3fYU !=u9 #fQ;R%a ] "4 Q7mA`T3q[=2g[˂*B>"\"0N0ֽgALQNM؂WHn@-XQ\C9-:4Ul( =Ka Y. N37CB%4ٳQܾ4YxOyGPWPsdSP6;*4Q7'm H@^#k;Z`-m0ׂ9y%FI>XLdrs-snW]rq2Hji/fWoaaIlюB7<,F<$ bPh1F3&XYj僟}}7gȐnYX0a8qG@n l/$q_RhW̕ggUd[gL+Ī(ycb H?&hwqO'cxI=54'ۍ?Ԭ |~N[ {SKƽ2됂Nx9Q=91|q"⤱_ZL wjHDtM&qet+l )q ߃2 (h:!lX64?}am5 ɬJ;H5>$ZYAbux$av/xO2FRQ8'@_u;CZ .g*Հap:a=L5uDκ*L%KW.8SjV篩Zf} N $D 3^ao4:FyO9CΛ(|=_?CrPK|XEzȓrX+z"l1 ÚI)BH˃~O'P)E[p) AءROY'5a~TEV6jh r)}ЪUP}YR'}>^m &y~tJќ.Hq둁!=_}VX?syZ,no[FMuxe#t%^_voV+/o*pue%l.wK4>IRRP_hh WVnyO]Rs4nom Y*iCt|vK$ImOB;DMBԮ1y71L0x{H uՀ \8Kz' ^צs\]ɠGgc,+x2"d?I_VBN,2OK6;OԄv0D-JD+8AEliɋsHl\m\O6'c20+yl~JG{ NaQ#ĪYEXI ̲nW}o R#:E'cZ)/~L<]kQ:"A-g$L1~7#A*~2 H:LO_B걟f1^X7kxAYPm}ō3#;8g{H[R <сbas9LdzoU!/VyoVqwSAa dS;J0J|̏ 4r&3!ÎD고߮2͔.r&ZX CMn5-?hv4ܜKAp;.R$P$^e7q";,oB7^m4,|v~p@%zD?4zZZ2˨4Ϝ+2PIK9>p8EbieVa-E+$I^rWW~-۞yvi ŷ 9oG0U32ϸ̪S듺'oatľ6zeO$Ӭ˴;Rr`d>~H h!%QfmT[)mZ[)-LmTl;`c%IZl8ifppS_z"N{&$Cl4jfTSyCL-[AG:Ћ!Z)ws6خ  `HQG/kS5^zG;y ~Αg 4jS+~mÊ|\q+FJ;wIT6[0OB%8l2#v?(s@#| vaIev5O0>xѕ:F⯅\kE^1: mȡX <'bMؑ`EzuAаTŖb2nd![o1<Ş Dz'{;*). pUsֈ=YKŸ6fόJ?t?Q>| ֦:`}%J؋"9,fWEG=B,jԠVQWH:çK6ŊLMGD1瀞H\\ݤK  $\-(Ew#^9D¯nBjt_Y귙SAj$-Zo|L ;ٵj[mukq i&lGb7 fD?% |37a"Px]F]˱VeO8eo޴;OIs 5EhOr`G6g+ieN[Cix,:udҥnÖ1Fo7.s@"PQzOJE9“}͢qcuY-'Z]:`2Y-xw{?=F1ʠa,Q" CD9:$@Cvy^Y>d\Ny5}hcLIs^ r̙7}b{S}uj萤,J 9(--O7VgJ2jˆڐA=SNݏ7i-?UR1 Q6np#N.5}SLl }:9a3J'iYи`5Q} ûl!XR|dO *gc|$ ҍя?4WOJ_&67h %_j?}X[듄5{ePjݐ Ep-i"nAdቬ@q!\gw+YjN2ɻ +n_Ip`]bgiRn]2y]#Qsh'T_Y-AȍZ| lOPHTWlAhhS^ҝ~sr&r#Q7Oݮ)SJ7ߌ|Voߡhm"^K#Q&;ڱpHi~hO 1Ú@EX2dh@YO%WVBU-O?@Ń_@\C:uogjmpE֮Cf x: jzG{=-ZM+T|#(Ёׂ^F$je5 *,m;u@3xB3,HwM8m֑)5Tƨ-ZV5,P7Gdھn `os(P,@z}53 :;G8RgG1آU9 c p<s\?Wŭם1Au8WzM|C^^7EtՋxR aO U]8Cf/G'Ra6Vзs|٬#4X',,,YWL%xȃw5GuEl]UW9֟)@uvjR,yH{cmW`&:RO>mZĚX;F^3;HK3k>v"jbLb)IEjSg:o͚kg& QJ1sJL3F cEeA>g%u1’*.䖠X?0^c8 q^e|\ Y"]]Y#\_͜oY/6?o8SMo|_\ I= C.SH2 e% Fa=fFw]ԠWmjj hn tra :gps7?R5qq(f(QvxaAS‹0\ %Z÷+Mx ? o?@{Eջqq,kzkOydjN.~_Q$Z Xwxf5)󗺽 /\)UF3Ux>ȝ\ o?eoc`wtO6eGFQ}HNm)~=K'f]X7oMScç_S֨Ay#Ih7 {Yo:qVM;[@7X!+'NA#/*]OH&j:i똗mqG-^䏽ð9gz i;=Z(MUZ!)F`dg4)>tcVyJ\pcI.#\Bbq*eilNizܾR}6ݱ @)R}ecOym6od[ T7y'xئg:۴ߖ&"(^S  $11ٙS_L3yCo"h?}ۑ 7lE}?xfQO?]v1j|$p4ٞPZ$ yȹy℅V1i  mlݽb$QRi_JUjE}6L_LB/>i#{(1BW0ܬ6~4on&mj@ 1E=[޼\ٶOÐHDL9XdIo'-IU)ٿH/H百7ղ>1F.[lY:d<yǬ>3>fGw$PaɄbHbV:cHwhkP'\b ?rU7d*^dRj9̉*;*og%54+X:0֌(㑍*NU2wGoܱ:m󟦿H5¬?vrp A-xP:Fݻϗr??0mUe~ddopVz5̴ tShDf0OG% :g F) _`Vt. χ=@D-K.ڵa^}'ZhVnF6\P49ϊOw{9̕g0DӔPhU~ ݻeF}vY(-2ZlcQN$(IJMzhk<>c"G`wVj"bTF=|(m&7& (=H|9l܆d7)MGkڑYpNU}NH;>Bp[:xV0?Nl_+˵~摟)O^[{bv}a%'=]=6'+:KNXn[UzMtO%Ev*O~'[[CՓz!~"hJ b]7Q]JDfNtQo-H- _ *yQW%SUr܆3ThŢv3'ND&j}TD-5>-8~"戚յ,֋T};PsQ=75Ta3tpυ6nyeQl58TwFߟ&RǷX(z6;_gP,f du#B%ONNx+?`دd]~ak~ɉ.θ2 2|2T[nL)m@/ހYFsj'Y[dڐ&HDZ T{[@ KWwܦ[ 蜰vQdXȽ:;]+łǛ5Y~O*JZ{*; qPt@hY*R;FǨtك []4ƚ*5vWҊ5]W]* . sH{ƮfI/EdW{x%\l֊ 5-N&iNl <˾Q** .…;ҾѨI%x溮Y(¬y̱:hrA+]=WiubΖ3Ǻ iFlةii{YOdL1v/PߪD6"jͱy˸d3j/BYrBd6QFrpН}u<'U0:4l@}7[/xӪG f6k΍DXI:|Q{U gr+okmv&H_p뻇"EΧ* XqS? IR;$ZJ/Ax7'c}@@+d]G8'm4_C&/jɺqJ߼Qfv@$峣[XVwPQhpHfGS['{'’jX߭i=@k Rzgc{ɧWTNAԆL&џL.?6!]^olZP1蚫>}b̩5'tos#zs{9sO24O)mwzF!q'/}Bpa GYGհ^qJ5bz Y{,~=}Mam4?HB' IFV)с;1״pY罓>^| `Yc2:RW050X?Sr⎄}=c u/!: (JWIx3+6t30#)xŃ/]o"|fUYL,1L[t ")&…\?.aW9FrX5Qj<|uo]|yYyYfu\89R*}kZgl\@qRCkm#e9ʩ42e/"UZ j0FPק3MA &!49|74,5fbzQp 3w; i}o h ZCEɑPT9tfF4Ug>Uj^}-puntQX5YsҪ(簚 X/q#ԓt~.9s閑)JB^U,C:ejArػ'd((@L(ɔrؗgye;7_`ѱw >_ai#ٯ) 44*_2`Ucߤ3N?ړk *|w`x_ڪ.;5]_)L N΢QwP nՊ!R3i0B`sMHcP]-`߉ 5\H,an2&du$~Ju+xN}|h'n0Q+gmѸ9;đblrg&V)Ӂd'%׋1⮠4/j}k =JG٥ M"1ue2w L) ǡ#"jȥW BV7+ ڱ.h@`0ijkxR5pg{ ͐:xiTΠJJ nҔ"m8ܫcb!\hÉurP]5~:ȝR%^ZooǜGcױzpt8zpzV}RHʰ`RJZI_SH!_?0+~=|}hmʔeAi#eړ=Fl} 6Lnv֚%>JmM.vmOR]c^ }-fJ?viyЕw$D{:~jOM iW[dW9ѱ1*]}D8vCBo$$  f |&GӰjl,v 3w[Wͮx.үI tm8,8uc&@pI#pqoxzgqqDk.e u':!9rڲA\szA \5)eNSOcW>It,~:5{mIr++NXz?v\hNm0ťIБzFRS% xi>XON7"-} WxIG^2M˜!*hc,qg0ELΡs5W#7z%7U4c cҿ`B]t:pM{E9F_!Iw % .tU hf>ZtWRu)LoѨ&V64ApjTRX~:2MRcp6h!EM67 ŘccB z#©jҋ_ P'v~YuaHc47:r}/}Ϳ[u"[h֒rg9JNKJf`f7IP&)8 hQ8G{m5blY9@hŧĭx+4<܂+UÁXV21 \!raG^`@ތ8䃟9tstg2fNkd/ϵzR7usr C,i9 }@kSp@Rep#h`3)*R+P,D xH\N iuG Nw[;bZ NN䛤LvYg wTcv(f.tmݖA'lZ3T|Xww±m+j[@.Rm9Nٴ;i$!>&|KP z8Fxu݊V=#^/]IVyx:bk<5؛f .׊ɢen *sfiAiϼ+|-۾Ů)szfTR}ځLL?K'?qI[GlyJx zTDE;nϳgPk? (ZJlkz݆@.+ߏ푟q]{ mC\SM*"MUchjio@8V=c& K44m_vvȴR{wcb$&%U ;/ v`޸{H{R"I5L0*AC>Y@`yU/e_6ʯ-,' [Gez}Sۮz鬄0/CN 8dPzE?9^1P}#*ˌ)vxfq9RQLt#rN*lHrX*ʑ%$N}tJ,U6b)InV0|9{b@Pdg=94?b=w~Ý~_^WlECT.b̤]hFYF4|kPN5ZsȤ76 Yw;G25O,-m_OJT c=e*ܐu / '8tj氃6-\ՌyoQn7E=As79í}pbG BԔN4gV } @ca Y%qES<-HWʆjy?dcW\Q9 'Kv h$–:RK2J)'Oe9P8WsR8_ X7fVGo<lGȏ\Ceۢ~{q43*xH6O`>?0mK2L){ax dQ9ۣ!2mBhgMj_+VQڕEj.ޘ:wA/t?ra[:\wFU>A[X|0Ch> VxJU=N͕G\ rY&(E{0̡Ӳ',H_W9BÞ75:'Ъ2vE 6v|/{L}bK/A >t@Z$B[g?xrHj :X[/qvɏ}ȏƈ2.x5(!01lqz ":RaqXqu9L^ ٗ/hV[xOV<~ݫ[w82)ZxIn|oz p{wTgߕ~M41}/zs0 XW'oҟ:Jhbm!ĉS֯ȷܸOr9`yOߦD-m Vn=[>Jq}wt{"%Zg2$?`e <¨/Zz2NP;9 ͐7]Q7ZEp(#W ś6ܻ6 Ĥyx)E;+YwS Ch 1&NXu0qS8b&{p;8Ш02:<&DcEӜ'~fBsw%ftOώ~C׶3]z@)ꏢ0=dƉt4L_// 5oS0gq%c]}gűlq>/jTp%L8>vpp.kRy~볅ѽ{ʵU4nu7VօumIޤ++]U?4p6ʈ ktb%#QU y}ХMĎ/"D^D3—XZ!QiPG ޒ}A{kl\'ٗ+D-x.U}˴Hc'}7(fhFfiGb~tuRvUb 4*a6 <: .\Vj|˺^fMQX%AE4zǨ"O#}-W(_~?)W/QLtMvƹd8+;X%.#֕+pzEκ4k*ݛN>\;B${=N XnlleA^Эb󜀔ޙ9(?u>IpQΏKn=Kꥡ/;wT3g/B9{q;{YƑXMH D %lrjj)ӱC Ϟ ә%=s1 mh@fW?x`HlP!1 6w>,9Ll5~wvhS}J6\(ջft=7%vj%,#}>V1j!Y 4eƖXjHTB E֥\聉u|6AV٫e<I. hDf_~?>uܝS "?M-'9\.WgHuBLix#P#ǻ>Q Is#~(5z|]會1znaWgE)TY&?+'2_?&=26p[Bn*/P\j2hF1\`pjtjA&陡}'[ b$PjCSvܺTjR5=!yC1%lsp[vhC-{~a:z"nI@1S%94Wh:@wDsZ=s.vW2(c)]ȁ9"L t[ KlGsRuVFatw)a1xo3 92^*~BVfpvF[eoKH/RM8e幑܁6e6wa?l쳺hta$jpꞻZ>ka@PT촹 vUt0ۭ(LڀuWf2ѭ,`PklOmBlP/GH5Rrѓ/Uɳ>v=ݸZEv쯠޴{sna~Ѻ1&ѓް ewovuqvA7AkD8)TX,=s M$ok<)j@ONbZ|ZsB9ÑOUT!m 0/;Ag^D!x9* Luq8+!+VV˼!]L̋bMg] -OM,Ǐp-3qm/nN;;KY8y[Ư ɩJ]Մ7V8" N2X'}":/6*|HC%-+O^A+`O>H/C/P{Frw*ti6j֠^)>ye!!7b{DQ@+{ X6"tAgf%̹]G8 W Ý?`:^d2$jȟvYfNE{ZYD[^$&Qw޶/12h/~ޢpA*iaJp@[ ;-SF<iY/.,׶ZAqF4 A_GDXGSwoxE) /}Ro\+7ZpW; W?ëI(J*(/ AhAE rfifhaY+GC wנhWK5Q1ipk3&UOg Խ;Na7FQOS۫$;s},?t3=M~',o՗B!4ɗVPԚΐ$77,[t1 JZ (aFL_!)] $o;v [o_quq`p(NQY5O=1qgWvpME[$_6DGLkGtƶbcJXjYu: 檙p&Sq0uh˫Ug]9A? vowGJXlWtO .ϐj݊L/?M =GC vľRj{P=ʐWFFǘD~[=w9媻?ccrļ`Fze)<,NAŤ?\iU `=xI&loHKNxx'GƸwQV)U#;^1<ƟԚ|kCr"KN_1H0BeQݍ@ez`.]B:N0yJ t&/a;ssoNum7aڄQ.h^x{hCNhw$xUwU. ʂN wB.ajb7Jl}'-=6gguuqs}o3)ĵJ*>j=+SCz賦!n^h/m{slMݮHE3N[^;A߃OHj)h =9@'{R-&IŸl[M7W= NnFۍqAdž4pJدoqWY~T;~ұc%-ĀLjH FJS8fҒTVX @LsF`]B !xC?xo"-ZTJ47$®V˰\D7Ipwxvcjp&]Qb  '"IxRD2!eQuSPoTks9H=iQRU8&8_QkZ*?azKg.,*৔9H3 "ȷ~Ʉr*)"r韏T)\g3P G%"}HOd`{XZKz'+VV9OXUyl@LzYaT5aDҦg+\"̻4<u<7\X-#zbO^CCfgJ IvGeETIЂ R!w}d+a:RAhȎߓvmv]k.bRV<ۊ㳊_|Tz}96ԲYc;2w(vƊ3$1dB\,"##RlSx>@C^Q ީٯ,n**=9iޯك7:/ryByv@L~Lw/h,fDK1qu9}{5&Sao{!m&Wb C*e#ERwp1_搞a96XQ9yYt4_fl!gзL&0 A}@fT# L>⼃zf^m ={gǻ+;ndjWXdX`ܧnvS!; 7n2V{RЩD#l%oaEkS Yn!SIZcBq@d)}ZK2m%G$Fc$F65}p]l" y'幌SF%LRg5di{<'-UHʺ/K5Fp7g2!I5)MST;*ӊ2JYS(wq犾 2Gw 'zteIx. 4+^vm/=s[[H"lP ]|b?r՞?Ÿ< lR$d92ef߫M$lY=6bypڑ"Eج!s^VmACKmW^T-k P{ɼcG+ox]/1&Pl|LM! {"tDRecU923D2V]g]\z4U:FA9. G+aWC;y (aMr =-ڄs`$(]BN\_B%- O%ӖEncc?(a<)ϗRΘ;(Ž=:Aw>;GKCkO*ka֗Go߼x4h($ۡS Z v$OÓQ*pXb(XwQ ja i )Dže$-|(@=i[z6ZqXQ2dՀcΛ'XHa7_>jK|pXϊ]B盯d?,H J[WZFbpWlh@F{+mCbx·C> f7uZ{A3d>S"9'vOA^Tm"QFNok2egr)f '-KnmˆT~KrCV{14QQW5Һ8^]~EO_"h]\y@@ր\MRʅ1Z 4oȨeau͈?o ,/P]~@;ޫ$$wMz\mͣ@ܡ/P׵6v?o AqzcRǫC \4k>y/h%N/)6(P5/#xaclk}XYs-Qe g-=&'/)ʷȌ}$4azOQ39Ƴ]lUɕכB?p~&#Iw.R*la*C:-z^b1}%&[ -TPB{'~y[w,&BCF#gj)*yơ) IJz΂ 2a΂Q f-gk`kE/ utKR!ooCR]}u_ E NSQ0t^ͧBJpW/Z>P,*Ma&U&!~+-ø#H3LljA(X?6VZ$ɓG0me&Oȝ0M6FeDt77zmW8:J Lgj0Pq~vYSد? Hba7@,Cb&J2*Q By4#d2<~l[HL`WdhDNa4xL {8D~/0Љ 3H+m.YQ?h֟'| U_ț藸t$]c9wzenUHc^B,[%̫&'=gҸ7ך|S ˢ?ɋv7tՆW/IS)!ۏ{lﷸ44'e[ƿ]SyoK3ŞчUɬN蹵g"b[ k3wVD8d]( Ƈ%³,'@ 2(F>ꏬQx>XuuZ ZR6v ;'"gS8eۋ(gXx'ڤp HRCv[_êW VBITh7qq29cS<LQ Ylj pAα.۪Ӷ5Y3)<04s}K"e4WKoY}s6t+7h)eF]4pIq _ӵm ._>5eY[NzIq 荋(טIb>S, ybm% U :Zs~+V֨Gi3V F\TaK c+5wLGO.6bV fTf9CZJؗ.%lzUe-UsJQ0Y,+W°^4e ؝3=/hS¾!mHŷ+psԅ2';`U蟯xP?"|`z;_U$0f6-5;ՓHEr|=N/v?Ū;iF>DzGF5;5 puKh E?>-Ɗ)]a[ONkx鴶ܻV W7)˫x$O>iJX˴qhW/]4~d̳J>\eͬ$WzDKԙXazo@2cv:ķo`;x>yݮZ+F[ArCEblK}ż=*ce-)KVN1E׼s6d+Z^:ʱ#l~|bKmǵl3lڤH+Ealc@boѫMKI/)LXs"sj ^!J37Ylr5q_(tQROIK5#DB"bh1rՄZ {tHW˼/)aȪx7Q s7Aᓛ̌yj#;3C܍oܮ-8s}j@NAY1pI ̠BX~@K|ӾY/WЩE_ V &{.jUuz;ÿ[Otw^AXxgTotbHW?jxQ_->J 9 6|,TN|>zs9z&)+aoMU3RͶ=CJ F&ە}2k:1 B?lGsd*T95+aK!Ev=$?N|e/MKbً^(*!F H* M4O!ӽ,?ϥT7U. O%+ kKƍkꩦ7Б1dD.0W)e#O<@@LbwRR]qxM9=^REUX{YzLrL[rl5?Bzc+Vf1ݓ)^8d8]6Jb[Gdk\]Ұw.fc_1EhpS@&)ϙTs!2ބE@%Q!&%i:6%Y uAQ~8=zq$R+)5kK9[W\X|JNo*aH Sۭªr%WVA1/ˎ+NBa^GD8ӱ}o!ObQ]' ːHDO\" {jd>hL֜Qi<镠j>xx@`g)(D_ّmeZ_~_SbV}A@BVi/n2.e%~ARՄƓE͌$1iz=J5Z6Ua$ xVJ#B;  WШ6W`iD-(xeF$C!E8=mUY@(Kp[!V}=^dg*A+@Zҷz0t<'6\}XzdmS.\+"MkF1a1(eIz 097ݨc$s*aܚw(![$ BEjj( RQ1)1UD\<a^ݍm#o㿔<>0"}!bzʬ9{|)N`H"({$ q7{'dH}{lkމ }$n~/XEQQL1Q`U$Kã0 wR9t.aJ_IFR cw'.)ޱaTfiFa[1Oz"~TdwIH7&: |Lj6["RgQ (#2~ hĮsD{lkHHSyK:zig sh98nYـTߛ8oMn֑F|E?#Ž+Dں73[8ظH8g3n䟂ly"R&q-xov SնO X]<8E,RCbV?) v&7?Hk@/nXByx5*N"0ApFj,Q5sR:̻ߔ'HQ;G]eE<.}I KoEY܁G+aKXH%l ^jK%\ca<.CJx-:DSRd8WKEGVJ-c昬|K{%!XğS–Zt}hIφ(ӟ7*٠TQEt}ttڊM!&q0m49AGstT 0ͳL$RQJ)hAKӫ j_xo& q58RY1p9񒖊6#,ZTUM2#]w|W.)- ġ%BM'YyCH`o+{~h ᢖVy3MVXcrkGJ\Zuj1_`$rc;3}u(vpЮ%I=A31cަ50ӔldJ6Ę8nܻ8|&-tņ A漾Ţf.3{I.K1 ! JY*OJb?O? bc9U]pR.Մ(x.%cT^GL8#9G QEibf1v-&;}H{%Iz0K]%!?-XHpKSqװ3KEa×ܮ'&>]zxH-ٰ]]dn?:x wNGM]bx<ɂ_ [bFwvq:iܘ%\f*?m~${[6nު2?(5m|Y=4{箛C|Ivjsr{"~9JtmAo^Q!2ִ2NLj4pkvll/$~u囒xmPW CʩJmH`SjU֕cdBS!d }w@gS%܎"zPvTX$s{*t.߹h=&Ùzw_6;ccrDF̞P•Ô׃]og&dX ? [H=]ֆ/ R¤g/ml@Cɂ߂$E#lb2.PV*a&zϑfg B- [s*^im}̧_PN>@4U (|ּ^f`bU->!"DHRk&7<.qϝ~K%j5^*aGb| f{_KUgv?/&%ϭNl&0F乮Q=IK#I~g6P֐ t7oc 1Ųi]DʝI7{9v@GU'ڞUH)ȅWKv.cмޕSڴazY]@ՏM'߫|}UؿP3opG_: ~9$ٛG\ 7+ncsW}&K ?CxEaDёDw 9y/8T?x!w/h+^䍹sC&l9,mT=& u;]J2 EbfCgpMrtWxVf˩~#PO7`iWZ:%R)oL&1O#嗐wju|]WG*9[S|/j PuQ~PezZo0д`qL BL@@0 fcD6u[Nj5lӹE>VKz. CC#E{5-Wڼ"듚`kPtQO..e `r$+4VA8̹N&~zƔw+,ßr➳Zc0fS쏜2WLg'??~)2_ j.@3Sf41 emBlG_cL"N{6ME"f~cbI+NMjqTɿm~b&-.꿏'A#[t _@O^lHeWd+d@3)k\ syf8JX2und#q/GɟItb!y?d{hӿ60IV4粅I,7yEۧdGP|6pO$?9*0K2q8'Vٜ܀Gմw$V2TX@[5v4 * (A֧lLt:O<[cOp/ej?_k$z]]ϜG4uEb4òo^aPv`Jgh;u<' ׅل^eYypKL1à0ķ^|hF c7ii$RY*}4BsOZOO!H '_[^TXjқ8FjI[~h #=ܓ }I׌b'eaB;q`@[ .G&\{8m">Q7 ,O(⅝cga;o#qkrJwtHMj -b5̭d#V[S^i>J$ Bo N9[:ks Қ^Sld[ QS.Bco'ɵ,B ݑP|CSTWw)G;ͽ!wQ%~ Tz.,zRMbb? *9v~rjq,z#-=E ra#4!#V+ : tY]קBIaQ[ߘAq>͂}U֙Z~Ѕ⍊va~?Ӏ c}u$%z޻*\x(xTegu_~`C{VtW %J=WTt.J\3y=[4jЭ' aߕS|i$Eϧ'e _96ƀm1jAlXpUI)ǯ;?`ym@^{`Zwo44LY da,4f)L}ԋ-19UZ1+$|a{Ϥ\3 >s DWMb,u,/ k0S>0#bZz4˗Gq ]a\9IScl3Dp{bcA@~N'*=*莶wlg)JX>*0uC]:(_}˰VDs/^0Y{WOϮ?t\3i)7ӦYWA?<|杇߽λpclCPU C L( Iߜ${DmN 5\NYYn:vEYk<9%" 8Eٵƽʃ#1'zk%[UWcRw%3W|쒳.7hB_ k7!,7Q3a-OߖS<=ہAr]j!Fԛzg+;wz$ŏxoӯ@N?_/@,*+&8 =}Eѐ5 "z0AvnU!|gʋ+dE&61S?`n}cEѧӽ?Zae;r(竽2BX:'v}_{t./1_ɕ2S{&x*GS0x+/FjCy;\+ܾY_p#Vb-N}: ҕ~ot=!9#Л#PlS~G G qk}26Vs8H9w`+I$@\8EshGH@2"PX3 p1a'Cv*/i$_#21FԦN<9L;^>ܱ<bl%|{ i)g.;=G]2tG%re*Ƨ¹.'nU ;q\ɠÿCGԜgȐ&-[CG<8]K>8YZ槊+*o*^nD AIJZ:fW5X~rsys'EJ kEQf24zSg n*"wa 7%"7ſ2DzU /J̈"J\NԗEyXY>Ņ^ UFѝ@߇* g**Wi)ߧ*5d~_j{8 >:߼P?s'r8n{1PWCyTz <$H6USiys%UO,ڗSYvOW80x<DŽ1/>>BA[W1v:UoL :LQ_(1kP0rS``dn$)J2%lV37C۹2>WpO7ǰGpUq:5U zgpil8J,e %!42Z.P}4$N]M#j r FO"&jޓ)\5!Rk Epr:{X7c>w;@;AS2Ńswψ`ku`}ntWTwJ̯PM(7^HO7&p]/\jnY/򮯴19{Fs=P9Lkf}*8m~~xx ߲V߀񰙭f5cbS.<%+P]ڢDܞsbi|+ dJK43Ǒ)Z8%}q"uxt%/w3y([~RK U+aUKc|/6Am/ 7#GҖ;}/㍯A!FZPX%TvwkW'\?OwI[a=֌DS䄼KBOD'횏\I1TP#hЏS^\6Euf]3Oߧr%'?ZwNg|ţL uxU%&#C#Эaa'&bNN-6:pCͦW ,NC3wZaD=KBok˝bmEh`i1crs޴ԩZ iݾjUw?|Σp> #R !0mj*9Gƀ!-!" |'7?5>vUgg)E;тPJ{nRd}wW鳎]eP+n]|P~I0!a) n>6<%LG1? #$ecn K8|wXTa`N+B3C(!x9ޕO#5ϟV6k+IUjKi>1K2gO=eY`j~MX'L/%[*%qR}FO'n!&l :n"htm-XE&9aY?o;r/×qydj9ݧFeEaC@kWt*lTgR[}v0

ճrVZْϠ}C7pN5F=㦘ֳ(Kh0 fgշM\t~FF/'Рlg]Cwn=?6 8?Ѫ&\R{&M+G}[Nw!`^GFxKnk6B;W 5Ye3 _/=}lr{W1lK76rl"SUn#<F; ) dfZF20m%b9ڡ}E╟Cx\ 0h1vj&3-,eZ o\Lj[=IjS7U"XS@BA-i}[EUOM6I.U.3[%kYedZz  8(L$Ҭȭ4UH/QRlbf䷓#f.?aO:Fog;@ rzUՑr >#dSu8k~^maʂ7$׼&&'jO~:~o-b/,Kl"Cߞ_O,-_S>-V«@/ 86C4'^0US9#gpM3[79|sphMる<ȒwO&hw?qo;yu50(?V %y%¹}Ce1X&B;@]B'?kYplzQYzW뽑Jq7Pbvùrsv:ßV9`h }pL#bT *'% va6/յ w8] \,uon:S{m0.<̚7Y?1gBs7Z\?4ă0i#"55̳|N:awh)l9 1`RTc_TGdĕOணN,~LP8Թz(&: kB( x߄Gi `&͂lduݠCUYvfj_I|kT8՘RpG SGZ8u.="܎,aH3Kq:椝O"lj19veՔNecŏU"tt/0o;,2_ɯrp؂3u;_o :`X\/3|rY퇌yP,\#?y/RmE^ ; ~>۾· D\KNd@l0jL{Ob`I>z[ISV".@Ϋ&i (D0y$+iNW@Q:M7Զ<2TG-ᖇ(ރ;j'<1u,@$ECͻNnra8 m6Rwf;SRb yJ{ ))]/Gn|T𴘑9q"S! #MHME g.2ofˍXr.&HDA9ǣ/!Xk7k ](6| OAlF*-)Y"p.Gd죦/"xһr~֢v-28i8κ-\0ݮy?Nc9TLD_HJ I; 2L5;P.:[B%BOtgIBg)ֵlxl%&Gm~Q!:P#׀ g9NRQ2e<*|&| lL_mXkUmDl=]G 9{ Ľ7 kYWx횚FEODg3oMzCH{-Jd"ki5"H.'v u,O(n8kPJlI|B`iŐLGA@yJ-iΘe.+|94٧.i<#ծolפڳSߎlepIL0_" ͯNi Zʍg_V,ⵣ/Bw nSK"ܤ/Z̆\ͪ{y`۪ W&R29M>Kr6꫆9*mU~0K65^#Wb3%G &җ` OWny ?-6яDR;3;BFv/ V t~!fv9tCZoһzg]̣#Ծ4:'!zdW!k^++Źp]%O!c>+[O_:$zHzQɠmZPa'!&q+w*>/$?}jSxw ]OR~TZ ՝]KPGq:CgIA$Sn 7*OukeTSLT̃.LO_Y}tunu4L&ĶPbcP'v[ĔCX7~|WRL>[N7[/$˚̳ 碤S@2ݞPf&:5!_)%G kv4\jMYvcxnL"Z@I֤GH.S~vl1OR6aC ̇C*pR= )l1e*f[uxD>hjg':|{JE8] k|kyVͻRSE.O]fm=->1S=O|;?ڪDvT`u?z:Ghᦪ.-*>3% Cs}ylf齭#j]-<^[~yòx^Yme v6>8٨ČGYe:gTI,)C=W_c΀a:-*g `@4an 'X[) !sy%˫wogOȦh4M>{jG*3眱qM.{WW2RHs;VrROǫCl-0vO<{Ahyv>M bJFק\3|6#$=!*~i>[q*,-ҥ||v<(SLJ݂eנ"!uMry?5'8^Pftۜ9T`7VZ2؄b~gmܜ>ZM&"1/Հ_YԮepq4# d"A"evouױ@|% '9Nfnk>MFьn +ҧ(¹16I3jaT9iΝ25q|j% SH3= м _t1F-eAnaHmNm\*y_z~ fX1x~oy= iw#~Ԫ09@#8PbPdŜ!Qd79m@N2 _Ҽ Aݫ3JxYгB-Jl˫'{?W liXūiuw]VT"n w\Eb0H8 OB8>-]+ N(h_"(? ̉"%KXKKeFN措WCkX숈ݕQ>7k~ ɡ/#&ڤ3JCoi{St!IzЅ tTBbesln57NhaHbqU>w;vL:W2?>#i Yh ɶCGgC;40JXScE2פnE~<5dsB{g1aa#zl~9`'עiF U3L1 U1\xRhpY?hF]u- X}к7~lrsKR/o 7Tłǔ5XlZqh\୙[E#`wr^ٖDR\G-AG3q%)ٖ*^۹[o7m6j+pGFkq,:MX_-rԍUrDQZ"V}Pzi7j[mGPIn!F>5k!+ pk}K|!N5H#.֏v<nxYmXmEGy{sg ݜÅOwLxӻHS&4%bU# -e;T^gt7A/y 5 A d鿭}idM؏m{s#":N( ;J9db"r(-F0Cmn*@[3-S \?[#V{YgL9,B,T2N%漽ӈ3ƒގN±T+iN+.Z|NaCL2t-u.S?(y33k6}f61&3z].H3 Nx!nu ae{nD[9y۔,Or6"g_:Q7+4%;!F}}O͉Loxt}dcgη!8zɭ2anPM0su?99lFiϔz *1[=3NQiD|Y ;+xxc~|vG7ėZs\pPZxk&T :1؅ĴoYH Ipy(`xh#% (F.@ӒcS_a]D8,|IMZ(e^{ROL[p;]no)I--٤ACRD#kx܃\`/4YkR!A!pK)PƔr!)]ȗ4x:QJn:qp~įɠ}N5,cWwP9 4q?&G+QT9|DyD*7O Sk3Z3ƒj"hcs6YIw)er , 6 0@Rjm0ii6>ЩϠv0])FӏuER jѩP42ŘEqۍ)OMX~H<݂ 5k\ȇ}\CwQI }- Q 3RcV':Ңe%¢7] M[!zda(p"NlZ9y þv-?H5Y]\ZŚa ג%bK8I(IWOC0K jKjRw{e/?[{!-rټ?ZR}H]3l*dU<ȯS{#AEq]=FUkQv+yrDݺ 8#eӡVPbaT}r"ڦ+ojwh\(P Az<w# .zBwe$u7sun;i45=Ք=U}nx@t64_ZAYBOU,Xsee'77yeV?&nrG 97Z{ ձ*Ʌ& H5\+h,,o^- )W0g+)@)}P֤s;Sa<\,uб+AkV̉uaĝ褱.ShllA#m@IӣۊOLKb XEsSڒ7GZgXfxKH_^|l1A|a0œr!DLۏ6x]P/ *vٯyAc-[ɹncQj_ۼ9]1i@;l@ . $!Mg`$:]\P+Tz1:~]R#<1nOB_rڷQl;#+cJ3ybgKc\xg+}Jx^q.Yf?QěԳ0/FaL9M>5FdE؄׆0fof*x 4OɔHKt}EQ"}$~uGc){N2f,پ>̵פu<%3' XQ&rIGb8~Q+4L(ҵ:,_40"|ɤhrZ/z@Y-tV<$deՂmr̬o~?L6DzP S %_هp.u._*'oQӕQԓ8ގ&πo™=U| j rtV&+6PB^I6Yxi樒>@4tky)H r7rTyf"xfAT(6$0񃤧SksA\8+j1]Sd2 KQ5w:ɉ N(mN v1oi^]0q KS:..zU )"o~"`ˬծWN}5 wd!me$vS )[.Z1YBxlP`WhS Z~,ݒ*Obq.;! ̥7 v,c6K}lUifgzaF&"̵]ȏ2Xy_+%/BclRDʫk2{Tnߔٱâ̢_s o_Vcl|PR1.C<=t os؛3 __Zex/O1Lߓ<ێX%A =MFƽlqnOB?4tH%[IYuShj8O=ML lw53(]y)Ėe2#K;xSoQ"P^G`ak+RJ!3*MZ)l *6>@Lo,%Yxnnslq%svp s0vmy)/<^Z XH*ś)ixi۸7w\E^ nrllQ*gגv.6s `Rd4g0i֎>{ *},RڋE, 7H友:VygJ3T׶)Wm2yfƫԒwY2GI_uvr\ݜ-$ΩJN!@t%LJU/=FA59Z+bb,[zwBE*64bbt -`bsh¬;]oQNClY]UT\p 9/ˈv(W:/.m7;%BS ɵɏ,/yɥ] $ߨw? 潰XSC4oҔ{A=]=UJc]/ ^~ tҾp) g,V))ScMi9Y"Kŋ1pf]<*Rp#P7"F5}WuJdEme-Ӣܺ'S>p~X?n8vw̘ÍyzlwD%{i8Ǭ?PV9ȔD>M?ה/ ٢]v#+V1bK#}lth KP C}^~ni 5[KGƇH@PKVla#IN5%OmuLzS &<'~FkB:8;1lUX&;ꇒSl ^ɷj* 3caBlt E1Q"D!ĐI  BFz "%EDj$$6zJTku8>=ssx2-o} 11O!9wò`?,|&oҳH#:wwPOki!k:ox#yqC"JA`67~:5yH! bRD99SֆM9?+uf՚ ?%oT፴۳$j/arM]Wؚ謹;o7cj9Hkr(u`4;1g^qr]Y6L/X@(7 >:#X=7k)C)x=o^ڞ\֊R%{+ \ qCHL yMB!>[X$|8/#,v|ϣ~L~RZj1"j &ia{ӞCjVREW$IskΏA] B m?rPO%|¢D'S?lDaSX)xSDĄ"OF?Lǩ&m P_lLQЩ1 4dV 6`gQ̀ȹ_辽%nt UT*gB3ccG)d޾/N͠Lzڃ RR~</N˖DQ5dX $I&S4__:1{T=shj_>]]UVN 2+rx)"ݵK yTnZ뱽0,=@G\P6o!G3ftbe)Dػ[!]FDXz 2}I2t=!Fg ƿ#|]|׵歽>_sNQ)U Lo e!ԃ'cdRGKFJa"̓gdI V8tXlxC|C 9^}xnGw¨~,k\Kze]':L%gDDfRJlCjݜ܎UKiՒ*޲G>=c.a0H"[ԡ݇;bLwr}}=xTi8IyvYBScs.ARŢ قN B_쓟pVF&d`[#L+:_4Y$R6|,raǞb6᤺ŒS J,N*x}u10NYoWoTN5¦)wäU0@wnNh yIfZ5+ aC%>IhF,>h>%4 ǀ+LBpdl׹er"q&Z`1ݿ S,Þ,R^D6`ǷJ!|܁| nCJ'<3c=pHM9yp85K[-AbBU}tphz_)d^k>{3=,0 ΝL\ti "SZ ze6uw$3'pn=n/"Q , g.HczDn]~gA@ ^`یtxD|TI`ԐFW'd_Y[XX+oVctG uMyL9J(&6",:|?C𑓽 bD)5g 6MplN٘mVAj>8blf[oѲM;T`#P[|ߴ٢?^y#YOb+-7ڳ8Kh59x|Gfӥ|@RVaaШ /c+_e]E-DbųM;ur={ݢO/S]&ɤle//{,ch]I]wrtt^ g4l $ex]=Bsbӆ1ȗW.~7UH~~z{8'߹Mhһ 6Hb6"ͧO"  (BJ& )829-PSqeOiGtV%Y+L%Yޔ;nvq#!&LIMl0oLt־8.摛+Rb1 @ Gite7fPFXֈS(kXyC\: W[56 qL͈)Qd96^>3T|&EuÕVOZj~Ufnܙrzb[4qW=P\31qo 4:9#AFxdv奢Cb SoԼ#gw}UIBd-ݔ2q,IZ}nhd h+XAC!E6(V*q+?Q Q?;H,-ZcXL/&hټ;wiTcKg+E[AY>R}.@6)KwZؾ56I66XlHMwX7""ݐkʊ>U8dW?,R)q< ,381dY@Z'%ݪPE'Vi+%J~G7n Lz̭"Mo:'ںN~ǀJ6ץbZ+ZiюJrX7?Qf3LwZES˛Aۉ=拡>W;sh}>k`xJ'rwYEP[_AEhF:T&$5]p(@ÉjO͜{eݒyiTڶ{MR&χt\wG]Ϊ+ ;ge!}~e1^ bwnv@v_s-t,6E|RHiyM/ B殺GptPF6)K:^SE(t"B2b}g#s֘1 aS~2߉[t;qi# 29ya5QgK:)LnGw:)v#uViED9lz]EWsikVbơ3z XULbI'vuG1Zaʾ3N z#o2m󇶶s0T/OW Sij|3.c?ga{$cw,=2I.|[tAhx"S%>M5UG) ȋlLTMaj8Yf"؝ЩB9~a%z-2BgZE"!eB/37C}N4:Z+&u6{]}6pz]Z2f] ,ncۋr(Z,fyBUӋ?فXrx=!ܙ\͢Aa>?ngg.JGtF/[L ĝ` ~jvAJ62{Ji[_R5o<k7|g4&\ {tW1y#z5v9|). WVj 4]vFT.3`שr ^>1viR ^P񍶖Q.;^55afFCL,OD'O#E{*?HT&aL6]bmz'nw<$ЖN|".X*?.zAgǛS`\v7y}=EB4T?w $coC3wKo[ y=Ӯ,~ZOky4E'W zoސFʫu" \w/^Irb{㎳:wz0Nv-xp?@dE6Z87qYpvGJ~k]1h^&nh۱% PZ^7yoY­1-Z*«z\0OWMjQ-CCZwcbUjyFOPo(L n/R -2,aeS=n|Y3avؔumCB#FƦm}v%?ԁ +yىJ.+=^%*~h8uT7͹Xq"(r%D*o-_D-%th/[u=I{WVEfEIPbGYa %ͣV6ӂLwΠ1ќӚUV',КAG0woBGy ILQܰzz+kD.fTyc[e_|)o|'&y]6[)@+J~۬-&8?f2 rk`wHtgS|>: ,Oxz&S!tL!C*^eQIyjJx ]=TDS 32wPkjs6g+k^vhLmB VTHP&iKlNg;:9Oi]~gCةaosnmqĿtK>~rczXY^?\fnN=> +8c"7KIGL!YuqJ}Sl.Qz߯)g}d Lu΃l>*'oO+ @ײ".;*0Z"~j\̂J\e㳔Y|a-F؏4)ӛ( )RɅƔkb%9Ka8>}p,Ý \oCr~V$y]%Pv=!t~۬M/ް P65heU6X'k)!^O9lZUaC7X i"5&L֝eŋ9.ԏ󌲨:,=1W3Ǒ> A?N(kv}̻4kA7B8ؤ:ZL]`f -krܿ.)- co o}߇84M1*S'ZU^JC)^{O8H+jwI|x@G[&ÜjЧsj eJG#pYi[7.ͣlUҥ(Rx1N<߄_0s@ۅ Z}DhǓ :8?z3Cyx1o<ڃv292F|DNd`ᨊ* @7~N_]3Q-m#ŭmWX7Ԍ/\t33TB)x:ƶPHW(1Π_iVa ͶnHoX i EZevc;--Fy5LV!-o>X?%ZJ>T A@uR37aKiݗ ='Kvխ]re:w/fǴ=OD #EV\,Bx ,4Lwj)W0c}hTFT$f,ṠaGR-оS2 Y>p_r4wA]6/315CؙSHO;FW3k39ìaRk aשfal;1#!9_譙<V;NU*+&˃vxnEOjwӼK.K'=ʍ"?szfXK !V~wUլk6Ͱ>֙No+ކ!)Ĩ >9m%lj奶 }R/-p3˹Z~7&Q!\yE-3_L?2BBkvn0V}z[RbUN5z%ʛL2,֕ ;>.F:SU ʍj : T֕͠D3?2W}M u#̜<Ϗ>rut8 Ř#e8pfsb#adUJttJ;n},"~7*V6j˳{`cWkOB zsk>C/ S?Rv?5r]aO] 7Z+YҩD?hyX2ʰj{yw|j3+T_n2L>dFE{_PQqSozfTg4-j$:"9:*,f_o,Fgv(ojWbmӛ{g-0S8-4A'/?oKA^0+ @f:C,JXy:@]ZZdA@xrc]QKr5$l%>>606/aWxè;WA _?bq\̟Lia(,|J֊]Lb< ]|=w&vbkY-k řaM&mD*vO`x ˕3+G>Dy?A[xSrk[Wmrٕk,j^$dX#zytG#XX1e &g} WbR)R5+u-]ur2/y5/j8ՋsO={z}L9'RК^Ro1+ b\)jM96fNzS 7SovG]5*/<2o >]6pvXm4Nrqm<ԽGy.;&XHǭ--UU_ު'/I!MF.%;72ˮRNc%3~˲ru"RX~C-n̝7W hOLf(+_/Gt^ 3_K!ͨA/զpa?EgT>z]il/yN8"ؚjRH$}3[Tjw9}_gPM)dꮵqC}v%nb?Z nT AMwl@-~oܨBpf8';>]}K!_GYY"]L@;z~e:OfPa3glTwl:J&>l}%{.lgD^ݨ9vcbg^ bt&od}{詤:$ةNkDТ32;vX%2q4F 8'=UW 9Q s:^;8kI-2XE@DvQVwOGnN _d[.K 2 Q"H&`{3xx`=ɴLrA1x]8}k}Zï,Tq?/l߅.&y߭=N54;R4{ry)c[f k!.qH'R;Ok ZkOqۧh ᰠOoZtx9'g=p#'|Iu`j@e&E_;Rft`gY5Ԗ:))4rj͈{%-,>MDa"k1(G^yQ'r\sH!2KGm&[,7y `n?eji,<62X T3C/?S*)d/a/ZĦVƇ̔KsNm&v8e]A[_+T{0 -lHU00\yx~5iϖ[17338'5sHu .ibLD *RM/H! AɆ⛦jI ۲X2$Ź6n/2xΠOՏO~Zr 5"sKF흜ȕP SҠO}ж[p E=-]sM[Vξ+wX\Is{l[S%#ՀL<4S)7}jճ{tb PW+dz jGބUY[a.U4='!:FgəD-zs峇ۋbQM8x]e3eѴ 5ھ2\>{eg&>)rG-Osδ8[w )'YD|(B q+/uY\>hqңE8_+l<=E-JXA=H%Se2&@?I!#{DNgJ#dJ!0,\+o^)d}^L@~ $E0N +πe5kYuځ8_&g'0oe M\}p?,dn\}TY5^zL|uk RǸA鵦bo aK:zh1qtvpD2`5%MJX^3T2rX"yqxCm w!6 ?-B_1B E~o` M2e@`fi[k5" haLaSLtGǣ˖Xi&mK+=q/?Hb+zHA͚LCT9PpqHǿ8>_YgQq-9#*YM*8Ѯw˗Uc}S킼 GxQ>%,@ (k04?I"׉LPm}{ve;dIsp7T })1:1``S)V()=gcs?xtUVjfƹ] 2beM]B gF[@T0ފ4lq?,T`$}rzָ2W60[vI'v<L#bT-7$uX@52Ft-lˉP6ڳ}`74}S$ďas~͛vE୤v_m^]967{niD!Xz ԋYfkg2 6] Dx!?TҡŹ{u.[|(?!G-%f9F[|hI4@R~Qu ࢆ'(܌!_^Jg߅TidZ i6,9{WAڥ\cJUQUPgԔN"w^VkwjVI|^Z:(Pm-NŴf{2_'ԩUAmcVw7D~.ʚ-W%wvaO"9.йEP/>SLrjs3:ey>3#$SԲvυ&:,$p0(x %w#2tv*d UIRiLYթV*۬bN~SS:-56A֝*`߆XVB@YRk}dR0yZ}6t.ィivßD(}P3m1چUܒ[q8%[쥐R+i!$)O*I!0)0D Ӗ~-@'9R6eɟjYRÇޏ-at^KKכyMyJ!6-)bW)$mF4`?' _D~ _[)07I!vϜ%ty;(*[O4u7'ڙlٍ.} #Ͼ^J[S']_ՖIiۘ?Й3AK8pW=0]70_btt%~xɇBOSNjK1;88`C)Ւ/%RȻ0aP&ఱCZf O0MqJl.[[+1NW6-yYIBSfGAm>h+㶶d*SPQH:3Qӕ/"2d?i:B% C qA\$kGTU-qMէ|2Y"yJ}R`-(HƬѬxsy\]Q0)aա< T"wx2{  (Ziޘt퟼W=s sRJX$Ic\==b+j223 {{<޸㬠>YׁSQY^ҩ'2b㱄Vꑁj}dE`s!ްVlKn)[OϠj#h0\/^PW(K}i-N LhXf5L6Bf_'w.=Z4+od4zؒ#o?W-m7+/.DTej34B-oDfA>o&Ulm /Pw.k#~, *FhMK> VD8>gS'ԯdhiAޚA!d8w%/{&4N\O 4\4)d4':FrݳDA`0epEa,/JvR6کi57 Op˼XanDkR`1&&uC"??);P ! W k^$ nrI*e1U,! &pGqo?PAAHBV&Ջc7% 9oG=@$w ̽jIWk|pcST:,I ى;N;!Oޢ3"~4˄w,؞_1&ZRIxҎN 4~hu轄pVl¬y4qa_XL"Lr[7E&DHvGN+.R0k /p$w(&zjzpA’>wnc:ͳy[:b+%ແ ToR|X%ZHd`-H %Pe:U1!}M<|y#L*D wFb#Bj}3T!r=zw+>]-A,+w[H U=P~W+Ά0l4.E+h[>V|~T^Eij:x6Nm}KD|6؈ۜV/ηH7nlfV]O[> <Nt7y̑\Bć`)>W1sj|O{G Ӭ0FXiJrE|ZA/:N](/15"245iYfbA]7 /L/6ux|nݲϹ S;瓘S"[HocXp6ft<}X=u{!s}rqe}sB$oӪF,zBo/H:7~|M<-{93]'Hl'#i*Ww˚P o*g&lÚ\PM&^[v%{`~xSED1Z'AAmVY-'Jt|."]pPH!"eL7D7sw}I ~ -`EP'I4ʼJ &i -TR Nۂ砓D+GuV睢YA^_b'+9Lg lo7(cE5$^y7Y``j魚H81ji0E#b 0 0SZw"̆{λlgs,[D@ZVw'\Q?QtD~^{BK~w^W٪O ׃_^bՃ*eʹet6dWe^yUؔ6lL5[)\ ݆bFrsE<Ҵmj^t|&DӇMl<:O2) Ů~{ЏtY{%I4I(Crr;֤Hb38H,E \#C1:0بߘc4y\h¬RIڣ‡`6LqZ$az YDu\VtK ؂1i!> W PGz)X-+Gߓv##̙J+ Lp54kEuRYBIM =^  !riO&\EDzDƪjJM򎝾mvQM9S>Tpp;f&W={v@~dP>&(?c妭-X կr(nD) &◓*JW[(4Eh4 ۷ 6CiGDn#m=l矤%6243|!BB6 W`:~)z]DmdiPI4<od'7ꞋW#M2|~]vÛ@s \ N0nӤkxh - W@9 U{ KXpŧ YWC}KWRޒW^K;6pB P=2?6_D<^ɘY9C*O5N- d\&qAagK{/h)%&^(uXsҪKQhƥ.7HT\jg2w)P޽S,)UܟA583Ea,Lw9@4!1|;[:n<ӺÜv.2eb>hٷ0*I*e3R v5 zM@̤Ej2 9x/[?3ռfR@oW#lJ:i(m1T$.D,8EQ sC^lRfG=ޠi>gʮxKӥwODҰ$TiGGNZGJa_np@ 9ҏv\j%: > nun! RyTkڭeZNS7$+RsR64rTj^1=F`kwcO"ZޜSBN6LŸJ"ZWhr^ en͎2pz-WN\s!.`EmdҚʧ!GڞJ%]{?^ H*i-!%ec)Vd84 L%x<)c>&ƌK,Ў@܏DgǬJyء':q'| ՠ;_p\ur:z>z@fYNM m猹JO:w}Sc\BYwl@$\xE*@Sy5啦qF'7SP1 GL^= Γ guC 7aZ9Q=kiCeHI+-3@VFDd>lahK;m@ s93u,la yŋZFo>`V:i LT\n}(^ ,lC\EI̯o )w@B|f]eǮ-_'zILjD &.?A%]׻]d+Bb+,ys-;RW:Ղ7xd6|))\RVlM] ɣ;ƴE1p w1d&K8,06qgyx*/Rܠt>ނ*8amć8(_SؕIQ1 !G_Iپ 0z): EvˈQ8h7h։tHGRbu( Hb/T32nB稔6YZrr@oIGb=*O,9U\50 J>:80:C^8 .c׮(S"G8i`N5DF.^ׁYAtd[#iHχqOo1׵o~/o/2kɵ? SrBJ̍OOU-lće 64"C2>6l*fv'7#*'*>;ۡ oaAR4߁OEcwpAcsi/F4rC}[>/Tw1j<;cu,U)MQ|R-MjBjM&VYj: Z (1MvFc9[|Bgjk!Y3_/Ph#v%DRK]qnj*nu x,K^YP l\'Qh:Ϻ[\b5tugaَ2 kaCñ&TeST`"rl}4a8FPO}r6:V^=wq/!~JIUb¥ ;qϨ&F$\*']洩T /Rv?-NJ@TVBwi \xH$&dz}ҧGkcz7H"񓧧ywߪZ}F>t]({[˔68cF[[jZ\q$7]# 4T*kܦ.QOY 14 m@1ׂvVo!,"L%EMvN([̢@-nQ1HUu #3U[@C"PFWZ4[xŽ~*;^pZ:bV`.ց p28Ì$[v.%vMs O]H5Ij99Ig75f\PpTU`Eqd@v/ EDc1J $55.Ȍh~՟#w_7qJynk) \E=UFXU#s-,f~IcQ{+qP~afM{3;fS. vgGebX?Xsj~ϬQjS `DP I扊ob@h,bO͒fyd0fI2ŕNR@tux'!y ;K*rHƳ,:5Ř·ucW;\gps8ZU Fvor C=ރt2hP,7X(a ރ!\ǁ٬&6t--~H>+?I <1Z gڍ]٩~;b:=Yg(I)e>quo> pߜmӾJY/sL c[[vKh_7Fn|_I1'_)Y[w{-W'=VZZD+A'˜Mw,2Դ %?D٭1)@U=hšQ)sF;NmUd*$4kJA"ݘn6IELFz< XE85C|G8?"KZo?wF5rOFC4Y(K怔fS >!yɭD}$'sX- uf@gj{I碬elZ0l R*0n+Xe՜\xWiKI"hA<,p]FhBlwגEIw3+#7sy@>]^Z9[{4'u>v%Lgn vXZki{|W__~GӠD"LrǩY`6ad_#t~f-3{:Z[Y:ǒ$,,7#B7T@\=WCRցNgF4\ 2X1_gZ@g"'MFd ߐbQvE$DuɎkF.95(=Sc4YД oc{23/dVeFA 4?z$:֐}&4iers-6/Gs|"cR%% M،"Q~q^"U$@ 1e&T?AB+`EAn yG҉^?bh-9sɅ۱ݿ` AѮޒ<Da v+=%gj>E!7b&oW ?oZ~:ի]Qn0EpG#ǛAt7̬02Kd?<iqVB ]>*|yd&/4c99X$&\Jr."ܕd5hZ7~Wpj? +TYiLe! v 9V@˙]dVM9 w8Ta=qe2 @9KvؼMr0 ɗzWсYfRRrF{~f}0*FY {G`20;/2#.2gU|x %,6PݡZB\!c}[l+~Hrϐ߂{<Cj[[BG\0X`#vaMPO2.`|T$*ɰ Mz۹wgqoXwSN(0~ؽV.y42v܈4,U#"FX]% hcV< )өVa6fyrH M&OʁtWj'j;qNMd'+#AUF`t]Bꚍ=-Hv}Gu:P2@f5!3 ^YV c6/6?:,YX&f 14y-s4ꅅnfН33p k<pt,qa(} )P@\Ygu 2cйV. %JYi+=`S,5P{9aƱ5 Zd,.,~̸_*N#hd |yB枏@큒F]sXnri/w(ګ[jUz dpLF]+?a,4 aB >~>6ꏌ3V>y>=Z{<RUeUFǏ&\.3B̃c+~E8U!/{3kikν NvG}ÞB}b9|C,GuHLT$zo/x1QeZ- ;/" jBХATK;P"bT)Q[Xз],DmLu@(/f]sn]*#7پ`2tM2PPlQUہQ)3 M 8 `CIrZꏊdCӼE9%m =ֹ+BYI=9DhfbpK6С;ȌG5ĥa q!M'! +N\"''U pR!M 0ZHuAj^gK_iXj&qv3jS=D4ҵ22tnt.sxIUgK쨵]Jpm`K9+Rx MoHyWHԒ4[0|DƱ{qI>tSU_/"N<%}}QyOz)e8ێ:`)xXi(J~EtFҳvV$LE9IsP:)#]#6C ˠ"6gK& Q!k*C JP~e*E\G'V'q\:JO!;-5T#+NL bJ6$w gyd:f,۾s'˗wZ}+Cu'f8+ei76 >x+x& ˌ-޾οoΒy]BUTrRX[p\Dm`hU)4Ł~ 1p`L,&Ozt^ElB2a!’[6Ihg{IVPVkbAIL3>HvJf<7>D]U0֞7$5B(t32"r<+^xl7輅{DdiTrۜ82G0(bR^F2Qa*@^Q=ݲ)29]?4Š)CDhn"Ɗ{Z6;D]WA{& ugGKn^3\7{vTN;4TsKMm#-J_OŅXrʑ!T(LΗ8h1hZ{P"-6.ւ%P;Ôb,[JvbP3\l<ɂ]iֈE±2pPzO~7ɉ\*u-d}@BX)!S\Iw@M.aX\)"wV;GEM 47rDL_UCSnN1rѶyjFU778'AT2]mzF1>vɦ@ |:1hSDHfGTD8 [Oa泎CWTL zjLΤzI%t1 O:qrЦ&̣cDlvRtrq$|X6gS=$D-(NER.YgԭGFo}jO dY:q"k2݋ faW&=0.s!NJҥ5L!TZy N~ܑp6B^2dnsÑdvf`ߠKDAuGZE=L}m@ #dEney<>K !fDP|A|.*-eaك դNp~V9n&O*G`"Z(z- HWZgcNj\ICzc-X8Z|kA5/kJ=տ@X/dY3`5̄lL)nu:kBQSak<լ>Y&ѧl-g͎6˾`ӖP6+F Dc~/𻴿픪JEI9Ddq䣷Mg* &urN (- PALH ;z=yTkpS\ $׾>u>CVsc(a C1P\L,"lBBVlla/žkh(:<(5s n%+1``++Ûh|WC;L>)}FNqLsY+;s׿ zd>qUQol=w&zg'[ KmsTl^]M;[כּ%/%P/KP _ .u/ ,"Yj'<,-Uz(U79rlcِ>%c%Ɇԃ eMwB>T#wd1/--5051Geasqfᆼn]Lw̚XUy= Jgoe{G!%̡(M cC@ q%HȾDMwk88~z+ZX ڠ),~-*+>rI)uhc5 *;5A+̓T9>DY2{2ĻHsRr[͜&Z>tSYDkn%HJS}`3GRZ;9v)I/w٩ #!RD,7w!{)A RYM2AM1VQ7Peܸ6(K~ }6ֈ]o]E,obؽF}gP:pʀrUIP,D40f^/s9;Rz "ӄcd/@VڒE+kˉ.n>YZJhJz8N[!KqcsP:wB4d|aCLsct&GB8cMG/%gqu*b~qʼ.o 45#g[:MXȫt 8Jtr#d! ˢXq:5uHq̈́fJUf!KptJ/ȳ*.VRRjj\ )nJHʴ'-W;42:čq<;R&~m>MhN˕M Ss_S 5ڥJ5y?XVrj]6oFaS_@J7 nPFjli؆>vڽNUvۆ2'qcߝyJ\TX"ϦQm$XvȄ<%NwW&NmZ}Na"͜|a*d^:;2Ě·Q07II$OԫdBl)?haO h5-uQlTP@@#, ݅%ECA%SbZ(/|TsrEKCp!@UAt쌥2,Rs~6-ڹ6͢QPDe+'e\klL.VsI9ԞED%e/TU/`jߏDM)-O*%Z%mkݐ]kgZ=ߘ>_(Pr$9Xւ2|\i0(Tbvdzb雲SI 3-Ae[m?^sґWE)ѝvǎbe*ױkίË>Tj'|DG8=hEцB >1LGŋGIiwLg#ȌR'HX>0. {z R^^b Njo@\mIx"iS~1f;vYFW?M0[Ma84)@e|TplzQOQMceDAsOORP~Bh>wfDYӧcٲ-wM}i^^鶻gt7V =<4o͉ hJnigH=!yb=DS$ARjTK@#-WԮP'o* HeR[ s\0OZC %,"p62GV--`5y-]QOHqyKOPoc'ϮpCk <.Дd EǑ,V$-x *8) {C:iY#Qv˳F=sħ舘?ɡ)įi@2E-"30~ѕ[}S̉G! 8eڐ+=^ 8~fn!sm:egVU$4@i՟ҭLތpU(,:k5/&ϕڑL9;kSW:+ia}QO#yj-ĺʋ#-'0-F>|l~ݴzt6<*c[8ʦ"gDyj)tЮ'Ce 9>sy2d ]'4ٹVNggxS{fm< wTHlBnV;dčZ93Mɑ }N2VP5<2!bYxKӛB6!v ; ߯~y!ɢk67=`刪9QE>m mCV@H)Z7Ex}Ì^U{@ge?4nfZD?Sjf{Umj1hӴ9iT ĈґOf ƶ_wul[H:M/Q[ďV/O`k;VɮS4vmL\-^Di7(N~S:uӵI YK- WC,YrHX)\ӄ7`g*!FG ]p.JsnC/"60`ܲC Md^NbaXE3N"i.~<Milq%kWQN*k`f蹜PPTps9O8Wo6aRV{_Vk7\8P͏ ^Wc;+(+c#t.e2ô2n'mvWv!}^L:?<ʴd}JQbE5CT9i,]Eʩ=G/SO).'lW5<3Rnm=(sd 6`бpB* @ v)S$wë|Rf.q_ٴe'oMrٗ2 W7L bFA>>=bLJ-dPM)(u[ZW P:1[TE۷SetT2%e&ۍ+&8\:i6  qWAFRBm WFfF=)mvx nr`/JYu'rI+Jj.qijS}qf6ޠZFq:2A3{(,of:> _:p{(A`„kɧ :L8?Oa?VυM=<ak6D-sRuJL< ꭢP u])Xsl?cC]wFG:HeI:yXԇPduUWz5JM~(Vte#JgTSl _Sxfe'w5?yEg7eqPVE^=Q;+)rB[%Hӄ]V}^PMq|g%f OA [Zvt @BC9v`_jv;yy/0 /@ú-\)SF]e?IJmQvCA| eɆc=37߭|C}LL<6r7e+GQt!V%o _v⎔AAΌlVZ?!' MoeUjw'0=ƍ,xLXWEVyl3>L` wMle))c&w5dڝyQyNvn!jomBdm1Z{j~6?XiMrE-ԮW\<+Hjn.:Lku|e߇ btnh*:Uڰ#FYߤ*Qo!ߐybڭmB{߱b\KhTZ%e3<[J]8tjיGؿc͞{M虒bF> 3P\ƲF"d<22MWnyDI ·52a'=h  '*iG:a6{-"c-8vF_> ɓ2θ7^)zjC7}\M==@RN|vIK!%HqVk c}v&LA*N!/kTXPtA("JQ") "BĈJ UFAH A` ͂[)[fqssN<;_}k 9z8}H3`Nsd?;XUIQj6 {}j8A޾u8-6:2/Ǟ³V$1MG'PFidy"FII,Z}{pSi4&K'C/:YHplMaQCn(y9T"AF%Wq{^,H /%lfOJJFaڣ8[s>);8K53~a0;'U߻\IjMPנvn%) t$cXe㥚 N-z ~l$P{g'8{Vj^Až}VȐbH:DfמS/Ae|6MV#$JZYܯJj`tsfW} 9MfU>?ߪ*~:[*% ;_3Yq>qfGmmK:l+y]=$V;Ek.ٽ "HB/z\t*V*8t5@L2bDR>E? kܘmgƊ)[z笜[\T?2QdV3Ju&7ֻ2u=w]2[2 s)RGS_nP+0%=Uv Hz eHY`1Z6n; z/\ [JjflDlY-&YF$c ƌ6#BCy @ 61XπyZ1ƶaPR6e&D ɾh4:%kƐE7 D7"W7g/TGb+3C)baiRj)#B fMEb_f\!Q#{joo< Y&"** V3m7r\Zg|r1{hO۔;tV>K_Дj(;br|\.J !O$b_g*T7ߠwO HQ +_+ bU)@EsT!ds(+7p-$`5Z=L{(QKI2<%>&@fײ?x_¬bȈbg~Z@d'9!q( #"AbKiȠ.)J9u(<~xrEj(:Ie~.+p"Hx w+жU5P |#;{ǎ3}qzsz܂7r= EѪ>ƍqo)ddk#|R3qwJd}d"=,p˿z+]K5 BNK pqv2Ï=8 P!r[N<ʼNA BV(FPj,J9 H8U\ -Jvg:$S3sUVoKQzsU/U_ͣ#QG!E5G,Awxq2׸9!zy܍N RD((j' WgZᚈ{bx. f.qXm{.{OqQW2)bQA7˓'TAwFSfF y]]d!"f] l e\"Ͱ̵Iٰ9q%ry5LIP%}.o_5:=FnT"gWoTRP^mm'Фgg`ʣM*ٟ*ϋ4Miئus iǛt pڱݜH9hɁf`%Y}_"P2:,u_f l$r;Z((>7'2.64 ߾ :g'jM8߳=&݀ulH'>߂)``'KrJֈ}]:1Elbf>G2gsw<^IOndH2۹)U$9iW/B_C +2P, `/.PhLbI})F2&zt!k)3c_@K?c-AQ9Pcmy 軘 -)mNo}Q{U>lF?WvpEO'.DeGTt*WEI3]|jHD4oGciMTiA WգY+55sxi ED̀bMlbʪ3M hrA=f3/BzEcn6eII+:Gk $ެ4{sDZ]C|~@DY2U:w5#EK&Gf9]38k(`zlyEi?I Ǣ6R8 DDp%Єcj HM^X/6%HzV$ZKP1#K29s|Fzyu~GckɱwNlz=Tr]z*QqYBˊ 7YVBc$TռŲ*AAYG'~']5٭Lΐp'ЉcЂ*"(TrKr|":5 Kh_eeO@t)=%΁R8_xTun}w*׫'Ȟ۽s.k,ّYF*f|87H5RB4?p#y£ʊV.}S2*֭f dV^ HfMktg [oʼnp_6eYB^Ir_vΪ٨וCR$P_:4 )q-.b^DqH]2[ =R6=q R5;l6U\mpB16"to<@iIbZ\W3EǒɆ]T7uEה%!D 9ͩH@DqmB K^\^4sE{%C~/Av![{v!lnWVTQ]xBYd"DAlnq7`֤wtm 2<7̼g*gW'eTt:GJ{}>׭ Ou'zAWD`dkjQoĂ~r]oi\M[M`:[=ĆZ6L=|VTW:k#u sӚWjɏRQ[ B*D-n x|d7 @m% _vg(w3AB39ک0jBpeE{ݥnʨ"]B#tY9EH(g;85t#^ E q@PVh/9>%S{)0-F:N34va#yik2oςTǦL@Ş@oΏc|OhN cEeA=ѭP ycKHJ[Chm> p2XJD{aCYK:Drl%V$!";h@wvtb圇 |q#o}i~BpUuTxv^j+g@ bJ?y{̩X]ɿda7F:bOTĿq8U=;Gp<׃*F3|] yINv}@m%Z~pk>\Ӧ0PǻekԄSK6&⻴28`?!x QM s916DZm.6V =H^$A2 !rqsAܴv;`BP%9g tY},N mvor n&l.u!o'S2ض5r-՛&Bgt$AD6 g?=@I4v j:҃Kֻ,rA7 +[Hiq>rϫd_ e`@Xj_x:Q&ɘo G0u,\?ԤJg3(%-Ӣ ^?3Ln}T֧iDîZm/ nT_rWeq|;IYl"tNQ:%>3d“#@Ta` ;:8,Hի Wex[Tu$lۈb_T\cnݔ)klh:PDNp @!"1N :_zP[k\K-#o@tSsg|IUҴ+oXKv%$];o[!#Cd|(EmZԟCia-21kq_T`ont{KOb/mfn9GH5J4J|ya`ow鼽I/7=<1 _״܉8A]k^\[f8nf{lFən@ .GZqu B:X΍ϮapG(`J`[=X@r~[Z}Fv) k >@Mm†~g'==='f2}بgms̈́m뚤#m6B"VMd׈95A&E4 uF]mx6Cx^EjŪziK%ǘg眠@J C썃CbϡLs#ϟM!<#m]WF'm IA_ϐT.בoXJCL郍?;2WQGB6a!eeA^R+Ӭ%ԗ4ↄY\@kno&g DVۤw}}a/)r"v6C~-}$ }4XЉL %{~[w_d3փ4CMFw[f׷\LR. _#r3gqGE_ mrl>]~ O]>od$rnZDK*E?GWXDA҃npi$N sQ*(-Zw@91SCoH"ʰ_CܠG|V-m`maHXi4bT1X&nE>ɛɖ!%0&(Mxm[b `?ts /(xkW#S?}P\^C^бZ#ʨo oؔB@xJE0^Qi&fߍ5}ѧ/puX1 ir)01Ry\Ҧ8=%JB(tP1Pg5EX?\ZCPQŦj>e*) \|wABgEsѩyU:qu?L~.|}և*bLH(K HO'Z$>UIff_{s56g,G)oi@ΦLD)ShO3ٽݨlwjf]PPP\%rql9> (LJQ7e()TaRզw҄ƴ Es-)[r ;c[Gp^1!BD)Hb ){EBP!Qӥ?S̘FjF{M>ig{8dpMXδ:4^~K "-$Y=o55? Z?i5<˹  ;߱M<|*Vnymjb0d^>+4vnvlG>wx db\;帼ÇM{8]oD:Uv *'v| &.8"|eL}E[IW. #hSEr % >^mNV:~ZSƹNG mٟgO+*i>>l W5C: xaZ8ёK f(u74ڻRzc6'αHt/mOkuˎ A322 Z#G SUw9sl Dd@m#ΦX(1OP by־ȐrH ebV! Dʕ,|7,|H|nNև"t bqpp݊ R#ˣTCyR9}9767,-k@KĦ =d Z g2F,RI;k!J*?2l:UιҺ%}#RLD#N0m(3vhԔ RAn4+{~ĔƼ [>>&vA:\~6T_;%ȉdХPjnHnjU9}M/ *Eɡ,$%(* ⍂z"OTQ4M'p  t|*D+}ea. UNeG( ԹR۔ۆC[Qam {s#$ѼF=J0FdADLŜ5ukL`"U0 }tSc#B}ZN+^1xe_PyB+]B}SǺ'GB=,IVT fw~6~X 1顱ziO'"6rpi&`L!e Kb Q ny1Ke!:E 4Y늵]̵E M3m^Gᩬz9~|9fvy ]Z̔HWJG ~S )QȤo۔I$HRhx(e^) C ٔkBU1$Q ,K/̷*k\xKPퟠ5cSEκEs8YN͔ќzn̙W=~|%\'jə̱)[@Y6tVɶWlY*&/!p{tHXx0+Fte|=GtȇC5'g}'4: %o塔x @yjMEsi?{vp="Vn,a&ʡ=p2WY=լkhԻlYC\̔eGpq:?5hiaPFZ7eIi3 y0̳5+05E S`Ԩ,i| rzwEUBƘNzSMMѹϗKv?@t*:Yf;RYYgQFŁH({҃aAε_-wr=)W 8CQ9CXL%c[PՌ*XƴuFHrk7e棳+ ~]O$<ˌ9DraI9Ci L4SތPQS!ͪY29|b…[Wŕ7ԄeLiXcdj2:)k,TJ {x)zӬTF|#[;k}i睒q+PkL [!5J#q?t=H{f]E!qPIR%%Y4fNhxgK%Sye{ 1ș. Ρ5HG+WOr UTYǦ@gp÷_d%}~on0\f}*]{UҥNjM,q>YБͧhC+#iP95CrRс0Eb @k4܂w2{nAVץF㯎:&lbiPlj~4ė_:/Ms$AN_բUɉ,Y!=݋J\+W&yLMX  @mh0I\\j?}1 FtGQ5& KT˦-m?Tkb.G_c' @ ><={^>/R 5*BV5?"K_ =m]a]̴Nӡ8ARcACU}tƊzr`N]GZϵzQpv`ç/:/+; T\*1v {~?%{hQ/˱7Mrf쉍,&A8q(YƓ:ROϿQwZ2nT=9qB8h\&sY|{꥟WMgXߚsn 5w~c\]/ I$z=e>5NgtN7;H\r Hq+ zD!Q}is)*"S8/l؀P,ꘘ qBN o2Ck_}\x}hQpihaX+Si+kXY 8T]\d` IQK-ۅQH,ه=J<9ݶ8@*j!]7m5#kn\ fH@yp`1ˠ%_Fn-Xr$Peo>~\UK~w$y ZĽ-DrM"\QJcc0kOWCA@`OɽX\7tE'7^XӑCq|^ֈ<: mU|\] T,Zf@_'"^cRƸJ~O~ܴKLӽY pI[<\r֥qW ӃWڻ]{z |/\CB.p c˄F<*L,9v{u]Bmm4t51֞R5ը2ұfPQ'F,P.*}Q#cuIJ6pK㉕~ws>q7,sEOGMօR;u['@ tiux;N2? )A6uUSx)65={p;Q.9@Lhԕ< j]/J׮d`*f`#"eQyKFѱٴ> (>Y`eꁔ ^bf*Q#Sη"8N+9{*ZYQ#ث^,G[וFѼ{ۏoO&ޝXc$78X=5zʿX4]`p-hlxMbeX'oAWclog0\qHX!4r⸴$!S0['yÝ."L uOiX_!) 2PLLh]m)]+/,8G[huAEo~^Nܫ~p˲8}09ZdjQJl cJ)y+E5=_5+Jf ulǢ۲?r;. r~fS7`$JLiZD8IޔQaTMC,Qfp L ʱ@$ u#&gaDfb$5N2C@7\+T@F/Y3!o$}lIWiz6O&Yl G[3Go# dȺ# 7Ȍ)-q#9'vչUAx-E5-{UҎX%DI ձD~х s(~QZ3cZw˳[27E~V%h:txϮR~QZu˹)qt;rh2g'aMF3]ILR:̼~CI) a/_:4E%A~?p@(GBzH7+2>s|wO.y&2g˝;4cѺ!,HG>9ʈ쭂Vt5f_}"q+w NIb \*V%CZ$ռ;guhP'ED+p3<{2x-=b?Zgܛ['*!CeZCQyi_LUvUy/.};4Z%+R^w[ hHAX'?~ao|MLT5_ﯮ5Q>*c)wԉZLN%f='6}*. -;2i?Ckw•Sh%Zꚤ >FNjрRX=pPjۊ9lCVI Q5HşempYGF 1m` 'ϔ[ ߆850~~i~Ý1dd#dc:ꦪN-ɓdϕct?1뚱xӶ*tm8eօ9WT|BT ܙ Sޣ_!d*pHVBFXyPL!CiT1R5hF^bFQx#;Tq~ek f\p[S BZkD!rr1D=AvSjjxI~p/13c4S_/o7\/ d,lTU(8$֡hXXGn2q%`4eozRtisdhP;4Ӂ .I2"0{I@R9\Xy~ 6c)dv_k$v2-x+~ΞQu1@`H{Ûqjr%?TMrQ=$L7iۃ]NBz-0gx[ vyN`` a8|j?1%Ep q@qP&|;hOɈ)ǜ*q_xl~'V2(T2qZۭVKp+Lop^rM\ ";$ȏ0=g9':6-!$$ڍ]_e[u:hNFb^~ Ֆ1n{kcQD ۡ[V#>ztө޲xkz(q[ ۵bn#Rs3, vG D{?ygo"6ڊg`ne&qNPBI? wЖTXD15`U3?ҟSS]r{-m=wgkI.½ސN(hZjDꯌ|W߀%x'^(,w\ >wҀyŦ-HQ 8} bŸ"(3Mn\D̜h?12ʜ{{ pY=( &"(g:qu0Xm*՟f#u-bYcԚe&$x{e4ťMԹSiᬵW9Z Ợ4ٿߞG&Z"@淄;d6a6 Ij#'Rx7}%+=g s\Sx-P (>x% ;MJӳT9wRͬtOdu{bmUxyU*9tuRd4W ryfRlŵ'؁gͦ6ԋ:sdt(*VFp_4j㏫HgF7WVuV/e^0G+=qIXGL܈K!n$hv9-a 8aI(4?隹8h@&J9WYYdY8G}oΥP&sRۡf11`bN$_ ѡҬ.,ʟ]ڿiuHH# R8pB;rK*Ǹ?:%3E vKs 51X?Dz5sbP V 냢EFҒFA}hZ"bB\v__us*=+,I>\ļȿDKJ3⮡﹯C7 O:֜.HM yЃ 58\99Z>^^4 β lkcQkRzT}LMaZ\1O"ߝT{t s}+"M a .yH፽/ObYJDsYDy[*/p` iuB,iNVkCh+uz#%֐ZI! Z`uIA١ ?gm#DbOpI:Հb-HZpS5ЂeړK0DIkxY˧92j.zjO,D4F3hRc O Ml3t֋J'J-\GEkZ.WchKg;J4~RU>3Ԏ=0 eS܄j1QKic|]W{HH6#%Cuӣ_9^8cH*I-`"cB96oGW*j !.d?Uxfr5oAJ]DP50$klEC)s)P} jbQ"R  u ar$fVHYv G.!F_QNjd/_S˩'/McL ׺mwn1WS2휞zZ[ Cf3$/yT= 7g֖ `ɤQ`):q{n|e$fsbqBG_#"yJi׸I%Zn›J: ! dyǧL[eD^8"υ'!; ˫,e8GR6c_6#4ގiÆ&!iפm/8 ?G\M!QhHo@=sR0ܦZ&%.  z{?>\,ŐۘҠD<Ugo] ^b\w' \|'i6¥\ )ܳ^-M٣C&ZTu>Bi@-Gaylw7u+.kPҏJȈ-_WDW.$y#xP6^4}gRܻ"PmcE+`Szx0'C̪@@[_A}]WUS8 (n [;<2QpwOQJ@ŲFM/Hr;ghm v-Ѽ5Lغ .Gt p,bDVws1ltT}MgFlcu<E3O^.|L^ׂoi o)y)&&95wkV1H&Z0`!qo=ƋԚ1#+0Sd 7y:rzh╛9^P] !r?rJYx)ߓ"ñ J- IKNʭg6^:XZEb- @㡌X]_bkގt9;sRh!Gr̊i{T\ٜ##gIer4 A\F6}-oDLa'<{QZ"_@tvV= o1_p0W r쿦`  @$7^$T ˹~f"q^$aL,~!ٿ#7o7cdnfO5={`dیITwB rhQ>%Rkx{.*'9SBH_ TRVs=q=ƴ S>nv.IB$9b[c=Yd IQOC k8_>qT!# ߕY]1YC]*dž#b?>OBϹ7˟.6#z{筳=@ֈ5W?K|/IHo ;׸Q*ҤlIAYɠTJ'½!e|ͫ|)JL=[(x"\Wt JmzC / >~ ⣱HRfܦ~ ibM8DZ[K2 "zR_=ݧTwM /}5NqpkkzYep|W8ƒmbn+@*%UQ>|Gw_i.8-$q6o`S!yMa62LQb!BF܌ gFB^W $9L3dlo/X{Y5Ns/bO-NlTc,Mm fDA*pBUWmZQ I 5+u 'F=r[GfҵZa îTq"T;# Cݷ3f!*dвv/r~mmf_ٞA^B>㒉)!<5rK}&hEW`u*{+q1Dgf#c[G.PX~ոfcƚlniwbvggEekur1Fj_v kql4%L[ JM/4pq` ıEf\ZV(mgg$7U '9H߃;d h}w:9Y:uכ {HO0 mqEe+R%~ s) ֵzzF#}+8YtQv#?[oSv_Rܨ/D֏D#UZ%'<=Vrw H2J8.lu.л'Mt9IT>}ն9 c%/B0Yjɺ>!>q[+bȯ.IQoef,I.@(CGvCOcXHRm&PHqvJ`5$͵\6Fp,vRwv{\1B;Q);W%m_Kk<20z\X2bD@\g6+jb?Q 왺*v/AA9b XyATc{y;Ğ C-"f\{ӽͮNvh)Om'}yB˖R̩[]\$m;*?r> O[T?C9:q)`?*ΖVUpC;Qd[rɷxoY5a=8C5h!Fc8ɑ%8p F[1!|^A$qi$؎2v֏ 更Bw-; Uj%t" jޝYo4ZPvW>G/I{ KއqZ&  njjk]spEEN1;|uXR'T]~d V, 0} r'h!7rE sJp2U^(> I$ϗ]4eShկ\GzhON̗ iF=H4;dJKaͣ{A%93^6}[)tg:] +=Pj?4~ӊ˅OVjC8.+J kηv47ЙCp aJ|'A3qzUE|Bc\R=(4_g(+Йˏ#.{ئ 5bVemYF"K?xUeSX%P~=z[WLV7$w ܊7Lvoy1JYjnU- Ny)|iWq"b>.~~/30m$[g}-weǰI7'z,]23۽*XR?3bnwZaࠧG7;*Ȧ h <0zc1"ǿU߰?gl$5NU %l!Jo&P0W%@s u!cVbÂG8)nI]v /!Aُ5J8m=lvnf^,`pW~uRalgdsUkHjct߳1wMPLv9rZI<5p"}Uɶ/܇ah8xCԚ7P-J*dJ8 3BrYΘU/LG(qS^Lc-A:P?Πv1ř|O>-VW=6Ň5' $o'alInr-GMu~0&cMzZI%k(Z+nbV9}sIGq]sTnIQ)Aǃ@>Tڕu:T$'C(Ϊ&| D2lKBIJZWo=l\Қ;skzU<5_\Gn˨TWHDYGW9SkH&D9^2uR םCL fUަJ'l(=p{LPoۅ+7Uh.~ Na(Dc0 үFУ8*0 gN]R5sj* \X}?7SZroY 08֕g;D=,>`kU`J%ȅ.o0d㤹9/\掶i|VTQ ;uY8-QXuͽޭ;[^_FK@H[WNpJt/;d~/(+tu8N_ +>sâ8ʮrNݹsco;e?/>(jP\JYKһ|su?կ?,yu-li 1塝yG[O`ic-ZWL_NabB@š "Yb pb¨"!%C NOZ$YmM>HQ2]9Y3jj"154Wkh2Lp3ݍA҆-m0jdȓ T]6+hɛ织Huv /2 86\aÃ7F',?]l(}Gvq+?^4VVX1uG abgpÓ/Y[ =5ߵLa)D2L:>@c9 =&<|^ 3]14Y7ųM10;JV<+?&FBE\g@ c[uxd JaUV!Zz;hP~g,6 RN{;8*1~e+'zܣ7U8bէ] }Mmk*Q\.V/ %Oĥ)W3dy~h#23bɦ2sZnQӾ!0ӼJ-q)r˩՘gIw0:].{$Z fw&z\eazk_/r=^~7,W|Ūξ,j3=7j~. ՝ M[%0x/T\@Rw/He?3 IK*л݅ K,JcT(TA8̿ Y)8d_ Xh/h _7|:D|IbjCHiJm[6GF7r#?@e$?9n{rQ7(%jv֎u-߷\&\CR[?"z-4z7>97@q|.7%}ކ1Luz2ȧ0&9vHjAg ]i8<͠Í ==%mjC OYԡ}Ф1._Kr?7;}TX47L۔m(5H`τ{UNJO/Mf`?.]<QYx{YEͣ;6 5_}a{q7ٗM,yԘ{#Ѽ9hf~M.w n3ZqLŰtǰn} Nʹ7w,USsFO[o>ky((,#qKBz~j@8/]ߋ"{!\k*)&V ㍜ Ġb$.4fz,-XB[HJ)vn @pyN*D?Q5pmaLBӝTK} \dvkj3}i>1XR"~F[E(&=hVҕJt &T KZ~چ0v鯥l?75" {T~Tm3^s6xZ뼿 uU}q^xyxQ{1WeYDMi:u#+ȅ`0a.y.{ _kk,0v=i"2P5h~GB6N"mLl<\՝%lH:9fb`ܞvX@r(uJbyXV;6+ލUXNJ!kkXSt!9ĹCI^g=)(zLF tm8e'kI"MĀuE)یvZ[::i;G "E 989$hW%hR] "%8ÿzsE_k4L n[|ѭN'NZ5sM݅J;PC= :&m:0˼}-Y,,{X0cìRjyE\ʣ=&y}+G'c76?SKDOtF3G!pY:MT2W`Aa&Gp8%vHU O`¬G'QRFD#j05j|e0֫>K!/WkpdJ +oD4ϽQ)6n79Up/ 55ˋCQ=6=gWXP{H*3;6,-Fuǁ @j2 7$t>[1rکRװjCo鷟?Ei L`0##v*{|4=/m/C]CI3-2 :S 8E,-^ hn̡v҂pgPʫɆ)e]Zu'󯌑kSAFD p/X+X$hV᳷n:C5zCl)F=,{bdծ^!)tܳhKfn0?-Q O6 JQ]yw7Fa{d_)/vs' { eǟ&cZžӰ1x^;[s3x Fg/'M k]yR>p/,|0GUPˇpu)pV7&-2Vw,n'S ĄI[sݒ1T{NSK`I̘,} 2dy@nj% 3} dM9%%,T1DQY*G0eF/?M٬U96ԗ"PgEffƾ|WTb Uu?h.A2A(ă#3k8=[0ٖ\?i m jȨ2WVaUfG=B=#~Fe. }6f8bF^k ϶ָJ=\Q) ,&Ƃ( eXE`[e繏X77_' l^B! uzԉIw"Y;Ivĉȡ-T$a%B*m3ܝkj5[e-w?m+He9x2F2CpLL295cjt)TOݐ*\=tN8=jH7bkNb4o py  jvZZ1Wz[j]TXYȼy_Tu+"铼iɽ/ju<5gx{匟FqmT( . p@q3/>S~0_iw]Q= j!SxhAnUt!ҡ IQj,m=qmC ߴ k,dy#õ$5\]S-DǼ0gǎpoy9,}WW\aSOfH۬Syalft/w~!ktd ͝u(%;nEʃ?Yh"'RuϰJQv).'TnK K󍥲ŹnMZW.ØbN#f/N[eZ[fN{/q'D j Vn`ԝ ` _~ݷd Ԟ-]AӆN 5~BbB9?\F|j.A:t() \mݼc\!E4a#$G!#woC四m܋ բߛ"м1@υQuAy[K̘'&]f[+*:_Zݫ;Ɯ߾r xFjAHm/ZIݬ~&YSG_wܭd]VU"y}~w` yif'p)r9%ߐD M;Ȼ1S1IZ~ޔrdy5E֋>\=Bj/8:l;_?R Mr34X9OZ>nC7q1,ސh2w/$ v~$U\crPm=:ˆ t4vS 芖g i)727lF)<$@"_Ii5=$ ;UWe:Ksӱ҈IxgB`o)2# ] 1$ 1!t IvtVꆆVc!X;Yȋ/?7ڸR?Ut/O7C}^>YB,D-/SO2Mt=RF/7۲8_$%\MJS2}_6kIޖqv̧IY:6^YPcyeb[nZE{} 'FfRtCwZ83APu c6WԈUq)2%0YDVW6f\EmѥeH?Vp "!4j93hS<0)d~65 EVf^q^U0u|0Eoz3t8,ה闍 ߲!}L ƬkYni~DϷ:wغgUM+&Iy'|_)a5LsVCy sByy%qyWOm 젃snc1u{?sL*GMrZ9]3eVdxqj\R~I䞺@,mן&lqԅ{v2_ Bn|vQ*ngGEN4gRF }d={:T0;01'{#4$1W d `Qqnwގ>:3S*3h4 i/3D'#FPr1cV ;<9699T5@*Qc|٬JWKUWV*/1~/gY՝ ۚh7ԛd|duJ/sEEhg rïp WvֺύƆ+?>f}И7ip%QGNɢYt5ZE}3z-[׽5ixIX5H\ycun 3f2`{s[_6eyGO;DN n\8vjOr(I~]7"t.{VIXa~_8+446ma!kgsk41xE$Ӻ"(22l_ AnMRs!㣯?*E5wп;}@ْWPйn$kH:Xnߥxqʣ{?cS8VB ڞQZSl'9٠y[Z7tj k^:Wܥi R$O_8g;Bc!>V:/2| z5N) ffx*P^Hppѱ\1쁮!r-ŷl-t8D/4^Uz8Nn7˭X)+߾*( L%y)l^&Ci˔ &I5Pd!}kĊ@6ZyG7f .ׅyp ɢ,@N~H&X-l~aӌq0EzybLHC'A&2~5hW7GBeWg4$,6$:N3t9m f||#>֫mPÓD-Ao[R83ȼ'^H򏡕ڛE L;.<^9B42!$f.tFyrEѡW!~K;8PRPD0.!-/)ŲWNfI囌 [g0d$^')nvqCe/g(b ZV-9︉[ zƶt`5%" =S?ۀ(P"jXriV p`(YKEij5uGф`fjv 's-ߟKD[㔮2'Nxw\/@{z^F4ǻ8aMrP+VJ7l;I 'ݢcI[g 7VdguxXQ?@<4E~i?c^@65#' c} DBM_"4R=10ċ %By'V M|"PjwL |H}\ĥmҨ|wڷ)JlY&ő  Gѥp(ij`$N,x}iJO<'7IJzun21ƶu#w{6=]ĒƁMʃxC\V͍VG4ؤ`cZ@υCEo0y!1&"P|5Ka4(NpCU99qE2! "yPP| gs*yc$]7!IRs[^8i wsĝ=A{-E h;gp H)~P"ٽ8(SZxT(JTj?~Y/Q#l҂ʉ"D8sJ EJ݂9xS~q"P!X" 8H gGvўmaJ#R!쳁4ck}$.Ԏ p )᫧h.q|mclvc9OY޸* K1@3O[ !<\T֙qr>d76N޾s⎁: ڭ\3X+*mcjHl&GD:|fd\W1&;g,Εc<|R$l10\b2ab8 Hކ9!BSzga!S ϮI,*`9%`vzh2cZn2Hx2uv?`Q]; {siBYAXGH/0xcx^>9x1.T^ZZkYp}@s'ף8qX=ԬY"EoHZ@$(9J`73@۠];%-#\2Gl/+ۚ}g8.m賫"ɑ]|[ķ(bHSXf3Dד4T& wDgiejhYTںB"o>,:{&LlRa۲}ԜJKzH2b0c'‘\,imaKyDQ\v :axd`CGKpyl'o]B\4Ka-*VY8ŕØ ^Au()2gbʃ뫃 j)Zw zXbe, Trr$/%ge^B+:܊e MKw^!P鋀{F5߱""Dj~DDD*+PZYd!DJ =(QC i+DHkE!m3 a$'y?r3gse;8 %U&e:M.̠#y+.&ie!| H[ wa,a*z8ULVz߂x`4S.)BҴTx:H[m ,sb>yGw@| 1kfWTIiq3^hJѩxHQl$8kI4eLȂMMNxwP_Eipc5[!Tű/,{[5>(̀ OCm0&^~CHFGfP*bd&?TvG-M||gW?/i==NapB pA۴K"tKܫ=n$q9[X9=mH\# ll?gK7)< P7Z'H,]T~:|f/#|' W ՔSvwl}ZNͣЙ mC LWNY炞ꑠzWM%g6<Hvl7guPt{~f {m w6&XcrޠCm_T zZ۲3H<䑍IGfLZvc8|P_ N) >98~5mW8TNpi[%wz2 7cƒZ |M>|]}Kf>ߠ2frkLDfM^[o>y rPY_&<H0sŜ줇CRA_ v)ӦJVZ{IԤY+\?ܐ*[vZaUzEnFɧ&CzKGp=129dlqml >vײBD񡒸7'T8N%*3QK C#Q)ͤx`OI58Ry;C?JS/Q,8 V`AP%4`05t jV`]"%?8wr4.h] =0M.G=d?d}o_>>6Ea-G}ϓ*[OE 5f-E[vG陟/TFR)J| :HjΊ0,e׭6?o^j{Ϟ/\xV>e#63"y! +?;;x!d:dsۺ̜Zެސ}`F_81S99s=_V|5Uv$DRc߾ꪼ?9't-xDFvfwכϊX66NnX.xD-*f)UUrtt8tJBDz#Y}V!z_:Q#2fKpExW6$'G1).z(~PVe4D O zWe=\#]Eˏ+I4C`$ Ŝب %ne+J;\37'? 1qJSϚO.Kf*!K5zSA\b+; q^GiZ߇boq۾fZAm(/(F PhIuL#xեX0Y6^$5?mGѿsHCNW^pb/?D84p,О:O3s\7$p$*?<)b3@ nY%Az~:۲kF-_w}hg@ɉQn ƑsaŇdĎ%-+gW`s&Vi@4]*Qa +c%#>3SW~ %[L%w w5 ^)%|hw *l~zK_ *Z'4Ҹ O?EPju*vv;QxÌ.Jiݠq }]>Ei5M x 6ޮ^UѯӥI$n5ULɪ%G2'y23žf@Hw4 |ß08*ܾ -yɶTyM8_y<{ߪ?1%3j]H@~C![HW@t H<42֛kwZB #蓺FÉH`%‚l=UyzqڃG8{{b4~x$k+dٺgE:VCǃ+SG|H5N[#=X{j.,^\QɞY,WQhݥIRkuYJwf0}raI7-]MaIh9$m* (mU< ]"R#6˞ xSYڛ27>Zm/# gUAYh 7/>4˰0n_ a0;m"ΰ6|Ž!ˮwgҬ**/`[@*TbKX9^j>ogV 64gلw{“2s :ON~V`w{.8ܹTz˕GMx.\Uk_x89>u_^e5R\६"m FOK2PoOjodBTxD>YSF: p:Ox\lRQXAR!~#=>8d(ZLPWQ}uccc(F^hЂUlR(k8kAh2wp1ڪA w(@Qs4"^C S3j1* 6y$[\ p):-K!6on`SY, Z}ގ,z7]jQLJLNOcBf7}?A?io+7>mDI~xzc⠑E3߸-Jg $[BYo> aR7~3TH&Ʊsj|&YLzK+SӉff1-{7ގo"G8.P1%~%b'|˵VAoƗor?Έ=S{$8{9M!JTl~BJ^a6*/NX?"ܠ!](wv9=>-YibƇm5 Ny/[ݗS~t::ÝrX?ϧ<4v87''[9]6i 93~b H+fAL(BSZZPY> 9{VF# kqxE"|tP'#(z\?7tIy+?Nj=*EҐ\.Z(EKc*FBCrLhHKQHS!: ;.ָ0P:Ŷ+AUct./":)$KVm,(zmL\L3.ILP'= xt!YOܛq`cFUm¥o_܇0?S06v\$競AV0lޮ>j&&^\%q xP/@ 9osYU>ҟnbC7gE'߬h(G̟xCLո b[.â=[jSI-J|:qɑ͍:r: -hWBBvcxtNoɁ+0+'ۮ1|zp1;P *iiH&#я&Y84s5#aɗrdu\9`lS5vLFz%4"F( AGIZG uRJ}e[[LNTfT٘uH$DEK͓hp~tת!!l>&Y5.qCkEϩ`雠e upo@|(Y9rtmW @߸厴 rnN_ Ƅ;[}`_/{t:ʍzO~5̺}'(ewV`]k$25СjU}D4! s$*u磳ؖM\MtȔw xb07d F fj곟%[#=,axQO-}CYX+#aC8i/Զg^ p;}kxK˙%N~ন/?/ᇅS@YIqVE$9vNrlnh?2.bEuY&8S<$8 %/yY 5ZChFD/T*\l6Ic OtY?I4"'7{{Gp69p|{1U>i&UHR>P;ulk@=/LNU@~Shhy›rF/}3z{r^7[-|_ܚ]b].PAsx,"xv35:d?8àq[TޡvCH$e& GT#\M9Yݜ\$%@cswxמɐD9[?VR@y01doc!q hve63sK3T%۝1 $kW~U8RAfs)ܾvl )fOS孆}FGݩm+Ԑ|.nϻ! , G҂w  0. (XW)LFl;. 7\⡴}cV|aeB/6oV`jq:IjiIe' ƶPDzZQ|I>uC}bJܓtyd9p}cf gnPKDHߙx *+ԉH5%^j.*; >P"K 'qD֫-lcJ:4ɉ7?},w٤H'T˳ƝWa6ܫ֤.λkvo]({Clus-m-RV߹nq%蔂5 ϰ Ygs5YOjY5 ;ע^7ϗ>xۘh)aP0jw㇪rQWt5.Iχ-wSsThNvzh'Tϯ#FHid&{[GkDs5q1N-+0]q 9ֲaՁ. 7}}*'eNIHM *@S9HvI!GEJK!MM@dv]<Rq+M16ۗ@Rt!A^5_\co*=X"'Z%7!kF:BZBR4%=&eRsЉpɻ.!{ΦSAbiuPIc"FT7T=Iߝl;̚vE}b[nZVn~{ٺŻ u]jt Ft]~{Wƛew:>k& ,RMpE: *_+{mKTN=H# .fPl_R`"JY ,di 43fNCJYGDE\ v]%7}.K3f4jY__O1fw%x @Q~;UQp:LHeRAƣfV_d"H@$O4EO vug7o'fN7c?%Վ}|^ a1K K>Ŕze>Roz| Ғ&{Z, B-GS5]l"\PKD N.#7C?zPpB51j/AF<9gB\ F.k3@f7 O|km$Ŀ$,Y*s҇DbTK{}/'3h-E >(02Ǹ\I@A4׾cL(t'f1%S12|k9^'\mϬgPK(ズbZP#hCvRy 6ShXOĀV"AcCG!ѥ[R_#!gNYfg$t''6pHl-1,ghve݉QǛoNy&AQ\niok~_#=LKZ '}t^4BA |U!*F, 6ߛƉ 1C'Ë֣GcYW+ y}Bng3GLVyU75:ҭg#^ ;yW4jbԇG^[(ʼ_k)QVrbș4_3Zꍀ2ᦅ,F LG2(O;CC&/(ӄ%^ȺЬ+.^1߬A΋I\ejPռcz bAWw{+/Aer DVep|9n*6KCe9IQ!K%Zr sGd; E(n=')%T]UF =O7BtOl紧<#:+Tׂ#Wu_6zXt,?sŻr&`<]k"+Jhړ[u_]Իs̓["j#UYpPDRo.j:]NkBo} p L D9fw!bj"Hya-xM1M]`x5m=i;&ff-by`8R37,xg/u&~sJ^\+^fL-L_lf:)Z]DܻcC_ ~ʧy|Һ۽fCnjZo!U̵0`wD"c0 ,񩈠ϐ?Ogt,pmu":Іyg.2Z"MF菵*`ߢs'k=n?=i欦 m_҄rõPF}(a+_mR2"rF_ϼUvY=)HH!VοրT[ })Ug=BZ ;꿍f(m 찹lUV98+06!ځ-"7.W)ЃC\A3堋P 1Oڣhyo |oV`;2Օ"ɿ~re< Giζy]V⦔,X;>} |6ؚ39:y~%(?9E !\ŧ 5ЪFww?--&SͼjsCx$C}h`06*Y-?fg~$LΎ q|GT QmJߒVK;V~U<|2:XC)/׉\fi#Kcak>Ĉ.e몆>DQPs{3mxWukq\sfTK>9gnWLM2cf BܵJ˿PU u?>bˊA6_[.9AŤoj\hVd|I^ {:5I&WpVo%F= 6B% cKHIh]qgAG87GGʰrU3tI~ CY49Ql-ڏhh-k W]S~qzc4ox89P|im{rZzb/UECn9,@ʎP{(Hk7޻~q|PhbMSS3lY3jy]mZI߃^S6+0s4=۬FFY`,y6[g"4 Ʀ(B Mbå4eRr&sdγ(4w> ʿRr(?ѻ.;m//jX6dVm3^ˆ|-boy` r~!YX4ɳmi0S$PKb&'.6&Mz󏶲޺sBNUDV.U<f>p]!D(*$W|*a6+ѿ^uBY#IcZEP[zDMfMI'Q5ia}zԍ2CvwOAH.(߅"tny6.BB$3fM2G6$86" جOq7MH;PQ{SB6mC-YQjSwzI\s_b[ܻɛԄnOތP/Fz_bgD@wצ4N*SP7cӐ94s,%k%qa2R̙tVK!!p೵[3YBZXϱEPi[3Q:П}R0Y~7\naK18:?k&+ u$Z#mL#ȝ6EW iJ4#`E|?.(!. ;\i A}舸;K,w1g q/Ha29I\]O}P)vw$g'Z圮Ԉ_ӤiQ ^ml!mC .?]T>q@Sd[+,PhL\'%=i Kx^!gMyUYFheVv.J)C!;7X"y  {16-ؠ!g)eeF30S$Ab)'NWVFA< `Ľ݁$iBA rv#k|קE?fO2j<p" 9D,Z׏=ӎŎT˻!iCR=c{z{ʹmP~䞬pI[#WWhBEEmCj?W`xݑt3e]E4#)+VvW45vv39-x H蕠(-6FEYS\cIq.õнx}yyymJpA+Ϋ̯˨njPh:GG6tp넉c/0^?z+)Զ힍Fާ(vP忐5KUeArк `c NA*ǒ&fr"W`Mn5 YoX)ajF͆>*\%Z"JqQN'ٿjF@JPClNsP~Erkju4ր%AeU!-y M;]'9z͌Pe˜2Md,?璖ť'+C]׈Of ZZCK4"8P.E' 8Y{M;(xz|{fO#j[yO?ܶ24CU8,ߚsrǨdc>қ r ljZKKatt};P|Z|2Z8aBFgXAqmA5us$ #1s?;`4{Yi *93웡;Mh> 8z 5 %m aC 5 V<׺=ϝ} v)A zP((zyL0[]7IS5 IoJxpYu?'c~Vه.#g.*gMI@q1wf ! [kY/28vm‹_y!CKљØz~"QYゆz*;H;},l! wu$d',ft ̠J|_a)P\kXA/~$ _h bY&7DžO{޸jK@@j]eeK@f4wvB^].vd+UȞ$TC$[ta^\Dꨥ[LM'!> 6(~1>4D-)^a9![K 0U(jԪGI'lNk}Ud([smYS֗B-6߾ QE]Omzsɗ-: ӝVn~t:f4:1GJF  Z(3%!Kܾ'te5PNο<:yӵ mqZgw>o*?CnPW`eAomH $Bdo4o`FQx=yq^nLqYs3;nJqPWKLPp3o{CL1'mı^M3dѨHFy _O\bZuo^ܛ*ǂW5R7TE}#}w֩'t94oo Lvi9gͬlzd[z]'ra+Haٚz@&2黟rBa^C+.FUf`oqYZrq'|ÝNlגچb e6rs} tngzŝ- '&RosIhk: x@+y}:X)1ʺݩa%vRvOҊΩBc+7&V\pTݚ9ApO.q$P}ͷUbH\@<0+|0*#W ܴG: \jCׂ*-uin 6eQJgMϿmbՅ ak(X[t"[gO$/ p F^j~uc7O>x*+ߛ橲c˯~o g7,6OE>{tg"tp %x{Lf:!4LItmZO0Q:/tUY !єD'*ܛyuصt|W'ߕ:#Id-=g#?{/M/Uta g\\YOBÐX0PC=~q0\ B3rǥέSi gYr "kWt̖-Hѡ'@݂\К~ŕC0~eĦnI## .cZ{A/Va;)r"ۓzH)W累>ަ;t-(7qkeQ{(```A֌ K3_ |d;}t tzo`<5i4VϣasxOE͕U\d-hcxȊG|_5^<ތnyY/7+q B^"6zObSSi5w~?ԭ4ĪbEAhx 0Q@cvɻ\V;90^3"i|5e.D[a3f1 3eJ 7'/;N I4\I#>RM,!qpDwǑC6Nԁoْ1?&vLꇔ˝RU@spkF>r\iywcs/rdԤ"<ЊӸb| L8/Kґ76i~ewqV6b!boVn*~9|tg84&Wd\`36h_O(27 4N5M!]QxϿg;^˸4]xL^D3oru]INѲyv$ĘI%m_ MV>)Gj)kXrmi0[B|P!o"8h#׌` ܲi(8㹘Fp|E F f%\e]F<_M@{XOʖZa_Ń>Ф<(Ŵ3X.:UUf=[sy$K%<ўUmʃMQ<|;|'!XTyS~ 4-93c>+o"WK::Qm{z%NweO+;u^{$pr{޶eaާip:7wj?_Oi[]mfjA4 t~fs@ua"B8e5ʺxtH_RЏJxSl(2k4;^EL/t'vsgb~j073J qE޺kt˲ڂU`iM!%;~ ^y`f=(*zl(ԛt}5. (;"^ca;͔[fiV4]ι V8̝ ٹ.?BlOgD㞀_4p[q~3$6?IufyUA =ܴ@ntӊe àaR GSBCSImzFIVFvx8e,Q`C1门҇3xg٠?bd@8ՂHgNV&z((=f"yjc^l82A7lfQOS 9P;XW˷zhiieɩQ*w**)6xild{ 7CaHr2 t(bI'%/Ò1utwfQCr.hzvKU7O R;ew:E⼝oQ~LDfi u,GJo'L5 ]!ՅRl#ÅjiEx"{rt.;`/%I1b 䑪 bͪxsc~,Ex߉€PW8{AjZSpe`QL* teѻ"Or?KD %B 2M-۾wR5~>ʙ"&V16@o1|of2cl\yOE+נAek Au"dfՍoل҃,J z tHCJJXG(@/[#5z?`jԁI ؞Ģ} ito n} sh[ ~3fǖ.ǭ}hef 341^ߥ%̮0Xv5u_ҎG)%<Y]{;NVL Ky(` !$/r+J2w*oq#( ßo|1SVH9cVo]NI $P5Yg͡BTT a]HS?~NIՏl2!j8#י6NjyArZ[8}?yd:X +GV!|3W(|X,Qm7=[9-C.FA*TԊTZ/uoHnԁ-KhV.+*J=\3)V3u^!Ei] zGj(c=.sDjLQ}>Ue7(ts,iUo܄g ي hD07Ppjfm(?B-J$?Ik΁TUot^- R;vo5U`sTOXxA_CܣMKXL PO; Myhxyv \۲I@MEfui+ y8(yU[ϘR2x==Go4fSu&brL˳Y n+C T=_6HY K9^rT5YcF8PU_3odԕίu;ݍ7yPzdpH~24`wƂn :d.1*?|k1'Kt4,!_!N{W3x hh d6-&ޮ8ˠ[HD$!yeY?+]%,L U)YtkB7.t4SKm]&,^~hYk.m'@x"Y}]Ϟ g˔JYG9im9j[Yk^ uE{_7^@ ]f(|_~9[h8DSR?.QFrshuBKp#?)t/HA˼NMÕMmߠO+V>ʫ W)pqF8v3xSǗU]7`Pw?MKq`]ƟiaUE B/Nj@Z0rU`1i BQt\\ٜڡLV%0hvi,/CtW~M^i4_v#Ll|/ u}|1I~d`gOЪPv%4@xre`mݥ6P1M<Ի~]fLh1D;r"2u]v zy :۝tDt tfzmmD|T"nY'|{MRF<}yMedS?~[Q!|tWa`0S j\.#`EiA?y8]zSFk^5ҽj򒆃1T&-;5`U}H d#P|E@qA<ыoJ ,7YSn3æV\%ĽeK'ԥ K!9k" Ʒp z/$퇥VvvBVȺ$% mDz;OLİ6eOF1v\# Uxc$-f8+A1T&;q&/U ]nԬY|vdS-pـ}PF^$wq8|> K$ٹE [\i9 "耀Kt#shyX<yIIK63'(1I~G9Ҧ(L{gɡEfw,f_PhY -v^`߬W6QrށY-y.a!Q6D<@$$E :kϚ'ErY/.x;ݪ!6PL0뽕pQt *=[j#JyF MTxc` b~P @L.U;c 45Uow\ü摁ngٚbTn'o HEp˿mqLnml3|&C񝩄'ϮϠ3eaNӎsI}akyE[.1:5)[@.&BQڄ!Sτ5- ^vQϐ׺{J#9?8P(ڸ;f{,QjX u_b.a.4:u3:V+S bP80߬Ȉ+}_<?#=Y_b˿uc(j/;gW:Ո.%yoZ gP$2l%VeNT R#Qf TSFQOװDWSpdF,ADmR`i k-uFi1 I1ۘ}&2ƲVd}jb_8nl^i?pO04ɻC5+|ixPuofՀ# ?b#RPn褔*XL^ @tATV>)w^R+W9JE[%:RO2x2o!EaJMn⚫dUx؟7ɲhߞah iEуH9v_P.`a%9lj.l;5C*DnHBN?c뛁pcNAuGS]m2+: ڷeϴ]dy[57~ǬE~dKtLCD UNjBlqe8UD;[.tlOp/r㩔E;]a쳝'+{eiҟfX?ra_H\)<%\]^jm;Vݑ|UǢ._)LCJtRS5 aD4A(r5RdzN^sj_~3|J^FVf;G]!EzVdSREA+uqDǟ`ZEO< xU20;b Mh!B^@|XWeҺڄȒ3״ekjHmĿpVr0l|O_t~Z8TU:i ľ@6x]lo! /_zcKa*32uԍIw$糑W;Č'G;ikr>տ{i SB#nO%\S3Ae5,x#rOɞOb˰P >6/IXccan0Җmf&1r !NnXk<~fnfA*OpJrr6M݋ѭ\7/hڠyAyNRz7 1 i]pج^{V{ XJ7#KTƜ`+j,p_d|8?~]>Ϥ&SAӵ):Ch_:^yLl[qž [!qii)y~j3d@.C>1zE[9Sf>5_Y ,h-rL^;׃B3ig {ð1ZO7!Z'W^1<"^]}4qTCg "N+dR;R!':a{Gv?&hANA?[l.JBXD_4KpWϾ\l tb t@RiC)B 7R8]9٦j$?_x7uQ)qrsE>h53#b_gջ/~ա{k:,5[>)^8>taWn ]UJ RKűMIڄkQpVxBtRӅ2*hͻBĊxRjtA%A`r-0eP G-W,{8f&̳״uChdch\6CZ&5ON8|a]3bҳ܍xvS>[,DxKDAXT2'ቦ1O6;͊XР]we\+DS2sI%zlsNN!=>w+?e\e =+؎6Nĭv7ýpj; k[ޟ~bi?zmhRJ;Ϻ`CΫJ`R^Vែ5闁12{G|Sqϡ[v2wVa _=CN P JK扚SPv+&A)8z< j~2n 1ƧۃlK8Y|1il91Tau.`fp.^1ڏ[N.v*.4hwx$qtxXy/f@U%-6y 93~׍nq€)B$98Q4J:z5%Ͻl4C^87!B / x\ h^b^*4E eý@lk6Bx =7`J@r"|f==Ltˢ`]&szޖ@\ʚh=Ҋ.?etifY#ʣNQ*ǩ$57w mB-ۂDZpRG_gJ5L!!~uyLӷv3=%9?uZ3 Mչws+ޭH驸ǖnCab6])5Us**^w.@%Ht#7m&?h]+jsx.*pj'n1LQ4j`Mǚ&h~쐋[:fţ?u$GH,|cĪ(Z*WɇzG*7g䭽w!#:^8O{9dxBk8I~`˝$sZi\gi.ɤq M3TͱvϷUC+\w!ƛFL0 a~aƹSlqx>wv6cY 2M˜ESF*5ƮT EJpE2*:-ϡdlӞ:5 YѨU[Ə,p ./eQ{NbоZQ:a\|iF#/3!U@(L>7([*!;޵WD`JDe:}jNHzIF,u˻5mSds+].YWZe4~Vz lkz,|7&trkfٞkV>@vвw3}ffp*%,_A"1=od7:),FD !Tt`u+-Ȩ%7_(\x "?dg/EVт2E.&t)۶!cVagۍ0(Bg-"JhA }89`/s=GNN{5H*Hmյ $o:դJ<˂ɴ5RάA ,xtTǭ ,6Jg7+'~hsʡ*bIَ4e}JvO·Ĺz<N.|hzV]&mm5[gIf\xy @J4+ixA0Po1E3a:nFEnٸ/av;g;W8`xvAcXBIEXxTǺ3ݑ ?yR KvS⩪Hb0 oºL4Ŝ4r^vZ)ΕwuMRzDhL;DMG-J'a[Y#P5n?W'L<؎9&'>Z= 6fQd-m!hYM7M|ykVL KA{F5vk""F DE@$*igje6|7>'}Ta&f)B{ⶹ D1".ZVI_0T in)ًf~.YLm$ds!-ѡLLߍVI֋}Z '3l~zY[鴉股+>rRY_T=7ڮOw:0 T/LL*\V|?jP}V -!{~WPDEBA {JpS龳⛸_k0q@ы`0 h|bp247".i#V7 zE ZhK=^ugsǪ0k+#]^ .}~}Iβ&IxO%7sulqK|'c+Rߓ5XO =* Q'ё2INwmn{`$VӜU"YCYc),h^Φ' 7( oŠT^}w00ؓp'ΈLڿmܝs3qx7N,G)cZdC郔[@cnf#m98TPb-ϘJD*wm|.=803--߷% <`2*p9s[f/cv7 a+zysɘ Cw0s$~MXlHz$] VfJ]\=ڠּ9m7~v5d(.Cmrj*L/2/ j o>n69=ȹ11 =5?Z(p5gEHV;\vs|PRǩ[M:–+[i-rBX*1r6sX{/p-\Nr$S͇KЂ*Yp+c_ׯ9N X'ZcXy[N:1B'ԅyn>1Af%MnaWr)Ӧ39k^=OO{TQ\>0&QVEպdQ]5bBRs)a:bjΆ fJqisKFvfFO]Zx(Z³,np`llt Mw*P3:U%̚Uܯ~s5|l1=%0c]7ޕswgu^>6gثQ#rL5O#NET.kN4 6 k.O&wOx?qB3#'6!gzëVkt :p: λv8ڼ pyEE۶oŷEVKO9ߋLIh̥"OZW+pHJ- a[t~ O(Oud7:m%)>w0xq?G;Ey`{+r6\cRfz*f<<Ξ|ԣbkcWoCx!d[XKGCB؋O1S"lGBBPc!^y/$YZ疲3? q$p0Р6NXd*=^PW > a[I:XA 8P89p`-kc!lJ!f $PR~Eg)?;CTxh"Bkmx#-5@c\;%(!gZ )2" (o>򝄰 S/|EiZrw &85ۋwZf a %)GЖ"j;#Hy25u2]\GLݿ7|4 R$ذjNNe~r>l}_ ~W]]y_q^b 4V~_ue=ߏB{7O*-~ZSCjir~٢װKz4( \('T%W\ΏlZs,jUo&p-a*ՒuSp̡;jCo5Hpʍ*A>yJ/ݷ<)5vW3bq]q esجV(pH8N1*bBCb9tiw*c.1N+S]6kuv;3]Al5:&]Q"x2M=U'r8ދGYgR8M (gY1Aq/oOf}a4B#6QTG|7IޅԻn%R0j|qvW;N9JU9Ŵ읯UM)=o}&?MBj5jDth꼋iό&2#p-&@0¢m@RKug6(IΜ:k|O!UjM 71Ê,D<Tf48w6i؅)Q+fLJ Ԋte :RQ{pWKxz@$V`t2Z =qVQ UGʟ&;8`Ab6pM 'n&<DYOtVpb$B MR MXHFDdtt.bPCԀvZ{(c.||&l6y;6rmĮnVZ^Q7^iEII;Dx ]ŕYZ3TF#Y2);QK'7bcBt} jQ [ kڄZ>|IBX:M_ 5.%΄eƾpB;CVKftH&b3 /Z0s PIZۅ˜N Kx$ u8R:Ps 7- _L& ^nyBo&NkBX%$Y+0#.W_+C>bN'Ig%PE>!̓x:j2 UƢOd@ io_ϰX\JyQ^X5&;k$gmXkx2 X^ީy yQwDkQGx;@F~3t%Ѱ3G;"A3D)p4~JM˼h$a( O}4W+|8#=N!\@X2f. Gf+փ{> ig&Zɉ$MLeTdXm¯=?m{Ŷi6•3;,|ExLE 7FfN]Ƚ3râgN')XB}4qZ67 Y:c1PF0(gYm@jN63Y!xi hl,ӽ܁ 0M=ڀG*`;i8- b0NzR,rjrp[@9>|cV[Jv\bHy v bwb_<ï]^k5OmL z5b_\*Uz%,z55Pz,򺧃-W'g7BE]Kb='eA_|=hpz_3SL^w2jZ]ssP+sl0Oʴ^;( D r |$80R Rǘy~?0HIvdRM%s_Czxi rJ^rR#qFR̎-ť\t7>:ym+nÀղ0H_hO.+aDZY&)7ug@uÎ="0nAi!̷AтElR6BBuX}y`uA#f3򠞍x8+0󢎀8=wh6Uvg% ]|񈑔{_OEXyi^mq[6 Kd Y a̟ZDf~އ=̐zWAj؂Y4Z&DjaNrwF> ;LFך*)cڇF?a<:-/I {4YuuO~ZYjǹLmxqhzS u'd6ri,\A&>Ɠ~LTSV[@+'Ue2@)j UJDY hOJr8amގDˡT+M $fͨ+( KsNvǺ 0?䚹hjiNxTgxH4QPR4/Z)ݒ^L&K?m,R&2_5ZpCc(c.8`[rq{lUUm*Ώ╎\Za޷"Gٜ] HVH}zUXP0ڷj[]at1Epw)/fxĄ N9Z<1G{w"?8[8[ƺx*c;h4.%^%B`|Dl3H Gh鳇Ч<86K&lڕܺ à'0h@lXCiYijYVUqAL_#zJIǘfkܝW|_T>z:Ym@x9;2SyPyVQؽt@W_ewf-.yf%&Y܏C3/)n73lks#C׃VyEQP9C!l])@6dM= 08o@!O޴uUD4Pik8YJ\=ͪ/G4̜.s~b bI~-%bd}%Ǯpk, BR*P`ߣ|w ̉ЦA4Yb+Xb&=+EdSeGC9J#H 33ҳɘL 7[ͩSl:; {ػdJ9"u 7#%t|'R7֚gHitlmm%GI0RPx,žjHj.^m$mu3S&ڗ VJ7): e|A:L0[+9qe1;jKSP}`%ډ\&Z](\c)&p s&PO[ j͕9[=+u)!IgmZ:bG }nnر#&wm&;)ʬ~o^D&B70mĽ&:2(+{8F\~ĐHKm+vO!+3'b˚<}*V", Ku7w΂YM6{Sq45;-ol;:8\(@:;iݯ/*CCKR6Uv.zȩ%mfA\UHzv g& ޳e8$x3@hF:e:btmo&IT.j6!W͙1  p!̯V?I!"P"8jNWA ͰGRAEVF`05R G$ O YFol^7+r>eW=F-HG.o${8q\n$骃BŻr.*BeMʫ׬sNGܫW^&;r{]O3mu/O9sJyw7eʎ7_; G>K93:|2Z<±<](V8]k"*tY4p56MD<-`M|KSՌbRǢwrvgdHy;5v s1lEYG+ɜ YfP5cBlA#1;9~!4q| {N][ے\,% <<b"ֆz8R-G<<0QQΉ,=[DG.Q ~#7[xG@6v S\eOī/Tʷ<0sY/?U(y6x7e$op;V3E\겷rۺ!b#"ؓ,$c֚;ɴ=X9Ua.OnZBxgjtܝׯA| pbu,MWj vT4y'Rr.W|jr,y?JoɊV=1@Y2索ӣwώO2D󹹜6WkJuR 2Эt{-:>|{s)+Z{JzBhy**nW,Ի3T"Is{%K{ MrYE*z~ǽeԾEF=׎I׉ȟ`T`-Νw0Ak3 i3B4My[pp EtO)~Ӡ_qdٙar ex#>/2BlXǙl9'Zkև@/G*=sVs+ξuq-n7|" 7N,괢ٯut|hZa΃YruH(oIx1S˽ڼړ*=ˑ /]<VȏJ@w)bY6Gk*{Im{ {K>mklKxY!軱?.[L¼C(`͍OYe64gZ0OPrFW{9.HG׺䀓KIʋv W|թaNGsk+V;F?4V^(y7d2csxv}-Gk?s٣3s2ʺ6Ilt؟PAHU4hU߱nSAˀ8"a)-6a$zfR+,QM9]?ylT`u`<4 %3v ׊#©3c8>؏k yƴw`qbܑ/:Zx+?lqhqK NUi;gN)nXwm>:vez&|ڽ.?-mZw :`$0Fi : a3 dc_*=ZEժ|jb~Vg#&ıf1Ew N/yBL+%ync*;߂8Ŧ/UeW{s?Ԭ;MK=;ϵF}%낏䭄3`(w]{Jm$p6`C} |3%N@PlCRFM%Q<hN ?9պ:m OpEi4 y(`xWzn)_6To :&DI~LѽMQ)`ӯJ( ejUR#o~yt8 'MpJ-3mب\`߻uvQ mUk'@c fBhT/VbE<1ğ4>;U.{Ѣ:T-5P_YGu& <9{zj8|$"sSLiprV^NNT{uZ.m楳.28sWxtob$ Q0_8^yviwgI;diA7~Tjޅb*2,1#en|''s`r192{ӻ='iw aQN,R;"Kޱ)*N>T"lV};>z+Yp=8k&qԋwaAcQ/NTEW=)'t}aWyfQ.,< Eo~8qZf4[ ewr=ko,S0$ky߂j2jVn 4&30Z?f2uە;0,@o%1(V탘GIo< ''q.#!,>.\BK R2a(6rX$cPpѴ3(ia)7CJїo>Q!lYd,IxAP^u_B^'2www!R$p(r9^g\GQ*Sr !| @a̠j aw!e0Q |K@̑cש ;fkF̶ɗ`_xTՉ~HIcTM&Cqvb{C(|aZ#u?urO($ a=N_&R6ލѿΊ9 1*'gj﮺>Licʞ?|&'4jun>\n%q җɏ]ߋl#AZY +))(8qy2 c)K: `9!~q3oߧ$2zXrAz)@͕,UqJXU{F;E֜˚oZa^_Ʉa3o[ E!RGp׵[Au&&W B^$j_}ytYZp+Rk׺:yaEg`vA)rʢT[Ķ͊Q ! *XZ Lɶ+ެozIvwP3;P:aNMT+AO@1S'79Rr"?+o3ABG-iAF!bWrCv: atP7H$ N a@E rAū7QRx#^3;˲jՆ urU.9[k.VZЫ_oNC~OmZW6='hD0ֶV{Y i_.[|R`<:܉@i}!R$G:vn!]s"nS'X2S-6ΟTbN"qY͡2m_rwWT>hMʐA*±⎭[%~e)3./x3[ZR1J+X~!V"j(lk.0ߢC__w 䴩P]E=91StziƬ=ܟO>˥}콜(*fYjPtZKRnSlJMcP@~ 悆)M".U`]>)*%J Tqc\Fv8sxվ 3n=qQ -I*0m, yvUp[M´AJWTtaHln/?<`A.kpv|;|hBCINHv1DdKI) O]if ae s;x8aK2m;17'6^chzcWԅ0*示FTz<94'P-L^ SLh,!cE/s=%E0[En' svU, . bPoC@SRcPWE aQ;J2FXf~, .cPy9t GE=4b%p@ybuvh 2CHWR BR\NaS?ts| uSR&M%'FQ>gSTsCڊf:DwEKcIGʫE3QZ?s7LP0O5P4f[ֿ7:g aO $L ւ^ 3lA۟Kd$FpI B-jY+f+V^GwE6S't2 Ԃ2?/NGvaVs4Tɯ+-Luy)~q_2P{/SdM~jӭ4uCQ#~xH6yHũjbs1C%RȊښy$BlOM!TPHmaޗ5m8"""$4FDAAcZ"!*(DA&"B@ah! ̐!*>|UŮZ{Z*HXaOBѾR\GKwߤf TX4`/|sɗ&CtfM,_z|Έ]tˇ~KS]%,(0ubqI{ސ=҅Np17lvQa `~P " z 1RiJӗ¢J*]+12%7bLsm1?P$9 K5&X-8@!^@Pɀ9=F/o; @#Ŧ2Z/8 #es"kS 4a,T΃Hg4̏'tmwաJ]0vAyѥku#~u4` k/O);uY? k `߆%4mߔ+?,WB4P0=+cƯjX7Wb?:+=> -N"CJTEJo#ʼRBQ2`mӍi!Lm>  lLl aE #~wd TA(YUw iWo5[fȗ[,b8Z|K;G؅ނm<[7L^cf}-5ϑ`tLW+${=¡ċ@~]Q&[/=Fom"3l8R@B鋩e`L vVJH~4L'_1}>o\#6.WѴɭRp1/ȥTa%љbm=sIqK4ca--}F%e2IOσ}o=~zvh:?G>xPx>X0qDzLNJ Igͳ7%k,ǃ\.ol~m9$1nJv?笏<|)< Vza4%yˋeV[rI(- -i7FQe =lֺ*wȓME-:ZT'Gbmzwy ~nAާs2Ļ n`$ ў|ɥQv//g,\Lu;C8sJQ'b{,െ|F;s8G׈2i^t#`ka‡5I s;_x Y gڣP?/53kz%>𿿿WޘEt9vCᆳc1Y[{ǪNs #pnB{ /g;XH;p&vl^ Ç im[/z%˗K9/yU{/Y2D]v\3Z^&?r E Ac~4\xz=뗼]jn:?胫"=Ɠn*φVϧIbPQc)zj(R$:AU*tN.BK_Lꌡ-f75&G)T \ZYЧ0U9EĈՀĆs\ju;|ͯȉUsOW ToÿFٜDZf>_z/=_.X7#KH]X7&0V *]0J., g@r+)X] 8q~}:7~,x}Xw0p˪MRkR 0Mt)zGC,_RNmV`gW_`N~R؁`S#2+ 4NǪ[g9UHA(ҍ:1Uݼ.a%Ma1ょN:y"\2'XT*q!kS tn})]n5: QJ ,erP[H %mF ˺#Α&ν\%&FdLTˀր: қ⡥+Į).īػ%DimSk.&;^ ! ŋл,\ŸrMe]*L-MRWycn1͟ԝPK)u ҙu+@*s^ f )q{LvaghS%`A }^|gF=!yX#vIhلEPakWl1Nޚz,֎*MA׏o3[_ O dΜà% XYJ4\؈T"a@:&C4ŎEp+ No4Ww= ゙Sq\M]S0LJh;R;[h{AA)Zo8^ngI. 22 㥉&u)H;a T ŜY&(9Bિ!#Eb@/t_'- ޶?_-w pՈ ݽ"36gs7R4|gQurL?P L=A7~cgǷ4}gߟz *_1b(£flztݔ²hMUP"m*/k^ E b3ɉ P'0k jv]3,t!`X ULU Jɗ&$Ԡ]͖b`gt|,%y&|{Un)D<1:0wIfՈoLD嫀S}dj]>\/E6Id]|uG,'y⾓GѢ(bf#6*c21L$ˇoN$GdEB8[0SmC4K^EY8$2{܋EA;LP\㶏ZOa\I6m Up2(.5gRפg2mÚmt_ff1쐟I#_хaJVptIe2D-rB. o}MJ{ @cfє.[&([Pz+RZ8LzA̬`cЦTnW̷{ W:.z;=JA2O佽jwsᳪ6G}7ES lw s菜L"Cs4\ "©ق}КL v `pV 6[F p xhm滐>;~[8҇ ;bAxBL>z#wp[, _\.| CgaΥ@cDB4I8U͟;RUw$CTv ҽ2ĦW=XmU?!+g ׹ub( d#HAw}!ƏhN9? nt?f36IGY/?(e{$FjErEXN߳ŕw0mIvX/'>;ڪ qg3C ):!~LF{8g`OHw+i~_*#*0FC;f_@%a 5L,_öM( ^qOW<-kfI42u2ޠ h-IÍEm]o\Z(75FՈ gʏ:))% tVHe6,F1uu3i0#6e[A~b]꼓 DEp0SB}yXFeנ (½ StE[nw޷.,wݕ! $&py^ϐLj;sܤtN>j0v鶧X`tk(ɵNԤ4=fD~Y֪$\<*~H pJͷW~;kh̭YU)ax{wMd%ݜX~1:4^ȇ(#2pLB l%ê!cU}fH=:jW*,U1c˯A㥣f } ^CYIm!Bdw< LJDtoTär@jdR  *3!`#y&CTeH^Iz4R AzedC,:env6 30D- OӴ?jQc3,, v9:U*֩ZeAO)rͽPX. j=đv0t0h}`gvL5EYmz›.Z% ޵8c1(-/h3.`h4Kz[kc}Q6F.|tlCbqRâSqgUfʇ15SǏbY TRM8|?]G|S`90{8W{jUqÊ cE-YV+|zMTllJ7C u:8eo$j}U$NC<8>f`[A%Fk<ړb/IWkEh_ W WcK(VHU2e[,;Je58*#1`^ݳ%tP-YchCiKCPJl;G ]OOʻs&HSƶ%7ٍEzm6- o}9pe_yTga?`{ 1۶wԮ"_٧ ѫ9M`)ӭbDvըȕݸy`\|+"ѳcNyٲ;?Aѫbؙd@W Qi`da~Lj!4갫$Hl+C 0#]*EnUԀ?4C45`)Qw9mg`1inV9-eK1%2{QBĬ * !Ce3&orn3$C@%e3%Cz @#;a26xm>ܰOl567{AI }[ dZhu" aUj%!ep3Be-lb$!` 8Uw`i Ĕ$9F{.l5NO.NM\Kz6΀_ 3rͱ؆bHC5Uj1S:SgQUd7VN`/pj!ln >]YTwSP+ BHO뫀&/M٩eU0G˱\Cjԛ'?k<.޳Yp5aT3UհHnʯ] ]"'ok{v?@QtՓ>ƖO.Ɂk~D#B{f7g 3{hpeh,Mvѳ\/\._WqxCI{[TzƈFl/=܋{d瑆+ymn{yx9jL iv,5ȊMЕpỺ+o\-J1! lQ4io 7o"%G鍛)qfOXs1؅!K=+|x$d~g{ O7|SWd?RP+He7+^XɻN;`!|@2V/ I` {7ާϟ^mnۛtrz6Ɋ1`"+Cp8|lrt,x?/U:#Q5pUR7_F.N#RCTs>{C+ AMC`Ԋt6dS܄҈kn7Ԇv@+i B^_S%r!ꑊJƽ77,"{ f'ű+4B0WPVh@ԻZzwoBIS$èM|u3P?[e]}Ї Sl`XL0yYz!vA[q0J,ЪV>-AcW ]U^ܶ NjoK9SdQ4֮tnPZVC{j 2ڌ9+XrF\{˓󇜜k#t9m X7nƺ}2.mwXbM?qru.i[^g>W:@:ˣN2v>YF1j1 G,X P^ /۟xαZIWw9́31ۏ8Ƽ,?w舊WsYO#Y86LJ"N&gu8vBFtɴʏcA`ĺm: flA2 -b_)C3@-B،&_̡Vpv:ڝ%%0" βOnzD܏*N!ԧ~k-?B2 ዎy¶2-?r'qyşykPmá{,.'0&CWhgI=(3R0HnT씘g{+If/ANFj`y^C ul9 nytgKN/*LOdk2G }2D&^>QcQYZJmw*D=j~,qNgIS(Js<[`J~;^?DsI|dC8X2"Ȉ͠x(Hm>Gr7"@No>Y>4ԲH^ݫ"F. 3dιuJ} 8 !H; puuNJy34ҚwvC&1#M4+>ٱxӾݗ>;dM$6)11Xv[)j]Ӯ{$+ߞ.vIMaJ 5|!d'V>ECԷ:8AkGo"o p f \Oy},6Z.G& xQ@WU[VdHz_~c?N^"h(>TUb6ӚnkXCr«1alyUqws[)pӔX wT_++.KA_vw̘$L:u^BKNl>L9h9u]<4;[/juߥm)|ϊ S LbvȨ+oUVLvkPem ZφEO0֛Z˂==(Zڵ0!|W\X.>~dݵ|N#FZC| g T-u/!(Y.<ܝh#_'3ᣁܔ9KO9z2Mae%de(P/txgvA洝#7y>_ӏ',llЫ)qluMi c\ ?lʹ9E]35s~s$Vab4h2 -q}A?Rw;F eJ -;GvczmziT,aϑtbP C VB:g?LTe~!ukC) ѥLj5Zfp")@T 6 aRZ!ޑOO M sFrYX!R@CITxBsXF$нtIO49Ы≢:Mgg@/ʷDEMf-k l|on7k:Ƹ־"S(7ّ·{@d֗)+wd4bxn ϔvwK!b'u#H 7VgdU:L 1dge<][  VU2t-T|{,Dtx 3e>cƧFzz=;Iߗ"y؁a3$@(u]RUi>?WH x ڇPؕZTG1lce+V"k[ ucID͑2; *-h < HVU7!yq J h7= ]$4M.Nz-gnA1I}s.:6tnȶG_hh# D ~igtS{]H+0*3f;3&CR)<E &uВ;ɨdWyM5 |x(>k_3w<.h?8ӨCLӱ5κp0Kl.JAw%jC0hë-_=JēJIzolx[Obmd:).){1*ٱlcdwlqL̅#̎ysԈ>߿M# J7' HVZBer|LgQc+q[W].W ?BZ-Ė?t4ю Y@}Mhbk`oi 2j[ɏig[Bэ'Q^Uu!zb_\-ݷ_#8wkTpNYگ64FiƐ?V&V-)2Nh^((ַi qIkRg;yJKPmW&9KuwӾwRt}6lkd~9c\w:3 FO9zmF^J=._/D-b _UwsnDt8KHs?7N[awk-qMlw*Ǭ:#|XαroJ.QrƋvاSg)P(̝2xV$p(ԇz67H,&bjCZ``F imh6-d&ڕ?3 .@'>^_ه>/@jcMv9A:a`ےsl1k+9ۇpмWv%H~o|i* PA=2Jԧ}7A,N2rmmXRz1`#M`@ᲦPH=!"a;Q}l sG8M+  ц'hdhC]bdK^RhLt>ziqz=)NJN!aȨHZnnk1Lj BU:0O9bM7ѶN⨑tm}sAZi+$·9 oocT2=^>Gvc-Ž,܅-O+Ր^}#8v_Pݞmޛ7Xem v Ƭ5yhw_:k_ VCjZpJ#!CSinWԯe]jJ*Œ B%X)ݐN$Wo TEHVOͷTXfRfKޖln%dB],8Oqs݃?xHpl(kۇ;O)*/,*glkuX$)C$8i\kY]#tvo( rcu4&7NpxP2}wD_ OQvvhiglvIasp}NB#].8qgl`ex߈(0I j,ˍdt_rkeGaB''!?N@#a:%R.,ص&;4瑋{ pw/2a>mz'yMZdXX5ܴKΪ9殒raM瓉FWFmRlbs=3'qn{bg+ }ڇk[G.IJ/%c9#zH떧ů~IhaϽ1;l'U/n\g {R7'MTĿ uc<2ī`ZJRps. WўweHt"7-+^sѩvFӿ {^S7:]y);"G-Ÿn[m'<}UOxfkO>E/as}%B9yf;~σT}[X:A6 bgYpcڔL{=E+Sj-Fvb*"P*4 7\=]϶u+|^DY{@L_ƀ彇/ZݣKM7/*2Tg^z) ya"# haH4aVJ)E!~5Z8wr⣡(8۷-U/@Z.SUQRT3)jjoå-ߓ4աU(a ?t.ܒZ]]ޓQ 7v7/nyٻߢBAt,E0^L[tT) >vW1w dd1ΞbK;꛱.7r9P be `Eg.tb-b^ts*+|PUz_њڎVI R kZEg0}R#Z%&f~\50Ap]xJ itlv4kZmS8ǃn??,Ta=7^%C(mm{_F,xu!beoطa'etX QH/$l\ٌCW,'{z},uSz~J]GRUm2I ӟ>L]zM=7=eTb*pq(ܛV늩2k7s$[|mr(rEuSL]F:j}} G/;O,1S^9惕LZ&qt ЂAK*cv6-t(yGZԩ~ սlR'nOSzg[C6 9+,1܉R"3{o3ln9tJ-es))Oe.o4;>3(!yoz#$s^T񑣱g'ڶMuƑl%b$; S2Ċ||ԣ!,1 vSχd!ŨDu8˃9X f_])?23O'|8;&`Sq椣`| 9ؙo?>SQ9χc L sAz1̞6Hg\I<\xL)tޅLBX}K)_XV:f:Wfob9 ZVÁf06N)6J^ >R0=uPѩmf24h富$^Msonq4w]h1&\ ֏6r2FZ׿shn!m֬ȯD3@~ލ -z>H!1؃_MV^;JB{'Q&~ծLZq%?eO#}Q(롸챁7ͥ kc|VX^ vh3H8zUOA2m$> #&Wu u{:nk{ζ/G)z) `(߮o!D;M6>s{Jv:XN앿EO?OOʏvFK:SuѶr`3K9 i Q㘑]Kn"a[rD,E%$j{ =vYz*`k?_ 2.Cl&Ԣga{xȓopVPKSі:(PKE-Pictures/100000000000041C000002BD1B9075FE.gif@GIF87aL¤Ԗ BԌDBCtLbD$"#ҼdbcDV<䜒d\$"ttrttd,2< ̄ĢLTRTtʬLJLľ,*,ljk$Įt\VTDfηtz|dd<64᜚|TưԜTNR4.,\^\ f4BL湔LFKTrT|lfeܦ,ʲ$.8tnlԲTt~tlƪ$&,ֽDZ,|vt||424ԔL^r|DN\~L 4>LTf|ք<s'X9A@{|ZύNw{{>5 .r7 /Թ́[X.Fl{#ZLxzucݎXbJomvEk AXց-ƲgH` -dsržǺG.{7bٺ7NXLXڧ?OXGqH2TmmEDu#,I ن:4 _(TA8pk 9" tm̤&7It(Pz(=pV2Ke*M)O.V*.w^>p 0a{m%f:D&6nr '8)rL':שv'<)z'>~ (@*ЂM(BІ2(D'*QyK+юz HGJҒ(MJWҖ0LgJӚ8ͩNwӞ@ PJԢz$qXPhT*ժRV*Vծr^ +X*ֲfj|Qz\J׺xͫ^׾ `KMb:d'KZͬf7ٸ %SǑT6M-jWֲ-lg+hR*ɌC>pKMr:ЍtφtdE,JֻxK񚷼=zރZsJmS V!ͯ~LkvMΕ6#}j;  a: qEL(>qxT ]*\<&PxF07]EЄgx!0*Џa >h“ Ȑq Ϙ 4AˎmBj溊 ^6L:x&"`= zpc(/

~}$`zg۵ & o@f1~~$ߐ7(p} k&&J 7 g Y{EdUnz@hM&WM1 r|؇~%/sוG csQM0kà&s> y @R w9 vNz\p ް `aDp  M 0{6MjtsEwlf\@X m@y0 Őwhɠ "@Űl\̦:'PRh U bà c>Ph  MuNDpֈϐM؏X}*y},.ْ0^57ۖ&πD~֋ØT"P$pp758n5ŀ EdwQd{W5YZȠ Hy0 'l9cW>pV9o`_@HrxU] [(P eg({$@Ii @df W-V8 Pyې Ȱ xs@ csȎpY)ٜЉgnVKUM׎A9w v_48Ii`") NXp>"Yn>P$ "R g[ 夌֋EfP ㉎gM`> ` sH錼Xj6x 1[Vn# l4 p_ 90fz@ T \g4nƎPnh'e/٥1^`:؇`T'f_h/77@zC]tEovMC \pYϐ c`pDh!`p o1h#M0wU{f%qʶcD@K fW4iJ $o ) jegs tjxʋ ƫ Mp\~7w:" ް縜5xڠp :6lЛ9[{gzs)ZV8bwfo K6 kNz >'zF8 7Ȑ S 70 jIeo `oЏ޴ps@qyE5 1䤠*NGT\ OFzyZ{ ̪~+sugpVnX^N g`oèN~ $gH- o9J+۹+鴽 nig`u]xsǺ{t5øM &g[WI%t-ƻio("8>) [][pp4٠g* pJ׼n4YZ˕Kzz0bpyۿ{Ecۊf9;o))jo[ȫMKfJLz_zT (,$a{f±*M7~;h+><ldn+LNŷU,I *ߧ}9L_bUzs8)lA;c&W% ĞEok+Wg,< s) ,VT+\ɖ|~xk[#|b\ ˤ:LU̽r̲Çs<",",ȳȮO9پ<,4)<7NA|sRP<\ԬP[|YܗLn5D+ȁ,r<Ƣw`L΄ČhX +ʫKL\b >| t NG_w)~[4^6~ein")DDn:̋̚UmEî7͕HJ/M.ȈZgB~%n^-t>^K=3-\n=m~<<}1>WyNMG΂^㨞ꪾa%爺P|ZG^^\H̫,.Թʽ~ LRҫ lon5=ǞuvgE7b\ՠml.yh |y=iր ^nIQ9 &-链>Ӝu_?ђp@P!_3H1(_0Q.$&?3#'/33o+3*6 D-/HQB(L_L,;]HM 僙==ysBHydj?c5+BOPv2LnybݗRyoGtrɝK&Ҧ#vݹ|v55/^o{)#z]hz_=oɌi2&)kocЯt0B'B /0C 7԰C?0DGDO41 J8R 1 یr |h4ք$M5֌tȣ 5CH' *ip6`(dc_[ɵ#ӯ*34jtTJa,.M*ąodO'cŇ%@AT_%.N.O?5TQG%*,5UUWE%Q0+͠DHDŽ(#wQXBvXhXc-` Hm}ۄiiJqgͶ$sv|EXɌ7#/49%/4&䛁3σ9C!c|B"`p[=\XXE-FdSfyeI '&Pjb] ~h{JwM)f0J4qiLMII4.MaXF,~PDPwXUBRy&P'|lϨ)|%CGhf89Nq(0vΠ ' p9$g>)5) sRheP2UAaMk_Re|6lM``6-z[de&^'ƑHM,*0a MSbI=91n`RԨ+EQT.թMQzmJғfp< X B0c.A"P%IjKyaAlF*LʚeՀK R"wܕ0thz1 .J0&ID$J+Q}X2 )@O9T]Y@׸J`P To jeYךַJa~AA;X( >f 7! > 4fLmtG(,KB=Cp7#bҦq=o[7(KF'Ёjj2ۊ%Xa. /\ nac)4mg"q''M)eom 6i}DP ܧ>`y*.D!ae/izSsK,(-٤>@d M|)C-DCoI/x/ts҃f5kOZ)-҈BĿцd_$}_CfcDc h ),xXHH)JsJй  ;4ٰ2{HHbpWgNrЀWц@phAgԀXЂ7%87Q:;tɺx$A0 n3Ѐ_譾1 (78_PA;HkڳRBABt)4I5zz> o 6Mx*'Y:7 {`c96q;pt 7((IK?tE[{~bZgPA^@X cL!srgjԬXjɎld'("$X{@ T @IY; ph 0{ȃdc`c,m;-RA0C221MKg`-~i9Z>y̪P&:d -81AȬrB9wcP x'-rG=hc:[Tʥ  d6=PpxX=lʂ`hHpЙ p {9J=(dHo 4. 0vy>}; 2h&?ft0'SL#ѾVx*H1ْx ̹̜ N2͡τ_Є|4ZeTLEa$FQ4̈硊 #01́ "M@WH_`tTkM8)] [&՝ +13,.6up0`xmH(8M˜<]46zHX&mϣ ܽp0fӃ10Pc voLԝ7M  ҥ!0i!ˑB#XUL 'UMӿ6@P}Q]GuDV0R0VV1.u*DW :@+[\XL V&A-E +kN"Jc |d3ȦsCPW.ҝ͟;}9Y֥P> Y%QU&*IQcƒU96+W پLV%՝R3< .\G\&I+5]vXu zRC 04mRsNԲ5[UM͒8.QױZ&28aPeE(4nxg!UbL]QZ~ڡ_3ˊ +LˌM]UeqcI }]֝*ֵcQ(+L5e˺mV*H]^+ 8*uܭh% q] m]ݵ׉eu_NWetm;Sѻ_ [Ъu~7Y!d)jeT3b)[๩\հǩ:#sۓ2% a*\2,=xBxa!灉0}: 8 `.eۆu א1Ta`5 :`we8]Yn8XK~!͠?5hK~Y#Q z<͊ĄrhUdW_ݴL6+;6Cږs`eaN ># v`]HÏY$+YUrW:92}p֪p3{z{Cbeq݋a`e 8Q~M#S ad0 )Vdш:F^e3)3 ,:`>Ӄ ؠ&>=ŘXfY < sqZ@Q*>h-Ò b[(jGFk{6WW@џ0Hg(kk3R㿼7m&PkDgEP cdJQHeb~?%8\0]i@L 8 0 \v= \NjEuu*;₠yl#jhjC&{SW=>d_j~1Xn疀DVo|fQj? h_znˀfe5`\]\ -h`m(-_mиWy .>]QmH֯9]fF,ɋ${t [7Cqlu58΁ej^1}iƩرZ⠍lJ 3-.r2JlΑn.kr ?3 F#Lȥ` vdX]b8Vu BPB8!a%X(d@~@IӃNLN_Ok[n[qoQ*eY%gAg5Md6j| WWW&qblmn{% Exklmnn&g}Nuz!w-wu>߆ EP 8_ALlxLF:h ~Uh՛s:.ijh HmX¾`R?)H~y.yٰfypwժ'?  6$Yv&W738qh[N ̰'7G{a6osbrWw3-xo՜؅&kd<4}/aى0;·_pxsrU t*eWS,`FPdMm@*xSX7 }rj_Ꮡ\oef?n)mBkqu}eBe U :_Xrg]<u(gw'p~Z=b"8PO,z|,4X‡ R#Ō7jǐ G,Iɔ(1ˈ gœof-Ƿgb%qè;92Uj48MJ:UլYr׮RÒ[v*+/#&;i}(2x)r+)Tͤ*GmِQ,K#[S^-C(w2 3-e©\0֮7rifPqzt~GLT6qnjpyꃪۊHB}vzӯo[.? 8 TTQC9 J8!Zx!dry(QfLxSsU!-_uUסB@ 33NzXfYG*YYJ6mGP[D-X`D@8`s.h4 17̡1HS0EP[,80|hP-$)u7 c+ L(h0Dzho(ipIZЈ+ :M*-^ǪJ%IURj-z-;UlUҹ颻nyZSo6 / 0*M7@:wiXE eVyeVd12]|1MtBP8#E9^@1U^~OH# zq,],أ \NL"mCT` S׾}=ܱ _j&l&e|,g7i ?[tjzF={2{u 衋>Sr#ꩫ:QR7g 4){#⫰|cM|…7<7Bv}d/'uT)Ug4j0 y|~@3PPZB@!!/1#ߪ*\XAEQR%$@0P4RN-R` A o uZ8 ƍr+@ ihS%="x˕8=A UA@hS22~PpX фp q f(9) Bǂq~G蕬ӐLDr",0֗& s3 HM ,WI(@ ~Η>b@X9XnO?,TQ7=|)a_M RJ  )aA$nL!g*q t@ _6㖰e9&BуW`u3^ g:߾c o_@@c\C8^D:D%QX4q i4!DK<6 )-j*+f(5AJ2e';*RA? A{*T "р`DE3/}MxcTӪs4Z^LGRB HСG>;rEH!_I*bK=,_=WYd=LC228/i270+@ D 1P^;l4\,A<84T̘V8߆YQiU@9/Z 2ďl @<4 +lUU%Y.XLKW 7τ!M\rc<;J$(#%b\0yDx 10ė Y[Z>&$]\XORiybu @a}1gbRthfjz^&k}PQ(TA(D 68-AA 9*pFk=qjk2  Jh:"D#=j|} t:ԂmKC$QC''yT%AG !hEk. Mh+z#IaB h,Aͤ@7hW$pl(1p ("py#Vf D%FP WdU"*)q' 01UxQg .R@jSCzZALBO(D[BPuAπq*!+$:zAl+z1EMٸC u],H 9kC B6Ȉo`q7&'/|[b &yhGEH$R0(xPʩ4ABêI(xQQ8(+,>C<7H4#C:@4i<쀘z֞3TaMԹ%"&l8bgN-f2cnL&B]&]qYA +ݢX<04kh+C8>FɰL' ipGS& -`n k}QGD 1 %!/;\@qX2N4}!w LpvG ƏU#Oto>JEXz(mR'p<ɭȗڰa?0pl %%DSR!a$zބDOw4RC'1H1Nj0/BHS jC?CvD8߶H oM9ˀF@hNmDs!G')8htYtbhDE:Ks|tXrys*xx6cjYvD8%곂HYk-Z<6EO!,x޵U?3e&u@FLAWkj63thGhJ߄&A@Pv1Mx=4M{w@[֮Ї+`Z#uK=ɷh$y6nxt a5O95\md^86kɾE)`6g6|2xWxwei:q6@gN<̛řA888"uW‚H ˑq2hAHoK&{wz8k>Q=ݐF(pڄÛx[[q`.FEݣHle*KccU%;;;pޗe;y;;;};GSxW{{ӭy?{CNN :ƋgUy(G%lf8o 1+zaD'okIfzbAy^z3XwCM|!sR1Ⱥ1aIZocT|HM?]?fS';zC*k$b>$GUv8?<7DLS>@!@TB !=. DLye8=-xr"I!KY16XZT9rΜ&CL2Nb3Sm)$RDϧD4p,GъgK j6FIr{)3.Z4Ddg4ԓJIT1aQB>Jk c|d,><:rZE{Vj׭al۵q mE78˃{鑹g>8A~KؐCῗ|x|Y!щXbKKA@/&Ԛ Ƈ!$02p3$)P; @1& ,Ok+>@0kH(+-RK/ /$30N5l7S9;|8|D]Q<MTEԴL<ҹtO= QE- C,FTW}f}UWcխ&(H#=\;zHUmZշR2HoblK|XJ^'akRg饷RN2{W}Ʒɲ Nmc%;5RE+xZ9Vv'`5-(KҍHmԗ].fG5|X;mt( в*Nr ulWfv)?!Sr\%\?b ϿkwrX[; /\o45c!\N\%#f%]: YkӍՌdP6oyIim(d,rq屴J2 9 x+O>yxJ-rG{ٯ2fRߝ'|fwr? $4 @.`cc-ȍ3Ҹƹ 0b2s0 ~l ]H,ձ945!w=}+g5$.1hUar-O|[S*>q=a}ZBH7#!ucAF WG8`PVPg ͌_әdExƚEqӛI@a.'9OdT?WЄ-HpCcPN!$#MhEY%rd'@A*'&d2YNe5ܡ)aJ4PD5:mO;:mܚzڦI$Q ?rT66 5t#qKRt)< ڣµS!xtr0V]d4+|`r$aGSR "|3hh0R-eA5 D`*|C DXFէyOK&I̮:e4#p(CCz3@rkWI ohȀBJ i z 뛫ByFhՌicG?ڐa \ZXnZc\e z#тr.;\q) O}"<018i鼲$"BVI%p\&"HTV`Hu~ra9ߚގ&5i~Ϗ'ot=,\MƚY.t%h }h/h#="1M } |h b)1#fUܚ@ψ4fpcF3D`к 1H3H=4!t:JBЄkX^q @!a]_C19jtuXƓ߽Ϸ͢ $s*Tz(ߦ$F#™/2_"v[zI[d/H$κ_/i•ɲGJM@%,V3H +Ir@ʡ*NaLaBX @'?gZO-gOI& rbi"-!B`U(&be ۚD` AB !ͲtЮ g,g rum)1VԥJb/H}oq4RC+#R JP%|L`,cJj^T1^.Pe%B2nF@ZGv"hO,vn!^a\!L"#d Jk V!+b,0 4 Aq (SC+\/.6/&" \tp AȀn!V*8UB@Ph 0oV@,#!& !%aџQoc&^M!1jhn蓾HdZ(.hV䩔`"iŰ&E)%,"A]&!5 "h6hCԦF8(Aڒ.yH%R`"x-A b @ X?`  !**`JAe@bU3OjI(baAu`  s ׸~aC)8,V&)sSڄ2$j5 IE,k-'h v育<2dH1@Nh=52')86n'ђ] Fd0@q%a,&^\W~&m+z""t&5],NboDVl E\$2z##b kb!Ar(ȮBlze]:`%Ijqʡ R@ށ#}`E 3R($͒B%4j"rs 4 KbN`NAQJt58i&5jBAB '.<9ԧbŒ.b`B` ۠J8g^7$ƃ$?n# f!0-r#/=8n]:bloYbrh ښ SxMC ! "Q!!VFm+ 䃻<%@>[?;v*-FKa )@DH 2SBc S +c3m$"H !69}`n`> ;YaC)KF;7XӄuPef iSS{($*FU446"\@DR5R>I&GbXk*e'e2p#L4tAm']nM"HRp T Q9C\ .%&$e/^+("f- |`b`~aT !_wk ΠU}'b!r4 !S.Z&Q5#V^ mʔ$>D§g0j/b4B WQQ9I}5p( m+FdZ $8qhXͬs^P;o',BDC8As x bp`s4 Xa !a*@¡ !!4!íLeTQd"<5hUp]PZ/4f.I?[m./YiqБgE;5]*++;toSaY?f0%(n4 o \`C/q`" 1@Z3oaoavB%*zjHWVМ lζOYa}/rdXM2PTdB^ׇXTz+fS{VuP;Ȕ-YKiLS[дT78ʳPi/is)z?TCq%aAA5BSk(, [lb_znBp(@ a5`fa;68e;r+fn+|'\:b&cϫi1':{hv/;zGzŧCef~R˅Y\[լD}qhe~;b`h))!4aYac ,ɣC Y)/% baV@UAkǔ5@r*-6`g@Bo4as3H""`#6ʦZW `A9] >&EBU̞F*$U|>`E#/l#|؉ؙؕ=ٷLDN}ڗy X RӶYɬ$zib-uRهOQ{u}_'vQ "89fU4a v>&;#Nಳ>ۃ`ܠ@>Z'*b@!*`aMa,4(`;~A8|9p?~>q B~ޥp/z-=ܾzw޻( tu:kzcrmn]q ;M?@ H$pkLH(W  4U_4A0f mU p^"Id\ ^2ܢCB d聶+ 3[A?,Gg~by' 4+I ƅ"F4+FtrL3Ƥ(BOΝ:{䩒ϡ?{%'!ДLU, !ҜAm:ʭIz 6رd˚=;V֚YWf}6.܆rmQZ{־ =8X ._+F wg]ѤG.ԬWn شgۮnW&-8=9ѭҀ=AФ9hDzkJzM JdpBkÊ#2HPAV!p }h y2E @ 4>@ &ܳ^S)wCWԷ~.M3+CcnȢ~1NfA Ѐ;"(.bYŘ1bqw}ҖrCLeVhBf%[ q%"\g*hjh.hV5eqXFFvHNm)l4Sr("`*V*Y= gM*D[+lk,jEKb)`Mh̤2W GxX̶QC( [QpC)9XisE*T0Sw,5c' '+C=TQѨmr28Y2KiW6_I%UzZuQ&ңhUXcԣXb%jt`j:c 7ad}XQiY "x/x*\U#4J4K6aM7l=Đl 4rȔ 1¯FEdƱҶ:KÌ|`N̻oRg 4prT 9$ ^i8m3=M/ آ214AS&mRLIOpQ ҆"0.Wk #@j#ao|)D d&W{#*1LMV^(^G6L hn K< dT&#d<.4#CeFx }ቑ_[ȞFP'vyIIh#WvH/Y :1MTz'hG?{DB&GfzSL&N TՒB7bSlKU׵+x5ŦP41Xf|5iZmfg"l3 G|szgsҨ7a!up uz<vUMHO+x{nBh8Ӡ @@AyD`+p1*@z'Iy@Kjl"5_=M1rRR 0VtM$ 5 'Xp2k} ;üpzՔ.MʅOd^5?vYvШ  }È>?Y|"mW (GEa A 7B!1G&WK39G#V VkcR >d E@uj p) !UGp BR2*\"$L95UIRR|Wr7T ;Hz%dWHYh8][gRrWpQ&:? ⰊS-4,xgvHvǡ屏 y HC՜H?p:@ M%ڥ'~mml1҅Ԩx]1 nIJrv1(Ia1.)MJ| P)S^r)yO]OIJ3m0xթyn-Z2Omucax2F8,j8gH [˭Uvu%j)xtuux=6s0l÷/H܏~G. 5k YA]~M4]F&`\2.Q~ 㕳X0tiUrJ^ K0)0xVl+4hNͤu/kZq旋RyE n`8cE8/8٪ͫ)KOz粬 GOX{zs]4Zi>}K/H>B^je9EX6LV#g4@̨OhiKOa[>dнa4x9<" SG |y4V’vԖ=jP!{c+j6&T M8UpÞ>u@鰼<#lcZ}đe;L,#C2)bnLV|.e eH[T0RG34UrB6_2g^6\_Æ4QH  $pE 0 oM Gt&u7t5Y;r(M18}Zii6_A5R^Mwa`m=jfkwyCY*iHhKTg9$ȉ4)U=6V{8JbՍ{(.@o M@ 0!My pp&!k''鍱XCNcIهcܗ㹖bhq .Yaɘ&x`I:w1woqDZU'\%TAM>I$iL'.q%("X7HbG[)a{8C]) urYM VH0KRFށ;w6}1v4z Pq8zU"#Mxif9L Aq' Uɘhl Mwэ"|yeʨ3!zk1 g % & 7@z0, 0XX#qX_B*\wq9{ Fq|fѤ%4-Y7Qr5WVHZVC+!| ư  ް a 71"`  k 7Cu߀ʚ=DWu"CfGKdFEVdBQS{E3T;LMdFAZ+f;dijރmkM P30d+de_fiy[y j8z]zXL4f-4*: 3]OZ&A**b(xE+c #r+ ⳳ˳M ƻ;U !^cˋTfJ¼ыT i'1[sQ5kCJav6ߛ' 9Q[DŰ*Xg3m(KL,5j |w,l\k #T(B)|%)"v3Vrh 4T+))JAsgHĂ"Ӊj>mCԨO M\ T;V âAglŒ\o pܶ\+h۴8Srܴ-lyM2x]kQK;T aڿrGZ[Zns`!v,k໘ƭ.^̿z@+3lRiƳ\ 0b˽˿A+9lF)m,}'49M5t&0?K-;P( UMWmYRV :?}']OJaJ\ɝ,S3\MJs]zپ˕Z㛊#E эy=4-Gٟ ڡVAAsOQ-*O*ڧMۖMmBs!ڻۢ[OD-Bxm(=]۩&zX=Iѐ۫Ix^, K<}Т8L myDN-=Mm- >}\Bl(/J@ .r{o+n%2G[HC.%@^+-^rwf[pjĕ64$NNDB?>umcC$ {| O,K@2ٲHӅfER4 sZIQ<3aC\dkiރ_~'l)cLR!unq/<-7t%O1fzUgq>tBm4 >͒}?n1tХ yMXCzq3Q&sLNG.-%T6;KÎɍ& F Ȉ~e.Ţ lnQq-.&E^6Sbɍ&TɆr9k']]>`A(hp§M`Az14잎r=F|Jԝ-\6]lK?ln>I) X) aE|M6Ɋz7?Z徝lmɸҡV&&yοa&m߯ȂTb)~,Vo7x]W?~u #&Qoس߂~ö߂1˟L~'`?ё|}jC>=qne:.o㢞yj2UnzT}3>$A"!B tƼ$DM bBg EФȓ)Q>$IХ+U:l9SM-uid08Yh${9Qq00BaE*4)س:> T3d\BTT/M o߿~},ݛjպvoNoy*Nc;5ug̠K'LtsUPB]k'tgWPg;c⊿M$'.ib7Њ Q Z, \`H"!i 'ihHggT`:D i*x&^qb}WA f`=XAVm,[;b!bx0@z@4'/Xp! c |~XHc:A(FQSbx(^Xbh/QccE2QhtF51dlh $avgyk7VQiF:"'aC$nf J d+!xo CyЄHX( ф (D9$#48)bSL&(L̜20 N%LA= D q% 1w7*(Ch1iLgB-f5yP& UhCPFtq&D*MJT&EYQ~ThLzRT+eiK]J` G7zST6e&OӉ 4CU(PuPe&UJ5R*'$%Q:S.2 G13ц1 ҃XƐ Ūm|Cť Ԉ!c$0<$ 3T^-HWPӸXF[6( m`IZւq}],hG=!2p;.HQ,XhA؆11\W<#.XܐRn (-^KZς([le/lkZ7Hw[H]|ӻ׳%x| wuIJ6$%yI^ Wp;a%l#e[WGu0kbm0qg^\XCr,sS%Y{\VQlA;kٺ yh$=Rʤ9\q+`F"ejiRX/ A,J7^Z`\>0tDBHEV`hHEZZ҃i\;81ZμD:8f()HKɮ4i68f;96ɳjG'9N$:5:=҆-sF7nx[ޏdh5Z'N'8ݔ"VjrLwlj |$ņL pgl\o+T:Ub+pA4gXVxJ.H7Qa J-E/g\DÒL`KgKT,L4<˃TK4k7m˞H4I̕S4+wGت߫oHŒ4I4\N͈EH:ξBz ˲̖FK.@ͬCtAOKI$ϷELL|NI̾|s,mN Lűzl Oʯ6,\HP|Nl5tSX!Q]Q Q%RR$Q%MR&]R'mҘG%ц,R-R.R/R0 S1S2-S3=S4MS5]S6mS35,5RpSS?S@ғ9R9; T0MpGEFXԖTB}`h!u"$'%eREUUM- ڒ:J4!RT[U\U]65:: 9UHT^=VdMVe]V6UaaV;MּDϘHLl3SV˰K U=EWueumWطд`V|W}]%,WuW,5ցԃ-ԄWmX}Z9iWE؅rC˦8aPHTEX&`WuWYU!J= {U؇Y Z&=XՂ%,u։V}ZZ6U5Zb-VC%֪Z<ʼn)I{DY܎i W-&VaE^d}MdF~dHUGUba ~oZ`wHR>eIIePe]eWneXfeY~YeZe[Ze\e]v ٶ[*LtQ c99uh`-$cf(&-HgrSq.gtN5=gE%]5IݲW!ɲHx΁P.eR6eFeghh.h>h.eIKD=)ccSchhFގVeP!i&银EifV鑆i%u njiiijj.j>jNj^jnj~jjjjjjjj-p$5|b-bT֘~넎kkknijh++r if~fh iP=`.i c%}Rx5Q# vNF>&ms>m>-m3Um2e1um10m0F=m/E&ƃ y縭*&ўbSnnnk8#f1dJf&Ujvf.]^nocvooNR4niGTNm?=pVpOpp/p7e 0 FdMg`3n}f`胾X~qΊ`XqTo ~`hhNllv&h'f0@ ښU oS o\ p r6r473Ws5Ms62/U⑰d-q\}vHu qEqF_tvV)kŮ4^ @>6rF8h@ll.^MwS'MoY;j7Yu9'[1Z_^\_`]aUdL]"*d VP~ޘ&Gotnvo'bnLBNNr-U VRSomfr l)Q&|ol*fy )vb_862x=Ux1_wcsox0]^yρ—pݍ3"b0|dxdyy?!,w `f SMS]^Qwleg)U ҷ^'~o7~o/&lqXO{).JI1c2|Vh e +́r@A?||ow hCkerQbMp#Df(1"ɑIjxdʕ%M$9++Bz|ɓ`,"Mt)ӣFBT*UObխRz 6lӱd=4Zlվ=Wn۲u]:^}E`XY:یopxmBs$N3͞9LEtϯ?Y^N䐠 *6 979P(ab%ZllL8 ȬVfD!X#7ژm@@?c>6@EwzG yOBSjwB)gO>i3_)}aYgk6%"sQr>ef]H!r̍g$4A"*JK &8N )zzzzd)>P٪FIA%9rGi֘[l~Jz Ӟb8;md;KJ? SJzO)2 9)НI&NNš /iy uOPQ_p11RwƁp r$\'sr/ 333(l73̂82& -t2G7 F40/uJ'm^k_6\ j}5e#eG p:pmdE:MT8B:dpY$Jgu-S{uӭy`pQÎϞ{{<{>+<cSO{Gso>އo~3/e֭?52@L|03`B1hӄo40r g/=,IÓiT s@A U[H0b,ֹN}x=PC!BvF "&K,%ZQU)Fы`ه8]'t25OF8$z DJBsOSIs#HF:2$YII^$&9q`;$&S:9;p:e]ciK%Qy^2/)FcҒǔ߃l%VbHs ä!7FoMq}8Vb$uNKJhɁ>c&Y d"\&Bʽ\.U0 ˊ:ʜF-*ĈRt{XPz1t3|m1Y2jjӛ4:N{ӟ5B*Qjԟ@aJZ=G  ݁hp<"(G*ҎfyekH=>µwk^׽խv^'dI~D A5,g3vֳ74͢U-kW-mgkvn>q%!͹:qLT6UpM  ^0\a#L3 {81I@R3@vQ:h2;dCJ+Bө9w;WEW_l_-aD$hN %nۜy#æy鞍g=90]h 9ц>4G7zю4'miIcҙ>tRdoyB Of2ը^5)5{ڑMf`=({_`6e_MfcC6=m%IPAԷ,'`)$9x6B8j.]?@&j{;): nfzV8aW}UX_8j,"Ch`9k+:^DžWGFY{a9U>s}J\攚L pτ^NMK~ rp bTzm{=[{nUOO0tXaN}`\K&U8Z279{xI7Gr7f%/d;69˘[>坟e[^z!mG̝~Ҡ(,e$t$Z'tMѡ@8n>ʧ|&z/vUYk@Gy_ PLkfm ˟3^Ցr PLћaNPiVgfHN]u%6@`U N M@S{STЕPQᔴ - zaB_r^!z* ,6ўp iJtF8TMA@ Z&p$%X&^7xM!(!(bM"*)a+""rCDi\t2Èߩ"Z0V}bb2r2@32Q83Jc43B#5^#6V6r6z75#9c8#:f:v:v#;;c64c9f;#AAڣA dB"?dCCB?*D2BcDFVEzGn$@dGDdT9 s[,|FL7kM i %@&@C BC'S6%NFSJMAUVeem%uUj%U"NILbÈʝ"\F גQt `$X^e^V]`_a%ba&`:ceRJaR&d fe2&ffe6&gbfbvfdbg^g>fhh&j&kbʦlkfgަk&lfkrIpeJ"!"*FO` @M@& %'%f +'+gtz'{'""|Bb:ݰsx)th haUA@ߍ 5N6( Th:hh舒h艢h芲hh hhhi )0KXKZӲRVrf[f`ֺNF ڔ<e,%PT4TWbX*i&6ZXY,T]Jy(E C(hNu jj"&(_I.>*B*Favifkzvjnjfm&n&*lN&ꦫr*jjm*j毾kުk~[@  @r\O*ؤA|١+u@ 7%B'(7t"ڠ}ݔ2ZꔽkkNT՝(V SѢ8h:>lBJ>2hRBaϹȂj2벲jˮ*ʶ,koڬΞlΖ,ɮlm1D!;evU7 8ؤ)PBCu'4d%0(1yk{{m|eΧ&_U`jNK hrlĞ_JYA bhjllRVN,n^n҂zbn*і` EДfͫhX"_ )-.'a nA,* ,n2Zl).5@ pT¯/oԯ aүܯ#p+3p/00O0J_c0W{pn/pp wp p00 p ǰ Gpp  0p -G59YLƔ݊;5S>gjE_Pmm7?/F/iTyۖ/ޱ6*)>}JLgyB&6JR@4TCsp1 B!4윴IGIJJKNLt.'tMtK'EOOtPQP+P R#uQCS'5S?5QG5UOuUKQ4VsUkV[RuYWuW۴Zg5[GY5Zo5I5m*GYB17erK`C va?]a+)6a+c6@6cK6`[`_LvP@a 96FWjjB@C7"PkoTG 6oRȦ\5\uZJ3Q7$7s'm6Sv!7P9xcxmGonCs[}ןԋ֗=׏}okA\-6RE64j8b⑂{4sk>Ϸ +wP[{ct;yˆSTl(7wO9'?o~ g>??w7~Os~3G?[4a:ql5=09Ɉ Fo9ǩÿnH@s%,Ĺq0 \x`C 8`B"x1#H# 'Vw'}!e` gAr, `gѤF.-iӣQJjg9{38]Zpٱ>UhϞ9f[Q>j`L j3x*dK6\/eˎ#gyrϟ1lzriħWY5hԭc´vL5[O.|o92pR^u{6Nw}ܿ7_y%/Ot`H2N@h@b,"$„B@P!ƙᅳC $Xp,ʋ5 FIKq秸~baKwL Gy'oD$LGS4+Jr1\ 6-/E05r$K44sL6EStE2Lkc?X¯T:If8C9fOk/J#BƯpO[9S%}#oŝ&HI_mX1Z7roTu[D24n%D b(*4>d>3)84H.'sJzQx0l\w8yhC/3 "pK]%"qxB D)JoJbH'΋\̖^?C՜Jjs4GxL#d)>)ɏ HDID"8%Nqۮ2 J^( ~?! P'AaAT(;eTf)K%Q.iyK2%/Ҙ><2u/sILk sפ6Mi~59MsRś~h7ςԟ4 #(+%%5Ejm)dx#b1r Xc)%$gF?EUHk&+Iԃ5j>-V(BE$NK!@`'68oPTmq \@xcM4wԃo@n"O;zrz Tf2u7l{K!~eڗu% N`f* + S8< { Y =׺V{:t: R4ŚrcGQj{0 /ܹ pR@th!C g%Ȣ) XpYe/a\f3iβ f7q\g;yրMm6Z8Us䌁l);^H (4:ȘN{=*?SNԩFzm;`C8$/m _R#>fٹq^Oն0-lm^3[ 420!m>30n3}VX}_*Azk/ FGUֆTpV?pqF&v~qhw{svUqi|+OM<5a.rɺ'A#(6>-/z ,$qa؊/o򓯝:Kv4?}zwÿq|3Sѩ%ZLy@>KOUHngKzql! sV\#W}.ї>_S7>+q2åT'?rCMUCP-m{/BYbA105m.-P)f&r-e%ʈFP/rTEȁzV -X W@PidM p#0 -s. Č ǐ E0q Kp͐PO ߰rM/cЖF^̍po~C?hO9nV xr"%fVQ8Ӧ Pv`Ң, F+pEfkxQ^$QuN`gGrmy,~,Bbn1qQE`1(1[jt`nmM-(].Q1 - Qiq #R )-ֱ#PPL{7'P`,R4cW%-`&k&& T2%F@Q!d(PA62"{7 &H,H"^r+^|+d,',͒1`2.ے.â..1 a+R-,R++'-.s1/0 0HE1r1b3*2)++s41+r>,/B"]45df+\3-34Z&*o0OS9q31ςN &C%"<UAi8njo*o&K&X!,CNh1JIAHATH 4JBBn'XGr6T,='S e &>F 0{-B,r-WUWB-XT4rq:Z`f6\"]\X]U]-40U+%/%]R+U]u1Y{8U],7%(:a%F]"`*%^8^bUYscR*d5XdXˢX56];+PUdJi73@`Nr ^Ѷ;!U=b ^hh!S'&06(Ai#-0i`~?OAD5זd״BTm7_W48[n'bC4tZo3roWTG(vNOmv_IO3wn6H!$snvIEoHN9e7e`!o)*7qmOuFwFC7myvGR^#v,m yӆ$QM%~6Z|'hhRnh/Rv^X 7hBU:1 eU$<1"TW4W\uU_uX:"n$5d}d˕Xr,] [H_/rX..8/B݂`<+>p;Cb JKV+_E]M8\c`8d`O+X-W 'xY8WX)v#!uӥ]mK),agՆS\sZvRaǸX_ׅX-_eAdUb+}ijk&.7TRv,L|_a܁p5&DTK#Cp>r*=9 ΋%4)7gXow"bJ_+|Wby+auŖ Ly9_Fx@Y\S#RyM'فSb]Y38gӖRruvyOt$#t`f[J__sv[㙙susYyJ9ruK'Z_U9nކˡ 1oQQ0a~c:;&2-֏wS%f&@DEq)M#~eTpkUw~S`h$j P Ыq)L :),9pךZڬڭ:ZZm{lG:g:k!d@'ېZ"wc\m'n3V'ٴ-'j#Spw=W?PLhzz{qڮZwy}[:m]0#Z8,OQ| >RzXP'UlZX}" FK#(!D'k |7CU۸;)ß*,5SNóW]Ł;XI$*_Xo|nIꎯK_\Ɖُّ؛}ƭک]ر}eO|#`}ޭr}ӹg8r ,-u>2`-ʧܳ86Wk,:C-?%^'+/3^یD# Mi8Q {<}I`echSU")S%gn="Zʒ :b"O۝۫٧>ٛک~ڣ~۱1<ڥ럾>۵ɾ]h-ޚ |%wV=~6{yz-ʱd"&/+| pǞSG٧??;AC^-WK%Y$5FSwCJ]Qُ3{[Ls}߃z]p&Q_53?_ßYG__Y~ r(p"\!Ç#B("ŋDГ+S^y)U$KO˖>P9B͛6sܩ'ϟ?} :У;7LS$a@Xjʵׯ`ÊȪ]˶mXAZ͢uK]rn޾+g^QS> 5c.Qb΃D 5r|!EX(`\mpc-6BR&Ucr*7ͣ=7pʘk*VɛO^<῟/>Yo~G{ R_b *: {M BZ z((bUa$آ/(ȡAƒL Fȉ3|6;3j&EMLimX^BMH%QLqdxCrݜ5yS9I8JiS+Mw0Fʨ]A56Zib Mj鉋>)Z*)j *] ߩjkʪjXkz덻j3\q) cf jLG3hMe^Ten)nKa4是DFvu'틓x' \H#d,` k6]Cqb2#|l r:s̲?A<,#}tIj^=B=4Wױ̳2kq=[3W{3/5R xps vܦL6݃]5x4Iz>Tejhd67ĥ6$;oUG摘eR%ugN{s|wUjEXɽ D=P}3@x,[>ܾӝzMh߯l?slS#{ۻu|რݧ>&=wCdlD|S )x遰z\  mg @o_`B:Qg>D_ "fHȽ(z$ػxaSHԲHShtǷ tamB"q pB1bj6|G`./`& DL`KNBdF7L|0l -?K^ϗ.yӘż<5s|tPzf69=\of74-Kaҝ%SJl~&P} G&zY΄D(;GJPsAٶzs:uIRS8eKuٹDsbXL@(zAsJbh$\̐i ڄpP! ҄oئP=D )$"BL95l' :s]}<;&w2jV8Nel'=fﱎY54US_ 8F|jHz56Zl mCiAr{C|-BdvNh6͡f/{M 0S . =*}8¶6ԄYW e@1>;VK~FްWkm3=\"Ͳ 2}DgnK`v}pYm`c2v20WoJ8oaOb;Hu-#-\XzD] w$Pޠ ߠ Ȁ K" %@Aǐ@3` mibh%:BhTS{Id(Av|*IJ7Jt@fdV{b-Ә8,،5#@)3Jؔظh2PQ9Ra> $!K2 wUrM @T zD . ް bFߠ|r \Up-]HzaVe-2^;OdioddGȇid|XR>AIB#NyY 3ƩiDIȹ-S]yI2F 0-bv6Ƅs9fgQ!w4Qm zP $4P @^G3S  fb_3&49;r#J:8o@atCW@c)=!IRPW@DpCZJINMRQ:VUzjATSf9A23W8ͶVEUb؎ K2@ N PT1AӀѠbr @B;D[F{Hpj1/(IwT9S Z҆Z pAe {Y a!1g҄oN1xJ(=J$Ҭɝʬt긒+Kۙ˹[ 0B{N!2$vZRzH(%@zH@/ƴN{0| J%c#9I"K,˸ ߛ+;K3ዾK*##li4$A2$ bԒTTti:b ."m "Q&Ke)I΃Maի+)޻k <"ܾ'1+\#&a&2΀aJ5jdL̅:oj4/[-YI7bɓZZXfGYEnpnj1t|v|X869_Q+9F9IrNijĊlYVNSa]{əDpۄɾ<,§ ϩ4,+"7lˍB- ò bˬO#gbf'$΃DETZYج:..hűGi-QIJ˱/ =[fnr'[1E d qZu.D;WmB._eNnr]W7\_~rEzvf*1>yG܎!wG^%P ):-nN%@Z(XB/L|/g)cϻakAS߾;.5Z4΅ ZUSfh D~6t Bi呂}N2%L}vaC}xf)?7PBP<_&TR x5'YWtP-?7|(><"Ǖ"M-gGGfow`u@r Pef,:2aJ/:|~r_S\YhOiAqMjSeG~\;^dAIqo^%긟ֺOY&_sr+Ð!̙V]b˦-ΖV Py]&W4 "&3^F9~Hʂ!+_2U$9|!"͛jaPCBsG"]JjӢ:j5SWը֢Bǝ=+ԤOw:S ȑî޼{꽛C;p~v pRJ)[Pٲfu18tz)=m:3ժNٲlr :*8;.=*Lp<.1D-XIhr orat&)ɍq&iw2&1(`ʼn(!H0" dH&D2N%申No`ROSAZ)ѩ,JE 6" GP40IjԨM‰ȵ$*pŮzuX3MBl2Z3s4z X^Yp@}8 Z6WfMhuڤvWlbb3UraVte38]_z%6CMqHs;]uk!wݑ2ss53f/F@YXamxZWԕ?.`o &Y\H%&\wh,~Y\rc=fr9jw7X{sbED~+ zC$h1N1j׼)x"qqd iX!atH`nNWc >WrWơ{Ʒ)ɴ+LP ,N˂Qj*՛v$m7icn{1^뷷޺>c%p5'?fw?cgd^|^=~@i "لѐZW ";@m΄$iT$ s611@L1ds?HRҧI&4A۠f(eQEQ>E6P0YwR팂QFR]NEp$ck~vAXu# HHALd!~,"3HKJ̍6薶-Er[%mO|:"U.ue#1r , k A9EJb4mIAAt1!]P=籎nnyQǔsR!'"F ,Š:ϬΜO Jœ4>h#$hH4|u.9PM&}Dh ʆѠB=ORb&'ъ~44cGCЕ-i Asu҃TTAumARC*E)JP.x;QSH#a&d(39֡dF]leKN6(\Q]r/re ZFp}3' Dd%;YVֲlf5YR6mhE;Z b%mjUZ΢j]mnuYV,MvAM3)N@أ(rmCW1U؈%HpFA( 7QU Å*UD=۔A'Xg< ;g<)q'aDz@2El>~Xh):-eb86(sRJ @SXQ*~Xge7N}v2w(yL2>est(bsכ$8rҬ:ɵ8-֓pwsg>t=hBЇ hF7яt%=iJWҗt5ms'4NPI6鎼I+GIIsG֞+V/ÄUQ#ؙ:c/u Έ ,km 87-;HϭnsF`OTPt<o&6Jr7[_$/ܒ"vY&+ײ 7G5^le'kxmQw%hm&y-sx1qno|}$.6=Uf.#ȍ GNWkI tG`qgg)Pڂ9}cys>לz;w@}{뾾mwؔE! n\N yp/cOH\uXmg=`d.@/[۶~gM+-/ OEoMATùW:e9qG5]k21MJϝ&Sxka&n9<;3Cz)\$;<@Y D@S@ <\"2Ai1Z~'$J?I!R!=0{+J3K",9e#'d+zR ."a#;䰘$@6 y$/136C C T/8@ ƀ&gԃ 6 0GI%hp@ ʡ* +V3eƑ!2JQ S#9੢a,aPNw:0B0B$C^C.vFg<9t$l̾Clhf4g̣,,>13 `˃e]jqP&S>Pa*&ƹ!eb&=*V8hc;d30UB清[в`⽖BdNa.}:Ɠ ( ll^LՆmGm ?6hC>~Vp OnӉ<̳B@_|'jih*"~( @ΪphsbҀ&hX0M2L+嘈_źktBs'0V~"yb 0ª Olp  LN6xswp87:os5p9?4p:(@7tj,ٶ<oخn.bS(Xp~V~ppnDI`d˸1=JEAB&rj.)I,vުi_ʰviomnvp߭q'm4{ @Jwԛp_ .X5pS.XcG+z? _v`e?vJ6x3 s;C 7E/8/>'yGyy6yG]IJ]ž13B|YoiʈY^d8$ %[#8oh޴{E_Pm1IV !zf#){Xz%k!dn߿8{,T37}yayDJ$ɔ%Ek@OȐIr j-e$fQѤH*mRRj*֫Zrj ^2UXCO@YfqzHBWݼx .L9=0 `$RL9Gn93ϡ-Mzi̢StΪ=f {k٥k׶=:ݸ&5oվ/xpå~c[)YTGj!O36Ю>d>~],,Afe8BVLa&!ZXa`$1S[ ¤G r")"-"1ʨ x#9 )XЎA 9?@$I"iM:y#OJ9%6RyhR09<҇.ewmSO5Qi &sکT[ڈ5+ieVCc5d^2JXLB]"1XՅ֜rYhFjnjj @^JJ*:+pШijЭ v,x o'^MA578&Ny|XLu}7՝񺫕\! xVZ}Jap 搅%Уe^ Oa\#fF*Eplq:r-ZɵL2.;i3l22Az!M4>W^~wK*(ҙ7b#7/$45 45B,xӏ&Hc6jh+o5HP`P1I tN` CxA@C`8z=)7\\Pc#z. ^:As ;͐BlҪ,Τ^:ꧻn;~D3I~tO@^|̇=G_}q;<.~D'{%b?=샿͏zӓxsG?%z<_Q´H&[p@H·X|&aN& x[Bp1jLoq~$tg.0NxsHC:EqT%Ra15* h;52(8э97q#H! I:E.r~wt$# I&L6vvģHGQ~R~|#8H?˝OG衎]tlYYa+X hrylc(AYd.dX)J+U,5YLR2I9^լ+GMN|')9s:"\NЙx`%mWd,N!6oxOw4"Tj<. јE&Mhp] t-=_\Zv1]KBӿtNk HaPF#Q9G(MRCNOJS=`ϐrtW6q`+WKgV~4[״"w;jQWvOeRՎW5V2*WVnrkdΊVqA͎jyu+'M96гlgGUZ SkcC[V5n l$<84tj)A/栆G.RPd|#XN1&|(uGJ oP(0&ЮC"DRJ%Is5!5#.MJ=FxޙI{@̀`Wi!RxWSPdxW4A б G{ L7 4Ql*lᶥD>! tK ̂lHH8xXQ^A_NMO%b([PpVHVfLlVƊ]Ҁ%WRdY͐ZLX [֌%Wڥ5?BuaE$|FE+LL;@? B ΀1A$L^4XD^DAGtPߌC[@KA!q!ML5&L`%]^ ^ [%& \vWzgyYv|vgZf[g[g^gTKOAn`{A&T ᱹH7 3+72ah:2jC_58[[dAYbEžhP(Q!^ݨ Q(fUJH̝(vxVi@ ҧ`zZ{gz)W)| 2Gisg&LhN>`šȚKvR m-(&j}w紅FH`h*=gQ|*^Nl*^(طXKs-W`6IHH*ȭ*Ȯ*ȯ+° J-d\Mu߭Р6ɺ8ꦊ>MH$o` 8JRf*a,Jb^N2Ԑn|kri|)+i)2l>_``e׵W6"yPmHlS } ^Whȡ[,,,-- $-6>-FN-V^-fn-s,A1b,CrS(ۆ,@H$HԭmdJrH$%ZnV 9+6)>h8ٛi&,.,Z"F>nvnq0WLcDG>(L$Knhb,*Hg J,+ΐ.Jn ^nf.V 膯n/v/.^/~6rkPTLHAa6$//007@.70-.)J/#ixA Ne/ o 0 000 pp̫b|kHa197?1C1"-qW_1g?' CMm=u/fT0W\]nʬ;tP"++j1 2!S "'rnaFIHfɮ'K\xr',(('r(4)r*2)r,2*ϲ-2.Ҧy|whPt12q HƜgװ @t5˰pli k_i7РD3Sk;08_B,i 4 b[@\tJB'4C#CkLJlTH EO~FE[tDkDs&KGgb4HcFItH$ŜmK6JJqr!raL4`$DKġH7Os6s}s;7"6s5{.Vsd5W3UV׆WK5Tk#Esxh%]uj ݝq_6` va665+Ĵ޺VJ} PJ)KAJ} joal6Z*5Y6ZoXn66 go'oSj ݐUt_5#AE|DS*ُ\Ouo7s6ԙl?%,wzv[#߶NP{<B^8^8\8&8ă78Oh$ @; fR!eK9#i_ &QոdISWQ٥#E3qW'!YҒw _`Q'ݸUxx#и㔇TY9cřxw㸔8y# ^/;BP#Ͷ)RxU9w9ùa]3OĸupKͅa7+2vb3+6zzh 6do3^Q%PbXLzjhSgP B_ۘ$ebXgUµU};+і+aXM;sB1ֻ;_홽9QջX%YȒ߻ V_[C<;G{)a}KdP?}:̃wvIxNtP_W\Ɇs%ܧ 8aTxTiKy~V)&' ֢N5~W9io>ѭ@L#~+>iф/_+h|{<;=^?ZD,sYgљGA`SMB*RVFUtP]fKOJE+PTU hНAziݥ7Zp]&'Sz Sq̸:,pfo\T4Tw㞊4wT:0gÅqCEC1MI*9/]-ܴN4!O8/NKH$‹653'zO @N*fX BK=@CAL }ؼxEȗE=ĐI<ѤQsDh"eH!j9f'Q*^Hg~$[P=w+7(f_rl&,8{Ӿ/ճ E[&Ҹ~۬HsinsmK7iYO:*>jn'2h;CԖĎIj7sA)r WuM/]ևRr xDnS=urp2owa?6;)ˣnp·n͚q񹢷CwA1,?>.xƒFY?<W"?&)(  @y> +i"X  pCF␐6iI6a6 R1HG>4K kPexJk YCqjH_A-g[re15#|f5_/^IK<9xeٿ~'0hE/эv!iIOҕ-LoӝAjQԥ6QjUsp#x"u(-zELi|^]le#ؾGx f/;ӶvlmS}#A0d 8 v7=s/r ]V#o񾣚Y8&p~ wz j+SDʵ~k00g)9MNr(wE!LdJVr_s-߹U =4I^F}CꙍAVghT5Cܛwv]mOvbۯX &} #Vk*G%&.QOd'xO4Fzƽ a 1a)f?7VxL`5&37s.^BPf4G(LsǨ24555c2f5a5_6es7C,23539x>8=5(R358C448s9K(,S(.NR;3cj)s'jO&9"3:Ws>3;S;Og ;S8R8C344@m^=$ 㾡 a&B$*Ad& KT.barHL:OHmƅф0fx@;`il|(6e$_c @dn>D咡.ZuEIdt IEpd11~tHK\/BnrG[(CJ;eMg{6&)3P"u04ܘl46:_qh:W;8y//6j1Ð'd7eW&<3']w"(yt(3udk!`9/8sm598,z88db68PI0:ccKWYDI$(^E%NK|a!~!_ џ$a |`@-`V4!{)>жڃ_E]qcՍ"j=f}rSkWd_Hqر͵={;uJE?Y]_U_[mc7\d;9JppL=`~Aղ [_Za9>'qm$,LЭ gjؿݿ5?Ӵd|@BD,=}!mH*gf-G< &qn`G'V *Q 6,)̘g<3M]th̪3vM95׭M˖=n֧s8۫y/~|wpTKIlߨnFŧ#S:I=!'Ϋ$ߟG tD`C5 M뭇]CE!\Vke8MZCTDs)p'ڶ"o)bl-ٌ**wX,XA6dE8DڈJd;(%bW]N)Dq]Fq]UH Œv։zTBzlePT@;Va&D9q!6!MTe4)#U.iB~$(*T e~ꪲj┵ꑰzk7* NYRIMGA`~^EhU^`Szy~'[5e v ֋/X(>xIBpp /p?|ALq_ܰ K 2r&<*Lq, sL3 utt{L,xվi)s&: K+BuShS] b%GVo푵J5ľܟ^r+쬱ڍW7ݫ x.xc{'Ix8ߑ T097 YWϊ)Kf&DꪧzǮߎ{{z9 ZoB^Z|AK޷;yy?| :rE@1R"^,E"EqPT x}HżXeb阃,ޑycؗ/y=*2U H::<x>zd$'~84Nf\d'_RN0d܈\L'8KYZH\+}$'A rj2́;l^7 ps"=]țL { ^&ļz,qhO}*Z8<Ԛ(90J\yhF=/ؐ>a@zȃx¤`k_Zv5Yvo \3'1ԙRP)tl92Ba e<( r+ڽ\H5h!Sގi}귽lz9=mkG \`Cm]0E5`GXXz rF[|E+սh~{b˅C`񭰂KC'h +T-t\tV(Ruu81e(qBO]5^ih!]bvx]HOʂ^/`o3mgo%Njmq FpgqchdmVmt[tX(TGmwyCSsV pXԌqHRXR%#hLeAf&FH|hqVŷJsm|wD@xH5[XVה Pȍ׋XЈ䘒ԇ,9ԑB1 tpMʷGf5/iұiBiQDw$qvXjZjVwv//!>id@k4?d?jt"4CBHr)t)9Iis?9# AᔙN4">@A Xx[߀Z8i^G}9ر(Ve]ᵊr׊Ij]uyH4Yq6I))| i旊Ib){䉝Yש$ٗi빘퉞& 9D~9I8 MKYB ʠTD.R^ejCD^Jkvfi)_':mYh%7YoS٣a9*>8AJ2c3:7K4 9DlID-d:)QW[yiJE'Ȥ(i696˩/mgRX3a8:[(j305'21ӨJ3 sʩ J1U"9y,uP9G CEM * J:E u z'/9;˳=? A+CKEkGI:+KO Q+SKUkWY[˵]}Lѡ4hݚhUM ju+y3<==6u:!s@O>亯:@azʯ*)j ۹yA"`;ѷ2tZZFӰ*뻊ȱ2K0I 뼄 Zi\_)2k:渜۽ߛ櫽[[1|!ŸQDâl{MIQ- l U- ! u*f&/=+#+˾,,. '<k" -4Ytw ÀEpY߀s«œ89aLEB^B%Cl\/ի^J NJ#swNj{\3}1ȁl39Fa~7/1䪳3w[Ѡ Ɛed@N0<k"İHE7, [k 1|[(FAe]5e|v:ԛJpAn4&|I|ОVl̏ = 8ѽ+ ;1rƍ,YΝ17}4 ;Ij z2jvpTaAlLP{kPKծJIIL#L ˩pևK\K'rLVGm}Hpվ~mKTH|ը1MڨK`o-^{t ցM@kxq=ٗmِԬQ O ˥C9ӯ=,ۺE+\h5iC%k]\CDI}g|?n(|ԽeJ]I9S-wEeS=E7IlTo}kXm؍֗W&]bT݋WX n-.[5lE^XNBߎeQ-|!{fU0~M78 j  "k^YP% Qn\rDHsօXsxrzE F` nEe`r~EtpW`y;r^doa^{l+{_WalabNrHtH]f`el^&r@ryoU%pf_.^g(AX _a}_nzfrhH'dV$mZDm:Eny$e}} ,{!{I{'gb~~ H'E֌ 'F{6H-}7FcQydbfbWbE>?gl-<1/YaD4MX 1 =- P~=)=ʍj*=aXIfy`^cǂn떇0DŽ~f-(/xn6Lzqn!7.{`n~oe{:15}(%yrV[XUU.W$7K?JOpPKX(Oly?UoR5;GU[L>E~xvɛiB)pRmO}]pG]_x)^Yr. t(3bxǏ.hɇ}&Bpzh ?nzK¿Ɓ@T$2:'q t\p(C A$B E ikvs7 q H:G7*ȕ88r1&S삾)}h%Z2-iʖ!E3ɟ@9jK 3:LH%\ɺ΄q<,ѭkBlmLAFAGE=K~l 5$Wt2Р,TT+5OTҙ:$/]rM]WfߜG;Ocճ7hsG7n]Ob!> fpb8n^yu^|w_~_Η^M`~#Nalas6l3XB7KINp!yU6Tyfg fgb *YMF6Ӡejh՜1i.iV,MN駱vZkZjZ{뱻k6h&hz;߾is[V݆Px*~n枓ނ#Wrʳkr3לëo>=$V8 ]!CYK$1vCl#_0w#PC!'t~m韴:[:^_??}:_?jk_{l[m̅.u%KB*wA rG``=x/ L[ҙp8i] `b033,AK Ò}3!nV$񦂽цg?O} FJ~hEi"1m<1ύh[W@M Uכ19ytBGps ɝ@2y;8-O8-P8IJB[H1Wu "qK`S$f1yLd&St2LhFf3yMlfSf7Mn~SLf8yNtҜDHH\#s-'x wH<$hA9y @q@1yE{eRY@}%FkCLbԼ8vd_W*G2f{0#KmS*iOsӛ0jPwEM ;w掅%qy\F ΘFs g ԰NV sh%V!;ATU\ ] ¿>åelcXFVle-{YfV,cYІV%miM{ZԦVemk]ZhC gz*qyyr .]KG,b\w0ü\XC]^q @$nw&>h3]ez^H<))rm;OߨʹD~h4"8`8NlE- f? Nq%EBǞ3 V\%8⑎[ ;vM@ j(xw(8eN RY"LqX"*,O! B+NB9$/-Ͻx 8S1Ϡ[HP!ۘ[hP.=IQD[H۱ [ \h5%\<4\`;I\5@\\QuI FQ I>" - ܼʭR%ۓ4[=\ɀ445݋?c.-T̑^VaX%Y6 44 /ݡHUH1-X㍙?+ֳQ{UXU X0J`t} | [ [FWT l5WĤJq}WE-\LtUxɋ}EPamJy}ŔZդ 55V n`oᙄfa-\XN%Yd7)F=saY~ ^= =4uc lͿ;BZ_IZ!䑉09F=8dLW_fXU5ffeQ{Mhk )e|d gƈ$QgDSf]> fUfgܯl9bre~.gDufyFhFg-@'İ`^m?@i5h4U.)=8߫žTq _xɈPb'2@ A@Л@@@?Ė)?@jΔVYịSU~!lόk 0SaA™x— lAΞA<^cvn"`ΌaYB} pNf|`;3.dw+Sf3̞s0J1Ο'Z@ADoƭ;7o9~.|w#?9 ~",8Д$ivh)ϛGyWNcj&j~7he_`RHE `\jx!h%fX6".2X߇4+5cBCbIyd8Lt~L0%1_Dqce2iɁ fH10d8ː(fS"mz4w P8]ai0 ݷv(^~#vGҩLLd#::٤x2+Xv28:*k>+Z-"mjK-k&+n&Ft~!+9٬zsXb|"HigiKXX + CqhovFٙhb9H2"hRNm;h 1|]z=]BzԩC!mwIz@s5i}JQFą`mS qSvn[\-7Tt-St7|b;v;- ۠ŝCvG^7h[57} y9!ޕn$nۍ:޺E?imhUMS&D& Š̟rfA$* 5|9K2)7LNslEt&fm2*5fyXDs)Qg3eYhD5s|L:ҠzA:g"ZK<=F# ZЏw<,!@>"N9_qTjD5>k^LnDM$PnF- aNUq/r nk XDՔ+xnVڷlǐ-YԜZ[̂}|X/ 78mQp7q&OQuy]q s(<Ψ U)v7 o*!Xj3?amnלy/9]),_t\nǘ15LD@<ď; gDgk3T%E^(gDwڒ@vxTHu'*qh(r%(rh& ŤB`"bhc,g|JioL)KD6U`ܠLT^JfImH[JaC!N])ZET`EPi TjR**Q$:j 4JwЊsIܙ ,|\DFi&ZthBzInIj =j8@u|Љw((>뎔FkBk.krb: d8B`p3|*kZ+LE7M D@[e@KzP̌6CNyDq@ZbljrlzǂlȊȒlɚ ɪʲl˺lllrf͖͡h~`Fhdj(k2eEei*^lǦPM*m~myZ-DDO뵲-r"gڶm+Zۊҭުmm2 |P"떬'blXRV.DbYs ĖFbلlג.nJy`Fn&B mnL.ɇƮ.n})U俊6Znr/e fYJODnJ(ida  onoo"0&/ʮ/LI^Dy&C}}PGͬ؄¯ . G`8,ީq1)P#q*E;[@q]}ED2GMqi-Ũp%`$Z 4Mp'hޝϝCTH:Ko6p!'2+# +16"C022qZnF-0**[`0y MMH!" D!/J#¦I hF%  uc2\e'?36KvV'k2p3%{34sN4g2v354/DhӺrf fz)+*[P(<_Tt6/F!.omk"%%eIry`&јqbd6:OJθK8s%;HtMMgNJw[2N5 IN#uܒ: S'э,UˎZ|It42]@o 7Uf8UзV-w*7}|q]xu~ x=xr#wϩ n~GD5!kb<@4 C換F$G,eA+Xg{) K AFNBc0POt'z0F.:EĊ ٦aٙiW [ViX[YmܟY:U}ea/ZKSyџMzsz9RvzٍUjez=nc\- ~癨s2ں ט+u^^ݪ7 E|6_n|Gg mani(CJ%1GyM=j[ihD ` U ]7rMEgL 9ɛƙefٕ q8nM]n%"5H1xOfļ:$!A8Ey[|}Ϗ^9=T 7Ρwr'ؒ?{JnF@Pš{w´nm<@ ǴF$&hQh;4X<+䑷{n hzņj^RvmsqR2(C/([lXGϾik{wS]=y:9#= 0~ \~37S`o0>/}M}_⎣u:Y*I`ԝj?"r ,`A È#Bx Â5flȑ 9p$i2GɄAnt鱠2ip*=&qGیo|ˑL=>#x32r\y'+">:A%~ ծ&|pbċ7fqd"gϜuHLSeV =ꈩY jخSujh;lݳ!wqk)ʊhD&HwjhU"#мw幋gOѡE;^Pp3!o"d"CZ;o<@t/C8L%Br(s'F, gQ,;3HrhIr+d tTOIE-!ܒO$P9Tms xN*`$4Mh6֤mM\nӛZZeyI H=E)եfxL6_hXBLu]yXMpF!F0}9Q eN$gaD>3/}0iKQO[_tZZ>9Pf^z/tmUt +R 2Q8 n݂| @t>3,q7S38 c{\r!M.?R.A#bBWWtl)^zb@3C;.k QWԥ^u;gܰ*L{*&˽qoڿ]p_9.]F[B(A;StO#ny5t\>V%Xτ(TpJu[e,OzFkvr3;[{۳us.>: ܁Fg;21]!k3~!N!O"Cg( a#?|[k K" pп&.3-t<,OFj9,c*Y,.RF{dfpj0.|#Os*~]Iy/qjho0n PX P  p @*+06o&%eZM1~IPh*)4sbM^`mtI ~+d@(iɐ( PJI  񬛼4Q$8Q,Qq2 /q +EQnRU 1K1npY@΍)@,)\*lL2PztlPHY0 /:o8|Χ?}~N4#%&5b_f2< \AqnIpphI!"Q"" !R$"R""G`#6΅JbB#E$IL#q#]anB2)r&T(92eR)'Q( osM.)}?P,# >g  mZj#'j[n\,. Ni.-ix#kV^`1Q"C;S<!%Ħ (30&%p8335$4ApH3?s4S51<6W1=DCh2k#*332-S3_s%b;d6E8g37/7w$7SmR@Ԧ32%9{%D&93;S99@n<6ccat:lAш RAR1t1#P1}`|f!xcC_[~ԧ\؇}q816t4e|FCFnTGCOz4n #XE?6HEJH4IIcM&Ft bG,NlTKNrtIvtGI$D%FFDGK<"|4`KlnrJdM<$ȔGtHfPCKIzrLDLPӔRG/5L$P!O°-2 -E`+r(AU2B )0i[:t8.2U.18E9iUK'^-||0%9UB#$\FLFeKrgm8WrSdpVCUkpQ#s?B`DTO8`$Ap-TD2j^wCJ v1EW!HHL_Dts{w#)w5yrr;Cos .qR 1+4!`\1aP 1X! (( !LFj*|T[RXl.yU5WQ/1XkPc&8̰Rj0߳ZSg`&seOrRFkx^u>4BcnDԇE`dUy7$=qQր`eo6) iKu&1+w5/I#T4\BnI:%|H"]oYjYfۦ@׬$p? ]Ɯ/c ׹[(yWpYrZ9xy>3#Fa:4[R.em@ڳnpDF9l&OY5_cM#&xfZi"ilor9jvڡ@2zb-'$o*j(RuKg!Ka0a1Le"1@VnDZeH1SCUYA`X !!bҁy8B 5a;ZaD@ʁVzqEY|()198'"C̽1$P VK|еC;)#"!;[G5; \#%[[{#X1odBI{b(pX׸ b@U@kW.r  BB/ʥ'3@U0'(k0phåѰ {*5X^1}ҭꇤBn9?r uxnZ"0X*h"+n] 6a*6ak؋?2fn%T)6o(ZzV҄E#Z Ic:? GKOS_Wٌ嗨('QuL )"XA!⡠`:` AT ,1 '֒{{}_[i#+ˡ%WN>'D  egUR\ȷ+k覫$+/.A  lfdlv*zY(rAJISNRe&5%w|U'ctғ**ZhONO Emh(Msg-ud*i`gK7Jmw?ݒ4wCnUjc8ˏGm2;)"m,[$cqM'sOPr8niXZpvhu׾Sx3p_|3¿-}]S=种V~?&vN7\}X"hKiRVT! fX2Ӝ-:rB-΂^ADs7#Q`V4hʁ piaBdH2H9pR>x) ?8EE?y%#gVVHz-Efe#zv8JiO#8G)k#}tHCZR\cG }AZÅ+;KVVaҰ:%ƀZa+rf+/M_`љ])d6gCwa6&K yMn.hZɖqӜdkӝ7lBz3g>hOs?Gzf<No.(9tΑ(<Ƅ ]CINv褨F34o(CT(O'DiRjR(nⳆ|N+jR*m'K)Uv4!ͪ;UBtU? `b}s) `'Pg͕x}e^:U JP"`p6&89X$vd`A BtŜb1A$6viIEr=}mlaNZԤnUڻv%g9\<.G\18-/"mjnӻ؜mU[#nպ5.![6=t[V0!s+݁V6Wkvm8^! Nt˫_)֮)Lbz7((׾AI[7jGz1_w_yŲ qKLFYfYwL%K0yrp*||;Yxkh>7٩wr1e3XJa7q"7kybu+:u9#*MΐN3FRqt1R;UD*]f6 N0*[pϧF}גjnѪaPSԐ&5QRvB=3G[-u;\iZkӜts66ʖY\ɵ-tk,"#[~\,@5Rg^ =+JE7.VipH>abӅ/Knޖg8-Ab^`.8"w1ӓs;k`J:Dvzs l7إDyTeu,jNW:NQgvWcPB񔶣TEd1*M|[>W|d6WaQe6Lvf0dzN]N3_UÝ;LpzyֶVpުNOo t uu}֧ ti {Feک$J]Ux:x`w8ާ~+~6gGi{P7RQ'4w|~m÷ifTKI6@0r%ׂ@Bd0@A&Xw4d pY YqzSG;>i7BCTDqPSI~2CD=ɑi~4%j=(&iU"@{t-!Xcwa @B){K13BX {0aY4Y @QwpR !>#T&*(nr=⁑k ْv vuI5rٖ=l$I!!O"$v'2B4ya"+y  UP+62"oOŽ>"X,qhI]Ĺ^iɄڒf-Y)×"a6C)y&ٞY<)6 wi䑟!&Gbi >d1Rog Q2  P AAPp ^G2oDŢ&1{A{4c⣴фf9B81j 1RZ0 3V /.Uz\ /[ڥ`._d:.cZhg 3(3#8hi;Dca 0{J~ ia Ic.C>pS)h;c@#"4ǩXA?#&>&I*G9)7ʫĪ )ڗ!!bzn,RcypW"PiQC ] &%Ѣ/*E!V79%BB4)M"[{۱ ";$[+&*,۲.02;4[6{8d rbJt*mm D;` ^| 3Y i'@99#3M۲|عn2Fx1X7ƺ:6Zz^øk't{F鳽)->Gi1 ڙ&y\V p@kk[w ߐi/ȩ?2rw1>ÚLZZl&k-l:j0ܥY-kzWʬ<˲0\#B3p %q[">xJ3 :$R 0 Up &͌aWjRC^@ 0 Ґ$. Î&qyFѽ|ϛ1%cVWL[6Y=;YM7nV ӬfEO96vZy*N0ly9ǃ!ىQ$ Ν$ɓNȔC%YɔpA'q[=zbݣesEŲJ\ MTzY=҃9 mIzyׄ}m끑̛JCdq#ّ*pJ`+VhK[Z d4*qAIX_͕5<ϣw%RPVf fQ_Mǒ%4Un>ePr}B]FIL^*2_]b]mщ_dj7)sT#7uMEAu%T?7k.am^o^rZns`n>c|f^J"K9,N)yTH0EJ2h!":'b *y'YzWLyA hz4M=ϞgmgimഁWg21T\E.\%r\fӵ\hЎmVnfXv&mp\ɦvin(_ %OVSfjh^FFG&}'l&FRp %U,M) *UǢ^Ѡ6J"Mm XsWʾpJ[I9G8XY!e9Z v|G`~r䂗bi^lMQ0T#Z=uXf\}CxbMdorg/x3'vfhba__w8aL*xpw`owmHtυ悏_{[a7vKW˚˜Gu66>LfVoјeT/;:>Kz:e7o%fG3H&O|km,}7ho'@C6T‚!Lq<cH$?x!]ZLpDrī鎡;Ab(cI?rL[ (͘Oe$ˋZ4z(X*_<5&WV'CJ 2ӑc"MgZ!6mW+jKz2Xx3W_&"ym3t$Yu޶nݽypʼn7P6g69s}|2}^$xy,?8{\=>c@ w;ܑLtˆB,DC40öx!C$/N+)@į‘dmZG,,)E<P&'P ;I *D +;<ɽǤ( I+K4J%{'yZ(obr͟B1S+r?˴0JՔtPDRHO lL+GI2NU3ADWn0[fHTXkS.evYggL[;@{U2o'Kb=De/oۯ>>}ozˇ ^h磟1g7/dz"YJ?N 5@EЁ ` $2N-AQPDa w6.xFΑά8( CU,kxG$D&&-p-5A"#}]"//r_ʐT!"@,T#@JR03 G$(yJzr * 7P~`30a9 vJ+H6"j0-јMD1\2ȫ%:8<^̃"*k|$+}$$.4e+I2ҟ| @?)P\@#)ARhFTBb %hF9O.Mm<Uիx;ؑWKfNS"\7!4 w&6Ԏ$Cԧ]}vB]೪SF{G`>宾0n@kZպVխok\:׵wk^WAծ{l`;׿ְlaXUldXF3kq&~۝D;6)OUZ&2`vW6Ϋn`dDo}KS}We,LZ VB\0\Qs&`1nlvG Vcm&Є@i c":-w~S7K٩`U |}u->c)}ӵi~Oo-ןo{YZ&T%.~YbVpw0McЃq`}ph눠)X wKo p(4&୕{D :Żq{j.Q;|<#$58CB'L%+$, 9c-D C/B%o:hjW@:!Ș<@Q)&X = 8%MD q=w0qЄmٓcH~hcD*4+*qP [*}5:/Jū*.4j1ZE{Ҙ=*%,C&NE3B/`B_t2^ )ԨeF1FFgFkFBB??pɘ0y)i@*}e w0")%:wc@VHADcB1 2E6)㭃ӃlJwY.'UT2Ȍp.C6] 0A8ɖI&Ɔ;R4JɤIiʝđiJɥ<?ɾIƿJI4|ʑKJI<ˬʮI a˨K)tɻ$LTˇI Ejly\9L Qgk~`܀pXt}9Dy8<eeȗqx©LM&C Gp9 E.X8(.tHQ.Zy"(*ΕΉ )϶(ϩP0/NBϬYϾOO4bO@29MO``OdUPTa * mɽiԋBIPPǠQ 5O=OQфRK%PP mj2a+6bWș+-"$ qCdH *8 ջ `D;&Vc(Mfh4T,*k[ VPLh&6H6{!vKJ;-ӈ QK14UA$I U^V(UݔdUE)"q3iU+ XՊq[\%(PV3KA[mLAV;U_VsMa%! tMjI\VׁsVMquWW]yփփH5Z !D0 Hpy6 pXxdw bdx3AqX}php̈́d(68q0Z~A3jt9E0ڪ-ΗEʸN] {58 -XQ(\ T\M H\ QȊDž bh-ܙĀ])u֒q[&v \E˴ #JPp [к ۮѽmOhEї[eϔ5p/= 1 SX 88C۰˨ dG $*PHr4YΐLQU'o:J vU)a 3@!UX\%~EaE'Xaa\t2`2aɘME/iV Sq6eVHx& xKa -|]+aP %ƍ&>'W3aVRc;!aAA),mXI9,*(*F DuwI^!D7HG{EWT[%:ц,=׾,9V^^ѭٍc((fU`fɅfʵ `V^_`]l m>%^\]8JlvѪe0g{t{ p.][^_ݕc[CL~EPs!3@  ϸ-Hi'~`.|ii>`kj&TE6UeU#PxU^ ѪVhZU\✩Ƌ%%PQݷNީ׹Hf"ʦƑїdcaܨQݖ9 (lܥ `kf>$Uj!]jёjѥ㠊,X K*^PUNT58NVn(7R~#& ?o}3fk䙟mE"ʠLFo~LonBl^o>C @Xzih14 _)c)RpX!"Km.T.aE9YdU4X4$]('Hu #r7< zf8YwutoyRtKouGyyO'Z C |`w Ԁo"fQh߯ J΢ƹ'cw"Y9,{{:{<f#:dŷи +6ܮ|8y:P"L 'zy7}Շygwy}yyo} @߿%P,o߆zMGSen9c|KTu'O߯7O(GWw}؏ zb #VW^АÅ9|+;>F ߞ}Ө;w9T\%̗2cҜi&Λ:s'П/5BaСC% AL8Yj+XbÒk,ڳj^*\mokݺx@_ k_FXcȎ'~Lrb̏efLYg͟AsӖ;l4kգ_vjҶeݻ6mԹ 'uMZԓaCXQX7V4u.(z׫oN)fHhW02O1X衍i* >uQI(Eh!z!!8"%vxb&"-(("5hܸ#;#AEybG*!iCGE+Au}4;ЖL8CB@<䐇3ӄTShJPNAH<JuH@xRQDQS" 4N.:XyFvNхo%rX"Gجjokvl*RFl:,p‚Ƭq,Nb,qR(a})CT7.UWip4.L,@1qS,P;A x3zcEJgCЖ]A ũyU.sW2#UQh2ybx=tnp kmz424՟f[]Qo]]-5׺i]\QnQ2%YL<8N`;d : R<" 0{{%TTTI su3`a{WŻZM4E RA{1beW=`w=އ}9}瓿voNC?_ P|; @ A-{}ɟoip >A~곟$ӼIz,7+= U*= p:B _LXKGk\Ϲ J"NG#HJ&`%s9`E t J)Lp4cL"X}sOVFQtYu&eUSi9X) A޸8L@X7~qG pN$`S1V=;(47ҭto(3%)_+[%^!VB <ֶn2먶dTEW \.mntYݮrW{ܮwz'7%{_B/U/s-6^o~,(]|=x+]. w KNa=q@<kP3~O Bt.UY zY璷pG 8$b(#d2akBvngo¦3w&x&nvmyrofP[v&hΧ|vfhNH-CQNIIU䝵4A4@,hBL;CC d2 8AÜX2C@+TLPITt!#xWn굒YګTT"̱%$'ڀP n6)O۰Oִz)vin)ȩ)))@@ ݨYR`EyM̄OJhƨ(K$J%}(SRjDv8)pQkњWVp%Fyi'U"USTDiژ)6 qꩳJ) k)⩶&N@+՜I\R[Ru2z NNCNn*r*$1$쇡RMiJW*NbY!^lr9˨`>k~kP*q̺lj)̲n,,& Ўkެ-r+Ēɮ؍k,)4P4Ҡ,ךat ,LP!絪mYZVu +$,  .lH.H>zHNB^YU`rDPl {,@%a^P)EX|,zYjTCJj!ꀌ m2о.m,Zob:oFo>oB/zJsPGM4uXmGdDzt-~V̠2ģ-Y hMp&9DO0W_0go0w0K 0 0 0 ǰ 0 0hjߜpG 7%ؚFE(A(2H^Ȃ,lҡZfqo/opLq/o.-ޱ1qkdYoZSJ"EJڡ.$V,OYNʩj'o'gY&j q 1 ,qq/.- %ݨn^ aaNs 幘%:,('kqeu$o*.r02.F,3;30>3? /;?3> BFEB+CK\+/N2EopRS/] Ex88tY3dt4ĴLMߴNﴒ4OO4,IUI@0(5OuZJaQ5t&CDtI5I-]#"[l?=4[4,,^tK@2\ ]ײ\u[ 5`_ a>42[R#RaL4UgvP(, pt[00j1kž6Zt)tQİ=6ak\nK/sawtbvrrws?o3ZKDsO7c&ND-&Q 鞝TW4zsj s"%ސJXG:)ZԎUړw;Uq.A])S48qC7rcbS]4k %o \>xexϘ`;xq 6-s[̈́Ƃx^_wu8 OxAHB KA%X92`A]yA1T;::ox]`8?C[k(zc7Ϥ3RPx7o85wzx3׺_]9iW{L{ެBL4Ͽ,_dM@3ɿ+d¬4A< dfPh͍FqWSC!ZSX$iV Z<ț#ޞu?7Z"%@3{W|~e#\x`"9 Ҙ5ɧ~MWxX~>퓺: MM飘S=_o+J_J翼+(R,W&@ڈB8aN/$p5@C=c%qwPq!>!XhaF&Hυ!cI%Gbd9S8 Xg$ƺ]9=(RL98EAԪ965E]~ ++f˞0T)ڶ\>,ݬso_- *Vӫ.nq>;/`{1we\!7~le˔+ZukԙWn:ױ-ҢQAl۵YoV|9T_\EzByeꕅWۻCu=O1%Th"#_I!%ɈTIJ(ȋ\BRqTҩw/a(Q?5tt84o:;3/D+P@j+QC3O=[,?AdRxDSӦDGMRQP6Om9FeTZo-W3UMa 5XXZUYu(]SizSP_T]/F>h ' ]>J#cs o)j- pA c7BV&#h!¨!҃)ƿaō5=)H.y!Atnka6:Y0f3!hhPs?|xC#p,dbD)6Lh)vGu#dgM!%41m4_z7j;L12 `1!/d#'I; ' YV򑇌$@4T#ˌ'*WPPmTܢ6,RYtsa"wcά48Mk&j7́A3l\D'E<1O=*E ~4A `4! Ej4%#EsSG7 7_pK].'\+^0o Df< dt.48cpmhi'Loӏʃ띀B x*c/{+roO~ЗWS  fEi;ǔ6 ;0 _D'~6M\ ="?0Xe^MĉsO)P / q)1i< 3Qt@op~g`%Hc#8HhGΌ.OSBq)lj)HѨB+$1ؑjQLq82QQ q%k"q䌤D |q@@z#t%qL~'M鈇o)!nrLNd`'NG0z31N** mHl)%,ǒ,o2-rkt'nc9r+t2/rR;/! /8²3"݄,+02ng.T2+33+ӉH/LیB nI^\r5_rx£G(yq>DLb{w7Ă*Ȫ.7nX*Z3N$Q;D;5%X"놂?0( %)ʓ<1*S={3;_;;0 !0Л(ENO"TQ>1:tCS1hDӐ"H ZEYseI< x\grc"(T%HiJz$Xi0dگxcLrJ+*F#:)pZ1 .)L m;aoR+)t)B7b3ݱ@ T*40p1+(@+(mTG4P5#P-(2J4Kg/i'6ML4qyRhEUE%N>j[BϕMda۵Zih#ʿ@rFML TDLX5dWc#c0F;S!b7Ie"Wy&"jvKtbG#Rbt)*hRN"Q2R5jV)qj/+\h>;RV:* ^TO r@BJtXBld16)KMR*ih^#s RkDdJ( `D -aEBr1Ws٠ idEvE^shDi@V{+Ws7ywwXDK!,R'|@ o78Bzk'k7.Vl8m-7/ʗ#,ZT'zzm'wzuG}^Pmm%3*}Fknw^8M~߱}}7{q~׊dL!܁uDHhrH xutw˂8xsY} JfIEus_ю9mUmk)􊠙ٛc(㘎bufpNLshyBb``(D(jF(4ACƁZ-|x M6O {^!WgbHbjdvrjdkʊq%V hE 0oy tZ'jۘəyʧ6V£8<'StFrc!D¡s-&? ӄ~#a܁V@n8:ښKG5 D$ζ8ѷNn+71b'Lro-0-D[U{Y틴]S; bdT$Prg H }f8{`ˮ'jX!A? A|&MvD[;^Lu%FzJa#,o :r ٩Z>:\ڨ |›MQI7;j!&;ޙ K2z>~Xc> Kܡ-!j&AHDX@?|;dG;'>\w?]ʄU;|Bi -z#yڿa!<|g}o]mi5[=H&xDhP #r =!&΁< HB+` '|cs HAD+~|ٰ;4I|!.;KhH󏵡M}UY}쾸w`~y=)kbwBb*xB|cG( XAŪH@a B,F(o(Xž;IYGpbZܛӣf&!p:!%\:Y};>_]%ᷙS}΄gZ!B\M||{Ƈ~]ݵm t]8ӏ#\enh{f;F a[/]߻X+bfj߶Ť#0K]>I >fE֍@&KbAy1e}"yv)>"9>ڧ~x1 ,(aB*lHB >Dx!aƌ3Fbŏ!IDЙᕅWztw=&aSķߨ "b%.Gرb˖uG6ٵj۲ ۹rҽk7/޽r}ɠD_K'צ<4p'q+S ɚ1{2͟/|:sAҬ#xz⧊*Ǖ3i3/&~38rc2ORB㻩/W;oSZ'}s'oϷo=.×~z8Çϟ~bA`JDO?=Ƣ]0ΚjfknX袪IVo2,euirXs*':1 לК8/AI1ì<] $|7ʓ~Ь\ Rp?AkLt5R,vpwV5/0tp_8V>:'rPC5.rC=M~=W3ǥO'o'~C.wA2JJPd@:&Kp#|3ަ{oh /= I藁hBSб0wʾ2UZ(YrR<6ץuإ5unN1ÜZU~  q1(1@%eH\hPGbc %U&p4UMQ!ed3'hLsqFUorМn@YiЇ'갦XvˡkkXφ /==e5Ylc[YkΊ"VBe]^GP_f(rdrY_{)bDYHEٝLc`+ n`u˩?˼͇Kz6ȉm4ЪȟʴU$e.YT+ N1{*Qng䵧ʷ$nzF<.w7sAn13.wj 辝S丒Qyd8^ګnۣ478tI#0 \mq`in g/bG8/ab~u+oG!G3P!K7!lQd uU 0  47{UQ QIov|;nׄR|tQ<"w; ewfikȆmoqX-!uhwo(hHЇy(j؇8hȈ(1U7 wz: i1  sTP po {AP9 צX-\1,uvAKx'/s4eK}Rgo8q``׎(~h~so Ldd5y`gi.*0? &ra Cp{` @;h}PAw)EH.t4E%r&2U"œT< KɔMO Q)SIUiWY[_ a)cIeigikɖmuSz[+^#!89Ht`4%jX pO\ 1h0XЊ%Ҁ A00It͸F: (8RNfx)؏ ĩɜٜ ǎ%7&C +A(e9hP  )0@b)$P b!頢3REd\qʡcv~1G_wwҩy67i.٢2_X*z4N6J[f (f3ʒkPM pV  HF W*&&` pm9rJҌP+10# jG:JV%37w9j;3aǣ壏hک" -ỤdB_n3hӰdQȀ E9 ]QK` nJ-SR;As!iuFnGS_#FHfsx*wfXdoxqد*j~خ:iz#C*nYz8h-%P`h2ಲ 9 @{;ck{QI"8QǚyBtJ(I K7% ߧwc(bDb{~ڨ hK%ʶ\)jy{d2EFe HG9 H!P( ߰Up .3+;ϐh1pM@ ƀ.:["ؘDUr*Z?ΗSkv;:$bv͕;C[FxywSY[~:rЋ۷xݻ x=Z{j5w{Xs{ɑdc:su12n# 9}n٧X$9@ ` 8 h&9˰UT򙳭}!!t~w E\X|$G/\$"< }[ M%a;LJbq+*)***1ě_&aW7Q(~*zx%Y*)h|j\Ƴ&m\{wrǏr1yĂqŌ>^P 1F?kGK _lq9{ºr A =6ڊKs;Pj S_͌AsrWR> R\r3%)ٓU\S&Xm|='ơ&@p3z|Yt"n_#t YtUU͒"`UlsQ%,,g.c&pP|/$K}]ۥ/(ܴ>! )?gCeb!L'5EB\Yl-pQ8Dji@ `OKd}42nApbP9h3D9$f=O'V=`[k~]UD$gMa"SB|a#%$ؚBPi/1e"#8Q I]F˸ftՒ?Әܭ,^1^硾;"$<mvkޕq/ehx,϶Qan@ q?D^Kxb4Ї5?kq=m.vk.`O{TUh@؉ce T86H5oVv._j.^á,2tP 3H8IoQqgXwT8]fHŻļMM}'%mOQ0R&fA63V0FW$aLd׊J4D֟^c>'>X`UM4nꭞcPR렄Uc΄ڮ_nYcr*&nb^zC1D*G7n-߰.NnORڃu~.ihYHE1m@^-DS.U(sdTQJ弮KW9kiH_{fE1?)OYDϷ2ۘͫDD^h_aT!JX\~H`e=KS1Ɋ5$̇&/m]?{ OosN>/|Roܘ.^OђVJ&-)d~|%g(^j|fW0!d&kkvOfXhM_LmdXo-J>av1tOga (` \B8bw@9`Ԉ!G=qIQn\!Ƥ93!ʼnsT9nǐ)E;QQ29tp6='WYҊU>D4pLDof-oT1GDݻ"Wo^\/Æ&f1z3Y彘%S\1⨡X"^bϖ]{@ݿk۝{q}.;rs~N\vQ#;"HM>o/NtKHoAtAl%O !P-̩"A8lD ?T=K0Bc1B L a|?J W2H"_1ŝԼs*=QfpgAT;MKC2.R; ˹ 7یK79S,4O2P.4} kQE{4$ :Jߣz#Rڜ uQAԸqR,rdz`e*+۱7վ %0&uzUSlvesZhqQ3^V߭̋cqELVZZ_48Bm6r\҆h! R#׉][9RtPFȹ)򑊋!-YD^r܉$:er$2BxW)b1;HEVYn) g=yO|Sg?OT%(=QP&T ehCPFThE-zQhC9`ɺyGRSZ4o<^J8$4 3)Mg*ST9NmӜ=*MS"UKR$0jgXx7q:XjVZ>2s%vQbD&:Ggd[ZJO{k_zWka ɲHDhVz6ŖoR^V=J{N4b}0>$o}{_Wo_Xg&XD" }o:0cה .E x6q]bcE !I4d"3fg1RN$'YKfrd(GYSr<~R|~Ϳ.+ HC83q3+ư{&`~MtFt h`MZxwJ#\ZrH-e鐅٣% p]jXZ2c񊹫c5g3^;Tyvͭ,>cCL6<6f#n~sb ۃvWi{&}oCJaQ""Jg5|ie'\ gxÝsQd Ҳ>U_‡qʫׄYqZ!"Ws\2V\-[ 9snng5]vETtg`7vi)߀;2gKA9k]kpKbiI9`w)Nc X0؜Jn\chD|tΐW("Zoy~$ }zm ;~.?ǽ替>Cg5ca߈@J`9};IK*< pٖ_e;5h=RSiO rBB/̽\Î>< U 1:  d CA @4Ғ|( *)"phP rxpЃR*'EYEXˈkVԙ b; X˸F;X@d$*3r@V`>p 5L('4 q$Gr rAH4ǎpPsFzF =t 0ǃ4pd 2Qɘ=FڙTW$S6ա<7B:6-&/(Z%Cȋم@^eɂ߯UZw) ]sR!1`{]Qa8MV6hȃgbh2{\qafs WٝWٴ988Ìv MiWqڐ=W_M_]O¼hd%:ތ1_/Sk05c9nٝuW!:VF9ֽՃ2 ,pd"EdO/v8?8F ` Un MЍ խbe=04GeCc7Vc:G;.fcfcch1gSR"ZJﳴ|y,`͋%cM0'xVa~g&~i["#tܠQ@9OĜw=#=諑h'~F#VΒibd7fIp+1F6jfPz7k{kf޶kii4 ܒoD8Q1E8XXmih0{t0}ONkE~lJ>\;0C[寢kgEwV F fWUh(G~ga>2n^a"4_^춭:*]mV>cFfF6:fhsiNo^ooP(F PO-B! ]Vk E0-, qa>qZn(֝xqq?(qqqqqU5$@Jeh @pvn-Kh[]^+s82s3?=@fo8:so9o;=sBt>>ߕlX,|1p@hp'0%REpPh^Fs^L\"X A2BtCD<Xs[ubucCuDovewUKSuT׺tv{R-w:!w[>auvwu3̺ ~v.vdg^G`ioo?w^7d'x}7x|wv?vН1=tJoˁΞ #}P"qQ" vOyw''."Fl=C҆ 8l͖lz&:z7 4! K Y5,'' ;̵Wm({` O{_{o{{{{{W{0̺\  *8 W&&spj6?xfNy|`'Пw6|e |_}{ i* i7Ptpq#jU͞h~?;n0F*(hҍ7 zњu k-!|O97/c/8 P  Dx 2tؐā8\QcF?>I0"ɒ!GpʍWzdŔoRi!̗.[e͙F|(‡`ᕩWSN*"%aUķߨ7>D<jSK>}-ޮ~v}Xz#Nx1ƎC,ya–9v`L>9Va6ԶevmܲO`o޶9v94Ӱ^/2(O@Ȟ$ݵ!'EgQz_p|s h=2^~A^y$QQB1L!@~xU8} P͇a!Ad݃#RPyZPt'y7#Iv}+JM%%Bf g0;Z\}vhe2W>ThmBTSp>%w♧{٧h9oWwXbU [k3ŭFՆZqzڛpXXjs>h݊+V FMTvkÁ#ָS;6 yꣅ 8Ҕb} ";j$dvFHY[;fl9ۢ]n$֒n«o`9l5:o[|48@:$W<{w J++䤙x)h__5@^M[hVr-(hzb1Stٵ_c]g&\Yuo͕[ln~࠺ 95bJޔyNbWM؝$79cdQ*.7r&Ȯ2CZU91.I M.W@oV" faK ۪BCp;Nd ryyDxx `GABl{"{2`x3ɎZ;W,Fż\+^țfxjMj7&5^in ጫP")v99;jްF2uP0W=j%SdD#QjMJD~{C-BPi/-^(jK^RP2]׺P.>¿,1/r1pn u)K ܮk)Ծ"Pv85TBTLC*gzbSbZ<"фAŷŚČ+:e3/Kӕddicdk-`\Q$G싁 Y O؁$-X1N'dGlV!9V5 @ea*gxeX{E9%/EK0֕6,UK mC#:ъ^4݀FC:Ғ4#K#хִ OSa仚"NTD5O,up0X=9-m=JD;]k%(B)~7=?,ۋ3 0>qp Es.;4AE8<ᰚa(vb$.\51X@7SMC3'W'{}".tipc0`vyE <ͣ<%J6k n/XRh6ooq#pvo붛(q?pKsnGws7vWwqO7s[w_7twwrwv7Jqvzwtx˷z7{w}qǷy7~v|7u۷~ wx{'/A-ԨD QF ?eb@"5;>sla8}khDvA8(C3z]f N/ǂhojz0ku .G"&@MVkz᳚c)9_yhy]ܹ9S9Sye9:'/:7?:y#:`::_zvz~3:+::C:;:׺:纬Sz[:K:o:z^1yͨ X+7x5 FnbC6Lgxj0`/JWP>l @A; pv 溊51 sWj;skMP(2iocV<i7|^xpȇ29Հ0/7sʟ|ˏ?<c9ʺ3;< d&(9aA#:t* |Es~ospͦa7ko9j9ol\ds6W |SC??{C_?{eaz!k=?cv˿[H&VB& CP./([D, TK*qJ<w׋w_LE] gD z 3"RH"\H d!{G(+LG+DR0/,Ls0RI7DSN8N1s8:EivEfZ槫Zꭷ^㦵f~l֔W,hۂW܆Wۂ!n;o;o[pEs)aiADc욉G$HE& U(q$. It#B*Vyhl+-Z6Ր.5eVz֖meEepeI]ҭtOi{yԽ&i[sо\ylkF={V 8f7pf;qKsܾj;6=JMV!IkYIsڎaRH# 4k(`(b-+"ፘ5'l~ ۢHκ(0mh, aE@U hMG$"W5cD!Ccsty(pipAh1lii`7_5oe-,e&[. v< f ζn}kbjS0=o31ť&rBSĜ.zd2oLטkd߽e}_7?Gg~ߺʷn{_/ߏ;SOM+nJ~8O@{&z)¡bdp!t͓EceN2 $D`gmNb fz <"Hbz!iަMIڈ-KqizO>1rFѺJqIɏOjQ9Q`In phUٰj": :R\&X7 c+D6" oB>bkhj⮱"')&G1 RA ]E$2o!uo'穜[0E.{HcV5Jjj<&!_O$#n$ $mM$Q }"fʕK)Iل 0vR)oܺ )u(rqr( +r++}2β2ǦRf g !$l3 -  R !A1C &>NpՐN+va3 <),;*L è s^6pt6;Rb %77go$2Ki _9siLM,uF<Ғ(I q+iƳR)+Q-& =i=<4? N@,;C)T ]  %/=N%LXP*"L; o%l$Ƒ5,&w4#Tf54k3#B:!bf6T&SJѭp{0S~毾gS oK=q‘"M6at/4tMgg1)mu@ُP]P OB++4RiR- R')*!$- Q-uT1TAQ/U= ,T"gFiJ2 j6} |8'6 H K t:3+ GF%t9K!S;U}-v DQT" FҮ]m8bc\2}b}0 *g]W[`[[6]]  Q -.s*_>7QbbcRw.VMP6bU6/dkA'4fɯeq6eIvee8>fwҕ ^"F5. ^5` fd6)"gNt% N1[nYpGu[yDm1/8FSBr va6KYKy hq23!G5 r]Br/oZg'+rV#QM Tt3ustI(Y7\l)YVtx7|Wvve7wikx]Vvkyu^4Bl_.(R<.0Ss"! |}W}ח}˷wǒ|}շ~~Vb7}7}@ͷ|^0}Vᶏo3r#^ a{""J0rOsv:D+7GQ8nSﴮcj<濖<כib+O_qA+5Au6{e7Xc6ٳuXHWqԈ>M'~i3n5'"CJ؏YyLُّ&ݗ@;ٓWY! F4 xXU99wo91qw9 hB/(ɘ'Oyoc{=k59Ǹ.Qeڸ98qPy9kd@AܾXwѷFMrTdqq b/EZڡ%X#ڢ/}@)Z1:AZC%h YW[hSH ¥kڦosZoZ@#<<~@=Jd=8$($c?X==#<~کccߣQ=>?>ȺZګ:zZڨﺭzڪګ:۩[ڱZ:کګǃ=:FH<3`V1ba% bP*z۷[*PFhkc[Q:s"{۸ag(0!*:G[Py [?ڻ;۽[{Ifd#jNj*Fj[eklQb&kcitc;'|c8F=UU&<z*/ih6A|E3MQjT\c<{Kbezil7Tꁞ$lw~蹶lWaC#n|AbL;^^݃:M{#Ń ?D# ?37?41_<ƣEX^0 [Wg?__k{ {l54O;7fs1Gϖs/r˧hk?%lUԋֶC(ܻW߯S/yTo4Ҵ\Kӟ!$х |KO!Ç&gߨیoELɊPԓʖ0_tYA"GdL@ }y2NFwq'ʓC&<)2U9k6,0a$`ÊK6IaϪM,صnۢ}+ZsƅX z/ÈU̸ǐ#Kx/t[zr3ΙG-[hԦA fԴ1~unyctݧ}mvwM~XyޔucF3}!ȅ\Y=㻗~+CH~6(ڜ@A`,]-Š tPu `zP9.+8#4ڈc܈;c;HdG#K85ʘCI*f"\v\dihexD"sFp>c,rZ Zn"2j蝅Hbbj((it کDYF%V}Zw^?j磨jj"(zz뢡,(ڪim]g*k. a4uQD&TeD vU`2+ n%B>,D oE%gTWI&&yCo{NФdTQ:N0ӼS5/|3464>Q2S-3P7MQ?-VW5[g]5`{]wNFG3JMT7MW#4vDT]SKw)=uۈ; 7^|vwW:!ˌx7#U>']И+U䳟^6Mw.,wqB B w?1CSn~p/zL_$`/I>&S@&s= I,Ub? !G(&Lc $,Y~/Y ID)mFJЁ c I0 ASYHܪW#>( c =(d"hA ah٢al lIx3J1ATiх|a"X%P+=b _6!3Zz7),%ӟFɽ8쳤,0VB,J҇%HB?TBQlԟ/Ldd({ `Z5kr8IpsL':yvS$2(M Q`n&xdno|[G0޲R))`BўWӖB)>: _F)*K^" CD;f4uI/L1')iOG#G) uQ/u)EE*Sԥ:ޑSխu` XJV2U\*F U&uZE*V G-^ַXYךԏxgmx&ֱ}d طR֪ud g;V&ujCԶv-lgֶn[:kFL;٪n|m+\{ʵh]*[;WLMkvj5]qW`![zo薷P{w,x eoV{jA_w`~}`g -U(NQ<Zw06k_XX+1];xoc"Ȇu"PnlZ S%΃e+C_2c2{cvɬ#ǘ=vhfK_$7Ϝpf¿AӸ2>tMd@3ē~tݼ˘q==wXSƪliW5Á~/Xl;ףue;97Ԧ5m!/Ѷ47?Fn@gzMyۛ~7og GNp~K\x/35Nϛ!8W.?^)-^p@ms}G'ыt;Ly/Nu\՛s{|z֥}c.rOq{\>wP߱qO;񐏼'O[ϼ7{GOқOWֻ;PK} PKE-Pictures/100000000000020000000180D648AAF2.gif?oe͑=Ygv8{dg$ {e;M*;JEi>/40J詅 /^ɤwyzzzd$ oyܸZb~Q7O_b78 =w󒐑k sR(QuSZj)\?ޟ);)<"zZ0788*5ځ\x'ה\c`g9[&q`t]ME͙_ѩŗmf=. N%)6$$AW{[Rxs s{+QT]}m߀kE^^N:W3<( \Ni_IQ1V{PO =nj._R 3ǽ݌G,PH` Sc]{7ҵ6nܚnfhrrMjNT9qTOt?:68:M @[ ;z+XG,=vk4UwdF2,һvd3-wޖhS(ڲ(`Š_m}y[ZP'3`bǖ%k+Au9|VGe7n9m<{Tͥzh^9kO#1').Qݖ)Z]vy>6v**My]ZW6gyK}(,!#Hie'}G\vr[3Uh0\eI $Q)[3aƌ#YKGw=0Za5&wZR1 jȼui%A&8B y&jf03Wfz!vXY{SεqJZunmrcQsTB0ƮntqQ@wF߆帐,;="]#jŸ-{A+~/uj߬\fx?OArU8>|2W"ǶMEHgc ۈs_Fsh?Ns7l`&WJw[8ؿ"T&8575GE0ćGIBaT`[j-'wfTQF:M3fw7p D2?F! LMMkFAra¯hNR@l7B2Z{v ^exxֵ +^;/Uqq˵KMzeݐy~\\X󫦄oޟ:>-ְS2L/X JT{VoE[G1+Yv?#Q0:q+CryS^|Gt+*y@{w\'SB]_ , ]@Ry\ͤ@o>7a/)ȃavXyaIwp|B6e1.I}Wr Oxr(+E2#Pj.TF[lּ>D0_T18P#PՀw^;쥸^6ֹɹÉ=L_n_ub: ctx.Ǽku;<~,)bqU޴ϔB_~IitA̵u.->b5,.Jx"fԂc?lxsTz7̅ WRxg; v,;EM:1P ެg7ማUM/N67ǣZҮjafy-$wc5ԊV^l<*WUBP$+]N8֠zFj0-}'zcVsFLCA3}h-i>*X>!ӎm<(Zv tuXUXѠ޶_uW;ÐLԔ`hՄ8.1.ׂz}$%}-1M n|AAdTf!EwFMXSQޤkn?q=HQTpљ*u앰{Cod*!%s={d+TsӚ3=A1U_"^88:Ș=[r 3ϼv˓UC$X4_RHm#%@=rjs^?Ljpұ8|+6z5a%7`hB`I%sK>& :FY2+@Hm)*ϿXUtÊTZ2\_e&0s'< u$)Efd -6tH0)GiJ `C5 SFhbӆ!HHlDv路nXO%sES2ŵu$Gڄv }|3ؼ9%FeT-$'ꢋb]dMk_BB*?0 اg{ n֑qQf K$12.4#"&BoئW~Z3g vn^8TQ($/qt㼙|{qBvdT7*eXOyEn"jĢV Iyv*du rۋ[`!\SHT~b-(p4ǓJn0޵qDS:PҪu$_aP~o|glB0d2#͏즀_߅Πޓ̠933O'誮&en3XE5\I l٪#/t;4K=~#`&!#t)"-NɒלOqX8 xp$J"3?(-ˊQ*L5#'##{Yd~3DQ' 1TtU6 )w`02VVd'{媑e([hTnZg-|pDP̖-w@mט1Gco'?,qB[Z>VFgJ%҃r;'BL [[ҩF44䠐|$&xa#bn4!CXӉ).pb'bl̗3}g,Ci*c2cxbb0u݉``e+C|#z嬡+Oypuq8zge{O&r9Jw]z7#:9hPl FJ-0-8)'htdD:v;u;c:1;\tWtXMjE-EjCh4%S8F8@3)> 5IF.7EyBMF{:˛낐*yTaV[ ,|5tbKz1ĂCyNg0V9\˾B(/Nut n(pOKz @+JE\7*Kmw3߂=[=eGfn Z4jǠpV=L o\EYZz8ݯ .wq.1 `xZ~yuیHi]߮ݒS}1K{ˉlQgN9r2fYA:Lf[?0ͣ ND6PIE)~ʜ~몯ezRlwI||`<.H~)J? R" cRiRZ'zi%-C$3,ˮl}rʲY)1i,c/L0oulouzMQ\S@ ע(nyJSQ \ѥ\g㐷2kReƟUhr y{qNsFk}gSFqC ǷIId"^c4[t vn1o75|pR]?|;z#Xtd6 LJQr)eR@g4WjrFvb0-]k]B 1eOUn%iB6·JV8ͺ=\Ω.uˢAき/l z\%nKfƨis3U)Zm.o;MNLB # R>JYز/}Ƌ5 uǰϞ甯W|dxx1!F'r3 Aq Fۥ-c]OME{Gk,^TAPkƺqDË&CM\Ƅ0Ht E)AJDZӎ;߷>9a6=yMG=?`-Pާ֘멃ZTw`Ԟr T"݆A\OSr 30@yF,aEf oVV'fDYA5B@<0 *anڈy̰|DnIK콟u+u!b)Lđof ␜ ~IIUF$e /Ԑ/1j^D.Zn<9UZ*zpǑȑOZZK>.#>jUG6gu|~(vxMvbYd-wi1#?kE2-m/Qۖo, 8" !~l]~ѹ|>ete) GFd x YXR Vo&31o"Y] X`34_ 'BQ_dWCԎlgf xcU\wXw, DXGR)#˚L[&-Z+.'۴ޢ*r!Hjr)I]y-~] 9;َQ>N?%]~{hJ; rBBFN~X 5ل%mZH"^OoLnwnsÙ &Q]g`[{I.ZygN[Ɵ[XwzňK7.wvԼvcЗ˲ӃC#ʻҮkb,sg] 0K5\,i&D_}dy<\G6W0Ůx̒Dp!x_pKy߇S檜XP|#8!=Ŀ/6Ume%V|CqGw2ڤqpR#24ٹ`AUc{1.bQBP|BV EٰۀU,L+`fQYDA|2$Rؕ m. fW#?5V4;]M?mwV(be#b=gڵ=xJi/` +1J򼝂rw]y;{~.K4zIm$ %aHk6cC?W(.iuz) o[x(nlV7x`dkR!bܺ,=.2Tdɰf~)ޯzFT$+ Gy2KL%rHTb'5-9KښkÌ<@=3.3Vq&!M:A`Qxq4g"e!QmBtέ˘, O| -cp\yn&ϟ5$b*!@Q6SLFl;]Yu"G{_6s7NUPk* ]H4F;e9{PWv)t:FK>Uhw jxflS"q+J׌emv·7y8`aZAݾ;'w>5.ӥ`2??LՖ]C^d`0[VWv1GԲ:I~? y^Ufg"~T0ɁD3KcũB2'DVtYٴ݁/?qn@(|"\~`Hu4e/39b(GSh~0I\yn6kjT渪vZ\K/sQ&"xsuF{_&WӲB%62E"D^?*i0 Ghk@tW?;Yҕ8AZ*A5 'ogb/7,%!b^:#Ⲽʕc UzjY38*3q1Yo BfF0C$$Hz +_u1Qwf,.L Q}?:2J31pzז;! ͹/˘7\k:| zGQ טB@ӽboU@/%m5K(? OSWy |'?jXKz,V#T> n<, ;n17ežj{{76!)]kGeDZ)FmI12^d(U;B@lUʐ1Ze&AVdd>k}8lDq;_AOu&+;)LE~;4Ur!y~묟?ϰD|z5bjKKH',VL%OŲjRm86LWzz 9 Yоѻ-x-$8Θ|Gmu{/}e|Ӟ֡ɹR2)`n7,O,_c_G"5Ok=Pap$GwR4a#6obm%3+o#YT#9gLF/*g}ٛ@y8FtXmY۪y `2u+޷|hm Ce𚖨F_pHcd. 4lEE GĭI8"WT/6+ʁg<mwR'bT&ZݹBʙ}F1\]v)_R *|GYҿG޼fL8g-hky2 CsJlJy<;2ڋ>zb";pE#RB4.w ׆rcF~mASC/tҊk ?TB;-ڏp# J~ )u!51d ) f8c(p,?nulg΂z2@[R;C0?RT(~}bWY (Pt@+y}`6fAA;\HK`drǡNFW}|W}Ψ, n)z4O(}(δEP{5,\ܩKcIE祊ҍY(mv|`zs3ؚ1Uoiq~>n :R4R s_]-85>~24ƆEkLFe9Gx^Td{dZ3z "YqW6Z@cX i"Vrs ~&ާTUC91~>hZ27\+Z ǓMY3HZuZ*k3bq2 ކ疘Or~Q>AjFpJ2Okx6QNݛoPWT2Θ"گ 83RX|3V )y ȧZ]?_2%R"6e;0 ö(F38XGu>:!%!A<1YLZ3ם/!xIXNyQ d@'Ӓe>\߃/ Aʸt$;I#vr)<^* |IȽΖ4wֻ]4s 2٢G,F"*Ǎ+s!Lsq݉"rb(arP62ޛG΁⹸!@/ड़ȍ͎ С=EN(Ԧ L췚Ge+sta2:5`iV)a̔NUybQd=pB&iQ|ֿAaKeK;/a3ɼe ~go9mp͵\?өߊdBpy!;f>?쳰:?BZ#9;YX+ND ڌ# sd3LYixKp y^MKy5:m\::~LGr+j)y2;jӤϟ9qW:ajku q*{;&^C=T挹|hzOc*|Z#t.Z\>iyaW׹>d8/;Pp(!)tX'jߨ"5rKpJ7Sbu8,6GN҇ⷀ=WtS@E֌w<طoK\N<_y EFk(o@ϧ.4fs{>l058iTs {t;xSۉʐ*5505>f& =%s1cÜýKZI~؅Y Τq pб/T}i)Dk5S%>(UOhRr(0jv_|Ns~U1:DT4М\M|%[_[Q8(8Kald3^҄w\0'hϕk`06zZpETa/|4uư\2 V;Xw; X5>d>y6͍xu; c)4ޅ%ΠdaJ=_kwuddO>.P krOs{ 㣨nj SRW !3mlJ07Uaf$ܢx}In?" QZbF7M=ɏ/fQؔC' 'Nȼ~-<461`(|bMe8aeKd9D[aL1Y #jST`(ʜ"3asw{ok?GNإݜya J8b]Mó0~̽sV-"LrYx{lxʯNf2`Sµ96 4 *u L;$əݻD'jv:k+|v -iYK痧K:k{Q_}KM7+( n^plDڢ\jgg_~WPȾh #ыDŽ~r GoTe+GE/ #/H!66W׊4s#9&Z77ڭƳJC2?EuGaֳ_zwMX-)fTɐϬz$~ޒ9HGƉo%3൚+l1tz7vjOe"U@X5f%s7[ȷȘK cpՙ$Q61j5q4Q+"=TtPԦJ1o dr ɂM(TҩMũC2;qZ}#vs»=,>\R~*%~FQ\8]R&tN YQч+QGZbvEE}/m6dLDG( {hUfFMIϟ jfű%R &_Ӭqs?־}7Șlo˺V)-:o@2 94nO1Z%ƃvAN8m Q;͋n *R ei.̠3g@wNx3dD qXhn>W+:.T2]ҥ# 2[_TF@@V wlGƸ7Al f'Bˬ'y\\`a{~˽Ѐ?f^I0[ 4f\rڋ=LՕԄ[33X,z._iz1>{A]mN/*s 4gw<"WUc81W8|ec8(ʏGzsQי!}9ʷ}IV{Uc ׼'N PX9|3*R~ 5rpk5%,DGqaAV<sNHL 4(U7or @d\dWDOPVj[j^[OIk ]fZWC)hWҗR~uzED’+2yF:aUӎ1K(5ӍdVu%yUcW^CΣW&YT+K5ͶF[EaU;{o{llLURn(2ϯDJe,y4 ';4D-E DΎ^G3yL|n, l `K?iC0[:֔ w*յ 8xW,C@̫HdmiH,˶,q0^e\6y٪G6RTmwz|hRR'd[*aqR޹1˟IDQnTs}[ux%CnƽPL5 7c/Zɗ;ʹ(43w2)1e|kVzl?,ʤфq$. yWu_b[}+'q{SbFKYرX X|H ۛRt!J]MmA I3GA܏ja2 wԢS5lxνGA)E^Uz`vcsY~| SU#r}kT4L#M^8afೋoP%\p$]k|JKv_xv'n)EUH*9ʳIջ='>e؎ZH$>6n(cP7Mo2:slɜu YPS0cF'E/[o#9 ԰?qٖV.UkM R ~(jH*{IX7>{fq~]"k)hcE+.Eڜ҈7;[%#Lq$@'d$ |F`4SOhxX'KB:*AFxP We"_P3c \ A -£nPgV(jVU %խWyy|8F/T7l]o;{RFE :~eSjrk_b%pM5t1IrQ^S@ \vJ̈]b԰ap/c6Oƒf- /'tK2J >i5iGz-  w -|Ƨ..75b~C a_qY N=7{f q }&ǐGTPz(6&-, M$ -ǯ%z5.ӗSk_ކ]<̈/7mHDEI(>d]K1֢8}JzY\WI)fr32j4T3(-rtsiB ` 7cXZ@lqk}rƲy3S?G`燈yJzpdexac#};C`}R0bc,ŞS8*ೣrdѢMi32$ZÞ lpa<_[&UB.WT@4&vǏpaEeMF^a} F[z56+s˵$KpΩQv_U úacMEͳ6y: H.`*ͨ,7 nuk^Cv%^4{V/ZG#˅w0I ;6|كzB'2fb.i ~&G \3}Tusjh/pDYjW u든?B{?nК@r+q/YlXvlP[[?N`%ÌFt>h{L>jz쇎_Lq~ߟHy|"W+Oc |ҶJrO7[6qg4 ˝ݏ8q/׶V"pEo*Z '0Ldp%vq3>acSTSqTz=ey}%/d Sὣu֨Qd,?GVWp F/xSD)_h)-cu8]\$t$P{z(e2'Yyj}WZU#Eo!t9pt//>?Bot332A r޸#dSrw0]<_N_Hp($L$U2ڷU2N^Sh~{s:glTo-eNx.)# αYj59m5}6(KiU"6ʘ3|dy0r+ >Fz.pu~`kdTɟlCttKQpT85ҵgk]q/ Z^]D(R$h\ZZ׊M*I|xpGX,?_xZ)0}L0iջkyu ˹ͩeZnatDQ!"3b+^qaVs YwGljthб K %‹]y7KoٛDۅ5ܼ{Р0p[VYeK7Px~b1e=jÀx3Iqr,g;(&NwW d&7xFn1z~Ywʪ|.vdJnMu:  A`S!7! W7޽yJwzz@z޻M"6a)f42Z M}.1Nd͍=;}Sl hsz_;racodFA 0N+ItٝmERJ'J̕Fo_Q:Ӿ}?=<wݛuz7UXNE{̟g灻ӽ,-W!%?arģS Y/]=s"X+IuVꎜd ŧq g-`+n4m眍G.hiWJ|qzA"#d5c\̻1ooݽiCP`52a] ^|޿?EˬkoyUcgm(l T֕0Ԓ[ ָ7INd??+xYd3Қ{Fj%4g&0َ*#;yZ)* '3a䯓 QLtCe6 v'?I3G8vMzM !c' 'xgT6lU~RZ kTS(5Q-WÓEͨ ~sEg6]ڝKWl5,Xg~S6b(U4p5Iy)RVɴs3 B`c/+MNzB#`VP&;a^~w5;O}a_p,6l7]^z{'IG߸/ ^:>q~ aw$*{ϓ)O[7_J M#3( 3@Gb=[_>4 Jo.] wEy-ko e?gCx?Y ?Nۇ>c8@nv#+b[`y9䕯ѣ d`$D4uQy=p#M+Өk[)utfF.X`S)F0LeHBv/t*PGܞ@;PK^F;`ӉU~"A6eSzq'NjG=?fQv! DZum*]Bݟ;k_Z]Sʖ($4W'ٟTLJbT C+.mrs-ymmJ6!HnReP< |Hǰxߍ)c\8H~qnEhK!_Z5Nw+n͵P9{ Qc޻v?+MHvg&q' WrңёŹJ3d\?]S:ϰUe̓9F8lܤ,=4Tnf`|ySAD^` g=)cv'qr19:UvѪcL1z@fL;)ӸG‚j}r@+&^ Bllhc2A ʚ*f큲=q^?Qg J @ IM'@ xAQ#LP6DT^BJtB8HQ8𞻭ΩaAZws)p[g!ɀ2D 1` bXg6t{ y\d =&]RV=P6I-o-8WbgCVc-B-R1"ࠦK/Nm$6FWG]+_c꺑"Z4'NC1!Hoe +ѩtDT.?ā2r 퉆"3==f> !K ]әԄ4x#fR]h8 f|}8֨mw3ɏxq{'7 kς(lMƋ "1rdŔPwA<[*Pȵ?v Q`N0lIQxT_غ投Jpl @qi0H'j57CJ3M&Cn+H)Ӟ[hX1~Q1js[P#PN"_w]R^bA"!Ͼ)S/kZTK\e' ? @㪕RZ$JV pw̄K{d /s:kͥJeb}7p]TN=%-0e&?rjcZٳD1ݙdXS+dW`G^saNhm"΍JeXIp³?ICXcϠF2 @Pk}+?t|a,,sېqz!P e`Sm B\1&VMRNOY3tHQSI6%"yIKrz+aP$MCG,V~TH08+?zU,'ȢJx,R^]g1@&ҟ{uEcρTX>p}9Z-" @sn.'~bpy 'FFxrYMWS|;T+tx',v`3tͤJy"8'bi&5 zM OZJX8,<!~'8~pH$_gc&nB;YP>?`{#t7B~؏p+yXPr&P;S>T6UN?CVv%UEQVvlwӵyL .y@y [6l.Y|pS̝$sk/[b_}RS!f=QHKQ9Aָ5M(HS7h1[Ql{1-GjU܆. l ZUޝ{ÝpNg, $)9]1r`I bo$5dOM}\6^L-G/$<,j>72y?b( ?ieLOMS*n;!N1m.2kT.zHˍvFH:W6I  ۇm}ly, ר!LB(L4+0URy6+ͮ%r So!xÆ^ 2r?HZK[^w6Gg[mdz*:Y-1<_\f8r)Ie5Ok'O^"rT~)a˜J߻aXatlqY#/<_$ >ktWRhg$}I=s H)rއ,o#.LD& t2_`庀!K/-8?Dzu"dtLj =uMC]B-&8'Qqza)_+4O#YG;b4`oH ڊ`an{'~t dOC=Tyy4]5 "k!x*СifUv+~r5n Nϻ{TӽΜ@HOv4Zuݜ½<ג6s"^xw[5P?`0/uLm\՜8c>_;D<ʺ%1ٙ$: Ozn4=j%+?k i>ዂxuѣ(Bxa\zy{2]MK@P-DĶ`ݓy} s<_ r_..5!dZ -t=$,kJS.G<VWٱ k ]jrtUw'7؞Le!6V o tzrr㊴Ɖef?:h9/!(65dN^ZW8CDP5%_=`ul$ح{s#|h>>^( Z7b0iE :/(w98A 4*t-Wc2h1Tsz`7n 1Nkoﯱ N9lSА 1MKk'yT@d0aUnTwuQb١ojH]OWäw)uwWhSٜ 1.j@'bi'e+q|,C&': yۡ\>xYXu,i}Be|g+Q;L`W^c |=m䂳Ρs/t?(8r]xG)mJ73݁=JjK{zo]u?؞VM:f2U|<4S8 e`38̫'_ H7!L? a |ֵH澡U]ʌӺf)b7 |d˛W8,+eoj"uH7rYԙITٵXг㫀]Ӂ.2倯)b. Y_SY߸fnxǗQuY/㿯oc:KmT &UrAAxr&`+2!$bHa `N'!xl/PLU Q)Mȟ<`-DᧉD_ ˾ c$ {i*Tdd 50p"1Zt3giᱯihq+M#| C `CEOHpN0/X}+0AP* @3%hBg6s>B)9khg^U1qdXI$ܡ"ulG(_9ʖ֭eG%w!;WӤ EqOcRRjNӔPHɀIJ=5[d,vvK1j]giT8ߡcgO% -L/&I}1pbVii,{yژ0$>IEQ%WHn,8iҔrgB>kS8HRbY [6vOс+:r)tk!":,KC^l*^_heb LqJ?%UA]e'=muOmWG׎8a9JWhZi7}Wڈ'r & )sz-.?۴y42ooB/qBݬ z{۸T_Sc<!,{TF]*Oau/{+7bLBM<8͓ƀ̏ lz Z[Ё*"|eg JX78%PN!No1E1>1ZZAxrfɇW F?+LY1y~%K0:MH˦BL9:~NyylF(F$og!31?2K 3Ror|rױ}dSMJ;O$o gkz zj(Lib#j̀N-BBK6'6P*o,ӥ>ʵ#!D_h!>w  1ZYێ#s2[3K݋{L.Sv_=귫q_N⤫)h +ƞc mLj@va*| [+=3X72nvS7luiBP"4:jetaaC]Na6xb(75k_ 56Fim)*!~ wC  Gd)1t4h>kd*z;# =F(/m4YoHA':V,+;M0$cuGWH" ,ΛGQON48!ZmqRJt-Qm|KD`uoㇸɳ0á|{Q/$Gй,~'I64f)kIG"s?>ə ƈ*.^x.W6Uŭ[bB??lƨО\օ5 Ҧ5)6F jآL:$!e4U}so(fj".2oMڕlF~>p*/{jUPFZWN;<|,q#pP,~^,C,܉{6[UiGQ;fz\Ro6l9ʴQnU&aj r*/AmN; c®H$`OC7~Jv>jyJˎI[,Y3#ʒ.S ع>JV̥Gˇ?11<.4o󀹼 OU>޼N|{AmqXE!vi (J*n5r]d=>TG/^M h22|ufeVukI vHtܔGťԀ}[VH!Lz5M=wy?` ga0~ؔ/voL|{#j!Dٴ/vQ Pꦌ8K P:i|VL_0"("oE$DD~PqGE$|:yyh)5cMm]};ȟl~^͞>SdJx[cjyϢm >+s۪۫Fi؉}/ ]ܻpZ3?9c6iNEr,)}ƸGC.ff.8ƕӕ(o_# bso\ E_lS_ё|hUP䎫tOL"./|{L] >1bf>3uxR8Јn:ٻmk@1_pAgmgگjI#)'4MvedSE]Q!r(jY,<&Y~0e l*OoUŅ3^~6.O ;ksb,NE ߏ>S  3ҶR̈,T5rⲊL-XFS%童1XChܰ7ެN:y'wApgdGe AD(K$1tyKVr+usB2v0rH2Ux(w8eI2f}[%/%hS_p)[S2f3_"؇zޏ,F n`BDuѰk׻+/xRz$_i>v@(`մXcީ[gGF1oVjC:|" sfa ~X޻?@H!ҿ/ž~/겏~,C=B{@{uUј=+:WOlҙU*i ʚ/%jq)$)_kx]o48ˣ?[>_=M8^3<^SͰ@(ni5)ى ))l'@l>Pp3=:cD^ ]w?L]tM{ww r%|Դ0jg J81ǐOf!DZ>9ЦgaF_Iʃ2ec{"ӭv ko_Li^珨]+i--qWcQ1t\z3CjG.rO/]"$KwE.QDf`txqMOgAoIO!^^5Nd/ri=CE-}WS@x 4;Gتڤ}Wn=B.r!!PIΥ%r#FHqL <@NeU1;cA-ӥYY̹- ~?BvfO[S!Nrtd~*'qS;`O׫P LxTJ {$Ҡ'02] Y&I ,B;~E*wdLȑo>3|U5^`50gǠJnΪ֐{mgR#Ay!nc!e ]=zN>qe@v !up1rhVcӓg3)8=3h;Z**P&A< ɳ 6&_% +')v$k7BNfP;i,Pbۓ4xZ۲7JV,}gSz6#-O+x?,yλVM1cgWf$ȴ,ٛvw "6ϱyz S T+P2Wqኩ)ݱ^"\yZE.g6.Tގ1ҏT o(i[Ffp3?G@Bt@9JK0u <ӨVlz(z'?nUl+~Rզ-3ϸEqF+9 1'Y.\ /}툪ꃁ4-z:GΡ_&T1A3]Y#̓g5D>Fbav뺤hVOD):*z+ou r}Q!֣)ZzG&ͺ ٙt g: uuy8}zyW@OuNrX?%OK$-F7:>yFƞ%9vV?[3κ^p)P>]6z?~/;[x;B{qx>P;7'?(rUC.V[T )(t쓒/ag0 ?wՁ=I‰!+}2Rɉ%C`ARfA_RB7{.|[K۷kv/oU'*oVj"_hٴT-mR%ᓅp@qW.ccNXfT19WkEqm݌BYxb͍ܾn!3 *?7ȷ>W3 NP1sИiȺ{Hގ\H7 ;c *7xhIU$,ĄHsqv\xdS=|whl _82vIc _vA"`pn#ެ %*)>pndWe8..vS;u-}7 #A}!dG U %Jq&\c^$h[Dz[;k~1S v5&YO+KWB,L'p.[?5ߪF&E^$̢mԟ+:OuѶarnK|_Kv7s, U)Ќ~|ea+WRhg S!;*-f ^RugN'6Jx U>p/ ͇t s) 3_ތzD[xDZO'b/TxJ-JۍM*.(7Qw6[PV AVc)p2Ʌ5 E(l3 /l*YH~֛uܕiU1\S*ǯE0`/J<GYO->PBh9vߣ4;ŨP>8RGdݝ`ޞ@Ϣf[GQ`n`ֲQ(Ssi6M.,#l-bW O3(BH8w4W3AozlN9l w/xm;g q؁dQ (UrDIR<0c͂PP<͇Tr %np̅2?ld&g]X/mFMz: 5MGlI  .9ݴzT}[RSSCGB9<+oNl@gV*x4lv"Lî{s=D-gnUgLHo:nUG [:ktڼw(fRytH`j'ԻG̫q^̳ܶ 1˙[> N .*3dbG  m?W@sO`g^aE8!T5]/0҇: uBR~dq0 G % )7۝fE)@h{'~6(1{_ ԰>vy2$`']FD@, ʾKS͕&A{~^ Rrc UMRW@Wr+܀s:?qv~(-Y]&cb2!]P=&,zJ{KaEC")9Mou+(kovNTX0n2yD7b?V̔Xϻ[(;<^ Lvtic ?%$v~$.6%[NkOo!  ߽!oaWsE֎h%!5R\^8ףmg,!ծMZ:]T<`quD\'TDi߲4ǂW F\]f-9ʹA2y>,KZV0 Oi>_ZGa$wz4} Nm]~Q!s"z$ak-YY#jϾW6WXs[cg mZRȂ(n旡H bR>8đ h&Ӆ}M%c! .+׌%h*wW5M{qT}R~M@UMŵy7ԩNlbWW؉¯~BUۗ~$)D!j- s3=Q=v6^`뱩_#xy爆G|(B]s{Ror]>rFOI=ƣ!: 0ؓYaRa< ίԬǢEM)#s| QTQ̷9Q{.y]n%D(8h(Ͼa,`03c$bli,٢l fƾ$[%Q3(%T3T!IƒTjW}?s9yǽp /@̝^bF-H[s|U㲈U[Ce۴Y[aGo}:VϚBb7*S?zB0V`*mg-ֶ2 =r ug[r}}]LJ}UOA#zK"G\qW/}tz6Qճz5'x G{\v$BN`_Wإ;N Tߛ^ͶW"gwfcf'_&d ASӎ q%qz m,q.3~"dg'q\xK d'UZfV]3s56#X!̯w Z C_ +/߹';۳//\_%jJ_Qg@-Mim=w&}G} Fk5u3նk0Gq~EN[t{_0$eh|in!aoT5xj|g[ mY)[;I|!rry)p|gJA8~<>o޼Y9%uhg-Xf(Ku'}hmyKXuPO'MLfƣ߽߭{`v#Dٟa^Tb.ZMZݘ%ȳ J`WsUfEyJ5Ya{toi.Hϼ)THuɌ,D~^p;Vy^JhX9sĎr'}K5C;Bߝ rI{.V˩5biTR]ss0dg4㞘RaFk*Jw'UN 7 sHAǀ/ GXe7+N g\-//V<_W1Ed7.; >-}׏S20JrQ}G ּEǖF$Y )Dڭo+&RTUWqĴW5-:a2Uk5֙]|2MQRMuNQix:b{շ9__>2׉m-U~{''uʊkE鑈Lbdzce9\THjGnѲJ̊gbgO2]ޝ i4˺PYpNǛi5NuâkϽwM#Ō!ݤiVF좯iA\Rў*cy: CR@6 Evg4ZXQя?K#'efbB0 .r{2q4S~ࢂö]siqϙq0$` n3JfZHk t6|Pid=‡lo[ڦ2NsnkgFyKҨN1qo|"+?1;2w>COW´sٲ5O>rqqX5/ܬ]qSH;LՌG>xuBYO&T7NZd̵bB3ւ J^t໖upVAE֧PdHԯ}U_5~xBxFշ{KH#sAS!SC=/ Uz]Ƥ="J LrZ{yŠ q$_/Pl]cz&t :1gNueZ#%9d,f!$F6CĘBTbycb~#~tȷȹߤe~(RNNU˾?AmZk ]/MV0dŽ/6.rޤ5(j09>j#aUQ." vvH#dk7 .ʄhCvc83UXQTXv1-koUğ(EG اӕrHm ZhY ]iv*][Z(_MZn:[B*_ SBA>rʚkDc<#F//N7O/Fj%{Ѝjz2wӐGV|{Pi'OpZsGg~'z-[Wn.C@oN-%.Ѓ=ŒG$ngp{`,4F@8`lQKa0,f'ag+59@8CRЈsU1odCb@`B^ ޞc.el +fnMXQ^=lܬ;7;33`LL,L)7#/DጼXFOӿŷVXf//nW&>5~LrkV4:evAy'z̔-v 4El^3ϾuJr&bQ.{,rm_auNi+xiPY 4G %"EuI)Կ k,>F`Sn̓N~E)Nɞ01E\{ܻ\i$lW5*ڡ" 3s>)V1w2GO-E]w̅96M 2eB_x~XiH ކe0Z=BZ)VrAqohn+2Z;L)A6]CK2sQ!Ɇ:۬&yO]ğ.[7wm:?oFuM~VA_:=.|2ktlXzJ!%ȧ-ina)>N Z- ﳇnxCd)A/ryɎZ׭Q\ ̳+bv V,*x%Df :B;hKzT3V5.%2gXȴN7GHY _$Ywi[nV,܇ h޶)0 s-~.Gaĝe:GgnoNzFL3 OٖRcne^}nmͽV'#-qhfH38kayov?1x; (Z ^oݽek\ (>#Ʌ#gŞ_O:1R^o?`lzLHə]QnH 6m>b]MP͔kB mƾ[mj6%:Vf_6]/ x3}~B7'؀q&heW\J']/0uv|:* {1`L Нa \Q7h=h`SNc6aZBXSs#|j`GB93$~5@Вz>)?'JҝU`[M[!:xHQᎭYOv>g\ ha`]fD%ɞ#ȶ"[ =l-qd(@k ՟?*m51yH;9kE4)PBzz[M@cY )iZ\ W|fe&i9mH~LdHBۘ/ŊLtCj+*kʨt+RG#≶G|bfa(yXi+ou!|GIsb1#WG,'G7_>lYs ipV멘h#t¡D~FaMŞ>V6kPx9Lʚr4ӠjQ*50788~X9]|g KB%On|}Vwot?aw%1PH/d#E82(t܀VqL Z/P}|,l՝vesJusPGf#,=3XöTJ`<0COD3P鏨rZwhGbK! T{_%?s^O)lϚ=ye -:e2 >D \(|":ƒ~,9 0l[;? D\si2Sɷ8|ך oJuV>{X~hrt!l{6eUyGNu;-8ݫKaZI/JMW!C9F Ʋ04G $P|(8ZERjϯ%p]h3 \ePbxx*Xa=gǿv s3RHZ.4gwE)=Qؕ\CJx[Z H_n &-^gJB *Kyh|<.v\)H?Y@S EA6a w' ' QE\nD)!~Ǻ/S s͗t'շ'Ǘ;lzz`NG[&O*U4yNj>w'}`XnS` ETU.**1vU402+9x^wM;r%Rتot^<>Y[$ikyU W&a$ȫU\4*߂7Z5j}Tu'( Twj!j`WLarVGץ8K1>t׼K{$ h9M55UG=zX)K9amݤvj6GbJ7JlEj)@v JK ].^(\8U!g(9f=ҸÐsl(}`,>qu~ct~C?$AwڳdPlw9+|PI̘řD*8V] Dw 8%LӇfPC?%@KwRȩyU)9Tdց1R=`%PIVC>;_q*tbTN'>wGGLޣ)di> =`eeӰ.N(ɃoC>9 >\1.aČV- [ݾ!bڰ>&wv K1W\ln󞜓Yyd 'PrFd$Jj*c@ j= M+| vbİ4ї;aq@~N7möw(s1a+<"|8Pƈu0h7bSH4ʔNmoaD'/ƞw=bxC BlD#wzqNeuZ^Kͩ^63pmsB8O1 \u/@f/G! یU:DÏG[{~<:'R$ͅѿ%hc~o3_f:Uz '1]2)ԠiV0(I;ɜ1 =)N*c[k1A񛵷E){:{; #cD.JoxʥmAI]vqRDfP+‡H^;Fa%B'xm pDŽ||az/GM7? y.wwŧ_;xEZڸB%hF/z߮sϚ8zgwOW<(lh Nw#{?%x'Jj""BvF6Ȁsn$8>Զ>y<,r 0͇êSXkTzLm]&&{ӇM 1D~Sۥ5^S\$C-C$W&/N9nppU_FλhXEjɫک|lY/pN/#}A+CE9@#mq ̈́ .TC2\w'BQ((1̀ADE. Pܧ˃INŧ/' okP)swTl9$CLBiuWAw%{d4n:NL4섍o{͗=F}]? x}[3#}ř0PD:ӤFV:D@(z<5ǹ2υ5]{Sن}N"J}ec.w7EGkh2Jģ3G ;:Kzdza jͤ& >ǻ7WF / ++mq(${ *\jV@(M=q!ͩhyyÿ(9IҝYX]iҎZ9y-h17wΡ<#1ޯ wL\+.8n]؜9kT670yresmYzkNbǑ{|fG +$M!D  ?0QBR*զNO9Kp .q-0gL~Ͳ%_;l!9uڷ1[o2n'J ;YeC +RBR|KId|诘iAYos9܉95/Q񓫧˂np2[\׺8+'N=wR^"im錄uߋahj#*ݭu_%uG;+G<ͽyC[>#CL֘F:si#؍CFO8EvιK$J\QEۍK{ uD|1lMBSߚig j |pbmw XE% 1cEhS5 qPD%y22'>.z(ajELSDS3 `-nQ,o-9BE~Ɨ+2eZiï鄫Gˀ$O`pL;_uN~Y-cHOS'~`[jesͳƳF$yOݻw .I) *23**w7(;$|]ýw>p7(6F-Unwz׾ʛw 0dFm\;T{pMSԇs1]vq/P02*owVbԣqOdCbBW&% ڍC:/ RƜbһ+s_ UGkW2!RM'mVz@Qfa ߀m<*r;~w[kcM9w ME㗯 4B) nOs3!'Ƹ;(7H"_qgF]m)aY`?t~ g+[u{xgDk_yne\)l%[KM3RMʆsxJmvAZ7(j<q@$k,;TK0w2hO_,l5Th[d1׮lT/jlzWs6ƴ"t\; \=j}'PXo:6j{qgرwSVz͸]o:ֹp;w34<#kLc2'Qetp݃$MF}w֥aIOS4 UsYl|KDtK:IOJ.: u5iX~}F+oqsjvf3 XG49lڧѳ"yWwNiXcӮ> ^iyPя|3$e߉# ,v҄AGJA6?&cP꺂Q>`uFk v_|}AC갟_LM0Zu1gt)#y]6UF]J߈e<(ru\rWS0oT_Sz}mNV;+=qscD=MEٌT@5& LeL5$pGtܨbHb ;C=bΫ&jr l|5uiXeN^YQ50͎a""8Md@GN!hNU,ܱR-5<ZB,jz <>I!ps;9 nsj i_p5{F4" `M"dXTjgYʾlaV鍎FÐV622˻tSԼյgv?]XKwcޢL4o>:}Йl,HS63?a/neX5n/nGǤ}+lʫ lO3y&S)6oKe>'oiso}u&8_pp,#!;ԲYJpPyJl=WJye6[/snhz\  zI&o* [%c:)X*ˉ%@@څ;[KXhL!t:_~ۯ9>uD8pg$Ig.`j8RU΂]14"u)v́Pp%0Sk\:&. 1;]6n4l?zViEacXN٨TAtiW"Dg elHlv*inIm}uKۉ>X"(PqmU͇eCHbaX|Rra踎J4'6m*hs󘳕:+92M'0v%C[ylʜemm O[R}vOy#(&0|,}!uCVЯzUE9*'^ 7ː3 h[ )jW=ޔ A0 yŦc|O5\ 7K) Jr/`@jԊApAEhZ, Ri[~j9MtȤ ņM!ԋk7S{\D^P{8EoIUϜ!gmk 8G1t$lo)慘wyCA#D #_-p#7HŐ\$5%7#_j)>[SocxQI2n&=\2aZnUeKQ!kWGU|TȢl$)dህs)xSD27Z,W@[wruW@D u k\RD%F=O6Dp`%xe({}nEpTKM$fy da-/Ϋ.szNZsHlm߾ gUe-b'BN.'?W[*%ᥕw%b2hW2h&HΊ5靘ˌ['N'M_(͕CikgaLh<> :J x )@nȔ66Fl5w9+V\GQ:@vt*SW0d4l ǍPx=).p@JފypKE)f{D^N\ u?) )YZzH5a㔈?f1ʗF 0E'*@+J7~m#tӉWP";DARxtYn?[Qf|3D'"VŵS/ؐAK/%ñk YlȅZd#rrAZ2$=0*%&C\id CaqW@yF?Evnw:mw  sRc@Lo&ͭA;z`<{$1rͅq^>+q=Ԍ 4pK9sCF#t0knčY.P@Vă?F@u&x1]ی% d[_$vݛyS$ M1bXٸ{5+ A\!71-aUw(4T G)f@T^zW#A6+1{Ƹ{IbD#ȏv4%iOuWV@EbE|< 1*dο"LAL]qO5lj++(g!)lj܎$.Qs` Yjs h 6.[^s=⳹ aEs[(g%09ԖtޝU|QNo6ӓ=_܃s~얇jijw@TrHTSOQBe/Ut)alv=Ybro{M.NᗓV5zAӠx5oe<8F*![>m0Pp=Y5J Z.p#;QS2s.j \ZlrPyiE vlWZWU^HDF`휘WOU F.Cv_.11pǰ|₦k<ú4RTo{g~{K*nmjNc:f Ѯw+ؖHlo$X2:rArq]kQ%8hy' 2vXΩC{@?J7z'xJG^[.PWycxd40&cbru/XPm-ɯcoF_N*8>gju˶>߉c ]a|sI͗I~&0u3/p:!7pLA {ٔf%lP*2lS[!xĊP},3-A*ɉIJ>5@*Q5m ҫui[YC'냻5HXI{.>B`(\^0,7k&P2l2V vior2hէR^8b,%_x|~%`ܕjlXÑ`Hn5;&E10ɠK4WU5A^o4>e  xpw(sZ8~Q wݢOiqiQpL< cð9yNvˆB*jsJR!Iv2T i9$RmNQ%J5%Tq=qnϧGEħ$C /7ВuaB9"][vXrЊGnƭy +@=x}}0ZqiBbÆ`T*wgͶ̽<<>J+}c+H50Y*POh lolI%I+fm=̲Qz?r 7ko>;$ycD̍\L.lߗݠSܨ6⦓0S7mjppG. WT=4>wyPwV1J8O{981Bh>wS\Iȼ sn̽w }eC[>&~ljhY_TjCT8!s[A*}7Rߡ;FV/>F8T萈5+Py}Z[$hi󏀱_2bڦqIVQ8![aά}W۸~^ăUYW/uN^鳇 >e}FRnࣚ%YV:ZIbt9͌6} Wq-nhImxk:"P(u(Ҩ aW65Ҭ٥1 2 #`tO;mWѶ,+;lQԢG˄ޛFEeM6=43?f_8vn{OϹOz}RcطOZuvܨS,7NV>vbsQXh@O^!xjuʹIX|Vevd}lvmbF[. ڎ܁{\2 dez#۲I'W< iolJ'ߴiG%b$bxWL@˕ ;}qÕ#!dh8Aӯ͌nfY5j'Sa^L1uY~u@<~FG~TRDf q{jc]XU"u-9<'5u(ɧ}-ξxZ3y_L_"-ND@rjj̦f-B c[ qV8ZNJ;f ǧ- CFnCRVx,KK-Ͳe΋lOMȆ/|^3ix [TADkzI0!kUQc[èQYY[nwUY,_/ B[,D)uhBn|WMÚDXK5v~}1EOOou%^8ZO_tMeMޚqo3V[ 3߅)T$_ j<'^l֩Z9rIWa%#~s98q7 /͕&Q'p _jؠ`K2RWjLUnD ڜC3Qp(RW]vQwMVì-f./FYqDs|zB~\`< jeQ[}U 3ByѦ466 إ,RI}K8x;z"&W}U5b>,rg>h}ڭY!vb[l'̷|˘P_`0BkՈ:"ԉWD\e->\`|p3ջ!4YOaȱ=_l]t2d$aYV^~,qӝ2qwQ>}|n|"SO)ԯLa98 x䨥Њ>ByAXQn!/ H taBޔ%1LZ=/2V)~bKIQJnlMv$<e]"4@H(ZSfw3畚;giFD'z 1oքχ5auy>(c(0߂{XM khyȠΎ/sV)e0o Eܿk.=!zUy%AG3 KoKT+F@mPmon6ChYCmaLG0z> 3ݝw1'%{Oz $%&{]sWLPؼ,=WA%r!k?(*<%xoȦ!S/P5 @hg6%*LZߩhi/Z`@W#oAլ^J@^W/y0/%he%^+yr f6?Iw+|+F;Ӿ>7ih0w]Lo 3SzLaT9g( UX8jp|g*?ctoX@}p)Ǫ~2U ;M3ބJ)nu)??3X"`pˠѭ2UMN^@w40 '2x7_-6xpEc[4+DJӤW/ؚ"Ԭ9=i?˃JkEwT4yN%xXaZw[E>GϤf|6]lw }noi;BPa>c&5N)v7"j,Q=,@AoR܉[{ݮksםsu5_{A7AP7,(3妺"e+^U^cG„jZ:rbu05+?^G,SNI nQnV "uXs9 3i5)c r;P[p Eq,G6d>jOXݡ2m\h0.,N_t9iiti!-*YFA\k?L/. H4$$E$0D 6'ۅ*dYIx.M`}3#HAlM6hGA/[ &b۴4GHCaDC-`Eh  @nbT"†QZ[WQްo#C _6K_I4m? 5IQ'jQq֡=+glV|Gkju=aVgԏbK{֣n]\c;%e|rlbdw9Zxb%AZO#:خ*yr 0 '#3BBzÞ7٪\C~"öqP:UF=R:#+-bn~(>N-ؤB#53BMu>)}9,fC ܪ+_2+A.y#y }π{tUr";{cλ`vkSǎTޤd 2x-N-%9Xl:nb=❚uxtW3CrN2Xn,Ɍ|7i1 N7-=Aw+# A3b@Z#(Rsߔ8Ե;8ζ3~.wRtJtުlº<9x[\p~J_˅ذ=+Q ԙԖWߊBoЙm?f#׿Լ5> %G$Ʉ}/ z-R{Qiq˅'.-YTS W6}GE;HZ/[TۂO,ح#<<$v|صfm+7ڭD Vxz8VVraMWqiNQOpnT_V~ w^ i9cdo9q+V6r[&4$.:!Pٱ9 `;gOF]oKSMގ8#}io€k|MdVV4L aiDn-90j8 oUOz\hۖFuˉ;֯TianS֧/Uu7_w:jZ{2ENnbwlΆD!A[=(}i i(@-}}<.K6R^rAhުP/ @&%0x%b$#9(JzWu㕥8NZYtwÜ\Oqr6xrys)>-6Ām tl4!J,`\8'Ζ>qK{{U\ȧ6 aj 7U5~|D[iPIHq,xٰ(T ᫍC72?Ԥ8<6O?N\u ٚ$n΀EXdj֢s` H>|.O&v.܀ƁW@j`Ƃ%Ȃ 9pͱËȬ{E{YdA'FH&_(;l\7+͑1:Ŵ}˵bCeߐOEE_uF$O Yl!|H*w;9_"56l$ͷEƻp//s@j#sԥDQDۏQe(*!^ {! z=7^T?lPX1=zNas"X[χĂȏ=ɫ۶nN6:Ig7쌸4}*Ͻ{cbg{'mVG<1YV}ZEm~Ei) RKJ2G[퀴 jAZ~2)nHchY;T֏뿛SF}ö1oD\.8Bao$v|q!:z8o`_nCrneWDž"ntQzjm= ˛"|2$2SSUHmRc-ƹz3\M<2 ZT)n[OIat=;gbF}*c;.40wsȶeGI ^6| Iӏ:SdC[MdAL互)Գ6c޳UKtk'Aj+FNi%PcB#.ϒ456b#LF;tR:!ͯty+/$8N7]$ ?RՁ\Ɯ2.ڌrZ* LwqK*f)Wqzdjp`$ikɼhה2`$[\C2$կX~XƻZ]f*̛v6h>p#DӛtMbQ3B-Wڸjf}J8 ⼶v,7Մ \uL;\hLV9չ5,2m!J(+72/o{eK}uuB+#o0 @wO7ky&2 bE++XR0Njִ|j3{7o G:=0EM2s|$d0ք(ح(Uq@4Y:GWwԚ{Kz*҄\B 4ڬA }33(%o L+ ؼ Uȯ<'΢cE0n}IvÝ^Ծul/JoN_q0W`p )FˋoߜTb $&m@KChr 8CHބ$jx4SzkNL6ʜzY3ƞ`Wk۟j[3 9%*&& Q yf.[u#vGUa#&Z6C TCH o!P.7M3,Q@W: fQ0huQ fC/h ߏjpĒf_ZP!}8_5k/Pn3>jώ5vCK֌ES IYo m8%{s9{目:{1(p ydQ` 4WhS h0R%dwS =O4@*3L-O^(ڨ;[ym3V],x⺜bmqwn<Ш뺮wcScp+_gejn͗[,b e?4^^w|8Jv0$"땺-fWt *Ծf w3nm4^PM<#$rq~Vpf8{$>kVɷFI1pq«G9C͖jٸi؊{Lou/ 6w+Pa&ACNB (6a*+Äh֮A#瘦H.4 /4^~+ }NSJ/^a_ҧTiieboX"}dq!7_4쯠,?t?QBY»GTҋu9(lUX]Uz:00[,Wg0@P41FPXQ€SS~XeDE͔A vb34 ZHkNL՗dG"kCJBU-M89S$E_)g0̈́f }┯w6fULXȬdzK ?ӓhLqpÄB&{lXJs1Ah$ if$A>*{ +KO $=,򠚫 [kר q\[*W;sczvxmiv%œ۷|xgV3/(Q/)}Jz?M`%Kar]aY%/Ҭ;гq{3:1:)@C[5J'd9ѬYENѓYO똰~*~ղC+֤l2?C##픤kWc\}Rnpa: \S%QZ-bU;w$א a1ܒTab*ӏg>=m<:!ݺ-p'% HPAXp[,Pɿ`g^.- ϝ >]_EU\g |{m@n8j҄|e8*+ %%\ a? ,YӐڄ[5S=5?;sV a%i *-keʇ,caIZADmZ!5*1}m :dOGGqtIZ C1tyj"WkzGj i =|Ez9 y ?=[#\-֢m.K4S!ثcxn*Bz;~C4:O-/ѐ#I~ 9\/!lr"쏤JT6^;#2cs^;y}W1x,CH0.xO5 C+^Q2Il~Z =m&_O%@nn@4_7gQ=æLyHiJg:sorV:Pe_.-SO) w- TѲU]($^?;3ɃNSlb * }:!C'p\Њꂶ|0bC23-6ao^AtËNLE #J9{ ,/}ryNE7[DC|遝eYԖ,&Ť՚\4Nؠi_Q}|ӭRR?q[#Ժ$/Mud[X,vj1X?R"xUb!~|[j:c-t l|Wݹm\M0qf$3ysxk5f@؀ SF^d:VN7Bׁs,KD*_Ce! RL> ?fK򃗟*z?+kR} ~}4kߜRpت zDϢ?2dc\S4 ^hіh݀U\ BgӃսXA*p-x0.FMϨ -Rڅ0%qSs.JT+n}R8C{ J?*_;E~`BuyXw'wD8}m䫍:F8 5t '+CE:0']p3[|?]n^e$*L̻qJ}#g^N`|lli0,ߤp6v ٭ʳARQPDF78) x b+'Zzq~G Pt'lݸo]4kR]نrp3FVR[2Ǡq7ra~1+~J.z#IF[ m yʇ*LgfZoZ̟rև -űf>]K'D_^8^(a0YA&\@6{ -୸רa7 \}w^:œ 8Yg1Zp AOgUuVIR랢)pLX鶩-z{̒ :0F}Vs n&i$<|_܂=T٤_mʾ2Դy+X{N_(\'Df87 otŀm(]tZf4V Po:xDZ6K=Skv( To;h켮K=W-6c ,@A3v>c4|,s&x%E~ܭWJЃ.i[~oR 8x]ݼXJ lF}$aW/Qq"5?r84k$ee^ 8'ul+~Gcvrt OW3oKSz,`>7 GOò]SF9s VO)@^I'kP@t]-AAڨxULEKΠlЧO/_":=YXEcD.l-^qH[DfwRI4oG.(:&Z9m%0ёBsNvW?S&6ZM_؈f(? ns̘4yD8OEl+ᙼl)f@ɲi~2^iyvmSt!U}0㩙zbmW7D9e Q dɉ|WSE`L ]j jDv5X̴8C<,||"T¢N^bOy^ZIn lڎB @9CHPd6P2ޫFr!E>WҀr=v>v &K{8Ҫ=R>WQ|D zVO0`/XT#/3v;co#FTIKQ@lPz&f dX2+@LtZ;U|kfێAzݔA vkpewT;Y\; 9y:n~;? 7 ؍ww߼z;m>i=fQb -u՞l\;j.iTS.jƍ"m=ixe!}pOQZo]Ws6]"7i$iu$X:0"yM>Wx7.8SοdFcd?Sdy/Cx;rrSY;R2m*4V P/|zvkvh=lAg7D{F c$O創&F5zW@65"^F|hZWx0HSLd.duwdWE-YJ뷲y!9 Hh!Oj=FQ!^V&x6dv0!Dqk(U3DK뾁9#ϧw9u>W qx'?:TG 7eNRwIljM6&u*GiyRS(Fl]BX AD̛B+@F7\_²Av~DJ͖cj=G.uPP ?r|' J4'/6|[j=,nTX}$s6#;uUC9)ٗNTfVqɾ9GƟ(⤽,a0 NzI Di>W}hi pڏVR,{\(AZ)" FҴg:r t#0)/ra 0DBIa8ql },1i|tC6R)ڗᢔ8]X2(Fm(mu.l}038d=J>z_Iwҳ43daIz6WjBᕔ0阄C9%i&1M4`Nze*`Q-La6ǁ<'Hϓ-%uNw z,o Q6Cӌ4j؇X RX&|QC& ALǾC:R.Nճ~EC -:wK:C<<A+\|4 Ze-MA)FVB׀M DeY -ը߁oܥSH|hH\X;Q#AI"Cۚtq7!)lӋjA[x >:i󮽁kqmq?UQbS+ fEF m`T4|o0&_+ù%#o5K#|w[Z;.h;~ tipt8<ΈNj 4, nƽLveNKqk lCI›X%n O"y$2)q҄ PI(ڑ+)1:!E&CIMj<$pGMԠj$Iÿ s6r] Hkzp )Q?ޤ ,Iz*<^#OuI>~q7»Z43~6bOIIPڀ ēizR5@u t&<$[7Y:S>1vp^ؿҎ@ߣV|7dجV\ "31.5b ]\ Mshp /G|pC$( @Cڕ ITܞ=mT3-YǑa|e",sJ'peN'P ^D˴koFĐ MhtwWG<0O/黻/&Eܞlm+[e8({9VI`N:/W y@ ݋eͲ ܳ.a,\?V3v.œ4cId %b#_㵅<㛓RW^eAaI$LRWkۀ:ZVdAԴW5Vb~#t0 74_pb0gk}ut@2cРDc^IƤ6J@w-̬'Fq;.TTIyJԬV@}EWdͩ H<;#,oD{F;x٥ۍD?C0Uo8*+-y,_1>LbDz禾gn]xŭNeOs肻f(/1)> K )_Lj>iȊx\M`|ƓQ0S NlP֡6w)6&f0"G֍<7kѦyLl}M)@a#!lofo U{7=4bUwoVLV&~0L s˱P8uܝ_ۅYXyl`8l7UXftK Txj"z ‹eJѴ"%gþ~ם#I4Av~V1P0 <>QtLau:a>y}0d-ju0.D'1mUn|5&rx7n:66ީ㭜N2ki.d^w&(@0ǀzzfDm*dDe|{k3_O~_CU(<O]TyY[R "KSr߿sm_y~>djϼt%<6Z+=͋vlp2H_ n!C vJ0nn`\I|lj9Ծ:n0)uЧ4(bD4xz 6^a{CJ}))2Y%VT5ųug=~rcxéO]tY_;.Fً ˵;] O jFer70k"*IpBk2v(ϥ[۬1]3,YS'Y7^הpGTsPHk-8!36f,2GO pAl>H(2ΌWz{2Q,q"W%xwvWA?ߑ0ʁk{Ei6ie y0a$$g/_1"]h E]evnkaUn,@)Y/9#h! vX$  +L0 ^RB7̜3v93Ű-GL Ot]p\AmH+:5QSX,%Dr*Xp#SM|yglxevYF49eU&&X[r(M__3=^0&e@TmUf6Q{H'PSe\k#==};u9Ҷ}|}XH<1y3a^AKYHQ`W2vpj 0Yy't=zL7-re*1eL:>G i ?ơKsK;s63@Vk#DAUJ}m>}TmI{HK73‰'ơ'VUs)[g|;9jm6=PIxNnqCsxk`SWbS'K};R';Lؙ bk0cm ,2!TE4s.ԻoGQ RJ#:iJ<"#`ֺN K~:HgȦ휫nu`3KPr$`AuEYun%js"赬\n߸*g8WӴ`[Mn锥6KfdO{ܖM w}L}U׸p!G\2fސjG{v\Ccx,5%`GNt^%IceT8:'9lUS7 hK~ 8]nξ5>tGDHTi[z1I}UD@: [Ldv|ᅣ -uJ&Ǿ<$o ^Y@>&!2L i7ŀXӅXW9nuZyM#J6nB0[~>酅g!.ʦB)KGz!U Thal OK|ak ֊F0â \UYX nwT- ^1YfK,mZ=l[SX{̅}eJoJJ  ބ"!pHnnjo1]>ýLsʨ=уB/(zIw- ΊGie&K ]FMnų:cךlϘ MzN[LD`NFj.~|bޯ)Z@MGdpۗ8§fZ'ogXjGFCtn"Ԣ:L +Bx5Ƚßb .ӝ0Y38Ng$7!]'-p+x@V.ZPpZ`e2Ff!ځ }r?}PxXt K*: L>^#[7Ep9 ޞ2WW&Y5CZ SPe>_0I` ݘbmv)$Gv=zY}}|˨Wٛ7k 0PP5CE?Uw,>h} ~uVTWŶyPgd6g7>Ҫ<-Ga'L!l.oh{J$ʨp@ʐvٽKiP^jur;#Fh.Р󾮇YӒ#4]zqO=BrF5&FLA.3eùz(#.rbv,h|X62lO=Y^L#ѭd=A/S?{SՇ,[=30)c'[^~~M:M;5ui+ʘ])) (nkfj %??}yܧ-tJZf:݌ǧHnu` νppӭuP5`ì'Kg~+(>wp"؂c]ٛ*H]7栶d,=e[-'Co$䠍?tLB#l59n:/K/f]=¿o4+e$7' n[˅1ξ>R A'Aj"_ii3aG|j~Uv9BғSi:*>#[%NN ' ԽQ){]#\fz#9 @ɡc߹&Ȭ%m[$:9Բ ![i' GklZh;>G.lrez.~Q]F[ͺ ϶PVk]"k4OPJ Q {wSU -Փ,Mhu  M,uP]쳒qw] {Ark-8^ќV}-kKto _KIn1Z*CGV5VdL(N^(,oO;A.>}&Nz5t[ ޑK\xK+Z>r{ +щOxODw؂wGqv[v)ValШr4"p 0M^kI|vz$]v#>ܵ- Xx0iO}'Tظwr1+x~|ܼtg|;i's3L2~ڵ8ߊ#la8"p&9:܉Vr@JHZkwh8Pk=bMVso+h3V#Q>t|A Th v9xOc+[DZtv6OHMѿ==r^Tns lg qJ}t~Wꒄ˥ BF X[Lߖ;̲$_tE4 (*q0^H|Ks0Y+tős*9vr\z|2>k\y@R?'++)t&яM1n6ŭhm:&﷗0+,_עY"~ko3#d,/i~囘y_ z t7lCb}CPqnJfc#t.i0zw( ?&| A IS'G+8 ٟEՕԒZm脤/-E Vuz7O.gEMh[kE w1v rR}TnT%3ي[84h 5n!zݥUu=Mݰ ۣy|\B{e9J@@,T#oV֮|CPփ~:2(W+Aۇ%^ q|d8~:1R>^Idx8sgZCӿ=G,KlZ@n#53:MgӲ-U9}^cD{mP~٠е Y]%-ϖ=(gq:]8tTW`pm1Ӻ J#bVfA 1]ԂMb:cH ɖ ݈7A)^6p\'_f_[r|vdӆyM㈃~̥.!8ְc㏴Xj Vv*ha>7'K1"~^3ų[pd0``%I% ^ɌcB4A( frxš*|gג;|JI.q tEAVu,QMf2NayM_U5w@$}]LHOʬVY$@{iݔKUL'I|ν(ʡH|=ʡdB{ooH~r:%>eޘy?'nD_ܬڈdX|\ i#54{Yͤvi\'7e_,$V:g߼Ƴ;?#, xG*1r~e3ơþYD1j@mL }q[CP t)hM`BjУWe+0fUĞkw;,вԺZX E͛즒z%Y1|35eb;9!*tE ? ߈l TH DžAlGwXzVBbvV; )L|O* &'ݗb_S2mOtQͯ7bg3h78 a&o_a|&eHHY=dGK[,f?sDV-|sϕBiP[|Y`(?`0XUe'nJO@Áxm^oG-W5)ڜ堽M\4lѿTD/srPݞPTH>L;jT~GB2P;d&uյ3Vng`&S ]6ҽA9H̲nKߊ|j)mzt&sb&$$닕|SZ`'"+tɂx +n$a)sTaH)c]zb<藺pձˑ'~:4gs%n8ph0Y6?+c#CKC~`֘ULX~.W3J gذ8攮G9wtCM[x14@Aipz Xʯ;€Xk=aaGIe/$-R5t+g6):t f\C|- (i]B jvTA+) nd8ղDz藄 3aXl 6kʞHa1.RNR4V\UG*Ow9߇p=9Y8\,+ҕ5B:Z`:6F?o Rr2ܹC! e XLhB[y@*]KdEPSz݌ں_.-J奻x3?#$1 R"wJUDg]ymG ڎ1Ӹd{D\\Iv-hįķ ml:p6 Db%4Ee[ :%r=ˀ^^R\cRzIa5EZF1t ^m6~pp WCW:|qs1w0GC8oE7o1>_autzeoW04WCQr}lT&DnKsa~59^NSzO  o$O&)5-VYb*{ חs2Y4|DK 2a ]&as@JS *fCtКb(F,m@P)R ln:&Ē ƻ{}:aI31YP2t\:\a|xj&-ſRj"Dʈ+[\O||`]9|zyqhAr.ݽgYtcvh^f4k"v¯gA.NR> bl\1S3dtObd7c::S8_Է7~"+CiMe+ (kbgg3 'U/6ׂ)4r,X4$ oe(Q)5Ѥ4p>F֘4Y KJs#:iώ) L{=ǽAyp#*H%J^f 0)N'51 `H5 o+2d''|9V2̮ZqS_m30 Cm9 9q:QÊSO,quZGyKWko[ͭ9@=DbQ}]2dI񕄒J^OG},~j<)?&K<'!3Tg*-tH町2+9uWOEuܲt?|Wfv̝i) 8,<->B)/lފLA;"&֤ T/ k ]<)7+^~VDs1k-za .^XSghzBx~7 ?/KVO4u/Sq-p^-BX]q_2 8XY[:tڕMbVzruVt2d(Nc~@%dqn͟E',U~ x(ksas"mό*\<|:Y~@P}l_u?@T;$-\ ws"{miOB3-K_b?濧̕a11#2&\Nݠ", ܌SnfA&pـ'b?32to7M*! }Y ΢-րֳԑTk eBwVNEMjGS='fw%He(yIEIu@n8E&M j;g˝i 'ux=g9L*4v"!2WWޓ 1w2<^sRO""$}w[A؈Q.Cn?z!hkC=c/_?lMtάok:۰HN(ף],QIys.dgd[8fP¶#.Dd^&1q`DwM-*K&k޾I^:x3ټj$笿{uHX-ӼnKY(7~&+O+q876i4cN`|zxQh[-.]!jVɁln"=7~>Ƞ(PVH@[&0<{J0U_k5N@LEYvoVV;ܾ.Y,քC6S%Г pѱ,8HoZ7 Ν,MPJԁlS\ +60&[Q;#Z2d;^[j!5'ϗ3,Ȗ z"v7X}kVe'K7#zW㖳&-ӧ8Dܻ7bܮW.g<k|X/r,yn\o5]NzLw8{os7mf91>Ǥq ]SQkY\*q`^ ۷4&TMŗXLw8׏ 4N5ԧ;]gf6ΗP[qX1OC\C$Am_mpǀ|I-xp%q6fCS52n|b`ŪMnDVX'zTP"b5Nǩ c~s#j*v 6xfA"%z lǴgFK:UO$&Qs7qYRGs'<]!U7;Fئ6e]YMOnY:490]45yZ VÚ9FV qY#y h6s,&^'4SBv~+O\( &WMj!7sf҃w-)T1CɌp>8/IGL'?J}Ò{Avyj_\ozgmaD+(6g@h?'TnI 'oBMg)GSEѢȯ6rLA;`1~DéWt2l+ 6w[%6.ٹ@D^5 :zge4 "_P{ySHk?k&[w]uRyb.C0iQX {Gf~'aڄ0ж{lGlk Q]equԲCQl֭@K&̩[u;%'~آrl^ W\іG_Ў#6}1n#qBK~jߓSz쐮ؘ ¡Giq aFj9f^?M|GPayJjs0#.*C2l5ƍ_yʿnb|y(p l+aF' tu1NތExFa*Po/侲ZR;"Y֫s ioRjBg"!.l4 !T8tmT8>"\@"4UbC(- +-;KX[\8/QϋOo6v(UR'*Z|{CfxBMvV=1Qu8+idj#fm3!\w/Ȯ^vƍ%~2\F5C?w1-XT(V*p>[0մE:kͭ5 "bqQ$O=iJkbS.@TJ*-4f~ީ5QJCsY@ݔ:vUD~=Fy 2kחuAf8]VPG-n'?L 1&ب-nc(ȿٻz㮳 "lxR홊~r|8,_Ve̡С:,]H7S0Ekiq|8LK Vj S}I"~8<2aɥڟأn.=YMQP!~C5xxZ%]^EG Vggl.KΌYS-t[;a$6=l*%j&gFcב^NӀbFjձn! Ii@qvTεCh@\{PRyr_݌y87mI=3ڔ<=^8f㼤6>X :yĺ2Uxܲ⁞~s1Ϭ"jwص@J薜,|j:mʩE 8Sa9k?1*K3_~ t2ŐT2W A/U5^qټQ, %`&N#Ou}N;Š࠰v軞NӸzmu4B>S.qO1my{FM]B`#b@M܈hVEag%1 KM$Hzm' S~"  ,(d}#IK}q,>V(Kd)Hu]jn{jcA'c8䒌x0}7XJYG+Hm^Nm9IAdUΜ5|ö*^ga H;2TT>{>%j($E#8ʌ>1c.q'GЧz dVW3̽ս^ )QEreϖ'tP}8F 2QTx7^Q(sI#9^EKݷb廙iAZ&!%R䷴^d<@jV RE|,ķs6Ff]D/܍0]*ba:=BnފESk%jF*&fV4cEgĹ3 x%g> .0Ŕ] "6*܀?9:y!#ZYgq{ѫ%#JOI9đ#Q1@F !`4 OFT `y w:B#儇ء/*-[/ʿ%;6N0MV yT4oΔrY3O|+(A^. ,VJ͖2ng=ůV5Fz/Sƍ+--Ɗ" \qN6F SDC5X>&OE^]`*U>peH3ek.F7:S3 ^z-z4&` @#Wd1º QF )S QΌxo;gNFmZ@McoA/kúJ[Cܹι%}CQl08hZf?7c4x(>{ 0cirtf Rߩ3slDkx'8W41 2lњmCb{D66>Z?k&iJGzi@fY_|<`o]O:-ʩw.!,pes+&bxσ+pp8_Q 8<@oN;IߝxlV [u03ޒlv%N|sآқU_w2+ e%<旐<𦍿g @@쳕Wv`ߔR!$RZLp ~@.Ci]Gj}-/s6nnL;y<$詐&#:ᘉXwsd;O1C ;: zC/˂C_F50!Y OS=wUEsOcBEU1N裡#22Nn暎v"_xT. հkH\ tƉY}*nI*~a!{y#vk.Ze˺ ;a?lC$2L<\D .ECVdNb)QQt b=F`]e帱\&2pr6%wou 媘ɱH냸!2S@Ӂ@XN,??-ļXO:"|\%-Ώ8 +#ѫkj!إ6pc}VlOgVz`[)QD#Ei .8Z/Hrl@~@ˬOvMcEa^"*N G%wXfZ̓hV #Q-X򀣬<*++?x<}]_J m,l  7V}hn_ ^KGV-ё^m&j: 0mwt-ݍD&]οnR@WL3O 3KQuᯜkw ߥ.'g1v0؏AۯLIzv+-ifuF=-b3S' 69Ey ?;ٲsc83svY^0oioc1+b]?I1/Zv7tضxǠŕlǨDzpB *wN& }X&yiϿV^#Oydi~s3pPpgQb >^J&n>XMo_>cOƏmk|,¼eiZ$r3rsJϜuk|>5p.ZF/CAjJa^sPeAP<,'{@?:Emh"s8 wF"7 wWL0`,67?BJj"zߏ.gчfˢY59+U( Ƀq*c>!+'dPĞeqϣ|X y)$2kf(H6x_B%b-9T?W-rЂNR ci0Ft-d&fOEb{PFXm1.k߄f_PML΅œjeS TPl1˜09B/4g$.쓼> wz6NOˋVƖOԁ -rQW[A8u[ yCxU{e޸q}4rR!…wYA^ 8ڜVbqr7CCMUFmNn^Ftќ?z9ks_ hbN3\o0}@{)<4scesz[hK$ёQx穕= cӏ8 :0DLhVw9*2ǹo`]5]W{Hw0*݄pT=&T I 6MQ!&]~'xl Pjɷ"U V<^ qR/z4s!.T[np a#&G. 4 BA򨥖|0aQ|;K{+ Ҋ@H Hhk"'xm!l-1U0jL-<*0lґzWN cR̪@aL( N Y}"г۰e * M֭:(p"_r2]h ݨ߾UShQL ^I%,x ~~~Y)UEęA; :l6![=[ut 5/+O :@ficoײXe`ܮ;_. 6.HYHz|(.]Zv%mܦ5 !(0rb,(Hj[N\QPD Q\tjg=b8<$4U]B2|w[QQQMp4s?Ԙ 0/iP]EnM2SxD'.\<!"m؋E:9YT n;1m8C"%eL{`Ik/d|ྠҠX6f"*(gEШ(G/Zn5"D^# (WRf#fgOBF}\zJv:&I”E<:v]TPjXݲT HT@‡fhjJhh/)ci8.7X*4O|.nVhz "Z%Ff stؑ lR#_X,Eݛ:>dHb*h`^wB-wt@h:͐H3+Ln]tPlT6 bq DwJcCh%#{[aX>etɉ:j&4Pf."А4o&/卪ќ1?7QznfLEEHPz#)黕& Qa 0^KƤHy@w?0R2-C9kV'BVE[/e=a~ d.ngY!"_k 4jM&VZX*"ЯV2j&W<7 ς} FFr"S\l{sj ^&q JΝrɇi5$?7ٻ*'?[CF f >^9HE UZZm"Z|PHs F%sAcZjjr|0{)u7Sh h oH2,5.UemOliړԼ3!3{uo>nV]KZh#)40_f eĬēکҀ#"|og(5X@+7'|=5W[ZDQRAGXd@zLV]& ߓ]*܁ /{/MPdU:_ ),߯ ˽8풳 o2Uߴ@/u?RA% ]H$,aۺt+($֊LGx5o@$ݠ(̗s":Gs塜2ޠrQ,f1\]I&Unȍ&?n ~yݖı _l(lZXHrͥ4L [= s* ĥҨ0}GHq\z%}ң6[f`}#a| }O37S^DI2Ebg!S?5xYƏCD5M3 o cW|^N cQ+Q^z}jzZWlЩâΦEbh1EDԆJ#W/9?t.% '$΂4K'&-_Fu=sXN7l0qӴwI%5i0Uc)#MvC:g2.(E!Hnk`HH K@?i \բu[?MtīlR.˖E$P"蚐\^~alE!n432(Jab)zO~AQ_]m,{,߲pG7YZ J!N=m]"4O(idEiH.+}4 0bd G <p}SuHǥ-0Q,.*BRcgA*2z+6&/SцOVǓwy$EPݦrdR^U} gcRI=qӊ 6ZZD= Qd7a\́iT]T* fml|-Q y(¯$ ^ {vI%C vҏsѮoGaz޼+wgJ UP g>ko=xPo6d,7oJ[6(DC+ΡtD6 ϋ_bH~ f37`9]C!t@Zy;y{k`WuWt]ـ~- ׳Z_[­4<^"|< j?&w>'IjGEװ*o|ܠ E_m'v.\_B4E}9QaM:~@z zhByY!>5pSUŝ~c \9b2"_16ܞwq١y}Kѫ?y|qCgA\tpǵC>"si"7[^}EZwψ,|8{ cGD…E@]qwjFy#j^̊Њf3GcF~"23C"@`]O}4W3ޏzy%~dR׽`x sU?ށŷ'}3wpo3=~?Y}-$zxśep%CΚ|ީ_kUvr!yȪ)lU)Uh/M eia͕5U4|R2 HvVU_0b6V &\ǀ׻>*NR]-KoFr tx6\U./ If4ۙiPM5iH2̄c1Ug(q3=ͺܾhME8]b=+8w{(:?π@*L>֒ w.Ō$!>CQ׎͟6]++ JC@?w=L5vx[/'Cߞ=Yq/#/f]Gs]3PgK0֔u:nhٹi]\Mpk%yf(FNa 7攓Jc&qkK7]%ޤxoP=u i= cv{v?U4 |=Y$d ipM%De XMr͘&œ!}=F<0wнD!YNcCW`d'ff{DͅZ4=A&ҸGWlnI+`q+Tl;G6+ix)P(ߗ-Nuz|bW{(H?0&o%Lw0tد 6]@L7Tg;CxXK2WƬ]F6{c/-klڡ|=ۑamysŬM2E)HvS Rrkw|NrӬ0nin%se*= x@h? gxSv2:#dCSnZfSa>}YvՓZ3|h|Cɤ5/ɼ'}UtwIwURzo?%;p_c9`Z̷NpSPd76jyz\2˲^ P97!ب# 8˪E<˙% Q!!V`Wyj KYOPA 3KHw4S3q9FA9{^heQjW/R >P 8F+ i0\Gxe:Z6)]ySbi>Juj\E2-O./xrZ6qdaXv}x9*HC @pm+ ac}sjb,hEG-|H zC8]-xB/:8QQ`Vfe (k@ +F_Ѻgk,/9nG#in._O`9.Cj˄ϑK*=7.dөmd6Q+O=6÷~QƟwZ7h_K ɚQa%8 @ic`-/Q`۴Hzj* *=P$wcwOl?S8,KK:<<^͔$ clxKM"rYjgH=]2zӍ 7G孳q { Mx{B" ֘Yj* MG7fdOlmm :v K>rV!:N'ЮZ&DzuX 4 AR ːy6ɂߪ5` Tho5:bh\0W;G;0/G3Yk2cyWS`{}v.kf7L]!{‰37>co.=ZfAi! NV'C| ^H Y[\Р1/jD|{q]f̊*&r~hl8^!rF+{M /Ż\d_Bo*4"as5ЉnS票[ZxgxIE^]ĞQ$=_ Q黻4oDsWcZ)pՅB3p9'KOl.r=7 ;8Պp!.Zo?]Q8uLk0d'[e3b:YjM,PrH)d #rH i~;6yS~1 QҊ|:f^`JڙVRun# MoSӽ^LP\a&_^Er4~RG?R)bJ̜V̟@}gMr߄/ V{~Lqv;kMXy&G; b@H[7|y#3L ~&>#kWCwiə,ekԽZQ~1J?k0;ƜYaZNzF WZ5,sۇ#=g}E7TTܔB ށ0auZFYSh+ﱲwL˯ˤ eNj? SBeU!vJ:z@q/"SlhXϞpt&s﷔ {;Y`Pa1`ao-Sn$<3X w  ~K25~܋NkHsb(sʴ4( *eeyVûk4öPS D]怀QWe9<,dcϺꇫ7YVL*97L Ѵ@evuRᬛ- p߿ETV<훵6z=RyEUmHuzkV6Ƶ%UGht bZrPԥ^[.\)I1zWH{W_H!'A2ePz;YS+i5ҒKIlؤ@똕U+b]> 慇Z p4YFPẳ )'-ȴاVD( "7eDcbyE\Gl}m pLshjUf6!)Uej'*\^UBWs|S98@Ĝ(!wМ5ah+f#'ܧJp% $E/js6Ʒ\q~m}fڽn 6^C^ڳM~1A^]8byǂ0+I 0PݢU}rKBбz Yɻ}W߭}6'+OX|'_Ң]e3 Z$F cp[b~kcׅ?'\7`?*F1jG8Fƒ>Hk. [;,I`r؛ `ߝN9v\ ɳ_JEA:&KnOOgk猖:?}֔mɸ-,vۖX]:J-B,= \AcA?ڙD? wf0kYhpҭ-%pȽʕ C#Oo. '?&UcG  1m[@ՁΖbRRP[F$j<.21n! <Fz)>Ӗe-~LȘ·V[3WM#w@>KظRaș D2]llxBH8sjcBz4xs~G6k֝ոԞKS}0'oo:tfO剶W@C:KMWLrjnZheDg@z=&Xm`پRsQ2az-3+w:5yYsw~Z[ ջ_gI}]󗙎Umn7 ?a?NNewjF M,cΎ+ \3۪8%/z $ C,@1cz~n2Ȣ=N)1* u9 6l5G 4=-Զ:h!xNUjԺjAC4_H 9X/9T2;t%Lj9~9ߑHh!{=;.Tۇ/]N+IJm+2g;$dYn^"&#÷^CO.lG>nLqwy8JL~{&v^Y.\5pyST[]F[*cИr+L.<@bynxGA۞ T)Ȓѯw!6*Ob(9!;fƻO9&d%IG]s,I{hu;m*}%K{HzrY/dR^`$Yaσ,,N<)* m`IFS،|XSf9I`A\$mɲ{iFэ>_US6?.v^!?s|A8 >yR[}UrVGWїDBڏt_-V x[1 :AdtcouQnstR̴FV'FmN-w14Dux|A(k| n+'D^x|sld^`#iCeƩEЇcM8 {FgJ<;V/? 3ˉOndx{glZ,0uەP8϶pJyFWܦ]8^(x~֔Q Ck5U鳇h9g*B|Ru3&FR_D/\']~^dVERLЗ[.ʅCZއf?6om^[BN lLVzR"3j!p{[8wN\N6U_oS}ƷCM}A}6ALOt|& J,i%9υSJ2H[yx4"՛ 'Z͐z$%4o)UF %{pj?K5?7j-ɵQ vå㔝:%Gnu#% `zEvHYEkz, =-]9J_mjZUC$O肁de0`F#î@PםVl2LFK\xj2~kͮpG {L8λ-XǣWrYtM 'ac^%Suq|j5ȳ[`y_UU/鬀w}~[v"O%wݽ-%{dzoRx۾V'_P.x1؆`Nhap#%|d$A>;߫}83nyOly 8VgOY'K`\zi Yw>z䩂DeZ~uY nZDC"`&(LT\S$C7J~rx0nA8UPT4{z68Ȣ 5 մ'2bb@Ķ;qli=JݮؖQ{nYC;ŷ q'j7JIZp<9=P;D-at6poihNZXj4\:Ĺ8(FII#8?{v<, O㻠hn`Zɗ ^H&׉\zq6BO 8S!L|oݸ„yk5#Zl|*܍ [ 7dk5^i<r7Qc3;|"Ǟ!EGgj_L@*ӕJ  ,EI VE*ؐ/`V "C :5:>OtK+p`wKct7/ǖT5|%_oӒOاrv+B( ;֚xr\W6*Vo@PBjaSAs=k'CS8n\Ivht994kGu5>a^$94O\w.߿:dJI`7cלUӊ$<4Ij(J/tWty _P cvޮqNX yxXusaAoyȭjFI 4# @lg Gpڔ'Ђ0xFr #R \p"*HC;|:q4?Y=o[*z`/:FGEe ( 57MB-RĞ/͉^_^S=zNmPb-6*@dagˎתynߖWk~gKB<7Hcσ;#Kko}Kcv^ؖ^͗.Lz!j a ZuTOPYRQl'cekEٝrT1q>:߬*o j``Ȕ Q`?@y N:p+֜uA9 #$)Už˜}&2]T/Wؔ*~wx|mDBDHQWԻ { [] bw@nq!p*'Hn $D(;%JdJ`%<1X۲.O8sG`.(z}hN1C>`T01ātyN{`yH0j(L6 TFV)Y]~c4f\~ڣ retrʵaJrW"L2 jiZgQҾ5l|綸_BV۵aȠl|XY褀2PL*Ԗ[T8_ %$ĵ~|8:WO>9 vy9GJ0O[lZmFHX9=]5Th:%2/`"U6Z?g:>*rEOi@vJ_\x hQ "Cw:T=·-ӷOޞmp>8 ? 12ƾkKdNTcMQREIC*3vFTrǚB*uݹ<~yE]8?Wj.tYYU[1(早 k!'CJ}\"v[|EFGH[Ln]pȄə&ZnKNژM97YUے\nV?}C{psw#y[[ OLq .k}U9\vٵJ0u,N7KЭco{j wˢ,ip%pq6̛§U;{.mADFo"Q|st 3k!}\]y 20S9Ṳ&7Vhϭ"i͚m's[?\W_(qt;U9![S>s7!i(NQR]ݯ@(q~H1[s[w>R1(DЂe8@.{xɁzk=Qmņ\ ^-^Lh&+]$sTFsU0NdDi;[^v$HOl ;[a4v9&U(YuȥY2٨)`7+V=*3"V iQp?5r󝛥!9, ^ֿy1O,HC`¹gDUL[H9UɆ1aERq^Ci>XDw>%l:޸w+fwrD_ΥR=JCp ]/m`GL=gseVFCP+ef(.gL&bG$tfm R>g ؁BY?#lnSYAoҜ/yQ#=?[Ɖ!F"5.. X%n ϼ* :{eD{þ|jUϟAEPވ‡.`UOӅCÏǽs l\(!|lVnpڂbesxHlxW+ji)eE+ ʔL=2CHD+ԑD0f KPlebGs+*P~?pv`bt>y:$8$tiW4?KlE=lM=N($eշ4ս K2al D/ϝ>,tS^~|uٳ)8=;ĖR382'F:|aPSwGD3XSٗnRh>$ m/p_|SCZ.|` ^cz?]x@X/2&qQUSp-QYquNqv9f|FkӄbaHi&)tA< J|`+vTGnF\  dj0`l^',AȠu8\#7kfa;bB&oV n`oNH(9[+"҂š-12@J뜶H LH[5LF٢i9?ǩbA{0o*lw<3F.04k O϶!MģNg BoՕ Q\s^3S_ EqM ^#xD6y΁ߊ y O~I[*\ɫԸ5pc>*o ࿹M<&c^1o+ U*խLwS1Uq嗕d,7lvypC/'(qqP0{V&Ln8cןKdM%/¾`'4, Qn^bϪdTi S2/="hRyzatbb-Q kq曺 5X<|[%u}v.\sC6I#q|G5YpV0]BV -GM3DKՙ8FͰAqb Ǝ,˥\M_'2`@<]wYҡTcD'Gj> ʺ 4qD=hKr742?/ng{ZQ]/]pF $0sYB?Ӟ(~-^_Mw3gײª6]<+z!何mQA3!g8E;րdR+'4ߊZһ?rlӦsBqѦ*+" ]  g2[q?&][.lEjNYV:/u5 ^h܁ݩz7Ҿ;?y՘j? ٝCGt7fH%q 5XXF+2_;`,gZ:kA tc>fe0OvB> Uj@<hc"""•D)0UDpK˙XoXIO?j@ۜ*$NҚ?.$ls{P>h K˰M?QcWY4@RF3eOgF mu3?jAN }*4i VPدUL\3o>b|ʕÂғi$iPt:3Ħ+OZ:8)RSJ7tJ)c[,i,EH0-]3  0>)$0T0% 4&LooPާ)Womh5J*'&޴erEBW [dd߯ȼBoQ׫.YP'yk<:MuҡiHIqdFEKʀ s*%U]s>J J1"L8هv%Ml?m r̖ w # gTFE AXId\bf\iiN}9WZkƣMC櫃~Eh Nc#Ѧɴi*Df%Y?aAMP3w~L+ʟ{-sioroE\,CwwZPK7'd[عA ׸y{>DJlk8WsM6'KH#wyRgּؑH2ڟ>*0alMXf{{ga3qL