gtkwave-gtk3-3.3.125/0000775000175000017500000000000015047725113013516 5ustar bybellbybellgtkwave-gtk3-3.3.125/distro_from_svn.sh0000775000175000017500000000063515047725112017275 0ustar bybellbybell#!/bin/sh echo "Cleaning out SVN directories..." find . | grep '\.svn' | tac | awk '{print "rm -rf "$0}' | sh echo "Making distribution tarball from SVN directory..." cd ../ cat ./gtkwave3-gtk3/configure.ac | grep AC_INIT | awk '{print $2}' | sed 's/,//' | \ awk '{print "mv gtkwave3-gtk3 gtkwave-gtk3-"$0" ; tar cvf gtkwave-gtk3-"$0".tar gtkwave-gtk3-"$0" ; gzip -9 gtkwave-gtk3-"$0".tar"}' | sh echo "Done!" gtkwave-gtk3-3.3.125/depcomp0000775000175000017500000005570315047725112015104 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-gtk3-3.3.125/src/0000775000175000017500000000000015047725113014305 5ustar bybellbybellgtkwave-gtk3-3.3.125/src/wavewindow.h0000664000175000017500000000234315047725112016651 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 MaxSignalLength_2(char dirty_kick); /* used to resize but not fully recalculate like MaxSignalLength() */ 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); void XXX_gdk_draw_line(cairo_t *cr, wave_rgb_t gc, gint _x1, gint _y1, gint _x2, gint _y2); void XXX_gdk_draw_rectangle(cairo_t *cr, wave_rgb_t gc, gboolean filled, gint _x1, gint _y1, gint _w, gint _h); #ifdef WAVE_GTK3_SIZE_ALLOCATE_WORKAROUND_WAVE_VSLIDER void service_vslider(GtkWidget *text, gpointer data); #endif #endif gtkwave-gtk3-3.3.125/src/getopt.c0000664000175000017500000010346615047725112015764 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-gtk3-3.3.125/src/savefile.h0000664000175000017500000000324715047725112016261 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-gtk3-3.3.125/src/twinwave.c0000664000175000017500000002613615047725112016324 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2006-2018. * * 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 #else #if GTK_CHECK_VERSION(3,0,0) #include #endif #if GTK_CHECK_VERSION(3,22,26) #if !defined(MAC_INTEGRATION) && defined(GDK_WINDOWING_WAYLAND) #include #endif #endif #endif #include "wave_locale.h" #include #include #include #include "debug.h" static int use_embedded = 1; static int twinwayland = 0; #define XXX_GTK_OBJECT(x) x 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"); exit(0); } return(FALSE); /* TRUE would keep xsocket open */ } int quit_callback (GtkWidget *widget, gpointer data) { (void)widget; fprintf(stderr,"%s\n", (char *)data); 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 *mainwindow; int i; int split_point = -1; #ifdef __MINGW32__ char mapName[65]; HANDLE hMapFile; #endif #ifndef __MINGW32__ GtkWidget *xsocket[2] = { NULL, NULL }; GtkWidget *main_vbox, *vpan; #endif 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) { #if defined(__GTK_SOCKET_H__) && defined(GDK_WINDOWING_X11) #ifdef MAC_INTEGRATION sprintf(buf2, "%x", gtk_socket_get_id (GTK_SOCKET(xsocket[0]))); #else sprintf(buf2, "%lx", (long)gtk_socket_get_id (GTK_SOCKET(xsocket[0]))); #endif #endif } else { sprintf(buf2, "%x", 0); } arglist[0] = "gtkwave"; arglist[1] = "-D"; arglist[2] = buf; arglist[3] = "-X"; arglist[4] = buf2; for(i=1;i "" Open File Opens file for a given RPC ID. Example: gsettings set com.geda.gtkwave open 0,/pub/systema_packed.fst "" Quit Quits viewer for a given RPC ID and return code. Example: gsettings set com.geda.gtkwave quit 0,255 "" Write Save File Writes save file. Example: gsettings set com.geda.gtkwave writesave 0,/tmp/this.gtkw gsettings set com.geda.gtkwave writesave 0,+ "" Reloads Reloads file for a given RPC ID. Example: gsettings set com.geda.gtkwave reload 0 "" Zoom Full Zoom Full for a given RPC ID. Example: gsettings set com.geda.gtkwave zoom-full 0 "" Move To Time Moves to a given time for a given RPC ID. Example: gsettings set com.geda.gtkwave move-to-time 0,123ns gsettings set com.geda.gtkwave move-to-time 0,A "" Zoom Size Sets zoom size for a given RPC ID. Example: gsettings set com.geda.gtkwave zoom-size 0,-4.6 "" Dumpfile name Indicates current dumpfile name. "" Savefile name Indicates current savefile name. "" rcfile name Indicates current rcfile name. "" pwd Indicates pwd. "0" Optimized VCD usage. Value indicates VCD file is optimized. "" Image grab Indicates image grab filename. gtkwave-gtk3-3.3.125/src/tcl_np.c0000664000175000017500000005021515047725112015732 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 + 128]; 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; #if TCL_MAJOR_VERSION < 9 static void (* tcl_findExecutable)(const char *) = NULL; #else static const char * (* tcl_findExecutable)(const char *) = NULL; #endif /* * 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); #if TCL_MAJOR_VERSION < 9 DLSYM(tclHandle, "Tcl_FindExecutable", void (*)(const char *), tcl_findExecutable); #else DLSYM(tclHandle, "Tcl_FindExecutable", const char * (*)(const char *), tcl_findExecutable); #endif } 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-gtk3-3.3.125/src/timeentry.c0000664000175000017500000001272415047725112016476 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2016 * * 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 "gtk23compat.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(); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); g_signal_emit_by_name (XXX_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) || (!strlen(entry_text))) /* null string makes 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]; label=gtk_label_new("From:"); GLOBALS->from_entry=X_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); g_signal_connect (XXX_GTK_OBJECT (GLOBALS->from_entry), "activate",G_CALLBACK (from_entry_callback), GLOBALS->from_entry); box=XXX_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_size_request(GTK_WIDGET(GLOBALS->from_entry), 90, 22); gtk_tooltips_set_tip_2(GLOBALS->from_entry, "Scroll Lower Bound (use MX for named marker X)"); gtk_widget_show(GLOBALS->from_entry); label2=gtk_label_new("To:"); GLOBALS->to_entry=X_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); g_signal_connect (XXX_GTK_OBJECT (GLOBALS->to_entry), "activate",G_CALLBACK (to_entry_callback), GLOBALS->to_entry); box2=XXX_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_size_request(GTK_WIDGET(GLOBALS->to_entry), 90, 22); gtk_tooltips_set_tip_2(GLOBALS->to_entry, "Scroll Upper Bound (use MX for named marker X)"); gtk_widget_show(GLOBALS->to_entry); if(!GLOBALS->use_toolbutton_interface) { mainbox=XXX_gtk_vbox_new(FALSE, 0); } else { mainbox=XXX_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-gtk3-3.3.125/src/tree_component.c0000664000175000017500000000553015047725112017474 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-gtk3-3.3.125/src/wavealloca.h0000664000175000017500000000262715047725112016602 0ustar bybellbybell/* * Copyright (c) 1999 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. * * SPDX-License-Identifier: MIT */ #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 #endif #define wave_alloca alloca #endif gtkwave-gtk3-3.3.125/src/vzt.c0000664000175000017500000005606015047725112015302 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" #include #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(f->flags&(VZT_RD_SYM_F_DOUBLE|VZT_RD_SYM_F_STRING)) { htemp->v.h_vector = strdup_2((f->flags&VZT_RD_SYM_F_DOUBLE) ? "NaN" : "UNDEF"); htemp->flags = HIST_REAL; if(f->flags&VZT_RD_SYM_F_STRING) htemp->flags |= HIST_STRING; } else { 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(f->flags&(VZT_RD_SYM_F_DOUBLE|VZT_RD_SYM_F_STRING)) { htemp->v.h_vector = strdup_2((f->flags&VZT_RD_SYM_F_DOUBLE) ? "NaN" : "UNDEF"); htemp->flags = HIST_REAL; if(f->flags&VZT_RD_SYM_F_STRING) htemp->flags |= HIST_STRING; } else { 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; np->head.v.h_vector = strdup_2((f->flags&VZT_RD_SYM_F_DOUBLE) ? "NaN" : "UNDEF"); } { struct HistEnt *htemp2 = histent_calloc(); htemp2->time = -1; if(f->flags&(VZT_RD_SYM_F_DOUBLE|VZT_RD_SYM_F_STRING)) { htemp2->v.h_vector = strdup_2((f->flags&VZT_RD_SYM_F_DOUBLE) ? "NaN" : "UNDEF"); htemp2->flags = HIST_REAL; if(f->flags&VZT_RD_SYM_F_STRING) htemp2->flags |= HIST_STRING; } else { 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-gtk3-3.3.125/src/status.c0000664000175000017500000001031315047725112015771 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) { gtk_text_buffer_insert (gtk_text_view_get_buffer(GTK_TEXT_VIEW (GLOBALS->text_status_c_2)), &GLOBALS->iter_status_c_3, str, -1); GtkTextMark *mark = gtk_text_buffer_get_mark (gtk_text_view_get_buffer(GTK_TEXT_VIEW (GLOBALS->text_status_c_2)), "end"); gtk_text_view_scroll_mark_onscreen (GTK_TEXT_VIEW (GLOBALS->text_status_c_2), GTK_TEXT_MARK(mark)); } 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 *sw; GtkTextIter iter; /* Create a table to hold the text widget and scrollbars */ sw = gtk_scrolled_window_new (NULL, NULL); /* Put a text widget in the upper left hand corner. Note the use of * GTK_SHRINK in the y direction */ 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_get_buffer(GTK_TEXT_VIEW (GLOBALS->text_status_c_2)), "bold", "weight", PANGO_WEIGHT_BOLD, NULL); gtk_text_buffer_get_end_iter (gtk_text_view_get_buffer(GTK_TEXT_VIEW (GLOBALS->text_status_c_2)), &iter); gtk_text_buffer_create_mark (gtk_text_view_get_buffer(GTK_TEXT_VIEW (GLOBALS->text_status_c_2)), "end", &iter, FALSE); gtk_container_add (GTK_CONTAINER (sw), GLOBALS->text_status_c_2); gtk_widget_set_size_request(GTK_WIDGET(GLOBALS->text_status_c_2), 100, 50); gtk_widget_show (GLOBALS->text_status_c_2); /* Add a handler to put a message in the text widget when it is realized */ g_signal_connect (XXX_GTK_OBJECT (GLOBALS->text_status_c_2), "realize", G_CALLBACK (realize_text), NULL); gtk_tooltips_set_tip_2(GLOBALS->text_status_c_2, "Status Window"); return(sw); } gtkwave-gtk3-3.3.125/src/globals.c0000664000175000017500000027576415047725112016120 0ustar bybellbybell/* * Copyright (c) Kermin Elliott Fleming 2007-2017. * * 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 "analyzer.h" #include "bsearch.h" #include "busy.h" #include "clipping.h" #include "color.h" #include "currenttime.h" #include "debug.h" #include "fgetdynamic.h" #include "ghw.h" #include "globals.h" #include "gnu-getopt.h" #include "gnu_regex.h" #include "gtk23compat.h" #include "lx2.h" #include "lxt.h" #include "main.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 "strace.h" #include "symbol.h" #include "translate.h" #include "tree.h" #include "vcd.h" #include "vcd_saver.h" #include "vlist.h" #include "vzt.h" #include "wavealloca.h" #include "lxt2_read.h" #include "vzt_read.h" #include "fst.h" #include "hierpack.h" #include "fsdb_wrapper_api.h" #ifdef __MINGW32__ #define sleep(x) Sleep(x * 1000) #endif #if !defined __MINGW32__ #include #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, /* default_fpshift */ {0, 0, 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 */ 0, /* hier_ignore_escapes */ /* * 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 */ -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 */ -1, /* color_highfill */ -1, /* color_1fill */ /* * 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 */ 0, /* fullscreen */ 1, /* show_toolbar */ NULL, /* time_mainbox */ 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 */ NULL, /* entrybox_text 82 */ /* * extload.c */ 0, /* extload_ffr_import_count */ NULL, /* extload_ffr_ctx */ NULL, /* extload */ NULL, /* extload_idcodes */ NULL, /* extload_inv_idcodes */ #if !defined __MINGW32__ 0, /* extload_lastmod */ 0, /* extload_already_errored */ #endif NULL, /* extload_namecache */ NULL, /* extload_namecache_max */ NULL, /* extload_namecache_lens */ NULL, /* extload_namecache_patched */ NULL, /* extload_sym_block */ NULL, /* extload_node_block */ NULL, /* extload_xc */ NULL, /* extload_prevsymroot */ NULL, /* extload_prevsym */ NULL, /* extload_npar */ 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 */ 0, /* extload_max_tree */ 0, /* extload_curr_tree */ /* * fetchbuttons.c */ 100, /* fetchwindow 84 */ /* * fgetdynamic.c */ 0, /* fgetmalloc_len 85 */ /* * file.c */ NULL, /* pFileChoose */ NULL, /* pFileChooseFilterName */ NULL, /* pPatternSpec */ 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 */ NULL, /* fonts_screen */ NULL, /* fonts_context */ NULL, /* fonts_layout */ 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 */ NULL, /* xl_enum_filter */ 0, /* num_xl_enum_filter */ 0, /* queued_xl_enum_filter */ NULL, /* enum_nptrs_jrb */ /* * ghw.c */ 0, /* nxp_ghw_c_1 93 */ 0, /* nbr_sigs_ghw_c_1 */ 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 */ {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 */ 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 */ 0, /* disable_auto_comphier */ /* * hiersearch.c */ 1, /* hier_grouping 116 */ 0, /* window_hiersearch_c_3 117 */ 0, /* entry_main_hiersearch_c_1 118 */ 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 */ NULL, /*sig_store_hiersearch */ NULL, /*sig_selection_hiersearch */ #ifdef WAVE_GTK3_HIERSEARCH_DEBOUNCE 0, /* h_debounce */ #endif /* * logfile.c */ NULL, /* logfiles */ NULL, /* fontname_logfile 133 */ {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 */ /* * 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__ 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 */ 0, /* socket_xid 224 */ 0, /* disable_menus 225 */ NULL, /* ftext_main_main_c_1 226 */ 1, /* use_toolbutton_interface */ /* * 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 */ 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 */ #ifdef WAVE_ALLOW_GTK3_HEADER_BAR NULL, /* header_bar */ NULL, /* main_popup_menu */ NULL, /* main_popup_menu_button */ NULL, /* top_table */ #endif NULL, /* sst_signal_popup_menu */ /* * mouseover.c */ 1, /* disable_mouseover 254 */ 0, /* clipboard_mouseover */ NULL, /* mouseover_mouseover_c_1 255 */ NULL, /* mo_area_mouseover_c_1 256 */ 0, /* mo_width_mouseover_c_1 260 */ 0, /* mo_height_mouseover_c_1 260 */ NULL, /* surface_mo_pixmap_mouseover_c_1 */ NULL, /* cr_mo_pixmap_mouseover_c_1 */ {0.0,0.0,0.0,0.0}, /* rgb_mo_dk_gray_mouseover_c_1 */ {0.0,0.0,0.0,0.0}, /* mo_black_mouseover_c_1 */ /* * pagebuttons.c */ 1.0, /* page_divisor 261 */ /* * pixmaps.c */ NULL, /* redo_pixbuf */ NULL, /* larrow_pixbuf */ NULL, /* rarrow_pixbuf */ NULL, /* zoomin_pixbuf */ NULL, /* zoomout_pixbuf */ NULL, /* zoomfit_pixbuf */ NULL, /* zoomundo_pixbuf */ NULL, /* zoom_larrow_pixbuf */ NULL, /* zoom_rarrow_pixbuf */ NULL, /* prev_page_pixbuf */ NULL, /* next_page_pixbuf */ NULL, /* wave_info_pixbuf */ NULL, /* wave_alert_pixbuf */ NULL, /* hiericon_module_pixbuf */ NULL, /* hiericon_task_pixbuf */ NULL, /* hiericon_function_pixbuf */ NULL, /* hiericon_begin_pixbuf */ NULL, /* hiericon_fork_pixbuf */ NULL, /* hiericon_interface_pixbuf */ NULL, /* hiericon_svpackage_pixbuf */ NULL, /* hiericon_program_pixbuf */ NULL, /* hiericon_class_pixbuf */ NULL, /* hiericon_record_pixbuf */ NULL, /* hiericon_generate_pixbuf */ NULL, /* hiericon_design_pixbuf */ NULL, /* hiericon_block_pixbuf */ NULL, /* hiericon_generateif_pixbuf */ NULL, /* hiericon_generatefor_pixbuf */ NULL, /* hiericon_instance_pixbuf */ NULL, /* hiericon_package_pixbuf */ NULL, /* hiericon_signal_pixbuf */ NULL, /* hiericon_portin_pixbuf */ NULL, /* hiericon_portout_pixbuf */ NULL, /* hiericon_portinout_pixbuf */ NULL, /* hiericon_buffer_pixbuf */ NULL, /* hiericon_linkage_pixbuf */ /* * 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, /* sig_store_ptranslate; */ NULL, /* sig_selection_ptranslate */ /* * 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, /* 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 */ NULL, /* sig_store_search */ NULL, /* sig_selection_search */ NULL, /* sig_view_search */ /* * signalwindow.c */ NULL, /* signalarea 369 */ NULL, /* signalfont 370 */ NULL, /* surface_signalpixmap */ NULL, /* cr_signalpixmap */ #if defined(WAVE_ALLOW_QUARTZ_FLUSH_WORKAROUND) || defined(WAVE_ALLOW_GTK3_VSLIDER_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 */ 0, /* dragzoom_threshold */ #ifdef WAVE_GTK3_SIZE_ALLOCATE_WORKAROUND_WAVE_VSLIDER 0.0, /* wave_vslider_page_size */ 0.0, /* wave_vslider_page_increment */ 0.0, /* wave_vslider_step_increment */ 0.0, /* wave_vslider_lower */ 0.0, /* wave_vslider_upper */ 0.0, /* wave_vslider_value */ 0, /* wave_vslider_valid */ #endif /* * 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, /* 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 */ NULL, /* wave_splash_pixbuf */ /* * status.c */ NULL, /* text_status_c_2 398 */ {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 */ /* * 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] */ {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[1] */ #if WAVE_NUM_STRACE_WINDOWS != 2 #error the number of strace windows as defined in strace.h does not match globals.c! #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, /* sig_store_translate; */ NULL, /* sig_selection_translate */ /* * 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 */ NULL, /* sst_exclude_filename */ 0, /* exclhiermask */ NULL, /* exclcompname */ NULL, /* exclinstname */ /* * 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, /* 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 */ NULL, /* sig_store_treesearch_gtk2_c_1 460 */ NULL, /* sig_selection_treesearch_gtk2_c_1 461 */ 0, /* is_active_treesearch_gtk2_c_6 462 */ NULL, /* afl_treesearch_gtk2_c_1 464 */ NULL, /* window_treesearch_gtk2_c_12 465 */ 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 */ 0, /* fetchlow */ 0, /* fetchhigh */ NULL, /* treestore_main */ NULL, /* treeview_main */ SST_ACTION_INSERT, /* sst_dbl_action_type */ /* * 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, /* ttranslate_args */ NULL, /* sig_store_ttranslate; */ NULL, /* sig_selection_ttranslate */ /* * 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 */ 0, /* mti_realparam_fix */ -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 */ 0, /* vcd_already_backtracked */ /* * 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 */ #ifdef WAVE_ALLOW_SLIDER_ZOOM 0, /* enable_slider_zoom */ #endif 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, /* wave_vslider2 622 */ 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 */ 0, /* made_sgc_contexts_wavewindow_c_1 649 */ 0, /* fill_in_smaller_rgb_areas_wavewindow_c_1 659 */ -1, /* prev_markertime */ 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 */ 0, /* fill_waveform */ 0, /* lz_removal */ NULL, /* surface_wavepixmap_wavewindow_c_1 */ NULL, /* cr_wavepixmap_wavewindow_c_1 */ {0.0,0.0,0.0,0.0}, /* rgb_gc_white */ {0.0,0.0,0.0,0.0}, /* rgb_gc_black */ RGB_WAVE_RAINBOW_INITIALIZER, /* rgb_gc_rainbow */ {{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0}}, /* rgb_gc */ {{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0}}, /* rgb_gccache */ 1.0, /* cr_line_width */ 0.5, /* cairo_050_offset */ #ifdef WAVE_ALLOW_GTK3_GESTURE_EVENT 0.0, /* wavearea_gesture_initial_zoom */ #ifdef WAVE_GTK3_GESTURE_ZOOM_IS_1D 1.0, /* wavearea_gesture_initial_zoom_x_distance */ 0, /* wavearea_gesture_initial_x1tim */ #endif NULL, /* wavearea_gesture_swipe */ NULL, /* swipe_init_time */ 0, /* swipe_init_start */ 0.0, /* wavearea_gesture_swipe_velocity_x */ 0, /* wavearea_drag_start_x */ 0, /* wavearea_drag_start_y */ 0, /* wavearea_drag_active */ #endif -1, /* use_gestures */ FALSE, /*use_dark */ FALSE, /*save_on_exit */ #ifdef GDK_WINDOWING_WAYLAND 0, /* wayland_marker_timer_hack */ #endif /* * 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 */ 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; 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) { XXX_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(GLOBALS->gtk2_tree_frame) { /* upper tree */ GtkAdjustment *vadj = XXX_gtk_tree_view_get_vadjustment(XXX_GTK_TREE_VIEW(GLOBALS->treeview_main)); GtkAdjustment *hadj = XXX_gtk_tree_view_get_hadjustment(XXX_GTK_TREE_VIEW(GLOBALS->treeview_main)); if(vadj) tree_vadj_value = gtk_adjustment_get_value(vadj); if(hadj) tree_hadj_value = gtk_adjustment_get_value(hadj); GtkAllocation allocation; gtk_widget_get_allocation(GLOBALS->gtk2_tree_frame, &allocation); /* tree_frame_x = allocation.width; */ /* scan-build */ tree_frame_y = allocation.height; /* lower signal set */ vadj = XXX_gtk_tree_view_get_vadjustment(XXX_GTK_TREE_VIEW(GLOBALS->dnd_sigview)); hadj = XXX_gtk_tree_view_get_hadjustment(XXX_GTK_TREE_VIEW(GLOBALS->dnd_sigview)); if(vadj) treeview_vadj_value = gtk_adjustment_get_value(vadj); if(hadj) treeview_hadj_value = gtk_adjustment_get_value(hadj); } /* 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; #ifdef WAVE_ALLOW_GTK3_GESTURE_EVENT new_globals->wavearea_gesture_swipe = GLOBALS->wavearea_gesture_swipe; #endif new_globals->surface_signalpixmap = GLOBALS->surface_signalpixmap; new_globals->cr_signalpixmap = GLOBALS->cr_signalpixmap; new_globals->wave_splash_pixbuf = GLOBALS->wave_splash_pixbuf; new_globals->hscroll_signalwindow_c_1 = GLOBALS->hscroll_signalwindow_c_1; /* only was used for obsolete XXX_resize_sstpane_y_hack_for_gtk3() */ new_globals->black_and_white = GLOBALS->black_and_white; 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; new_globals->surface_wavepixmap_wavewindow_c_1 = GLOBALS->surface_wavepixmap_wavewindow_c_1; new_globals->cr_wavepixmap_wavewindow_c_1 = GLOBALS->cr_wavepixmap_wavewindow_c_1; new_globals->rgb_gc_white = GLOBALS->rgb_gc_white; new_globals->rgb_gc_black = GLOBALS->rgb_gc_black; memcpy(&new_globals->rgb_gc, &GLOBALS->rgb_gc, sizeof(struct wave_rgbmaster_t)); memcpy(&new_globals->rgb_gccache, &GLOBALS->rgb_gccache, sizeof(struct wave_rgbmaster_t)); memcpy(&new_globals->rgb_gc_rainbow, &GLOBALS->rgb_gc_rainbow, 2 * WAVE_NUM_RAINBOW * sizeof(wave_rgb_t)); 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)); new_globals->fonts_screen = GLOBALS->fonts_screen; new_globals->fonts_context = GLOBALS->fonts_context; new_globals->fonts_layout = GLOBALS->fonts_layout; 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_pixbuf = GLOBALS->redo_pixbuf; new_globals->larrow_pixbuf = GLOBALS->larrow_pixbuf; new_globals->rarrow_pixbuf = GLOBALS->rarrow_pixbuf; new_globals->zoomin_pixbuf = GLOBALS->zoomin_pixbuf; new_globals->zoomout_pixbuf = GLOBALS->zoomout_pixbuf; new_globals->zoomfit_pixbuf = GLOBALS->zoomfit_pixbuf; new_globals->zoomundo_pixbuf = GLOBALS->zoomundo_pixbuf; new_globals->zoom_larrow_pixbuf = GLOBALS->zoom_larrow_pixbuf; new_globals->zoom_rarrow_pixbuf = GLOBALS->zoom_rarrow_pixbuf; new_globals->prev_page_pixbuf = GLOBALS->prev_page_pixbuf; new_globals->next_page_pixbuf = GLOBALS->next_page_pixbuf; new_globals->wave_info_pixbuf = GLOBALS->wave_info_pixbuf; new_globals->wave_alert_pixbuf = GLOBALS->wave_alert_pixbuf; 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; #ifdef WAVE_ALLOW_SLIDER_ZOOM new_globals->enable_slider_zoom = GLOBALS->enable_slider_zoom; #endif new_globals->context_tabposition = GLOBALS->context_tabposition; new_globals->use_standard_clicking = GLOBALS->use_standard_clicking; new_globals->dragzoom_threshold = GLOBALS->dragzoom_threshold; new_globals->cr_line_width = GLOBALS->cr_line_width; new_globals->cairo_050_offset = GLOBALS->cairo_050_offset; 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_highfill = GLOBALS->color_highfill; new_globals->color_low = GLOBALS->color_low; new_globals->color_1 = GLOBALS->color_1; new_globals->color_1fill = GLOBALS->color_1fill; 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->mti_realparam_fix = GLOBALS->mti_realparam_fix; 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->clipboard_mouseover = GLOBALS->clipboard_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->disable_auto_comphier = GLOBALS->disable_auto_comphier; 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->extload_max_tree = GLOBALS->extload_max_tree; new_globals->ps_maxveclen = GLOBALS->ps_maxveclen; new_globals->show_base = GLOBALS->show_base; new_globals->display_grid = GLOBALS->display_grid; new_globals->fullscreen = GLOBALS->fullscreen; new_globals->show_toolbar = GLOBALS->show_toolbar; new_globals->time_mainbox = GLOBALS->time_mainbox; new_globals->highlight_wavewindow = GLOBALS->highlight_wavewindow; new_globals->fill_waveform = GLOBALS->fill_waveform; new_globals->lz_removal = GLOBALS->lz_removal; 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->hier_ignore_escapes = GLOBALS->hier_ignore_escapes; 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! */ new_globals->sst_dbl_action_type = GLOBALS->sst_dbl_action_type; new_globals->use_gestures = GLOBALS->use_gestures; new_globals->use_dark = GLOBALS->use_dark; new_globals->save_on_exit = GLOBALS->save_on_exit; 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; strcpy2_into_new_context(new_globals, &new_globals->pFileChooseFilterName, &GLOBALS->pFileChooseFilterName); /* search.c */ new_globals->regex_which_search_c_1 = GLOBALS->regex_which_search_c_1; /* preserve search type */ /* 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; 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; #ifdef WAVE_ALLOW_GTK3_HEADER_BAR new_globals->main_popup_menu = GLOBALS->main_popup_menu; new_globals->main_popup_menu_button = GLOBALS->main_popup_menu_button; new_globals->header_bar = GLOBALS->header_bar; new_globals->top_table = GLOBALS->top_table; #endif 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; memcpy(&new_globals->iter_status_c_3, &GLOBALS->iter_status_c_3, sizeof(GtkTextIter)); /* 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; strcpy2_into_new_context(new_globals, &new_globals->sst_exclude_filename, &GLOBALS->sst_exclude_filename); if(GLOBALS->exclcompname) { jrb_free_tree(GLOBALS->exclcompname); /* strings get freed by automatic _2 mechanism */ GLOBALS->exclcompname = NULL; } if(GLOBALS->exclinstname) { jrb_free_tree(GLOBALS->exclinstname); /* strings get freed by automatic _2 mechanism */ GLOBALS->exclinstname = NULL; } /* 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; new_globals->socket_xid = GLOBALS->socket_xid; 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; } if(GLOBALS->enum_nptrs_jrb) { jrb_free_tree(GLOBALS->enum_nptrs_jrb); GLOBALS->enum_nptrs_jrb = NULL; } #ifdef _WAVE_HAVE_JUDY if(GLOBALS->num_xl_enum_filter) { int ie; for(ie=0;ienum_xl_enum_filter;ie++) { JudyHSFreeArray(&GLOBALS->xl_enum_filter[ie], NULL); } GLOBALS->num_xl_enum_filter = 0; } #endif /* 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) */ 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); /* 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->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_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->sig_store_hiersearch = GLOBALS->sig_store_hiersearch; new_globals->sig_selection_hiersearch = GLOBALS->sig_selection_hiersearch; 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; if(GLOBALS->cr_mo_pixmap_mouseover_c_1) { cairo_destroy(GLOBALS->cr_mo_pixmap_mouseover_c_1); GLOBALS->cr_mo_pixmap_mouseover_c_1 = NULL; } if(GLOBALS->surface_mo_pixmap_mouseover_c_1) { cairo_surface_destroy(GLOBALS->surface_mo_pixmap_mouseover_c_1); GLOBALS->surface_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->sig_store_search = GLOBALS->sig_store_search; new_globals->sig_selection_search = GLOBALS->sig_selection_search; new_globals->sig_view_search = GLOBALS->sig_view_search; 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]; } } #ifdef WAVE_ALLOW_GTK3_GESTURE_EVENT if(GLOBALS->swipe_init_time) { g_date_time_unref(GLOBALS->swipe_init_time); GLOBALS->swipe_init_time = NULL; } #endif /* 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(); */ sst_exclusion_loader(); /* 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 __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 */ #ifdef WAVE_ALLOW_GTK3_HEADER_BAR if(GLOBALS->header_bar) { char recbuf[128]; sprintf(recbuf, "Reload failure, reattempt in %d second%s...", reload_fail_delay, (reload_fail_delay==1) ? "" : "s"); gtk_header_bar_set_subtitle(GTK_HEADER_BAR(GLOBALS->header_bar), recbuf); g_usleep(30000); } #endif set_window_busy(NULL); #ifdef WAVE_ALLOW_GTK3_HEADER_BAR if(!GLOBALS->header_bar) #endif { 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 = 10; break; /* recycle back so message changes if header bar */ default: break; } set_window_idle(NULL); } } /* 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(!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", G_CALLBACK(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->sig_view_search) { dnd_setup(GLOBALS->sig_view_search, GLOBALS->signalarea, 0); } } 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, G_CALLBACK(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); } /* 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((!GLOBALS->hide_sst)||(GLOBALS->window_treesearch_gtk2_c_12)) { 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 = XXX_gtk_tree_view_get_vadjustment(XXX_GTK_TREE_VIEW(GLOBALS->treeview_main)); if((vadj) && (tree_vadj_value >= gtk_adjustment_get_value(vadj)) && (tree_vadj_value <= gtk_adjustment_get_upper(vadj))) { gtk_adjustment_set_value(vadj, tree_vadj_value); XXX_gtk_tree_view_set_vadjustment(XXX_GTK_TREE_VIEW(GLOBALS->treeview_main), vadj); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(vadj)), "changed"); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(vadj)), "value_changed"); } } if(tree_hadj_value != 0.0) { GtkAdjustment *hadj = XXX_gtk_tree_view_get_hadjustment(XXX_GTK_TREE_VIEW(GLOBALS->treeview_main)); if((hadj) && (tree_hadj_value >= gtk_adjustment_get_lower(hadj)) && (tree_hadj_value <= gtk_adjustment_get_upper(hadj))) { gtk_adjustment_set_value(hadj, tree_hadj_value); XXX_gtk_tree_view_set_hadjustment(XXX_GTK_TREE_VIEW(GLOBALS->treeview_main), hadj); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(hadj)), "changed"); g_signal_emit_by_name (XXX_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) { g_signal_emit_by_name (XXX_GTK_OBJECT (GLOBALS->filter_entry), "activate"); } } /* 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((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 = XXX_gtk_tree_view_get_vadjustment(XXX_GTK_TREE_VIEW(GLOBALS->dnd_sigview)); if((vadj) && (treeview_vadj_value >= gtk_adjustment_get_lower(vadj)) && (treeview_vadj_value <= gtk_adjustment_get_upper(vadj))) { gtk_adjustment_set_value(vadj, treeview_vadj_value); XXX_gtk_tree_view_set_vadjustment(XXX_GTK_TREE_VIEW(GLOBALS->dnd_sigview), vadj); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(vadj)), "changed"); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(vadj)), "value_changed"); } } if(treeview_hadj_value != 0.0) { GtkAdjustment *hadj = XXX_gtk_tree_view_get_hadjustment(XXX_GTK_TREE_VIEW(GLOBALS->dnd_sigview)); if((hadj) && (treeview_hadj_value >= gtk_adjustment_get_lower(hadj)) && (treeview_hadj_value <= gtk_adjustment_get_upper(hadj))) { gtk_adjustment_set_value(hadj, treeview_hadj_value); XXX_gtk_tree_view_set_hadjustment(XXX_GTK_TREE_VIEW(GLOBALS->dnd_sigview), hadj); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(hadj)), "changed"); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(hadj)), "value_changed"); } } } } } 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->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_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; if(GLOBALS->cr_mo_pixmap_mouseover_c_1) { cairo_destroy(GLOBALS->cr_mo_pixmap_mouseover_c_1); GLOBALS->cr_mo_pixmap_mouseover_c_1 = NULL; } if(GLOBALS->surface_mo_pixmap_mouseover_c_1) { cairo_surface_destroy(GLOBALS->surface_mo_pixmap_mouseover_c_1); GLOBALS->surface_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) + (intptr_t)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->mti_realparam_fix = g_old->mti_realparam_fix; 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->fullscreen = g_old->fullscreen; GLOBALS->show_toolbar = g_old->show_toolbar; GLOBALS->time_mainbox = g_old->time_mainbox; GLOBALS->highlight_wavewindow = g_old->highlight_wavewindow; GLOBALS->fill_waveform = g_old->fill_waveform; GLOBALS->lz_removal = g_old->lz_removal; GLOBALS->use_standard_trace_select = g_old->use_standard_trace_select; GLOBALS->disable_mouseover = g_old->disable_mouseover; GLOBALS->clipboard_mouseover = g_old->clipboard_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; GLOBALS->hier_ignore_escapes = g_old->hier_ignore_escapes; GLOBALS->sst_dbl_action_type = g_old->sst_dbl_action_type; GLOBALS->use_gestures = g_old->use_gestures; GLOBALS->use_dark = g_old->use_dark; GLOBALS->save_on_exit = g_old->save_on_exit; 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, intptr_t ptr_offset) { g_signal_connect (w, "enter_notify_event", G_CALLBACK(context_swapper), (void *)ptr_offset); g_signal_connect (w, "focus_in_event", G_CALLBACK(context_swapper), (void *)ptr_offset); } /* * wrapped g_signal_connect/g_signal_connect_swapped 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(gpointer object, const gchar *name, GCallback func, gpointer data, char *f, intptr_t line) { gulong rc; if(f) { g_signal_connect_swapped(object, name, (GCallback)ctx_prints, (gpointer)f); g_signal_connect_swapped(object, name, (GCallback)ctx_printd, (gpointer)line); } g_signal_connect_swapped(object, name, (GCallback)ctx_swap_watchdog, (gpointer)GLOBALS->gtk_context_bridge_ptr); rc = g_signal_connect(object, name, func, data); return(rc); } gulong gtkwave_signal_connect_object_x(gpointer object, const gchar *name, GCallback func, gpointer data, char *f, intptr_t line) { gulong rc; if(f) { g_signal_connect_swapped(object, name, (GCallback)ctx_prints, (gpointer)f); g_signal_connect_swapped(object, name, (GCallback)ctx_printd, (gpointer)line); } g_signal_connect_swapped(object, name, (GCallback)ctx_swap_watchdog, (gpointer)GLOBALS->gtk_context_bridge_ptr); rc = g_signal_connect_swapped(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) { XXX_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_pixbuf = b->hiericon_module_pixbuf; a->hiericon_task_pixbuf = b->hiericon_task_pixbuf; a->hiericon_function_pixbuf = b->hiericon_function_pixbuf; a->hiericon_begin_pixbuf = b->hiericon_begin_pixbuf; a->hiericon_fork_pixbuf = b->hiericon_fork_pixbuf; a->hiericon_interface_pixbuf = b->hiericon_interface_pixbuf; a->hiericon_svpackage_pixbuf = b->hiericon_svpackage_pixbuf; a->hiericon_program_pixbuf = b->hiericon_program_pixbuf; a->hiericon_class_pixbuf = b->hiericon_class_pixbuf; a->hiericon_record_pixbuf = b->hiericon_record_pixbuf; a->hiericon_generate_pixbuf = b->hiericon_generate_pixbuf; a->hiericon_design_pixbuf = b->hiericon_design_pixbuf; a->hiericon_block_pixbuf = b->hiericon_block_pixbuf; a->hiericon_generateif_pixbuf = b->hiericon_generateif_pixbuf; a->hiericon_generatefor_pixbuf = b->hiericon_generatefor_pixbuf; a->hiericon_instance_pixbuf = b->hiericon_instance_pixbuf; a->hiericon_package_pixbuf = b->hiericon_package_pixbuf; a->hiericon_signal_pixbuf = b->hiericon_signal_pixbuf; a->hiericon_portin_pixbuf = b->hiericon_portin_pixbuf; a->hiericon_portout_pixbuf = b->hiericon_portout_pixbuf; a->hiericon_portinout_pixbuf = b->hiericon_portinout_pixbuf; a->hiericon_buffer_pixbuf = b->hiericon_buffer_pixbuf; a->hiericon_linkage_pixbuf = b->hiericon_linkage_pixbuf; } gtkwave-gtk3-3.3.125/src/tcl_np.h0000664000175000017500000001046715047725112015744 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-gtk3-3.3.125/src/timeentry.h0000664000175000017500000000077115047725112016502 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-gtk3-3.3.125/src/tree_component.h0000664000175000017500000000104015047725112017471 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-gtk3-3.3.125/src/vzt.h0000664000175000017500000000116215047725112015300 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-gtk3-3.3.125/src/status.h0000664000175000017500000000057415047725112016006 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-gtk3-3.3.125/src/globals.h0000664000175000017500000013622315047725112016107 0ustar bybellbybell/* * Copyright (c) Kermin Elliott Fleming 2007-2017. * * 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__ #include #include #endif #define XXX_GTK_OBJECT(x) x #define XXX_GTK_OBJECT_GET_CLASS GTK_OBJECT_GET_CLASS #define XXX_GDK_DRAWABLE(x) x #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 "gtk23compat.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 #if GTK_CHECK_VERSION(3,0,0) #ifdef GDK_WINDOWING_X11 #ifndef X_H #include #endif #endif #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 */ TraceFlagsType default_flags; /* from analyzer.c 5 */ unsigned int default_fpshift; 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; char hier_ignore_escapes; /* * 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; 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; int color_highfill; int color_1fill; /* * 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 */ char fullscreen; char show_toolbar; GtkWidget *time_mainbox; 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 */ char *entrybox_text; /* from entry.c 83 */ /* 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__ 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; int *extload_namecache_patched; struct symbol *extload_sym_block; struct Node *extload_node_block; void *extload_xc; struct symbol *extload_prevsymroot; struct symbol *extload_prevsym; struct tree **extload_npar; 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; unsigned int extload_max_tree; unsigned int extload_curr_tree; /* * fetchbuttons.c */ TimeType fetchwindow; /* from fetchbuttons.c 85 */ /* * fgetdynamic.c */ int fgetmalloc_len; /* from fgetdynamic.c 86 */ /* * file.c */ GtkWidget *pFileChoose; char *pFileChooseFilterName; GPatternSpec *pPatternSpec; 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 */ GdkScreen *fonts_screen; PangoContext *fonts_context; PangoLayout *fonts_layout; 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; #ifdef _WAVE_HAVE_JUDY Pvoid_t *xl_enum_filter; #else struct xl_tree_node **xl_enum_filter; #endif int num_xl_enum_filter; fstEnumHandle queued_xl_enum_filter; JRB enum_nptrs_jrb; /* * ghw.c */ struct Node **nxp_ghw_c_1; /* from ghw.c 95 */ uint32_t nbr_sigs_ghw_c_1; 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 */ GtkTextIter iter_help_c_1; /* from help.c 117 */ GtkTextTag *bold_tag_help_c_1; /* from help.c 118 */ 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; char disable_auto_comphier; /* * 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 */ 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 */ GtkListStore *sig_store_hiersearch; GtkTreeSelection *sig_selection_hiersearch; #ifdef WAVE_GTK3_HIERSEARCH_DEBOUNCE int h_debounce; #endif /* * logfile.c */ void **logfiles; char *fontname_logfile; /* from logfile.c 137 */ 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 */ /* * 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__ 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 */ #if GTK_CHECK_VERSION(3,0,0) #ifdef GDK_WINDOWING_X11 Window socket_xid; /* from main.c 241 */ #else unsigned long socket_xid; /* for windows compiles */ #endif #else 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 */ 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 */ #ifdef WAVE_ALLOW_GTK3_HEADER_BAR GtkWidget *header_bar; GtkWidget *main_popup_menu; /* from menu.c */ GtkWidget *main_popup_menu_button; /* from menu.c */ GtkWidget *top_table; #endif GtkWidget *sst_signal_popup_menu; /* from menu.c */ /* * mouseover.c */ char disable_mouseover; /* from mouseover.c 271 */ char clipboard_mouseover; /* from mouseover.c */ GtkWidget *mouseover_mouseover_c_1; /* from mouseover.c 272 */ GtkWidget *mo_area_mouseover_c_1; /* from mouseover.c 273 */ int mo_width_mouseover_c_1; /* from mouseover.c 277 */ int mo_height_mouseover_c_1; /* from mouseover.c 278 */ cairo_surface_t *surface_mo_pixmap_mouseover_c_1; cairo_t *cr_mo_pixmap_mouseover_c_1; wave_rgb_t rgb_mo_dk_gray_mouseover_c_1; wave_rgb_t rgb_mo_black_mouseover_c_1; /* * pagebuttons.c */ double page_divisor; /* from pagebuttons.c 279 */ /* * pixmaps.c */ GdkPixbuf *redo_pixbuf; GdkPixbuf *larrow_pixbuf; GdkPixbuf *rarrow_pixbuf; GdkPixbuf *zoomin_pixbuf; GdkPixbuf *zoomout_pixbuf; GdkPixbuf *zoomfit_pixbuf; GdkPixbuf *zoomundo_pixbuf; GdkPixbuf *zoom_larrow_pixbuf; GdkPixbuf *zoom_rarrow_pixbuf; GdkPixbuf *prev_page_pixbuf; GdkPixbuf *next_page_pixbuf; GdkPixbuf *wave_info_pixbuf; GdkPixbuf *wave_alert_pixbuf; GdkPixbuf *hiericon_module_pixbuf; /* from pixmaps.c */ GdkPixbuf *hiericon_task_pixbuf; /* from pixmaps.c */ GdkPixbuf *hiericon_function_pixbuf; /* from pixmaps.c */ GdkPixbuf *hiericon_begin_pixbuf; /* from pixmaps.c */ GdkPixbuf *hiericon_fork_pixbuf; /* from pixmaps.c */ GdkPixbuf *hiericon_interface_pixbuf; GdkPixbuf *hiericon_svpackage_pixbuf; GdkPixbuf *hiericon_program_pixbuf; GdkPixbuf *hiericon_class_pixbuf; GdkPixbuf *hiericon_record_pixbuf; GdkPixbuf *hiericon_generate_pixbuf; GdkPixbuf *hiericon_design_pixbuf; GdkPixbuf *hiericon_block_pixbuf; GdkPixbuf *hiericon_generateif_pixbuf; GdkPixbuf *hiericon_generatefor_pixbuf; GdkPixbuf *hiericon_instance_pixbuf; GdkPixbuf *hiericon_package_pixbuf; GdkPixbuf *hiericon_signal_pixbuf; GdkPixbuf *hiericon_portin_pixbuf; GdkPixbuf *hiericon_portout_pixbuf; GdkPixbuf *hiericon_portinout_pixbuf; GdkPixbuf *hiericon_buffer_pixbuf; GdkPixbuf *hiericon_linkage_pixbuf; /* * 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 */ GtkListStore *sig_store_ptranslate; GtkTreeSelection *sig_selection_ptranslate; /* * 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 */ regex_t *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 */ 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 */ GtkListStore *sig_store_search; GtkTreeSelection *sig_selection_search; GtkWidget *sig_view_search; /* * signalwindow.c */ GtkWidget *signalarea; /* from signalwindow.c 396 */ struct font_engine_font_t *signalfont; /* from signalwindow.c 397 */ cairo_surface_t *surface_signalpixmap; cairo_t *cr_signalpixmap; #if defined(WAVE_ALLOW_QUARTZ_FLUSH_WORKAROUND) || defined(WAVE_ALLOW_GTK3_VSLIDER_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 */ gpointer 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; int dragzoom_threshold; #ifdef WAVE_GTK3_SIZE_ALLOCATE_WORKAROUND_WAVE_VSLIDER gfloat wave_vslider_page_size; gfloat wave_vslider_page_increment; gfloat wave_vslider_step_increment; gfloat wave_vslider_lower; gfloat wave_vslider_upper; gfloat wave_vslider_value; unsigned wave_vslider_valid : 1; #endif /* * 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 */ 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 */ GdkPixbuf *wave_splash_pixbuf; /* * status.c */ GtkWidget *text_status_c_2; /* from status.c 426 */ GtkTextIter iter_status_c_3; /* from status.c 428 */ GtkTextTag *bold_tag_status_c_3; /* from status.c 429 */ /* * 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 */ GtkListStore *sig_store_translate; GtkTreeSelection *sig_selection_translate; /* * 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; char *sst_exclude_filename; uint64_t exclhiermask; JRB exclcompname; JRB exclinstname; /* * 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 */ 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; GtkListStore *sig_store_treesearch_gtk2_c_1; /* from treesearch_gtk2.c 490 */ GtkTreeSelection *sig_selection_treesearch_gtk2_c_1; /* from treesearch_gtk2.c 491 */ int is_active_treesearch_gtk2_c_6; /* from treesearch_gtk2.c 492 */ 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 */ 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 */ int fetchlow; int fetchhigh; GtkTreeStore *treestore_main; GtkWidget *treeview_main; enum sst_cb_action sst_dbl_action_type; /* * 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; char *ttranslate_args; GtkListStore *sig_store_ttranslate; GtkTreeSelection *sig_selection_ttranslate; /* * 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 */ char mti_realparam_fix; 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 */ char vcd_already_backtracked; /* * 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 */ #ifdef WAVE_ALLOW_SLIDER_ZOOM char enable_slider_zoom; /* from wavewindow.c */ #endif 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 */ gpointer wave_vslider2; /* from wavewindow.c 681 */ gpointer wave_vslider; /* from wavewindow.c 681 */ gpointer 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; 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 */ 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; char fill_waveform; char lz_removal; cairo_surface_t *surface_wavepixmap_wavewindow_c_1; cairo_t *cr_wavepixmap_wavewindow_c_1; wave_rgb_t rgb_gc_white; wave_rgb_t rgb_gc_black; wave_rgb_t rgb_gc_rainbow[2*WAVE_NUM_RAINBOW]; struct wave_rgbmaster_t rgb_gc; struct wave_rgbmaster_t rgb_gccache; double cr_line_width; double cairo_050_offset; #ifdef WAVE_ALLOW_GTK3_GESTURE_EVENT gdouble wavearea_gesture_initial_zoom; #ifdef WAVE_GTK3_GESTURE_ZOOM_IS_1D gdouble wavearea_gesture_initial_zoom_x_distance; TimeType wavearea_gesture_initial_x1tim; #endif GtkGesture *wavearea_gesture_swipe; GDateTime *swipe_init_time; TimeType swipe_init_start; gdouble wavearea_gesture_swipe_velocity_x; int wavearea_drag_start_x; int wavearea_drag_start_y; char wavearea_drag_active; #endif char use_gestures; gboolean use_dark; gboolean save_on_exit; #ifdef GDK_WINDOWING_WAYLAND int wayland_marker_timer_hack; #endif /* * 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, intptr_t ptr_offset); gulong gtkwave_signal_connect_x(gpointer object, const gchar *name, GCallback func, gpointer data, char *f, intptr_t line); gulong gtkwave_signal_connect_object_x(gpointer object, const gchar *name, GCallback func, gpointer data, char *f, intptr_t 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-gtk3-3.3.125/src/gconf.c0000664000175000017500000004376315047725112015561 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2012-2018. * * 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_GSETTINGS static GSettings *gs = NULL; static void remove_client(void) { if(gs) { g_object_unref(gs); gs = NULL; } } static char *parse_rpc_id(char *str, int *this_wave_rpc_id) { char *comma = strchr(str, ','); char *str2 = comma ? (comma+1) : NULL; *this_wave_rpc_id = atoi(str); return(str2); } static void user_function (GSettings *settings, gchar *key, gpointer user_data) { (void)user_data; char *str = NULL; char *str2 = NULL; int this_wave_rpc_id = -1; g_settings_get (settings, key, "s", &str); if(!strcmp(key, "open")) { if((str)&&(str[0])) { str2 = parse_rpc_id(str, &this_wave_rpc_id); if((this_wave_rpc_id == wave_rpc_id) && str2) { fprintf(stderr, "GTKWAVE | RPC Open: '%s'\n", str2); deal_with_rpc_open(str, NULL); g_settings_set(settings, "open", "s", ""); } } } else if(!strcmp(key, "quit")) { if((str)&&(str[0])) { str2 = parse_rpc_id(str, &this_wave_rpc_id); if((this_wave_rpc_id == wave_rpc_id) && str2) { const char *rc = str2; int rcv = atoi(rc); fprintf(stderr, "GTKWAVE | RPC Quit: exit return code %d\n", rcv); g_settings_set(settings, "quit", "s", ""); exit(rcv); } } } else if(!strcmp(key, "reload")) { if((str)&&(str[0])) { this_wave_rpc_id = atoi(str); if(this_wave_rpc_id == wave_rpc_id) { if(in_main_iteration()) goto bot; reload_into_new_context(); g_settings_set(settings, "reload", "s", ""); } } } else if(!strcmp(key, "zoom-full")) { if((str)&&(str[0])) { this_wave_rpc_id = atoi(str); if(this_wave_rpc_id == wave_rpc_id) { if(in_main_iteration()) goto bot; service_zoom_full(NULL, NULL); g_settings_set(settings, "zoom-full", "s", ""); } } } else if(!strcmp(key, "writesave")) { if((str)&&(str[0])) { str2 = parse_rpc_id(str, &this_wave_rpc_id); if((this_wave_rpc_id == wave_rpc_id) && str2) { const char *fni = str2; 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); } } } g_settings_set(settings, "writesave", "s", ""); } } } else if(!strcmp(key, "move-to-time")) { if((str)&&(str[0])) { str2 = parse_rpc_id(str, &this_wave_rpc_id); if((this_wave_rpc_id == wave_rpc_id) && str2) { if(!in_main_iteration()) { char *e_copy = GLOBALS->entrybox_text; GLOBALS->entrybox_text=strdup_2(str2); movetotime_cleanup(NULL, NULL); GLOBALS->entrybox_text = e_copy; } g_settings_set(settings, "move-to-time", "s", ""); } } } else if(!strcmp(key, "zoom-size")) { if((str)&&(str[0])) { str2 = parse_rpc_id(str, &this_wave_rpc_id); if((this_wave_rpc_id == wave_rpc_id) && str2) { if(!in_main_iteration()) { char *e_copy = GLOBALS->entrybox_text; GLOBALS->entrybox_text=strdup_2(str2); zoomsize_cleanup(NULL, NULL); GLOBALS->entrybox_text = e_copy; } g_settings_set(settings, "zoom-size", "s", ""); } } } bot: if(str) g_free(str); } void wave_gconf_init(int argc, char **argv) { (void)argc; (void)argv; if(!gs) { gs = g_settings_new (WAVE_GSETTINGS_SCHEMA_ID); g_signal_connect (gs, "changed", G_CALLBACK (user_function), NULL); atexit(remove_client); } } gboolean wave_gconf_client_set_string(const gchar *key, const gchar *val) { if(key && gs) { const char *ks = strrchr(key, '/'); char *k2 = NULL; if(ks) { ks = ks+1; } else { ks = key; } if(strchr(ks, '_')) { char *s; k2 = s = strdup_2(ks); while(*s) { if(*s=='_') *s='-'; s++; } } g_settings_set(gs, k2 ? k2 : ks, "s", val ? val : ""); if(k2) free_2(k2); return(TRUE); } return(FALSE); } static gchar *wave_gconf_client_get_string(const gchar *key) { if(key && gs) { const char *ks = strrchr(key, '/'); char *k2 = NULL; char *str = NULL; if(ks) { ks = ks+1; } else { ks = key; } if(strchr(ks, '_')) { char *s; k2 = s = strdup_2(ks); while(*s) { if(*s=='_') *s='-'; s++; } } g_settings_get (gs, k2 ? k2 : ks, "s", &str); if(k2) free_2(k2); return(str); } 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 #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); client = NULL; } } 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 #endif /* Examples of RPC manipulation (gconf): 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 Examples of RPC manipulation (gsettings). First number is RPC ID: gsettings set com.geda.gtkwave open 0,/pub/systema_packed.fst gsettings set com.geda.gtkwave writesave 0,/tmp/this.gtkw gsettings set com.geda.gtkwave writesave 0,+ gsettings set com.geda.gtkwave quit 0,0 gsettings set com.geda.gtkwave reload 0 gsettings set com.geda.gtkwave zoom-full 0 gsettings set com.geda.gtkwave zoom-size 0,-4.6 gsettings set com.geda.gtkwave move-to-time 0,123ns gsettings set com.geda.gtkwave move-to-time 0,A */ gtkwave-gtk3-3.3.125/src/tree.c0000664000175000017500000006432415047725112015420 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2016. * * 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) { uintptr_t p = (uintptr_t)(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->child) treenamefix(tnext->child); 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; } } /* * 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 such as a hierarchy name also being used as a signal at the same level of scope.]\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(s && t && !strcmp(t->name, GLOBALS->module_tree_c_1)) /* ajb 300616 added "s &&" to cover case where we can have hierarchy + final name are same, see A.B.C.D notes elsewhere in this file */ { 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 */ /* * GTK2: build the tree. */ static void XXX_maketree_nodes(struct tree *t2, GtkTreeIter *iter) { char *tmp, *tmp2, *tmp3; gchar *text [1]; GdkPixbuf *pxb; 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; /* was 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(t2->kind) { case TREE_VCD_ST_MODULE: pxb = GLOBALS->hiericon_module_pixbuf; break; case TREE_VCD_ST_TASK: pxb = GLOBALS->hiericon_task_pixbuf; break; case TREE_VCD_ST_FUNCTION: pxb = GLOBALS->hiericon_function_pixbuf; break; case TREE_VCD_ST_BEGIN: pxb = GLOBALS->hiericon_begin_pixbuf; break; case TREE_VCD_ST_FORK: pxb = GLOBALS->hiericon_fork_pixbuf; break; case TREE_VCD_ST_GENERATE: pxb = GLOBALS->hiericon_generatefor_pixbuf; break; /* same as TREE_VHDL_ST_GENFOR */ case TREE_VCD_ST_STRUCT: pxb = GLOBALS->hiericon_block_pixbuf; break; /* same as TREE_VHDL_ST_BLOCK */ case TREE_VCD_ST_UNION: pxb = GLOBALS->hiericon_instance_pixbuf; break; /* same as TREE_VHDL_ST_INSTANCE */ case TREE_VCD_ST_CLASS: pxb = GLOBALS->hiericon_class_pixbuf; break; case TREE_VCD_ST_INTERFACE: pxb = GLOBALS->hiericon_interface_pixbuf; break; case TREE_VCD_ST_PACKAGE: pxb = GLOBALS->hiericon_svpackage_pixbuf; break; case TREE_VCD_ST_PROGRAM: pxb = GLOBALS->hiericon_program_pixbuf; break; case TREE_VHDL_ST_DESIGN: pxb = GLOBALS->hiericon_design_pixbuf; break; case TREE_VHDL_ST_BLOCK: pxb = GLOBALS->hiericon_block_pixbuf; break; case TREE_VHDL_ST_GENIF: pxb = GLOBALS->hiericon_generateif_pixbuf; break; case TREE_VHDL_ST_GENFOR: pxb = GLOBALS->hiericon_generatefor_pixbuf; break; case TREE_VHDL_ST_INSTANCE: pxb = GLOBALS->hiericon_instance_pixbuf; break; case TREE_VHDL_ST_PACKAGE: pxb = GLOBALS->hiericon_package_pixbuf; break; case TREE_VHDL_ST_SIGNAL: pxb = GLOBALS->hiericon_signal_pixbuf; break; case TREE_VHDL_ST_PORTIN: pxb = GLOBALS->hiericon_portin_pixbuf; break; case TREE_VHDL_ST_PORTOUT: pxb = GLOBALS->hiericon_portout_pixbuf; break; case TREE_VHDL_ST_PORTINOUT: pxb = GLOBALS->hiericon_portinout_pixbuf; break; case TREE_VHDL_ST_BUFFER: pxb = GLOBALS->hiericon_buffer_pixbuf; break; case TREE_VHDL_ST_LINKAGE: pxb = GLOBALS->hiericon_linkage_pixbuf; break; case TREE_VHDL_ST_ARCHITECTURE: pxb = GLOBALS->hiericon_module_pixbuf; break; /* same as TREE_VCD_ST_MODULE */ case TREE_VHDL_ST_FUNCTION: pxb = GLOBALS->hiericon_function_pixbuf; break; /* same as TREE_VCD_ST_FUNCTION */ case TREE_VHDL_ST_PROCESS: pxb = GLOBALS->hiericon_task_pixbuf; break; /* same as TREE_VCD_ST_TASK */ case TREE_VHDL_ST_PROCEDURE: pxb = GLOBALS->hiericon_class_pixbuf; break; /* same as TREE_VCD_ST_CLASS */ case TREE_VHDL_ST_RECORD: pxb = GLOBALS->hiericon_record_pixbuf; break; case TREE_VHDL_ST_GENERATE: pxb = GLOBALS->hiericon_generate_pixbuf; break; default: pxb = NULL; break; } gtk_tree_store_set (GLOBALS->treestore_main, iter, XXX_NAME_COLUMN, text[0], XXX_TREE_COLUMN, t2, XXX_PXB_COLUMN, pxb, -1); } void XXX_maketree2(GtkTreeIter *subtree, struct tree *t, int depth) { struct tree *t2; #ifndef WAVE_DISABLE_FAST_TREE if(depth > 1) return; #endif t2=t; while(t2) { #ifndef WAVE_DISABLE_FAST_TREE if(depth < 1) #endif { t2->children_in_gui = 1; } if(t2->child) { int blacklist = 0; if(GLOBALS->exclhiermask) { uint64_t exclone = 1; if((exclone << t2->kind) & GLOBALS->exclhiermask) blacklist = 1; } if(GLOBALS->exclinstname) { JRB str = jrb_find_str(GLOBALS->exclinstname, t2->name); if(str) blacklist = 1; } if(GLOBALS->exclcompname) { int thidx = -t2->t_which + WAVE_T_WHICH_COMPNAME_START; char *sc = ((thidx >= 0) && (thidx < GLOBALS->comp_name_serial)) ? GLOBALS->comp_name_idx[thidx] : t2->name; JRB str = jrb_find_str(GLOBALS->exclcompname, sc); if(str) blacklist = 1; } if(!blacklist) { GtkTreeIter iter; gtk_tree_store_prepend (GLOBALS->treestore_main, &iter, subtree); XXX_maketree_nodes(t2, &iter); XXX_maketree2(&iter, t2->child, depth + 1); } } t2=t2->next; } } void XXX_maketree(GtkTreeIter *subtree, struct tree *t) { GtkCellRenderer *renderer_t; GtkCellRenderer *renderer_p; GtkTreeViewColumn *column; GLOBALS->treestore_main = gtk_tree_store_new (XXX_NUM_COLUMNS, /* Total number of columns */ G_TYPE_STRING, /* name */ G_TYPE_POINTER, /* tree */ GDK_TYPE_PIXBUF); /* pixbuf */ XXX_maketree2(subtree, t, 0); GLOBALS->treeview_main = gtk_tree_view_new_with_model (GTK_TREE_MODEL (GLOBALS->treestore_main)); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(GLOBALS->treeview_main), FALSE); gtk_tree_view_set_enable_tree_lines (GTK_TREE_VIEW(GLOBALS->treeview_main), TRUE); column = gtk_tree_view_column_new(); renderer_t = gtk_cell_renderer_text_new (); renderer_p = gtk_cell_renderer_pixbuf_new (); gtk_tree_view_column_pack_start (column, renderer_p, FALSE); gtk_tree_view_column_pack_end (column, renderer_t, FALSE); gtk_tree_view_column_add_attribute (column, renderer_t, "text", XXX_NAME_COLUMN); gtk_tree_view_column_add_attribute (column, renderer_p, "pixbuf", XXX_PXB_COLUMN); gtk_tree_view_append_column (GTK_TREE_VIEW (GLOBALS->treeview_main), column); gtk_widget_show(GLOBALS->treeview_main); } /* * SST Exclusion filtering for XXX_maketree2() above */ #define SST_EXCL_MESS "SSTEXCL | " enum sst_excl_mode { SST_EXCL_NONE, SST_EXCL_HIER, SST_EXCL_COMP, SST_EXCL_INST }; void sst_exclusion_loader(void) { JRB str; Jval jv; int dummy = 0; if(GLOBALS->sst_exclude_filename) { FILE *f = fopen(GLOBALS->sst_exclude_filename, "rb"); int exclmode = SST_EXCL_NONE; uint64_t exclhier = 0; uint64_t exclone = 1; if(!f) { fprintf(stderr, SST_EXCL_MESS"Could not open '%s' SST exclusion file!\n", GLOBALS->sst_exclude_filename); fprintf(stderr, SST_EXCL_MESS); perror("Why"); return; } fprintf(stderr, SST_EXCL_MESS"Processing '%s'.\n", GLOBALS->sst_exclude_filename); while(!feof(f)) { char *iline = fgetmalloc(f); if(iline) { char *p = iline; char *e; while (*p) { if(isspace(*p)) p++; else break; } e = p; while (*e) { if(isspace(*e)) { *e = 0; break; } e++; } switch (*p) { case '#': break; case '/': break; case '[': if(!strcmp(p, "[hiertype]")) { exclmode = SST_EXCL_HIER; } else if(!strcmp(p, "[compname]")) { exclmode = SST_EXCL_COMP; } else if(!strcmp(p, "[instname]")) { exclmode = SST_EXCL_INST; } else { exclmode = SST_EXCL_NONE; } break; default: switch(exclmode) { case SST_EXCL_HIER: /* this if/else chain is good enough for an init script */ if(!strcmp(p, "VCD_ST_MODULE")) { exclhier |= exclone << TREE_VCD_ST_MODULE; } else if(!strcmp(p, "VCD_ST_TASK")) { exclhier |= exclone << TREE_VCD_ST_TASK; } else if(!strcmp(p, "VCD_ST_FUNCTION")) { exclhier |= exclone << TREE_VCD_ST_FUNCTION; } else if(!strcmp(p, "VCD_ST_BEGIN")) { exclhier |= exclone << TREE_VCD_ST_BEGIN; } else if(!strcmp(p, "VCD_ST_FORK")) { exclhier |= exclone << TREE_VCD_ST_FORK; } else if(!strcmp(p, "VCD_ST_GENERATE")) { exclhier |= exclone << TREE_VCD_ST_GENERATE; } else if(!strcmp(p, "VCD_ST_STRUCT")) { exclhier |= exclone << TREE_VCD_ST_STRUCT; } else if(!strcmp(p, "VCD_ST_UNION")) { exclhier |= exclone << TREE_VCD_ST_UNION; } else if(!strcmp(p, "VCD_ST_CLASS")) { exclhier |= exclone << TREE_VCD_ST_CLASS; } else if(!strcmp(p, "VCD_ST_INTERFACE")) { exclhier |= exclone << TREE_VCD_ST_INTERFACE; } else if(!strcmp(p, "VCD_ST_PACKAGE")) { exclhier |= exclone << TREE_VCD_ST_PACKAGE; } else if(!strcmp(p, "VCD_ST_PROGRAM")) { exclhier |= exclone << TREE_VCD_ST_PROGRAM; } else if(!strcmp(p, "VHDL_ST_DESIGN")) { exclhier |= exclone << TREE_VHDL_ST_DESIGN; } else if(!strcmp(p, "VHDL_ST_BLOCK")) { exclhier |= exclone << TREE_VHDL_ST_BLOCK; } else if(!strcmp(p, "VHDL_ST_GENIF")) { exclhier |= exclone << TREE_VHDL_ST_GENIF; } else if(!strcmp(p, "VHDL_ST_GENFOR")) { exclhier |= exclone << TREE_VHDL_ST_GENFOR; } else if(!strcmp(p, "VHDL_ST_INSTANCE")) { exclhier |= exclone << TREE_VHDL_ST_INSTANCE; } else if(!strcmp(p, "VHDL_ST_PACKAGE")) { exclhier |= exclone << TREE_VHDL_ST_PACKAGE; } else if(!strcmp(p, "VHDL_ST_SIGNAL")) { exclhier |= exclone << TREE_VHDL_ST_SIGNAL; } else if(!strcmp(p, "VHDL_ST_PORTIN")) { exclhier |= exclone << TREE_VHDL_ST_PORTIN; } else if(!strcmp(p, "VHDL_ST_PORTOUT")) { exclhier |= exclone << TREE_VHDL_ST_PORTOUT; } else if(!strcmp(p, "VHDL_ST_PORTINOUT")) { exclhier |= exclone << TREE_VHDL_ST_PORTINOUT; } else if(!strcmp(p, "VHDL_ST_BUFFER")) { exclhier |= exclone << TREE_VHDL_ST_BUFFER; } else if(!strcmp(p, "VHDL_ST_LINKAGE")) { exclhier |= exclone << TREE_VHDL_ST_LINKAGE; } else if(!strcmp(p, "VHDL_ST_ARCHITECTURE")) { exclhier |= exclone << TREE_VHDL_ST_ARCHITECTURE; } else if(!strcmp(p, "VHDL_ST_FUNCTION")) { exclhier |= exclone << TREE_VHDL_ST_FUNCTION; } else if(!strcmp(p, "VHDL_ST_PROCEDURE")) { exclhier |= exclone << TREE_VHDL_ST_PROCEDURE; } else if(!strcmp(p, "VHDL_ST_RECORD")) { exclhier |= exclone << TREE_VHDL_ST_RECORD; } else if(!strcmp(p, "VHDL_ST_PROCESS")) { exclhier |= exclone << TREE_VHDL_ST_PROCESS; } else if(!strcmp(p, "VHDL_ST_GENERATE")) { exclhier |= exclone << TREE_VHDL_ST_GENERATE; } break; case SST_EXCL_COMP: if(!GLOBALS->exclcompname) { GLOBALS->exclcompname = make_jrb(); } str = jrb_find_str(GLOBALS->exclcompname, p); jv.i = dummy++; if(!str) jrb_insert_str(GLOBALS->exclcompname, strdup_2(p), jv); break; case SST_EXCL_INST: if(!GLOBALS->exclinstname) { GLOBALS->exclinstname = make_jrb(); } str = jrb_find_str(GLOBALS->exclinstname, p); jv.i = dummy++; if(!str) jrb_insert_str(GLOBALS->exclinstname, strdup_2(p), jv); break; default: break; } break; } free_2(iline); } GLOBALS->exclhiermask |= exclhier; } fclose(f); } } gtkwave-gtk3-3.3.125/src/gconf.h0000664000175000017500000000172015047725112015551 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2012-2018. * * 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_GSETTINGS_SCHEMA_ID "com.geda.gtkwave" /* 1234567890123456 */ #define WAVE_GCONF_DIR "/com.geda.gtkwave" /* 12345678901234567 */ #define WAVE_GCONF_DIR_LEN (17) extern 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-gtk3-3.3.125/src/simplereq.c0000664000175000017500000001234315047725112016454 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 "gtk23compat.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, GCallback 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) { XXX_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_size_request( 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(XXX_GTK_OBJECT (GLOBALS->window_simplereq_c_9), "delete_event",(GCallback) destroy_callback, NULL); gtk_window_set_resizable(GTK_WINDOW(GLOBALS->window_simplereq_c_9), FALSE); vbox = XXX_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); #if GTK_CHECK_VERSION(3,0,0) gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0); #else gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); #endif gtk_widget_show (label); if(is_alert) { pixmapwid1=gtk_image_new_from_pixbuf(GLOBALS->wave_alert_pixbuf); } else { pixmapwid1=gtk_image_new_from_pixbuf(GLOBALS->wave_info_pixbuf); } gtk_widget_show(pixmapwid1); #if GTK_CHECK_VERSION(3,0,0) gtk_box_pack_start(GTK_BOX(vbox), pixmapwid1, TRUE, TRUE, 0); #else gtk_container_add (GTK_CONTAINER (vbox), pixmapwid1); #endif separator = XXX_gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, TRUE, 0); gtk_widget_show (separator); hbox = XXX_gtk_hbox_new (FALSE, 1); #if GTK_CHECK_VERSION(3,0,0) gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0); #else gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); #endif gtk_widget_show (hbox); button1 = gtk_button_new_with_label (oktext); gtk_widget_set_size_request(button1, 100, -1); gtkwave_signal_connect(XXX_GTK_OBJECT (button1), "clicked", G_CALLBACK(ok_callback), NULL); gtk_widget_show (button1); #if GTK_CHECK_VERSION(3,0,0) gtk_box_pack_start(GTK_BOX(hbox), button1, TRUE, TRUE, 0); #else gtk_container_add (GTK_CONTAINER (hbox), button1); #endif gtk_widget_set_can_default (button1, TRUE); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button1), "realize", (GCallback) gtk_widget_grab_default, XXX_GTK_OBJECT (button1)); if(canceltext) { button2 = gtk_button_new_with_label (canceltext); gtk_widget_set_size_request(button2, 100, -1); gtkwave_signal_connect(XXX_GTK_OBJECT (button2), "clicked", G_CALLBACK(destroy_callback), NULL); gtk_widget_set_can_default (button2, TRUE); gtk_widget_show (button2); #if GTK_CHECK_VERSION(3,0,0) gtk_box_pack_end(GTK_BOX(hbox), button2, TRUE, TRUE, 0); #else gtk_container_add (GTK_CONTAINER (hbox), button2); #endif } gtk_widget_show(GLOBALS->window_simplereq_c_9); wave_gtk_grab_add(GLOBALS->window_simplereq_c_9); #endif } gtkwave-gtk3-3.3.125/src/currenttime.c0000664000175000017500000004713215047725112017020 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2016. * * 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"; #ifdef WAVE_ALLOW_GTK3_HEADER_BAR static void update_labels_to_header_bar(void) { if(GLOBALS->header_bar) { char buf[1024]; sprintf(buf, "%s" ": " "%s" " | " "%s" ": " "%s", gtk_label_get_text(GTK_LABEL(GLOBALS->max_or_marker_label_currenttime_c_1)), gtk_label_get_text(GTK_LABEL(GLOBALS->maxtimewid_currenttime_c_1)), gtk_label_get_text(GTK_LABEL(GLOBALS->base_or_curtime_label_currenttime_c_1)), gtk_label_get_text(GTK_LABEL(GLOBALS->curtimewid_currenttime_c_1)) ); gtk_header_bar_set_subtitle(GTK_HEADER_BAR(GLOBALS->header_bar), buf); } } #else static void update_labels_to_header_bar(void) { /* nothing */ } #endif void fractional_timescale_fix(char *s) { char buf[32], sfx[2]; int i, len; int prefix_idx = 0; if(*s != '0') { unsigned char *dot = strchr(s, '.'); unsigned char *src, *dst; if(dot) { unsigned char *pnt = dot+1; int alpha_found = 0; while(*pnt) { if(isalpha(*pnt)) { alpha_found = 1; break; } pnt++; } if(alpha_found) { src = pnt; dst = dot; while(*src) { *dst = *src; dst++; src++; } *dst = 0; } } return; } len = strlen(s); for(i=0;iuse_maxtime_display) { gtk_label_set_text(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_text(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); } update_labels_to_header_bar(); } /* 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;inamed_markers[mkv]; if(mkvt != -1) { return(mkvt); } } } } 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) { #ifdef GDK_WINDOWING_WAYLAND GLOBALS->wayland_marker_timer_hack = 10; #endif 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; } } 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_text(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); } } } update_labels_to_header_bar(); } void update_basetime(TimeType val) { if(val>=0) { gtk_label_set_text(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_text(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_text(GTK_LABEL(GLOBALS->curtimewid_currenttime_c_1), GLOBALS->curtext_currenttime_c_1); update_labels_to_header_bar(); } 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_text(GTK_LABEL(GLOBALS->maxtimewid_currenttime_c_1), GLOBALS->maxtext_currenttime_c_1); } update_labels_to_header_bar(); } 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_text(GTK_LABEL(GLOBALS->curtimewid_currenttime_c_1), GLOBALS->curtext_currenttime_c_1); } update_labels_to_header_bar(); } /* 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=XXX_gtk_vbox_new(FALSE, 0); } else { mainbox=XXX_gtk_hbox_new(FALSE, 0); } #ifdef WAVE_ALLOW_GTK3_HEADER_BAR if(GLOBALS->socket_xid) #endif { gtk_widget_show(mainbox); } GLOBALS->time_mainbox = 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); /* fallthrough */ 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); /* fallthrough */ 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); /* fallthrough */ 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); /* fallthrough */ 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); /* fallthrough */ 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); /* fallthrough */ 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); /* fallthrough */ 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); /* fallthrough */ case -9: default: GLOBALS->time_dimension = 'n'; break; } } gtkwave-gtk3-3.3.125/src/renderopt.c0000664000175000017500000003611115047725112016454 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 #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(GtkComboBox *widget, gpointer user_data) { (void) user_data; GtkComboBox *combo_box = widget; int which = gtk_combo_box_get_active (combo_box); int i; for(i=0;i<4;i++) GLOBALS->target_mutex_renderopt_c_1[i]=0; i = which; GLOBALS->target_mutex_renderopt_c_1[i] = 1; /* mark our choice */ DEBUG(printf("picked: %s\n", render_targets[i])); } static void pagesize_clicked(GtkComboBox *widget, gpointer user_data) { (void) user_data; GtkComboBox *combo_box = widget; int which = gtk_combo_box_get_active (combo_box); int i; for(i=0;i<5;i++) GLOBALS->page_mutex_renderopt_c_1[i]=0; GLOBALS->page_size_type_renderopt_c_1 = 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(GtkComboBox *widget, gpointer user_data) { (void) user_data; GtkComboBox *combo_box = widget; int which = gtk_combo_box_get_active (combo_box); int i; for(i=0;i<3;i++) GLOBALS->render_mutex_renderopt_c_1[i]=0; i = 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, (GtkPrintJobCompleteFunc)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 __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,G_CALLBACK(pdf_print_cleanup), G_CALLBACK(NULL), "*.pdf", 1); } else if(GLOBALS->target_mutex_renderopt_c_1[1]) { fileselbox("Print To PS File",&GLOBALS->filesel_print_ps_renderopt_c_1,G_CALLBACK(ps_print_cleanup), G_CALLBACK(NULL), "*.ps", 1); } else if(GLOBALS->target_mutex_renderopt_c_1[2]) { fileselbox("Print To MIF File",&GLOBALS->filesel_print_mif_renderopt_c_1,G_CALLBACK(mif_print_cleanup), G_CALLBACK(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 *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) { XXX_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(gtk_widget_get_window(GLOBALS->window_renderopt_c_6)); } 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_size_request( GTK_WIDGET (GLOBALS->window_renderopt_c_6), 420, -1); gtkwave_signal_connect(XXX_GTK_OBJECT (GLOBALS->window_renderopt_c_6), "delete_event",(GCallback) destroy_callback, NULL); gtk_window_set_resizable(GTK_WINDOW(GLOBALS->window_renderopt_c_6), FALSE); vbox = XXX_gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (GLOBALS->window_renderopt_c_6), vbox); gtk_widget_show (vbox); small_hbox = XXX_gtk_hbox_new (TRUE, 0); gtk_widget_show (small_hbox); GtkWidget *combo_box = gtk_combo_box_text_new (); for(i=0;i<4;i++) { GLOBALS->target_mutex_renderopt_c_1[i]=0; #ifndef WAVE_GTK_UNIX_PRINT if(i==3) { break; } #endif gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(combo_box), render_targets[i]); } GLOBALS->target_mutex_renderopt_c_1[0]=1; /* "ps" */ gtk_combo_box_set_active (GTK_COMBO_BOX(combo_box), 0); gtk_widget_show (combo_box); gtk_box_pack_start (GTK_BOX (small_hbox), combo_box, TRUE, FALSE, 0); g_signal_connect (combo_box, "changed", G_CALLBACK (render_clicked), NULL); combo_box = gtk_combo_box_text_new (); for(i=0;i<5;i++) { gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(combo_box), page_size[i]); GLOBALS->page_mutex_renderopt_c_1[i]=0; } GLOBALS->page_mutex_renderopt_c_1[0]=1; /* "letter" */ gtk_combo_box_set_active (GTK_COMBO_BOX(combo_box), 0); gtk_widget_show (combo_box); gtk_box_pack_start (GTK_BOX (small_hbox), combo_box, TRUE, FALSE, 0); g_signal_connect (combo_box, "changed", G_CALLBACK (pagesize_clicked), NULL); gtk_box_pack_start (GTK_BOX (vbox), small_hbox, FALSE, FALSE, 0); combo_box = gtk_combo_box_text_new (); for(i=0;i<2;i++) { gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(combo_box), render_type[i]); GLOBALS->render_mutex_renderopt_c_1[i]=0; } GLOBALS->render_mutex_renderopt_c_1[0]=1; /* "full" */ gtk_combo_box_set_active (GTK_COMBO_BOX(combo_box), 0); gtk_widget_show (combo_box); gtk_box_pack_start (GTK_BOX (small_hbox), combo_box, TRUE, FALSE, 0); g_signal_connect (combo_box, "changed", G_CALLBACK (rendertype_clicked), NULL); hbox = XXX_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_size_request(button1, 100, -1); gtkwave_signal_connect(XXX_GTK_OBJECT (button1), "clicked", G_CALLBACK(ok_callback), NULL); gtk_widget_show (button1); gtk_container_add (GTK_CONTAINER (hbox), button1); gtk_widget_set_can_default (button1, TRUE); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button1), "realize", (GCallback) gtk_widget_grab_default, XXX_GTK_OBJECT (button1)); button2 = gtk_button_new_with_label ("Exit"); gtk_widget_set_size_request(button2, 100, -1); gtkwave_signal_connect(XXX_GTK_OBJECT (button2), "clicked", G_CALLBACK(destroy_callback), NULL); gtk_widget_set_can_default (button2, TRUE); gtk_widget_show (button2); gtk_container_add (GTK_CONTAINER (hbox), button2); gtk_widget_show(GLOBALS->window_renderopt_c_6); } gtkwave-gtk3-3.3.125/src/zoombuttons.c0000664000175000017500000003642615047725112017066 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2016. * * 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); gtk_adjustment_set_lower(hadj, GLOBALS->tims.first); gtk_adjustment_set_upper(hadj, GLOBALS->tims.last+2.0); pageinc=(gfloat)(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx); gtk_adjustment_set_page_increment(hadj, (pageinc>=1.0)?pageinc:1.0); gtk_adjustment_set_page_size(hadj, gtk_adjustment_get_page_increment(hadj)); /* hadj->step_increment=(GLOBALS->nspx>=1.0)?GLOBALS->nspx:1.0; */ gtk_adjustment_set_step_increment (hadj, pageinc / 10.0); if(gtk_adjustment_get_step_increment (hadj) < 1.0) gtk_adjustment_set_step_increment (hadj, 1.0); #if GTK_CHECK_VERSION(3,0,0) gtk_adjustment_set_value(hadj, GLOBALS->tims.start); /* work around GTK3 clamping code */ #endif if(gtk_adjustment_get_page_size(hadj) >= (gtk_adjustment_get_upper(hadj)-gtk_adjustment_get_lower(hadj))) gtk_adjustment_set_value(hadj, gtk_adjustment_get_lower(hadj)); if(gtk_adjustment_get_value(hadj)+gtk_adjustment_get_page_size(hadj)>gtk_adjustment_get_upper(hadj)) { gtk_adjustment_set_value(hadj, gtk_adjustment_get_upper(hadj)-gtk_adjustment_get_page_size(hadj)); if(gtk_adjustment_get_value(hadj)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); gtk_adjustment_set_value(hadj, 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); gtk_adjustment_set_value(hadj, 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." " Alt + Scrollwheel Up also hits this button in non-alternative wheel mode." ); 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_set_value(GTK_ADJUSTMENT(GLOBALS->wave_hslider), GLOBALS->tims.timecache=GLOBALS->tims.start); } else { GLOBALS->tims.timecache=0; } fix_wavehadj(); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */ g_signal_emit_by_name (XXX_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." " Alt + Scrollwheel Down also hits this button in non-alternative wheel mode." ); 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_set_value(GTK_ADJUSTMENT(GLOBALS->wave_hslider), GLOBALS->tims.timecache=GLOBALS->tims.start); } else { GLOBALS->tims.timecache=0; } fix_wavehadj(); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */ g_signal_emit_by_name (XXX_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(); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */ g_signal_emit_by_name (XXX_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(); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */ g_signal_emit_by_name (XXX_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(); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */ g_signal_emit_by_name (XXX_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; int dragzoom_ok = 1; if(time2dragzoom_threshold) { TimeType tdelta = time2 - time1; gdouble x = tdelta * GLOBALS->pxns; if(xdragzoom_threshold) { dragzoom_ok = 0; } } if((time2>time1)&&(dragzoom_ok)) /* ensure at least 1 tick and dragzoom_threshold if set */ { 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); gtk_adjustment_set_value(hadj, time1); calczoom(estimated); GLOBALS->tims.zoom=estimated; fix_wavehadj(); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */ g_signal_emit_by_name (XXX_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; pixmapzin=gtk_image_new_from_pixbuf(GLOBALS->zoomin_pixbuf); gtk_widget_show(pixmapzin); pixmapzout=gtk_image_new_from_pixbuf(GLOBALS->zoomout_pixbuf); gtk_widget_show(pixmapzout); pixmapzfit=gtk_image_new_from_pixbuf(GLOBALS->zoomfit_pixbuf); gtk_widget_show(pixmapzfit); pixmapzundo=gtk_image_new_from_pixbuf(GLOBALS->zoomundo_pixbuf); gtk_widget_show(pixmapzundo); pixmapzleft=gtk_image_new_from_pixbuf(GLOBALS->zoom_larrow_pixbuf); gtk_widget_show(pixmapzleft); pixmapzright=gtk_image_new_from_pixbuf(GLOBALS->zoom_rarrow_pixbuf); gtk_widget_show(pixmapzright); /* Create a table to hold the text widget and scrollbars */ table = XXX_gtk_table_new (1, 1, FALSE); main_vbox = XXX_gtk_vbox_new (FALSE, 1); gtk_container_set_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 = XXX_gtk_table_new (2, 3, FALSE); b1 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b1), pixmapzin); XXX_gtk_table_attach (XXX_GTK_TABLE (table2), b1, 0, 1, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); g_signal_connect_swapped (XXX_GTK_OBJECT (b1), "clicked", G_CALLBACK(service_zoom_out), XXX_GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(b1, "Zoom Out"); gtk_widget_show(b1); b2 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b2), pixmapzout); XXX_gtk_table_attach (XXX_GTK_TABLE (table2), b2, 0, 1, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); g_signal_connect_swapped (XXX_GTK_OBJECT (b2), "clicked", G_CALLBACK(service_zoom_in), XXX_GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(b2, "Zoom In"); gtk_widget_show(b2); b3 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b3), pixmapzfit); XXX_gtk_table_attach (XXX_GTK_TABLE (table2), b3, 1, 2, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); g_signal_connect_swapped (XXX_GTK_OBJECT (b3), "clicked", G_CALLBACK(service_zoom_fit), XXX_GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(b3, "Zoom Best Fit"); gtk_widget_show(b3); b4 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b4), pixmapzundo); XXX_gtk_table_attach (XXX_GTK_TABLE (table2), b4, 1, 2, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); g_signal_connect_swapped (XXX_GTK_OBJECT (b4), "clicked", G_CALLBACK(service_zoom_undo), XXX_GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(b4, "Undo Last Zoom"); gtk_widget_show(b4); b5 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b5), pixmapzleft); XXX_gtk_table_attach (XXX_GTK_TABLE (table2), b5, 2, 3, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); g_signal_connect_swapped (XXX_GTK_OBJECT (b5), "clicked", G_CALLBACK(service_zoom_left), XXX_GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(b5, "Zoom To Start"); gtk_widget_show(b5); b6 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b6), pixmapzright); XXX_gtk_table_attach (XXX_GTK_TABLE (table2), b6, 2, 3, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); g_signal_connect_swapped (XXX_GTK_OBJECT (b6), "clicked", G_CALLBACK(service_zoom_right), XXX_GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(b6, "Zoom To End"); gtk_widget_show(b6); gtk_container_add (GTK_CONTAINER (frame), table2); gtk_widget_show(table2); return table; } gtkwave-gtk3-3.3.125/src/tree.h0000664000175000017500000001070115047725112015413 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: libghw 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); 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 /* #define WAVE_DISABLE_FAST_TREE */ enum treeview_columns { XXX_NAME_COLUMN, XXX_TREE_COLUMN, XXX_PXB_COLUMN, XXX_NUM_COLUMNS }; void XXX_maketree(GtkTreeIter *subtree, struct tree *t); void XXX_maketree2(GtkTreeIter *subtree, struct tree *t, int depth); void sst_exclusion_loader(void); #endif gtkwave-gtk3-3.3.125/src/search.c0000664000175000017500000011077315047725112015726 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 "gtk23compat.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" enum { NAME_COLUMN, PTR_COLUMN, N_COLUMNS }; static gboolean XXX_view_selection_func (GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean path_currently_selected, gpointer userdata) { (void) selection; (void) userdata; GtkTreeIter iter; char *nam = NULL; struct symbol *s; if(path) { if (gtk_tree_model_get_iter(model, &iter, path)) /* null return should not happen */ { gtk_tree_model_get(model, &iter, NAME_COLUMN, &nam, PTR_COLUMN, &s, -1); if(!path_currently_selected) { set_s_selected(s, 1); GLOBALS->selected_rows_search_c_2++; } else { set_s_selected(s, 0); GLOBALS->selected_rows_search_c_2--; } } } return(TRUE); } 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, GCallback 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) { XXX_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_size_request( GTK_WIDGET (GLOBALS->window1_search_c_2), width, 60); gtk_window_set_title(GTK_WINDOW (GLOBALS->window1_search_c_2), title); gtkwave_signal_connect(XXX_GTK_OBJECT (GLOBALS->window1_search_c_2), "delete_event",(GCallback) destroy_callback_e, NULL); vbox = XXX_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 = X_gtk_entry_new_with_max_length (maxch); gtkwave_signal_connect(XXX_GTK_OBJECT(GLOBALS->entry_a_search_c_1), "activate",G_CALLBACK(enter_callback_e),GLOBALS->entry_a_search_c_1); gtk_entry_set_text (GTK_ENTRY (GLOBALS->entry_a_search_c_1), default_text); gtk_editable_select_region (GTK_EDITABLE (GLOBALS->entry_a_search_c_1),0, gtk_entry_get_text_length(GTK_ENTRY(GLOBALS->entry_a_search_c_1))); 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 = XXX_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_size_request(button1, 100, -1); gtkwave_signal_connect(XXX_GTK_OBJECT (button1), "clicked", G_CALLBACK(enter_callback_e), NULL); gtk_widget_show (button1); gtk_container_add (GTK_CONTAINER (hbox), button1); gtk_widget_set_can_default (button1, TRUE); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button1), "realize", (GCallback) gtk_widget_grab_default, XXX_GTK_OBJECT (button1)); button2 = gtk_button_new_with_label ("Cancel"); gtk_widget_set_size_request(button2, 100, -1); gtkwave_signal_connect(XXX_GTK_OBJECT (button2), "clicked", G_CALLBACK(destroy_callback_e), NULL); gtk_widget_set_can_default (button2, TRUE); 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 on_changed (GtkComboBox *widget, gpointer user_data) { (void) user_data; GtkComboBox *combo_box = widget; int which = gtk_combo_box_get_active (combo_box); int i; for(i=0;i<5;i++) GLOBALS->regex_mutex_search_c_1[i]=0; GLOBALS->regex_which_search_c_1=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,G_CALLBACK(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; interval = (gfloat)(GLOBALS->num_rows_search_c_2/100.0); /* LX2 */ GtkTreeIter iter; if(GLOBALS->is_lx2) { int pre_import=0; gtk_tree_model_get_iter_first (GTK_TREE_MODEL (GLOBALS->sig_store_search), &iter); for(i=0;inum_rows_search_c_2;i++) { struct symbol *s, *t; gtk_tree_model_get(GTK_TREE_MODEL (GLOBALS->sig_store_search), &iter, PTR_COLUMN, &s, -1); gtk_tree_model_iter_next (GTK_TREE_MODEL (GLOBALS->sig_store_search), &iter); 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 */ gtk_tree_model_get_iter_first (GTK_TREE_MODEL (GLOBALS->sig_store_search), &iter); for(i=0;inum_rows_search_c_2;i++) { int len; struct symbol *s, *t; gtk_tree_model_get(GTK_TREE_MODEL (GLOBALS->sig_store_search), &iter, PTR_COLUMN, &s, -1); gtk_tree_model_iter_next (GTK_TREE_MODEL (GLOBALS->sig_store_search), &iter); if(get_s_selected(s)) { GLOBALS->pdata->value = i; if(((int)(GLOBALS->pdata->value/interval))!=((int)(GLOBALS->pdata->oldvalue/interval))) { gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (GLOBALS->pdata->pbar), i / (gfloat)((GLOBALS->num_rows_search_c_2>1)?GLOBALS->num_rows_search_c_2-1:1)); 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_bar_set_fraction (GTK_PROGRESS_BAR (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; interval = (gfloat)(GLOBALS->num_rows_search_c_2/100.0); GLOBALS->pdata->oldvalue = -1.0; /* LX2 */ GtkTreeIter iter; if(GLOBALS->is_lx2) { int pre_import=0; gtk_tree_model_get_iter_first (GTK_TREE_MODEL (GLOBALS->sig_store_search), &iter); for(i=0;inum_rows_search_c_2;i++) { struct symbol *s, *t; gtk_tree_model_get(GTK_TREE_MODEL (GLOBALS->sig_store_search), &iter, PTR_COLUMN, &s, -1); gtk_tree_model_iter_next (GTK_TREE_MODEL (GLOBALS->sig_store_search), &iter); 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 */ gtk_tree_model_get_iter_first (GTK_TREE_MODEL (GLOBALS->sig_store_search), &iter); for(i=0;inum_rows_search_c_2;i++) { int len; struct symbol *s, *t; gtk_tree_model_get(GTK_TREE_MODEL (GLOBALS->sig_store_search), &iter, PTR_COLUMN, &s, -1); gtk_tree_model_iter_next (GTK_TREE_MODEL (GLOBALS->sig_store_search), &iter); if(get_s_selected(s)) { GLOBALS->pdata->value = i; if(((int)(GLOBALS->pdata->value/interval))!=((int)(GLOBALS->pdata->oldvalue/interval))) { gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (GLOBALS->pdata->pbar), i / (gfloat)((GLOBALS->num_rows_search_c_2>1)?GLOBALS->num_rows_search_c_2-1:1)); 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_bar_set_fraction (GTK_PROGRESS_BAR (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; interval = (gfloat)(GLOBALS->num_rows_search_c_2/100.0); GLOBALS->pdata->oldvalue = -1.0; /* LX2 */ GtkTreeIter iter; if(GLOBALS->is_lx2) { int pre_import=0; gtk_tree_model_get_iter_first (GTK_TREE_MODEL (GLOBALS->sig_store_search), &iter); for(i=0;inum_rows_search_c_2;i++) { struct symbol *s, *t; gtk_tree_model_get(GTK_TREE_MODEL (GLOBALS->sig_store_search), &iter, PTR_COLUMN, &s, -1); gtk_tree_model_iter_next (GTK_TREE_MODEL (GLOBALS->sig_store_search), &iter); 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 */ gtk_tree_model_get_iter_first (GTK_TREE_MODEL (GLOBALS->sig_store_search), &iter); for(i=0;inum_rows_search_c_2;i++) { int len; struct symbol *s, *t; gtk_tree_model_get(GTK_TREE_MODEL (GLOBALS->sig_store_search), &iter, PTR_COLUMN, &s, -1); gtk_tree_model_iter_next (GTK_TREE_MODEL (GLOBALS->sig_store_search), &iter); if(get_s_selected(s)) { GLOBALS->pdata->value = i; if(((int)(GLOBALS->pdata->value/interval))!=((int)(GLOBALS->pdata->oldvalue/interval))) { gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (GLOBALS->pdata->pbar), i / (gfloat)((GLOBALS->num_rows_search_c_2>1)?GLOBALS->num_rows_search_c_2-1:1)); 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_bar_set_fraction (GTK_PROGRESS_BAR (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; } void search_enter_callback(GtkWidget *widget, GtkWidget *do_warning) { G_CONST_RETURN gchar *entry_text; char *entry_suffixed; int i; 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; 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); } GLOBALS->pdata->oldvalue = -1.0; interval = (gfloat)(GLOBALS->numfacs/100.0); duplicate_row_buffer = (char *)calloc_2(1, GLOBALS->longestname+1); gtk_list_store_clear (GTK_LIST_STORE(GLOBALS->sig_store_search)); 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_bar_set_fraction (GTK_PROGRESS_BAR (GLOBALS->pdata->pbar), i / (gfloat)((GLOBALS->numfacs>1)?GLOBALS->numfacs-1:1)); 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))) { GtkTreeIter iter; if(!GLOBALS->facs[i]->vec_root) { gtk_list_store_append (GTK_LIST_STORE(GLOBALS->sig_store_search), &iter); gtk_list_store_set (GTK_LIST_STORE(GLOBALS->sig_store_search), &iter, NAME_COLUMN, hfacname, PTR_COLUMN, GLOBALS->facs[i], -1); } 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); } gtk_list_store_append (GTK_LIST_STORE(GLOBALS->sig_store_search), &iter); gtk_list_store_set (GTK_LIST_STORE(GLOBALS->sig_store_search), &iter, NAME_COLUMN, s, PTR_COLUMN, GLOBALS->facs[i], -1); free_2(s); } 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); gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (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->sig_store_search = NULL; GLOBALS->sig_selection_search = NULL; GLOBALS->sig_view_search = NULL; } } static void select_all_callback(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; gtk_tree_selection_select_all (GLOBALS->sig_selection_search); } static void unselect_all_callback(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; gtk_tree_selection_unselect_all (GLOBALS->sig_selection_search); } /* * mainline.. */ void searchbox(char *title, GCallback func) { int i; 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; int cached_which = GLOBALS->regex_which_search_c_1; /* fix problem where ungrab doesn't occur if button pressed + simultaneous accelerator key occurs */ if(GLOBALS->in_button_press_wavewindow_c_1) { XXX_gdk_pointer_ungrab(GDK_CURRENT_TIME); } if(GLOBALS->is_active_search_c_4) { gdk_window_raise(gtk_widget_get_window(GLOBALS->window_search_c_7)); 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(XXX_GTK_OBJECT (GLOBALS->window_search_c_7), "delete_event",(GCallback) destroy_callback, NULL); table = XXX_gtk_table_new (256, 1, FALSE); gtk_widget_show (table); vbox1 = XXX_gtk_vbox_new (FALSE, 0); gtk_container_set_border_width (GTK_CONTAINER (vbox1), 3); gtk_widget_show (vbox1); frame1 = gtk_frame_new (NULL); gtk_container_set_border_width (GTK_CONTAINER (frame1), 3); gtk_widget_show(frame1); XXX_gtk_table_attach (XXX_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 = X_gtk_entry_new_with_max_length (256); gtkwave_signal_connect(XXX_GTK_OBJECT(GLOBALS->entry_search_c_3), "activate", G_CALLBACK(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_editable_select_region (GTK_EDITABLE (GLOBALS->entry_search_c_3),0, gtk_entry_get_text_length(GTK_ENTRY(GLOBALS->entry_search_c_3))); gtk_widget_show (GLOBALS->entry_search_c_3); gtk_tooltips_set_tip_2(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."); 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 the GtkProgressBar */ GLOBALS->pdata->pbar = gtk_progress_bar_new(); gtk_progress_bar_set_text(GTK_PROGRESS_BAR(GLOBALS->pdata->pbar), " "); gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(GLOBALS->pdata->pbar), 0.0); 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_set_border_width (GTK_CONTAINER (frame2), 3); gtk_widget_show(frame2); XXX_gtk_table_attach (XXX_GTK_TABLE (table), frame2, 0, 1, 1, 254, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); GLOBALS->sig_store_search = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_POINTER); GLOBALS->sig_view_search = gtk_tree_view_new_with_model (GTK_TREE_MODEL (GLOBALS->sig_store_search)); /* The view now holds a reference. We can get rid of our own reference */ g_object_unref (G_OBJECT (GLOBALS->sig_store_search)); GtkCellRenderer *renderer = gtk_cell_renderer_text_new (); GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes (titles[0], renderer, "text", NAME_COLUMN, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (GLOBALS->sig_view_search), column); /* Setup the selection handler */ GLOBALS->sig_selection_search = gtk_tree_view_get_selection (GTK_TREE_VIEW (GLOBALS->sig_view_search)); gtk_tree_selection_set_mode (GLOBALS->sig_selection_search, GTK_SELECTION_MULTIPLE); gtk_tree_selection_set_select_function (GLOBALS->sig_selection_search, XXX_view_selection_func, NULL, NULL); gtk_list_store_clear (GTK_LIST_STORE(GLOBALS->sig_store_search)); gtk_widget_show (GLOBALS->sig_view_search); dnd_setup(GLOBALS->sig_view_search, GLOBALS->signalarea, 0); 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_size_request( 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->sig_view_search); gtk_container_add (GTK_CONTAINER (frame2), scrolled_win); frameh0 = gtk_frame_new (NULL); gtk_container_set_border_width (GTK_CONTAINER (frameh0), 3); gtk_widget_show(frameh0); XXX_gtk_table_attach (XXX_GTK_TABLE (table), frameh0, 0, 1, 254, 255, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); hbox0 = XXX_gtk_hbox_new (FALSE, 1); gtk_widget_show (hbox0); button6 = gtk_button_new_with_label (" Select All "); gtk_container_set_border_width (GTK_CONTAINER (button6), 3); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button6), "clicked",G_CALLBACK(select_all_callback),XXX_GTK_OBJECT (GLOBALS->window_search_c_7)); gtk_widget_show (button6); gtk_tooltips_set_tip_2(button6, "Highlight all signals listed in the match window."); gtk_box_pack_start (GTK_BOX (hbox0), button6, TRUE, FALSE, 0); small_hbox = XXX_gtk_hbox_new (TRUE, 0); gtk_widget_show (small_hbox); GtkWidget *combo_box = gtk_combo_box_text_new (); for(i=0;i<5;i++) { gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(combo_box), regex_name[i]); GLOBALS->regex_mutex_search_c_1[i]=0; } GLOBALS->regex_which_search_c_1 = cached_which; if((GLOBALS->regex_which_search_c_1<0)||(GLOBALS->regex_which_search_c_1>4)) GLOBALS->regex_which_search_c_1 = 0; GLOBALS->regex_mutex_search_c_1[GLOBALS->regex_which_search_c_1]=1; /* configure for "range", etc */ gtk_combo_box_set_active (GTK_COMBO_BOX(combo_box), GLOBALS->regex_which_search_c_1); gtk_box_pack_start (GTK_BOX (small_hbox), combo_box, TRUE, FALSE, 0); gtk_widget_show (combo_box); gtk_tooltips_set_tip_2(combo_box, "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."); g_signal_connect (combo_box, "changed", G_CALLBACK (on_changed), NULL); gtk_box_pack_start (GTK_BOX (hbox0), small_hbox, FALSE, FALSE, 0); button7 = gtk_button_new_with_label (" Unselect All "); gtk_container_set_border_width (GTK_CONTAINER (button7), 3); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button7), "clicked",G_CALLBACK(unselect_all_callback),XXX_GTK_OBJECT (GLOBALS->window_search_c_7)); gtk_widget_show (button7); gtk_tooltips_set_tip_2(button7, "Unhighlight all signals listed in the match window."); 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_set_border_width (GTK_CONTAINER (frameh), 3); gtk_widget_show(frameh); XXX_gtk_table_attach (XXX_GTK_TABLE (table), frameh, 0, 1, 255, 256, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); hbox = XXX_gtk_hbox_new (FALSE, 1); gtk_widget_show (hbox); button1 = gtk_button_new_with_label ("Append"); gtk_container_set_border_width (GTK_CONTAINER (button1), 3); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button1), "clicked",G_CALLBACK(ok_callback),XXX_GTK_OBJECT (GLOBALS->window_search_c_7)); gtk_widget_show (button1); gtk_tooltips_set_tip_2(button1, "Add selected signals to end of the display on the main window."); gtk_box_pack_start (GTK_BOX (hbox), button1, TRUE, FALSE, 0); button2 = gtk_button_new_with_label (" Insert "); gtk_container_set_border_width (GTK_CONTAINER (button2), 3); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button2), "clicked",G_CALLBACK(insert_callback),XXX_GTK_OBJECT (GLOBALS->window_search_c_7)); gtk_widget_show (button2); gtk_tooltips_set_tip_2(button2, "Add selected signals after last highlighted signal on the main window."); 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_set_border_width (GTK_CONTAINER (button3), 3); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button3), "clicked",G_CALLBACK(bundle_callback_up),XXX_GTK_OBJECT (GLOBALS->window_search_c_7)); gtk_widget_show (button3); gtk_tooltips_set_tip_2(button3, "Bundle selected signals into a single bit vector with the topmost selected signal as the LSB and the lowest as the MSB."); gtk_box_pack_start (GTK_BOX (hbox), button3, TRUE, FALSE, 0); button3a = gtk_button_new_with_label (" Bundle Down "); gtk_container_set_border_width (GTK_CONTAINER (button3a), 3); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button3a), "clicked",G_CALLBACK(bundle_callback_down),XXX_GTK_OBJECT (GLOBALS->window_search_c_7)); gtk_widget_show (button3a); gtk_tooltips_set_tip_2(button3a, "Bundle selected signals into a single bit vector with the topmost selected signal as the MSB and the lowest as the LSB."); gtk_box_pack_start (GTK_BOX (hbox), button3a, TRUE, FALSE, 0); } button4 = gtk_button_new_with_label (" Replace "); gtk_container_set_border_width (GTK_CONTAINER (button4), 3); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button4), "clicked",G_CALLBACK(replace_callback),XXX_GTK_OBJECT (GLOBALS->window_search_c_7)); gtk_widget_show (button4); gtk_tooltips_set_tip_2(button4, "Replace highlighted signals on the main window with signals selected above."); gtk_box_pack_start (GTK_BOX (hbox), button4, TRUE, FALSE, 0); button5 = gtk_button_new_with_label (" Exit "); gtk_container_set_border_width (GTK_CONTAINER (button5), 3); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button5), "clicked",G_CALLBACK(destroy_callback),XXX_GTK_OBJECT (GLOBALS->window_search_c_7)); gtk_tooltips_set_tip_2(button5, "Do nothing and return to the main window."); 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-gtk3-3.3.125/src/simplereq.h0000664000175000017500000000074215047725112016461 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_SIMPLEREQ_H #define WAVE_SIMPLEREQ_H void simplereqbox(char *title, int width, char *default_text, char *oktext, char *canceltext, GCallback func, int is_alert); #endif gtkwave-gtk3-3.3.125/src/currenttime.h0000664000175000017500000000354515047725112017025 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2016 * * 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-gtk3-3.3.125/src/renderopt.h0000664000175000017500000000060215047725112016455 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-gtk3-3.3.125/src/zoombuttons.h0000664000175000017500000000147615047725112017070 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-gtk3-3.3.125/src/search.h0000664000175000017500000000107015047725112015720 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_SEARCHBOX_H #define WAVE_SEARCHBOX_H void searchbox(char *title, GCallback func); void search_enter_callback(GtkWidget *widget, GtkWidget *do_warning); void search_insert_callback(GtkWidget *widget, char is_prepend); int searchbox_is_active(void); #endif gtkwave-gtk3-3.3.125/src/vcd_saver.c0000664000175000017500000011113015047725112016421 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 /* can't use WAVE_NODEVARTYPE_STR because it has shorthand versions of various types which will fail to parse as VCD times with the VCD loaders */ WAVE_NODEVARTYPE_VCD_SAVER_STR static unsigned int vartype_bounds_fix(unsigned int vt) { return( ((vt > ND_UNSPECIFIED_DEFAULT) && (vt <= ND_VARTYPE_MAX)) ? vt : ND_VCD_WIRE); /* GHW was printing "" for vartype */ } static void w32redirect_fprintf(int is_trans, FILE *sfd, const char *format, ...) { #if defined __MINGW32__ if(is_trans) { char buf[16385]; BOOL bSuccess; DWORD dwWritten; va_list ap; va_start(ap, format); buf[0] = 0; vsprintf(buf, format, ap); bSuccess = WriteFile((HANDLE)sfd, buf, strlen(buf), &dwWritten, NULL); va_end(ap); } else #else (void) is_trans; #endif { 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); } static int vcdsav_tree_node_compare(const void *s1, const void *s2) { vcdsav_Tree *v1, *v2; v1=*((vcdsav_Tree **)s1); v2=*((vcdsav_Tree **)s2); return(v1->val - v2->val); /* emit in node add order seems good enough to maintain bitblasting order instead of something like (-sigcmp(v1->item->nname, v2->item->nname)) working directly on names */ } /* * 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); int is_trans = (export_typ == WAVE_EXPORT_TRANS); int dumpvars_state = 0; 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; unsigned char bitblasted = 0; if(n->head.next) if(n->head.next->next) { flags = n->head.next->next->flags; } /* look to see if we need to emit all bits of a bitblasted vector in order for completeness */ if(n->msi == n->lsi) /* single bit */ { char *lb = strrchr(n->nname, '['); if(lb) { if(!strrchr(n->nname, ':')); /* look for bitblasting */ { char *rb = strchr(lb+1, ']'); if(rb && !(*(rb+1))) /* ensure is at the end so it's not part of a generate index */ { struct symbol *v = symfind(n->nname, NULL); if(v->vec_root) { v = v->vec_root; while(v) { vt = vcdsav_splay(v->n, vt); if(!vt || vt->item != v->n) { bitblasted = 1; flags = 0; if(v->n->head.next) if(v->n->head.next->next) { flags = v->n->head.next->next->flags; } vt = vcdsav_insert(v->n, vt, ++nodecnt, flags, &v->n->head); } v = v->vec_chain; } } } } } } if(!bitblasted) { vt = vcdsav_insert(n, vt, ++nodecnt, flags, &n->head); } } } } else { bvptr b = t->n.vec; if(b) { bptr bt = b->bits; if(bt) { struct symbol *vr = NULL; /* used to keep from having to go O(n**2) in worst case across bt->nnbits when bitblasted */ 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; unsigned char bitblasted = 0; if(n->head.next) if(n->head.next->next) { flags = n->head.next->next->flags; } /* look to see if we need to emit all bits of a bitblasted vector in order for completeness */ if(n->msi == n->lsi) /* single bit */ { char *lb = strrchr(n->nname, '['); if(lb) { if(!strrchr(n->nname, ':')); /* look for bitblasting */ { char *rb = strchr(lb+1, ']'); if(rb && !(*(rb+1))) /* ensure is at the end so it's not part of a generate index */ { struct symbol *v = symfind(n->nname, NULL); if((v->vec_root) && (v->vec_root != vr)) { v = vr = v->vec_root; while(v) { vt = vcdsav_splay(v->n, vt); if(!vt || vt->item != v->n) { bitblasted = 1; flags = 0; if(v->n->head.next) if(v->n->head.next->next) { flags = v->n->head.next->next->flags; } vt = vcdsav_insert(v->n, vt, ++nodecnt, flags, &v->n->head); } v = v->vec_chain; } } } } } } if(!bitblasted) { 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(is_trans, GLOBALS->f_vcd_saver_c_1, "$date\n"); w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "\t%s",asctime(localtime(&walltime))); w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "$end\n"); w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "$version\n\t"WAVE_VERSION_INFO"\n$end\n"); w32redirect_fprintf(is_trans, 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(is_trans, GLOBALS->f_vcd_saver_c_1, "$timezero\n\t"TTFormat"\n$end\n",GLOBALS->global_time_offset); } } else { w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "$comment data_start %p $end\n", (void *)trans_head); /* arbitrary hex identifier */ w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "$comment name %s $end\n", trans_head->name ? trans_head->name : "UNKNOWN"); w32redirect_fprintf(is_trans, 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(is_trans, GLOBALS->f_vcd_saver_c_1, "$timezero "TTFormat" $end\n",GLOBALS->global_time_offset); } w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "$comment min_time "TTFormat" $end\n", GLOBALS->min_time / GLOBALS->time_scale); w32redirect_fprintf(is_trans, 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(is_trans, GLOBALS->f_vcd_saver_c_1, "$comment max_seqn %d $end\n", nodecnt); if(t && t->transaction_args) { w32redirect_fprintf(is_trans, 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); qsort(GLOBALS->hp_vcd_saver_c_1, nodecnt, sizeof(vcdsav_Tree *), vcdsav_tree_node_compare); /* reconstruct array in order vcdsav_insert() was called to get bit ordering back */ for(i=0;ihp_vcd_saver_c_1[i]->item->nname, &was_packed); char *netname = lxt ? hname : output_hier(is_trans, hname); if(export_typ == WAVE_EXPORT_TRANS) { w32redirect_fprintf(is_trans, 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) ? vartype_vcd_saver_strings[ND_GEN_STRING] : vartype_vcd_saver_strings[ND_VCD_REAL]; int tlen = (GLOBALS->hp_vcd_saver_c_1[i]->flags & HIST_STRING) ? 0 : 1; w32redirect_fprintf(is_trans, 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(is_trans, GLOBALS->f_vcd_saver_c_1, "$var %s 1 %s %s $end\n", vartype_vcd_saver_strings[vartype_bounds_fix(GLOBALS->hp_vcd_saver_c_1[i]->item->vartype)], 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(is_trans, GLOBALS->f_vcd_saver_c_1, "$var %s %d %s %s $end\n", vartype_vcd_saver_strings[vartype_bounds_fix(GLOBALS->hp_vcd_saver_c_1[i]->item->vartype)], 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(is_trans, ""); free_hier(); w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "$enddefinitions $end\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 { if(dumpvars_state == 1) { w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "$end\n"); dumpvars_state = 2; } w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "#"TTFormat"\n", tnorm); if(!dumpvars_state) { w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "$dumpvars\n"); dumpvars_state = 1; } } 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(is_trans, 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(is_trans, 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(is_trans, 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(is_trans, 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(is_trans, 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 { if(dumpvars_state == 1) { w32redirect_fprintf(is_trans, GLOBALS->f_vcd_saver_c_1, "$end\n"); dumpvars_state = 2; } w32redirect_fprintf(is_trans, 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(is_trans, GLOBALS->f_vcd_saver_c_1, "$comment data_end %p $end\n", (void *)trans_head); /* arbitrary hex identifier */ #if !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(int is_trans, struct namehier *nh1, struct namehier *nh2) { /* struct namehier *nhtemp; */ /* scan-build */ if(!nh2) { while((nh1)&&(nh1->not_final)) { w32redirect_fprintf(is_trans, 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(is_trans, 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(is_trans, 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(is_trans, 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(is_trans, 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(int is_trans, 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(is_trans, 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(0, 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(0, 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(0, 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(0, 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(0, 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(0, 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(0, 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(0, 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(0, 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(0, 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-gtk3-3.3.125/src/hiersearch.c0000664000175000017500000007702715047725112016602 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 "gtk23compat.h" #include "analyzer.h" #include "symbol.h" #include "lx2.h" #include "vcd.h" #include "busy.h" #include "debug.h" enum { NAME_COLUMN, PTR_COLUMN, N_COLUMNS }; int hier_searchbox_is_active(void) { return(GLOBALS->is_active_hiersearch_c_1); } void refresh_hier_tree(struct tree *t) { struct tree *t2; int len; static char *dotdot=".."; struct treechain *tc; GtkTreeIter iter; gtk_list_store_clear (GTK_LIST_STORE(GLOBALS->sig_store_hiersearch)); GLOBALS->num_rows_hiersearch_c_1=0; 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 */ } gtk_list_store_prepend (GTK_LIST_STORE(GLOBALS->sig_store_hiersearch), &iter); gtk_list_store_set (GTK_LIST_STORE(GLOBALS->sig_store_hiersearch), &iter, NAME_COLUMN, tmp, PTR_COLUMN, t2, -1); } 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 */ } gtk_list_store_prepend (GTK_LIST_STORE(GLOBALS->sig_store_hiersearch), &iter); gtk_list_store_set (GTK_LIST_STORE(GLOBALS->sig_store_hiersearch), &iter, NAME_COLUMN, tmp, PTR_COLUMN, t2, -1); 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); gtk_list_store_prepend (GTK_LIST_STORE(GLOBALS->sig_store_hiersearch), &iter); gtk_list_store_set (GTK_LIST_STORE(GLOBALS->sig_store_hiersearch), &iter, NAME_COLUMN, tmp, PTR_COLUMN, t2, -1); GLOBALS->num_rows_hiersearch_c_1++; } t2=t2->next; } } if(t!=GLOBALS->treeroot) { gtk_list_store_prepend (GTK_LIST_STORE(GLOBALS->sig_store_hiersearch), &iter); gtk_list_store_set (GTK_LIST_STORE(GLOBALS->sig_store_hiersearch), &iter, NAME_COLUMN, dotdot, PTR_COLUMN, NULL, -1); GLOBALS->num_rows_hiersearch_c_1++; } 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, GCallback 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) { XXX_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_size_request( GTK_WIDGET (GLOBALS->window1_hiersearch_c_1), width, 60); gtk_window_set_title(GTK_WINDOW (GLOBALS->window1_hiersearch_c_1), title); gtkwave_signal_connect(XXX_GTK_OBJECT (GLOBALS->window1_hiersearch_c_1), "delete_event",(GCallback) destroy_callback_e, NULL); vbox = XXX_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 = X_gtk_entry_new_with_max_length (maxch); gtkwave_signal_connect(XXX_GTK_OBJECT(GLOBALS->entry_hiersearch_c_2), "activate",G_CALLBACK(enter_callback_e),GLOBALS->entry_hiersearch_c_2); gtk_entry_set_text (GTK_ENTRY (GLOBALS->entry_hiersearch_c_2), default_text); gtk_editable_select_region (GTK_EDITABLE (GLOBALS->entry_hiersearch_c_2),0, gtk_entry_get_text_length(GTK_ENTRY(GLOBALS->entry_hiersearch_c_2))); gtk_box_pack_start (GTK_BOX (vbox), GLOBALS->entry_hiersearch_c_2, TRUE, TRUE, 0); gtk_widget_show (GLOBALS->entry_hiersearch_c_2); hbox = XXX_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_size_request(button1, 100, -1); gtkwave_signal_connect(XXX_GTK_OBJECT (button1), "clicked", G_CALLBACK(enter_callback_e), NULL); gtk_widget_show (button1); gtk_container_add (GTK_CONTAINER (hbox), button1); gtk_widget_set_can_default (button1, TRUE); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button1), "realize", (GCallback) gtk_widget_grab_default, XXX_GTK_OBJECT (button1)); button2 = gtk_button_new_with_label ("Cancel"); gtk_widget_set_size_request(button2, 100, -1); gtkwave_signal_connect(XXX_GTK_OBJECT (button2), "clicked", G_CALLBACK(destroy_callback_e), NULL); gtk_widget_set_can_default (button2, TRUE); 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); } /***************************************************************************/ void recurse_fetch_high_low(struct tree *t) { top: if(t->t_which >= 0) { if(t->t_which > GLOBALS->fetchhigh) GLOBALS->fetchhigh = t->t_which; if(GLOBALS->fetchlow < 0) { GLOBALS->fetchlow = t->t_which; } else if(t->t_which < GLOBALS->fetchlow) { GLOBALS->fetchlow = t->t_which; } } if(t->child) { recurse_fetch_high_low(t->child); } if(t->next) { t = t->next; goto top; } } /* 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); } } } static void ok_callback(GtkWidget *widget, GtkWidget *nothing) { (void)nothing; int i; if((!GLOBALS->h_selectedtree_hiersearch_c_1)||(!GLOBALS->h_selectedtree_hiersearch_c_1->child)) return; set_window_busy(widget); GLOBALS->fetchlow = GLOBALS->fetchhigh = -1; recurse_fetch_high_low(GLOBALS->h_selectedtree_hiersearch_c_1->child); for(i=GLOBALS->fetchlow;i<=GLOBALS->fetchhigh;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=GLOBALS->fetchlow;i<=GLOBALS->fetchhigh;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=GLOBALS->fetchlow;i<=GLOBALS->fetchhigh;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)||(!GLOBALS->h_selectedtree_hiersearch_c_1->child)) return; memcpy(&tcache,&GLOBALS->traces,sizeof(Traces)); GLOBALS->traces.total=0; GLOBALS->traces.first=GLOBALS->traces.last=NULL; set_window_busy(widget); GLOBALS->fetchlow = GLOBALS->fetchhigh = -1; recurse_fetch_high_low(GLOBALS->h_selectedtree_hiersearch_c_1->child); for(i=GLOBALS->fetchlow;i<=GLOBALS->fetchhigh;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=GLOBALS->fetchlow;i<=GLOBALS->fetchhigh;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=GLOBALS->fetchlow;i<=GLOBALS->fetchhigh;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)||(!GLOBALS->h_selectedtree_hiersearch_c_1->child)) return; memcpy(&tcache,&GLOBALS->traces,sizeof(Traces)); GLOBALS->traces.total=0; GLOBALS->traces.first=GLOBALS->traces.last=NULL; set_window_busy(widget); GLOBALS->fetchlow = GLOBALS->fetchhigh = -1; recurse_fetch_high_low(GLOBALS->h_selectedtree_hiersearch_c_1->child); for(i=GLOBALS->fetchlow;i<=GLOBALS->fetchhigh;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=GLOBALS->fetchlow;i<=GLOBALS->fetchhigh;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=GLOBALS->fetchlow;i<=GLOBALS->fetchhigh;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,G_CALLBACK(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 gboolean select_row_callback(struct tree *t) { int rt = TRUE; 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); rt = FALSE; } } 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); rt = FALSE; } } return(rt); } static gboolean unselect_row_callback(struct tree *t) { GLOBALS->h_selectedtree_hiersearch_c_1=NULL; if(t) { DEBUG(printf("Unselected: %s\n",t->name)); } else { /* just ignore */ } return(TRUE); } static gboolean XXX_view_selection_func (GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean path_currently_selected, gpointer userdata) { (void) selection; (void) userdata; GtkTreeIter iter; char *nam = NULL; struct tree *t = NULL; gboolean rt = TRUE; if(path) { if (gtk_tree_model_get_iter(model, &iter, path)) /* null return should not happen */ { gtk_tree_model_get(model, &iter, NAME_COLUMN, &nam, PTR_COLUMN, &t, -1); if(!path_currently_selected) { #ifdef WAVE_GTK3_HIERSEARCH_DEBOUNCE /* updating tree can sometimes retrigger XXX_view_selection_func() */ if(!GLOBALS->h_debounce) { GLOBALS->h_debounce = 1; rt = select_row_callback(t); GLOBALS->h_debounce = 0; } #else rt = select_row_callback(t); #endif } else { rt = unselect_row_callback(t); } } } return(rt); /* TRUE if tree updated causes crash */ } 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, GCallback 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; /* fix problem where ungrab doesn't occur if button pressed + simultaneous accelerator key occurs */ if(GLOBALS->in_button_press_wavewindow_c_1) { XXX_gdk_pointer_ungrab(GDK_CURRENT_TIME); } if(GLOBALS->is_active_hiersearch_c_1) { gdk_window_raise(gtk_widget_get_window(GLOBALS->window_hiersearch_c_3)); 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(XXX_GTK_OBJECT (GLOBALS->window_hiersearch_c_3), "delete_event",(GCallback) destroy_callback, NULL); table = XXX_gtk_table_new (256, 1, FALSE); gtk_widget_show (table); vbox1 = XXX_gtk_vbox_new (FALSE, 0); gtk_container_set_border_width (GTK_CONTAINER (vbox1), 3); gtk_widget_show (vbox1); frame1 = gtk_frame_new (NULL); gtk_container_set_border_width (GTK_CONTAINER (frame1), 3); gtk_widget_show(frame1); XXX_gtk_table_attach (XXX_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_editable_set_editable(GTK_EDITABLE(GLOBALS->entry_main_hiersearch_c_1), FALSE); gtk_widget_show (GLOBALS->entry_main_hiersearch_c_1); gtk_tooltips_set_tip_2(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."); 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_set_border_width (GTK_CONTAINER (frame2), 3); gtk_widget_show(frame2); XXX_gtk_table_attach (XXX_GTK_TABLE (table), frame2, 0, 1, 1, 254, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); GLOBALS->sig_store_hiersearch = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_POINTER); GtkWidget *sig_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (GLOBALS->sig_store_hiersearch)); /* The view now holds a reference. We can get rid of our own reference */ g_object_unref (G_OBJECT (GLOBALS->sig_store_hiersearch)); GtkCellRenderer *renderer = gtk_cell_renderer_text_new (); GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes (titles[0], renderer, "text", NAME_COLUMN, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (sig_view), column); /* Setup the selection handler */ GLOBALS->sig_selection_hiersearch = gtk_tree_view_get_selection (GTK_TREE_VIEW (sig_view)); gtk_tree_selection_set_mode (GLOBALS->sig_selection_hiersearch, GTK_SELECTION_SINGLE); gtk_tree_selection_set_select_function (GLOBALS->sig_selection_hiersearch, XXX_view_selection_func, NULL, NULL); gtk_list_store_clear (GTK_LIST_STORE(GLOBALS->sig_store_hiersearch)); gtk_widget_show (sig_view); 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_size_request( 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), sig_view); gtk_container_add (GTK_CONTAINER (frame2), scrolled_win); frameh = gtk_frame_new (NULL); gtk_container_set_border_width (GTK_CONTAINER (frameh), 3); gtk_widget_show(frameh); XXX_gtk_table_attach (XXX_GTK_TABLE (table), frameh, 0, 1, 255, 256, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); hbox = XXX_gtk_hbox_new (FALSE, 1); gtk_widget_show (hbox); button1 = gtk_button_new_with_label ("Append"); gtk_container_set_border_width (GTK_CONTAINER (button1), 3); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button1), "clicked",G_CALLBACK(ok_callback),XXX_GTK_OBJECT (GLOBALS->window_hiersearch_c_3)); gtk_widget_show (button1); gtk_tooltips_set_tip_2(button1, "Add selected signals to end of the display on the main window."); gtk_box_pack_start (GTK_BOX (hbox), button1, TRUE, FALSE, 0); button2 = gtk_button_new_with_label (" Insert "); gtk_container_set_border_width (GTK_CONTAINER (button2), 3); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button2), "clicked",G_CALLBACK(insert_callback),XXX_GTK_OBJECT (GLOBALS->window_hiersearch_c_3)); gtk_widget_show (button2); gtk_tooltips_set_tip_2(button2, "Add children after last highlighted signal on the main window."); 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_set_border_width (GTK_CONTAINER (button3), 3); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button3), "clicked",G_CALLBACK(bundle_callback_up),XXX_GTK_OBJECT (GLOBALS->window_hiersearch_c_3)); gtk_widget_show (button3); gtk_tooltips_set_tip_2(button3, "Bundle children into a single bit vector with the topmost signal as the LSB and the lowest as the MSB."); gtk_box_pack_start (GTK_BOX (hbox), button3, TRUE, FALSE, 0); button3a = gtk_button_new_with_label (" Bundle Down "); gtk_container_set_border_width (GTK_CONTAINER (button3a), 3); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button3a), "clicked",G_CALLBACK(bundle_callback_down),XXX_GTK_OBJECT (GLOBALS->window_hiersearch_c_3)); gtk_widget_show (button3a); gtk_tooltips_set_tip_2(button3a, "Bundle children into a single bit vector with the topmost signal as the MSB and the lowest as the LSB."); gtk_box_pack_start (GTK_BOX (hbox), button3a, TRUE, FALSE, 0); } button4 = gtk_button_new_with_label (" Replace "); gtk_container_set_border_width (GTK_CONTAINER (button4), 3); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button4), "clicked",G_CALLBACK(replace_callback),XXX_GTK_OBJECT (GLOBALS->window_hiersearch_c_3)); gtk_widget_show (button4); gtk_tooltips_set_tip_2(button4, "Replace highlighted signals on the main window with children shown above."); gtk_box_pack_start (GTK_BOX (hbox), button4, TRUE, FALSE, 0); button5 = gtk_button_new_with_label (" Exit "); gtk_container_set_border_width (GTK_CONTAINER (button5), 3); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button5), "clicked",G_CALLBACK(destroy_callback),XXX_GTK_OBJECT (GLOBALS->window_hiersearch_c_3)); gtk_tooltips_set_tip_2(button5, "Do nothing and return to the main window."); 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-gtk3-3.3.125/src/vcd_saver.h0000664000175000017500000000161715047725112016436 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(int is_trans, char *name); #endif gtkwave-gtk3-3.3.125/src/hiersearch.h0000664000175000017500000000122715047725112016574 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2010-2017 * * 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, GCallback func); void refresh_hier_tree(struct tree *t); int hier_searchbox_is_active(void); void recurse_fetch_high_low(struct tree *t); struct tree *fetchhigh(struct tree *t); struct tree *fetchlow(struct tree *t); void fetchvex(struct tree *t, char direction); #endif gtkwave-gtk3-3.3.125/src/vcd_partial.c0000664000175000017500000023450415047725112016750 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2017. * * 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 __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 ? ch : -1); } 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 ? ch : -1); } 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 */ GLOBALS->yylen_vcd_partial_c_2=len; if(is_string) { 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==':' && !ignore_colon) 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==':' && !ignore_colon)||(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 ignore_colon, int match_kw) { int ch; int len=0; if(GLOBALS->varsplit_vcd_partial_c_2) { int rc=get_vartoken_patched(ignore_colon, 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==':' && !ignore_colon) 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) { if(!GLOBALS->varsplit_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); } else /* TALOS-2023-1806 */ { int vsplit_len = GLOBALS->varsplit_vcd_partial_c_2 - GLOBALS->yytext_vcd_partial_c_2; /* save old len */ 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); GLOBALS->varsplit_vcd_partial_c_2 = GLOBALS->yytext_vcd_partial_c_2+vsplit_len; /* reconstruct old len in new buffer */ } } 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==':' && !ignore_colon)||(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; } else if(strstr(GLOBALS->yytext_vcd_partial_c_2, "Questa") || strstr(GLOBALS->yytext_vcd_partial_c_2, "ModelSim")) /* realparam fix only is for MTI, conflicts with Vivado */ { GLOBALS->mti_realparam_fix = 1; 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_2<=v->size) /* TALOS-2023-1804 */ { 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; int colon_seen = 0; int num_seen = 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_END && tok != T_EOF) { 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) /* reinstated because of TALOS-2023-1805 */ { 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(255); } 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(0, 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(0, 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(0, 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, 0); if(vtok==V_RB) { v->lsi=v->msi; v->size=1; } else { if(vtok!=V_COLON) goto err; vtok=get_vartoken(0, 0); if(vtok!=V_STRING) goto err; v->lsi=atoi_64(GLOBALS->yytext_vcd_partial_c_2); vtok=get_vartoken(0, 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(1, 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, '\\')) && (v->lsi != GLOBALS->pv_vcd_partial_c_2->lsi)) { 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(0, 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(1, 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) && (v->lsi != GLOBALS->pv_vcd_partial_c_2->lsi)) { 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; num_seen = 0; vtok=get_vartoken(0, 1); if(vtok==V_END) goto dumpv; if(vtok!=V_LB) goto err; colon_seen = 0; vtok=get_vartoken(0, 0); if(vtok!=V_STRING) goto err; num_seen = 1; v->msi=atoi_64(GLOBALS->yytext_vcd_partial_c_2); vtok=get_vartoken(0, 0); if(vtok==V_RB) { v->lsi=v->msi; goto dumpv; } if(vtok!=V_COLON) goto err; colon_seen = 1; vtok=get_vartoken(0, 0); if(vtok!=V_STRING) goto err; v->lsi=atoi_64(GLOBALS->yytext_vcd_partial_c_2); vtok=get_vartoken(0, 0); if(vtok!=V_RB) goto err; } dumpv: if(v->size == 0) { if(v->vartype != V_EVENT) { if(v->vartype != V_STRINGTYPE) { if(!GLOBALS->mti_realparam_fix) { v->size = 1; } else { v->vartype = V_REAL; } } } else { v->size = 1; } } /* MTI fix */ else { unsigned int abslen = (v->msi >= v->lsi) ? (v->msi - v->lsi + 1) : (v->lsi - v->msi + 1); if(!colon_seen) { if(num_seen && (v->size > 1)) { char buf[32]; char *sfix; int vname_len = strlen(v->name); int num_len = snprintf(buf, 32, "[%d]", v->lsi); sfix = malloc_2(vname_len + num_len + 1); memcpy(sfix, v->name, vname_len); memcpy(sfix+vname_len, buf, num_len + 1); free_2(v->name); v->name = sfix; } if(v->size > 1) { v->lsi = 0; v->msi = v->size - 1; } } else { if((v->size != abslen) && (num_seen)) { if(v->lsi < v->msi) { v->msi = v->lsi + v->size - 1; } else { v->lsi = v->msi + v->size - 1; } } } } 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)) { if((v->msi-v->lsi+1) > v->size) /* if() is 2d add */ { 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)) { if((v->lsi-v->msi+1) > v->size) /* if() is 2d add */ { 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))) : remove redundant condition */ if((!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; if(n->curr->v.h_val==heval) { n->curr->flags|=HIST_GLITCH; /* set the glitch flag */ GLOBALS->num_glitch_regions_vcd_recoder_c_4++; } 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)||(v->msi != v->lsi)) { 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); /* 2d add */ 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; } } 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; } } } 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; #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 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(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(); } } 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-gtk3-3.3.125/src/vcd_partial.h0000664000175000017500000000063115047725112016745 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-gtk3-3.3.125/src/interp.c0000664000175000017500000002171715047725112015761 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-gtk3-3.3.125/src/symbol.c0000664000175000017500000001450115047725112015756 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 #include #ifndef __MINGW32__ #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-gtk3-3.3.125/src/interp.h0000664000175000017500000000072715047725112015764 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-gtk3-3.3.125/src/lxt.c0000664000175000017500000020227115047725112015263 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__ #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__ #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__ 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__ { 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__ 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__ FILE *tmp; #endif buf=malloc_2(total_mem); pnt=bufprev=buf; if(GLOBALS->zfacname_size_lxt_c_1) { int rc; #if defined __MINGW32__ 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__ 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__ 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__ 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__ 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__ 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__ 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__ 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__ 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__ 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__ 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__ 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__ { 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__ 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__ 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__ fclose(tmp); #endif } munmap(GLOBALS->mm_lxt_c_1, GLOBALS->f_len_lxt_c_1); #if !defined __MINGW32__ 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__ 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__ 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__ 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(f->flags&(LT_SYM_F_DOUBLE|LT_SYM_F_STRING)) { htemp->v.h_vector = strdup_2((f->flags<_SYM_F_DOUBLE) ? "NaN" : "UNDEF"); htemp->flags = HIST_REAL; if(f->flags<_SYM_F_STRING) htemp->flags |= HIST_STRING; } else { 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(f->flags&(LT_SYM_F_DOUBLE|LT_SYM_F_STRING)) { histent_head->v.h_vector = strdup_2((f->flags<_SYM_F_DOUBLE) ? "NaN" : "UNDEF"); histent_head->flags = HIST_REAL; if(f->flags<_SYM_F_STRING) histent_head->flags |= HIST_STRING; } else { 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-gtk3-3.3.125/src/symbol.h0000664000175000017500000000622215047725112015764 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 */ #include #ifdef HAVE_INTTYPES_H #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-gtk3-3.3.125/src/rgb.c0000664000175000017500000010336515047725112015232 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" struct wave_rgb_color { const char *name; int rgb; }; #define WAVE_RGB_COLOR(_name, r, g, b) { _name, (r << 16) | (g << 8) | b } /* * 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)); } 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 __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); } } wave_rgb_t XXX_get_gc_from_name(char *str) { struct wave_rgb_color *match; wave_rgb_t rc; if((match=(struct wave_rgb_color *)bsearch((void *)str, (void *)colors, C_ARRAY_SIZE, sizeof(struct wave_rgb_color), compar))) { int red, green, blue; red= (match->rgb>>16)&0x000000ff; green=(match->rgb>>8) &0x000000ff; blue= (match->rgb) &0x000000ff; rc.r = (double)red/255; rc.g = (double)green/255; rc.b = (double)blue/255; rc.a = (double)1.0; } else { rc.r = rc.g = rc.b = rc.a = 0.0; } return(rc); } gtkwave-gtk3-3.3.125/src/lxt.h0000664000175000017500000000410415047725112015263 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__ 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-gtk3-3.3.125/src/vcd.c0000664000175000017500000023214015047725112015226 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2017. * * 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 * Backtracking fix 16oct18ajb */ /* 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); memset(GLOBALS->vcdbuf_vcd_c_1, 0, VCD_BSIZ); 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 ? ch : -1); } 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 ? ch : -1); } 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 */ GLOBALS->yylen_vcd_c_1=len; if(is_string) { 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==':' && !ignore_colon) 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==':' && !ignore_colon)||(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 ignore_colon, int match_kw) { int ch; int len=0; if(GLOBALS->varsplit_vcd_c_1) { int rc=get_vartoken_patched(ignore_colon, 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==':' && !ignore_colon) 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) { if(!GLOBALS->varsplit_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); } else /* TALOS-2023-1806 */ { int vsplit_len = GLOBALS->varsplit_vcd_c_1 - GLOBALS->yytext_vcd_c_1; /* save old len */ 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); GLOBALS->varsplit_vcd_c_1 = GLOBALS->yytext_vcd_c_1+vsplit_len; /* reconstruct old len in new buffer */ } } 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==':' && !ignore_colon)||(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; } else if(strstr(GLOBALS->yytext_vcd_c_1, "Questa") || strstr(GLOBALS->yytext_vcd_c_1, "ModelSim")) /* realparam fix only is for MTI, conflicts with Vivado */ { GLOBALS->mti_realparam_fix = 1; 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_1<=v->size) /* TALOS-2023-1804 */ { 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 { if(v->vartype == V_PARAMETER) /* github #446: size 0 on parameter with type declared wrong */ { v->vartype = V_REAL; /* override any data we parsed in for $var declaration */ v->size=1; v->msi=v->lsi=0; fprintf(stderr, "GTKWAVE | Warning: symbol '%s' changing datatype from parameter to real.\n", v->name); } 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; int colon_seen = 0; int num_seen = 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_END && tok != T_EOF) { 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) /* reinstated because of TALOS-2023-1805 */ { 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(0, 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(0, 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(0, 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, 0); if(vtok==V_RB) { v->lsi=v->msi; v->size=1; } else { if(vtok!=V_COLON) goto err; vtok=get_vartoken(0, 0); if(vtok!=V_STRING) goto err; v->lsi=atoi_64(GLOBALS->yytext_vcd_c_1); vtok=get_vartoken(0, 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(1, 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, '\\')) && (v->lsi != GLOBALS->pv_vcd_c_1->lsi)) { 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(0, 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(1, 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) && (v->lsi != GLOBALS->pv_vcd_c_1->lsi)) { 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; num_seen = 0; vtok=get_vartoken(0, 1); if(vtok==V_END) goto dumpv; if(vtok!=V_LB) goto err; colon_seen = 0; vtok=get_vartoken(0, 0); if(vtok!=V_STRING) goto err; num_seen = 1; v->msi=atoi_64(GLOBALS->yytext_vcd_c_1); vtok=get_vartoken(0, 0); if(vtok==V_RB) { v->lsi=v->msi; goto dumpv; } if(vtok!=V_COLON) goto err; colon_seen = 1; vtok=get_vartoken(0, 0); if(vtok!=V_STRING) goto err; v->lsi=atoi_64(GLOBALS->yytext_vcd_c_1); vtok=get_vartoken(0, 0); if(vtok!=V_RB) goto err; } dumpv: if(v->size == 0) { if(v->vartype != V_EVENT) { if(v->vartype != V_STRINGTYPE) { if(!GLOBALS->mti_realparam_fix) { v->size = 1; } else { v->vartype = V_REAL; } } } else { v->size = 1; } } /* MTI fix */ else { unsigned int abslen = (v->msi >= v->lsi) ? (v->msi - v->lsi + 1) : (v->lsi - v->msi + 1); if(!colon_seen) { if(num_seen && (v->size > 1)) { char buf[32]; char *sfix; int vname_len = strlen(v->name); int num_len = snprintf(buf, 32, "[%d]", v->lsi); sfix = malloc_2(vname_len + num_len + 1); memcpy(sfix, v->name, vname_len); memcpy(sfix+vname_len, buf, num_len + 1); free_2(v->name); v->name = sfix; } if(v->size > 1) { v->lsi = 0; v->msi = v->size - 1; } } else { if((v->size != abslen) && (num_seen)) { if(v->lsi < v->msi) { v->msi = v->lsi + v->size - 1; } else { v->lsi = v->msi + v->size - 1; } } } } 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)) { if((v->msi-v->lsi+1) > v->size) /* if() is 2d add */ { 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)) { if((v->lsi-v->msi+1) > v->size) /* if() is 2d add */ { 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; } /* backtracking fix */ else { if(tim < GLOBALS->current_time_vcd_c_1) /* avoid backtracking time counts which can happen on malformed files */ { if(!GLOBALS->vcd_already_backtracked) { GLOBALS->vcd_already_backtracked = 1; fprintf(stderr, "VCDLOAD | Time backtracking detected in VCD file!\n"); } #if 0 tim = GLOBALS->current_time_vcd_c_1; #endif } } 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))) : remove redundant condition */ if((!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")); } } } /*******************************************************************************/ static 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) /* backtracking fix */ { 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; if(n->curr->v.h_val==heval) { n->curr->flags|=HIST_GLITCH; /* set the glitch flag */ GLOBALS->num_glitch_regions_vcd_recoder_c_4++; } 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->flags != (HIST_STRING|HIST_REAL)) /* because n->curr->v.h_vector could be a double and not a pointer */ ||(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) /* backtracking fix */ { 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; } } else { free_2(vector); } } 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) /* backtracking fix */ { 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) /* backtracking fix */ { 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)||(v->msi != v->lsi)) { 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); /* 2d add */ 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; } } 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; } } } 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_san(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-gtk3-3.3.125/src/vcd.h0000664000175000017500000000605015047725112015232 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 #include #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-gtk3-3.3.125/src/ttranslate.c0000664000175000017500000005763615047725112016652 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 "gtk23compat.h" #include "symbol.h" #include "ttranslate.h" #include "pipeio.h" #include "debug.h" enum { NAME_COLUMN, N_COLUMNS }; static gboolean XXX_view_selection_func (GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean path_currently_selected, gpointer userdata) { (void) selection; (void) model; (void) userdata; gint *idx = NULL; if(path) { idx = gtk_tree_path_get_indices (path); if(idx) { if(!path_currently_selected) { GLOBALS->current_filter_ttranslate_c_1 = idx[0] + 1; } else { GLOBALS->current_filter_ttranslate_c_1 = 0; /* none */ } } } return(TRUE); } 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__ cmd = (char *)malloc_2(strlen(exec_name)+6+1); sprintf(cmd, "which %s", exec_name); stream = popen_san(cmd, "r"); result = fscanf(stream, "%s", abs_path); pclose(stream); free_2(cmd); if((strlen(abs_path) == 0)||(!result)) { status_text("Could not find transaction filter process!\n"); return; } #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 add_filter_callback_2(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; int i; 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(gtk_widget_get_window(GLOBALS->window_ttranslate_c_5)); 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); GtkTreeIter iter; gtk_list_store_append (GTK_LIST_STORE(GLOBALS->sig_store_ttranslate), &iter); gtk_list_store_set (GTK_LIST_STORE(GLOBALS->sig_store_ttranslate), &iter, NAME_COLUMN, GLOBALS->ttranssel_filter[GLOBALS->num_ttrans_filters], -1); } else { GLOBALS->num_ttrans_filters--; } if(GLOBALS->is_active_ttranslate_c_2) gdk_window_raise(gtk_widget_get_window(GLOBALS->window_ttranslate_c_5)); } 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,G_CALLBACK(add_filter_callback_2), G_CALLBACK(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; GtkWidget *label; GtkWidget *entry; if(GLOBALS->is_active_ttranslate_c_2) { gdk_window_raise(gtk_widget_get_window(GLOBALS->window_ttranslate_c_5)); 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(XXX_GTK_OBJECT (GLOBALS->window_ttranslate_c_5), "delete_event",(GCallback) destroy_callback, NULL); table = XXX_gtk_table_new (256, 1, FALSE); gtk_widget_show (table); vbox1 = XXX_gtk_vbox_new (FALSE, 0); gtk_container_set_border_width (GTK_CONTAINER (vbox1), 3); gtk_widget_show (vbox1); frame2 = gtk_frame_new (NULL); gtk_container_set_border_width (GTK_CONTAINER (frame2), 3); gtk_widget_show(frame2); XXX_gtk_table_attach (XXX_GTK_TABLE (table), frame2, 0, 1, 0, 253, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); GLOBALS->sig_store_ttranslate = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING); GtkWidget *sig_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (GLOBALS->sig_store_ttranslate)); /* The view now holds a reference. We can get rid of our own reference */ g_object_unref (G_OBJECT (GLOBALS->sig_store_ttranslate)); GtkCellRenderer *renderer = gtk_cell_renderer_text_new (); GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes (titles[0], renderer, "text", NAME_COLUMN, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (sig_view), column); /* Setup the selection handler */ GLOBALS->sig_selection_ttranslate = gtk_tree_view_get_selection (GTK_TREE_VIEW (sig_view)); gtk_tree_selection_set_mode (GLOBALS->sig_selection_ttranslate, GTK_SELECTION_SINGLE); gtk_tree_selection_set_select_function (GLOBALS->sig_selection_ttranslate, XXX_view_selection_func, NULL, NULL); gtk_list_store_clear (GTK_LIST_STORE(GLOBALS->sig_store_ttranslate)); for(i=0;inum_ttrans_filters;i++) { GtkTreeIter iter; gtk_list_store_append (GTK_LIST_STORE(GLOBALS->sig_store_ttranslate), &iter); gtk_list_store_set (GTK_LIST_STORE(GLOBALS->sig_store_ttranslate), &iter, NAME_COLUMN, GLOBALS->ttranssel_filter[i+1], -1); } gtk_widget_show (sig_view); 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_size_request( 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), sig_view); gtk_container_add (GTK_CONTAINER (frame2), scrolled_win); frameh0 = gtk_frame_new (NULL); gtk_container_set_border_width (GTK_CONTAINER (frameh0), 3); gtk_widget_show(frameh0); XXX_gtk_table_attach (XXX_GTK_TABLE (table), frameh0, 0, 1, 253, 254, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); hbox0 = XXX_gtk_hbox_new (FALSE, 1); gtk_widget_show (hbox0); button6 = gtk_button_new_with_label (" Add Trans Filter to List "); gtk_container_set_border_width (GTK_CONTAINER (button6), 3); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button6), "clicked",G_CALLBACK(add_filter_callback),XXX_GTK_OBJECT (GLOBALS->window_ttranslate_c_5)); gtk_widget_show (button6); gtk_tooltips_set_tip_2(button6, "Bring up a file requester to add a transaction process filter to the filter select window."); 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_set_border_width (GTK_CONTAINER (frameh0), 3); gtk_widget_show(frameh0); XXX_gtk_table_attach (XXX_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=X_gtk_entry_new_with_max_length(1025); gtk_entry_set_text(GTK_ENTRY(entry), GLOBALS->ttranslate_args ? GLOBALS->ttranslate_args : ""); g_signal_connect (XXX_GTK_OBJECT (entry), "activate",G_CALLBACK (args_entry_callback), entry); g_signal_connect (XXX_GTK_OBJECT (entry), "changed",G_CALLBACK (args_entry_callback), entry); hbox0=XXX_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_set_border_width (GTK_CONTAINER (frameh), 3); gtk_widget_show(frameh); XXX_gtk_table_attach (XXX_GTK_TABLE (table), frameh, 0, 1, 255, 256, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); hbox = XXX_gtk_hbox_new (FALSE, 1); gtk_widget_show (hbox); button1 = gtk_button_new_with_label (" OK "); gtk_container_set_border_width (GTK_CONTAINER (button1), 3); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button1), "clicked",G_CALLBACK(ok_callback),XXX_GTK_OBJECT (GLOBALS->window_ttranslate_c_5)); gtk_widget_show (button1); gtk_tooltips_set_tip_2(button1, "Add selected signals to end of the display on the main window."); #if GTK_CHECK_VERSION(3,0,0) gtk_box_pack_start(GTK_BOX(hbox), button1, TRUE, TRUE, 0); #else gtk_box_pack_start (GTK_BOX (hbox), button1, TRUE, FALSE, 0); #endif button5 = gtk_button_new_with_label (" Cancel "); gtk_container_set_border_width (GTK_CONTAINER (button5), 3); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button5), "clicked",G_CALLBACK(destroy_callback),XXX_GTK_OBJECT (GLOBALS->window_ttranslate_c_5)); gtk_tooltips_set_tip_2(button5, "Do nothing and return to the main window."); gtk_widget_show (button5); #if GTK_CHECK_VERSION(3,0,0) gtk_box_pack_start(GTK_BOX(hbox), button5, TRUE, TRUE, 0); #else gtk_box_pack_start (GTK_BOX (hbox), button5, TRUE, FALSE, 0); #endif gtk_container_add (GTK_CONTAINER (frameh), hbox); gtk_container_add (GTK_CONTAINER (GLOBALS->window_ttranslate_c_5), table); gtk_widget_set_size_request(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 __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 __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-gtk3-3.3.125/src/edgebuttons.c0000664000175000017500000003227615047725112017005 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_set_value(GTK_ADJUSTMENT(GLOBALS->wave_hslider), 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; pixmapwid1=gtk_image_new_from_pixbuf(GLOBALS->larrow_pixbuf); gtk_widget_show(pixmapwid1); pixmapwid2=gtk_image_new_from_pixbuf(GLOBALS->rarrow_pixbuf); gtk_widget_show(pixmapwid2); /* Create a table to hold the text widget and scrollbars */ table = XXX_gtk_table_new (1, 1, FALSE); main_vbox = XXX_gtk_vbox_new (FALSE, 1); gtk_container_set_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 = XXX_gtk_table_new (2, 1, FALSE); b1 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b1), pixmapwid1); XXX_gtk_table_attach (XXX_GTK_TABLE (table2), b1, 0, 1, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); g_signal_connect_swapped (XXX_GTK_OBJECT (b1), "clicked", G_CALLBACK(service_left_edge), XXX_GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(b1, "Find next transition of highlighted trace scanning left"); gtk_widget_show(b1); b2 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b2), pixmapwid2); XXX_gtk_table_attach (XXX_GTK_TABLE (table2), b2, 0, 1, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); g_signal_connect_swapped (XXX_GTK_OBJECT (b2), "clicked", G_CALLBACK(service_right_edge), XXX_GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(b2, "Find next transition of highlighted trace scanning right"); gtk_widget_show(b2); gtk_container_add (GTK_CONTAINER (frame), table2); gtk_widget_show(table2); return(table); } gtkwave-gtk3-3.3.125/src/mouseover.c0000664000175000017500000003726515047725112016511 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2006-2016. * * 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(Trptr t, char *ch) { TraceFlagsType 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_FFO) != 0) { ch[pos++] = 'f'; } /* [15] */ if((flags & TR_POPCNT) != 0) { ch[pos++] = 'p'; } /* [16] */ if((flags & TR_FPDECSHIFT) != 0) { int ln = sprintf(ch+pos, "s(%d)", t->t_fpdecshift); pos += ln; } /* [17+] */ 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; } /************************************************************************************************/ #if GTK_CHECK_VERSION(3,0,0) static gint draw_event(GtkWidget *widget, cairo_t *cr, gpointer user_data) { (void) widget; (void) user_data; cairo_set_source_surface(cr, GLOBALS->surface_mo_pixmap_mouseover_c_1, 0, 0); cairo_paint (cr); return(FALSE); } #else static gint expose_event(GtkWidget *widget, GdkEventExpose *event) { #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX GdkDrawingContext *gdc; #endif cairo_t* cr = XXX_gdk_cairo_create (XXX_GDK_DRAWABLE (gtk_widget_get_window(widget)), &gdc); gdk_cairo_region (cr, event->region); cairo_clip (cr); cairo_set_source_surface(cr, GLOBALS->surface_mo_pixmap_mouseover_c_1, 0, 0); cairo_paint (cr); #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX gdk_window_end_draw_frame(gtk_widget_get_window(widget), gdc); #else cairo_destroy (cr); #endif return(FALSE); } #endif 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; #ifdef GDK_WINDOWING_WAYLAND if(GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default())) { GLOBALS->mo_area_mouseover_c_1=gtk_drawing_area_new(); gtk_widget_show(GLOBALS->mo_area_mouseover_c_1); GLOBALS->mouseover_mouseover_c_1 = gtk_window_new (GTK_WINDOW_POPUP); gtk_window_group_add_window (gtk_window_get_group (GTK_WINDOW(GLOBALS->mainwindow)), GTK_WINDOW (GLOBALS->mouseover_mouseover_c_1)); gtk_window_set_transient_for (GTK_WINDOW (GLOBALS->mouseover_mouseover_c_1), GTK_WINDOW(GLOBALS->mainwindow)); gtk_container_add(GTK_CONTAINER(GLOBALS->mouseover_mouseover_c_1), GLOBALS->mo_area_mouseover_c_1); gtk_widget_realize (GLOBALS->mouseover_mouseover_c_1); gtk_window_set_type_hint (GTK_WINDOW (GLOBALS->mouseover_mouseover_c_1), GDK_WINDOW_TYPE_HINT_POPUP_MENU); gtk_window_move (GTK_WINDOW (GLOBALS->mouseover_mouseover_c_1), x, y); gtk_window_resize (GTK_WINDOW (GLOBALS->mouseover_mouseover_c_1), width, height); gtk_widget_show (GTK_WIDGET (GLOBALS->mouseover_mouseover_c_1)); } else #endif { 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); 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); 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); } GtkAllocation allocation; gtk_widget_get_allocation(GLOBALS->mouseover_mouseover_c_1, &allocation); GLOBALS->surface_mo_pixmap_mouseover_c_1 = cairo_image_surface_create (CAIRO_FORMAT_RGB24, allocation.width, allocation.height); GLOBALS->cr_mo_pixmap_mouseover_c_1 = cairo_create (GLOBALS->surface_mo_pixmap_mouseover_c_1); cairo_set_line_width(GLOBALS->cr_mo_pixmap_mouseover_c_1, 1.0); GLOBALS->rgb_mo_dk_gray_mouseover_c_1 = XXX_alloc_color(0x00cccccc); GLOBALS->rgb_mo_black_mouseover_c_1 = XXX_alloc_color(0x00000000); XXX_gdk_draw_rectangle(GLOBALS->cr_mo_pixmap_mouseover_c_1, GLOBALS->rgb_mo_dk_gray_mouseover_c_1, TRUE, 0,0, GLOBALS->mo_width_mouseover_c_1, GLOBALS->mo_height_mouseover_c_1); XXX_gdk_draw_rectangle(GLOBALS->cr_mo_pixmap_mouseover_c_1, GLOBALS->rgb_mo_dk_gray_mouseover_c_1, TRUE, 1,1, GLOBALS->mo_width_mouseover_c_1-2, GLOBALS->mo_height_mouseover_c_1-2); #if GTK_CHECK_VERSION(3,0,0) g_signal_connect(XXX_GTK_OBJECT(GLOBALS->mo_area_mouseover_c_1), "draw",G_CALLBACK(draw_event), NULL); #else g_signal_connect(XXX_GTK_OBJECT(GLOBALS->mo_area_mouseover_c_1), "expose_event",G_CALLBACK(expose_event), NULL); #endif } #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]; #ifdef GDK_WINDOWING_WAYLAND static int waycnt = 0; if(GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default())) { waycnt++; } #endif if(GLOBALS->disable_mouseover) { if(GLOBALS->mouseover_mouseover_c_1) { gtk_widget_destroy(GLOBALS->mouseover_mouseover_c_1); GLOBALS->mouseover_mouseover_c_1 = NULL; if(GLOBALS->cr_mo_pixmap_mouseover_c_1) { cairo_destroy(GLOBALS->cr_mo_pixmap_mouseover_c_1); GLOBALS->cr_mo_pixmap_mouseover_c_1 = NULL; } if(GLOBALS->surface_mo_pixmap_mouseover_c_1) { cairo_surface_destroy(GLOBALS->surface_mo_pixmap_mouseover_c_1); GLOBALS->surface_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; if(GLOBALS->clipboard_mouseover) { GdkDisplay *g = gdk_display_get_default(); GtkClipboard *clip; if(t->name) { clip = gtk_clipboard_get_for_display (g, GDK_SELECTION_PRIMARY); /* middle mouse button */ gtk_clipboard_set_text (clip, t->name, strlen(t->name)); } clip = gtk_clipboard_get_for_display (g, GDK_SELECTION_CLIPBOARD); /* ctrl-c/ctrl-v */ gtk_clipboard_set_text (clip, asciivalue ? asciivalue : "", value_charlen); } name_charlen = t->name ? strlen(t->name) : 0; if(name_charlen) { int len = determine_trace_flags(t, 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; if(GLOBALS->cr_mo_pixmap_mouseover_c_1) { cairo_destroy(GLOBALS->cr_mo_pixmap_mouseover_c_1); GLOBALS->cr_mo_pixmap_mouseover_c_1 = NULL; } if(GLOBALS->surface_mo_pixmap_mouseover_c_1) { cairo_surface_destroy(GLOBALS->surface_mo_pixmap_mouseover_c_1); GLOBALS->surface_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; if(GLOBALS->cr_mo_pixmap_mouseover_c_1) { cairo_destroy(GLOBALS->cr_mo_pixmap_mouseover_c_1); GLOBALS->cr_mo_pixmap_mouseover_c_1 = NULL; } if(GLOBALS->surface_mo_pixmap_mouseover_c_1) { cairo_surface_destroy(GLOBALS->surface_mo_pixmap_mouseover_c_1); GLOBALS->surface_mo_pixmap_mouseover_c_1 = NULL; } } goto bot; } #ifdef GDK_WINDOWING_WAYLAND if(waycnt > 2) { waycnt = 0; if(GLOBALS->mouseover_mouseover_c_1) { gtk_widget_destroy(GLOBALS->mouseover_mouseover_c_1); GLOBALS->mouseover_mouseover_c_1 = NULL; if(GLOBALS->cr_mo_pixmap_mouseover_c_1) { cairo_destroy(GLOBALS->cr_mo_pixmap_mouseover_c_1); GLOBALS->cr_mo_pixmap_mouseover_c_1 = NULL; } if(GLOBALS->surface_mo_pixmap_mouseover_c_1) { cairo_surface_destroy(GLOBALS->surface_mo_pixmap_mouseover_c_1); GLOBALS->surface_mo_pixmap_mouseover_c_1 = NULL; } } } #endif if(!GLOBALS->mouseover_mouseover_c_1) { gdk_window_get_origin(gtk_widget_get_window(GLOBALS->wavearea), &xd, &yd); create_mouseover(xin + xd + 8, yin + yd + 20, totalmax, num_info_rows * fh + 7); #ifdef GDK_WINDOWING_WAYLAND waycnt = 0; #endif } else { gdk_window_get_origin(gtk_widget_get_window(GLOBALS->wavearea), &xd, &yd); gtk_window_move(GTK_WINDOW(GLOBALS->mouseover_mouseover_c_1), xin + xd + 8, yin + yd + 20); } if(!GLOBALS->cr_mo_pixmap_mouseover_c_1) goto bot; /* harden against NULL pointer */ XXX_gdk_draw_rectangle(GLOBALS->cr_mo_pixmap_mouseover_c_1, GLOBALS->rgb_mo_dk_gray_mouseover_c_1, TRUE, 0,0, GLOBALS->mo_width_mouseover_c_1, GLOBALS->mo_height_mouseover_c_1); XXX_gdk_draw_rectangle(GLOBALS->cr_mo_pixmap_mouseover_c_1, GLOBALS->rgb_mo_black_mouseover_c_1, TRUE, 1,1, GLOBALS->mo_width_mouseover_c_1-2, GLOBALS->mo_height_mouseover_c_1-2); XXX_font_engine_draw_string(GLOBALS->cr_mo_pixmap_mouseover_c_1, GLOBALS->wavefont, &GLOBALS->rgb_mo_dk_gray_mouseover_c_1, 4+0.5, fh + 2+0.5, alternate_name ? alternate_name : flagged_name); if(num_info_rows == 2) { if(asciivalue) XXX_font_engine_draw_string(GLOBALS->cr_mo_pixmap_mouseover_c_1, GLOBALS->wavefont, &GLOBALS->rgb_mo_dk_gray_mouseover_c_1, 4+0.5, 2*fh+2+0.5, asciivalue); } else { char breakbuf[MOUSEOVER_BREAKSIZE+1]; int i; num_info_rows--; for(i=0;icr_mo_pixmap_mouseover_c_1, GLOBALS->wavefont, &GLOBALS->rgb_mo_dk_gray_mouseover_c_1, 4+0.5, ((2+i)*fh)+2+0.5, breakbuf); } } gdk_window_raise(gtk_widget_get_window(GLOBALS->mouseover_mouseover_c_1)); #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX GdkDrawingContext *gdc; #endif cairo_t* cr = XXX_gdk_cairo_create (XXX_GDK_DRAWABLE (gtk_widget_get_window(GLOBALS->mo_area_mouseover_c_1)), &gdc); cairo_set_source_surface(cr, GLOBALS->surface_mo_pixmap_mouseover_c_1, 0, 0); cairo_paint (cr); #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX gdk_window_end_draw_frame(gtk_widget_get_window(GLOBALS->mo_area_mouseover_c_1), gdc); #else cairo_destroy (cr); #endif #ifdef GDK_WINDOWING_WAYLAND if(GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default())) gtk_widget_queue_draw(GLOBALS->mo_area_mouseover_c_1); #endif bot: if(asciivalue) { free_2(asciivalue); } if(alternate_name) { free_2(alternate_name); } if(flagged_name) { free_2(flagged_name); } } gtkwave-gtk3-3.3.125/src/showchange.c0000664000175000017500000002653315047725112016607 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 #include "analyzer.h" #include "symbol.h" #include "debug.h" typedef struct { const char* label; uint64_t value; } LabeledUint64; typedef struct { const char *label; int64_t value; } LabeledInt64; static const LabeledUint64 ATTRIBUTES[] = { { "Right Justify", TR_RJUSTIFY }, { "Invert", TR_INVERT }, { "Reverse", TR_REVERSE }, { "Exclude", TR_EXCLUDE }, { "Popcnt", TR_POPCNT }, { "Find First One", TR_FFO }, {} }; static const LabeledUint64 BASES[] = { { "Hex", TR_HEX }, { "Decimal", TR_DEC }, { "Signed Decimal", TR_SIGNED }, { "Binary", TR_BIN }, { "Octal", TR_OCT }, { "ASCII", TR_ASCII }, { "Real", TR_REAL }, { "Time", TR_TIME | TR_DEC }, { "Enum", TR_ENUM | TR_BIN }, {} }; static const LabeledInt64 COLORS[] = { { "Normal", WAVE_COLOR_NORMAL }, { "Red", WAVE_COLOR_RED }, { "Orange", WAVE_COLOR_ORANGE }, { "Yellow", WAVE_COLOR_YELLOW }, { "Green", WAVE_COLOR_GREEN }, { "Blue", WAVE_COLOR_BLUE }, { "Indigo", WAVE_COLOR_INDIGO }, { "Violet", WAVE_COLOR_VIOLET }, // { "Cycle", WAVE_COLOR_CYCLE }, {} }; static const LabeledUint64 ANALOG_FORMATS[] = { { "Off", 0 }, { "Step", TR_ANALOG_STEP }, { "Interpolated", TR_ANALOG_INTERPOLATED }, { "Interpolated Annotated", TR_ANALOG_INTERPOLATED | TR_ANALOG_STEP }, {} }; static const LabeledUint64 ANALOG_RESIZING[] = { { "Screen Data", 0 }, { "All Data", TR_ANALOG_FULLSCALE }, {} }; enum { COLUMN_LABEL, COLUMN_VALUE, COLUMN_COLORED_DOT // only used for color combo box }; static GtkListStore *flags_list_store_new(const LabeledUint64 *flags) { GtkListStore *list_store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_UINT64); GtkTreeIter iter; const LabeledUint64 *flag; for (flag = flags; flag->label; flag++) { gtk_list_store_append(list_store, &iter); gtk_list_store_set(list_store, &iter, COLUMN_LABEL, flag->label, COLUMN_VALUE, flag->value, -1 ); } return list_store; } static GtkWidget *flags_combo_box_new(const LabeledUint64 *flags, TraceFlagsType active) { GtkListStore *list_store = flags_list_store_new(flags); GtkWidget *combo_box = gtk_combo_box_new_with_model(GTK_TREE_MODEL(list_store)); GtkCellRenderer *cell_renderer = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo_box), cell_renderer, TRUE); gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo_box), cell_renderer, "text", COLUMN_LABEL, NULL ); g_object_unref(list_store); // Set active entry int i = 0; const LabeledUint64 *flag; for (flag = flags; flag->label; flag++) { if (flag->value == active) { gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), i); break; } i++; } return combo_box; } static GtkListStore *color_list_store_new(void) { GtkListStore *list_store = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_INT64, G_TYPE_STRING); GtkTreeIter iter; const LabeledInt64 *color; for (color = COLORS; color->label; color++) { gtk_list_store_append(list_store, &iter); gtk_list_store_set(list_store, &iter, COLUMN_LABEL, color->label, COLUMN_VALUE, color->value, -1 ); if (color->value != WAVE_COLOR_NORMAL && color->value != WAVE_COLOR_CYCLE) { const uint32_t RAINBOW_COLORS[] = WAVE_RAINBOW_RGB; gchar *dot = g_strdup_printf( "", RAINBOW_COLORS[color->value - 1] ); gtk_list_store_set(list_store, &iter, COLUMN_COLORED_DOT, dot, -1); g_free(dot); } } return list_store; } static GtkWidget *color_combo_box_new(void) { GtkListStore *color_list_store = color_list_store_new(); GtkWidget *combo_box = gtk_combo_box_new_with_model(GTK_TREE_MODEL(color_list_store)); GtkCellRenderer *cell_renderer = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo_box), cell_renderer, TRUE); gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo_box), cell_renderer, "text", COLUMN_LABEL, NULL ); cell_renderer = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo_box), cell_renderer, FALSE); gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo_box), cell_renderer, "markup", COLUMN_COLORED_DOT, NULL ); g_object_unref(color_list_store); return combo_box; } static gboolean combo_box_get_active_value(GtkWidget *combo_box, void *value) { GtkTreeIter iter; gboolean has_active; has_active = gtk_combo_box_get_active_iter(GTK_COMBO_BOX(combo_box), &iter); if (has_active) { GtkTreeModel *model = gtk_combo_box_get_model(GTK_COMBO_BOX(combo_box)); gtk_tree_model_get(model, &iter, COLUMN_VALUE, value, -1); } return has_active; } #if GTK_CHECK_VERSION(3,0,0) static void add_header(GtkWidget *grid, const gchar *text) { gchar *markup = g_markup_printf_escaped("%s", text);; GtkWidget *label = gtk_label_new(NULL); gtk_label_set_markup(GTK_LABEL(label), markup); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_widget_set_hexpand(label, TRUE); gtk_widget_set_margin_top(label, 6); gtk_grid_attach_next_to(GTK_GRID(grid), label, NULL, GTK_POS_BOTTOM, 2, 1); g_free(markup); } static void add_labeled_widget(GtkWidget *grid, const gchar *text, GtkWidget *widget) { GtkWidget *label = gtk_label_new(text); gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_widget_set_hexpand(label, TRUE); gtk_grid_attach_next_to(GTK_GRID(grid), label, NULL, GTK_POS_BOTTOM, 1, 1); gtk_grid_attach_next_to(GTK_GRID(grid), widget, label, GTK_POS_RIGHT, 1, 1); } #else static guint current_row; static void add_header(GtkWidget *table, const gchar *text) { gchar *markup = g_markup_printf_escaped("%s", text);; GtkWidget *label = gtk_label_new(NULL); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_label_set_markup(GTK_LABEL(label), markup); gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 2, current_row, current_row + 1); current_row++; g_free(markup); } static void add_labeled_widget(GtkWidget *table, const gchar *text, GtkWidget *widget) { GtkWidget *label = gtk_label_new(text); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, current_row, current_row + 1); gtk_table_attach_defaults(GTK_TABLE(table), widget, 1, 2, current_row, current_row + 1); current_row++; } #endif void showchange(char *title, Trptr t, GCallback func) { TraceFlagsType old_flags = t->flags; unsigned int old_color = t->t_color; GtkWidget *dialog = gtk_dialog_new_with_buttons( "Trace Properties", GTK_WINDOW(GLOBALS->mainwindow), #if GTK_CHECK_VERSION(3,0,0) GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_USE_HEADER_BAR, #else GTK_DIALOG_DESTROY_WITH_PARENT, #endif "Cancel", GTK_RESPONSE_CANCEL, "Ok", GTK_RESPONSE_OK, NULL ); gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); #if GTK_CHECK_VERSION(3,0,0) GtkWidget *grid = gtk_grid_new(); gtk_grid_set_column_spacing(GTK_GRID(grid), 6); gtk_grid_set_row_spacing(GTK_GRID(grid), 6); gtk_container_set_border_width(GTK_CONTAINER(grid), 12); #else current_row = 0; GtkWidget *grid = gtk_table_new(1, 2, FALSE); gtk_table_set_col_spacings(GTK_TABLE(grid), 6); gtk_table_set_row_spacings(GTK_TABLE(grid), 6); #endif GtkWidget *base_combo_box = flags_combo_box_new(BASES, old_flags & TR_NUMMASK); add_labeled_widget(grid, "Base", base_combo_box); GtkWidget *color_combo_box = color_combo_box_new(); gtk_combo_box_set_active(GTK_COMBO_BOX(color_combo_box), old_color); add_labeled_widget(grid, "Color", color_combo_box); add_header(grid, "Analog"); GtkWidget *analog_format_combo_box = flags_combo_box_new(ANALOG_FORMATS, old_flags & TR_ANALOGMASK); add_labeled_widget(grid, "Format", analog_format_combo_box); GtkWidget *analog_resizing_combo_box = flags_combo_box_new(ANALOG_RESIZING, old_flags & TR_ANALOG_FULLSCALE); add_labeled_widget(grid, "Resizing", analog_resizing_combo_box); add_header(grid, "Attributes"); GSList *attribute_check_buttons = NULL; const LabeledUint64 *attribute; for (attribute = ATTRIBUTES; attribute->label; attribute++) { GtkWidget *check_button = gtk_check_button_new_with_label(attribute->label); #if GTK_CHECK_VERSION(3,0,0) gtk_widget_set_hexpand(check_button, TRUE); gtk_widget_set_margin_start(check_button, 12); gtk_grid_attach_next_to(GTK_GRID(grid), check_button, NULL, GTK_POS_BOTTOM, 2, 1); #else gtk_table_attach_defaults(GTK_TABLE(grid), check_button, 0, 2, current_row, current_row + 1); current_row++; #endif gboolean active = old_flags & attribute->value; gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_button), active); attribute_check_buttons = g_slist_prepend(attribute_check_buttons, check_button); } attribute_check_buttons = g_slist_reverse(attribute_check_buttons); gtk_widget_show_all(grid); GtkWidget *content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); gtk_container_add(GTK_CONTAINER(content_area), grid); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { TraceFlagsType new_flags = old_flags; unsigned int new_color = old_color; uint64_t base; if (combo_box_get_active_value(base_combo_box, &base)) { new_flags = new_flags & ~TR_NUMMASK | base; } int64_t color; if (combo_box_get_active_value(color_combo_box, &color)) { new_color = color; } uint64_t analog_format; if (combo_box_get_active_value(analog_format_combo_box, &analog_format)) { new_flags = new_flags & ~TR_ANALOGMASK | analog_format; } uint64_t analog_resizing; if (combo_box_get_active_value(analog_resizing_combo_box, &analog_resizing)) { new_flags = new_flags & ~TR_ANALOG_FULLSCALE | analog_resizing; } int i = 0; GSList *list; for (list = attribute_check_buttons; list != NULL; list = list->next) { GtkWidget *attribute_check_button = list->data; if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(attribute_check_button))) { new_flags |= ATTRIBUTES[i].value; } else { new_flags &= ~ATTRIBUTES[i].value; } i++; } if (t->flags != new_flags || t->t_color != new_color) { t->flags = new_flags; t->t_color = new_color; t->minmax_valid = 0; // force analog traces to regenerate if necessary func(); } } g_slist_free(attribute_check_buttons); gtk_widget_destroy(dialog); } gtkwave-gtk3-3.3.125/src/ttranslate.h0000664000175000017500000000130315047725112016633 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-gtk3-3.3.125/src/tcl_callbacks.h0000664000175000017500000001503215047725112017237 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-gtk3-3.3.125/src/Makefile.am0000664000175000017500000000734415047725112016350 0ustar bybellbybell## -*- makefile -*- ## SUBDIRS= liblzma helpers helpers/fst cocoa DIST_SUBDIRS= 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) $(GSETTINGS_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 libghw.c libghw.h gnu-getopt.h gnu_regex.h gtk23compat.c gtk23compat.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 --initializer-suffix=,0 $(srcdir)/vcd_keywords.gperf >vcd_keywords.c" | sh gsettings_SCHEMAS = com.geda.gtkwave.gschema.xml @GSETTINGS_RULES@ BUILT_SOURCES= vcd_keywords.c EXTRA_DIST= vcd_keywords.gperf gnu_regex.c com.geda.gtkwave.gschema.xml gtkwave-gtk3-3.3.125/src/edgebuttons.h0000664000175000017500000000073215047725112017002 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-gtk3-3.3.125/src/mouseover.h0000664000175000017500000000064515047725112016506 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-gtk3-3.3.125/src/showchange.h0000664000175000017500000000063615047725112016610 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, GCallback func); #endif gtkwave-gtk3-3.3.125/src/fst.c0000664000175000017500000015543215047725112015256 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2009-2025. * * 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" #include #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 | " /* * pseudo 2D arrays identified as broken in development version testing: fixed in LTS * but removing via ifdef for now as this needs more testing and isn't likely useful */ #define FST_LEN_SUBST_IS_BROKEN /******************************************************************/ /* * 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; 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; int esc_sm = 0; int num_col = 0; while(*pnts) { if(*pnts == '\\') esc_sm = 1; if(*pnts != ' ') { if(*pnts == '[' && !esc_sm) { lb_last = pntd; col_last = NULL; rb_last = NULL; } else if(*pnts == ':' && lb_last != NULL && col_last == NULL && rb_last == NULL && !esc_sm) { col_last = pntd; num_col++; } else if(*pnts == ']' && lb_last != NULL && rb_last == NULL && !esc_sm) { rb_last = pntd; } else if(lb_last != NULL && rb_last == NULL && (isdigit((int)(unsigned char)*pnts) || (*pnts == '-')) && !esc_sm) { } else { lb_last = NULL; col_last = NULL; rb_last = NULL; } *(pntd++) = *pnts; } else { esc_sm = 0; } pnts++; } *pntd = 0; *namlen = pntd - s; if(!rb_last) { col_last = NULL; lb_last = NULL; } 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; } #ifndef FST_LEN_SUBST_IS_BROKEN if(num_col < 2) /* 2d array processing if number of colons >= 2 */ #endif { unsigned int abslen = (*msb >= *lsb) ? (*msb - *lsb + 1) : (*lsb - *msb + 1); if((h->u.var.length != abslen) && (h->u.var.length)) { if (*msb >= *lsb) { *msb = *lsb + h->u.var.length - 1; } else { *lsb = *msb + h->u.var.length - 1; } } } } 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); } } else if(h->u.attr.subtype == FST_MT_ENUMTABLE) { if(h->u.attr.name) { GLOBALS->queued_xl_enum_filter = h->u.attr.arg; /* consumed by next enum variable definition */ if(h->u.attr.name_length) { struct fstETab *fe = fstUtilityExtractEnumTableFromString(h->u.attr.name); /* currently fe->name is unused */ if(fe) { uint32_t ie; #ifdef _WAVE_HAVE_JUDY Pvoid_t e = (Pvoid_t) NULL; for(ie=0; ieelem_count; ie++) { PPvoid_t pv = JudyHSIns(&e, fe->val_arr[ie], strlen(fe->val_arr[ie]), NULL); if(*pv) { free_2(*pv); } *pv = (void *)strdup_2(fe->literal_arr[ie]); } #else struct xl_tree_node *e = NULL; for(ie=0; ieelem_count; ie++) { e = xl_insert(fe->val_arr[ie], e, fe->literal_arr[ie]); } #endif if(GLOBALS->xl_enum_filter) { GLOBALS->num_xl_enum_filter++; GLOBALS->xl_enum_filter = realloc_2(GLOBALS->xl_enum_filter, GLOBALS->num_xl_enum_filter * sizeof(struct xl_tree_node *)); } else { GLOBALS->num_xl_enum_filter++; GLOBALS->xl_enum_filter = malloc_2(sizeof(struct xl_tree_node *)); } GLOBALS->xl_enum_filter[GLOBALS->num_xl_enum_filter-1] = e; if((unsigned int)GLOBALS->num_xl_enum_filter != h->u.attr.arg) { fprintf(stderr, FST_RDLOAD"Internal error, nonsequential enum tables definition encountered, exiting.\n"); exit(255); } fstUtilityFreeEnumTable(fe); } } } } } 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; } else { hier_auto_enable(); /* enable if greater than threshold */ } 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; #ifndef FST_LEN_SUBST_IS_BROKEN int len_subst = 0; #endif 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); if(!h) { fprintf(stderr, FST_RDLOAD"Exiting, missing or malformed names table encountered.\n"); exit(255); } } 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 { #ifndef FST_LEN_SUBST_IS_BROKEN unsigned int abslen = (msb >= lsb) ? (msb - lsb + 1) : (lsb - msb + 1); if((h->u.var.length > abslen) && !(h->u.var.length % abslen)) /* check if 2d array */ { /* printf("h->u.var.length: %d, abslen: %d '%s'\n", h->u.var.length, abslen, fnam); */ len_subst = 1; } #endif 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); } #ifndef FST_LEN_SUBST_IS_BROKEN if(len_subst) /* preserve 2d in name, but make 1d internally */ { node_block[i].msi = h->u.var.length-1; node_block[i].lsi = 0; } #endif } 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)) /* allow chaining for search functions.. NOTE: removed &&(!strchr(f_name[(i)&F_NAME_MODULUS], '\\')) because of esc_sm fix */ { 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->queued_xl_enum_filter) { Jval jv; jv.ui = GLOBALS->queued_xl_enum_filter; GLOBALS->queued_xl_enum_filter = 0; if(!GLOBALS->enum_nptrs_jrb) GLOBALS->enum_nptrs_jrb = make_jrb(); jrb_insert_vptr(GLOBALS->enum_nptrs_jrb, n, jv); } 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(f_name_max_len) { free_2(f_name_max_len); f_name_max_len = NULL; } 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, s)) && (!GLOBALS->vcd_preserve_glitches)) { free_2(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 */ htempx = htemp; } 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 = htempx->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 */ htempx = htemp; } 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 = htempx->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-gtk3-3.3.125/src/Makefile.in0000664000175000017500000012263715047725112016364 0ustar bybellbybell# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : 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) libghw.$(OBJEXT) \ gtk23compat.$(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@ GLIB_COMPILE_SCHEMAS = @GLIB_COMPILE_SCHEMAS@ GPERF = @GPERF@ GREP = @GREP@ GSETTINGS_CFLAGS = @GSETTINGS_CFLAGS@ GSETTINGS_DISABLE_SCHEMAS_COMPILE = @GSETTINGS_DISABLE_SCHEMAS_COMPILE@ GTK_CFLAGS = @GTK_CFLAGS@ 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_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_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@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ RANLIB = @RANLIB@ RPC_CFLAGS = @RPC_CFLAGS@ RPC_LDADD = @RPC_LDADD@ 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@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ 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@ gsettingsschemadir = @gsettingsschemadir@ 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 = liblzma helpers helpers/fst cocoa DIST_SUBDIRS = 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) $(GSETTINGS_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 libghw.c libghw.h gnu-getopt.h gnu_regex.h gtk23compat.c gtk23compat.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) gsettings_SCHEMAS = com.geda.gtkwave.gschema.xml BUILT_SOURCES = vcd_keywords.c EXTRA_DIST = vcd_keywords.gperf gnu_regex.c com.geda.gtkwave.gschema.xml 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)/globals.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gtk23compat.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)/libghw.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=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(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 --initializer-suffix=,0 $(srcdir)/vcd_keywords.gperf >vcd_keywords.c" | sh @GSETTINGS_RULES@ # 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-gtk3-3.3.125/src/entry.c0000664000175000017500000000543215047725112015615 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 "menu.h" #include "debug.h" #include void entrybox(char *title, int width, char *dflt_text, char *comment, int maxch, GCallback func) { GtkWidget *dialog; GtkDialogFlags flags; GtkWidget *content; GtkWidget *entry; if (GLOBALS->entrybox_text != NULL) { free_2 (GLOBALS->entrybox_text); GLOBALS->entrybox_text = NULL; } if (GLOBALS->wave_script_args) { char *s = NULL; while (s == NULL && GLOBALS->wave_script_args->curr != NULL) s = wave_script_args_fgetmalloc_stripspaces (GLOBALS->wave_script_args); if(s) { fprintf (stderr, "GTKWAVE | Entry '%s'\n", s); GLOBALS->entrybox_text = s; func (); } else { GLOBALS->entrybox_text = NULL; } return; } #if GTK_CHECK_VERSION(3,12,0) flags = GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_USE_HEADER_BAR; #else flags = GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT; #endif dialog = gtk_dialog_new_with_buttons( title, GTK_WINDOW(GLOBALS->mainwindow), flags, "Cancel", GTK_RESPONSE_CANCEL, "OK", GTK_RESPONSE_OK, NULL ); gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_OK); gtk_container_set_border_width (GTK_CONTAINER(dialog), 12); content = gtk_dialog_get_content_area (GTK_DIALOG (dialog)); gtk_box_set_spacing (GTK_BOX (content), 6); if (comment != NULL) { GtkWidget *label = gtk_label_new (comment); #if GTK_CHECK_VERSION(3,16,0) gtk_label_set_xalign (GTK_LABEL(label), 0.0); #endif gtk_box_pack_start (GTK_BOX(content), label, FALSE, FALSE, 0); } entry = gtk_entry_new (); gtk_entry_set_text (GTK_ENTRY (entry), dflt_text); gtk_entry_set_max_length (GTK_ENTRY(entry), maxch); gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE); gtk_widget_set_size_request (entry, width, -1); gtk_box_pack_start (GTK_BOX(content), entry, FALSE, FALSE, 0); gtk_widget_show_all (content); int result = gtk_dialog_run (GTK_DIALOG(dialog)); if (result == GTK_RESPONSE_OK) { const gchar *text = gtk_entry_get_text (GTK_ENTRY (entry)); int len = strlen (text); if (len > 0) { GLOBALS->entrybox_text = malloc_2 (len + 1); strcpy (GLOBALS->entrybox_text, text); } func (); } gtk_widget_destroy (dialog); } gtkwave-gtk3-3.3.125/src/fst.h0000664000175000017500000000122215047725112015246 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-gtk3-3.3.125/src/cocoa/0000775000175000017500000000000015047725112015370 5ustar bybellbybellgtkwave-gtk3-3.3.125/src/cocoa/Makefile.am0000664000175000017500000000065515047725112017432 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-gtk3-3.3.125/src/cocoa/alert_sheet.m0000664000175000017500000000501115047725112020042 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-gtk3-3.3.125/src/cocoa/cocoa_misc.c0000664000175000017500000001617315047725112017643 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-gtk3-3.3.125/src/cocoa/Makefile.in0000664000175000017500000004770315047725112017450 0ustar bybellbybell# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : 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@ GLIB_COMPILE_SCHEMAS = @GLIB_COMPILE_SCHEMAS@ GPERF = @GPERF@ GREP = @GREP@ GSETTINGS_CFLAGS = @GSETTINGS_CFLAGS@ GSETTINGS_DISABLE_SCHEMAS_COMPILE = @GSETTINGS_DISABLE_SCHEMAS_COMPILE@ GTK_CFLAGS = @GTK_CFLAGS@ 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_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_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@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ RANLIB = @RANLIB@ RPC_CFLAGS = @RPC_CFLAGS@ RPC_LDADD = @RPC_LDADD@ 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@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ 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@ gsettingsschemadir = @gsettingsschemadir@ 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-gtk3-3.3.125/src/cocoa/alert_sheet.h0000664000175000017500000000152615047725112020044 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-gtk3-3.3.125/src/cocoa/cocoa_misc.h0000664000175000017500000000145115047725112017641 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-gtk3-3.3.125/src/tcl_commands.c0000664000175000017500000016375715047725112017136 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 #include #include #include #include #include #include #include "gtk23compat.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__ #include #include #endif #if defined(HAVE_LIBTCL) #include #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_printTraceFlagsType(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], TraceFlagsType ttVal) { (void)clientData; (void)objc; (void)objv; Tcl_Obj *aobj; char reportString[65]; sprintf(reportString, "%"TRACEFLAGSPRIuFMT, 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_getFacDir(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)) { WAVE_NODEVARDIR_STR int vardir = GLOBALS->facs[which]->n->vardir; /* two bit already chops down to 0..3, but this doesn't hurt */ if((vardir < 0) || (vardir > ND_DIR_MAX)) { vardir = 0; } aobj = Tcl_NewStringObj(vardir_strings[vardir], -1); Tcl_SetObjResult(interp, aobj); } } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } return(TCL_OK); } static int gtkwavetcl_getFacVtype(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)) { WAVE_NODEVARTYPE_STR WAVE_NODEVARDATATYPE_STR unsigned int varxt; char *varxt_pnt; int vartype; int vardt; varxt = GLOBALS->facs[which]->n->varxt; varxt_pnt = varxt ? varxt_fix(GLOBALS->subvar_pnt[varxt]) : NULL; vartype = GLOBALS->facs[which]->n->vartype; if((vartype < 0) || (vartype > ND_VARTYPE_MAX)) { vartype = 0; } vardt = GLOBALS->facs[which]->n->vardt; if((vardt < 0) || (vardt > ND_VDT_MAX)) { vardt = 0; } aobj = Tcl_NewStringObj( (((GLOBALS->supplemental_datatypes_encountered) && (!GLOBALS->supplemental_vartypes_encountered)) ? (varxt ? varxt_pnt : vardatatype_strings[vardt]) : vartype_strings[vartype]), -1); Tcl_SetObjResult(interp, aobj); } } else { return(gtkwavetcl_badNumArgs(clientData, interp, objc, objv, 1)); } return(TCL_OK); } static int gtkwavetcl_getFacDtype(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)) { WAVE_NODEVARTYPE_STR WAVE_NODEVARDATATYPE_STR unsigned int varxt; char *varxt_pnt; int vardt; varxt = GLOBALS->facs[which]->n->varxt; varxt_pnt = varxt ? varxt_fix(GLOBALS->subvar_pnt[varxt]) : NULL; vardt = GLOBALS->facs[which]->n->vardt; if((vardt < 0) || (vardt > ND_VDT_MAX)) { vardt = 0; } aobj = Tcl_NewStringObj( varxt ? varxt_pnt : vardatatype_strings[vardt], -1); Tcl_SetObjResult(interp, aobj); } } 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_printTraceFlagsType(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)gtk_adjustment_get_value(wadj); 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); gtk_adjustment_set_value(hadj, 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(); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); g_signal_emit_by_name (XXX_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; */ /* g_signal_emit_by_name (XXX_GTK_OBJECT (wadj), "changed"); /\* force bar update *\/ */ /* g_signal_emit_by_name (XXX_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_addCommentTracesFromList(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { char reportString[33]; Tcl_Obj *aobj; if(objc==2) { char *s = Tcl_GetString(objv[1]); char** elem = NULL; int i, l = 0; elem = zSplitTclList(s, &l); if(elem) { for(i=0;isignalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); sprintf(reportString, "%d", l); aobj = Tcl_NewStringObj(reportString, -1); Tcl_SetObjResult(interp, aobj); } 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_processTclList(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { 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! */ if(s) { num_found = process_tcl_list(s, FALSE); 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_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) { rv = SST_open_node(s); } else { rv = SST_open_node(s); } } 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_printTraceFlagsType(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) { gtk_window_present(GTK_WINDOW(GLOBALS->mainwindow)); } 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_proc_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[] = { {"addCommentTracesFromList", gtkwavetcl_addCommentTracesFromList}, {"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}, {"getFacDir", gtkwavetcl_getFacDir}, {"getFacDtype", gtkwavetcl_getFacDtype}, {"getFacName", gtkwavetcl_getFacName}, {"getFacVtype", gtkwavetcl_getFacVtype}, {"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}, {"loadFile", gtkwavetcl_loadFile}, {"nop", gtkwavetcl_nop}, {"presentWindow", gtkwavetcl_presentWindow}, {"processTclList", gtkwavetcl_processTclList}, /* not for general-purpose use */ {"reLoadFile", gtkwavetcl_reLoadFile}, {"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}, {"showSignal", gtkwavetcl_showSignal}, {"signalChangeList", gtkwavetcl_signalChangeList}, /* changed from signal_change_list for consistency! */ {"unhighlightSignalsFromList", gtkwavetcl_unhighlightSignalsFromList}, {"", NULL} /* sentinel */ }; #else static void dummy_function(void) { /* nothing */ } #endif gtkwave-gtk3-3.3.125/src/rc.c0000664000175000017500000007231615047725112015065 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2017. * * 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 __MINGW32__ #include #include static char *rcname=".gtkwaverc"; /* name of environment file--POSIX */ #else static char *rcname="gtkwave.ini"; /* name of environment file--WIN32 */ #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_auto_comphier(char *str) { DEBUG(printf("f_disable_auto_comphier(\"%s\")\n",str)); GLOBALS->disable_auto_comphier=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_clipboard_mouseover(char *str) { DEBUG(printf("f_clipboard_mouseover(\"%s\")\n",str)); GLOBALS->clipboard_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_dragzoom_threshold(char *str) { DEBUG(printf("f_dragzoom_threshold(\"%s\")\n",str)); GLOBALS->dragzoom_threshold=atoi_64(str); 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_fill_waveform(char *str) { DEBUG(printf("f_fill_waveform(\"%s\")\n",str)); GLOBALS->fill_waveform=atoi_64(str)?1:0; return(0); } int f_lz_removal(char *str) { DEBUG(printf("f_lz_removal(\"%s\")\n",str)); GLOBALS->lz_removal=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; #if GTK_CHECK_VERSION(3,0,0) if(GLOBALS->force_toolbars) { fprintf(stderr, "GTKWAVE | force_toolbars rcvar option does not work with this version of GTK, ignoring!\n"); } #endif 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_hier_ignore_escapes(char *str) { DEBUG(printf("f_hier_ignore_escapes(\"%s\")\n",str)); GLOBALS->hier_ignore_escapes=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_dbl_action_type(char *str) { DEBUG(printf("f_sst_dbl_action_type(\"%s\")\n",str)); switch(str[0]) { case 'I': case 'i': GLOBALS->sst_dbl_action_type = SST_ACTION_INSERT; break; case 'R': case 'r': GLOBALS->sst_dbl_action_type = SST_ACTION_REPLACE; break; case 'A': case 'a': GLOBALS->sst_dbl_action_type = SST_ACTION_APPEND; break; case 'P': case 'p': GLOBALS->sst_dbl_action_type = SST_ACTION_PREPEND; break; default: GLOBALS->sst_dbl_action_type = SST_ACTION_NONE; } 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_max_fsdb_trees(char *str) { int val; DEBUG(printf("f_max_fsdb_trees(\"%s\")\n",str)); val=atoi_64(str); GLOBALS->extload_max_tree=(val<0)?0:val; 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_fat_lines(char *str) { DEBUG(printf("f_use_fat_lines(\"%s\")\n",str)); GLOBALS->cr_line_width = atoi_64(str) ? 2.0 : 1.0; GLOBALS->cairo_050_offset = atoi_64(str) ? 0.0 : 0.5; 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_gestures(char *str) { DEBUG(printf("f_use_gestures(\"%s\")\n",str)); if(toupper(str[0]) == 'M') { GLOBALS->use_gestures= -1; /* maybe */ } else { GLOBALS->use_gestures=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) { DEBUG(printf("f_use_toolbutton_interface(\"%s\")\n",str)); GLOBALS->use_toolbutton_interface=atoi_64(str)?1:0; 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(highfill) color_make(low) color_make(1) color_make(1fill) 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 }, { "clipboard_mouseover", f_clipboard_mouseover }, { "color_0", f_color_0 }, { "color_1", f_color_1 }, { "color_1fill", f_color_1fill }, { "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_highfill", f_color_highfill }, { "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_auto_comphier", f_disable_auto_comphier }, { "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 }, { "dragzoom_threshold", f_dragzoom_threshold }, { "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 }, { "fill_waveform", f_fill_waveform }, { "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_ignore_escapes", f_hier_ignore_escapes }, { "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 }, { "lz_removal", f_lz_removal }, { "max_fsdb_trees", f_max_fsdb_trees }, { "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_dbl_action_type", f_sst_dbl_action_type }, { "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_fat_lines", f_use_fat_lines }, { "use_frequency_display", f_use_frequency_display }, { "use_full_precision", f_use_full_precision }, { "use_gestures", f_use_gestures }, { "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_highfill ("4ca09d"); /* dark dark blue */ f_color_low ("5dbebb"); /* light blue */ f_color_1 ("00ff00"); /* green */ f_color_1fill ("004d00"); /* dark dark 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 */ } int insert_rc_variable(char *str) { int i; int len; int ok = 0; 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 */ ok = 1; } break; } break; /* added so multiple word values work properly*/ } } break; } } return(ok); } void read_rc_file(char *override_rc) { FILE *handle = NULL; 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__ if(!(handle=fopen(rcname,"rb"))) { struct passwd *pw = NULL; char *home = NULL; char *rcpath = NULL; pw=getpwuid(geteuid()); if(pw) { home=pw->pw_dir; } if(!home) { home = getenv("HOME"); } if(home) { rcpath=(char *)alloca(strlen(home)+1+strlen(rcname)+1); strcpy(rcpath,home); strcat(rcpath,"/"); strcat(rcpath,rcname); } if( !rcpath || !(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))) { insert_rc_variable(str); free_2(str); } } fclose(handle); errno=0; return; } gtkwave-gtk3-3.3.125/src/clipping.c0000664000175000017500000000423715047725112016263 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-gtk3-3.3.125/src/entry.h0000664000175000017500000000067715047725112015630 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, GCallback func); #endif gtkwave-gtk3-3.3.125/src/bsearch.c0000664000175000017500000002046515047725112016066 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2018. * * 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_pos_bsearch_c_1=NULL; if(GLOBALS->wavefont->is_mono) { int adjusted_len = maxlen / GLOBALS->wavefont->mono_width; if(adjusted_len) adjusted_len--; if(GLOBALS->wavefont->mono_width <= maxlen) { GLOBALS->maxlen_trunc_pos_bsearch_c_1 = ascii + adjusted_len; } } else { GLOBALS->maxlen_trunc=0; 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); } char *bsearch_trunc_print(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-gtk3-3.3.125/src/rc.h0000664000175000017500000000773715047725112015077 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2016. * * 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 *); }; struct rc_override /* used for --rcvar command line option */ { struct rc_override *next; char *str; }; void read_rc_file(char *override_rc); int insert_rc_variable(char *str); int get_rgb_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_1fill (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_highfill (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_clipboard_mouseover (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_fill_waveform (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); wave_rgb_t XXX_get_gc_from_name(char *str); #endif gtkwave-gtk3-3.3.125/src/clipping.h0000664000175000017500000000117015047725112016261 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-gtk3-3.3.125/src/bsearch.h0000664000175000017500000000133015047725112016061 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); char *bsearch_trunc_print(char *ascii, int maxlen); struct symbol *bsearch_facs(char *ascii, unsigned int *rows_return); #endif gtkwave-gtk3-3.3.125/src/jrb.c0000664000175000017500000003026515047725112015233 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-gtk3-3.3.125/src/file.c0000664000175000017500000003405315047725112015374 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 "gtk23compat.h" #include "menu.h" #include "debug.h" #include "wavealloca.h" #include #include /* #include */ #ifdef MAC_INTEGRATION #include #endif #if defined __MINGW32__ #include #endif #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 void fileselbox_old(char *title, char **filesel_path, GCallback ok_func, GCallback 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; GLOBALS->fileselbox_text=filesel_path; GLOBALS->filesel_ok=0; GLOBALS->cleanup_file_c_2=ok_func; GLOBALS->bad_cleanup_file_c_1=notok_func; 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 (void) title; (void) filesel_path; (void) ok_func; (void) notok_func; (void) pattn; (void) is_writemode; fprintf(stderr, "fileselbox_old no longer supported, exiting.\n"); exit(255); #endif } void fileselbox(char *title, char **filesel_path, GCallback ok_func, GCallback notok_func, char *pattn, int is_writemode) { #ifndef MAC_INTEGRATION int can_set_filename = 0; GtkWidget *pFileChoose; GtkWidget *pWindowMain; GtkFileFilter *filter; GtkWidget *label; GtkWidget *label_ent; GtkWidget *box; struct Global *old_globals = GLOBALS; #endif /* fix problem where ungrab doesn't occur if button pressed + simultaneous accelerator key occurs */ if(GLOBALS->in_button_press_wavewindow_c_1) { XXX_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__ 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, XXX_GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, XXX_GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER (pFileChoose), TRUE); } else { pFileChoose = gtk_file_chooser_dialog_new( title, NULL, GTK_FILE_CHOOSER_ACTION_OPEN, XXX_GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, XXX_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=X_gtk_entry_new_with_max_length(40); gtk_entry_set_text(GTK_ENTRY(label_ent), GLOBALS->pFileChooseFilterName ? GLOBALS->pFileChooseFilterName : "*"); g_signal_connect (XXX_GTK_OBJECT (label_ent), "changed",G_CALLBACK (press_callback), pFileChoose); box=XXX_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_size_request(GTK_WIDGET(label_ent), 300, 22); gtk_tooltips_set_tip_2(label_ent, "Enter custom pattern match filter here. Note that \"string\" without * or ? achieves a match on \"*string*\"."); 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(XXX_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_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-gtk3-3.3.125/src/jrb.h0000664000175000017500000000634115047725112015236 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-gtk3-3.3.125/src/file.h0000664000175000017500000000114015047725112015370 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, GCallback ok_func, GCallback notok_func, char *pattn, int is_writemode); void fileselbox(char *title, char **filesel_path, GCallback ok_func, GCallback notok_func, char *pattn, int is_writemode); #endif gtkwave-gtk3-3.3.125/src/pipeio.c0000664000175000017500000001106315047725112015736 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 __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-gtk3-3.3.125/src/ghw.c0000664000175000017500000010014615047725112015237 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 "libghw.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; } // Exit the program with return value 1 and print calling line __attribute__((noreturn)) static void ghw_error_exit_line (char const *file, int line) { fprintf(stderr, "Failed to load ghw file due to invalid data. Terminating.\n"); fprintf(stderr, "Error raised at %s:%d.\n", file, line); exit(1); } #define ghw_error_exit() ghw_error_exit_line(__FILE__, __LINE__) 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) { int ev1 = GLOBALS->facs[i-1]->n->extvals; int ev2 = GLOBALS->facs[i]->n->extvals; if(!ev1 && !ev2) { 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; } } } 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 struct tree * build_hierarchy_record (struct ghw_handler *h, const char *pfx, unsigned nbr_els, struct ghw_record_element *els, unsigned int **sig) { struct tree *res; struct tree *last; struct tree *c; unsigned 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 < nbr_els; i++) { c = build_hierarchy_type (h, els[i].type, els[i].name, sig); if (last == NULL) res->child = c; else last->next = c; last = c; } return res; } 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 = (struct ghw_type_array *) ghw_get_base_type (arr->sa.base); char *name = NULL; if ((unsigned int)dim == base->nbr_dim) { struct tree *t; sprintf (GLOBALS->asbuf, "%s]", pfx); name = strdup_2(GLOBALS->asbuf); t = build_hierarchy_type (h, arr->sa.el, name, sig); free_2(name); /* memory leak from GH commit 7ae937b on devel branch */ 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; */ if (arr->sa.rngs[dim]->kind != ghdl_rtik_type_i32) ghw_error_exit(); 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"GHWPRI32, 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; */ if (arr->sa.rngs[dim]->kind != ghdl_rtik_type_e8) ghw_error_exit(); 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"GHWPRI32, 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; /* PATCH-BEGIN: */ case ghdl_rtik_type_b2: { int32_t v; char *nam; struct ghw_range_b2 *r; /* struct tree *last; */ int len; /* last = NULL; */ if (arr->sa.rngs[dim]->kind != ghdl_rtik_type_b2) ghw_error_exit(); r = &arr->sa.rngs[dim]->b2; len = ghw_get_range_length ((union ghw_range *)r); if (len <= 0) break; v = r->left; while (1) { sprintf(GLOBALS->asbuf, "%s%c"GHWPRI32, 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; /* PATCH-END: */ 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); // last element is GHW_NO_SIG, don't increment beyond it if (**sig == GHW_NO_SIG) ghw_error_exit(); res->t_which = *(*sig)++; size_t nxp_idx = (size_t)res->t_which; if (nxp_idx >= GLOBALS->nbr_sigs_ghw_c_1) ghw_error_exit(); s->n = GLOBALS->nxp_ghw_c_1[nxp_idx]; 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: return build_hierarchy_record(h, pfx, t->rec.nbr_fields, t->rec.els, sig); case ghdl_rtik_subtype_record: return build_hierarchy_record (h, pfx, t->sr.base->nbr_fields, t->sr.els, sig); 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) { unsigned 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_i32: case ghdl_rtik_type_p32: n->extvals = 1; n->msi = 31; n->lsi = 0; n->vartype = ND_VCD_INTEGER; break; case ghdl_rtik_type_i64: case ghdl_rtik_type_p64: n->extvals = 1; n->msi = 63; n->lsi = 0; n->vartype = ND_VCD_INTEGER; break; case ghdl_rtik_type_e32: /* ajb: what is e32? */ case ghdl_rtik_type_f64: 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); size_t nxp_idx = (size_t)t->t_which; if (nxp_idx > GLOBALS->nbr_sigs_ghw_c_1) ghw_error_exit(); s->n = GLOBALS->nxp_ghw_c_1[nxp_idx]; 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_i32: case ghdl_rtik_type_i64: case ghdl_rtik_type_p32: case ghdl_rtik_type_p64: flags = 0; break; 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: 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 { if (sig->val->b2 >= sig->type->en.nbr) ghw_error_exit(); he->v.h_vector = (char *)sig->type->en.lits[sig->val->b2]; is_vector = 1; } break; case ghdl_rtik_type_e8: { unsigned char val_e8 = sig->val->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 }; if (val_e8 >= sizeof(map_su2vlg)/sizeof(map_su2vlg[0])) ghw_error_exit(); he->v.h_val = map_su2vlg[val_e8]; } else { if (val_e8 >= sig_type->en.nbr) ghw_error_exit(); he->v.h_vector = (char *)sig_type->en.lits[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: { int i; he->v.h_vector = malloc_2(32); for(i=0;i<32;i++) { he->v.h_vector[31-i] = ((sig->val->i32 >> i) & 1) ? AN_1: AN_0; } } is_vector = 1; break; case ghdl_rtik_type_i64: case ghdl_rtik_type_p64: { int i; he->v.h_vector = malloc_2(64); for(i=0;i<64;i++) { he->v.h_vector[63-i] = ((sig->val->i64 >> i) & 1) ? AN_1: AN_0; } } 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) { unsigned 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; unsigned 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 "GHWPRI64"\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 "GHWPRI64"\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++) { size_t nxp_idx = (size_t)sig; if (nxp_idx > GLOBALS->nbr_sigs_ghw_c_1) ghw_error_exit(); add_history (h, GLOBALS->nxp_ghw_c_1[nxp_idx], 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 = {0}; int i; unsigned int ui; 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... */ } if (handle.hie == NULL) { free_2(GLOBALS->asbuf); GLOBALS->asbuf = NULL; fprintf (stderr, "Error in ghw file '%s': NO HIE.\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->nbr_sigs_ghw_c_1 = handle.nbr_sigs; GLOBALS->nxp_ghw_c_1 =(struct Node **)calloc_2(handle.nbr_sigs, sizeof(struct Node *)); for(ui=0;uinxp_ghw_c_1[ui] = (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-gtk3-3.3.125/src/debug.c0000664000175000017500000003211215047725112015535 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(GtkWidget *widget, const gchar *tip_text) { if(!GLOBALS->disable_tooltips) { gtk_widget_set_tooltip_text(widget, tip_text); } } char *tmpnam_2(char *s, int *fd) { (void)s; #if 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 /******************************************************/ GtkWidget * X_gtk_entry_new_with_max_length (gint max) { GtkWidget *w = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY(w), max); return(w); } /******************************************************/ FILE *popen_san(const char *command, const char *type) /* TALOS-2023-1786 */ { const char *p = command; int is_ok = 1; char ch; while(p && (ch = *(p++))) { switch(ch) { case '&': case '|': case ';': case '\n': case '`': case '$': is_ok = 0; default: break; } } if(is_ok) { return(popen(command, type)); } else { fprintf(stderr, "GTKWAVE | TALOS-2023-1786: popen() command string '%s' may not be properly sanitized, blocking command.\n", command); errno = EPIPE; return(NULL); } } /******************************************************/ gtkwave-gtk3-3.3.125/src/help.c0000664000175000017500000001455015047725112015405 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 "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) { gtk_text_buffer_insert (gtk_text_view_get_buffer(GTK_TEXT_VIEW (GLOBALS->text_help_c_1)), &GLOBALS->iter_help_c_1, str, -1); GtkTextMark *mark = gtk_text_buffer_get_mark (gtk_text_view_get_buffer(GTK_TEXT_VIEW (GLOBALS->text_help_c_1)), "end"); gtk_text_view_scroll_mark_onscreen (GTK_TEXT_VIEW (GLOBALS->text_help_c_1), GTK_TEXT_MARK(mark)); gdk_window_raise(gtk_widget_get_window(GLOBALS->window_help_c_2)); } void help_text_bold(char *str) { gtk_text_buffer_insert_with_tags (gtk_text_view_get_buffer(GTK_TEXT_VIEW (GLOBALS->text_help_c_1)), &GLOBALS->iter_help_c_1, str, -1, GLOBALS->bold_tag_help_c_1, NULL); GtkTextMark *mark = gtk_text_buffer_get_mark (gtk_text_view_get_buffer(GTK_TEXT_VIEW (GLOBALS->text_help_c_1)), "end"); gtk_text_view_scroll_mark_onscreen (GTK_TEXT_VIEW (GLOBALS->text_help_c_1), GTK_TEXT_MARK(mark)); gdk_window_raise(gtk_widget_get_window(GLOBALS->window_help_c_2)); } 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 *scrolled_window; GtkTextIter iter; 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_get_buffer(GTK_TEXT_VIEW (GLOBALS->text_help_c_1)), "bold", "weight", PANGO_WEIGHT_BOLD, NULL); gtk_widget_set_size_request(GTK_WIDGET(GLOBALS->text_help_c_1), 100, 50); gtk_widget_show (GLOBALS->text_help_c_1); gtk_text_buffer_get_end_iter (gtk_text_view_get_buffer(GTK_TEXT_VIEW (GLOBALS->text_help_c_1)), &iter); gtk_text_buffer_create_mark (gtk_text_view_get_buffer(GTK_TEXT_VIEW (GLOBALS->text_help_c_1)), "end", &iter, FALSE); scrolled_window = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_container_add (GTK_CONTAINER (scrolled_window), GLOBALS->text_help_c_1); gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 5); gtk_widget_show(scrolled_window); /* Add a handler to put a message in the text widget when it is realized */ gtkwave_signal_connect (XXX_GTK_OBJECT (GLOBALS->text_help_c_1), "realize", G_CALLBACK (help_realize_text), NULL); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(GLOBALS->text_help_c_1), GTK_WRAP_WORD); return(scrolled_window); } /***********************************************************************************/ 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) { XXX_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_size_request( GTK_WIDGET (GLOBALS->window_help_c_2), width, 400); gtk_window_set_title(GTK_WINDOW (GLOBALS->window_help_c_2), title); gtkwave_signal_connect(XXX_GTK_OBJECT (GLOBALS->window_help_c_2), "delete_event",(GCallback) ok_callback, NULL); vbox = XXX_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 = XXX_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 = XXX_gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, TRUE, 0); gtk_widget_show (separator); hbox = XXX_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_size_request(button1, 100, -1); gtkwave_signal_connect(XXX_GTK_OBJECT (button1), "clicked", G_CALLBACK(ok_callback), NULL); gtk_widget_show (button1); #if GTK_CHECK_VERSION(3,0,0) gtk_box_pack_end(GTK_BOX(hbox), button1, TRUE, TRUE, 0); #else gtk_container_add (GTK_CONTAINER (hbox), button1); #endif gtk_widget_set_can_default (button1, TRUE); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button1), "realize", (GCallback) gtk_widget_grab_default, XXX_GTK_OBJECT (button1)); gtk_widget_show(GLOBALS->window_help_c_2); } gtkwave-gtk3-3.3.125/src/fgetdynamic.c0000664000175000017500000000424415047725112016746 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-gtk3-3.3.125/src/ghw.h0000664000175000017500000000101015047725112015232 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-gtk3-3.3.125/src/pipeio.h0000664000175000017500000000203515047725112015742 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 __MINGW32__ #include #endif struct pipe_ctx { #if 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-gtk3-3.3.125/src/debug.h0000664000175000017500000001043715047725112015550 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 #include "gtk23compat.h" #ifndef __MINGW32__ #include #else #include #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; #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 #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 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(GtkWidget *widget, const gchar *tip_text); char *realpath_2(const char *path, char *resolved_path); enum WaveLoadingTitleType { WAVE_SET_TITLE_NONE, WAVE_SET_TITLE_MODIFIED, WAVE_SET_TITLE_LOADING }; #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 __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); GtkWidget *X_gtk_entry_new_with_max_length (gint max); FILE *popen_san(const char *command, const char *type); /* TALOS-2023-1786 */ #endif gtkwave-gtk3-3.3.125/src/translate.c0000664000175000017500000004153415047725112016454 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 "gtk23compat.h" #include "symbol.h" #include "translate.h" #include "debug.h" enum { NAME_COLUMN, N_COLUMNS }; static gboolean XXX_view_selection_func (GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean path_currently_selected, gpointer userdata) { (void) selection; (void) model; (void) userdata; gint *idx = NULL; if(path) { idx = gtk_tree_path_get_indices (path); if(idx) { if(!path_currently_selected) { GLOBALS->current_filter_translate_c_2 = idx[0] + 1; } else { GLOBALS->current_filter_translate_c_2 = 0; /* none */ } } } return(TRUE); } /************************ 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 add_filter_callback_2(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; int i; 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(gtk_widget_get_window(GLOBALS->window_translate_c_11)); 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); GtkTreeIter iter; gtk_list_store_append (GTK_LIST_STORE(GLOBALS->sig_store_translate), &iter); gtk_list_store_set (GTK_LIST_STORE(GLOBALS->sig_store_translate), &iter, NAME_COLUMN, GLOBALS->filesel_filter[GLOBALS->num_file_filters], -1); } else { GLOBALS->num_file_filters--; } if(GLOBALS->is_active_translate_c_5) gdk_window_raise(gtk_widget_get_window(GLOBALS->window_translate_c_11)); } 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,G_CALLBACK(add_filter_callback_2), G_CALLBACK(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; if(GLOBALS->is_active_translate_c_5) { gdk_window_raise(gtk_widget_get_window(GLOBALS->window_translate_c_11)); 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(XXX_GTK_OBJECT (GLOBALS->window_translate_c_11), "delete_event",(GCallback) destroy_callback, NULL); table = XXX_gtk_table_new (256, 1, FALSE); gtk_widget_show (table); vbox1 = XXX_gtk_vbox_new (FALSE, 0); gtk_container_set_border_width (GTK_CONTAINER (vbox1), 3); gtk_widget_show (vbox1); frame2 = gtk_frame_new (NULL); gtk_container_set_border_width (GTK_CONTAINER (frame2), 3); gtk_widget_show(frame2); XXX_gtk_table_attach (XXX_GTK_TABLE (table), frame2, 0, 1, 0, 254, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); GLOBALS->sig_store_translate = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING); GtkWidget *sig_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (GLOBALS->sig_store_translate)); /* The view now holds a reference. We can get rid of our own reference */ g_object_unref (G_OBJECT (GLOBALS->sig_store_translate)); GtkCellRenderer *renderer = gtk_cell_renderer_text_new (); GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes (titles[0], renderer, "text", NAME_COLUMN, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (sig_view), column); /* Setup the selection handler */ GLOBALS->sig_selection_translate = gtk_tree_view_get_selection (GTK_TREE_VIEW (sig_view)); gtk_tree_selection_set_mode (GLOBALS->sig_selection_translate, GTK_SELECTION_SINGLE); gtk_tree_selection_set_select_function (GLOBALS->sig_selection_translate, XXX_view_selection_func, NULL, NULL); gtk_list_store_clear (GTK_LIST_STORE(GLOBALS->sig_store_translate)); for(i=0;inum_file_filters;i++) { GtkTreeIter iter; gtk_list_store_append (GTK_LIST_STORE(GLOBALS->sig_store_translate), &iter); gtk_list_store_set (GTK_LIST_STORE(GLOBALS->sig_store_translate), &iter, NAME_COLUMN, GLOBALS->filesel_filter[i+1], -1); } gtk_widget_show (sig_view); 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_size_request( 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), sig_view); gtk_container_add (GTK_CONTAINER (frame2), scrolled_win); frameh0 = gtk_frame_new (NULL); gtk_container_set_border_width (GTK_CONTAINER (frameh0), 3); gtk_widget_show(frameh0); XXX_gtk_table_attach (XXX_GTK_TABLE (table), frameh0, 0, 1, 254, 255, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); hbox0 = XXX_gtk_hbox_new (FALSE, 1); gtk_widget_show (hbox0); button6 = gtk_button_new_with_label (" Add Filter to List "); gtk_container_set_border_width (GTK_CONTAINER (button6), 3); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button6), "clicked",G_CALLBACK(add_filter_callback),XXX_GTK_OBJECT (GLOBALS->window_translate_c_11)); gtk_widget_show (button6); gtk_tooltips_set_tip_2(button6, "Bring up a file requester to add a filter to the filter select window."); 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_set_border_width (GTK_CONTAINER (frameh), 3); gtk_widget_show(frameh); XXX_gtk_table_attach (XXX_GTK_TABLE (table), frameh, 0, 1, 255, 256, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); hbox = XXX_gtk_hbox_new (FALSE, 1); gtk_widget_show (hbox); button1 = gtk_button_new_with_label (" OK "); gtk_container_set_border_width (GTK_CONTAINER (button1), 3); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button1), "clicked",G_CALLBACK(ok_callback),XXX_GTK_OBJECT (GLOBALS->window_translate_c_11)); gtk_widget_show (button1); gtk_tooltips_set_tip_2(button1, "Add selected signals to end of the display on the main window."); #if GTK_CHECK_VERSION(3,0,0) gtk_box_pack_start(GTK_BOX(hbox), button1, TRUE, TRUE, 0); #else gtk_box_pack_start (GTK_BOX (hbox), button1, TRUE, FALSE, 0); #endif button5 = gtk_button_new_with_label (" Cancel "); gtk_container_set_border_width (GTK_CONTAINER (button5), 3); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button5), "clicked",G_CALLBACK(destroy_callback),XXX_GTK_OBJECT (GLOBALS->window_translate_c_11)); gtk_tooltips_set_tip_2(button5, "Do nothing and return to the main window."); gtk_widget_show (button5); #if GTK_CHECK_VERSION(3,0,0) gtk_box_pack_start(GTK_BOX(hbox), button5, TRUE, TRUE, 0); #else gtk_box_pack_start (GTK_BOX (hbox), button5, TRUE, FALSE, 0); #endif gtk_container_add (GTK_CONTAINER (frameh), hbox); gtk_container_add (GTK_CONTAINER (GLOBALS->window_translate_c_11), table); gtk_widget_set_size_request(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-gtk3-3.3.125/src/help.h0000664000175000017500000000072615047725112015412 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_HELPBOX_H #define WAVE_HELPBOX_H void helpbox(char *title, int width, char *default_text); void help_text(char *str); void help_text_bold(char *str); #endif gtkwave-gtk3-3.3.125/src/gtk23compat.c0000664000175000017500000001077515047725112016620 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2018. * * 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 "gtk23compat.h" #if GTK_CHECK_VERSION(3,0,0) #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX cairo_t *XXX_gdk_cairo_create (GdkWindow *window, GdkDrawingContext **gdc) { cairo_region_t *region = gdk_window_get_visible_region (window); GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region); *gdc = context; cairo_region_destroy (region); cairo_t *cr = gdk_drawing_context_get_cairo_context (context); return(cr); } #endif #ifdef WAVE_ALLOW_GTK3_SEAT_VS_POINTER_GRAB_UNGRAB void XXX_gdk_pointer_ungrab (guint32 time_) { (void) time_; GdkDisplay *display = gdk_display_get_default(); GdkSeat *seat = gdk_display_get_default_seat (display); gdk_seat_ungrab(seat); } #endif #ifdef WAVE_ALLOW_GTK3_GRID GtkWidget * XXX_gtk_table_new (guint rows, guint columns, gboolean homogeneous) { (void) rows; (void) columns; GtkWidget *grid = gtk_grid_new (); gtk_grid_set_row_homogeneous (GTK_GRID(grid), homogeneous); gtk_grid_set_column_homogeneous (GTK_GRID(grid), homogeneous); return(grid); } void XXX_gtk_table_attach (GtkGrid *table, GtkWidget *child, guint left_attach, guint right_attach, guint top_attach, guint bottom_attach, GtkAttachOptions xoptions, GtkAttachOptions yoptions, guint xpadding, guint ypadding) { (void) xpadding; (void) ypadding; gtk_grid_attach (table, child, left_attach, top_attach, right_attach - left_attach, bottom_attach - top_attach); gtk_widget_set_hexpand(child, (xoptions & (GTK_EXPAND | GTK_FILL)) != 0); gtk_widget_set_vexpand(child, (yoptions & (GTK_EXPAND | GTK_FILL)) != 0); } #endif GtkWidget * XXX_gtk_hseparator_new (void) { return(gtk_separator_new(GTK_ORIENTATION_HORIZONTAL)); } GtkWidget * XXX_gtk_hbox_new(gboolean homogeneous, gint spacing) { GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, spacing); gtk_box_set_homogeneous (GTK_BOX(hbox), homogeneous); return(hbox); } GtkWidget * XXX_gtk_vbox_new(gboolean homogeneous, gint spacing) { GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, spacing); gtk_box_set_homogeneous (GTK_BOX(vbox), homogeneous); return(vbox); } #endif GtkWidget * XXX_gtk_toolbar_insert_stock (GtkToolbar *toolbar, const gchar *stock_id, const char *tooltip_text, const char *tooltip_private_text, GCallback callback, gpointer user_data, gint position) { (void) tooltip_private_text; GtkToolItem *button; #if GTK_CHECK_VERSION(3,0,0) GtkWidget *icon_widget = gtk_image_new_from_icon_name(stock_id, GTK_ICON_SIZE_BUTTON); gtk_widget_show(icon_widget); button = gtk_tool_button_new(icon_widget, NULL); #else button = gtk_tool_button_new_from_stock (stock_id); #endif gtk_tool_item_set_tooltip_text (button, tooltip_text); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), button, position); g_signal_connect(XXX_GTK_OBJECT(button), "clicked", G_CALLBACK(callback), user_data); return(GTK_WIDGET(button)); } void XXX_gtk_toolbar_insert_space (GtkToolbar *toolbar, gint position) { GtkToolItem *button; button = gtk_separator_tool_item_new(); gtk_separator_tool_item_set_draw(GTK_SEPARATOR_TOOL_ITEM(button), TRUE); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), button, position); } void XXX_gtk_toolbar_insert_widget (GtkToolbar *toolbar, GtkWidget *widget, const char *tooltip_text, const char *tooltip_private_text, gint position) { (void) tooltip_text; (void) tooltip_private_text; GtkToolItem *ti = gtk_tool_item_new (); gtk_container_add(GTK_CONTAINER(ti), widget); gtk_widget_show(GTK_WIDGET(ti)); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), ti, position); } gint XXX_gtk_widget_get_scale_factor (GtkWidget *widget) { #if GTK_CHECK_VERSION(3,0,0) gint rc = widget ? gtk_widget_get_scale_factor(widget) : 1; return(rc); #else return(1); #endif } gtkwave-gtk3-3.3.125/src/fgetdynamic.h0000664000175000017500000000147715047725112016760 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 FGET_DYNAMIC_H #define FGET_DYNAMIC_H #include "vlist.h" /* using alloca avoids having to preserve across contexts */ struct wave_script_args { struct wave_script_args *curr; struct wave_script_args *next; char payload[]; /* C99 */ }; char *fgetmalloc(FILE *handle); char *fgetmalloc_stripspaces(FILE *handle); char *wave_script_args_fgetmalloc(struct wave_script_args *wave_script_args); char *wave_script_args_fgetmalloc_stripspaces(struct wave_script_args *wave_script_args); #endif gtkwave-gtk3-3.3.125/src/vlist.c0000664000175000017500000004430515047725112015617 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 __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) { uintptr_t 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; uintptr_t val, nxt; unsigned int vali, nxti; int offs_as_int; int rc; int len = 0; val = (uintptr_t)(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; uintptr_t vl_offs = (uintptr_t)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; intptr_t 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(uintptr_t) != 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; intptr_t 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(uintptr_t) != 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 "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-gtk3-3.3.125/src/vcd_keywords.c0000664000175000017500000001561215047725112017160 0ustar bybellbybell/* C code produced by gperf version 3.0.4 */ /* Command-line: /usr/bin/gperf -o -i 1 -C -k '1,$' -L C -H keyword_hash -N check_identifier -tT --initializer-suffix=,0 ./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 #if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_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[] = { {"",0}, {"",0}, {"",0}, {"",0}, {"",0}, #line 23 "./vcd_keywords.gperf" {"reg", V_REG}, #line 26 "./vcd_keywords.gperf" {"time", V_TIME}, {"",0}, #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}, {"",0}, #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}, {"",0}, {"",0}, {"",0}, #line 38 "./vcd_keywords.gperf" {"out", V_OUT}, #line 34 "./vcd_keywords.gperf" {"wire", V_WIRE}, {"",0}, {"",0}, {"",0}, #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}, {"",0}, #line 41 "./vcd_keywords.gperf" {"bit", V_BIT}, #line 20 "./vcd_keywords.gperf" {"real", V_REAL}, {"",0}, {"",0}, {"",0}, #line 27 "./vcd_keywords.gperf" {"tri", V_TRI}, #line 47 "./vcd_keywords.gperf" {"enum", V_ENUM}, {"",0}, {"",0}, {"",0}, {"",0}, #line 48 "./vcd_keywords.gperf" {"shortreal", V_SHORTREAL}, #line 17 "./vcd_keywords.gperf" {"event", V_EVENT}, {"",0}, {"",0}, {"",0}, #line 33 "./vcd_keywords.gperf" {"wand", V_WAND}, {"",0}, {"",0}, {"",0}, {"",0}, #line 32 "./vcd_keywords.gperf" {"tri1", V_TRI1}, {"",0}, {"",0}, {"",0}, {"",0}, #line 31 "./vcd_keywords.gperf" {"tri0", V_TRI0}, {"",0}, {"",0}, #line 25 "./vcd_keywords.gperf" {"supply1", V_SUPPLY1}, {"",0}, #line 49 "./vcd_keywords.gperf" {"$end", V_END}, {"",0}, {"",0}, #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-gtk3-3.3.125/src/gtk23compat.h0000664000175000017500000001600515047725112016615 0ustar bybellbybell#ifndef WAVE_GTK23COMPAT_H #define WAVE_GTK23COMPAT_H /* this is for any future gtk2/gtk3 compatibility */ #ifdef MAC_INTEGRATION /* #undef WAVE_ALLOW_QUARTZ_FLUSH_WORKAROUND */ #endif #if GTK_CHECK_VERSION(3,22,26) #if !defined(__MINGW32__) && !defined(MAC_INTEGRATION) && defined(GDK_WINDOWING_WAYLAND) #include #endif #endif #if GTK_CHECK_VERSION(3,0,0) #ifndef MAC_INTEGRATION #define WAVE_ALLOW_GTK3_HEADER_BAR #endif /* workaround for wave_vslider not rendering properly on startup */ #define WAVE_ALLOW_GTK3_VSLIDER_WORKAROUND /* workarounds for gtk warnings "How does the code know the size to allocate?", etc. */ #define WAVE_GTK3_GLIB_WARNING_SUPPRESS /* #define WAVE_GTK3_SIZE_ALLOCATE_WORKAROUND_TREESEARCH */ /* #define WAVE_GTK3_SIZE_ALLOCATE_WORKAROUND_WAVE_VSLIDER */ /* #define WAVE_GTK3_SIZE_ALLOCATE_WORKAROUND_DEPRECATED_API */ /* seat vs pointer enable */ #define WAVE_ALLOW_GTK3_SEAT_VS_POINTER_GRAB_UNGRAB #define WAVE_GTK3_HIERSEARCH_DEBOUNCE #define WAVE_GTK3_MENU_SEPARATOR #define WAVE_ALLOW_GTK3_GRID #define WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX /* gestures enable */ #define WAVE_ALLOW_GTK3_GESTURE_EVENT #define WAVE_GTK3_SWIPE_TIME_CONSTANT (325000.0) #define WAVE_GTK3_SWIPE_MICROSECONDS (8 * WAVE_GTK3_SWIPE_TIME_CONSTANT) #define WAVE_GTK3_SWIPE_VEL_VS_DIST_FACTOR (WAVE_GTK3_SWIPE_TIME_CONSTANT / 1000000.0) #define WAVE_ALLOW_GTK3_GESTURE_MIDDLE_RIGHT_BUTTON #define WAVE_CTRL_SCROLL_ZOOM_FACTOR 0.3 /* tested as working on thinkpad25 */ #define WAVE_GTK3_GESTURE_ZOOM_USES_GTK_PHASE_CAPTURE #define WAVE_GTK3_GESTURE_ZOOM_IS_1D #endif #define WAVE_GTKIFE(a,b,c,d,e) {a,b,(void (*)(void))c,d,e,NULL} #if GTK_CHECK_VERSION(3,0,0) #define WAVE_GDK_GET_POINTER(a,b,c,bi,ci,d) gdk_window_get_device_position(a, gdk_seat_get_pointer(gdk_display_get_default_seat(gdk_display_get_default())), bi, ci, d) #else #define WAVE_GDK_GET_POINTER(a,b,c,bi,ci,d) gdk_window_get_pointer(a,bi,ci,d) #endif #define WAVE_GDK_GET_POINTER_COPY x=xi; y=yi; #define WAVE_GDK_GET_POINTER_COPY_XONLY x=xi; #define WAVE_GTK_SFUNCAST(x) ((void (*)(GtkWidget *, gpointer))(x)) /* doesn't work in gtk 2 or 3 */ #undef WAVE_ALLOW_SLIDER_ZOOM /* gtk3->4 deprecated changes */ #if GTK_CHECK_VERSION(3,0,0) #define XXX_GTK_TREE_VIEW GTK_SCROLLABLE #define XXX_gtk_tree_view_get_vadjustment gtk_scrollable_get_vadjustment #define XXX_gtk_tree_view_get_hadjustment gtk_scrollable_get_hadjustment #define XXX_gtk_tree_view_set_vadjustment gtk_scrollable_set_vadjustment #define XXX_gtk_tree_view_set_hadjustment gtk_scrollable_set_hadjustment #define XXX_GTK_TEXT_VIEW GTK_SCROLLABLE #define XXX_gtk_text_view_get_vadjustment gtk_scrollable_get_vadjustment GtkWidget *XXX_gtk_hbox_new (gboolean homogeneous, gint spacing); GtkWidget *XXX_gtk_vbox_new (gboolean homogeneous, gint spacing); #define XXX_gtk_hpaned_new(a) gtk_paned_new(GTK_ORIENTATION_HORIZONTAL) #define XXX_gtk_vpaned_new(a) gtk_paned_new(GTK_ORIENTATION_VERTICAL) GtkWidget *XXX_gtk_hseparator_new (void); #define XXX_gtk_hscrollbar_new(a) gtk_scrollbar_new(GTK_ORIENTATION_HORIZONTAL, a) #define XXX_gtk_vscrollbar_new(a) gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL, a) #define XXX_GTK_STOCK_CANCEL "_Cancel" #define XXX_GTK_STOCK_OPEN "_Open" #define XXX_GTK_STOCK_SAVE "_Save" #define XXX_GTK_STOCK_CUT "edit-cut" #define XXX_GTK_STOCK_COPY "edit-copy" #define XXX_GTK_STOCK_PASTE "edit-paste" #define XXX_GTK_STOCK_ZOOM_FIT "zoom-fit-best" #define XXX_GTK_STOCK_ZOOM_IN "zoom-in" #define XXX_GTK_STOCK_ZOOM_OUT "zoom-out" #define XXX_GTK_STOCK_UNDO "edit-undo" #define XXX_GTK_STOCK_GOTO_FIRST "go-first" #define XXX_GTK_STOCK_GOTO_LAST "go-last" #define XXX_GTK_STOCK_GO_BACK "go-previous" #define XXX_GTK_STOCK_GO_FORWARD "go-next" #define XXX_GTK_STOCK_REFRESH "view-refresh" #else #define XXX_GTK_TREE_VIEW GTK_TREE_VIEW #define XXX_gtk_tree_view_get_vadjustment gtk_tree_view_get_vadjustment #define XXX_gtk_tree_view_get_hadjustment gtk_tree_view_get_hadjustment #define XXX_gtk_tree_view_set_vadjustment gtk_tree_view_set_vadjustment #define XXX_gtk_tree_view_set_hadjustment gtk_tree_view_set_hadjustment #define XXX_GTK_TEXT_VIEW GTK_TEXT_VIEW #define XXX_gtk_text_view_get_vadjustment gtk_text_view_get_vadjustment #define XXX_gtk_hbox_new(a, b) gtk_hbox_new((a), (b)) #define XXX_gtk_vbox_new(a, b) gtk_vbox_new((a), (b)) #define XXX_gtk_hpaned_new(a) gtk_hpaned_new() #define XXX_gtk_vpaned_new(a) gtk_vpaned_new() #define XXX_gtk_hseparator_new gtk_hseparator_new #define XXX_gtk_hscrollbar_new(a) gtk_hscrollbar_new(a) #define XXX_gtk_vscrollbar_new(a) gtk_vscrollbar_new(a) #define XXX_GTK_STOCK_CANCEL GTK_STOCK_CANCEL #define XXX_GTK_STOCK_OPEN GTK_STOCK_OPEN #define XXX_GTK_STOCK_SAVE GTK_STOCK_SAVE #define XXX_GTK_STOCK_CUT GTK_STOCK_CUT #define XXX_GTK_STOCK_COPY GTK_STOCK_COPY #define XXX_GTK_STOCK_PASTE GTK_STOCK_PASTE #define XXX_GTK_STOCK_ZOOM_FIT GTK_STOCK_ZOOM_FIT #define XXX_GTK_STOCK_ZOOM_IN GTK_STOCK_ZOOM_IN #define XXX_GTK_STOCK_ZOOM_OUT GTK_STOCK_ZOOM_OUT #define XXX_GTK_STOCK_UNDO GTK_STOCK_UNDO #define XXX_GTK_STOCK_GOTO_FIRST GTK_STOCK_GOTO_FIRST #define XXX_GTK_STOCK_GOTO_LAST GTK_STOCK_GOTO_LAST #define XXX_GTK_STOCK_GO_BACK GTK_STOCK_GO_BACK #define XXX_GTK_STOCK_GO_FORWARD GTK_STOCK_GO_FORWARD #define XXX_GTK_STOCK_REFRESH GTK_STOCK_REFRESH #endif #ifdef WAVE_ALLOW_GTK3_GRID GtkWidget *XXX_gtk_table_new (guint rows, guint columns, gboolean homogeneous); void XXX_gtk_table_attach (GtkGrid *table, GtkWidget *child, guint left_attach, guint right_attach, guint top_attach, guint bottom_attach, GtkAttachOptions xoptions, GtkAttachOptions yoptions, guint xpadding, guint ypadding); #define XXX_GTK_TABLE GTK_GRID #else #define XXX_gtk_table_new gtk_table_new #define XXX_gtk_table_attach gtk_table_attach #define XXX_GTK_TABLE GTK_TABLE #endif #ifdef WAVE_ALLOW_GTK3_SEAT_VS_POINTER_GRAB_UNGRAB void XXX_gdk_pointer_ungrab (guint32 time_); #else #define XXX_gdk_pointer_ungrab gdk_pointer_ungrab #endif #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX cairo_t *XXX_gdk_cairo_create (GdkWindow *window, GdkDrawingContext **gdc); #else #define XXX_gdk_cairo_create(a, b) gdk_cairo_create(a) #endif /* useful for multiple GTK versions */ GtkWidget * XXX_gtk_toolbar_insert_stock (GtkToolbar *toolbar, const gchar *stock_id, const char *tooltip_text, const char *tooltip_private_text, GCallback callback, gpointer user_data, gint position); void XXX_gtk_toolbar_insert_space (GtkToolbar *toolbar, gint position); void XXX_gtk_toolbar_insert_widget (GtkToolbar *toolbar, GtkWidget *widget, const char *tooltip_text, const char *tooltip_private_text, gint position); gint XXX_gtk_widget_get_scale_factor (GtkWidget *widget); #endif gtkwave-gtk3-3.3.125/src/lx2.c0000664000175000017500000005533015047725112015163 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" #include #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(f->flags&(LXT2_RD_SYM_F_DOUBLE|LXT2_RD_SYM_F_STRING)) { htemp->v.h_vector = strdup_2((f->flags&LXT2_RD_SYM_F_DOUBLE) ? "NaN" : "UNDEF"); htemp->flags = HIST_REAL; if(f->flags&LXT2_RD_SYM_F_STRING) htemp->flags |= HIST_STRING; } else { 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(f->flags&(LXT2_RD_SYM_F_DOUBLE|LXT2_RD_SYM_F_STRING)) { htemp->v.h_vector = strdup_2((f->flags&LXT2_RD_SYM_F_DOUBLE) ? "NaN" : "UNDEF"); htemp->flags = HIST_REAL; if(f->flags&LXT2_RD_SYM_F_STRING) htemp->flags |= HIST_STRING; } else { 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; np->head.v.h_vector = strdup_2((f->flags&LXT2_RD_SYM_F_DOUBLE) ? "NaN" : "UNDEF"); } { struct HistEnt *htemp2 = histent_calloc(); htemp2->time = -1; if(f->flags&(LXT2_RD_SYM_F_DOUBLE|LXT2_RD_SYM_F_STRING)) { htemp2->v.h_vector = strdup_2((f->flags&LXT2_RD_SYM_F_DOUBLE) ? "NaN" : "UNDEF"); htemp2->flags = HIST_REAL; if(f->flags&LXT2_RD_SYM_F_STRING) htemp2->flags |= HIST_STRING; } else { 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-gtk3-3.3.125/src/signalwindow.c0000664000175000017500000016335715047725112017174 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2018. * * 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 "gtk23compat.h" #include "currenttime.h" #include "pixmaps.h" #include "symbol.h" #include "debug.h" /* GDK_KEY_equal defined from gtk2 2.22 onwards. */ #ifndef GDK_KEY_equal #define GDK_KEY_equal GDK_equal #endif #ifndef GDK_KEY_Up #define GDK_KEY_Up GDK_Up #endif #ifndef GDK_KEY_KP_Up #define GDK_KEY_KP_Up GDK_KP_Up #endif #ifndef GDK_KEY_Down #define GDK_KEY_Down GDK_Down #endif #ifndef GDK_KEY_KP_Down #define GDK_KEY_KP_Down GDK_KP_Down #endif #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"); } void signalwindow_paint(cairo_t *cr) { int scale_factor = XXX_gtk_widget_get_scale_factor(GLOBALS->signalarea); cairo_matrix_t prev_matrix; cairo_get_matrix(cr, &prev_matrix); cairo_scale(cr, 1.0/scale_factor, 1.0/scale_factor); cairo_set_source_surface(cr, GLOBALS->surface_signalpixmap, -(gint)(gtk_adjustment_get_value(GTK_ADJUSTMENT(GLOBALS->signal_hslider))), 0); cairo_paint (cr); cairo_set_matrix(cr, &prev_matrix); } static void service_hslider(GtkWidget *text, gpointer data) { (void)text; (void)data; GtkAdjustment *hadj; gint xsrc; if(GLOBALS->cr_signalpixmap) { hadj=GTK_ADJUSTMENT(GLOBALS->signal_hslider); xsrc=(gint)gtk_adjustment_get_value(hadj); DEBUG(printf("Signal HSlider Moved to %d\n",xsrc)); GLOBALS->right_align_active = 0; if(!GLOBALS->use_dark) { cairo_set_source_rgba (GLOBALS->cr_signalpixmap, GLOBALS->rgb_gc.gc_mdgray.r, GLOBALS->rgb_gc.gc_mdgray.g, GLOBALS->rgb_gc.gc_mdgray.b, GLOBALS->rgb_gc.gc_mdgray.a); cairo_rectangle (GLOBALS->cr_signalpixmap, 0.5, -1+0.5, GLOBALS->signal_fill_width, GLOBALS->fontheight); cairo_fill (GLOBALS->cr_signalpixmap); } cairo_set_source_rgba (GLOBALS->cr_signalpixmap, GLOBALS->rgb_gc_white.r, GLOBALS->rgb_gc_white.g, GLOBALS->rgb_gc_white.b, GLOBALS->rgb_gc_white.a); cairo_move_to (GLOBALS->cr_signalpixmap, 0.5, GLOBALS->fontheight-1+0.5); cairo_line_to (GLOBALS->cr_signalpixmap, GLOBALS->signal_fill_width-1+0.5, GLOBALS->fontheight-1+0.5); cairo_stroke (GLOBALS->cr_signalpixmap); if(!GLOBALS->use_dark) { XXX_font_engine_draw_string(GLOBALS->cr_signalpixmap, GLOBALS->signalfont, &(GLOBALS->rgb_gc_black), 3+xsrc+0.5, GLOBALS->fontheight-4+0.5, "Time"); } if(GLOBALS->signalarea_has_focus) { GtkAllocation allocation; gtk_widget_get_allocation(GLOBALS->signalarea, &allocation); #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX GdkDrawingContext *gdc; #endif cairo_t* cr = XXX_gdk_cairo_create (XXX_GDK_DRAWABLE (gtk_widget_get_window(GLOBALS->signalarea)), &gdc); cairo_rectangle (cr, 0, 0, allocation.width, allocation.height); cairo_clip (cr); signalwindow_paint(cr); draw_signalarea_focus(cr); #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX gdk_window_end_draw_frame(gtk_widget_get_window(GLOBALS->signalarea), gdc); #else cairo_destroy (cr); #endif } else { GtkAllocation allocation; gtk_widget_get_allocation(GLOBALS->signalarea, &allocation); #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX GdkDrawingContext *gdc; #endif cairo_t* cr = XXX_gdk_cairo_create (XXX_GDK_DRAWABLE (gtk_widget_get_window(GLOBALS->signalarea)), &gdc); cairo_rectangle (cr, 0.0, 0.0, allocation.width, allocation.height); cairo_clip (cr); signalwindow_paint(cr); #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX gdk_window_end_draw_frame(gtk_widget_get_window(GLOBALS->signalarea), gdc); #else cairo_destroy (cr); #endif } } } void draw_signalarea_focus(cairo_t *cr) { if(GLOBALS->signalarea_has_focus) { GtkAllocation allocation; gtk_widget_get_allocation(GLOBALS->signalarea, &allocation); if(cr) { cairo_rectangle (cr, 0, 0, allocation.width, allocation.height); cairo_clip (cr); cairo_set_source_rgba (cr, GLOBALS->rgb_gc_black.r, GLOBALS->rgb_gc_black.g, GLOBALS->rgb_gc_black.b, GLOBALS->rgb_gc_black.a); cairo_rectangle (cr, 0.5, 0.5, allocation.width-1, allocation.height-1); cairo_stroke(cr); } } } /**************************************************************************/ /*** 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; #ifdef GDK_WINDOWING_WAYLAND if(GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default())) { GdkDevice *device = gdk_drag_context_get_device(dc); const gchar *gn = gdk_device_get_name(device); if(!strcmp(gn, "Wayland Touch Master Pointer")) { fprintf(stderr, "GTKWAVE | Touch DnD not yet supported on Wayland.\n"); return; } } #endif GLOBALS->dnd_state = 1; } /* * DND "drag_failed" handler, this is called when a drag and drop has * failed (e.g., by pressing ESC). */ static gboolean DNDFailedCB( GtkWidget *widget, GdkDragContext *context, GtkDragResult result) { (void)widget; (void)context; (void)result; GLOBALS->dnd_cursor_timer = 0; GLOBALS->dnd_state = 0; GLOBALS->standard_trace_dnd_degate = 1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); return(FALSE); } /* * 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; gint xi, yi; if(!GLOBALS->dnd_state) goto bot; 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 ? gtk_widget_get_window(GLOBALS->signalarea) : gtk_widget_get_window(GLOBALS->wavearea), &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)gtk_adjustment_get_value(wadj))+which; ddest = (GLOBALS->std_dnd_tgt_on_signalarea) ? GTK_WIDGET(GLOBALS->signalarea) : GTK_WIDGET(GLOBALS->wavearea); GtkAllocation allocation; gtk_widget_get_allocation(ddest, &allocation); if((x<0)||(x>=allocation.width)||(y<0)||(y>=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; gboolean same_widget; GdkDragAction suggested_action; 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); /* 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(gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE) gdk_drag_status(dc, GDK_ACTION_MOVE, tt); /* Only copy? */ else if(gdk_drag_context_get_actions(dc) == GDK_ACTION_COPY) gdk_drag_status(dc, GDK_ACTION_COPY, tt); /* Only link? */ else if(gdk_drag_context_get_actions(dc) == GDK_ACTION_LINK) gdk_drag_status(dc, GDK_ACTION_LINK, tt); /* Other action, check if listed in our actions list? */ else if(gdk_drag_context_get_actions(dc) & suggested_action) gdk_drag_status(dc, suggested_action, tt); /* All else respond with 0. */ else gdk_drag_status(dc, 0, tt); 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; gint xi, yi; wadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider); WAVE_GDK_GET_POINTER(GLOBALS->std_dnd_tgt_on_signalarea ? gtk_widget_get_window(GLOBALS->signalarea) : gtk_widget_get_window(GLOBALS->wavearea), &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)gtk_adjustment_get_value(wadj))+which; ddest = (GLOBALS->std_dnd_tgt_on_signalarea) ? GTK_WIDGET(GLOBALS->signalarea) : GTK_WIDGET(GLOBALS->wavearea); GtkAllocation allocation; gtk_widget_get_allocation(ddest, &allocation); if((x<0)||(x>=allocation.width)||(y<0)||(y>=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)(gtk_adjustment_get_value(sadj)); gint xsrc=(gint)gtk_adjustment_get_value(hadj); gint ylin; gtk_widget_get_allocation(GLOBALS->signalarea, &allocation); cairo_set_source_rgba (GLOBALS->cr_signalpixmap, GLOBALS->rgb_gc.gc_ltgray.r, GLOBALS->rgb_gc.gc_ltgray.g, GLOBALS->rgb_gc.gc_ltgray.b, GLOBALS->rgb_gc.gc_ltgray.a); cairo_rectangle (GLOBALS->cr_signalpixmap, 0.5, 0.5, GLOBALS->signal_fill_width, allocation.height); cairo_fill (GLOBALS->cr_signalpixmap); 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; cairo_set_source_rgba (GLOBALS->cr_signalpixmap, GLOBALS->rgb_gc_black.r, GLOBALS->rgb_gc_black.g, GLOBALS->rgb_gc_black.b, GLOBALS->rgb_gc_black.a); cairo_move_to (GLOBALS->cr_signalpixmap, 0.5, ylin+0.5); cairo_line_to (GLOBALS->cr_signalpixmap, GLOBALS->signal_fill_width-1+0.5, ylin+0.5); cairo_stroke (GLOBALS->cr_signalpixmap); } else { int i; which = -1; ylin = ((which + 2) * GLOBALS->fontheight) - 2; for(i=0;isignal_fill_width-1; i+=16) { cairo_set_source_rgba (GLOBALS->cr_signalpixmap, GLOBALS->rgb_gc_black.r, GLOBALS->rgb_gc_black.g, GLOBALS->rgb_gc_black.b, GLOBALS->rgb_gc_black.a); cairo_move_to (GLOBALS->cr_signalpixmap, i+0.5, ylin+0.5); cairo_line_to (GLOBALS->cr_signalpixmap, i+7+0.5, ylin+0.5); cairo_stroke (GLOBALS->cr_signalpixmap); cairo_set_source_rgba (GLOBALS->cr_signalpixmap, GLOBALS->rgb_gc_white.r, GLOBALS->rgb_gc_white.g, GLOBALS->rgb_gc_white.b, GLOBALS->rgb_gc_white.a); cairo_move_to (GLOBALS->cr_signalpixmap, i+8+0.5, ylin+0.5); cairo_line_to (GLOBALS->cr_signalpixmap, i+15+0.5, ylin+0.5); cairo_stroke (GLOBALS->cr_signalpixmap); } } #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX GdkDrawingContext *gdc; #endif cairo_t* cr = XXX_gdk_cairo_create (XXX_GDK_DRAWABLE (gtk_widget_get_window(GLOBALS->signalarea)), &gdc); cairo_rectangle (cr, 0, 0, allocation.width, allocation.height); cairo_clip (cr); signalwindow_paint(cr); draw_signalarea_focus(cr); #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX gdk_window_end_draw_frame(gtk_widget_get_window(GLOBALS->signalarea), gdc); #else cairo_destroy (cr); #endif /* 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; int ud_kill = 0; #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 ( (event->keyval == GDK_KEY_equal) && #ifdef MAC_INTEGRATION (event->state & GDK_META_MASK) #else (event->state & GDK_CONTROL_MASK) #endif ) { service_zoom_in(NULL, NULL); rc = TRUE; } else #ifdef WAVE_ALLOW_GTK3_HEADER_BAR if (event->keyval == GDK_KEY_F10) { do_popup_main_menu(NULL, NULL); } else #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_KEY_a: if(event->state & GDK_MOD2_MASK) { menu_dataformat_highlight_all(NULL, 0, NULL); rc = TRUE; } break; case GDK_KEY_A: if(event->state & GDK_MOD2_MASK) { menu_dataformat_unhighlight_all(NULL, 0, NULL); rc = TRUE; } break; case GDK_KEY_x: if(event->state & GDK_MOD2_MASK) { menu_cut_traces(NULL, 0, NULL); rc = TRUE; } break; case GDK_KEY_c: if(event->state & GDK_MOD2_MASK) { menu_copy_traces(NULL, 0, NULL); rc = TRUE; } break; case GDK_KEY_v: if(event->state & GDK_MOD2_MASK) { menu_paste_traces(NULL, 0, NULL); rc = TRUE; } break; #endif case GDK_KEY_Page_Up: case GDK_KEY_KP_Page_Up: case GDK_KEY_Page_Down: case GDK_KEY_KP_Page_Down: case GDK_KEY_Up: case GDK_KEY_KP_Up: case GDK_KEY_Down: case GDK_KEY_KP_Down: wadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider); GtkAllocation allocation; gtk_widget_get_allocation(GLOBALS->signalarea, &allocation); num_traces_displayable=(allocation.height)/(GLOBALS->fontheight); num_traces_displayable--; /* for the time trace that is always there */ if(event->state & GDK_SHIFT_MASK) { Trptr t = NULL, t2 = NULL; Trptr tc = NULL, th = NULL; int num_high = 0; if((event->keyval == GDK_KEY_Up) || (event->keyval == GDK_KEY_KP_Up)) { ud_kill = 1; for(t=GLOBALS->traces.first;t;t=t->t_next) { if(t->flags&TR_HIGHLIGHT) { if(!th) th = t; num_high++; } if(t->is_cursor) { tc = t; } } if(num_high <= 1) { t = th ? GivePrevTrace(th) : GLOBALS->topmost_trace; } else { t = tc ? GivePrevTrace(tc) : GLOBALS->topmost_trace; } MarkTraceCursor(t); } else if((event->keyval == GDK_KEY_Down) || (event->keyval == GDK_KEY_KP_Down)) { ud_kill = 1; for(t=GLOBALS->traces.first;t;t=t->t_next) { if(t->flags&TR_HIGHLIGHT) { th = t; num_high++; } if(t->is_cursor) { tc = t; } } if(num_high <= 1) { t = th ? GiveNextTrace(th) : GLOBALS->topmost_trace; } else { if(tc) { t = GiveNextTrace(tc); } else { t = th ? GiveNextTrace(th) : GLOBALS->topmost_trace; } } MarkTraceCursor(t); } if(t) { int top_target = 0; target = 0; which=num_traces_displayable-1; ClearTraces(); t->flags |= TR_HIGHLIGHT; t2 = t; for(t=GLOBALS->traces.first;t;t=GiveNextTrace(t)) { if(t == GLOBALS->topmost_trace) break; top_target++; } for(t=GLOBALS->traces.first;t;t=GiveNextTrace(t)) { if(t2 == t) break; target++; } if((target >= top_target) && (target <= top_target+which)) { /* nothing */ } else { if((event->keyval == GDK_KEY_Up) || (event->keyval == GDK_KEY_KP_Up)) { if(target<0) target=0; } else if((event->keyval == GDK_KEY_Down) || (event->keyval == GDK_KEY_KP_Down)) { target = target - which; if(target+which>=(GLOBALS->traces.visible-1)) target=GLOBALS->traces.visible-which-1; } gtk_adjustment_set_value(wadj,target); } if(GLOBALS->cachedwhich_signalwindow_c_1==which) GLOBALS->cachedwhich_signalwindow_c_1=which-1; /* force update */ g_signal_emit_by_name (XXX_GTK_OBJECT (wadj), "changed"); /* force bar update */ g_signal_emit_by_name (XXX_GTK_OBJECT (wadj), "value_changed"); /* force text update */ } } if((num_traces_displayabletraces.visible) && (!ud_kill)) { switch(event->keyval) { case GDK_KEY_Down: case GDK_KEY_KP_Down: case GDK_KEY_Page_Down: case GDK_KEY_KP_Page_Down: yscroll = ((event->keyval == GDK_KEY_Page_Down) || (event->keyval == GDK_KEY_KP_Page_Down)) ? num_traces_displayable : 1; target=((int)gtk_adjustment_get_value(wadj))+yscroll; which=num_traces_displayable-1; if(target+which>=(GLOBALS->traces.visible-1)) target=GLOBALS->traces.visible-which-1; gtk_adjustment_set_value(wadj,target); if(GLOBALS->cachedwhich_signalwindow_c_1==which) GLOBALS->cachedwhich_signalwindow_c_1=which-1; /* force update */ g_signal_emit_by_name (XXX_GTK_OBJECT (wadj), "changed"); /* force bar update */ g_signal_emit_by_name (XXX_GTK_OBJECT (wadj), "value_changed"); /* force text update */ break; case GDK_KEY_Up: case GDK_KEY_KP_Up: case GDK_KEY_Page_Up: case GDK_KEY_KP_Page_Up: yscroll = ((event->keyval == GDK_KEY_Page_Up) || (event->keyval == GDK_KEY_KP_Page_Up)) ? num_traces_displayable : 1; target=((int)gtk_adjustment_get_value(wadj))-yscroll; if(target<0) target=0; gtk_adjustment_set_value(wadj,target); which=0; if(GLOBALS->cachedwhich_signalwindow_c_1==which) GLOBALS->cachedwhich_signalwindow_c_1=-1; /* force update */ g_signal_emit_by_name (XXX_GTK_OBJECT (wadj), "changed"); /* force bar update */ g_signal_emit_by_name (XXX_GTK_OBJECT (wadj), "value_changed"); /* force text update */ break; } } rc = TRUE; break; case GDK_KEY_Left: case GDK_KEY_KP_Left: service_left_edge(NULL, 0); /* hadj=GTK_ADJUSTMENT(GLOBALS->signal_hslider); if(gtk_adjustment_get_value(hadj) < gtk_adjustment_get_page_increment(hadj)) { gtk_adjustment_set_value(hadj, (gfloat)0.0); } else { gtk_adjustment_set_value(hadj, gtk_adjustment_get_value(hadj) - gtk_adjustment_get_page_increment(hadj)); } g_signal_emit_by_name (XXX_GTK_OBJECT (hadj), "changed"); g_signal_emit_by_name (XXX_GTK_OBJECT (hadj), "value_changed"); signalarea_configure_event(GLOBALS->signalarea, NULL); */ rc = TRUE; break; case GDK_KEY_Right: case GDK_KEY_KP_Right: service_right_edge(NULL, 0); /* hadj=GTK_ADJUSTMENT(GLOBALS->signal_hslider); if( ((int) gtk_adjustment_get_value(hadj) + gtk_adjustment_get_page_increment(hadj)) >= gtk_adjustment_get_upper(hadj)) { gtk_adjustment_set_value(hadj, (gfloat)(gtk_adjustment_get_upper(hadj))-gtk_adjustment_get_page_increment(hadj)); } else { gtk_adjustment_set_value(hadj, gtk_adjustment_get_value(hadj) + gtk_adjustment_get_page_increment(hadj)); } g_signal_emit_by_name (XXX_GTK_OBJECT (hadj), "changed"); g_signal_emit_by_name (XXX_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_KEY_a: #ifdef MAC_INTEGRATION if(event->state & GDK_META_MASK) #else if(event->state & GDK_CONTROL_MASK) #endif { if(!gtk_widget_has_focus(GLOBALS->filter_entry)) { treeview_select_all_callback(); rc = TRUE; } else { gtk_editable_select_region (GTK_EDITABLE (GLOBALS->filter_entry),0, gtk_entry_get_text_length(GTK_ENTRY(GLOBALS->filter_entry))); rc = TRUE; } } break; case GDK_KEY_A: #ifdef MAC_INTEGRATION if(event->state & GDK_META_MASK) #else if(event->state & GDK_CONTROL_MASK) #endif { if(!gtk_widget_has_focus(GLOBALS->filter_entry)) { treeview_unselect_all_callback(); rc = TRUE; } else { gtk_editable_select_region (GTK_EDITABLE (GLOBALS->filter_entry),0, 0); rc = TRUE; } } default: break; } } else if(gtk_widget_has_focus(GLOBALS->treeview_main)) { switch(event->keyval) { case GDK_KEY_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_KEY_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); } 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_KEY_Up; keypress_local(widget, &ev_fake, GLOBALS->signalarea_event_box); break; case GDK_SCROLL_DOWN: ev_fake.keyval = GDK_KEY_Down; keypress_local(widget, &ev_fake, GLOBALS->signalarea_event_box); default: break; } return(TRUE); } #if defined(WAVE_ALLOW_QUARTZ_FLUSH_WORKAROUND) || defined(WAVE_ALLOW_GTK3_VSLIDER_WORKAROUND) static gboolean osx_timer(gpointer dummy) { (void) 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 static gboolean mouseover_timer(gpointer dummy) { (void)dummy; static gboolean run_once = FALSE; gdouble x,y; GdkModifierType state; TraceEnt t_trans; gint xi, yi; 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(gtk_widget_get_window(GLOBALS->signalarea), &x, &y, &xi, &yi, &state); WAVE_GDK_GET_POINTER_COPY; GtkAllocation allocation; gtk_widget_get_allocation(GLOBALS->signalarea, &allocation); if(y > allocation.height) { wadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider); num_traces_displayable=(allocation.height)/(GLOBALS->fontheight); num_traces_displayable--; /* for the time trace that is always there */ if(num_traces_displayabletraces.visible) { yscroll = 1; target=((int)gtk_adjustment_get_value(wadj))+yscroll; which=num_traces_displayable-1; if(target+which>=(GLOBALS->traces.visible-1)) target=GLOBALS->traces.visible-which-1; gtk_adjustment_set_value(wadj,target); if(GLOBALS->cachedwhich_signalwindow_c_1==which) GLOBALS->cachedwhich_signalwindow_c_1=which-1; /* force update */ g_signal_emit_by_name (XXX_GTK_OBJECT (wadj), "changed"); /* force bar update */ g_signal_emit_by_name (XXX_GTK_OBJECT (wadj), "value_changed"); /* force text update */ } } else if(y < 0) { wadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider); num_traces_displayable=(allocation.height)/(GLOBALS->fontheight); num_traces_displayable--; /* for the time trace that is always there */ if(num_traces_displayabletraces.visible) { yscroll = 1; target=((int)gtk_adjustment_get_value(wadj))-yscroll; if(target<0) target=0; gtk_adjustment_set_value(wadj,target); which=0; if(GLOBALS->cachedwhich_signalwindow_c_1==which) GLOBALS->cachedwhich_signalwindow_c_1=-1; /* force update */ g_signal_emit_by_name (XXX_GTK_OBJECT (wadj), "changed"); /* force bar update */ g_signal_emit_by_name (XXX_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); } #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 if(process_finder_names_queued()) { if(GLOBALS->pFileChoose) { 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); } } } else { if(process_finder_name_integration()) { return(TRUE); } } } 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) || (!gtk_widget_get_window(GLOBALS->signalarea))) { 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(gtk_widget_get_window(GLOBALS->signalarea), &x, &y, &xi, &yi, &state); WAVE_GDK_GET_POINTER_COPY; GLOBALS->mouseover_counter++; GtkAllocation s_allocation; gtk_widget_get_allocation(GLOBALS->signalarea, &s_allocation); if(!((x>=0)&&(x=0)&&(ymouseover_counter == 10) { GtkAllocation allocation; gtk_widget_get_allocation(GLOBALS->wavearea, &allocation); int num_traces_displayable=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; gint xi, yi; 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; GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); 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>=allocation.width)||(event->y<0)||(event->y>=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->cr_signalpixmap)) { num_traces_displayable=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)gtk_adjustment_get_value(wadj))+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; MarkTraceCursor(t); } } } else if((event->state&GDK_SHIFT_MASK)&&(GLOBALS->starting_unshifted_trace)) { int src = -1, dst = -1, dsto = -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++; } dsto = dst; 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; } if(cnt == dsto) { MarkTraceCursor(t2); } 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; MarkTraceCursor(t); } /* 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; int scale_factor; if((!widget)||(!gtk_widget_get_window(widget))) return(TRUE); scale_factor = XXX_gtk_widget_get_scale_factor(widget); #if defined(WAVE_ALLOW_QUARTZ_FLUSH_WORKAROUND) || defined(WAVE_ALLOW_GTK3_VSLIDER_WORKAROUND) if(!GLOBALS->force_hide_show) { GLOBALS->force_hide_show = 2; } #endif make_sigarea_gcs(widget); UpdateTracesVisible(); GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); num_traces_displayable=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", allocation.height, allocation.width)); GLOBALS->old_signal_fill_width=GLOBALS->signal_fill_width; GLOBALS->signal_fill_width = ((width=allocation.width) > GLOBALS->signal_pixmap_width) ? allocation.width : GLOBALS->signal_pixmap_width; if(GLOBALS->cr_signalpixmap) { if((GLOBALS->old_signal_fill_width!=GLOBALS->signal_fill_width)||(GLOBALS->old_signal_fill_height!=allocation.height)) { cairo_destroy (GLOBALS->cr_signalpixmap); cairo_surface_destroy (GLOBALS->surface_signalpixmap); GLOBALS->surface_signalpixmap = cairo_image_surface_create (CAIRO_FORMAT_RGB24, GLOBALS->signal_fill_width*scale_factor, allocation.height*scale_factor); GLOBALS->cr_signalpixmap = cairo_create (GLOBALS->surface_signalpixmap); cairo_scale(GLOBALS->cr_signalpixmap, scale_factor, scale_factor); cairo_set_line_width(GLOBALS->cr_signalpixmap, 1.0); } } else { GLOBALS->surface_signalpixmap = cairo_image_surface_create (CAIRO_FORMAT_RGB24, GLOBALS->signal_fill_width*scale_factor, allocation.height*scale_factor); GLOBALS->cr_signalpixmap = cairo_create (GLOBALS->surface_signalpixmap); cairo_scale(GLOBALS->cr_signalpixmap, scale_factor, scale_factor); cairo_set_line_width(GLOBALS->cr_signalpixmap, 1.0); } 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->cr_signalpixmap) { hadj=GTK_ADJUSTMENT(GLOBALS->signal_hslider); /* int pos = GLOBALS->max_signal_name_pixel_width+15 - (gint)gtk_adjustment_get_value(hadj); */ if ((gint) gtk_adjustment_get_value(hadj) > delta) { GLOBALS->right_align_active = 1; delta = (gint)gtk_adjustment_get_value(hadj); } if (GLOBALS->right_align_active) gtk_adjustment_set_value(hadj, (gint)delta); } } else { GLOBALS->right_align_active = 1; } } GLOBALS->old_signal_fill_height= allocation.height; cairo_set_source_rgba (GLOBALS->cr_signalpixmap, GLOBALS->rgb_gc.gc_ltgray.r, GLOBALS->rgb_gc.gc_ltgray.g, GLOBALS->rgb_gc.gc_ltgray.b, GLOBALS->rgb_gc.gc_ltgray.a); cairo_rectangle (GLOBALS->cr_signalpixmap, 0.5, 0.5, GLOBALS->signal_fill_width, allocation.height); cairo_fill (GLOBALS->cr_signalpixmap); hadj=GTK_ADJUSTMENT(GLOBALS->signal_hslider); gtk_adjustment_set_page_increment(hadj, (gfloat)width); gtk_adjustment_set_page_size(hadj,gtk_adjustment_get_page_increment(hadj)); gtk_adjustment_set_page_increment(hadj,(gfloat)10.0); /* approx 1ch at a time */ gtk_adjustment_set_lower(hadj,(gfloat)0.0); gtk_adjustment_set_upper(hadj,(gfloat)GLOBALS->signal_pixmap_width); if( ((int)gtk_adjustment_get_value(hadj))+width > GLOBALS->signal_fill_width) { gtk_adjustment_set_value(hadj, (gfloat)(GLOBALS->signal_fill_width-width)); } /* in gtk3 there is a race condition in how updating GLOBALS->wave_vslider causes resizing during configure phase */ #ifndef WAVE_GTK3_SIZE_ALLOCATE_WORKAROUND_WAVE_VSLIDER wadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider); gtk_adjustment_set_page_size(wadj,(gfloat) num_traces_displayable); gtk_adjustment_set_page_increment(wadj,(gfloat) num_traces_displayable); gtk_adjustment_set_step_increment(wadj,(gfloat)1.0); gtk_adjustment_set_lower(wadj,(gfloat)0.0); gtk_adjustment_set_upper(wadj,(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 = gtk_adjustment_get_value(wadj); 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) { gtk_adjustment_set_value(wadj,(gfloat)(scroll_bottom - num_traces_displayable + 1)); } else { int midpoint = (cur_top + cur_bottom) / 2; if(scroll_top <= cur_top) { gtk_adjustment_set_value(wadj,(gfloat)scroll_top-1); } else if(scroll_top >= cur_bottom) { gtk_adjustment_set_value(wadj,(gfloat)(scroll_bottom - num_traces_displayable + 1)); } else if(scroll_top < midpoint) { gtk_adjustment_set_value(wadj,(gfloat)scroll_top-1); } else { gtk_adjustment_set_value(wadj,(gfloat)(scroll_bottom - num_traces_displayable + 1)); } } if(gtk_adjustment_get_value(wadj) < 0.0) gtk_adjustment_set_value(wadj, 0.0); } } } if(num_traces_displayable>GLOBALS->traces.visible) { gtk_adjustment_set_value(wadj, (gfloat)(GLOBALS->trtarget_signalwindow_c_1=0)); } else if (gtk_adjustment_get_value(wadj) + num_traces_displayable > GLOBALS->traces.visible) { gtk_adjustment_set_value(wadj,(gfloat)(GLOBALS->trtarget_signalwindow_c_1=GLOBALS->traces.visible-num_traces_displayable)); } g_signal_emit_by_name (XXX_GTK_OBJECT (wadj), "changed"); /* force bar update */ g_signal_emit_by_name (XXX_GTK_OBJECT (wadj), "value_changed"); /* force text update */ g_signal_emit_by_name (XXX_GTK_OBJECT (hadj), "changed"); /* force bar update */ #else wadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider); GLOBALS->wave_vslider_page_size = (gfloat) num_traces_displayable; GLOBALS->wave_vslider_page_increment = (gfloat) num_traces_displayable; GLOBALS->wave_vslider_step_increment = (gfloat)1.0; GLOBALS->wave_vslider_lower = (gfloat)0.0; GLOBALS->wave_vslider_upper = (gfloat)(GLOBALS->traces.visible ? GLOBALS->traces.visible : 1); GLOBALS->wave_vslider_value = gtk_adjustment_get_value(wadj); if(GLOBALS->traces.scroll_bottom) { Trptr t = GLOBALS->traces.first; int which = 0; int scroll_top = -1, scroll_bottom = -1; int cur_top = gtk_adjustment_get_value(wadj); 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) { GLOBALS->wave_vslider_value = (gfloat)(scroll_bottom - num_traces_displayable + 1); } else { int midpoint = (cur_top + cur_bottom) / 2; if(scroll_top <= cur_top) { GLOBALS->wave_vslider_value = (gfloat)scroll_top-1; } else if(scroll_top >= cur_bottom) { GLOBALS->wave_vslider_value = (gfloat)(scroll_bottom - num_traces_displayable + 1); } else if(scroll_top < midpoint) { GLOBALS->wave_vslider_value = (gfloat)scroll_top-1; } else { GLOBALS->wave_vslider_value = (gfloat)(scroll_bottom - num_traces_displayable + 1); } } if(GLOBALS->wave_vslider_value < 0.0) GLOBALS->wave_vslider_value = 0.0; } } } if(num_traces_displayable>GLOBALS->traces.visible) { GLOBALS->wave_vslider_value = (gfloat)(GLOBALS->trtarget_signalwindow_c_1=0); } else if (GLOBALS->wave_vslider_value + num_traces_displayable > GLOBALS->traces.visible) { GLOBALS->wave_vslider_value = (gfloat)(GLOBALS->trtarget_signalwindow_c_1=GLOBALS->traces.visible-num_traces_displayable); } service_vslider(NULL, NULL); /* forces update of signals */ GLOBALS->wave_vslider_valid = 1; #endif 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); } #if GTK_CHECK_VERSION(3,0,0) static gint draw_event(GtkWidget *widget, cairo_t *cr, gpointer user_data) { (void) widget; (void) user_data; gint rc = FALSE; gint page_num = gtk_notebook_get_current_page(GTK_NOTEBOOK(GLOBALS->notebook)); /* struct Global *g_old = GLOBALS; */ set_GLOBALS((*GLOBALS->contexts)[page_num]); signalwindow_paint(cr); draw_signalarea_focus(cr); /* seems to cause a conflict flipping back so don't! */ /* set_GLOBALS(g_old); */ return(rc); } #else static gint expose_event(GtkWidget *widget, GdkEventExpose *event) { #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX GdkDrawingContext *gdc; #endif cairo_t* cr = XXX_gdk_cairo_create (XXX_GDK_DRAWABLE (gtk_widget_get_window(widget)), &gdc); gdk_cairo_region (cr, event->region); cairo_clip (cr); signalwindow_paint(cr); draw_signalarea_focus(cr); #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX gdk_window_end_draw_frame(gtk_widget_get_window(widget), gdc); #else cairo_destroy (cr); #endif 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); } #endif 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 = XXX_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_SCROLL_MASK | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK ); g_signal_connect(XXX_GTK_OBJECT(GLOBALS->signalarea), "configure_event", G_CALLBACK(signalarea_configure_event_local), NULL); #if GTK_CHECK_VERSION(3,0,0) g_signal_connect(XXX_GTK_OBJECT(GLOBALS->signalarea), "draw", G_CALLBACK(draw_event), NULL); #else g_signal_connect(XXX_GTK_OBJECT(GLOBALS->signalarea), "expose_event",G_CALLBACK(expose_event_local), NULL); #endif 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(XXX_GTK_OBJECT(GLOBALS->signalarea), "drag_motion", G_CALLBACK(DNDDragMotionCB), GTK_WIDGET(GLOBALS->signalarea)); gtkwave_signal_connect(XXX_GTK_OBJECT(GLOBALS->signalarea), "drag_begin", G_CALLBACK(DNDBeginCB), GTK_WIDGET(GLOBALS->signalarea)); gtkwave_signal_connect(XXX_GTK_OBJECT(GLOBALS->signalarea), "drag_end", G_CALLBACK(DNDEndCB), GTK_WIDGET(GLOBALS->signalarea)); gtkwave_signal_connect(XXX_GTK_OBJECT(GLOBALS->signalarea), "drag_failed", G_CALLBACK(DNDFailedCB), 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(XXX_GTK_OBJECT(GLOBALS->wavearea), "drag_motion", G_CALLBACK(DNDDragMotionCB), GTK_WIDGET(GLOBALS->wavearea)); gtkwave_signal_connect(XXX_GTK_OBJECT(GLOBALS->wavearea), "drag_begin", G_CALLBACK(DNDBeginCB), GTK_WIDGET(GLOBALS->wavearea)); gtkwave_signal_connect(XXX_GTK_OBJECT(GLOBALS->wavearea), "drag_end", G_CALLBACK(DNDEndCB), GTK_WIDGET(GLOBALS->wavearea)); gtkwave_signal_connect(XXX_GTK_OBJECT(GLOBALS->wavearea), "drag_failed", G_CALLBACK(DNDFailedCB), 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(XXX_GTK_OBJECT(GLOBALS->signalarea), "button_press_event",G_CALLBACK(button_press_event_std), NULL); gtkwave_signal_connect(XXX_GTK_OBJECT(GLOBALS->signalarea), "button_release_event", G_CALLBACK(button_release_event_std), NULL); gtkwave_signal_connect(XXX_GTK_OBJECT(GLOBALS->signalarea), "motion_notify_event",G_CALLBACK(motion_notify_event_std), NULL); g_timeout_add(100, mouseover_timer, NULL); #if defined(WAVE_ALLOW_QUARTZ_FLUSH_WORKAROUND) || defined(WAVE_ALLOW_GTK3_VSLIDER_WORKAROUND) g_timeout_add(100, osx_timer, NULL); #endif gtkwave_signal_connect(XXX_GTK_OBJECT(GLOBALS->signalarea), "scroll_event",G_CALLBACK(scroll_event), NULL); 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; } XXX_gtk_table_attach (XXX_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(XXX_GTK_OBJECT(GLOBALS->signal_hslider), "value_changed",G_CALLBACK(service_hslider), NULL); GLOBALS->hscroll_signalwindow_c_1=XXX_gtk_hscrollbar_new(GTK_ADJUSTMENT(GLOBALS->signal_hslider)); gtk_widget_show(GLOBALS->hscroll_signalwindow_c_1); #ifdef WAVE_ALLOW_GTK3_GRID XXX_gtk_table_attach (XXX_GTK_TABLE (table), GLOBALS->hscroll_signalwindow_c_1, 0, 10, 9, 10, 0, GTK_SHRINK, 3, 4); #else XXX_gtk_table_attach (XXX_GTK_TABLE (table), GLOBALS->hscroll_signalwindow_c_1, 0, 10, 9, 10, GTK_FILL, GTK_FILL | GTK_SHRINK, 3, 4); #endif gtk_widget_show(table); frame=gtk_frame_new("Signals"); gtk_container_set_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_can_default(GTK_WIDGET(GLOBALS->signalarea_event_box), TRUE); gtk_widget_set_can_focus(GTK_WIDGET(GLOBALS->signalarea_event_box), TRUE); gtkwave_signal_connect(XXX_GTK_OBJECT(GLOBALS->signalarea_event_box), "focus_in_event", G_CALLBACK(focus_in_local), NULL); gtkwave_signal_connect(XXX_GTK_OBJECT(GLOBALS->signalarea_event_box), "focus_out_event", G_CALLBACK(focus_out_local), NULL); /* not necessary for now... */ /* gtkwave_signal_connect(XXX_GTK_OBJECT(GLOBALS->signalarea_event_box), "popup_menu",G_CALLBACK(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 = g_signal_connect(XXX_GTK_OBJECT(GLOBALS->mainwindow), "key_press_event",G_CALLBACK(keypress_local), NULL); return(rc); } void remove_keypress_handler(gint id) { g_signal_handler_disconnect(XXX_GTK_OBJECT(GLOBALS->mainwindow), id); } gtkwave-gtk3-3.3.125/src/vlist.h0000664000175000017500000000375515047725112015630 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-gtk3-3.3.125/src/liblzma/0000775000175000017500000000000015047725112015736 5ustar bybellbybellgtkwave-gtk3-3.3.125/src/liblzma/LzmaLib.c0000664000175000017500000002112415047725112017434 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; }; /* * report abort messages */ static void chk_report_abort(const char *s) { fprintf(stderr,"Triggered %s security check, exiting.\n", s); abort(); } 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) { int chk_len = 16; /* TALOS-2023-1811 */ unsigned char buf[chk_len]; int idx = 0; size_t rc = 0; while(idxread_cnt += read(h->fd, buf+idx, 1); if(buf[idx++] & 0x80) break; } if(idx == chk_len) { chk_report_abort("TALOS-2023-1811"); } 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->blksiz) /* TALOS-2023-1810 */ { if(h->dmem) { free(h->dmem); } if(h->mem) { free(h->mem); } h->blksiz = srclen; h->mem = malloc(h->blksiz); h->dmem = malloc(h->blksiz); } 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)); /* TALOS-2023-1810: srclen used here, generally ok as data are compressible */ 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-gtk3-3.3.125/src/liblzma/LzmaLib.h0000664000175000017500000000270515047725112017445 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-gtk3-3.3.125/src/liblzma/lzma.txt0000664000175000017500000000036315047725112017444 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-gtk3-3.3.125/src/liblzma/Makefile.in0000664000175000017500000004227715047725112020017 0ustar bybellbybell# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : 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@ GLIB_COMPILE_SCHEMAS = @GLIB_COMPILE_SCHEMAS@ GPERF = @GPERF@ GREP = @GREP@ GSETTINGS_CFLAGS = @GSETTINGS_CFLAGS@ GSETTINGS_DISABLE_SCHEMAS_COMPILE = @GSETTINGS_DISABLE_SCHEMAS_COMPILE@ GTK_CFLAGS = @GTK_CFLAGS@ 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_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_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@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ RANLIB = @RANLIB@ RPC_CFLAGS = @RPC_CFLAGS@ RPC_LDADD = @RPC_LDADD@ 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@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ 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@ gsettingsschemadir = @gsettingsschemadir@ 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-gtk3-3.3.125/src/liblzma/Makefile.am0000664000175000017500000000022215047725112017766 0ustar bybellbybell## -*- makefile -*- ## noinst_LIBRARIES= libgwlzma.a AM_CFLAGS= $(LIBXZ_CFLAGS) libgwlzma_a_SOURCES= LzmaLib.c LzmaLib.h EXTRA_DIST= lzma.txt gtkwave-gtk3-3.3.125/src/signalwindow.h0000664000175000017500000000164115047725112017164 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(cairo_t *cr); gint signalarea_configure_event(GtkWidget *widget, GdkEventConfigure *event); void dnd_error(void); gint install_keypress_handler(void); void remove_keypress_handler(gint id); void signalwindow_paint(cairo_t* cr); #endif gtkwave-gtk3-3.3.125/src/lx2.h0000664000175000017500000000200115047725112015153 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-gtk3-3.3.125/src/fsdb_wrapper_api.h0000664000175000017500000000436115047725112017770 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); void fsdbReaderReadScopeVarTree2(void *ctx,void (*cb)(void *)); #ifdef __cplusplus } #endif #endif gtkwave-gtk3-3.3.125/src/color.c0000664000175000017500000000323215047725112015566 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 */ wave_rgb_t XXX_alloc_color(int tuple) { wave_rgb_t rc; int red, green, blue; red= (tuple>>16)&0x000000ff; green=(tuple>>8) &0x000000ff; blue= (tuple) &0x000000ff; rc.r = (double)red/255; rc.g = (double)green/255; rc.b = (double)blue/255; rc.a = (double)1.0; return(rc); } void XXX_set_alternate_gcs(wave_rgb_t ctx, wave_rgb_t ctx_fill) { GLOBALS->rgb_gc.gc_low_wavewindow_c_1 = ctx; GLOBALS->rgb_gc.gc_high_wavewindow_c_1 = ctx; GLOBALS->rgb_gc.gc_trans_wavewindow_c_1 = ctx; GLOBALS->rgb_gc.gc_0_wavewindow_c_1 = ctx; GLOBALS->rgb_gc.gc_1_wavewindow_c_1 = ctx; GLOBALS->rgb_gc.gc_vbox_wavewindow_c_1 = ctx; GLOBALS->rgb_gc.gc_vtrans_wavewindow_c_1 = ctx; if(!GLOBALS->keep_xz_colors) { GLOBALS->rgb_gc.gc_mid_wavewindow_c_1 = ctx; GLOBALS->rgb_gc.gc_highfill_wavewindow_c_1 = ctx_fill; GLOBALS->rgb_gc.gc_1fill_wavewindow_c_1 = ctx_fill; GLOBALS->rgb_gc.gc_xfill_wavewindow_c_1 = ctx_fill; GLOBALS->rgb_gc.gc_x_wavewindow_c_1 = ctx; GLOBALS->rgb_gc.gc_ufill_wavewindow_c_1 = ctx_fill; GLOBALS->rgb_gc.gc_u_wavewindow_c_1 = ctx; GLOBALS->rgb_gc.gc_wfill_wavewindow_c_1 = ctx_fill; GLOBALS->rgb_gc.gc_w_wavewindow_c_1 = ctx; GLOBALS->rgb_gc.gc_dashfill_wavewindow_c_1 = ctx_fill; GLOBALS->rgb_gc.gc_dash_wavewindow_c_1 = ctx; } } gtkwave-gtk3-3.3.125/src/tcl_helper.c0000664000175000017500000023573015047725112016603 0ustar bybellbybell/* * Copyright (c) Tony Bybell and Concept Engineering GmbH 2008-2016. * * 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 #include #include #include #include "gtk23compat.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__ #include #include #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) { 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) { 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; 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) { 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) { 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(gtk_widget_get_window(GLOBALS->signalarea), &x, &y, &xi, &yi, &state); WAVE_GDK_GET_POINTER_COPY; GtkAllocation allocation; gtk_widget_get_allocation(GLOBALS->signalarea, &allocation); if((x<0)||(y<0)||(x>=allocation.width)||(y>=allocation.height)) return(NULL); } else if(GLOBALS->dnd_tgt_on_wavearea_treesearch_gtk2_c_1) { WAVE_GDK_GET_POINTER(gtk_widget_get_window(GLOBALS->wavearea), &x, &y, &xi, &yi, &state); WAVE_GDK_GET_POINTER_COPY; GtkAllocation allocation; gtk_widget_get_allocation(GLOBALS->wavearea, &allocation); if((x<0)||(y<0)||(x>=allocation.width)||(y>=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 * ---------------------------------------------------------------------------- */ void process_tcl_list_2(struct symbol *s, int which_msb, int which_lsb) { Trptr t; nptr nexp; int i; TraceFlagsType default_flags = GLOBALS->default_flags; bvptr v; Trptr buffer; /* cut/copy buffer of traces */ Trptr bufferlast; /* last element of bufferchain */ int buffercount; /* number of traces in buffer */ GLOBALS->default_flags = TR_HIGHLIGHT; buffer = GLOBALS->traces.buffer; /* copy cut buffer to make re-entrant */ bufferlast = GLOBALS->traces.bufferlast; buffercount = GLOBALS->traces.buffercount; GLOBALS->traces.buffer = NULL; GLOBALS->traces.bufferlast = NULL; GLOBALS->traces.buffercount = 0; t=GLOBALS->traces.first; while(t) { if(t->flags&TR_HIGHLIGHT) /* copy TR_HIGHLIGHT->TR_RSVD and clear TR_HIGHLIGHT */ { t->flags&=(~TR_HIGHLIGHT); t->flags|=TR_RSVD; } else { t->flags&=(~TR_RSVD); } t=t->t_next; } if(which_msb <= which_lsb) { for(i=which_msb;i<=which_lsb;i++) { nexp = ExtractNodeSingleBit(s->n, i); if(nexp) { AddNode(nexp, NULL); } else { AddNodeUnroll(s->n, NULL); } } } else { for(i=which_msb;i>=which_lsb;i--) { nexp = ExtractNodeSingleBit(s->n, i); if(nexp) { AddNode(nexp, NULL); } else { AddNodeUnroll(s->n, NULL); } } } v = combine_traces(1, NULL); /* down */ if (v) { 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); CloseTrace(t); } t=GLOBALS->traces.first; while(t) { t->flags &= ~TR_HIGHLIGHT; if(t->flags&TR_RSVD) /* copy TR_RSVD->TR_HIGHLIGHT and clear TR_RSVD */ { t->flags|=TR_HIGHLIGHT; t->flags&=(~TR_RSVD); } t=t->t_next; } GLOBALS->traces.buffer = buffer; /* restore cut buffer */ GLOBALS->traces.bufferlast = bufferlast; GLOBALS->traces.buffercount = buffercount; GLOBALS->default_flags = default_flags; } 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; char **most_recent_colon_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 *)); most_recent_colon_list = calloc_2(c, sizeof(char *)); GLOBALS->default_flags=TR_RJUSTIFY; GLOBALS->default_fpshift=0; 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; } most_recent_colon_list[ii]=strchr(most_recent_lbrack_list[ii], ':'); } 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_msb = atoi(most_recent_lbrack_list[ii]+1 + (match_type_list[ii] == 3)); /* == 3 for adjustment when lbrack is escaped */ int bit_lsb; /* = bit_msb; scan-build: never read */ int which_msb, which_lsb, cnt; if(s->n->lsi > s->n->msi) { for(which_msb=0,cnt=s->n->msi ; cnt<=s->n->lsi ; cnt++,which_msb++) { if(cnt==bit_msb) break; } } else { for(which_msb=0,cnt=s->n->msi ; cnt>=s->n->lsi ; cnt--,which_msb++) { if(cnt==bit_msb) break; } } which_lsb = which_msb; /* Need to fix this to extract more than a single bit as in the case of a subrange of an existing vector! */ if(most_recent_colon_list[ii]) { bit_lsb = atoi(most_recent_colon_list[ii]+1); if(s->n->lsi > s->n->msi) { for(which_lsb=0,cnt=s->n->msi ; cnt<=s->n->lsi ; cnt++,which_lsb++) { if(cnt==bit_lsb) break; } } else { for(which_lsb=0,cnt=s->n->msi ; cnt>=s->n->lsi ; cnt--,which_lsb++) { if(cnt==bit_lsb) break; } } } if(which_msb == which_lsb) { nexp = ExtractNodeSingleBit(s->n, which_msb); *most_recent_lbrack_list[ii] = '['; if(nexp) { AddNode(nexp, NULL); } else { AddNodeUnroll(s->n, NULL); } } else { process_tcl_list_2(s, which_msb, which_lsb); /* is complicated, so split out to its own function */ } } 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->default_fpshift=0; 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; TraceFlagsType 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; GtkTreeIter iter; enum { NAME_COLUMN, PTR_COLUMN, N_COLUMNS }; gtk_tree_model_get_iter_first (GTK_TREE_MODEL (GLOBALS->sig_store_search), &iter); for(i=0;inum_rows_search_c_2;i++) { struct symbol *s, *t; gtk_tree_model_get(GTK_TREE_MODEL (GLOBALS->sig_store_search), &iter, PTR_COLUMN, &s, -1); gtk_tree_model_iter_next (GTK_TREE_MODEL (GLOBALS->sig_store_search), &iter); 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; } } } } gtk_tree_model_get_iter_first (GTK_TREE_MODEL (GLOBALS->sig_store_search), &iter); for(i=0;inum_rows_search_c_2;i++) { int len; struct symbol *s, *t; gtk_tree_model_get(GTK_TREE_MODEL (GLOBALS->sig_store_search), &iter, PTR_COLUMN, &s, -1); gtk_tree_model_iter_next (GTK_TREE_MODEL (GLOBALS->sig_store_search), &iter); 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 * ---------------------------------------------------------------------------- */ 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; } /* ---------------------------------------------------------------------------- * 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) { 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); } /* ---------------------------------------------------------------------------- * 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; TraceFlagsType prev_flags = 0; TraceFlagsType 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("@%"TRACEFLAGSPRIFMT"\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->t_fpdecshift) { one_entry = make_message("[fpshift_count] %d\n", t->t_fpdecshift); 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" %"TRACEFLAGSPRIFMT, 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 __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 * ---------------------------------------------------------------------------- */ 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); } /* ---------------------------------------------------------------------------- * 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; 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(8 + nlen + 1 + 1); strcpy(tcl_cmd, "source {"); strcpy(tcl_cmd+8, nam); strcpy(tcl_cmd+8+nlen, "}"); 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(8 + nlen + 1 + 1); strcpy(tcl_cmd, "source {"); strcpy(tcl_cmd+8, GLOBALS->repscript_name); strcpy(tcl_cmd+8+nlen, "}"); 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-gtk3-3.3.125/src/color.h0000664000175000017500000000461715047725112015603 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 RGB_WAVE_RAINBOW_INITIALIZER {{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0},{0.0,0.0,0.0,0.0}} struct wave_rgb_t { double r, g, b, a; }; typedef struct wave_rgb_t wave_rgb_t; struct wave_rgbmaster_t { wave_rgb_t gc_ltgray; wave_rgb_t gc_normal; wave_rgb_t gc_mdgray; wave_rgb_t gc_dkgray; wave_rgb_t gc_dkblue; wave_rgb_t gc_brkred; wave_rgb_t gc_ltblue; wave_rgb_t gc_gmstrd; wave_rgb_t gc_back_wavewindow_c_1; wave_rgb_t gc_baseline_wavewindow_c_1; wave_rgb_t gc_grid_wavewindow_c_1; wave_rgb_t gc_grid2_wavewindow_c_1; wave_rgb_t gc_time_wavewindow_c_1; wave_rgb_t gc_timeb_wavewindow_c_1; wave_rgb_t gc_value_wavewindow_c_1; wave_rgb_t gc_low_wavewindow_c_1; wave_rgb_t gc_highfill_wavewindow_c_1; wave_rgb_t gc_high_wavewindow_c_1; wave_rgb_t gc_trans_wavewindow_c_1; wave_rgb_t gc_mid_wavewindow_c_1; wave_rgb_t gc_xfill_wavewindow_c_1; wave_rgb_t gc_x_wavewindow_c_1; wave_rgb_t gc_vbox_wavewindow_c_1; wave_rgb_t gc_vtrans_wavewindow_c_1; wave_rgb_t gc_mark_wavewindow_c_1; wave_rgb_t gc_umark_wavewindow_c_1; wave_rgb_t gc_0_wavewindow_c_1; wave_rgb_t gc_1fill_wavewindow_c_1; wave_rgb_t gc_1_wavewindow_c_1; wave_rgb_t gc_ufill_wavewindow_c_1; wave_rgb_t gc_u_wavewindow_c_1; wave_rgb_t gc_wfill_wavewindow_c_1; wave_rgb_t gc_w_wavewindow_c_1; wave_rgb_t gc_dashfill_wavewindow_c_1; wave_rgb_t gc_dash_wavewindow_c_1; }; void XXX_set_alternate_gcs(wave_rgb_t ctx, wave_rgb_t ctx_fill); wave_rgb_t XXX_alloc_color(int tuple); #endif gtkwave-gtk3-3.3.125/src/gnu_regex.c0000664000175000017500000055742215047725112016452 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-gtk3-3.3.125/src/tcl_helper.h0000664000175000017500000000527715047725112016611 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)(void *, Tcl_Interp *, int, Tcl_Obj * const *); } 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-gtk3-3.3.125/src/gnu_regex.h0000664000175000017500000005030715047725112016445 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-gtk3-3.3.125/src/markerbox.c0000664000175000017500000003176615047725112016457 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2016. * * 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 "gtk23compat.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(const 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(const 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_editable_select_region (GTK_EDITABLE (entry), 0, gtk_entry_get_text_length(GTK_ENTRY(entry))); } 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_editable_select_region (GTK_EDITABLE (entry), 0, gtk_entry_get_text_length(GTK_ENTRY(entry))); 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, GCallback 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) { XXX_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(XXX_GTK_OBJECT (GLOBALS->window_markerbox_c_4), "delete_event",(GCallback) destroy_callback, NULL); vbox = XXX_gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox); vbox_g = XXX_gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox_g); table = XXX_gtk_table_new (256, 1, FALSE); gtk_widget_show (table); XXX_gtk_table_attach (XXX_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_set_border_width (GTK_CONTAINER (frame), 3); gtk_widget_show(frame); scrolled_win = gtk_scrolled_window_new (NULL, NULL); gtk_widget_set_size_request( 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); #if GTK_CHECK_VERSION(3,0,0) gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0); #else gtk_container_add (GTK_CONTAINER (vbox), frame); #endif for(i=0;ientries_markerbox_c_1[i]=entry = X_gtk_entry_new_with_max_length (48); gtkwave_signal_connect(XXX_GTK_OBJECT(entry), "activate", G_CALLBACK(enter_callback), (void *)((intptr_t) i)); gtkwave_signal_connect(XXX_GTK_OBJECT(entry), "changed", G_CALLBACK(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 = X_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(XXX_GTK_OBJECT(entry), "activate", G_CALLBACK(str_enter_callback), (void *)((intptr_t) i)); gtkwave_signal_connect(XXX_GTK_OBJECT(entry), "changed", G_CALLBACK(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); } #if GTK_CHECK_VERSION(3,0,0) gtk_container_add(GTK_CONTAINER(scrolled_win), vbox_g); /* GTK3: removes deprecated warning */ #else gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_win), vbox_g); #endif hbox = XXX_gtk_hbox_new (FALSE, 1); gtk_widget_show (hbox); XXX_gtk_table_attach (XXX_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_size_request(button1, 100, -1); gtkwave_signal_connect(XXX_GTK_OBJECT (button1), "clicked", G_CALLBACK(ok_callback), NULL); gtk_widget_show (button1); #if GTK_CHECK_VERSION(3,0,0) gtk_box_pack_start(GTK_BOX(hbox), button1, TRUE, TRUE, 0); #else gtk_container_add (GTK_CONTAINER (hbox), button1); #endif gtk_widget_set_can_default (button1, TRUE); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button1), "realize", (GCallback) gtk_widget_grab_default, XXX_GTK_OBJECT (button1)); button2 = gtk_button_new_with_label ("Cancel"); gtk_widget_set_size_request(button2, 100, -1); gtkwave_signal_connect(XXX_GTK_OBJECT (button2), "clicked", G_CALLBACK(destroy_callback), NULL); gtk_widget_set_can_default (button2, TRUE); gtk_widget_show (button2); #if GTK_CHECK_VERSION(3,0,0) gtk_box_pack_end(GTK_BOX(hbox), button2, TRUE, TRUE, 0); #else gtk_container_add (GTK_CONTAINER (hbox), button2); #endif 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-gtk3-3.3.125/src/shiftbuttons.c0000664000175000017500000001047515047725112017213 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." " Ctrl + Scrollwheel Up also does this in non-alternative wheel mode." ); return; } if(GLOBALS->nspx>1.0) inc=GLOBALS->nspx; else inc=1.0; hadj=GTK_ADJUSTMENT(GLOBALS->wave_hslider); if((gtk_adjustment_get_value(hadj)-inc)>GLOBALS->tims.first) gtk_adjustment_set_value(hadj, gtk_adjustment_get_value(hadj)-inc); else gtk_adjustment_set_value(hadj, 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." " Ctrl + Scrollwheel Down also does this in non-alternative wheel mode." ); return; } if(GLOBALS->nspx>1.0) inc=GLOBALS->nspx; else inc=1.0; ntinc=(TimeType)inc; hadj=GTK_ADJUSTMENT(GLOBALS->wave_hslider); if((gtk_adjustment_get_value(hadj)+inc)tims.last) gtk_adjustment_set_value(hadj, gtk_adjustment_get_value(hadj)+inc); else gtk_adjustment_set_value(hadj, 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; pixmapwid1=gtk_image_new_from_pixbuf(GLOBALS->larrow_pixbuf); gtk_widget_show(pixmapwid1); pixmapwid2=gtk_image_new_from_pixbuf(GLOBALS->rarrow_pixbuf); gtk_widget_show(pixmapwid2); /* Create a table to hold the text widget and scrollbars */ table = XXX_gtk_table_new (1, 1, FALSE); main_vbox = XXX_gtk_vbox_new (FALSE, 1); gtk_container_set_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 = XXX_gtk_table_new (2, 1, FALSE); b1 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b1), pixmapwid1); XXX_gtk_table_attach (XXX_GTK_TABLE (table2), b1, 0, 1, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); g_signal_connect_swapped (XXX_GTK_OBJECT (b1), "clicked", G_CALLBACK(service_left_shift), XXX_GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(b1, "Shift Left 1 Tick"); gtk_widget_show(b1); b2 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b2), pixmapwid2); XXX_gtk_table_attach (XXX_GTK_TABLE (table2), b2, 0, 1, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); g_signal_connect_swapped (XXX_GTK_OBJECT (b2), "clicked", G_CALLBACK(service_right_shift), XXX_GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(b2, "Shift Right 1 Tick"); gtk_widget_show(b2); gtk_container_add (GTK_CONTAINER (frame), table2); gtk_widget_show(table2); return(table); } gtkwave-gtk3-3.3.125/src/markerbox.h0000664000175000017500000000163715047725112016456 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, GCallback func); char *make_bijective_marker_id_string(char *buf, unsigned int value); unsigned int bijective_marker_id_string_hash(const char *so); unsigned int bijective_marker_id_string_len(const char *s); #endif gtkwave-gtk3-3.3.125/src/shiftbuttons.h0000664000175000017500000000073615047725112017217 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-gtk3-3.3.125/src/menu.c0000664000175000017500000073215515047725112015431 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2017. * * 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 "gtk23compat.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__ #include #include #else #include #include #endif #undef WAVE_USE_MENU_BLACKOUTS static gtkwave_mlist_t menu_items[WV_MENU_NUMITEMS]; static GtkWidget **menu_wlist=NULL; 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 */ void menu_scale_to_td_x(GtkWidget *widget, gpointer data) { (void)widget; (void)data; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nScale To Time Dimension: None"); help_text( " turns off time dimension conversion." ); } else { if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) { GLOBALS->scale_to_time_dimension = 0; set_scale_to_time_dimension_toggles(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } } void menu_scale_to_td_s(GtkWidget *widget, gpointer data) { (void)widget; (void)data; 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 { if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) { GLOBALS->scale_to_time_dimension = 's'; set_scale_to_time_dimension_toggles(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } } void menu_scale_to_td_m(GtkWidget *widget, gpointer data) { (void)widget; (void)data; 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 { if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) { GLOBALS->scale_to_time_dimension = 'm'; set_scale_to_time_dimension_toggles(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } } void menu_scale_to_td_u(GtkWidget *widget, gpointer data) { (void)widget; (void)data; 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 { if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) { GLOBALS->scale_to_time_dimension = 'u'; set_scale_to_time_dimension_toggles(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } } void menu_scale_to_td_n(GtkWidget *widget, gpointer data) { (void)widget; (void)data; 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 { if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) { GLOBALS->scale_to_time_dimension = 'n'; set_scale_to_time_dimension_toggles(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } } void menu_scale_to_td_p(GtkWidget *widget, gpointer data) { (void)widget; (void)data; 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 { if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) { GLOBALS->scale_to_time_dimension = 'p'; set_scale_to_time_dimension_toggles(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } } void menu_scale_to_td_f(GtkWidget *widget, gpointer data) { (void)widget; (void)data; 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 { if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) { 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,G_CALLBACK(menu_write_lxt_file_cleanup), G_CALLBACK(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,G_CALLBACK(menu_write_vcd_file_cleanup), G_CALLBACK(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,G_CALLBACK(menu_write_tim_file_cleanup), G_CALLBACK(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,G_CALLBACK(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 { 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"); } } } 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 { 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"); } } } /**/ 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 { GLOBALS->keep_xz_colors = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_KEEPXZ])); } 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 { 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"); } } } 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 { 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"); } } } 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 { 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"); } } } 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 { 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"); } } } 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,G_CALLBACK(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 { 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); } } } /**/ 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 { 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"); } } } /**/ 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 { 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"); } calczoom(GLOBALS->tims.zoom); if(GLOBALS->wave_hslider) { fix_wavehadj(); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */ g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed"); /* force zoom update */ update_maxmarker_labels(); } } } /**/ 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 { 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"); } if(GLOBALS->wave_hslider) { calczoom(GLOBALS->tims.zoom); fix_wavehadj(); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */ g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed"); /* force zoom update */ } } } /**/ 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 { 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"); } } } /**/ 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 { 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"); } } } /**/ 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 { 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"); } } } /**/ 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 { 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"); } } } /**/ void menu_enable_dynamic_resize(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\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 { 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) { for(i=0;i<2;i++) { GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } } } /**/ 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); 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->save_on_exit) { fileselbox("Write Save File On Exit",&GLOBALS->filesel_writesave,G_CALLBACK(menu_write_save_cleanup), G_CALLBACK(NULL), GLOBALS->is_gtkw_save_file ? "*.gtkw" : "*.sav", 1); /* was: menu_write_save_file(NULL, 0, NULL); */ } if(!GLOBALS->enable_fast_exit) { simplereqbox("Quit Program",300,"Do you really want to quit?","Yes", "No", G_CALLBACK(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->save_on_exit) { fileselbox("Write Save File On Exit",&GLOBALS->filesel_writesave,G_CALLBACK(menu_write_save_cleanup), G_CALLBACK(NULL), GLOBALS->is_gtkw_save_file ? "*.gtkw" : "*.sav", 1); /* was: menu_write_save_file(NULL, 0, NULL); */ } if((GLOBALS->num_notebook_pages < 2) && (!GLOBALS->enable_fast_exit)) { simplereqbox("Quit Program",300,"Do you really want to quit?","Yes", "No", G_CALLBACK(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(); } } 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,G_CALLBACK(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 < gtk_adjustment_get_value(wadj)) { 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,G_CALLBACK(rename_cleanup)); if(was_packed) { free_2(current); } } else { must_sel(); } } bvptr combine_traces(int direction, Trptr single_trace_only) { Trptr t, tmp; Trptr tfirst = NULL; 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; } tfirst = t; 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((!aname) && !single_trace_only) /* ajb 020716: recent add to handle combine down on 2D vectors */ { char *t_topname = NULL; char *t_botname = NULL; t = tfirst; while(t) { if(t->flags&TR_HIGHLIGHT) { if(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH)) { /* nothing */ } else { if(t->vector) { char *vname = t->n.vec ? t->n.vec->bvname : NULL; if(vname) { if(!t_topname) { t_topname = vname; } else { t_botname = vname; } } } else { if(!t_topname) { t_topname = t->n.nd->nname; } else { t_botname = t->n.nd->nname; } if(t_topname && t_botname) { char *mat = attempt_vecmatch(t_topname, t_botname); if(!mat) { t_topname = t_botname = NULL; break; } else { free_2(mat); } } } } } t=t->t_next; } if(t_topname && t_botname) { aname = direction ? attempt_vecmatch(t_topname, t_botname) : attempt_vecmatch(t_botname, t_topname); /* return this match */ } } 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; int row = 0, bit = 0; int row2 = 0, bit2 = 0; int is_2d = 0; int iy, offsety; char *namey; char sep2d = ':'; 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; if(ix>3) /* is_2d is for handling 2-d stored in 1-d vector */ { if(namex[ix-1]==']') { int j = ix-2; for(;j>=0;j--) { if(namex[j]=='[') break; } if(j>-1) { int items = sscanf(namex+j, "[%d][%d]", &row, &bit); if(items == 2) { /* printf(">> %d %d (items = %d)\n", row, bit, items); */ offset = j; is_2d = 1; } } } } nam=(char *)wave_alloca(offset+50); /* to handle [a:b][c:d] case */ memcpy(nam, namex, offset); if(was_packed) { free_2(namex); } if(is_2d) { is_2d = 0; namey = hier_decompress_flagged(n[nodepnt-1]->nname, &was_packed); offsety = strlen(namey); for(iy=offsety-1;iy>=0;iy--) { if(namey[iy]=='[') break; } /* if(iy>-1) offsety=iy; not needed as in above as gets overwritten below by offsety = j */ if(iy>3) { if(namey[iy-1]==']') { int j = iy-2; for(;j>=0;j--) { if(namey[j]=='[') break; } if(j>-1) { int items = sscanf(namey+j, "[%d][%d]", &row2, &bit2); if(items == 2) { int rowabs, bitabs, width2d; /* printf(">> %d %d (items = %d)\n", row2, bit2, items); */ offsety = j; is_2d = (offset == offsety) && !memcmp(nam, namey, offsety); rowabs = (row2 > row) ? (row2 - row + 1) : (row - row2 + 1); bitabs = (bit2 > bit) ? (bit2 - bit + 1) : (bit - bit2 + 1); width2d = rowabs * bitabs; sep2d = (width2d == nodepnt) ? ':' : '|'; } } } } if(was_packed) { free_2(namey); } } if(direction) { if(!is_2d) { sprintf(nam+offset, "[%d%s%d]", n[0]->expansion->actual, (bitblast_delta!=0) ? ":" : "|", n[nodepnt-1]->expansion->actual); } else { if(row == row2) { if(bit == bit2) { sprintf(nam+offset, "[%d][%d]", row, bit); } else { sprintf(nam+offset, "[%d][%d%c%d]", row, bit, sep2d, bit2); } } else { if(bit == bit2) { sprintf(nam+offset, "[%d%c%d][%d]", row, sep2d, row2, bit); } else { sprintf(nam+offset, "[%d%c%d][%d%c%d]", row, sep2d, row2, bit, sep2d, bit2); } } } } else { if(!is_2d) { sprintf(nam+offset, "[%d%s%d]", n[nodepnt-1]->expansion->actual, (bitblast_delta!=0) ? ":" : "|", n[0]->expansion->actual); } else { if(row == row2) { if(bit == bit2) { sprintf(nam+offset, "[%d][%d]", row, bit); } else { sprintf(nam+offset, "[%d][%d%c%d]", row, bit2, sep2d, bit); } } else { if(bit == bit2) { sprintf(nam+offset, "[%d%c%d][%d]", row2, sep2d, row, bit); } else { sprintf(nam+offset, "[%d%c%d][%d%c%d]", row2, sep2d, row, bit2, sep2d, bit); } } } } 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]; intptr_t 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, G_CALLBACK(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) { XXX_gdk_pointer_ungrab(GDK_CURRENT_TIME); } #if !defined __MINGW32__ /* * 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,G_CALLBACK(menu_new_viewer_cleanup), G_CALLBACK(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) { XXX_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) { #ifndef WAVE_ALLOW_GTK3_HEADER_BAR gtk_widget_set_sensitive(g_old->missing_file_toolbar, TRUE); #else GList *chld = gtk_container_get_children (GTK_CONTAINER(GLOBALS->missing_file_toolbar)); GList *p = chld; while(p) { GtkWidget *wp = p->data; gtk_widget_set_sensitive(GTK_WIDGET(wp), TRUE); p = p->next; } g_list_free(chld); #endif } 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; if((!GLOBALS->socket_xid)&&(!GLOBALS->partial_vcd)) { fileselbox("Select a trace to view...",&GLOBALS->filesel_newviewer_menu_c_1,G_CALLBACK(menu_new_viewer_tab_cleanup), G_CALLBACK(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", G_CALLBACK(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",G_CALLBACK(menu_treesearch_cleanup), NULL); } /**/ void menu_showchangeall_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; Trptr t; TraceFlagsType flags; unsigned int t_color; t=GLOBALS->showchangeall_menu_c_1; if(t) { flags = t->flags & (TR_NUMMASK | TR_HIGHLIGHT | TR_ATTRIBS); t_color = t->t_color; while(t) { if((t->flags&TR_HIGHLIGHT)&&(!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH)))&&(t->name)) { t->flags = (t->flags & ~(TR_NUMMASK | TR_HIGHLIGHT | TR_ATTRIBS)) | flags; t->minmax_valid = 0; /* force analog traces to regenerate if necessary */ t->t_color = t_color; } 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, G_CALLBACK(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, G_CALLBACK(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,G_CALLBACK(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",G_CALLBACK(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",G_CALLBACK(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,G_CALLBACK(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,G_CALLBACK(regexp_highlight_cleanup)); } /**/ #if GTK_CHECK_VERSION(3,0,0) void menu_write_screengrab_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; GdkWindow *gw; GdkPixbuf *pb = NULL; gboolean succ = FALSE; if(!GLOBALS->filesel_ok) { return; } gw = gtk_widget_get_window(GTK_WIDGET(GLOBALS->mainwindow)); if(gw) { GtkAllocation allocation; gtk_widget_get_allocation(GLOBALS->mainwindow, &allocation); pb = gdk_pixbuf_get_from_window (gw, 0, 0, allocation.width, allocation.height); if(pb) { cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, allocation.width, allocation.height); cairo_t *cr = cairo_create (surface); gdk_cairo_set_source_pixbuf (cr, pb, 0, 0); cairo_paint (cr); cairo_status_t rc = cairo_surface_write_to_png (surface, *GLOBALS->fileselbox_text); succ = (rc == CAIRO_STATUS_SUCCESS); g_object_unref(pb); cairo_surface_destroy (surface); cairo_destroy(cr); } } if(!succ) { fprintf(stderr, "Error opening imagegrab file '%s' for writing.\n",*GLOBALS->fileselbox_text); if(!pb) { fprintf(stderr, "Why: could not execute gdk_pixbuf_get_from_window().\n"); } else { perror("Why"); } errno=0; } else { wave_gconf_client_set_string("/current/imagegrab", GLOBALS->filesel_imagegrab); } } #else 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); } } #endif 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,G_CALLBACK(menu_write_screengrab_cleanup), G_CALLBACK(NULL), "*.png", 1); } /**/ void menu_write_save_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; FILE *wave; int len; if(!GLOBALS->filesel_ok) { return; } len = strlen(*GLOBALS->fileselbox_text); if((!len) || ((*GLOBALS->fileselbox_text)[len-1] == '/') #if !defined __MINGW32__ && !defined _MSC_VER || ((*GLOBALS->fileselbox_text)[len-1] == '\\') #endif ) { GLOBALS->save_success_menu_c_1 = 2; 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,G_CALLBACK(menu_write_save_cleanup), G_CALLBACK(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; int len = 0; 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) { len = strlen(GLOBALS->filesel_writesave); } if ((!len) || (GLOBALS->filesel_writesave[len-1] == '/') #if !defined __MINGW32__ && !defined _MSC_VER || (GLOBALS->filesel_writesave[len-1] == '\\') #endif ) { fileselbox("Write Save File",&GLOBALS->filesel_writesave,G_CALLBACK(menu_write_save_cleanup), G_CALLBACK(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 != 2) /* cancelled */ { 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,G_CALLBACK(menu_read_save_cleanup), G_CALLBACK(NULL), GLOBALS->is_gtkw_save_file ? "*.gtkw" : "*.sav", 0); } /**/ 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 xml2stems. 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, G_CALLBACK(menu_read_stems_cleanup), G_CALLBACK(NULL), NULL, 0); } else { status_text("Unsupported dumpfile type for rtlbrowse.\n"); } } } /**/ 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,G_CALLBACK(menu_read_log_cleanup), G_CALLBACK(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,G_CALLBACK(menu_read_script_cleanup), G_CALLBACK(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,G_CALLBACK(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,G_CALLBACK(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); gtk_adjustment_set_value(hadj, 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,G_CALLBACK(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,G_CALLBACK(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(); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); g_signal_emit_by_name (XXX_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,G_CALLBACK(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(); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); g_signal_emit_by_name (XXX_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,G_CALLBACK(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); } 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); } } static void menu_open_hierarchy_2(gpointer null_data, guint callback_action, GtkWidget *widget, int typ) { (void)null_data; (void)callback_action; (void)widget; Trptr t; int fix=0; struct tree *t_forced = NULL; 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( " 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 { help_text_bold("\n\nOpen Scope"); help_text( " opens and selects the appropriate level of hierarchy in the SST" " for the first selected signal." ); } return; } 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); } } } 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( " invokes $GTKWAVE_EDITOR or gedit (if found) on the appropriate source unit." ); } else { help_text_bold("\n\nOpen Scope"); help_text( " opens and selects the appropriate level of hierarchy in the SST" " for the first selected signal." ); } return; } 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); } } } } 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 */ } /**/ void menu_recurse_import(gpointer null_data, guint callback_action, GtkWidget *widget) { (void) null_data; recurse_import(widget, callback_action); } /**/ static void dataformat(TraceFlagsType mask, TraceFlagsType 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 or 32-bit quantities" " and that ones of other sizes (e.g., binary16) will display as binary." ); return; } dataformat( ~(TR_NUMMASK), 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_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_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_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_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_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_ffo_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-Find First Rightmost One Index-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 right->left FFO conversion. This is a filter" " which sits before other Data Format options such as hex, etc." ); return; } dataformat( ~(TR_FFO), TR_FFO ); } void menu_dataformat_ffo_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-Find First Rightmost One Index-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_FFO), 0 ); } void menu_dataformat_time(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-Time"); help_text( " will step through all highlighted traces and ensure that" " bits and vectors with this qualifier will display as time values." ); return; } dataformat( ~(TR_NUMMASK), (TR_TIME | TR_DEC) ); } void menu_dataformat_enum(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-Enum"); help_text( " will step through all highlighted traces and ensure that" " bits and vectors with this qualifier will display as enum values, provided such values were dumped into file." ); return; } dataformat( ~(TR_NUMMASK), (TR_ENUM | TR_BIN) ); } void menu_dataformat_fpshift_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-Fixed Point Shift-On"); help_text( " will step through all highlighted traces and ensure that" " bits and vectors with this qualifier will be right shifted" " prior to being displayed as Signed Decimal or Decimal values." ); return; } dataformat( ~(TR_FPDECSHIFT), TR_FPDECSHIFT ); } void menu_dataformat_fpshift_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-Fixed Point Shift-Off"); help_text( " will step through all highlighted traces and ensure that" " bits and vectors with this qualifier will not be right shifted" " prior to being displayed as Signed Decimal or Decimal values." ); return; } dataformat( ~(TR_FPDECSHIFT), 0 ); } static void menu_dataformat_fpshift_specify_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; Trptr t; int fix=0; int shamt = GLOBALS->entrybox_text ? atoi(GLOBALS->entrybox_text) : 0; TraceFlagsType mask = ~(TR_FPDECSHIFT); TraceFlagsType patch = TR_FPDECSHIFT; if((shamt < 0)||(shamt > 255)) { shamt = 0; patch = 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->t_fpdecshift = shamt; 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); } } 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_dataformat_fpshift_specify(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-Fixed Point Shift-Specify"); help_text( " will open up a requester to specify a shift count then" " will step through all highlighted traces and ensure that" " bits and vectors with this qualifier will be right shifted" " prior to being displayed as Signed Decimal or Decimal values." ); return; } entrybox("Fixed Point Shift Specify",300,"",NULL,128,G_CALLBACK(menu_dataformat_fpshift_specify_cleanup)); dataformat( ~(TR_FPDECSHIFT), 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")); /* fix up if there are traces above the current row being cut */ if(GLOBALS->wave_vslider) { GtkAdjustment *wadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider); int value = (int)gtk_adjustment_get_value(wadj); Trptr t = GLOBALS->traces.first; int cnt = 0; int high = 0; while(t) { if(cnt >= value) break; if(t->flags & TR_HIGHLIGHT) { high++; } t = GiveNextTrace(t); cnt++; } if(value - high > 0) { gtk_adjustment_set_value(wadj, value - high); } } 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_delete_traces(gpointer null_data, guint callback_action, GtkWidget *widget) { (void)null_data; (void)callback_action; (void)widget; int num_cut; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nDelete"); help_text( " removes highlighted signals from the display and discards them" " without affecting 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("Delete Traces\n")); num_cut = DeleteBuffer(); if(num_cut) { 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 { GLOBALS->do_zoom_center = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VCZ])); DEBUG(printf("Center Zooms\n")); } } 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 { GLOBALS->show_base = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VSBS])); if (!GLOBALS->signalarea || !GLOBALS->wavewindow) { return; } GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); DEBUG(printf("Show Base Symbols\n")); } } /**/ void menu_fullscreen(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\nFullscreen"); help_text( " toggles the fullscreen status of the main window." ); } else { GLOBALS->fullscreen = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_FULLSCR])); if(GLOBALS->fullscreen) { gtk_window_fullscreen (GTK_WINDOW(GLOBALS->mainwindow)); #ifdef WAVE_ALLOW_GTK3_HEADER_BAR if(!GLOBALS->socket_xid) { gtk_widget_show(GLOBALS->time_mainbox); } #endif } else { #ifdef WAVE_ALLOW_GTK3_HEADER_BAR if(!GLOBALS->socket_xid) { gtk_widget_hide(GLOBALS->time_mainbox); } #endif gtk_window_unfullscreen (GTK_WINDOW(GLOBALS->mainwindow)); } if(GLOBALS->wave_hslider) { g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)),"changed"); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)),"value_changed"); } DEBUG(printf("Fullscreen\n")); } } void service_fullscreen(GtkWidget *text, gpointer data) { (void)text; (void)data; gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_FULLSCR]), TRUE); menu_fullscreen(NULL, 0, NULL); } /**/ #ifdef WAVE_ALLOW_GTK3_HEADER_BAR void menu_toolbar(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 Toolbar"); help_text( " toggles the visibility status of the toolbar." ); } else { GLOBALS->show_toolbar = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_TOOLBAR])); if(GLOBALS->show_toolbar) { if(GLOBALS->top_table) gtk_widget_show(GLOBALS->top_table); } else { if(GLOBALS->top_table) gtk_widget_hide(GLOBALS->top_table); } if(GLOBALS->wave_hslider) { g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)),"changed"); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)),"value_changed"); } DEBUG(printf("Show Toolbar\n")); } } #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 { GLOBALS->display_grid = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VSG])); if(GLOBALS->wave_hslider) { g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)),"changed"); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)),"value_changed"); } DEBUG(printf("Show Grid\n")); } } /**/ 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 { GLOBALS->highlight_wavewindow = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_SHW])); if(GLOBALS->wave_hslider) { g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)),"changed"); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)),"value_changed"); } DEBUG(printf("Show Wave Highlight\n")); } } /**/ void menu_show_filled_high_values(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 Filled High Values"); help_text( " toggles the drawing of filled in 1/H values in the waveform display." ); } else { GLOBALS->fill_waveform = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_FILL1])); if(GLOBALS->wave_hslider) { g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)),"changed"); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)),"value_changed"); } DEBUG(printf("Show Filled High Values\n")); } } /**/ void menu_lz_removal(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\nLeading Zero Removal"); help_text( " toggles the display of leading zeros on non-filtered traces. This has no effect on filtered traces." ); } else { GLOBALS->lz_removal = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_LZ_REMOVAL])); if(GLOBALS->signalarea && GLOBALS->wavearea) { GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } DEBUG(printf("Leading Zero Removal\n")); } } /**/ 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" " s = Fixed Point Shift (count)\n" ); } else { GLOBALS->disable_mouseover=(GLOBALS->disable_mouseover)?0:~0; DEBUG(printf("Show Mouseover\n")); } GLOBALS->disable_mouseover = !gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VSMO])); } /**/ void menu_clipboard_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\nMouseover Copies To Clipboard"); help_text( " toggles automatic copying to the clipboard of mouseover values. Requires that Show Mouseover is enabled.\n" ); } else { GLOBALS->clipboard_mouseover=(GLOBALS->clipboard_mouseover)?0:~0; DEBUG(printf("Mouseover Copies To Clipboard\n")); } GLOBALS->clipboard_mouseover = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_VSMC])); } /**/ /* 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, ""), WAVE_GTKIFE("/File/Grab To File", NULL, menu_write_screengrab_as, WV_MENU_SGRAB, ""), 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, ""), WAVE_GTKIFE("/File/Read Verilog Stemsfile", NULL, menu_read_stems_file, WV_MENU_FRSTMF, ""), WAVE_GTKIFE("/File/", NULL, NULL, WV_MENU_SEP2STMF, ""), #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, ""), WAVE_GTKIFE("/Edit/Delete", NULL, menu_delete_traces, WV_MENU_DEL, ""), #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, ""), WAVE_GTKIFE("/Edit/Delete", "Delete", menu_delete_traces, WV_MENU_DEL, ""), #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/Time", NULL, menu_dataformat_time, WV_MENU_TIME, ""), WAVE_GTKIFE("/Edit/Data Format/Enum", NULL, menu_dataformat_enum, WV_MENU_ENUM, ""), 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/Data Format/Find First One/On", NULL, menu_dataformat_ffo_on, WV_MENU_FFOON, ""), WAVE_GTKIFE("/Edit/Data Format/Find First One/Off", NULL, menu_dataformat_ffo_off, WV_MENU_FFOOFF, ""), WAVE_GTKIFE("/Edit/Data Format/Fixed Point Shift/On", NULL, menu_dataformat_fpshift_on, WV_MENU_FPSHIFTON, ""), WAVE_GTKIFE("/Edit/Data Format/Fixed Point Shift/Off", NULL, menu_dataformat_fpshift_off, WV_MENU_FPSHIFTOFF, ""), WAVE_GTKIFE("/Edit/Data Format/Fixed Point Shift/Specify", NULL, menu_dataformat_fpshift_specify, WV_MENU_FPSHIFTVAL, ""), 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, ""), WAVE_GTKIFE("/Search/Pattern Search 2", NULL, menu_tracesearchbox, WV_MENU_SPS2, ""), 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__ 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", "plus", service_zoom_in_marshal, WV_MENU_TZZI, ""), WAVE_GTKIFE("/Time/Zoom/Zoom Out","minus", service_zoom_out_marshal, WV_MENU_TZZO, ""), WAVE_GTKIFE("/Time/Zoom/Zoom Full", "0", 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", NULL, 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/Fullscreen", "F11", menu_fullscreen, WV_MENU_FULLSCR, ""), #ifdef WAVE_ALLOW_GTK3_HEADER_BAR WAVE_GTKIFE("/View/Show Toolbar", "F9", menu_toolbar, WV_MENU_TOOLBAR, ""), #endif WAVE_GTKIFE("/View/", NULL, NULL, WV_MENU_SEP8C, ""), 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/Show Filled High Values", NULL, menu_show_filled_high_values, WV_MENU_FILL1, ""), WAVE_GTKIFE("/View/Leading Zero Removal", NULL, menu_lz_removal, WV_MENU_LZ_REMOVAL, ""), WAVE_GTKIFE("/View/", NULL, NULL, WV_MENU_SEP9B, ""), WAVE_GTKIFE("/View/Show Mouseover", NULL, menu_show_mouseover, WV_MENU_VSMO, ""), WAVE_GTKIFE("/View/Mouseover Copies To Clipboard", NULL, menu_clipboard_mouseover, WV_MENU_VSMC, ""), 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", NULL, menu_toggle_max_or_marker, WV_MENU_VTMM, ""), WAVE_GTKIFE("/View/", NULL, NULL, WV_MENU_SEP13, ""), WAVE_GTKIFE("/View/Constant Marker Update", NULL, 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, ""), }; 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); } } } } /* * set toggleitems to their initial states */ 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_FULLSCR]), GLOBALS->fullscreen); #ifdef WAVE_ALLOW_GTK3_HEADER_BAR gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_TOOLBAR]), GLOBALS->show_toolbar); #endif 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_FILL1]), GLOBALS->fill_waveform); gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_wlist[WV_MENU_LZ_REMOVAL]), GLOBALS->lz_removal); 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_VSMC]), GLOBALS->clipboard_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; } /* * kill accelerator keys (e.g., if using twinwave as focus is sometimes wrong from parent window) */ void kill_main_menu_accelerators(void) { int i; for(i=0;iitem_factory_menu_c_1, menu_blackouts[i]); if(mw) gtk_widget_set_sensitive(mw, TRUE); } #endif for(i=0;isave_on_exit) { fileselbox("Write Save File On Exit",&GLOBALS->filesel_writesave,G_CALLBACK(menu_write_save_cleanup), G_CALLBACK(NULL), GLOBALS->is_gtkw_save_file ? "*.gtkw" : "*.sav", 1); /* was: menu_write_save_file(NULL, 0, NULL); */ } if(!GLOBALS->enable_fast_exit) { simplereqbox("Quit Program",300,"Do you really want to quit?","Yes", "No", G_CALLBACK(menu_quit_callback), 1); } else { #ifdef __CYGWIN__ kill_stems_browser(); #endif g_print ("WM Destroy\n"); 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(8 + nlen + 1 + 1); /* originally a malloc, but the script can change the context! */ strcpy(tcl_cmd, "source {"); strcpy(tcl_cmd+8, name); strcpy(tcl_cmd+8+nlen, "}"); 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"); 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/Time", NULL, menu_dataformat_time, WV_MENU_TIME, ""), WAVE_GTKIFE("/Data Format/Enum", NULL, menu_dataformat_enum, WV_MENU_ENUM, ""), 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("/Data Format/Find First One/On", NULL, menu_dataformat_ffo_on, WV_MENU_FFOON, ""), WAVE_GTKIFE("/Data Format/Find First One/Off", NULL, menu_dataformat_ffo_off, WV_MENU_FFOOFF, ""), WAVE_GTKIFE("/Data Format/Fixed Point Shift/On", NULL, menu_dataformat_fpshift_on, WV_MENU_FPSHIFTON, ""), WAVE_GTKIFE("/Data Format/Fixed Point Shift/Off", NULL, menu_dataformat_fpshift_off, WV_MENU_FPSHIFTOFF, ""), WAVE_GTKIFE("/Data Format/Fixed Point Shift/Specify", NULL, menu_dataformat_fpshift_specify, WV_MENU_FPSHIFTVAL, ""), 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("/Delete", NULL, menu_delete_traces, WV_MENU_DEL, ""), WAVE_GTKIFE("/", NULL, NULL, WV_MENU_SEP4, ""), WAVE_GTKIFE("/Open Scope", NULL, menu_open_hierarchy, WV_MENU_OPENH, ""), #if !defined __MINGW32__ /* 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 WAVE_GTKIFE("/", NULL, NULL, WV_MENU_SEP5, ""), WAVE_GTKIFE("/Trace Properties", NULL, menu_showchangeall, WV_MENU_ESCFH, ""), }; void do_popup_menu (GtkWidget *my_widget, GdkEventButton *event) { (void)my_widget; GtkWidget *menu; #if !GTK_CHECK_VERSION(3,0,0) int button; int event_time; #endif if(!GLOBALS->signal_popup_menu) { int nmenu_items = sizeof(popmenu_items) / sizeof(popmenu_items[0]); #if !defined __MINGW32__ 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 GLOBALS->signal_popup_menu = menu = alt_menu(popmenu_items, nmenu_items, NULL, NULL, FALSE); } else { menu = GLOBALS->signal_popup_menu; } if (event) { #if !GTK_CHECK_VERSION(3,0,0) button = event->button; event_time = event->time; #endif } else { #if !GTK_CHECK_VERSION(3,0,0) button = 0; event_time = gtk_get_current_event_time (); #endif } #if GTK_CHECK_VERSION(3,0,0) gtk_menu_popup_at_pointer (GTK_MENU (menu), NULL); #else gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, button, event_time); #endif } /***************************/ /*** sst popup menu code ***/ /***************************/ static gtkwave_mlist_t sst_popmenu_items[] = { WAVE_GTKIFE("/Recurse Import/Append", NULL, menu_recurse_import, WV_RECURSE_APPEND, ""), WAVE_GTKIFE("/Recurse Import/Insert", NULL, menu_recurse_import, WV_RECURSE_INSERT, ""), WAVE_GTKIFE("/Recurse Import/Replace", NULL, menu_recurse_import, WV_RECURSE_REPLACE, ""), #if !defined __MINGW32__ 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, ""), #endif }; void do_sst_popup_menu (GtkWidget *my_widget, GdkEventButton *event) { (void)my_widget; GtkWidget *menu; #if !GTK_CHECK_VERSION(3,0,0) int button, event_time; #endif if(!GLOBALS->sst_signal_popup_menu) { int nmenu_items = sizeof(sst_popmenu_items) / sizeof(sst_popmenu_items[0]); #if !defined __MINGW32__ if(!GLOBALS->stem_path_string_table) { nmenu_items-=2; /* remove all stems popups */ } else if(!GLOBALS->istem_struct_base) { nmenu_items--; /* remove "/Open Source Instantiation" if not present */ } /* still have recurse import popup */ #endif GLOBALS->sst_signal_popup_menu = menu = alt_menu(sst_popmenu_items, nmenu_items, NULL, NULL, FALSE); } else { menu = GLOBALS->sst_signal_popup_menu; } if (event) { #if !GTK_CHECK_VERSION(3,0,0) button = event->button; event_time = event->time; #endif } else { #if !GTK_CHECK_VERSION(3,0,0) button = 0; event_time = gtk_get_current_event_time (); #endif } #if GTK_CHECK_VERSION(3,0,0) gtk_menu_popup_at_pointer (GTK_MENU (menu), NULL); #else gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, button, event_time); #endif } void SetTraceScrollbarRowValue(int row, unsigned location) { if(row >= 0) { GtkAdjustment *wadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider); int target = row; GtkAllocation allocation; gtk_widget_get_allocation(GLOBALS->signalarea, &allocation); int num_traces_displayable=(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; gtk_adjustment_set_value(wadj, target); g_signal_emit_by_name (XXX_GTK_OBJECT (wadj), "changed"); /* force bar update */ g_signal_emit_by_name (XXX_GTK_OBJECT (wadj), "value_changed"); /* force text update */ gtkwave_main_iteration(); } } /* * 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, "")) { #if defined(MAC_INTEGRATION) || defined(WAVE_GTK3_MENU_SEPARATOR) 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)(intptr_t)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, #ifdef WAVE_ALLOW_GTK3_HEADER_BAR FALSE #else TRUE #endif ); 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]); menu_wlist[WV_MENU_FONVT] = NULL; } if(!GLOBALS->partial_vcd) { gtk_widget_destroy(menu_wlist[WV_MENU_VZDYN]); menu_wlist[WV_MENU_VZDYN] = NULL; gtk_widget_destroy(menu_wlist[WV_MENU_VZDYNE]); menu_wlist[WV_MENU_VZDYNE] = NULL; } if(GLOBALS->loaded_file_type == DUMPLESS_FILE) { gtk_widget_destroy(menu_wlist[WV_MENU_FRW]); menu_wlist[WV_MENU_FRW] = NULL; } if(GLOBALS->loaded_file_type != LXT_FILE) { gtk_widget_destroy(menu_wlist[WV_MENU_SEP18]); menu_wlist[WV_MENU_SEP18] = NULL; gtk_widget_destroy(menu_wlist[WV_MENU_LXTCC2Z]); menu_wlist[WV_MENU_LXTCC2Z] = NULL; } 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;imain_popup_menu) { GLOBALS->main_popup_menu = menu = alt_menu_top(GLOBALS->mainwindow); } else { menu = GLOBALS->main_popup_menu; } if (event) { #if !GTK_CHECK_VERSION(3,0,0) button = event->button; event_time = event->time; #endif } else { #if !GTK_CHECK_VERSION(3,0,0) button = 0; event_time = gtk_get_current_event_time (); #endif } #if GTK_CHECK_VERSION(3,0,0) if(GLOBALS->main_popup_menu_button) { gtk_menu_popup_at_widget (GTK_MENU (menu), GLOBALS->main_popup_menu_button, GDK_GRAVITY_SOUTH_WEST, GDK_GRAVITY_NORTH_WEST, NULL); } else { gtk_menu_popup_at_pointer (GTK_MENU (menu), NULL); } #else gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, button, event_time); #endif } #endif gtkwave-gtk3-3.3.125/src/menu.h0000664000175000017500000003465015047725112015431 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2017. * * 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 #include #include #include "currenttime.h" #include "fgetdynamic.h" #include "strace.h" #include "debug.h" #include "symbol.h" #include "main.h" #ifdef WAVE_ALLOW_GTK3_HEADER_BAR void do_popup_main_menu (GtkWidget *my_widget, GdkEventButton *event); void service_fullscreen(GtkWidget *text, gpointer data); #endif 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); void kill_main_menu_accelerators(void); /* for conflicts with twinwave */ struct stringchain_t { struct stringchain_t *next; char *name; }; 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); 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, WV_MENU_SGRAB, WV_MENU_SEP1, WV_MENU_FRSF, WV_MENU_FWSF, WV_MENU_FWSFAS, WV_MENU_SEP2, WV_MENU_FRLF, WV_MENU_SEP2LF, WV_MENU_FRSTMF, WV_MENU_SEP2STMF, #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_DEL, 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_TIME, WV_MENU_ENUM, 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_FFOON, WV_MENU_FFOOFF, WV_MENU_FPSHIFTON, WV_MENU_FPSHIFTOFF, WV_MENU_FPSHIFTVAL, 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, WV_MENU_SPS2, WV_MENU_SEP7B, WV_MENU_SSR, WV_MENU_SSH, WV_MENU_SST, WV_MENU_SEP7, #if !defined __MINGW32__ 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_FULLSCR, #ifdef WAVE_ALLOW_GTK3_HEADER_BAR WV_MENU_TOOLBAR, #endif WV_MENU_SEP8C, WV_MENU_VSG, WV_MENU_SEP9, WV_MENU_SHW, WV_MENU_FILL1, WV_MENU_LZ_REMOVAL, WV_MENU_SEP9B, WV_MENU_VSMO, WV_MENU_VSMC, 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 }; enum WV_RecurseType { WV_RECURSE_APPEND, WV_RECURSE_INSERT, WV_RECURSE_REPLACE, }; 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_write_save_cleanup(GtkWidget *widget, gpointer data); 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); unsigned create_group (char* name, Trptr t_composite); /* 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-gtk3-3.3.125/src/bitvec.c0000664000175000017500000013742615047725112015741 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2017. * * 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; int is_string; int string_len; 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++; is_string = 1; string_len = 0; for(i=0;innbits;i++) { if((h[i]->flags & HIST_STRING)) { if(h[i]->time >= 0) { if(h[i]->v.h_vector) { if((GLOBALS->loaded_file_type == GHW_FILE) && (h[i]->v.h_vector[0] == '\'') && (h[i]->v.h_vector[1]) && (h[i]->v.h_vector[2] == '\'')) { string_len++; } else { string_len += strlen(h[i]->v.h_vector); } } } } else { is_string = 0; break; } } if(is_string) { vadd->flags |= HIST_STRING; vadd=(vptr)realloc_2(vadd,sizeof(struct VectorEnt)+string_len+1); vadd->v[0] = 0; } for(i=0;innbits;i++) { unsigned char enc; tshift = (b->attribs) ? b->attribs[i].shift : 0; if(!is_string) { 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; } else { if(h[i]->time >= 0) { if(h[i]->v.h_vector) { if((GLOBALS->loaded_file_type == GHW_FILE) && (h[i]->v.h_vector[0] == '\'') && (h[i]->v.h_vector[1]) && (h[i]->v.h_vector[2] == '\'')) { char ghw_str[2]; ghw_str[0] = h[i]->v.h_vector[1]; ghw_str[1] = 0; strcat((char *)vadd->v, ghw_str); } else { strcat((char *)vadd->v, h[i]->v.h_vector); } } } } 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, "%"TRACEFLAGSSCNFMT, &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; int row_hi = 0, row_lo = 0, new_msi = 0, new_lsi = 0; int row_delta = 0, bit_delta = 0; int curr_row = 0, curr_bit = 0; int is_2d = 0; 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) && strchr(namex+i+1, ':')) /* remove at '[' if this is a ranged signal */ { offset=i; } if(i>3) { if(namex[i-1]==']') { int colon_seen = 0; j = i-2; for(;j>=0;j--) { if(namex[j]=='[') break; if(namex[j]==':') colon_seen = 1; } if((j>-1)&&(colon_seen)) { int items = sscanf(namex+j, "[%d:%d][%d:%d]", &row_hi, &row_lo, &new_msi, &new_lsi); if(items == 4) { /* printf(">> %d %d %d %d (items = %d)\n", row_hi, row_lo, new_msi, new_lsi, items); */ row_delta = (row_hi > row_lo) ? -1 : 1; bit_delta = (new_msi > new_lsi) ? -1 : 1; curr_row = row_hi; curr_bit = new_msi; is_2d = (((row_lo - row_hi) * row_delta) + 1) * (((new_lsi - new_msi) * bit_delta) + 1) == width; if(is_2d) offset = j; } } } } 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, width; exptr exp1; int row_hi = 0, row_lo = 0, new_msi = 0, new_lsi = 0; int row_delta = 0, bit_delta = 0; int curr_row = 0, curr_bit = 0; int is_2d = 0; 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) { width = n->lsi - n->msi + 1; rgh = n->lsi; lft = n->msi; actual = n->msi + bit; } else { width = n->msi - n->lsi + 1; 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) && strchr(namex+i+1, ':')) /* remove at '[' if this is a ranged signal */ { offset=i; } if(i>3) { if(namex[i-1]==']') { int colon_seen = 0; j = i-2; for(;j>=0;j--) { if(namex[j]=='[') break; if(namex[j]==':') colon_seen = 1; } if((j>-1)&&(colon_seen)) { int items = sscanf(namex+j, "[%d:%d][%d:%d]", &row_hi, &row_lo, &new_msi, &new_lsi); if(items == 4) { /* printf("bit >> %d %d %d %d (items = %d)\n", row_hi, row_lo, new_msi, new_lsi, items); */ row_delta = (row_hi > row_lo) ? -1 : 1; bit_delta = (new_msi > new_lsi) ? -1 : 1; curr_row = row_hi; curr_bit = new_msi; is_2d = (((row_lo - row_hi) * row_delta) + 1) * (((new_lsi - new_msi) * bit_delta) + 1) == width; if(is_2d) offset = j; } } } } 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)); if(!is_2d) { sprintf(nam+offset, "[%d]", actual); } else { for(i=0;iarray_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-gtk3-3.3.125/src/logfile.c0000664000175000017500000003353415047725112016101 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; GtkTextTag *bold_tag; GtkTextTag *mono_tag; GtkTextTag *size_tag; 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, void *font, char *str) { (void)font; gtk_text_buffer_insert_with_tags (gtk_text_view_get_buffer(GTK_TEXT_VIEW (text)), &GLOBALS->iter_logfile_c_2, str, -1, GLOBALS->mono_tag_logfile_c_1, GLOBALS->size_tag_logfile_c_1, NULL); } void log_text_bold(GtkWidget *text, void *font, char *str) { (void)font; gtk_text_buffer_insert_with_tags (gtk_text_view_get_buffer(GTK_TEXT_VIEW (text)), &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); } 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_set_value(GTK_ADJUSTMENT(GLOBALS->wave_hslider), GLOBALS->tims.timecache=GLOBALS->tims.start); fix_wavehadj(); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */ g_signal_emit_by_name (XXX_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; GtkTextIter start; GtkTextIter end; if (gtk_text_buffer_get_selection_bounds (gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), &start, &end)) { if(gtk_text_iter_compare (&start, &end) < 0) { sel = gtk_text_buffer_get_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), &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); } } } return(FALSE); /* call remaining handlers... */ } /* Create a scrolled text area that displays a "message" */ static GtkWidget *create_log_text (GtkWidget **textpnt) { GtkWidget *text; GtkWidget *scrolled_window; 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_get_buffer(GTK_TEXT_VIEW (text)), "bold", "weight", PANGO_WEIGHT_BOLD, NULL); GLOBALS->mono_tag_logfile_c_1 = gtk_text_buffer_create_tag (gtk_text_view_get_buffer(GTK_TEXT_VIEW (text)), "monospace", "family", "monospace", NULL); GLOBALS->size_tag_logfile_c_1 = gtk_text_buffer_create_tag (gtk_text_view_get_buffer(GTK_TEXT_VIEW (text)), "fsiz", "size", (GLOBALS->use_big_fonts ? 12 : 8) * PANGO_SCALE, NULL); *textpnt = text; gtk_widget_set_size_request(GTK_WIDGET(text), 100, 100); gtk_text_view_set_editable(GTK_TEXT_VIEW(text), TRUE); gtk_widget_show (text); scrolled_window = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_container_add (GTK_CONTAINER (scrolled_window), text); gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 5); gtk_widget_show(scrolled_window); /* Add a handler to put a message in the text widget when it is realized */ g_signal_connect (XXX_GTK_OBJECT (text), "realize", G_CALLBACK (log_realize_text), NULL); g_signal_connect(XXX_GTK_OBJECT(text), "button_release_event", G_CALLBACK(button_release_event), NULL); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text), GTK_WRAP_CHAR); return(scrolled_window); } /***********************************************************************************/ 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) { XXX_gdk_pointer_ungrab(GDK_CURRENT_TIME); } /* nothing */ /* 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_size_request( GTK_WIDGET (window), width*1.8, 600); } else { gtk_widget_set_size_request( GTK_WIDGET (window), width, 400); } gtk_window_set_title(GTK_WINDOW (window), title); g_signal_connect(XXX_GTK_OBJECT (window), "delete_event", (GCallback) destroy_callback, window); vbox = XXX_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 = XXX_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 = XXX_gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, TRUE, 0); gtk_widget_show (separator); hbox = XXX_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_size_request(button1, 100, -1); g_signal_connect(XXX_GTK_OBJECT (button1), "clicked", G_CALLBACK(ok_callback), window); gtk_widget_show (button1); #if GTK_CHECK_VERSION(3,0,0) gtk_box_pack_start(GTK_BOX(hbox), button1, TRUE, TRUE, 0); #else gtk_container_add (GTK_CONTAINER (hbox), button1); #endif gtk_widget_set_can_default (button1, TRUE); g_signal_connect_swapped (XXX_GTK_OBJECT (button1), "realize", (GCallback) gtk_widget_grab_default, XXX_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, NULL, 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; 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; 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; } { GtkTextIter st_iter, en_iter; gtk_text_buffer_get_start_iter(gtk_text_view_get_buffer(GTK_TEXT_VIEW (text)), &st_iter); gtk_text_buffer_get_end_iter(gtk_text_view_get_buffer(GTK_TEXT_VIEW (text)), &en_iter); gtk_text_buffer_delete(gtk_text_view_get_buffer(GTK_TEXT_VIEW (text)), &st_iter, &en_iter); gtk_text_buffer_get_start_iter (gtk_text_view_get_buffer(GTK_TEXT_VIEW (text)), &GLOBALS->iter_logfile_c_2); } 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, NULL, pnt); free_2(pnt); } fclose(handle); } void logbox_reload(void) { struct logfile_instance_t *l = log_collection; while(l) { 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; logbox_reload_single(l->window, l->text, l->default_text); l = l->next; } } gtkwave-gtk3-3.3.125/src/pixmaps.c0000664000175000017500000027354515047725112016151 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" /* 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) { GdkPixbuf *gp; GLOBALS->redo_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)icon_redo); GLOBALS->larrow_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)icon_larrow); GLOBALS->rarrow_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)icon_rarrow); GLOBALS->prev_page_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)prev_page_xpm); GLOBALS->next_page_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)next_page_xpm); GLOBALS->zoomout_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)icon_zoomout); GLOBALS->zoomin_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)icon_zoomin); GLOBALS->zoomfit_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)icon_zoomfit); GLOBALS->zoomundo_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)icon_zoomundo); GLOBALS->zoom_larrow_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)zoom_larrow); GLOBALS->zoom_rarrow_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)zoom_rarrow); GLOBALS->wave_info_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)wave_info); GLOBALS->wave_alert_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)wave_alert); /* Verilog */ GLOBALS->hiericon_module_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)chart_organisation); GLOBALS->hiericon_task_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)cog); GLOBALS->hiericon_function_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)chart_line); GLOBALS->hiericon_begin_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)flag_green); GLOBALS->hiericon_fork_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)arrow_divide); /* SV */ GLOBALS->hiericon_interface_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)arrow_inout); GLOBALS->hiericon_svpackage_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)package); GLOBALS->hiericon_program_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)application); GLOBALS->hiericon_class_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)plugin); /* VHDL */ GLOBALS->hiericon_design_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)database); GLOBALS->hiericon_block_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)brick); GLOBALS->hiericon_generateif_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)arrow_switch); GLOBALS->hiericon_generatefor_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)arrow_rotate_clockwise); GLOBALS->hiericon_instance_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)icon_component); GLOBALS->hiericon_package_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)box); GLOBALS->hiericon_signal_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)signal_gtkwave); GLOBALS->hiericon_portin_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)door_in); GLOBALS->hiericon_portout_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)door_out); GLOBALS->hiericon_portinout_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)door_open); GLOBALS->hiericon_buffer_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)icon_extension); GLOBALS->hiericon_linkage_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)icon_link); /* FSDB VHDL (on top of GHW's existing) */ GLOBALS->hiericon_record_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)cd_img); GLOBALS->hiericon_generate_pixbuf=gdk_pixbuf_new_from_xpm_data((const gchar **)arrow_redo); /* set icon for window manager */ gp = GLOBALS->wave_info_pixbuf; gtk_window_set_icon(GTK_WINDOW(window), gp); #ifdef MAC_INTEGRATION return(gp); #endif } gtkwave-gtk3-3.3.125/src/busy.c0000664000175000017500000000756315047725112015445 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: case GDK_SCROLL: /* 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) { #if GTK_CHECK_VERSION(3,0,0) GLOBALS->busycursor_busy_c_1 = gdk_cursor_new_for_display(gdk_display_get_default(), GDK_WATCH); #else GLOBALS->busycursor_busy_c_1 = gdk_cursor_new(GDK_WATCH); #endif 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 (gtk_widget_get_window(w), GLOBALS->busycursor_busy_c_1); else if(GLOBALS->mainwindow) gdk_window_set_cursor (gtk_widget_get_window(GLOBALS->mainwindow), 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 (gtk_widget_get_window(w), NULL); else if(GLOBALS->mainwindow) gdk_window_set_cursor (gtk_widget_get_window(GLOBALS->mainwindow), 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-gtk3-3.3.125/src/getopt1.c0000664000175000017500000001124415047725112016035 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-gtk3-3.3.125/src/vcd_keywords.gperf0000664000175000017500000000160115047725112020032 0ustar bybellbybell%{ /* 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; }; %} 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-gtk3-3.3.125/src/analyzer.c0000664000175000017500000010166315047725112016304 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2016. * * 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 "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" 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((!GLOBALS->hier_ignore_escapes) &&(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); } } void MarkTraceCursor(Trptr t_curs) { if(t_curs) { Trptr t=GLOBALS->traces.first; while(t) { t->is_cursor = 0; t=t->t_next; } t_curs->is_cursor = 1; } } /* * Add a trace to the display... */ static void AddTrace( Trptr t ) { GLOBALS->traces.dirty = 1; t->t_fpdecshift = GLOBALS->default_fpshift; 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(!t->vector && GLOBALS->enum_nptrs_jrb) { JRB enum_nptr = jrb_find_vptr(GLOBALS->enum_nptrs_jrb, t->n.nd); if(enum_nptr) { int e_filter = enum_nptr->val.ui; if((e_filter > 0) && (e_filter <= GLOBALS->num_xl_enum_filter)) { t->e_filter = e_filter; if(!(GLOBALS->default_flags&TR_NUMMASK)) t->flags = (t->flags & (~TR_NUMMASK)) | TR_ENUM | TR_BIN; /* need to downgrade to bin to make visible */ } } } 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; TraceFlagsType 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; TraceFlagsType 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, TraceFlagsType 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++; switch(nd->vartype) { case ND_VCD_INTEGER: case ND_VCD_PARAMETER: case ND_SV_INT: case ND_SV_SHORTINT: case ND_SV_LONGINT: t->flags = TR_SIGNED | TR_RJUSTIFY; break; default: t->flags = (( n > 3 )||( n < -3 )) ? TR_HEX|TR_RJUSTIFY : TR_BIN|TR_RJUSTIFY; break; } } 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); } /* * Delete highlighted traces from the main screen * and throw them away. Do not affect existing cut buffer... */ int DeleteBuffer(void) { Trptr t, tnext; Trptr current=NULL; Trptr buffer; /* cut/copy buffer of traces */ Trptr bufferlast; /* last element of bufferchain */ int buffercount; /* number of traces in buffer */ int num_deleted; 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(0); /* nothing to do */ GLOBALS->signalwindow_width_dirty=1; GLOBALS->traces.dirty = 1; buffer = GLOBALS->traces.buffer; /* copy cut buffer to make re-entrant */ bufferlast = GLOBALS->traces.bufferlast; buffercount = GLOBALS->traces.buffercount; GLOBALS->traces.buffer = NULL; GLOBALS->traces.bufferlast = NULL; GLOBALS->traces.buffercount = 0; 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) { 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; } num_deleted = GLOBALS->traces.buffercount; FreeCutBuffer(); GLOBALS->traces.buffer = buffer; /* restore cut buffer */ GLOBALS->traces.bufferlast = bufferlast; GLOBALS->traces.buffercount = buffercount; return(num_deleted); } /* * 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)) && (GLOBALS->num_ttrans_filters)) /* seek to real xact trace if present... */ { if(!(t->flags & TR_HIGHLIGHT)) { Trptr tscan = t; int bcnt = 0; while((tscan) && (tscan = tscan->t_prev)) /* && branch formerly was (tscan = GivePrevTraceSkipUpdate(tscan, 1)): overkill as blank traces in transactions don't nest into groups */ { 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-gtk3-3.3.125/src/logfile.h0000664000175000017500000000063215047725112016077 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-gtk3-3.3.125/src/pixmaps.h0000664000175000017500000000112215047725112016132 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); #define WAVE_SPLASH_X (512) #define WAVE_SPLASH_Y (384) void make_splash_pixmaps(GtkWidget *window); #endif gtkwave-gtk3-3.3.125/src/busy.h0000664000175000017500000000160315047725112015437 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-gtk3-3.3.125/src/analyzer.h0000664000175000017500000004770315047725112016315 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; 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, TR_FPDECSHIFT_B, TR_TIME_B, TR_ENUM_B, TR_CURSOR_B, TR_FFO_B, TR_RSVD_B /* for use internally such as temporary caching of highlighting, not for use in traces */ }; #define TR_HIGHLIGHT (UINT64_C(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); void MarkTraceCursor(Trptr t); char *varxt_fix(char *s); #endif gtkwave-gtk3-3.3.125/src/pagebuttons.c0000664000175000017500000001025015047725112017001 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." " Scrollwheel Up also hits this button in non-alternative wheel mode." ); 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_set_value(GTK_ADJUSTMENT(GLOBALS->wave_hslider), 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." " Scrollwheel Down also hits this button in non-alternative wheel mode." ); 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_set_value(GTK_ADJUSTMENT(GLOBALS->wave_hslider), 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; pixmapwid1=gtk_image_new_from_pixbuf(GLOBALS->prev_page_pixbuf); gtk_widget_show(pixmapwid1); pixmapwid2=gtk_image_new_from_pixbuf(GLOBALS->next_page_pixbuf); gtk_widget_show(pixmapwid2); /* Create a table to hold the text widget and scrollbars */ table = XXX_gtk_table_new (1, 1, FALSE); main_vbox = XXX_gtk_vbox_new (FALSE, 1); gtk_container_set_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 = XXX_gtk_table_new (2, 1, FALSE); b1 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b1), pixmapwid1); XXX_gtk_table_attach (XXX_GTK_TABLE (table2), b1, 0, 1, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); g_signal_connect_swapped (XXX_GTK_OBJECT (b1), "clicked", G_CALLBACK(service_left_page), XXX_GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(b1, "Scroll Window Left One Page"); gtk_widget_show(b1); b2 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b2), pixmapwid2); XXX_gtk_table_attach (XXX_GTK_TABLE (table2), b2, 0, 1, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); g_signal_connect_swapped (XXX_GTK_OBJECT (b2), "clicked", G_CALLBACK(service_right_page), XXX_GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(b2, "Scroll Window Right One Page"); gtk_widget_show(b2); gtk_container_add (GTK_CONTAINER (frame), table2); gtk_widget_show(table2); return(table); } gtkwave-gtk3-3.3.125/src/gnu-getopt.h0000664000175000017500000001436115047725112016553 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-gtk3-3.3.125/src/pagebuttons.h0000664000175000017500000000073215047725112017012 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-gtk3-3.3.125/src/extload.c0000664000175000017500000020757515047725112016130 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2009-2017. * * 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" #include #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" #ifdef WAVE_FSDB_READER_IS_PRESENT /* experimental new code that uses FST's on the fly fast tree build algorithm */ #define WAVE_USE_FSDB_FST_BRIDGE #endif #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 #ifndef WAVE_USE_FSDB_FST_BRIDGE #ifdef WAVE_FSDB_READER_IS_PRESENT static char *get_varname(char *sbuff, unsigned char *vtp, unsigned char *vdp, int i, int *patched_len) { #else static char *get_varname(unsigned char *vtp, unsigned char *vdp, int i, int *patched_len) { static char sbuff[65537]; #endif char * rc; int vt, vt_len; *patched_len = 0; /* zero says is ok, otherwise size overrides msi/lsi */ #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; } if(pnt[1] == '[') esc = pnt; /* pretend we're escaped to handle 2d */ } 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((GLOBALS->mvlfacs_vzt_c_3[i].len > len_parse) && !(GLOBALS->mvlfacs_vzt_c_3[i].len % len_parse)) /* check if 2d array */ { /* printf("len_parse: %d vs len: %d\n", len_parse, GLOBALS->mvlfacs_vzt_c_3[i].len); */ *patched_len = GLOBALS->mvlfacs_vzt_c_3[i].len; } else /* original, non-2d behavior */ { 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, '[')) && (GLOBALS->mvlfacs_vzt_c_3[i].flags != VZT_RD_SYM_F_DOUBLE)) /* 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); } #endif #ifndef WAVE_USE_FSDB_FST_BRIDGE #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; int patched_len = 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, &patched_len); 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; GLOBALS->extload_namecache_patched[0 & F_NAME_MODULUS]=patched_len; } 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; GLOBALS->extload_namecache_patched[0 & F_NAME_MODULUS]=patched_len; } #else fnam = get_varname(&GLOBALS->extload_vt_prev, &GLOBALS->extload_vd_prev, 0, &patched_len); 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; GLOBALS->extload_namecache_patched[0 & F_NAME_MODULUS]=patched_len; #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, &patched_len); 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; GLOBALS->extload_namecache_patched[(i+1)&F_NAME_MODULUS] = patched_len; } 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; GLOBALS->extload_namecache_patched[(i+1)&F_NAME_MODULUS] = patched_len; } #else fnam = get_varname(&GLOBALS->extload_vt_prev, &GLOBALS->extload_vd_prev, i+1, &patched_len); 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; GLOBALS->extload_namecache_patched[(i+1)&F_NAME_MODULUS] = patched_len; #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); if(GLOBALS->extload_namecache_patched[i&F_NAME_MODULUS]) /* 2d */ { GLOBALS->extload_node_block[i].msi=GLOBALS->extload_namecache_patched[i&F_NAME_MODULUS] - 1; GLOBALS->extload_node_block[i].lsi=0; } 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++; } #endif #ifndef WAVE_USE_FSDB_FST_BRIDGE #ifdef WAVE_FSDB_READER_IS_PRESENT static void extload_hiertree_callback(void *pnt) { int patched_len = 0; char *s = (char *)pnt; if((GLOBALS->extload_curr_tree < GLOBALS->extload_max_tree) || (!GLOBALS->extload_max_tree)) { switch(s[0]) { case 'S': case 'U': get_varname(s, NULL, NULL, -1, &patched_len); GLOBALS->extload_hlen = GLOBALS->fst_scope_name ? strlen(GLOBALS->fst_scope_name) : 0; break; case 'V': process_extload_variable(s); break; case 'E': { GLOBALS->extload_curr_tree++; fprintf(stderr, EXTLOAD"End tree #%d: %d vs %d symbols\n", GLOBALS->extload_curr_tree, GLOBALS->extload_i + 1, GLOBALS->numfacs); if((GLOBALS->extload_curr_tree == GLOBALS->extload_max_tree) && (GLOBALS->extload_max_tree)) { if(GLOBALS->numfacs > (GLOBALS->extload_i + 1)) { fprintf(stderr, EXTLOAD"Max tree count of %d processed, freeing extra memory.\n", GLOBALS->extload_max_tree); GLOBALS->numfacs = GLOBALS->extload_i + 1; /* make sure these match the corresponding calloc_2 in extload_main_2! */ GLOBALS->mvlfacs_vzt_c_3=(struct fac *)realloc_2(GLOBALS->mvlfacs_vzt_c_3, GLOBALS->numfacs * sizeof(struct fac)); GLOBALS->vzt_table_vzt_c_1=(struct lx2_entry *)realloc_2(GLOBALS->vzt_table_vzt_c_1, GLOBALS->numfacs * sizeof(struct lx2_entry)); GLOBALS->extload_sym_block = (struct symbol *)realloc_2(GLOBALS->extload_sym_block, GLOBALS->numfacs * sizeof(struct symbol)); GLOBALS->extload_node_block=(struct Node *)realloc_2(GLOBALS->extload_node_block, GLOBALS->numfacs * sizeof(struct Node)); GLOBALS->extload_idcodes=(unsigned int *)realloc_2(GLOBALS->extload_idcodes, GLOBALS->numfacs * sizeof(unsigned int)); } } } default: break; } } } #endif #endif /* ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// */ #ifdef WAVE_USE_FSDB_FST_BRIDGE static char *get_varname2(struct fstHier *fh, unsigned char *vtp, unsigned char *vdp, int i, int *patched_len) { char *sbuff = NULL; static char zbuf[65537]; /* OK as this does not need to be re-entrant */ *patched_len = 0; /* zero says is ok, otherwise size overrides msi/lsi */ { if((fh->htyp == FST_HT_VAR) && (i >= 0)) { { const char *pnt; /* const char *esc = NULL; */ const char *lb = NULL; const char *colon = NULL; const char *rb = NULL; int state = 0; char *cpyto; pnt = (fh->u.var.name[fh->u.var.name_length-1] == ']') ? fh->u.var.name : &fh->u.var.name[fh->u.var.name_length]; while(*pnt) { if(pnt[0] == '\\') { /* esc = pnt; */ } else { if(pnt[0] == '[') { lb = pnt; colon = NULL; rb = NULL; state = 1; } else if(pnt[0] == ']') { rb = pnt; state = 0; /* if(pnt[1] == '[') esc = pnt; */ /* pretend we're escaped to handle 2d */ } else if(pnt[0] == ':') { if(state) { colon = pnt; } } } pnt++; } { unsigned int l, r; unsigned int d2; if(lb) { if(rb) { l = atoi(lb); r = atoi(rb); } else { l = r = 0; } } else { l = fh->u.var.length - 1; r = 0; } d2 = fh->u.var.handle; GLOBALS->extload_idcodes[i] = d2; if(GLOBALS->extload_inv_idcodes[d2] == 0) GLOBALS->extload_inv_idcodes[d2] = i+1; /* root alias */ if(fh->u.var.typ == FST_VT_VCD_REAL) { 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(fh->u.var.typ == FST_VT_VCD_INTEGER) { 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 = fh->u.var.length; /* if(esc && lb && rb) */ if(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((GLOBALS->mvlfacs_vzt_c_3[i].len > len_parse) && !(GLOBALS->mvlfacs_vzt_c_3[i].len % len_parse)) /* check if 2d array */ { /* printf("len_parse: %d vs len: %d\n", len_parse, GLOBALS->mvlfacs_vzt_c_3[i].len); */ *patched_len = GLOBALS->mvlfacs_vzt_c_3[i].len; } else /* original, non-2d behavior */ { 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 */ if(vdp) { switch(fh->u.var.direction) { case FST_VD_INPUT: *vdp = ND_DIR_IN; GLOBALS->nonimplicit_direction_encountered = 1; break; case FST_VD_OUTPUT: *vdp = ND_DIR_OUT; GLOBALS->nonimplicit_direction_encountered = 1; break; case FST_VD_INOUT: *vdp = ND_DIR_INOUT; GLOBALS->nonimplicit_direction_encountered = 1; break; case FST_VD_IMPLICIT: default: *vdp = ND_DIR_IMPLICIT; break; } } if(vtp) { *vtp = fh->u.var.typ; } pnt = fh->u.var.name; sbuff = cpyto = zbuf; sbuff[0] = 0; if(*pnt) { while(*pnt) { if(isspace(*pnt)) { if(fh->u.var.typ == FST_VT_VCD_REAL) { pnt++; continue; } else { break; } } if((*pnt == '[') && (pnt == strrchr(pnt, '[')) && (fh->u.var.typ != FST_VT_VCD_REAL)) /* fix for arrays */ { /* now to fix possible generate... */ const 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(fh->htyp == FST_HT_SCOPE) { { unsigned char ttype; GLOBALS->fst_scope_name = fstReaderPushScope(GLOBALS->extload_xc, fh->u.scope.name, GLOBALS->mod_tree_parent); switch(fh->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_FORK: ttype = TREE_VCD_ST_FORK; break; case FST_ST_VCD_BEGIN: ttype = TREE_VCD_ST_BEGIN; 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_INTERFACE: ttype = TREE_VCD_ST_INTERFACE; break; case FST_ST_VHDL_ARCHITECTURE: ttype = TREE_VHDL_ST_ARCHITECTURE; break; case FST_ST_VHDL_RECORD: ttype = TREE_VHDL_ST_RECORD; break; case FST_ST_VHDL_BLOCK: ttype = TREE_VHDL_ST_BLOCK; break; case FST_ST_VHDL_GENERATE: ttype = TREE_VHDL_ST_GENERATE; break; case FST_ST_VHDL_IF_GENERATE: ttype = TREE_VHDL_ST_GENIF; break; case FST_ST_VHDL_FUNCTION: ttype = TREE_VHDL_ST_FUNCTION; break; case FST_ST_VHDL_FOR_GENERATE: ttype = TREE_VHDL_ST_GENFOR; break; case FST_ST_VHDL_PROCEDURE: ttype = TREE_VHDL_ST_PROCEDURE; break; case FST_ST_VHDL_PROCESS: ttype = TREE_VHDL_ST_PROCESS; break; default: ttype = TREE_UNKNOWN; break; } allocate_and_decorate_module_tree_node(ttype, fh->u.scope.name, fh->u.scope.component, fh->u.scope.name_length, fh->u.scope.component_length, 0, 0); } } else if(fh->htyp == FST_HT_UPSCOPE) { GLOBALS->mod_tree_parent = fstReaderGetCurrentScopeUserInfo(GLOBALS->extload_xc); GLOBALS->fst_scope_name = fstReaderPopScope(GLOBALS->extload_xc); } } return(NULL); } static void fsdb_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; } static void process_extload_variable2(struct fstHier *s_gv) { 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 = NULL; int flen; int longest_nam_candidate = 0; int patched_len = 0; struct tree *npar; static char fnam_prev[65537]; /* OK as this does not need to be re-entrant */ i = GLOBALS->extload_i; if(i<0) { fnam = get_varname2(s_gv, &GLOBALS->extload_vt_prev, &GLOBALS->extload_vd_prev, 0, &patched_len); flen = strlen(fnam); npar = GLOBALS->mod_tree_parent; if(fnam) strcpy(fnam_prev, 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; GLOBALS->extload_namecache_patched[0 & F_NAME_MODULUS]=patched_len; GLOBALS->extload_npar[0 & F_NAME_MODULUS]=npar; } 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; GLOBALS->extload_namecache_patched[0 & F_NAME_MODULUS]=patched_len; GLOBALS->extload_npar[0 & F_NAME_MODULUS]=npar; } } else { vt = GLOBALS->extload_vt_prev; vd = GLOBALS->extload_vd_prev; if(i!=(GLOBALS->numfacs-1)) { fnam = get_varname2(s_gv, &GLOBALS->extload_vt_prev, &GLOBALS->extload_vd_prev, i+1, &patched_len); flen = strlen(fnam); npar = GLOBALS->mod_tree_parent; 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; GLOBALS->extload_namecache_patched[(i+1)&F_NAME_MODULUS] = patched_len; GLOBALS->extload_npar[(i+1) & F_NAME_MODULUS]=npar; } 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; GLOBALS->extload_namecache_patched[(i+1)&F_NAME_MODULUS] = patched_len; GLOBALS->extload_npar[(i+1) & F_NAME_MODULUS]=npar; } } 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); if(GLOBALS->extload_namecache_patched[i&F_NAME_MODULUS]) /* 2d */ { GLOBALS->extload_node_block[i].msi=GLOBALS->extload_namecache_patched[i&F_NAME_MODULUS] - 1; GLOBALS->extload_node_block[i].lsi=0; } 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; if(GLOBALS->fast_tree_sort) { len = sprintf_2_sdd(buf, fnam_prev,GLOBALS->extload_node_block[i].msi, GLOBALS->extload_node_block[i].lsi); fsdb_append_graft_chain(len, buf, i, GLOBALS->extload_npar[i & F_NAME_MODULUS]); if(fnam) strcpy(fnam_prev, fnam); } } 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; } if(GLOBALS->fast_tree_sort) { len = sprintf_2_sd(buf, fnam_prev, GLOBALS->extload_node_block[i].msi); fsdb_append_graft_chain(len, buf, i, GLOBALS->extload_npar[i & F_NAME_MODULUS]); if(fnam) strcpy(fnam_prev, fnam); } } 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; } if(GLOBALS->fast_tree_sort) { fsdb_append_graft_chain(strlen(fnam_prev), fnam_prev, i, GLOBALS->extload_npar[i & F_NAME_MODULUS]); if(fnam) strcpy(fnam_prev, fnam); } } 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 FST_VT_VCD_EVENT: nvt = ND_VCD_EVENT; break; case FST_VT_VCD_PARAMETER: nvt = ND_VCD_PARAMETER; break; case FST_VT_VCD_INTEGER: nvt = ND_VCD_INTEGER; break; case FST_VT_VCD_REAL: nvt = ND_VCD_REAL; 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; default: nvt = ND_UNSPECIFIED_DEFAULT; break; } n->vartype = nvt; n->vardir = vd; } GLOBALS->extload_i++; } static void extload_hiertree_callback2(void *pnt) { int patched_len = 0; struct fstHier *s = (struct fstHier *)pnt; if((GLOBALS->extload_curr_tree < GLOBALS->extload_max_tree) || (!GLOBALS->extload_max_tree)) { switch(s->htyp) { case FST_HT_SCOPE: case FST_HT_UPSCOPE: get_varname2(s, NULL, NULL, -1, &patched_len); GLOBALS->extload_hlen = GLOBALS->fst_scope_name ? strlen(GLOBALS->fst_scope_name) : 0; break; case FST_HT_VAR: process_extload_variable2(s); break; case FST_HT_TREEEND: { GLOBALS->extload_curr_tree++; fprintf(stderr, EXTLOAD"End tree #%d: %d vs %d symbols\n", GLOBALS->extload_curr_tree, GLOBALS->extload_i + 1, GLOBALS->numfacs); if((GLOBALS->extload_curr_tree == GLOBALS->extload_max_tree) && (GLOBALS->extload_max_tree)) { if(GLOBALS->numfacs > (GLOBALS->extload_i + 1)) { fprintf(stderr, EXTLOAD"Max tree count of %d processed, freeing extra memory.\n", GLOBALS->extload_max_tree); GLOBALS->numfacs = GLOBALS->extload_i + 1; /* make sure these match the corresponding calloc_2 in extload_main_2! */ GLOBALS->mvlfacs_vzt_c_3=(struct fac *)realloc_2(GLOBALS->mvlfacs_vzt_c_3, GLOBALS->numfacs * sizeof(struct fac)); GLOBALS->vzt_table_vzt_c_1=(struct lx2_entry *)realloc_2(GLOBALS->vzt_table_vzt_c_1, GLOBALS->numfacs * sizeof(struct lx2_entry)); GLOBALS->extload_sym_block = (struct symbol *)realloc_2(GLOBALS->extload_sym_block, GLOBALS->numfacs * sizeof(struct symbol)); GLOBALS->extload_node_block=(struct Node *)realloc_2(GLOBALS->extload_node_block, GLOBALS->numfacs * sizeof(struct Node)); GLOBALS->extload_idcodes=(unsigned int *)realloc_2(GLOBALS->extload_idcodes, GLOBALS->numfacs * sizeof(unsigned int)); } } } 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 int patched_len = 0; last_modification_check(); sprintf(sbuff, "%s -info %s 2>&1", EXTLOAD_PATH, fname); GLOBALS->extload = popen_san(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; /* make sure these match the corresponding realloc_2 in extload_hiertree_callback! */ 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_namecache_patched=(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)); #ifdef WAVE_USE_FSDB_FST_BRIDGE GLOBALS->extload_npar=(struct tree **)calloc_2(F_NAME_MODULUS+1, sizeof(struct tree *)); #endif if(!GLOBALS->fast_tree_sort) { GLOBALS->do_hier_compress = 0; } else { hier_auto_enable(); /* enable if greater than threshold */ } 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; #ifdef WAVE_USE_FSDB_FST_BRIDGE fsdbReaderReadScopeVarTree2(GLOBALS->extload_ffr_ctx, extload_hiertree_callback2); process_extload_variable2(NULL); /* flush out final cached variable */ #else fsdbReaderReadScopeVarTree(GLOBALS->extload_ffr_ctx, extload_hiertree_callback); process_extload_variable(NULL); /* flush out final cached variable */ #endif 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; free_2(GLOBALS->extload_namecache_patched); GLOBALS->extload_namecache_patched = NULL; #ifdef WAVE_USE_FSDB_FST_BRIDGE free_2(GLOBALS->extload_npar); GLOBALS->extload_npar = NULL; #endif 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_san(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, &patched_len)); /* 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(); #ifndef WAVE_USE_FSDB_FST_BRIDGE 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); } #endif /* 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, *htempx=NULL, *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_san(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(f->flags&(VZT_RD_SYM_F_DOUBLE|VZT_RD_SYM_F_STRING)) { htemp->v.h_vector = strdup_2((f->flags&VZT_RD_SYM_F_DOUBLE) ? "NaN" : "UNDEF"); htemp->flags = HIST_REAL; if(f->flags&VZT_RD_SYM_F_STRING) htemp->flags |= HIST_STRING; } else { 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(f->flags&(VZT_RD_SYM_F_DOUBLE|VZT_RD_SYM_F_STRING)) { htemp->v.h_vector = strdup_2((f->flags&VZT_RD_SYM_F_DOUBLE) ? "NaN" : "UNDEF"); htemp->flags = HIST_REAL; if(f->flags&VZT_RD_SYM_F_STRING) htemp->flags |= HIST_STRING; } else { 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 */ } } htempx = htemp; 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; np->head.v.h_vector = strdup_2((f->flags&VZT_RD_SYM_F_DOUBLE) ? "NaN" : "UNDEF"); } { struct HistEnt *htemp2 = histent_calloc(); htemp2->time = -1; if(f->flags&(VZT_RD_SYM_F_DOUBLE|VZT_RD_SYM_F_STRING)) { htemp2->v.h_vector = strdup_2((f->flags&VZT_RD_SYM_F_DOUBLE) ? "NaN" : "UNDEF"); htemp2->flags = HIST_REAL; if(f->flags&VZT_RD_SYM_F_STRING) htemp2->flags |= HIST_STRING; } else { if(len>1) { htemp2->v.h_vector = htempx->v.h_vector; } else { htemp2->v.h_val = htempx->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-gtk3-3.3.125/src/regex_wave.h0000664000175000017500000000131515047725112016611 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-gtk3-3.3.125/src/extload.h0000664000175000017500000000125315047725112016116 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-gtk3-3.3.125/src/ae2.c0000664000175000017500000011461315047725112015125 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2004-2017. * * 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 #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'; /* 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 *)); if(!GLOBALS->fast_tree_sort) { GLOBALS->do_hier_compress = 0; } else { hier_auto_enable(); /* enable if greater than threshold */ } init_facility_pack(); 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-gtk3-3.3.125/src/fetchbuttons.c0000664000175000017500000001206415047725112017163 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; pixmapwid1=gtk_image_new_from_pixbuf(GLOBALS->larrow_pixbuf); gtk_widget_show(pixmapwid1); pixmapwid2=gtk_image_new_from_pixbuf(GLOBALS->rarrow_pixbuf); gtk_widget_show(pixmapwid2); /* Create a table to hold the text widget and scrollbars */ table = XXX_gtk_table_new (1, 1, FALSE); main_vbox = XXX_gtk_vbox_new (FALSE, 1); gtk_container_set_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 = XXX_gtk_table_new (2, 1, FALSE); b1 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b1), pixmapwid1); XXX_gtk_table_attach (XXX_GTK_TABLE (table2), b1, 0, 1, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); g_signal_connect_swapped (XXX_GTK_OBJECT (b1), "clicked", G_CALLBACK(fetch_left), XXX_GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(b1, "Decrease 'From' Time"); gtk_widget_show(b1); b2 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b2), pixmapwid2); XXX_gtk_table_attach (XXX_GTK_TABLE (table2), b2, 0, 1, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); g_signal_connect_swapped (XXX_GTK_OBJECT (b2), "clicked", G_CALLBACK(fetch_right), XXX_GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(b2, "Increase 'To' Time"); gtk_widget_show(b2); gtk_container_add (GTK_CONTAINER (frame), table2); gtk_widget_show(table2); return(table); } gtkwave-gtk3-3.3.125/src/regex.c0000664000175000017500000000452615047725112015571 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++ */ #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-gtk3-3.3.125/src/ae2.h0000664000175000017500000000220115047725112015117 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-gtk3-3.3.125/src/libghw.c0000664000175000017500000014670715047725112015743 0ustar bybellbybell/* GHDL Wavefile reader library. Copyright (C) 2005 Tristan Gingold 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. This 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 this library; If not, see . */ #include #include #include #include #include #include #include "libghw.h" // Exit the program with return value 1 and print calling line __attribute__((noreturn)) static void ghw_error_exit_line (char const *file, int line) { fprintf(stderr, "Failed to load ghw file due to invalid data. Terminating.\n"); fprintf(stderr, "Error raised at %s:%d.\n", file, line); exit(1); } #define ghw_error_exit() ghw_error_exit_line(__FILE__, __LINE__) // Call malloc (size), fail exit when malloc fails (returns NULL) void * malloc_unwrap (size_t size) { void *ret = malloc (size); if (ret == NULL) { fprintf(stderr, "libghw could not allocate %zu bytes. Terminating.\n", size); exit(12); } return ret; } // Call calloc () void * calloc_unwrap (size_t nmemb, size_t size) { void *ret = calloc(nmemb, size); if (ret == NULL) { fprintf(stderr, "libghw could not allocate %zu elements of size %zu bytes. Terminating.\n", nmemb, size); exit(12); } return ret; } /* Reopen H through decompressor DECOMP. */ static int ghw_openz (struct ghw_handler *h, const char *decomp, const char *filename) { int plen = strlen (decomp) + 1 + strlen (filename) + 1; char *p = malloc_unwrap (plen); snprintf (p, plen, "%s %s", decomp, filename); fclose (h->stream); h->stream = popen (p, "r"); free (p); if (h->stream == NULL) return -1; h->stream_ispipe = 1; return 0; } 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 compression layer. */ if (!memcmp (hdr, "\x1f\x8b", 2)) { if (ghw_openz (h, "gzip -cd", filename) < 0) return -1; if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) return -1; } else if (!memcmp (hdr, "BZ", 2)) { if (ghw_openz (h, "bzip2 -cd", filename) < 0) return -1; if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) return -1; } else { h->stream_ispipe = 0; } /* Check magic. */ 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); } // Read an i32, make sure it's positive, cast to u32 uint32_t ghw_get_i32_positive (struct ghw_handler *h, unsigned char *b) { int32_t val_i = ghw_get_i32 (h, b); if (val_i < 0) ghw_error_exit (); return (uint32_t) val_i; } 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 |= ~0U << 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; } // Get the string with id str_id from h->str_table if the ID is valid. static const char * ghw_get_str(struct ghw_handler *h, uint32_t str_id) { if (str_id >= h->nbr_str) { fprintf(stderr, "Invalid string ID %u in ghw file\n", str_id); ghw_error_exit(); } return h->str_table[str_id]; } // Read a string ID from the input file and return the correpsonding string. const char * ghw_read_strid (struct ghw_handler *h) { uint32_t id; if (ghw_read_uleb128 (h, &id) != 0) ghw_error_exit(); return ghw_get_str(h, id); } // Get the type with ID type_id from h->types if the ID is valid and // the type has been initialized. union ghw_type * ghw_get_typeid (struct ghw_handler *h, uint32_t type_id) { if ((type_id < 1) || type_id - 1 >= h->nbr_types || h->types[type_id - 1] == NULL) { fprintf(stderr, "Invalid typeid ID %u in ghw file\n", type_id); ghw_error_exit(); } return h->types[type_id - 1]; } // Read a typeid ID from the input file and return the correpsonding string. union ghw_type * ghw_read_typeid (struct ghw_handler *h) { uint32_t id; if (ghw_read_uleb128 (h, &id) != 0) ghw_error_exit(); return ghw_get_typeid(h, id); } union ghw_range * ghw_read_range (struct ghw_handler *h) { int t = fgetc (h->stream); if (t == EOF) ghw_error_exit(); switch (t & 0x7f) { case ghdl_rtik_type_b2: { struct ghw_range_b2 *r; r = malloc_unwrap (sizeof (struct ghw_range_b2)); r->kind = t & 0x7f; r->dir = (t & 0x80) != 0; if (ghw_read_byte (h, &r->left) != 0) goto err_rr_b2; if (ghw_read_byte (h, &r->right) != 0) goto err_rr_b2; return (union ghw_range *) r; err_rr_b2: free (r); ghw_error_exit(); } case ghdl_rtik_type_e8: { struct ghw_range_e8 *r; r = malloc_unwrap (sizeof (struct ghw_range_e8)); r->kind = t & 0x7f; r->dir = (t & 0x80) != 0; if (ghw_read_byte (h, &r->left) != 0) goto err_e8; if (ghw_read_byte (h, &r->right) != 0) goto err_e8; return (union ghw_range *) r; err_e8: free (r); ghw_error_exit(); } case ghdl_rtik_type_i32: case ghdl_rtik_type_p32: { struct ghw_range_i32 *r; r = malloc_unwrap (sizeof (struct ghw_range_i32)); r->kind = t & 0x7f; r->dir = (t & 0x80) != 0; if (ghw_read_sleb128 (h, &r->left) != 0) goto err_i32; if (ghw_read_sleb128 (h, &r->right) != 0) goto err_i32; return (union ghw_range *) r; err_i32: free (r); ghw_error_exit(); } case ghdl_rtik_type_i64: case ghdl_rtik_type_p64: { struct ghw_range_i64 *r; r = malloc_unwrap (sizeof (struct ghw_range_i64)); r->kind = t & 0x7f; r->dir = (t & 0x80) != 0; if (ghw_read_lsleb128 (h, &r->left) != 0) goto err_i64; if (ghw_read_lsleb128 (h, &r->right) != 0) goto err_i64; return (union ghw_range *) r; err_i64: free (r); ghw_error_exit(); } case ghdl_rtik_type_f64: { struct ghw_range_f64 *r; r = malloc_unwrap (sizeof (struct ghw_range_f64)); r->kind = t & 0x7f; r->dir = (t & 0x80) != 0; if (ghw_read_f64 (h, &r->left) != 0) goto err_f64; if (ghw_read_f64 (h, &r->right) != 0) goto err_f64; return (union ghw_range *) r; err_f64: free (r); ghw_error_exit(); } default: fprintf (stderr, "ghw_read_range: type %d unhandled\n", t & 0x7f); ghw_error_exit(); } } int ghw_read_str (struct ghw_handler *h) { unsigned char hdr[12]; unsigned 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; // Read number of strings and total string size. Make sure that nbr_string // is not too large, as it's incremented afterwards. h->nbr_str = ghw_get_i32_positive (h, &hdr[4]); h->nbr_str++; h->str_size = (uint32_t) ghw_get_i32 (h, &hdr[8]); // Allocate str_table, str_content. Avoid exceeding size_t limits. h->str_table = (char **) calloc_unwrap(h->nbr_str, sizeof (char *)); uint64_t alloc_size = h->str_size + h->nbr_str + 1; if (alloc_size > SIZE_MAX) ghw_error_exit(); h->str_content = (char *) malloc_unwrap (alloc_size); char *p_end = h->str_content + alloc_size; if (h->flag_verbose) { printf ("Number of strings: %u\n", h->nbr_str - 1); printf ("String table size: %u\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++) { if (p >= p_end) goto err_ghw_read_str; *p++ = prev[j]; } while (1) { c = fgetc (h->stream); if (c == EOF) return -1; if ((c >= 0 && c <= 31) || (c >= 128 && c <= 159)) break; if (p >= p_end) goto err_ghw_read_str; *p++ = c; } if (p >= p_end) goto err_ghw_read_str; *p++ = 0; if (h->flag_verbose > 1) printf (" string %u (pl=%d): %s\n", i, prev_len, ghw_get_str(h, 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; err_ghw_read_str: fprintf(stderr, "Invalid string entry in GHW file.\n"); ghw_error_exit(); } 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: case ghdl_rtik_type_array: return t; case ghdl_rtik_subtype_scalar: return t->ss.base; case ghdl_rtik_subtype_array: return t->sa.base; case ghdl_rtik_subtype_unbounded_array: return t->sua.base; default: fprintf (stderr, "ghw_get_base_type: cannot handle type %d\n", t->kind); ghw_error_exit(); } } /* Return -1 for unbounded types. */ static 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_type_array: return -1; case ghdl_rtik_subtype_array: return t->sa.nbr_scalars; case ghdl_rtik_type_record: return t->rec.nbr_scalars; case ghdl_rtik_subtype_record: return t->sr.nbr_scalars; case ghdl_rtik_subtype_unbounded_record: case ghdl_rtik_subtype_unbounded_array: return -1; default: fprintf (stderr, "get_nbr_elements: unhandled type %d\n", t->kind); ghw_error_exit(); } } int ghw_get_range_length (union ghw_range *rng) { int res; if (rng == NULL) ghw_error_exit(); assert (rng != NULL); switch (rng->kind) { case ghdl_rtik_type_i32: if (rng->i32.dir) res = rng->i32.left - rng->i32.right + 1; else res = rng->i32.right - rng->i32.left + 1; break; case ghdl_rtik_type_b2: if (rng->b2.dir) res = rng->b2.left - rng->b2.right + 1; else res = rng->b2.right - rng->b2.left + 1; break; case ghdl_rtik_type_e8: if (rng->e8.dir) res = rng->e8.left - rng->e8.right + 1; else res = rng->e8.right - rng->e8.left + 1; break; default: fprintf (stderr, "get_range_length: unhandled kind %d\n", rng->kind); ghw_error_exit(); } /* The length of a null range is 0. */ return (res <= 0) ? 0 : res; } static union ghw_type *ghw_read_type_bounds (struct ghw_handler *h, union ghw_type *base); /* Create an array subtype using BASE and ranges read from H. */ struct ghw_subtype_array * ghw_read_array_subtype (struct ghw_handler *h, union ghw_type *base) { struct ghw_type_array *arr = (struct ghw_type_array *) ghw_get_base_type (base); if (arr->kind != ghdl_rtik_type_array) ghw_error_exit(); struct ghw_subtype_array *sa; unsigned j; int nbr_scalars; int nbr_els; sa = malloc_unwrap (sizeof (struct ghw_subtype_array)); sa->kind = ghdl_rtik_subtype_array; sa->name = NULL; sa->base = base; nbr_els = get_nbr_elements (arr->el); nbr_scalars = 1; sa->rngs = calloc_unwrap (arr->nbr_dim, sizeof (union ghw_range *)); for (j = 0; j < arr->nbr_dim; j++) { sa->rngs[j] = ghw_read_range (h); nbr_scalars *= ghw_get_range_length (sa->rngs[j]); } if (nbr_els >= 0) { /* Element type is bounded. */ sa->el = arr->el; } else { /* Read bounds for the elements. */ sa->el = ghw_read_type_bounds (h, arr->el); nbr_els = get_nbr_elements (sa->el); } sa->nbr_scalars = nbr_scalars * nbr_els; return sa; } struct ghw_subtype_record * ghw_read_record_subtype (struct ghw_handler *h, struct ghw_type_record *base) { struct ghw_subtype_record *sr; sr = malloc_unwrap (sizeof (struct ghw_subtype_record)); sr->kind = ghdl_rtik_subtype_record; sr->name = NULL; sr->base = base; if (base->nbr_scalars >= 0) { /* Record base type is bounded. */ sr->nbr_scalars = base->nbr_scalars; sr->els = base->els; } else { /* Read subtypes. */ unsigned j; int nbr_scalars; sr->els = calloc_unwrap (base->nbr_fields, sizeof (struct ghw_record_element)); nbr_scalars = 0; for (j = 0; j < base->nbr_fields; j++) { union ghw_type *btype = base->els[j].type; int el_nbr_scalars = get_nbr_elements (btype); sr->els[j].name = base->els[j].name; if (el_nbr_scalars >= 0) { /* Element is constrained. */ sr->els[j].type = btype; } else { sr->els[j].type = ghw_read_type_bounds (h, btype); el_nbr_scalars = get_nbr_elements (sr->els[j].type); } nbr_scalars += el_nbr_scalars; } sr->nbr_scalars = nbr_scalars; } return sr; } /* Read bounds for BASE and create a subtype. */ static union ghw_type * ghw_read_type_bounds (struct ghw_handler *h, union ghw_type *base) { switch (base->kind) { case ghdl_rtik_type_array: case ghdl_rtik_subtype_unbounded_array: return (union ghw_type *) ghw_read_array_subtype (h, base); break; case ghdl_rtik_type_record: case ghdl_rtik_subtype_unbounded_record: return (union ghw_type *) ghw_read_record_subtype (h, &base->rec); break; default: fprintf (stderr, "ghw_read_type_bounds: unhandled kind %d\n", base->kind); ghw_error_exit(); } } int ghw_read_type (struct ghw_handler *h) { unsigned char hdr[8]; uint32_t 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_positive (h, &hdr[4]); // Allocate type storage, initialize it to 0 to catch invalid accesses. h->types = (union ghw_type **) calloc_unwrap (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; if (h->flag_verbose > 1) printf ("type[%u]= %d\n", i, t); switch (t) { case ghdl_rtik_type_b2: case ghdl_rtik_type_e8: { struct ghw_type_enum *e; uint32_t j; e = malloc_unwrap (sizeof (struct ghw_type_enum)); e->lits = NULL; e->kind = t; e->wkt = ghw_wkt_unknown; e->name = ghw_read_strid (h); if (ghw_read_uleb128 (h, &e->nbr) != 0) goto err_rt_b2; uint64_t lit_size = e->nbr * sizeof (char *); if (lit_size > SIZE_MAX) ghw_error_exit(); e->lits = (const char **) malloc_unwrap (lit_size); 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; err_rt_b2: free (e->lits); free (e); return -1; } break; case ghdl_rtik_type_i32: case ghdl_rtik_type_i64: case ghdl_rtik_type_f64: { struct ghw_type_scalar *sc; sc = malloc_unwrap (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 = malloc_unwrap (sizeof (struct ghw_type_physical)); ph->kind = t; ph->name = ghw_read_strid (h); ph->units = NULL; if (h->version == 0) ph->nbr_units = 0; else { unsigned j; if (ghw_read_uleb128 (h, &ph->nbr_units) != 0) goto err_p32; ph->units = calloc_unwrap (ph->nbr_units, sizeof (struct ghw_unit)); for (j = 0; j < ph->nbr_units; j++) { ph->units[j].name = ghw_read_strid (h); if (ghw_read_lsleb128 (h, &ph->units[j].val) < 0) goto err_p32; } } if (h->flag_verbose > 1) printf ("physical: %s\n", ph->name); h->types[i] = (union ghw_type *) ph; break; err_p32: free (ph->units); free (ph); return -1; } break; case ghdl_rtik_subtype_scalar: { struct ghw_subtype_scalar *ss; ss = malloc_unwrap (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; unsigned j; arr = malloc_unwrap (sizeof (struct ghw_type_array)); arr->dims = NULL; arr->kind = t; arr->name = ghw_read_strid (h); arr->el = ghw_read_typeid (h); if (ghw_read_uleb128 (h, &arr->nbr_dim) != 0) goto err_array; arr->dims = (union ghw_type **) calloc_unwrap (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 (ndim=%u) of %s\n", arr->name, arr->nbr_dim, arr->el->common.name); h->types[i] = (union ghw_type *) arr; break; err_array: if (arr->dims != NULL) free (arr->dims); free (arr); return -1; } break; case ghdl_rtik_subtype_array: { struct ghw_subtype_array *sa; const char *name; union ghw_type *base; name = ghw_read_strid (h); base = ghw_read_typeid (h); sa = ghw_read_array_subtype (h, base); sa->name = name; h->types[i] = (union ghw_type *) sa; if (h->flag_verbose > 1) printf ("subtype array: %s (nbr_scalars=%d)\n", sa->name, sa->nbr_scalars); } break; case ghdl_rtik_subtype_unbounded_array: { struct ghw_subtype_unbounded_array *sua; sua = malloc_unwrap (sizeof (struct ghw_subtype_unbounded_array)); sua->kind = t; sua->name = ghw_read_strid (h); sua->base = ghw_read_typeid (h); h->types[i] = (union ghw_type *) sua; if (h->flag_verbose > 1) printf ("subtype unbounded array: %s\n", sua->name); } break; case ghdl_rtik_type_record: { struct ghw_type_record *rec; unsigned j; int nbr_scalars; rec = malloc_unwrap (sizeof (struct ghw_type_record)); rec->kind = t; rec->name = ghw_read_strid (h); rec->els = NULL; if (ghw_read_uleb128 (h, &rec->nbr_fields) != 0) goto err_record; rec->els = calloc_unwrap (rec->nbr_fields, sizeof (struct ghw_record_element)); nbr_scalars = 0; for (j = 0; j < rec->nbr_fields; j++) { rec->els[j].name = ghw_read_strid (h); rec->els[j].type = ghw_read_typeid (h); if (nbr_scalars != -1) { int field_nbr_scalars = get_nbr_elements (rec->els[j].type); if (field_nbr_scalars == -1) nbr_scalars = -1; else nbr_scalars += field_nbr_scalars; } } rec->nbr_scalars = nbr_scalars; if (h->flag_verbose > 1) printf ("record type: %s (nbr_scalars=%d)\n", rec->name, rec->nbr_scalars); h->types[i] = (union ghw_type *) rec; break; err_record: free (rec->els); free (rec); return -1; } break; case ghdl_rtik_subtype_record: { struct ghw_subtype_record *sr; const char *name; struct ghw_type_record *base; name = ghw_read_strid (h); union ghw_type * base_u = ghw_read_typeid (h); if (base_u->kind != ghdl_rtik_type_record) ghw_error_exit(); base = (struct ghw_type_record *) base_u; sr = ghw_read_record_subtype (h, base); sr->name = name; h->types[i] = (union ghw_type *) sr; if (h->flag_verbose > 1) printf ("subtype record: %s (nbr_scalars=%d)\n", sr->name, sr->nbr_scalars); } break; case ghdl_rtik_subtype_unbounded_record: { struct ghw_subtype_unbounded_record *sur; sur = malloc_unwrap (sizeof (struct ghw_subtype_unbounded_record)); sur->kind = t; sur->name = ghw_read_strid (h); union ghw_type * base_u = ghw_read_typeid (h); if (base_u->kind != ghdl_rtik_type_record) ghw_error_exit(); sur->base = (struct ghw_type_record *) base_u; h->types[i] = (union ghw_type *) sur; if (h->flag_verbose > 1) printf ("subtype unbounded record: %s\n", sur->name); } 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. Return 0 for success. */ 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: { unsigned int sig_el; if (ghw_read_uleb128 (h, &sig_el) < 0) return -1; *sigs = sig_el; if (sig_el == 0 || sig_el >= h->nbr_sigs) return -1; if (h->sigs[sig_el].type == NULL) h->sigs[sig_el].type = ghw_get_base_type (t); } return 0; case ghdl_rtik_subtype_array: { int i; int stride; int len; len = t->sa.nbr_scalars; stride = get_nbr_elements (t->sa.el); for (i = 0; i < len; i += stride) if (ghw_read_signal (h, &sigs[i], t->sa.el) < 0) return -1; } return 0; case ghdl_rtik_type_record: { struct ghw_type_record *r = &t->rec; int nbr_fields = r->nbr_fields; int i; int off; off = 0; for (i = 0; i < nbr_fields; i++) { if (ghw_read_signal (h, &sigs[off], r->els[i].type) < 0) return -1; off += get_nbr_elements (r->els[i].type); } } return 0; case ghdl_rtik_subtype_record: { struct ghw_subtype_record *sr = &t->sr; int nbr_fields = sr->base->nbr_fields; int i; int off; off = 0; for (i = 0; i < nbr_fields; i++) { if (ghw_read_signal (h, &sigs[off], sr->els[i].type) < 0) return -1; off += get_nbr_elements (sr->els[i].type); } } return 0; default: fprintf (stderr, "ghw_read_signal: type kind %d unhandled\n", t->kind); ghw_error_exit(); } } 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_i64: 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); ghw_error_exit(); } return 0; } int ghw_read_hie (struct ghw_handler *h) { unsigned char hdr[16]; int nbr_scopes; int nbr_sigs; unsigned 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, &hdr[4]); /* Number of declared signals (which may be composite). */ nbr_sigs = ghw_get_i32 (h, &hdr[8]); /* Number of basic signals. */ h->nbr_sigs = ghw_get_i32_positive (h, &hdr[12]); if (h->flag_verbose) printf ("%d scopes, %d signals, %u signal elements\n", nbr_scopes, nbr_sigs, h->nbr_sigs); blk = (struct ghw_hie *) malloc_unwrap (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->skip_sigs = NULL; h->flag_full_names = 0; h->sigs_no_null = 0; h->sigs = (struct ghw_sig *) calloc_unwrap (h->nbr_sigs, sizeof (struct ghw_sig)); while (1) { int t; struct ghw_hie *el; unsigned int str; t = fgetc (h->stream); if (t == EOF) return -1; if (t == 0) break; if (t == ghw_hie_eos) { if (blk->parent == NULL) ghw_error_exit(); blk = blk->parent; 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 *) malloc_unwrap (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 = ghw_get_str(h, str); 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: el->u.blk.child = NULL; 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 = malloc_unwrap (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) return -1; sigs = (unsigned int *) calloc_unwrap (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 j; for (j = 0; j < nbr_el; j++) printf (" #%u", sigs[j]); printf ("]\n"); } } break; default: fprintf (stderr, "ghw_read_hie: unhandled kind %d\n", t); ghw_error_exit(); } } /* Allocate values. Store indication if we have NULL-type signals with index i > 0. Index i=0 */ int sigs_no_null = 1; for (i = 0; i < h->nbr_sigs; i++) if (h->sigs[i].type != NULL) h->sigs[i].val = (union ghw_val *) malloc_unwrap (sizeof (union ghw_val)); else if (i > 0 && sigs_no_null != 0) { printf ("Warning: ghw_read_hie: NULL type signal %ud.\n", i); printf ("Loading this file may take a long time.\n"); sigs_no_null = 0; } h->sigs_no_null = sigs_no_null; 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); static void print_name (struct ghw_hie *hie, int full_names) { int i; int depth; struct ghw_hie *p; struct ghw_hie **buf; struct ghw_hie **end; /* HIE must be valid. */ assert (hie->name != NULL); if (0 == full_names) { printf (" %s: ", hie->name); return; } p = hie; depth = 0; while (p && p->name) { p = p->parent; ++depth; } buf = (struct ghw_hie **) calloc_unwrap (depth, sizeof (struct ghw_hie *)); p = hie; end = depth + buf; while (p && p->name) { *(--end) = p; p = p->parent; } putchar (' '); putchar ('/'); for (i = 0; i < depth; ++i) { printf ("%s%s", i ? "/" : "", buf[i]->name); if (ghw_hie_generate_for == buf[i]->kind) { putchar ('('); ghw_disp_value (buf[i]->u.blk.iter_value, buf[i]->u.blk.iter_type); putchar (')'); } } putchar (':'); putchar (' '); free (buf); } 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) { if (0 == h->flag_full_names) 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) print_name (hie, h->flag_full_names); 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 = hie->u.sig.sigs; unsigned int k, num; print_name (hie, h->flag_full_names); ghw_disp_subtype_indication (h, hie->u.sig.type); printf (":"); k = 0; /* There can be 0-length signals. */ while (sigs[k] != GHW_NO_SIG) { /* First signal of the range. */ printf (" #%u", sigs[k]); for (num = 1; sigs[k + num] != GHW_NO_SIG; num++) if (sigs[k + num] != sigs[k + num - 1] + 1) break; if (num > 1) printf ("-#%u", sigs[k + num - 1]); k += num; } 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]; 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) { if (s->type == NULL) ghw_error_exit(); return ghw_read_value (h, s->val, s->type); } int ghw_read_snapshot (struct ghw_handler *h) { unsigned char hdr[12]; unsigned 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, &hdr[4]); if (h->flag_verbose > 1) printf ("Time is " GHWPRI64 " 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 %u\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) { unsigned char hdr[8]; if (fread (hdr, sizeof (hdr), 1, h->stream) != 1) return -1; h->snap_time = ghw_get_i64 (h, hdr); return 0; } int ghw_read_cycle_cont (struct ghw_handler *h, int *list) { uint32_t 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. */ if (h->sigs_no_null) { /* Fast version. */ i = i + d; if (i >= h->nbr_sigs) goto err; } else { /* Slow version: Linear search through all signals. Find d-th element with non-NULL type. Note: Type of sigs[0] is ignored. */ while (d > 0) { i++; if (i >= h->nbr_sigs) goto err; if (h->sigs[i].type != NULL) d--; } } // i=0 is not a valid signal if (i == 0) goto err; 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; err: fprintf(stderr, "Error: ghw_read_cycle_cont: Invalid entry in GHW file.\n"); return -1; } 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, uint32_t e) { if (e >= type->en.nbr) return "??"; else return type->en.lits[e]; } static void ghw_disp_lit (union ghw_type *type, uint32_t e) { printf ("%s (%u)", 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 (GHWPRI32, val->i32); break; case ghdl_rtik_type_p64: printf (GHWPRI64, 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); ghw_error_exit(); } } /* 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) { union ghw_type *base = ghw_get_base_type (type); switch (base->kind) { case ghdl_rtik_type_b2: if (val->b2 <= 1) { strncpy (buf, ghw_get_lit(base, val->b2), len - 1); buf[len - 1] = 0; } else { snprintf (buf, len, "?%d", val->b2); } break; case ghdl_rtik_type_e8: if (val->b2 <= base->en.nbr) { strncpy (buf, ghw_get_lit(base, val->e8), len - 1); buf[len - 1] = 0; } else { snprintf (buf, len, "?%d", val->e8); } break; case ghdl_rtik_type_i32: snprintf (buf, len, GHWPRI32, val->i32); break; case ghdl_rtik_type_p64: snprintf (buf, len, GHWPRI64, val->i64); break; case ghdl_rtik_type_f64: snprintf (buf, len, "%g", val->f64); break; default: snprintf (buf, len, "?bad type %d?", type->kind); } } static char is_skip_signal (int *signals_to_keep, int nb_signals_to_keep, int signal) { int i; for (i = 0; i < nb_signals_to_keep; ++i) { if (signal == signals_to_keep[i]) { return 0; } } return 1; } void ghw_filter_signals (struct ghw_handler *h, int *signals_to_keep, int nb_signals_to_keep) { unsigned i; if (0 < nb_signals_to_keep && 0 != signals_to_keep) { if (0 == h->skip_sigs) { h->skip_sigs = (char *) calloc_unwrap (h->nbr_sigs, sizeof (char)); } for (i = 0; i < h->nbr_sigs; ++i) { h->skip_sigs[i] = is_skip_signal (signals_to_keep, nb_signals_to_keep, i); } } else { if (0 != h->skip_sigs) { free (h->skip_sigs); h->skip_sigs = 0; } } } void ghw_disp_values (struct ghw_handler *h) { unsigned i; for (i = 0; i < h->nbr_sigs; i++) { struct ghw_sig *s = &h->sigs[i]; int skip = (0 != h->skip_sigs && (0 != h->skip_sigs[i])); if (s->type != NULL && !skip) { printf ("#%u: ", 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]; 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 " GHWPRI64 " 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 " GHWPRI64 " 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]; 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 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_b2: printf ("%s %s %s", ghw_get_lit (type, rng->b2.left), ghw_get_dir (rng->b2.dir), ghw_get_lit (type, rng->b2.right)); break; 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 (GHWPRI32 " %s " GHWPRI32, rng->i32.left, ghw_get_dir (rng->i32.dir), rng->i32.right); break; case ghdl_rtik_type_i64: case ghdl_rtik_type_p64: printf (GHWPRI64 " %s " GHWPRI64, 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); } } static void ghw_disp_array_subtype_bounds (struct ghw_subtype_array *a) { unsigned i; struct ghw_type_array *base = (struct ghw_type_array *) ghw_get_base_type (a->base); printf (" ("); for (i = 0; i < base->nbr_dim; i++) { if (i != 0) printf (", "); ghw_disp_range (base->dims[i], a->rngs[i]); } printf (")"); } static void ghw_disp_record_subtype_bounds (struct ghw_subtype_record *sr) { struct ghw_type_record *base = sr->base; int is_first = 1; unsigned i; for (i = 0; i < base->nbr_fields; i++) { if (sr->els[i].type != base->els[i].type) { if (is_first) { printf ("("); is_first = 0; } else printf (", "); printf ("%s", base->els[i].name); switch (sr->els[i].type->kind) { case ghdl_rtik_subtype_array: ghw_disp_array_subtype_bounds (&sr->els[i].type->sa); break; case ghdl_rtik_subtype_record: ghw_disp_record_subtype_bounds (&sr->els[i].type->sr); break; default: printf ("??? (%d)", sr->els[i].type->kind); } } } if (!is_first) printf (")"); } static void ghw_disp_subtype_definition (struct ghw_handler *h, union ghw_type *t) { switch (t->kind) { case ghdl_rtik_subtype_scalar: { struct ghw_subtype_scalar *s = &t->ss; ghw_disp_typename (h, s->base); printf (" range "); ghw_disp_range (s->base, s->rng); } break; case ghdl_rtik_subtype_array: { struct ghw_subtype_array *a = &t->sa; ghw_disp_typename (h, (union ghw_type *) a->base); ghw_disp_array_subtype_bounds (a); } break; case ghdl_rtik_subtype_record: { struct ghw_subtype_record *sr = &t->sr; ghw_disp_typename (h, (union ghw_type *) sr->base); ghw_disp_record_subtype_bounds (sr); } break; case ghdl_rtik_subtype_unbounded_array: case ghdl_rtik_subtype_unbounded_record: { struct ghw_subtype_unbounded_record *sur = &t->sur; ghw_disp_typename (h, (union ghw_type *) sur->base); } break; default: printf ("ghw_disp_subtype_definition: unhandled type kind %d\n", t->kind); } } static int ghw_is_anonymous_type (struct ghw_handler *h, union ghw_type *t) { return t->common.name == h->str_table[0]; } void ghw_disp_subtype_indication (struct ghw_handler *h, union ghw_type *t) { if (ghw_is_anonymous_type (h, t)) { /* Anonymous subtype. */ ghw_disp_subtype_definition (h, t); } else ghw_disp_typename (h, t); } 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; uint32_t i; printf ("type %s is (", e->name); for (i = 0; i < e->nbr; i++) { if (i != 0) printf (", "); printf ("%s", ghw_get_lit(t, 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 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 = " GHWPRI64 " %s;\n", u->name, u->val, p->units[0].name); } printf ("end units;\n"); } break; case ghdl_rtik_type_array: { struct ghw_type_array *a = &t->ar; unsigned 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_subtype_indication (h, a->el); printf (";\n"); } break; case ghdl_rtik_type_record: { struct ghw_type_record *r = &t->rec; unsigned i; printf ("type %s is record\n", r->name); for (i = 0; i < r->nbr_fields; i++) { printf (" %s: ", r->els[i].name); ghw_disp_subtype_indication (h, r->els[i].type); printf (";\n"); } printf ("end record;\n"); } break; case ghdl_rtik_subtype_array: case ghdl_rtik_subtype_scalar: case ghdl_rtik_subtype_record: case ghdl_rtik_subtype_unbounded_array: case ghdl_rtik_subtype_unbounded_record: { struct ghw_type_common *c = &t->common; printf ("subtype %s is ", c->name); ghw_disp_subtype_definition (h, t); printf (";\n"); } break; default: printf ("ghw_disp_type: unhandled type kind %d\n", t->kind); } } void ghw_disp_types (struct ghw_handler *h) { uint32_t i; for (i = 0; i < h->nbr_types; i++) if (h->types[i] != NULL && (h->flag_verbose || !ghw_is_anonymous_type (h, h->types[i]))) ghw_disp_type (h, ghw_get_typeid(h, i+1)); // pass i+1 to access index i } gtkwave-gtk3-3.3.125/src/fetchbuttons.h0000664000175000017500000000106515047725112017167 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-gtk3-3.3.125/src/ptranslate.c0000664000175000017500000003407215047725112016633 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 "gtk23compat.h" #include "symbol.h" #include "ptranslate.h" #include "pipeio.h" #include "debug.h" enum { NAME_COLUMN, N_COLUMNS }; static gboolean XXX_view_selection_func (GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean path_currently_selected, gpointer userdata) { (void) selection; (void) model; (void) userdata; gint *idx = NULL; if(path) { idx = gtk_tree_path_get_indices (path); if(idx) { if(!path_currently_selected) { GLOBALS->current_filter_ptranslate_c_1 = idx[0] + 1; } else { GLOBALS->current_filter_ptranslate_c_1 = 0; /* none */ } } } return(TRUE); } 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__ cmd = (char *)malloc_2(strlen(exec_name)+6+1); sprintf(cmd, "which %s", exec_name); stream = popen_san(cmd, "r"); result = fscanf(stream, "%s", abs_path); pclose(stream); free_2(cmd); if((strlen(abs_path) == 0)||(!result)) { status_text("Could not find filter process!\n"); return; } #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 add_filter_callback_2(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; int i; 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(gtk_widget_get_window(GLOBALS->window_ptranslate_c_5)); 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); GtkTreeIter iter; gtk_list_store_append (GTK_LIST_STORE(GLOBALS->sig_store_ptranslate), &iter); gtk_list_store_set (GTK_LIST_STORE(GLOBALS->sig_store_ptranslate), &iter, NAME_COLUMN, GLOBALS->procsel_filter[GLOBALS->num_proc_filters], -1); } else { GLOBALS->num_proc_filters--; } if(GLOBALS->is_active_ptranslate_c_2) gdk_window_raise(gtk_widget_get_window(GLOBALS->window_ptranslate_c_5)); } 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,G_CALLBACK(add_filter_callback_2), G_CALLBACK(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; if(GLOBALS->is_active_ptranslate_c_2) { gdk_window_raise(gtk_widget_get_window(GLOBALS->window_ptranslate_c_5)); 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(XXX_GTK_OBJECT (GLOBALS->window_ptranslate_c_5), "delete_event",(GCallback) destroy_callback, NULL); table = XXX_gtk_table_new (256, 1, FALSE); gtk_widget_show (table); vbox1 = XXX_gtk_vbox_new (FALSE, 0); gtk_container_set_border_width (GTK_CONTAINER (vbox1), 3); gtk_widget_show (vbox1); frame2 = gtk_frame_new (NULL); gtk_container_set_border_width (GTK_CONTAINER (frame2), 3); gtk_widget_show(frame2); XXX_gtk_table_attach (XXX_GTK_TABLE (table), frame2, 0, 1, 0, 254, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); GLOBALS->sig_store_ptranslate = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING); GtkWidget *sig_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (GLOBALS->sig_store_ptranslate)); /* The view now holds a reference. We can get rid of our own reference */ g_object_unref (G_OBJECT (GLOBALS->sig_store_ptranslate)); GtkCellRenderer *renderer = gtk_cell_renderer_text_new (); GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes (titles[0], renderer, "text", NAME_COLUMN, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (sig_view), column); /* Setup the selection handler */ GLOBALS->sig_selection_ptranslate = gtk_tree_view_get_selection (GTK_TREE_VIEW (sig_view)); gtk_tree_selection_set_mode (GLOBALS->sig_selection_ptranslate, GTK_SELECTION_SINGLE); gtk_tree_selection_set_select_function (GLOBALS->sig_selection_ptranslate, XXX_view_selection_func, NULL, NULL); gtk_list_store_clear (GTK_LIST_STORE(GLOBALS->sig_store_ptranslate)); for(i=0;inum_proc_filters;i++) { GtkTreeIter iter; gtk_list_store_append (GTK_LIST_STORE(GLOBALS->sig_store_ptranslate), &iter); gtk_list_store_set (GTK_LIST_STORE(GLOBALS->sig_store_ptranslate), &iter, NAME_COLUMN, GLOBALS->procsel_filter[i+1], -1); } gtk_widget_show (sig_view); 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_size_request( 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), sig_view); gtk_container_add (GTK_CONTAINER (frame2), scrolled_win); frameh0 = gtk_frame_new (NULL); gtk_container_set_border_width (GTK_CONTAINER (frameh0), 3); gtk_widget_show(frameh0); XXX_gtk_table_attach (XXX_GTK_TABLE (table), frameh0, 0, 1, 254, 255, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); hbox0 = XXX_gtk_hbox_new (FALSE, 1); gtk_widget_show (hbox0); button6 = gtk_button_new_with_label (" Add Proc Filter to List "); gtk_container_set_border_width (GTK_CONTAINER (button6), 3); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button6), "clicked",G_CALLBACK(add_filter_callback),XXX_GTK_OBJECT (GLOBALS->window_ptranslate_c_5)); gtk_widget_show (button6); gtk_tooltips_set_tip_2(button6, "Bring up a file requester to add a process filter to the filter select window."); 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_set_border_width (GTK_CONTAINER (frameh), 3); gtk_widget_show(frameh); XXX_gtk_table_attach (XXX_GTK_TABLE (table), frameh, 0, 1, 255, 256, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); hbox = XXX_gtk_hbox_new (FALSE, 1); gtk_widget_show (hbox); button1 = gtk_button_new_with_label (" OK "); gtk_container_set_border_width (GTK_CONTAINER (button1), 3); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button1), "clicked",G_CALLBACK(ok_callback),XXX_GTK_OBJECT (GLOBALS->window_ptranslate_c_5)); gtk_widget_show (button1); gtk_tooltips_set_tip_2(button1, "Add selected signals to end of the display on the main window."); #if GTK_CHECK_VERSION(3,0,0) gtk_box_pack_start(GTK_BOX(hbox), button1, TRUE, TRUE, 0); #else gtk_box_pack_start (GTK_BOX (hbox), button1, TRUE, FALSE, 0); #endif button5 = gtk_button_new_with_label (" Cancel "); gtk_container_set_border_width (GTK_CONTAINER (button5), 3); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button5), "clicked",G_CALLBACK(destroy_callback),XXX_GTK_OBJECT (GLOBALS->window_ptranslate_c_5)); gtk_tooltips_set_tip_2(button5, "Do nothing and return to the main window."); gtk_widget_show (button5); #if GTK_CHECK_VERSION(3,0,0) gtk_box_pack_start(GTK_BOX(hbox), button5, TRUE, TRUE, 0); #else gtk_box_pack_start (GTK_BOX (hbox), button5, TRUE, FALSE, 0); #endif gtk_container_add (GTK_CONTAINER (frameh), hbox); gtk_container_add (GTK_CONTAINER (GLOBALS->window_ptranslate_c_5), table); gtk_widget_set_size_request(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-gtk3-3.3.125/src/vcd_recoder.c0000664000175000017500000026676215047725112016752 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2017. * * 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 * Backtracking fix 16oct18ajb */ #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 = vlist_packer_create(); struct vlist_t *vlist_summary_index; struct vcdsymbol *v = GLOBALS->vcdsymroot_vcd_recoder_c_3; guint64 val = (guint64)(uintptr_t)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(&vlist_p, (guint64)mystat->st_size); vlist_packer_emit_uv64(&vlist_p, (guint64)mystat->st_mtime); #else vlist_packer_emit_uv64(&vlist_p, (guint64)0); vlist_packer_emit_uv64(&vlist_p, (guint64)0); #endif vlist_packer_emit_uv32(&vlist_p, finalize_cnt); vlist_packer_emit_uv64(&vlist_p, GLOBALS->time_vlist_count_vcd_recoder_c_1); vlist_packer_emit_uv64(&vlist_p, val); val = 0; while(v) { nptr n = v->narray[0]; nval = (guint64)(uintptr_t)n->mv.mvlfac_vlist; vlist_packer_emit_uv64(&vlist_p, nval - val); val = nval; v = v->next; } 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)(uintptr_t)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); memset(GLOBALS->vcdbuf_vcd_recoder_c_3, 0, VCD_BSIZ); 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 ? ch : -1); } 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 ? ch : -1); } 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 */ GLOBALS->yylen_vcd_recoder_c_3=len; if(is_string) { 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==':' && !ignore_colon) 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==':' && !ignore_colon)||(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 ignore_colon, int match_kw) { int ch; int len=0; if(GLOBALS->varsplit_vcd_recoder_c_3) { int rc=get_vartoken_patched(ignore_colon, 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==':' && !ignore_colon) 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) { if(!GLOBALS->varsplit_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); } else /* TALOS-2023-1806 */ { int vsplit_len = GLOBALS->varsplit_vcd_recoder_c_3 - GLOBALS->yytext_vcd_recoder_c_3; /* save old len */ 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); GLOBALS->varsplit_vcd_recoder_c_3 = GLOBALS->yytext_vcd_recoder_c_3+vsplit_len; /* reconstruct old len in new buffer */ } } 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==':' && !ignore_colon)||(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; } else if(strstr(GLOBALS->yytext_vcd_recoder_c_3, "Questa") || strstr(GLOBALS->yytext_vcd_recoder_c_3, "ModelSim")) /* realparam fix only is for MTI, conflicts with Vivado */ { GLOBALS->mti_realparam_fix = 1; 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_PARAMETER)&&(typ2=='R')) /* github #446: size 0 on parameter with type declared wrong */ { v->vartype = V_REAL; /* override any data we parsed in for $var declaration */ v->size=1; v->msi=v->lsi=0; fprintf(stderr, "GTKWAVE | Warning: symbol '%s' changing datatype from parameter to real.\n", v->name); } 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; int colon_seen = 0; int num_seen = 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_END && tok != T_EOF) { 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) /* reinstated because of TALOS-2023-1805 */ { 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(0, 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(0, 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(0, 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, 0); if(vtok==V_RB) { v->lsi=v->msi; v->size=1; } else { if(vtok!=V_COLON) goto err; vtok=get_vartoken(0, 0); if(vtok!=V_STRING) goto err; v->lsi=atoi_64(GLOBALS->yytext_vcd_recoder_c_3); vtok=get_vartoken(0, 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(1, 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, '\\')) && (v->lsi != GLOBALS->pv_vcd_recoder_c_3->lsi)) { 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(0, 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(1, 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) && (v->lsi != GLOBALS->pv_vcd_recoder_c_3->lsi)) { 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); num_seen = 0; vtok=get_vartoken(0, 1); if(vtok==V_END) goto dumpv; if(vtok!=V_LB) goto err; colon_seen = 0; vtok=get_vartoken(0, 0); if(vtok!=V_STRING) goto err; num_seen = 1; v->msi=atoi_64(GLOBALS->yytext_vcd_recoder_c_3); vtok=get_vartoken(0, 0); if(vtok==V_RB) { v->lsi=v->msi; goto dumpv; } if(vtok!=V_COLON) goto err; colon_seen = 1; vtok=get_vartoken(0, 0); if(vtok!=V_STRING) goto err; v->lsi=atoi_64(GLOBALS->yytext_vcd_recoder_c_3); vtok=get_vartoken(0, 0); if(vtok!=V_RB) goto err; } dumpv: if(v->size == 0) { if(v->vartype != V_EVENT) { if(v->vartype != V_STRINGTYPE) { if(!GLOBALS->mti_realparam_fix) { v->size = 1; } else { v->vartype = V_REAL; } } } else { v->size = 1; } } /* MTI fix */ else { unsigned int abslen = (v->msi >= v->lsi) ? (v->msi - v->lsi + 1) : (v->lsi - v->msi + 1); if(!colon_seen) { if(num_seen && (v->size > 1)) { char buf[32]; char *sfix; int vname_len = strlen(v->name); int num_len = snprintf(buf, 32, "[%d]", v->lsi); sfix = malloc_2(vname_len + num_len + 1); memcpy(sfix, v->name, vname_len); memcpy(sfix+vname_len, buf, num_len + 1); free_2(v->name); v->name = sfix; } if(v->size > 1) { v->lsi = 0; v->msi = v->size - 1; } } else { if((v->size != abslen) && (num_seen)) { if(v->lsi < v->msi) { v->msi = v->lsi + v->size - 1; } else { v->lsi = v->msi + v->size - 1; } } } } 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)) { if((v->msi-v->lsi+1) > v->size) /* if() is 2d add */ { 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)) { if((v->lsi-v->msi+1) > v->size) /* if() is 2d add */ { 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 { /* backtracking fix */ if(tim < GLOBALS->current_time_vcd_recoder_c_3) { if(!GLOBALS->vcd_already_backtracked) { GLOBALS->vcd_already_backtracked = 1; fprintf(stderr, "VCDLOAD | Time backtracking detected in VCD file!\n"); } } #if 0 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; } #endif 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))) : remove redundant condition */ if((!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")); } } } /*******************************************************************************/ static 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; if(n->curr->v.h_val==heval) { n->curr->flags|=HIST_GLITCH; /* set the glitch flag */ GLOBALS->num_glitch_regions_vcd_recoder_c_4++; } 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->flags != (HIST_STRING|HIST_REAL)) /* because n->curr->v.h_vector could be a double and not a pointer */ ||(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: 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; } } else { free_2(vector); } } 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)||(v->msi != v->lsi)) { 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); /* 2d add */ 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; } } 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; } } } 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_san(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-gtk3-3.3.125/src/strace.c0000664000175000017500000012715415047725112015743 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 "gtk23compat.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 */ #define WV_STRACE_CURWIN(x) g_object_set_data(G_OBJECT(x), WV_STRACE_CTX, (gpointer)GLOBALS->strace_ctx) /* need to do this at top of every entry point function where a signal is connected */ #define GET_WV_STRACE_CURWIN(x) GLOBALS->strace_ctx=g_object_get_data(G_OBJECT(x), WV_STRACE_CTX) 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_windows[s_ctx_iter]; if(strace_ctx->window_strace_c_10) activ++; } return(activ); } /* * free the straces... */ static void free_straces(void) { struct strace *s, *skill; struct strace_defer_free *sd, *sd2; s=GLOBALS->strace_ctx->straces; while(s) { if(s->string) free_2(s->string); skill=s; s=s->next; free_2(skill); } GLOBALS->strace_ctx->straces=NULL; if(count_active_straces() <= 1) /* only free up traces if there is only one pattern search active. we could splice across multiple strace_ctx but it's not worth the effort here */ { 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; /* moved inside if() so it frees eventually and doesn't stay around until context cleanup */ } } /* * button/menu/entry activations.. */ static void logical_clicked(GtkComboBox *widget, gpointer user_data) { (void) user_data; GtkComboBox *combo_box = widget; int which = gtk_combo_box_get_active (combo_box); int i; GET_WV_STRACE_CURWIN(widget); for(i=0;i<6;i++) GLOBALS->strace_ctx->logical_mutex[i]=0; GLOBALS->strace_ctx->logical_mutex[which]=1; /* mark our choice */ } static void stype_clicked(GtkComboBox *widget, gpointer user_data) { GtkComboBox *combo_box = widget; int which = gtk_combo_box_get_active (combo_box); struct strace *s = (struct strace *)user_data; GET_WV_STRACE_CURWIN(widget); s->value=which; DEBUG(printf("Trace %s Search Type: %s\n", s->trace->name, stype[(int)s->value])); } static void start_clicked(GtkComboBox *widget, gpointer user_data) { (void) user_data; GtkComboBox *combo_box = widget; int which = gtk_combo_box_get_active (combo_box); GET_WV_STRACE_CURWIN(widget); GLOBALS->strace_ctx->mark_idx_start=which; } static void end_clicked(GtkComboBox *widget, gpointer user_data) { (void) user_data; GtkComboBox *combo_box = widget; int which = gtk_combo_box_get_active (combo_box); GET_WV_STRACE_CURWIN(widget); GLOBALS->strace_ctx->mark_idx_end=which; } 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_editable_select_region (GTK_EDITABLE (widget), 0, gtk_entry_get_text_length(GTK_ENTRY(widget))); 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]; #if GTK_CHECK_VERSION(3,0,0) sprintf (mark_count_buf, "Beg/End Marks: %d", GLOBALS->strace_ctx->timearray_size); #else sprintf (mark_count_buf, "Mark Count: %d", GLOBALS->strace_ctx->timearray_size); #endif gtk_label_set_text (GTK_LABEL(GLOBALS->strace_ctx->ptr_mark_count_label_strace_c_1), mark_count_buf); } } void tracesearchbox(const char *title, GCallback func, gpointer data) { 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) { XXX_gdk_pointer_ungrab(GDK_CURRENT_TIME); } if(GLOBALS->strace_ctx->straces) { gdk_window_raise(gtk_widget_get_window(GLOBALS->strace_ctx->window_strace_c_10)); 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_size_request( GTK_WIDGET (GLOBALS->strace_ctx->window_strace_c_10), 420, -1); gtkwave_signal_connect(XXX_GTK_OBJECT (GLOBALS->strace_ctx->window_strace_c_10), "delete_event",(GCallback) destroy_callback, NULL); WV_STRACE_CURWIN(GLOBALS->strace_ctx->window_strace_c_10); vbox = XXX_gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (GLOBALS->strace_ctx->window_strace_c_10), vbox); gtk_widget_show (vbox); vbox_g = XXX_gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox_g); frame = gtk_frame_new (NULL); gtk_container_set_border_width (GTK_CONTAINER (frame), 3); gtk_widget_show(frame); small_hbox = XXX_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); GtkWidget *combo_box = gtk_combo_box_text_new (); for(i=0;i<6;i++) { gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT(combo_box), logical[i]); GLOBALS->strace_ctx->logical_mutex[i]=0; } GLOBALS->strace_ctx->logical_mutex[0]=1; /* "and" */ gtk_combo_box_set_active (GTK_COMBO_BOX(combo_box), 0); WV_STRACE_CURWIN(combo_box); g_signal_connect (combo_box, "changed", G_CALLBACK (logical_clicked), NULL); gtk_box_pack_start (GTK_BOX (small_hbox), combo_box, TRUE, FALSE, 0); gtk_widget_show (combo_box); gtk_box_pack_start (GTK_BOX (vbox), small_hbox, FALSE, FALSE, 0); scrolled_win = gtk_scrolled_window_new (NULL, NULL); gtk_widget_set_size_request( 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); #if GTK_CHECK_VERSION(3,0,0) gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0); #else gtk_container_add (GTK_CONTAINER (vbox), frame); #endif 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 = XXX_gtk_hseparator_new (); gtk_widget_show (separator); gtk_box_pack_start (GTK_BOX (vbox_g), separator, FALSE, FALSE, 0); } small_hbox = XXX_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); combo_box = gtk_combo_box_text_new (); for(i=0;istrace_ctx->mark_idx_start); gtk_box_pack_start (GTK_BOX (mark_count_hbox_start), combo_box, TRUE, FALSE, 0); /* add mark end GUI element */ mark_count_hbox_end=XXX_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); #if GTK_CHECK_VERSION(3,0,0) #else ptr_mark_label=gtk_label_new ("Marking Stops at:"); gtk_widget_show (ptr_mark_label); gtk_box_pack_start (GTK_BOX (mark_count_hbox_end),ptr_mark_label,TRUE,FALSE,0); #endif combo_box = gtk_combo_box_text_new (); for(idx=0; idxstrace_ctx->mark_idx_end); gtk_box_pack_start (GTK_BOX (mark_count_hbox_end), combo_box, TRUE, FALSE, 0); /* 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 = XXX_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_size_request(button1, 75, -1); gtkwave_signal_connect(XXX_GTK_OBJECT (button1), "clicked", G_CALLBACK(forwards_callback), NULL); WV_STRACE_CURWIN(button1); gtk_widget_show (button1); #if GTK_CHECK_VERSION(3,0,0) gtk_box_pack_start(GTK_BOX(hbox), button1, TRUE, TRUE, 0); #else gtk_container_add (GTK_CONTAINER (hbox), button1); #endif gtk_widget_set_can_default (button1, TRUE); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button1), "realize", (GCallback) gtk_widget_grab_default, XXX_GTK_OBJECT (button1)); button1a = gtk_button_new_with_label ("Bkwd"); gtk_widget_set_size_request(button1a, 75, -1); gtkwave_signal_connect(XXX_GTK_OBJECT (button1a), "clicked", G_CALLBACK(backwards_callback), NULL); WV_STRACE_CURWIN(button1a); gtk_widget_show (button1a); #if GTK_CHECK_VERSION(3,0,0) gtk_box_pack_start(GTK_BOX(hbox), button1a, TRUE, TRUE, 0); #else gtk_container_add (GTK_CONTAINER (hbox), button1a); #endif gtk_widget_set_can_default (button1a, TRUE); button1b = gtk_button_new_with_label ("Mark"); gtk_widget_set_size_request(button1b, 75, -1); gtkwave_signal_connect(XXX_GTK_OBJECT (button1b), "clicked", G_CALLBACK(mark_callback), NULL); WV_STRACE_CURWIN(button1b); gtk_widget_show (button1b); #if GTK_CHECK_VERSION(3,0,0) gtk_box_pack_start(GTK_BOX(hbox), button1b, TRUE, TRUE, 0); #else gtk_container_add (GTK_CONTAINER (hbox), button1b); #endif gtk_widget_set_can_default (button1b, TRUE); button1c = gtk_button_new_with_label ("Clear"); gtk_widget_set_size_request(button1c, 75, -1); gtkwave_signal_connect(XXX_GTK_OBJECT (button1c), "clicked", G_CALLBACK(clear_callback), NULL); WV_STRACE_CURWIN(button1c); gtk_widget_show (button1c); #if GTK_CHECK_VERSION(3,0,0) gtk_box_pack_start(GTK_BOX(hbox), button1c, TRUE, TRUE, 0); #else gtk_container_add (GTK_CONTAINER (hbox), button1c); #endif gtk_widget_set_can_default (button1c, TRUE); button2 = gtk_button_new_with_label ("Exit"); gtk_widget_set_size_request(button2, 75, -1); gtkwave_signal_connect(XXX_GTK_OBJECT (button2), "clicked", G_CALLBACK(destroy_callback), NULL); WV_STRACE_CURWIN(button2); gtk_widget_show (button2); #if GTK_CHECK_VERSION(3,0,0) gtk_box_pack_start(GTK_BOX(hbox), button2, TRUE, TRUE, 0); #else gtk_container_add (GTK_CONTAINER (hbox), button2); #endif gtk_widget_set_can_default (button2, TRUE); 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_set_value(GTK_ADJUSTMENT(GLOBALS->wave_hslider), 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; TimeType orig_basetime; 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); orig_basetime = basetime; 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 */ if(basetime >= orig_basetime) { 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; TraceFlagsType 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("@%"TRACEFLAGSPRIFMT"\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-gtk3-3.3.125/src/libghw.h0000664000175000017500000002330215047725112015731 0ustar bybellbybell/* GHDL Wavefile reader library. Copyright (C) 2005-2017 Tristan Gingold 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, see . */ #ifndef _LIBGHW_H_ #define _LIBGHW_H_ #include #include /* To be libraries friendly. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef __cplusplus extern "C" { #endif /* The libghw uses the standard c99 int32_t and int64_t. They are declared in stdint.h. Header inttypes.h includes stdint.h and provides macro for printf and co specifiers. Use it if known to be available. */ #if defined(__cplusplus) || \ defined(__linux__) || \ (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ defined(HAVE_INTTYPES_H) /* Use C99 standard header. */ #include #define GHWPRI64 "%" PRId64 #define GHWPRI32 "%" PRId32 #else #include #define GHWPRI64 "%lld" #define GHWPRI32 "%d" #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, /* Obsolete. */ ghdl_rtik_subtype_unbounded_array, ghdl_rtik_subtype_record, ghdl_rtik_subtype_unbounded_record, #if 0 ghdl_rtik_subtype_access, /* 40 */ ghdl_rtik_type_protected, ghdl_rtik_element, ghdl_rtik_unit, ghdl_rtik_attribute_transaction, ghdl_rtik_attribute_quiet, ghdl_rtik_attribute_stable, #endif 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 { enum ghdl_rtik kind:8; int dir:8; /* 0: to, !0: downto. */ unsigned char left; unsigned char right; }; struct ghw_range_e8 { enum ghdl_rtik kind:8; int dir:8; /* 0: to, !0: downto. */ unsigned char left; unsigned char right; }; struct ghw_range_i32 { enum ghdl_rtik kind:8; int dir:8; /* 0: to, !0: downto. */ int32_t left; int32_t right; }; struct ghw_range_i64 { enum ghdl_rtik kind:8; int dir:8; int64_t left; int64_t right; }; struct ghw_range_f64 { enum ghdl_rtik kind:8; int dir:8; double left; double right; }; union ghw_range { enum ghdl_rtik kind:8; struct ghw_range_b2 b2; 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; uint32_t 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; unsigned int nbr_dim; union ghw_type *el; union ghw_type **dims; }; struct ghw_subtype_unbounded_array { enum ghdl_rtik kind; const char *name; union ghw_type *base; }; struct ghw_subtype_array { enum ghdl_rtik kind; const char *name; union ghw_type *base; int nbr_scalars; union ghw_range **rngs; union ghw_type *el; }; 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; unsigned int nbr_fields; int nbr_scalars; /* Number of scalar elements (ie nbr of signals). */ struct ghw_record_element *els; }; struct ghw_subtype_record { enum ghdl_rtik kind; const char *name; struct ghw_type_record *base; int nbr_scalars; /* Number of scalar elements (ie nbr of signals). */ struct ghw_record_element *els; }; struct ghw_subtype_unbounded_record { enum ghdl_rtik kind; const char *name; struct ghw_type_record *base; }; 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_type_array ar; struct ghw_type_record rec; struct ghw_subtype_array sa; struct ghw_subtype_unbounded_array sua; struct ghw_subtype_record sr; struct ghw_subtype_unbounded_record sur; }; 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 }; #define GHW_NO_SIG 0 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 GHW_NO_SIG (0). */ unsigned int *sigs; } sig; } u; }; struct ghw_handler { FILE *stream; /* True if STREAM was popen, else was fopen. */ unsigned char stream_ispipe; /* True if words are big-endian. */ unsigned char word_be; unsigned char word_len; unsigned char off_len; /* Minor version. */ int version; /* Set by user. */ int flag_verbose; /* String table. */ /* Number of strings. */ uint32_t nbr_str; /* Size of the strings (without nul). */ uint32_t str_size; /* String table. */ char **str_table; /* Array containing strings. */ char *str_content; /* Type table. */ uint32_t nbr_types; union ghw_type **types; /* Non-composite (or basic) signals. */ uint32_t nbr_sigs; char *skip_sigs; int flag_full_names; struct ghw_sig *sigs; /* 1: sigs does not contain any signals with type = NULL and index > 0 */ int sigs_no_null; /* 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); /* Return base type of T. */ union ghw_type *ghw_get_base_type (union ghw_type *t); /* Return length of RNG. */ int ghw_get_range_length (union ghw_range *rng); /* 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_filter_signals (struct ghw_handler *h, int *signals_to_keep, int nb_signals_to_keep); 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 }; enum ghw_res ghw_read_sm_hdr (struct ghw_handler *h, int *list); int ghw_read_sm (struct ghw_handler *h, enum ghw_sm_type *sm); 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); void ghw_disp_subtype_indication (struct ghw_handler *h, union ghw_type *t); /* 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); #ifdef __cplusplus } #endif #endif /* _LIBGHW_H_ */ gtkwave-gtk3-3.3.125/src/ptranslate.h0000664000175000017500000000127615047725112016640 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-gtk3-3.3.125/src/strace.h0000664000175000017500000000512115047725112015735 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" #define WAVE_NUM_STRACE_WINDOWS (2) #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 { 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 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, GCallback func, gpointer data); #endif gtkwave-gtk3-3.3.125/src/hierpack.c0000664000175000017500000001072615047725112016244 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2008-2017. * * 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) static 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)); } void hier_auto_enable(void) { if((!GLOBALS->do_hier_compress) && (!GLOBALS->disable_auto_comphier) && (GLOBALS->numfacs >= HIER_AUTO_ENABLE_CNT)) { GLOBALS->do_hier_compress = 1; } } gtkwave-gtk3-3.3.125/src/discardbuttons.c0000664000175000017500000000415215047725112017502 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; pixmapwid1=gtk_image_new_from_pixbuf(GLOBALS->larrow_pixbuf); gtk_widget_show(pixmapwid1); pixmapwid2=gtk_image_new_from_pixbuf(GLOBALS->rarrow_pixbuf); gtk_widget_show(pixmapwid2); /* Create a table to hold the text widget and scrollbars */ table = XXX_gtk_table_new (1, 1, FALSE); main_vbox = XXX_gtk_vbox_new (FALSE, 1); gtk_container_set_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 = XXX_gtk_table_new (2, 1, FALSE); b1 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b1), pixmapwid1); XXX_gtk_table_attach (XXX_GTK_TABLE (table2), b1, 0, 1, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); g_signal_connect_swapped (XXX_GTK_OBJECT (b1), "clicked", G_CALLBACK(discard_left), XXX_GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(b1, "Increase 'From' Time"); gtk_widget_show(b1); b2 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b2), pixmapwid2); XXX_gtk_table_attach (XXX_GTK_TABLE (table2), b2, 0, 1, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); g_signal_connect_swapped (XXX_GTK_OBJECT (b2), "clicked", G_CALLBACK(discard_right), XXX_GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(b2, "Decrease 'To' Time"); gtk_widget_show(b2); gtk_container_add (GTK_CONTAINER (frame), table2); gtk_widget_show(table2); return(table); } gtkwave-gtk3-3.3.125/src/splash.c0000664000175000017500000143332115047725112015751 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 */ /* 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) { (void) window; GLOBALS->wave_splash_pixbuf = gdk_pixbuf_new_from_xpm_data((const gchar **)wave_splash_xpm); } #if GTK_CHECK_VERSION(3,0,0) static gint draw_event(GtkWidget *widget, cairo_t *cr, gpointer user_data) { (void) widget; (void) user_data; gdk_cairo_set_source_pixbuf (cr, GLOBALS->wave_splash_pixbuf, 0.0, 0.0); cairo_paint (cr); cairo_set_line_width(cr, 1.0); cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 1.0); cairo_rectangle (cr, 0,WAVE_SPLASH_Y-4, GLOBALS->prev_bar_x_splash_c_1, 4); cairo_fill(cr); return(FALSE); } #else static gint expose_event(GtkWidget *widget, GdkEventExpose *event) { #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX GdkDrawingContext *gdc; #endif cairo_t* cr = XXX_gdk_cairo_create (XXX_GDK_DRAWABLE (gtk_widget_get_window(widget)), &gdc); gdk_cairo_region (cr, event->region); cairo_clip (cr); gdk_cairo_set_source_pixbuf (cr, GLOBALS->wave_splash_pixbuf, 0.0, 0.0); cairo_paint (cr); #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX gdk_window_end_draw_frame(gtk_widget_get_window(widget), gdc); #else cairo_destroy (cr); #endif return(FALSE); } #endif gint splash_button_press_event(GtkWidget *widget, GdkEventExpose *event) { (void)widget; (void)event; if(GLOBALS->timeout_tag) { g_source_remove(GLOBALS->timeout_tag); GLOBALS->timeout_tag = 0; } if(GLOBALS->wave_splash_pixbuf) { g_object_unref(GLOBALS->wave_splash_pixbuf); GLOBALS->wave_splash_pixbuf = 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_get_window(GTK_WIDGET(GLOBALS->splash_splash_c_1))); } } 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(); #if defined __MINGW32__ #if GTK_CHECK_VERSION(3,0,0) GLOBALS->splash_splash_c_1 = gtk_window_new(GTK_WINDOW_TOPLEVEL); /* workaround for black bar missing on gtk3 on win32/64 */ #else GLOBALS->splash_splash_c_1 = gtk_window_new(GTK_WINDOW_POPUP); #endif #else GLOBALS->splash_splash_c_1 = gtk_window_new(GTK_WINDOW_POPUP); #endif #if !defined __MINGW32__ #ifdef WAVE_ALLOW_GTK3_GRID dx = 0; dy = 0; /* necessary if GtkGrid is used instead of GtkTable */ #else dx = 8; dy = 8; #endif #else dx = 8; dy = 8; #endif gtk_widget_set_size_request(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 = XXX_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); XXX_gtk_table_attach (XXX_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); #if GTK_CHECK_VERSION(3,0,0) gtkwave_signal_connect(XXX_GTK_OBJECT(GLOBALS->darea_splash_c_1), "draw",G_CALLBACK(draw_event), NULL); #else gtkwave_signal_connect(XXX_GTK_OBJECT(GLOBALS->darea_splash_c_1), "expose_event",G_CALLBACK(expose_event), NULL); #endif gtkwave_signal_connect(XXX_GTK_OBJECT(GLOBALS->darea_splash_c_1), "button_press_event",G_CALLBACK(splash_button_press_event), NULL); gtk_events_pending_gtk_main_iteration(); #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX GdkDrawingContext *gdc; #endif cairo_t* cr = XXX_gdk_cairo_create (XXX_GDK_DRAWABLE (gtk_widget_get_window(GLOBALS->darea_splash_c_1)), &gdc); cairo_rectangle (cr, 0, 0, WAVE_SPLASH_X,WAVE_SPLASH_Y); cairo_clip (cr); gdk_cairo_set_source_pixbuf (cr, GLOBALS->wave_splash_pixbuf, 0.0, 0.0); cairo_paint (cr); #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX gdk_window_end_draw_frame(gtk_widget_get_window(GLOBALS->darea_splash_c_1), gdc); #else cairo_destroy (cr); #endif gtk_events_pending_gtk_main_iteration(); GLOBALS->timeout_tag = g_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)) { #if defined __MINGW32__ #if GTK_CHECK_VERSION(3,0,0) gdk_window_raise(gtk_widget_get_window(GLOBALS->splash_splash_c_1)); #endif #endif 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 */ #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX GdkDrawingContext *gdc; #endif cairo_t* cr = XXX_gdk_cairo_create (XXX_GDK_DRAWABLE (gtk_widget_get_window(GLOBALS->darea_splash_c_1)), &gdc); cairo_set_line_width(cr, 1.0); cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 1.0); cairo_rectangle (cr, 0,WAVE_SPLASH_Y-4, (GLOBALS->prev_bar_x_splash_c_1 = cur_bar_x), 4); cairo_fill(cr); #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX gdk_window_end_draw_frame(gtk_widget_get_window(GLOBALS->darea_splash_c_1), gdc); gtk_widget_queue_draw_area(GLOBALS->darea_splash_c_1, 0, WAVE_SPLASH_Y-4, cur_bar_x, 4); /* needed for wayland */ #else cairo_destroy (cr); #endif } } 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 } } gtkwave-gtk3-3.3.125/src/version.h0000664000175000017500000000067115047725112016146 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2010-2025. * * 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-2025 BSI" #endif gtkwave-gtk3-3.3.125/src/hierpack.h0000664000175000017500000000127215047725112016245 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2008-2017. * * 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) #define HIER_AUTO_ENABLE_CNT (500000) 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); void hier_auto_enable(void); #endif gtkwave-gtk3-3.3.125/src/print.c0000664000175000017500000023554015047725112015615 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 */ static gdouble maxdbl (gdouble a, gdouble b) { return (a > b ? a : b); } static gdouble mindbl (gdouble a, gdouble b) { return (a < b ? a : b); } /* * 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) (gtk_adjustment_get_value(sadj)); t = GLOBALS->traces.first; trwhich = 0; while (t) { if ((trwhich < trtarget) && (GiveNextTrace (t))) { trwhich++; t = GiveNextTrace (t); } else { break; } } GtkAllocation allocation; gtk_widget_get_allocation(GLOBALS->signalarea, &allocation); num_traces_displayable = 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, invert; 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; 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 */ if(GLOBALS->fill_waveform && invert) { pr_draw_box (prc, _x0, _y0, _x1, _y1); } 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 */ if(GLOBALS->fill_waveform && !invert) { pr_draw_box (prc, _x0, _y1, _x1, _y0); } 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; GtkAllocation allocation; gtk_widget_get_allocation(GLOBALS->signalarea, &allocation); int num_traces_displayable = 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_print (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; GtkAllocation allocation; gtk_widget_get_allocation(GLOBALS->signalarea, &allocation); int num_traces_displayable = 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_print (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; GtkAllocation allocation; gtk_widget_get_allocation(GLOBALS->wavearea, &allocation); num_traces_displayable = 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 */ GtkAllocation allocation; gtk_widget_get_allocation(GLOBALS->signalarea, &allocation); num_traces_displayable = 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; GtkAllocation allocation; gtk_widget_get_allocation(GLOBALS->wavearea, &allocation); if ((GLOBALS->traces.total + 1) * GLOBALS->fontheight > allocation.height) GLOBALS->liney_max = 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) (gtk_adjustment_get_value(sadj)); 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-gtk3-3.3.125/src/tcl_support_commands.c0000664000175000017500000003560015047725112020713 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 "gtk23compat.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" /* ** * 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 ; if(name) { int name_len = strlen(name); char *name2 = wave_alloca(name_len+2); memcpy(name2, name, name_len); strcpy(name2 + name_len, "."); rv = force_open_tree_node(name2, 1, NULL); if(rv == SST_NODE_FOUND) { memcpy(name2, name, name_len); strcpy(name2 + name_len, "."); select_tree_node(name2); } } else { rv = SST_NODE_NOT_EXIST; } 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(TraceFlagsType 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 '0': case AN_0: llp.str = "0"; l_elem = llist_new(llp, LL_STR, -1) ; break ; case '1': case AN_1: llp.str = "1"; l_elem = llist_new(llp, LL_STR, -1) ; break ; case 'x': case 'X': case AN_X: llp.str = "x"; l_elem = llist_new(llp, LL_STR, -1) ; break ; case 'z': case 'Z': case AN_Z: llp.str = "z"; l_elem = llist_new(llp, LL_STR, -1) ; break ; case 'h': case 'H': case AN_H: llp.str = "h"; l_elem = llist_new(llp, LL_STR, -1) ; break ; /* added for GHW... */ case 'u': case 'U': case AN_U: llp.str = "u"; l_elem = llist_new(llp, LL_STR, -1) ; break ; case 'w': case 'W': case AN_W: llp.str = "w"; l_elem = llist_new(llp, LL_STR, -1) ; break ; case 'l': case 'L': case AN_L: llp.str = "l"; l_elem = llist_new(llp, LL_STR, -1) ; break ; case '-': case AN_DASH: llp.str = "-"; l_elem = llist_new(llp, LL_STR, -1) ; break ; default: llp.str = "?"; l_elem = llist_new(llp, LL_STR, -1) ; break ; /* ...added for GHW */ } } 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-gtk3-3.3.125/src/print.h0000664000175000017500000000715315047725112015617 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-gtk3-3.3.125/src/tcl_support_commands.h0000664000175000017500000000176615047725112020726 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" 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-gtk3-3.3.125/src/mouseover_sigs.c0000664000175000017500000003722015047725112017525 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2006-2016. * * 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) { TraceFlagsType 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_FFO) != 0) { ch[pos++] = 'f'; } /* [15] */ if((flags & TR_POPCNT) != 0) { ch[pos++] = 'p'; } /* [16] */ if((flags & TR_FPDECSHIFT) != 0) { int ln = sprintf(ch+pos, "s(%d)", t->t_fpdecshift); pos += ln; } /* [17+] */ 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; } /************************************************************************************************/ #if GTK_CHECK_VERSION(3,0,0) static gint draw_event(GtkWidget *widget, cairo_t *cr, gpointer user_data) { (void) widget; (void) user_data; cairo_set_source_surface(cr, GLOBALS->surface_mo_pixmap_mouseover_c_1, 0, 0); cairo_paint (cr); return(FALSE); } #else static gint expose_event(GtkWidget *widget, GdkEventExpose *event) { cairo_t* cr = XXX_gdk_cairo_create (XXX_GDK_DRAWABLE (gtk_widget_get_window(widget)), dummy); gdk_cairo_region (cr, event->region); cairo_clip (cr); cairo_set_source_surface(cr, GLOBALS->surface_mo_pixmap_mouseover_c_1, 0, 0); cairo_paint (cr); cairo_destroy (cr); return(FALSE); } #endif 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; #ifdef GDK_WINDOWING_WAYLAND if(GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default())) { GLOBALS->mo_area_mouseover_c_1=gtk_drawing_area_new(); gtk_widget_show(GLOBALS->mo_area_mouseover_c_1); GLOBALS->mouseover_mouseover_c_1 = gtk_window_new (GTK_WINDOW_POPUP); gtk_window_group_add_window (gtk_window_get_group (GTK_WINDOW(GLOBALS->mainwindow)), GTK_WINDOW (GLOBALS->mouseover_mouseover_c_1)); gtk_window_set_transient_for (GTK_WINDOW (GLOBALS->mouseover_mouseover_c_1), GTK_WINDOW(GLOBALS->mainwindow)); gtk_container_add(GTK_CONTAINER(GLOBALS->mouseover_mouseover_c_1), GLOBALS->mo_area_mouseover_c_1); gtk_widget_realize (GLOBALS->mouseover_mouseover_c_1); gtk_window_set_type_hint (GTK_WINDOW (GLOBALS->mouseover_mouseover_c_1), GDK_WINDOW_TYPE_HINT_POPUP_MENU); gtk_window_move (GTK_WINDOW (GLOBALS->mouseover_mouseover_c_1), x, y); gtk_window_resize (GTK_WINDOW (GLOBALS->mouseover_mouseover_c_1), width, height); gtk_widget_show (GTK_WIDGET (GLOBALS->mouseover_mouseover_c_1)); } else #endif { 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); 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); 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); } GtkAllocation allocation; gtk_widget_get_allocation(GLOBALS->mouseover_mouseover_c_1, &allocation); GLOBALS->surface_mo_pixmap_mouseover_c_1 = cairo_image_surface_create (CAIRO_FORMAT_RGB24, allocation.width, allocation.height); GLOBALS->cr_mo_pixmap_mouseover_c_1 = cairo_create (GLOBALS->surface_mo_pixmap_mouseover_c_1); cairo_set_line_width(GLOBALS->cr_mo_pixmap_mouseover_c_1, 1.0); GLOBALS->rgb_mo_dk_gray_mouseover_c_1 = XXX_alloc_color(0x00cccccc); GLOBALS->rgb_mo_black_mouseover_c_1 = XXX_alloc_color(0x00000000); XXX_gdk_draw_rectangle(GLOBALS->cr_mo_pixmap_mouseover_c_1, GLOBALS->rgb_mo_dk_gray_mouseover_c_1, TRUE, 0,0, GLOBALS->mo_width_mouseover_c_1, GLOBALS->mo_height_mouseover_c_1); XXX_gdk_draw_rectangle(GLOBALS->cr_mo_pixmap_mouseover_c_1, GLOBALS->rgb_mo_dk_gray_mouseover_c_1, TRUE, 1,1, GLOBALS->mo_width_mouseover_c_1-2, GLOBALS->mo_height_mouseover_c_1-2); #if GTK_CHECK_VERSION(3,0,0) g_signal_connect(XXX_GTK_OBJECT(GLOBALS->mo_area_mouseover_c_1), "draw",G_CALLBACK(draw_event), NULL); #else g_signal_connect(XXX_GTK_OBJECT(GLOBALS->mo_area_mouseover_c_1), "expose_event",G_CALLBACK(expose_event), NULL); #endif } #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; if(GLOBALS->cr_mo_pixmap_mouseover_c_1) { cairo_destroy(GLOBALS->cr_mo_pixmap_mouseover_c_1); GLOBALS->cr_mo_pixmap_mouseover_c_1 = NULL; } if(GLOBALS->surface_mo_pixmap_mouseover_c_1) { cairo_surface_destroy(GLOBALS->surface_mo_pixmap_mouseover_c_1); GLOBALS->surface_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; if(GLOBALS->clipboard_mouseover) { GdkDisplay *g = gdk_display_get_default(); GtkClipboard *clip; if(t->name) { clip = gtk_clipboard_get_for_display (g, GDK_SELECTION_PRIMARY); /* middle mouse button */ gtk_clipboard_set_text (clip, t->name, strlen(t->name)); } clip = gtk_clipboard_get_for_display (g, GDK_SELECTION_CLIPBOARD); /* ctrl-c/ctrl-v */ gtk_clipboard_set_text (clip, asciivalue ? asciivalue : "", value_charlen); } 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; if(GLOBALS->cr_mo_pixmap_mouseover_c_1) { cairo_destroy(GLOBALS->cr_mo_pixmap_mouseover_c_1); GLOBALS->cr_mo_pixmap_mouseover_c_1 = NULL; } if(GLOBALS->surface_mo_pixmap_mouseover_c_1) { cairo_surface_destroy(GLOBALS->surface_mo_pixmap_mouseover_c_1); GLOBALS->surface_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; if(GLOBALS->cr_mo_pixmap_mouseover_c_1) { cairo_destroy(GLOBALS->cr_mo_pixmap_mouseover_c_1); GLOBALS->cr_mo_pixmap_mouseover_c_1 = NULL; } if(GLOBALS->surface_mo_pixmap_mouseover_c_1) { cairo_surface_destroy(GLOBALS->surface_mo_pixmap_mouseover_c_1); GLOBALS->surface_mo_pixmap_mouseover_c_1 = NULL; } } goto bot; } if(!GLOBALS->mouseover_mouseover_c_1) { gdk_window_get_origin(gtk_widget_get_window(GLOBALS->signalarea), &xd, &yd); create_mouseover_sigs(xin + xd + 8, yin + yd + 20, totalmax, num_info_rows * fh + 7); } else { gdk_window_get_origin(gtk_widget_get_window(GLOBALS->signalarea), &xd, &yd); gtk_window_move(GTK_WINDOW(GLOBALS->mouseover_mouseover_c_1), xin + xd + 8, yin + yd + 20); } if(!GLOBALS->cr_mo_pixmap_mouseover_c_1) goto bot; /* harden against NULL pointer */ XXX_gdk_draw_rectangle(GLOBALS->cr_mo_pixmap_mouseover_c_1, GLOBALS->rgb_mo_dk_gray_mouseover_c_1, TRUE, 0,0, GLOBALS->mo_width_mouseover_c_1, GLOBALS->mo_height_mouseover_c_1); XXX_gdk_draw_rectangle(GLOBALS->cr_mo_pixmap_mouseover_c_1, GLOBALS->rgb_mo_black_mouseover_c_1, TRUE, 1,1, GLOBALS->mo_width_mouseover_c_1-2, GLOBALS->mo_height_mouseover_c_1-2); XXX_font_engine_draw_string(GLOBALS->cr_mo_pixmap_mouseover_c_1, GLOBALS->wavefont, &GLOBALS->rgb_mo_dk_gray_mouseover_c_1, 4+0.5, fh + 2+0.5, alternate_name ? alternate_name : flagged_name); if(num_info_rows == 2) { if(asciivalue) XXX_font_engine_draw_string(GLOBALS->cr_mo_pixmap_mouseover_c_1, GLOBALS->wavefont, &GLOBALS->rgb_mo_dk_gray_mouseover_c_1, 4+0.5, 2*fh+2+0.5, asciivalue); } else { char breakbuf[MOUSEOVER_BREAKSIZE+1]; int i; num_info_rows--; for(i=0;icr_mo_pixmap_mouseover_c_1, GLOBALS->wavefont, &GLOBALS->rgb_mo_dk_gray_mouseover_c_1, 4+0.5, ((2+i)*fh)+2+0.5, breakbuf); } } gdk_window_raise(gtk_widget_get_window(GLOBALS->mouseover_mouseover_c_1)); #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX GdkDrawingContext *gdc; #endif cairo_t* cr = XXX_gdk_cairo_create (XXX_GDK_DRAWABLE (gtk_widget_get_window(GLOBALS->mo_area_mouseover_c_1)), &gdc); cairo_set_source_surface(cr, GLOBALS->surface_mo_pixmap_mouseover_c_1, 0, 0); cairo_paint (cr); #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX gdk_window_end_draw_frame(gtk_widget_get_window(GLOBALS->mo_area_mouseover_c_1), gdc); #else cairo_destroy (cr); #endif #ifdef GDK_WINDOWING_WAYLAND if(GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default())) gtk_widget_queue_draw(GLOBALS->mo_area_mouseover_c_1); #endif 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-gtk3-3.3.125/src/fsdb_wrapper_api.cc0000664000175000017500000006211615047725112020130 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2013-2017. * * 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 "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: strcpy(bf, "End Tree:"); cb(bf); 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); } /* * Reformat FSDB hierarchy info into FST's format (for use with WAVE_USE_FSDB_FST_BRIDGE) */ static void __DumpScope2(fsdbTreeCBDataScope* scope, void (*cb)(void *)) { unsigned char typ; struct fstHier fh; switch (scope->type) { case FSDB_ST_VCD_MODULE: typ = FST_ST_VCD_MODULE; break; case FSDB_ST_VCD_TASK: typ = FST_ST_VCD_TASK; break; case FSDB_ST_VCD_FUNCTION: typ = FST_ST_VCD_FUNCTION; break; case FSDB_ST_VCD_BEGIN: typ = FST_ST_VCD_BEGIN; break; case FSDB_ST_VCD_FORK: typ = FST_ST_VCD_FORK; break; case FSDB_ST_VCD_GENERATE: typ = FST_ST_VCD_GENERATE; break; case FSDB_ST_SV_INTERFACE: typ = FST_ST_VCD_INTERFACE; break; case FSDB_ST_VHDL_ARCHITECTURE: typ = FST_ST_VHDL_ARCHITECTURE; break; case FSDB_ST_VHDL_PROCEDURE: typ = FST_ST_VHDL_PROCEDURE; break; case FSDB_ST_VHDL_FUNCTION: typ = FST_ST_VHDL_FUNCTION; break; case FSDB_ST_VHDL_RECORD: typ = FST_ST_VHDL_RECORD; break; case FSDB_ST_VHDL_PROCESS: typ = FST_ST_VHDL_PROCESS; break; case FSDB_ST_VHDL_BLOCK: typ = FST_ST_VHDL_BLOCK; break; case FSDB_ST_VHDL_FOR_GENERATE: typ = FST_ST_VHDL_FOR_GENERATE; break; case FSDB_ST_VHDL_IF_GENERATE: typ = FST_ST_VHDL_IF_GENERATE; break; case FSDB_ST_VHDL_GENERATE: typ = FST_ST_VHDL_GENERATE; break; default: typ = FST_ST_VCD_MODULE; break; } fh.htyp = FST_HT_SCOPE; fh.u.scope.typ = typ; fh.u.scope.name = scope->name; fh.u.scope.name_length = strlen(fh.u.scope.name); if(scope->module) { fh.u.scope.component = scope->module; fh.u.scope.component_length = strlen(fh.u.scope.component); } else { fh.u.scope.component = NULL; fh.u.scope.component_length = 0; } cb(&fh); } static void __DumpVar2(fsdbTreeCBDataVar *var, void (*cb)(void *)) { unsigned char typ; unsigned char dir; struct fstHier fh; switch (var->type) { case FSDB_VT_VCD_EVENT: typ = FST_VT_VCD_EVENT; break; case FSDB_VT_VCD_INTEGER: typ = FST_VT_VCD_INTEGER; break; case FSDB_VT_VCD_PARAMETER: typ = FST_VT_VCD_PARAMETER; break; case FSDB_VT_VCD_REAL: typ = FST_VT_VCD_REAL; break; case FSDB_VT_VCD_REG: typ = FST_VT_VCD_REG; break; case FSDB_VT_VCD_SUPPLY0: typ = FST_VT_VCD_SUPPLY0; break; case FSDB_VT_VCD_SUPPLY1: typ = FST_VT_VCD_SUPPLY1; break; case FSDB_VT_VCD_TIME: typ = FST_VT_VCD_TIME; break; case FSDB_VT_VCD_TRI: typ = FST_VT_VCD_TRI; break; case FSDB_VT_VCD_TRIAND: typ = FST_VT_VCD_TRIAND; break; case FSDB_VT_VCD_TRIOR: typ = FST_VT_VCD_TRIOR; break; case FSDB_VT_VCD_TRIREG: typ = FST_VT_VCD_TRIREG; break; case FSDB_VT_VCD_TRI0: typ = FST_VT_VCD_TRI0; break; case FSDB_VT_VCD_TRI1: typ = FST_VT_VCD_TRI1; break; case FSDB_VT_VCD_WAND: typ = FST_VT_VCD_WAND; break; case FSDB_VT_VCD_WIRE: typ = FST_VT_VCD_WIRE; break; case FSDB_VT_VCD_WOR: typ = FST_VT_VCD_WOR; break; case FSDB_VT_VCD_PORT: typ = FST_VT_VCD_PORT; 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: typ = FST_VT_VCD_REAL; 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) { typ = FST_VT_VCD_WIRE; } else { typ = FST_VT_VCD_REG; } break; } break; case FSDB_VT_STREAM: /* these hold transactions: not yet supported */ typ = FST_VT_GEN_STRING; break; default: typ = FST_VT_VCD_WIRE; break; } switch(var->direction) { case FSDB_VD_INPUT: dir = FST_VD_INPUT; break; case FSDB_VD_OUTPUT: dir = FST_VD_OUTPUT; break; case FSDB_VD_INOUT: dir = FST_VD_INOUT; break; case FSDB_VD_BUFFER: dir = FST_VD_BUFFER; break; case FSDB_VD_LINKAGE: dir = FST_VD_LINKAGE; break; case FSDB_VD_IMPLICIT: default: dir = FST_VD_IMPLICIT; break; } fh.htyp = FST_HT_VAR; fh.u.var.typ = typ; fh.u.var.direction = dir; fh.u.var.svt_workspace = 0; fh.u.var.sdt_workspace = 0; fh.u.var.sxt_workspace = 0; fh.u.var.name = var->name; fh.u.var.length = (var->lbitnum > var->rbitnum) ? (var->lbitnum - var->rbitnum + 1) : (var->rbitnum - var->lbitnum + 1); fh.u.var.handle = var->u.idcode; fh.u.var.name_length = strlen(fh.u.var.name); fh.u.var.is_alias = 0; // for now cb(&fh); } static void __DumpStruct2(fsdbTreeCBDataStructBegin* str, void (*cb)(void *)) { struct fstHier fh; fh.htyp = FST_HT_SCOPE; fh.u.scope.typ = FST_ST_VCD_STRUCT; fh.u.scope.name = str->name; fh.u.scope.name_length = strlen(fh.u.scope.name); fh.u.scope.component = NULL; fh.u.scope.component_length = 0; cb(&fh); } static void __DumpArray2(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 __MyTreeCB2(fsdbTreeCBType cb_type, void *client_data, void *tree_cb_data) { void (*cb)(void *) = (void (*)(void *))client_data; struct fstHier fh; char bf[16]; switch (cb_type) { case FSDB_TREE_CBT_BEGIN_TREE: /* fprintf(stderr, "Begin Tree:\n"); */ break; case FSDB_TREE_CBT_SCOPE: __DumpScope2((fsdbTreeCBDataScope*)tree_cb_data, cb); break; case FSDB_TREE_CBT_VAR: __DumpVar2((fsdbTreeCBDataVar*)tree_cb_data, cb); break; case FSDB_TREE_CBT_UPSCOPE: case FSDB_TREE_CBT_STRUCT_END: fh.htyp = FST_HT_UPSCOPE; cb(&fh); break; case FSDB_TREE_CBT_END_TREE: fh.htyp = FST_HT_TREEEND; cb(&fh); break; case FSDB_TREE_CBT_STRUCT_BEGIN: __DumpStruct2((fsdbTreeCBDataStructBegin*)tree_cb_data, cb); break; /* not yet supported */ case FSDB_TREE_CBT_ARRAY_BEGIN: __DumpArray2((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); } extern "C" void fsdbReaderReadScopeVarTree2(void *ctx,void (*cb)(void *)) { ffrObject *fsdb_obj = (ffrObject *)ctx; fsdb_obj->ffrSetTreeCBFunc(__MyTreeCB2, (void *) cb); fsdb_obj->ffrReadScopeVarTree(); } #else static void dummy_compilation_unit(void) { } #endif gtkwave-gtk3-3.3.125/src/baseconvert.c0000664000175000017500000013652015047725112016772 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2017. * * 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 "gtk23compat.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" /* * filters mutually exclusive with file/translate/process filters */ static char *lzremoval(char *s) { char *p = s; if(*p) { while((*p=='0') && *(p+1)) { p++; } } if(p != s) { memmove(s, p, strlen(p) + 1); } return(s); } /* * file/translate/process filters */ static char *dofilter(Trptr t, char *s) { GLOBALS->xl_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 *edofilter(Trptr t, char *s) { if(t->flags & TR_ENUM) { int filt = t->e_filter - 1; #ifdef _WAVE_HAVE_JUDY PPvoid_t pv = JudyHSGet(GLOBALS->xl_enum_filter[filt], s, strlen(s)); if(pv) { free_2(s); s = malloc_2(strlen(*pv) + 1); strcpy(s, *pv); } #else GLOBALS->xl_enum_filter[filt] = xl_splay(s, GLOBALS->xl_enum_filter[filt]); if(!strcasecmp(s, GLOBALS->xl_enum_filter[filt]->item)) { free_2(s); s = malloc_2(strlen(GLOBALS->xl_enum_filter[filt]->trans) + 1); strcpy(s, GLOBALS->xl_enum_filter[filt]->trans); } #endif else { char *zerofind = s; char *dst = s, *src; while(*zerofind == '0') zerofind++; if(zerofind != s) { src = (!*zerofind) ? (zerofind-1) : zerofind; while(*src) { *(dst++) = *(src++); } *dst = 0; } } } 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 __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); } /* * convert binary <=> gray/ffo/popcnt in place */ #define cvt_gray(f,p,n) \ do { \ if((f)&(TR_GRAYMASK|TR_POPCNT|TR_FFO)) \ { \ if((f)&TR_BINGRAY) { convert_bingray((p),(n)); } \ if((f)&TR_GRAYBIN) { convert_graybin((p),(n)); } \ if((f)&TR_FFO) { convert_ffo((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; } } static void convert_ffo(char *pnt, int nbits) { int i; int ffo = -1; for(i=(nbits-1);i>=0;i--) { char ch = pnt[i]; if((ch == AN_1) || (ch == AN_H)) { ffo = (nbits-1) - i; break; } } if(ffo >= 0) { for(i=nbits-1;i>=0;i--) /* always requires less number of bits */ { pnt[i] = (ffo & 1) ? AN_1 : AN_0; ffo >>= 1; } } else { for(i=nbits-1;i>=0;i--) /* always requires less number of bits */ { pnt[i] = AN_X; } } } static void dpr_e16(char *str, double d) { char *buf16; char buf15[24]; int l16; int l15; buf16 = str; buf16[23] = 0; l16 = snprintf(buf16, 24, "%.16g", d); if(l16 >= 18) { buf15[23] = 0; l15 = snprintf(buf15, 24, "%.15g", d); if((l16-l15) > 3) { strcpy(str, buf15); } } } static void cvt_fpsdec(Trptr t, TimeType val, char *os, int len, int nbits) { (void)nbits; /* number of bits shouldn't be relevant here as we're going through a fraction */ int shamt = t->t_fpdecshift; TimeType lpart = val >> shamt; TimeType rmsk = (ULLDescriptor(1) << shamt); TimeType rbit = (val >= 0) ? (val & (rmsk-1)) : ((-val) & (rmsk-1)); double rfrac; int negflag = 0; char dbuf[32]; char bigbuf[64]; if(rmsk) { rfrac = (double)rbit / (double)rmsk; if(shamt) { if(lpart < 0) { if(rbit) { lpart++; if(!lpart) negflag = 1; } } } } else { rfrac = 0.0; } dpr_e16(dbuf, rfrac); /* sprintf(dbuf, "%.16g", rfrac); */ char *dot = strchr(dbuf, '.'); if(dot && (dbuf[0] == '0')) { sprintf(bigbuf, "%s"TTFormat".%s", negflag ? "-" : "", lpart, dot+1); strncpy(os, bigbuf, len); os[len-1] = 0; } else { sprintf(os, "%s"TTFormat, negflag ? "-" : "", lpart); } } static void cvt_fpsudec(Trptr t, TimeType val, char *os, int len) { int shamt = t->t_fpdecshift; UTimeType lpart = ((UTimeType)val) >> shamt; TimeType rmsk = (ULLDescriptor(1) << shamt); TimeType rbit = (val & (rmsk-1)); double rfrac; char dbuf[32]; char bigbuf[64]; if(rmsk) { rfrac = (double)rbit / (double)rmsk; } else { rfrac = 0.0; } dpr_e16(dbuf, rfrac); /* sprintf(dbuf, "%.16g", rfrac); */ char *dot = strchr(dbuf, '.'); if(dot && (dbuf[0] == '0')) { sprintf(bigbuf, UTTFormat".%s", lpart, dot+1); strncpy(os, bigbuf, len); os[len-1] = 0; } else { sprintf(os, UTTFormat, lpart); } } /* * convert trptr+vptr into an ascii string */ static char *convert_ascii_2(Trptr t, vptr v) { TraceFlagsType 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+7)&7)):(newbuff+7); cvt_gray(flags,parse,(flags&TR_RJUSTIFY)?((nbits+7)&~7):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|TR_FFO))))) { 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,(flags&TR_RJUSTIFY)?((nbits+3)&~3):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,(flags&TR_RJUSTIFY)?(((nbits+2)/3)*3):nbits); for(i=0;ishow_base) { *(pnt++)='%'; } parse=newbuff+3; cvt_gray(flags,parse,nbits); for(i=0;it_fpdecshift)) { cvt_fpsdec(t, val, os, len, nbits); } else { if(!(flags&TR_TIME)) { sprintf(os, TTFormat, val); } else { free_2(os); os = calloc_2(1, 128); reformat_time(os, val, GLOBALS->time_dimension); } } } else { strcpy(os, "XXX"); } } else if(flags&TR_REAL) { char *parse; if((nbits==64) || (nbits==32)) { UTimeType utt = LLDescriptor(0); double d; float f; uint32_t utt_32; 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;it_fpdecshift)) { cvt_fpsudec(t, val, os, len); } else { if(!(flags&TR_TIME)) { sprintf(os, UTTFormat, val); } else { free_2(os); os = calloc_2(1, 128); reformat_time(os, val, GLOBALS->time_dimension); } } } else { strcpy(os, "XXX"); } } free_2(newbuff); return(os); } /* * convert trptr+hptr vectorstring into an ascii string */ char *convert_ascii_real(Trptr t, double *d) { char *rv; if(t && (t->flags & 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) { dpr_e16(rv, *d); /* sprintf(rv,"%.16g",*d); */ } else { strcpy(rv,"UNDEF"); } } if(t) { if(!(t->f_filter|t->p_filter|t->e_filter)) { if(GLOBALS->lz_removal) lzremoval(rv); } else { if(t->e_filter) { rv = edofilter(t, rv); } else if(t->f_filter) { rv = dofilter(t, rv); } else { rv = pdofilter(t, rv); } } } 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); } static const unsigned char cvt_table[] = { 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 /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* */, AN_DASH /* ! */, AN_DASH /* " */, AN_DASH /* # */, AN_DASH /* $ */, AN_DASH /* % */, AN_DASH /* & */, AN_DASH /* ' */, AN_DASH /* ( */, AN_DASH /* ) */, AN_DASH /* * */, AN_DASH /* + */, AN_DASH /* , */, AN_DASH /* - */, AN_DASH /* . */, AN_DASH /* / */, AN_0 /* 0 */, AN_1 /* 1 */, AN_DASH /* 2 */, AN_DASH /* 3 */, AN_DASH /* 4 */, AN_DASH /* 5 */, AN_DASH /* 6 */, AN_DASH /* 7 */, AN_DASH /* 8 */, AN_DASH /* 9 */, AN_DASH /* : */, AN_DASH /* ; */, AN_DASH /* < */, AN_DASH /* = */, AN_DASH /* > */, AN_DASH /* ? */, AN_DASH /* @ */, AN_DASH /* A */, AN_DASH /* B */, AN_DASH /* C */, AN_DASH /* D */, AN_DASH /* E */, AN_DASH /* F */, AN_DASH /* G */, AN_H /* H */, AN_DASH /* I */, AN_DASH /* J */, AN_DASH /* K */, AN_L /* L */, AN_DASH /* M */, AN_DASH /* N */, AN_DASH /* O */, AN_DASH /* P */, AN_DASH /* Q */, AN_DASH /* R */, AN_DASH /* S */, AN_DASH /* T */, AN_U /* U */, AN_DASH /* V */, AN_W /* W */, AN_X /* X */, AN_DASH /* Y */, AN_Z /* Z */, AN_DASH /* [ */, AN_DASH /* \ */, AN_DASH /* ] */, AN_DASH /* ^ */, AN_DASH /* _ */, AN_DASH /* ` */, AN_DASH /* a */, AN_DASH /* b */, AN_DASH /* c */, AN_DASH /* d */, AN_DASH /* e */, AN_DASH /* f */, AN_DASH /* g */, AN_H /* h */, AN_DASH /* i */, AN_DASH /* j */, AN_DASH /* k */, AN_L /* l */, AN_DASH /* m */, AN_DASH /* n */, AN_DASH /* o */, AN_DASH /* p */, AN_DASH /* q */, AN_DASH /* r */, AN_DASH /* s */, AN_DASH /* t */, AN_U /* u */, AN_DASH /* v */, AN_W /* w */, AN_X /* x */, AN_DASH /* y */, AN_Z /* z */, AN_DASH /* { */, AN_DASH /* | */, AN_DASH /* } */, AN_DASH /* ~ */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */, AN_DASH /* . */ }; int vtype(Trptr t, char *vec) { int i, nbits; char pch, ch; if (vec == NULL) return(AN_X); nbits=t->n.nd->msi-t->n.nd->lsi; if(nbits<0)nbits=-nbits; nbits++; pch = ch = cvt_table[(unsigned char)vec[0]]; for (i = 1; i < nbits; i++) { ch = cvt_table[(unsigned char)vec[i]]; if(ch != pch) goto miscompare; } return(ch); miscompare: if((pch == AN_X) || (pch == AN_U)) return(pch); if(pch == AN_Z) return(AN_X); for (; i < nbits; i++) { ch = cvt_table[(unsigned char)vec[i]]; if((ch == AN_X) || (ch == AN_U)) return(ch); if(ch == AN_Z) return(AN_X); } return(AN_COUNT); } int vtype2(Trptr t, vptr v) { int i, nbits; char pch, ch; 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_COUNT ); } nbits=t->n.vec->nbits; pch = ch = cvt_table[(unsigned char)vec[0]]; for (i = 1; i < nbits; i++) { ch = cvt_table[(unsigned char)vec[i]]; if(ch != pch) goto miscompare; } return(ch); miscompare: if((pch == AN_X) || (pch == AN_U)) return(pch); if(pch == AN_Z) return(AN_X); for (; i < nbits; i++) { ch = cvt_table[(unsigned char)vec[i]]; if((ch == AN_X) || (ch == AN_U)) return(ch); if(ch == AN_Z) return(AN_X); } return(AN_COUNT); } /* * convert trptr+hptr vectorstring into an ascii string */ char *convert_ascii_vec_2(Trptr t, char *vec) { TraceFlagsType 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+7)&7)):(newbuff+7); cvt_gray(flags,parse,(flags&TR_RJUSTIFY)?((nbits+7)&~7):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|TR_FFO))))) { 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,(flags&TR_RJUSTIFY)?((nbits+3)&~3):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,(flags&TR_RJUSTIFY)?(((nbits+2)/3)*3):nbits); for(i=0;ishow_base) { *(pnt++)='%'; } parse=newbuff+3; cvt_gray(flags,parse,nbits); for(i=0;it_fpdecshift)) { cvt_fpsdec(t, val, os, len, nbits); } else { if(!(flags&TR_TIME)) { sprintf(os, TTFormat, val); } else { free_2(os); os = calloc_2(1, 128); reformat_time(os, val, GLOBALS->time_dimension); } } } else { strcpy(os, "XXX"); } } else if(flags&TR_REAL) { char *parse; if((nbits==64) || (nbits == 32)) { UTimeType utt = LLDescriptor(0); double d; float f; uint32_t utt_32; 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;it_fpdecshift)) { cvt_fpsudec(t, val, os, len); } else { if(!(flags&TR_TIME)) { sprintf(os, UTTFormat, val); } else { free_2(os); os = calloc_2(1, 128); reformat_time(os, val, GLOBALS->time_dimension); } } } else { strcpy(os, "XXX"); } } free_2(newbuff); return(os); } char *convert_ascii_vec(Trptr t, char *vec) { char *s = convert_ascii_vec_2(t, vec); if(!(t->f_filter|t->p_filter|t->e_filter)) { if(GLOBALS->lz_removal) lzremoval(s); } else { if(t->e_filter) { s = edofilter(t, s); } 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) && (!(v->flags & HIST_STRING))) { 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|t->e_filter)) { if(GLOBALS->lz_removal) lzremoval(s); } else { if(t->e_filter) { s = edofilter(t, s); } 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 "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 /****************************************************************************/ /* * report abort messages */ static void chk_report_abort(const char *s) { fprintf(stderr,"Triggered %s security check, exiting.\n", s); abort(); } /* * 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; if(len >= sizeof(s)) { chk_report_abort("TALOS-2023-1827"); } 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: if(!lt->len[idx]) { chk_report_abort("TALOS-2023-1824"); } 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: if(!lt->len[idx]) { chk_report_abort("TALOS-2023-1824"); } 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) { { size_t chk_x = b->num_dict_entries * sizeof(char *); if((chk_x / sizeof(char *)) != b->num_dict_entries) { chk_report_abort("TALOS-2023-1820"); } } b->string_pointers = malloc(b->num_dict_entries * sizeof(char *)); { size_t chk_x = b->num_dict_entries * sizeof(unsigned int); if((chk_x / sizeof(unsigned int)) != b->num_dict_entries) { chk_report_abort("TALOS-2023-1820"); } } 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); if(lt->num_time_table_entries > LXT2_RD_GRANULE_SIZE) { chk_report_abort("TALOS-2023-1819"); } 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); { size_t chk_x = lt->numfacs * 4 * sizeof(lxtint32_t); if((chk_x / (4 * sizeof(lxtint32_t))) != lt->numfacs) { chk_report_abort("TALOS-2023-1818"); } } 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; { size_t chk_x = lt->numfacs * sizeof(lxtint32_t); if((chk_x / sizeof(lxtint32_t)) != lt->numfacs) { chk_report_abort("TALOS-2023-1818"); } } 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)); { size_t chk_x = lt->numfacs * sizeof(char *); if((chk_x / sizeof(char *)) != lt->numfacs) { chk_report_abort("TALOS-2023-1818"); } } 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; } if(sizeof(size_t) < sizeof(uint64_t)) { /* TALOS-2023-1821 for 32b overflow */ uint64_t chk_64 = lt->len[i] + 1; size_t chk_32 = lt->len[i] + 1; if(chk_64 != chk_32) chk_report_abort("TALOS-2023-1821"); } 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; if(clone > lt->longestname) { chk_report_abort("TALOS-2023-1826"); } for(j=0;jfaccache->bufprev[j]; } do { if((pnt - lt->faccache->bufcurr) > lt->longestname) { chk_report_abort("TALOS-2023-1826"); } } 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; if(unclen > b->uncompressed_siz) { chk_report_abort("TALOS-2023-1823"); /* could fix this up with a realloc(), but abort to indicate the file is malformed */ } fspos += 12; if((iter==0xFFFFFFFF)||(lt->process_mask_compressed[iter/LXT2_RD_PARTIAL_SIZE])) { if(clen > zlen) { if(zbuff) free(zbuff); zlen = clen * 2; if(zlen < clen) { chk_report_abort("TALOS-2023-1822"); } 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-gtk3-3.3.125/src/helpers/lxt2miner.c0000664000175000017500000001662515047725113020051 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-gtk3-3.3.125/src/helpers/vcd2lxt.c0000664000175000017500000013007515047725113017507 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 int mti_realparam_fix=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; /******************************************************************/ /* * report abort messages */ static void chk_report_abort(const char *s) { fprintf(stderr,"Triggered %s security check, exiting.\n", s); abort(); } /******************************************************************/ static FILE *popen_san(const char *command, const char *type) /* TALOS-2023-1786 */ { const char *p = command; int is_ok = 1; char ch; while(p && (ch = *(p++))) { switch(ch) { case '&': case '|': case ';': case '\n': case '`': case '$': is_ok = 0; default: break; } } if(is_ok) { return(popen(command, type)); } else { fprintf(stderr, "GTKWAVE | TALOS-2023-1786: popen() command string '%s' may not be properly sanitized, blocking command.\n", command); return(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]); } return(NULL); /* TALOS-2023-1807 */ } 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) { if(!varsplit) { yytext=(char *)realloc_2(yytext, (T_MAX_STR=T_MAX_STR*2)+1); } else /* TALOS-2023-1806 */ { int vsplit_len = varsplit - yytext; /* save old len */ yytext=(char *)realloc_2(yytext, (T_MAX_STR=T_MAX_STR*2)+1); varsplit = yytext+vsplit_len; /* reconstruct old len in new buffer */ } } 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_cache<=v->size) /* TALOS-2023-1804 */ { 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; if(header_over) { chk_report_abort("TALOS-2023-1805: $var after $enddefinitions"); } 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) { if(mti_realparam_fix) { v->vartype = V_REAL; /* MTI fix */ } else { int vlen = v->msi - v->lsi; if(vlen<0) vlen = -vlen; vlen++; v->size = vlen; } } 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_san(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 "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; int dumpvars_state = 0; 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 = LXT2_RD_ULLDESC(~0); char vcd_blackout = 0; static int backtrack_warning = 0; 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) { if((vcd_prevtime > *pnt_time) && (!backtrack_warning) && (vcd_prevtime != LXT2_RD_ULLDESC(~0))) { backtrack_warning = 1; fprintf(stderr, "LXTLOAD | Time backtracking encountered: this VCD might load incorrectly in gtkwave.\n"); } vcd_prevtime = *pnt_time; if(dumpvars_state == 1) { fprintf(fv, "$end\n"); dumpvars_state = 2; } fprintf(fv, "#"LXT2_RD_LLD"\n", *pnt_time); if(!dumpvars_state) { fprintf(fv, "$dumpvars\n"); dumpvars_state = 1; } } 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; /* fallthrough */ case -3: time_dimension = 'm'; break; case -4: time_scale = 100; time_dimension = 'u'; break; case -5: time_scale = 10; /* fallthrough */ case -6: time_dimension = 'u'; break; case -10: time_scale = 100; time_dimension = 'p'; break; case -11: time_scale = 10; /* fallthrough */ case -12: time_dimension = 'p'; break; case -13: time_scale = 100; time_dimension = 'f'; break; case -14: time_scale = 10; /* fallthrough */ case -15: time_dimension = 'f'; break; case -7: time_scale = 100; time_dimension = 'n'; break; case -8: time_scale = 10; /* fallthrough */ 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"); 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)) { if(dumpvars_state == 1) { fprintf(fv, "$end\n"); dumpvars_state = 2; } 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-gtk3-3.3.125/src/helpers/v2l_analyzer_lxt2.h0000664000175000017500000000717115047725113021507 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-gtk3-3.3.125/src/helpers/fstminer.c0000664000175000017500000002376315047725113017755 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; intptr_t snum = 0; intptr_t 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 ? (intptr_t)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 const char *strnstr_2(const char *haystack, const char *needle, size_t haystack_len) /* exists in BSDs, but not in linux */ { if(needle && haystack) /* overkill for this usage, but to avoid tripping static checkers */ { size_t needle_len = strlen(needle); if(!needle_len) /* trivial case is match against null string */ { return(haystack); } while(haystack_len >= needle_len) /* otherwise, impossible to match */ { if(!memcmp(haystack, needle, needle_len)) { return(haystack); } haystack++; haystack_len--; } } return(NULL); } 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 */ && (strnstr_2((const char *)pnt_value, match, plen)))) /* #423: changed strstr to strnstr_2 */ { char *fn; fn = get_facname(lt, pnt_facidx); if(!names_only) { char *s = malloc(plen+1); /* #423: fstminer doesn't handle string transitions correctly */ memcpy(s, pnt_value, plen); s[plen] = 0; /* strings are not null terminated */ printf("#%"PRIu64" %s %s\n", pnt_time, fn, s); free(s); } 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-gtk3-3.3.125/src/helpers/Makefile.am0000664000175000017500000000456415047725113020014 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) $(RPC_CFLAGS) -I$(srcdir)/fst -I$(srcdir)/../../contrib/rtlbrowse bin_PROGRAMS= evcd2vcd fst2vcd vcd2fst fstminer 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) $(RPC_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) $(RPC_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) $(RPC_LDADD) lxt2miner_SOURCES= lxt2miner.c lxt2_read.c lxt2_read.h lxt2miner_LDADD= $(LIBZ_LDADD) evcd2vcd_SOURCES= evcd2vcd.c $(srcdir)/../../contrib/rtlbrowse/jrb.h $(srcdir)/../../contrib/rtlbrowse/jrb.c gtkwave-gtk3-3.3.125/src/helpers/lxt2_read.h0000664000175000017500000002124715047725113020012 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-gtk3-3.3.125/src/helpers/shmidcat.c0000664000175000017500000001550615047725113017716 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-gtk3-3.3.125/src/helpers/evcd2vcd.c0000664000175000017500000002515615047725113017624 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 /* * report abort messages */ static void chk_report_abort(const char *s) { fprintf(stderr,"Triggered %s security check, exiting.\n", s); abort(); } 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; if((len < 0) || (len > 32768)) { chk_report_abort("TALOS-2023-1803"); } 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-gtk3-3.3.125/src/helpers/Makefile.in0000664000175000017500000011050515047725113020016 0ustar bybellbybell# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : bin_PROGRAMS = evcd2vcd$(EXEEXT) fst2vcd$(EXEEXT) vcd2fst$(EXEEXT) \ fstminer$(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_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__DEPENDENCIES_1) 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__DEPENDENCIES_1) 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__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 = SOURCES = $(evcd2vcd_SOURCES) $(fst2vcd_SOURCES) $(fstminer_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) $(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@ GLIB_COMPILE_SCHEMAS = @GLIB_COMPILE_SCHEMAS@ GPERF = @GPERF@ GREP = @GREP@ GSETTINGS_CFLAGS = @GSETTINGS_CFLAGS@ GSETTINGS_DISABLE_SCHEMAS_COMPILE = @GSETTINGS_DISABLE_SCHEMAS_COMPILE@ GTK_CFLAGS = @GTK_CFLAGS@ 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_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_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@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ RANLIB = @RANLIB@ RPC_CFLAGS = @RPC_CFLAGS@ RPC_LDADD = @RPC_LDADD@ 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@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ 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@ gsettingsschemadir = @gsettingsschemadir@ 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) $(RPC_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) $(RPC_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) $(RPC_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) $(RPC_LDADD) lxt2miner_SOURCES = lxt2miner.c lxt2_read.c lxt2_read.h lxt2miner_LDADD = $(LIBZ_LDADD) 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) 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)/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` 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-gtk3-3.3.125/src/helpers/vcd2vzt.c0000664000175000017500000013515115047725113017523 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 int mti_realparam_fix=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; /******************************************************************/ /* * report abort messages */ static void chk_report_abort(const char *s) { fprintf(stderr,"Triggered %s security check, exiting.\n", s); abort(); } /******************************************************************/ static FILE *popen_san(const char *command, const char *type) /* TALOS-2023-1786 */ { const char *p = command; int is_ok = 1; char ch; while(p && (ch = *(p++))) { switch(ch) { case '&': case '|': case ';': case '\n': case '`': case '$': is_ok = 0; default: break; } } if(is_ok) { return(popen(command, type)); } else { fprintf(stderr, "GTKWAVE | TALOS-2023-1786: popen() command string '%s' may not be properly sanitized, blocking command.\n", command); return(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]); } return(NULL); /* TALOS-2023-1807 */ } 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) { if(!varsplit) { yytext=(char *)realloc_2(yytext, (T_MAX_STR=T_MAX_STR*2)+1); } else /* TALOS-2023-1806 */ { int vsplit_len = varsplit - yytext; /* save old len */ yytext=(char *)realloc_2(yytext, (T_MAX_STR=T_MAX_STR*2)+1); varsplit = yytext+vsplit_len; /* reconstruct old len in new buffer */ } } 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_cache<=v->size) /* TALOS-2023-1804 */ { 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; if(header_over) { chk_report_abort("TALOS-2023-1805: $var after $enddefinitions"); } 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) { if(mti_realparam_fix) { v->vartype = V_REAL; /* MTI fix */ } else { int vlen = v->msi - v->lsi; if(vlen<0) vlen = -vlen; vlen++; v->size = vlen; } } 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_san(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-gtk3-3.3.125/src/helpers/vzt2vcd.c0000664000175000017500000002761315047725113017526 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; int dumpvars_state = 0; 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; if(dumpvars_state == 1) { fprintf(fv, "$end\n"); dumpvars_state = 2; } fprintf(fv, "#"VZT_RD_LLD"\n", *pnt_time); if(!dumpvars_state) { fprintf(fv, "$dumpvars\n"); dumpvars_state = 1; } } 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; /* fallthrough */ case -3: time_dimension = 'm'; break; case -4: time_scale = 100; time_dimension = 'u'; break; case -5: time_scale = 10; /* fallthrough */ case -6: time_dimension = 'u'; break; case -10: time_scale = 100; time_dimension = 'p'; break; case -11: time_scale = 10; /* fallthrough */ case -12: time_dimension = 'p'; break; case -13: time_scale = 100; time_dimension = 'f'; break; case -14: time_scale = 10; /* fallthrough */ case -15: time_dimension = 'f'; break; case -7: time_scale = 100; time_dimension = 'n'; break; case -8: time_scale = 10; /* fallthrough */ 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"); 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)) { if(dumpvars_state == 1) { fprintf(fv, "$end\n"); dumpvars_state = 2; } 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-gtk3-3.3.125/src/helpers/lxt2_write.c0000664000175000017500000013455115047725113020227 0ustar bybellbybell/* * Copyright (c) 2003-2016 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 = (struct lxt2_wr_symbol**)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 = (char*)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 = (char*)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_%03u.lxt", lt->lxtname, ++lt->break_number); } else { memcpy(tname, lt->lxtname, i); sprintf(tname+i, "_%03u.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 = (char*)wave_alloca(s->len+1); strcpy(vfix, value); value = vfix; } else { vfix = (char*)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 = (char*)calloc(1, 1*sizeof(char)); } } } s=s->symchain; } s = lt->symchain; while(s) { if((!(s->flags&LXT2_WR_SYM_F_ALIAS))&&(s->rows<2)) { char tmp[16]; /* To get rid of the warning */ if(!(s->flags&(LXT2_WR_SYM_F_DOUBLE|LXT2_WR_SYM_F_STRING))) { strcpy(tmp, "x"); lxt2_wr_emit_value_bit_string(lt, s, 0, tmp); } 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) { strcpy(tmp, "UNDEF"); lxt2_wr_emit_value_string(lt, s, 0, tmp); } } 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-gtk3-3.3.125/src/helpers/vcd2lxt2.c0000664000175000017500000013442415047725113017573 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 int mti_realparam_fix=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; /******************************************************************/ /* * report abort messages */ static void chk_report_abort(const char *s) { fprintf(stderr,"Triggered %s security check, exiting.\n", s); abort(); } /******************************************************************/ static FILE *popen_san(const char *command, const char *type) /* TALOS-2023-1786 */ { const char *p = command; int is_ok = 1; char ch; while(p && (ch = *(p++))) { switch(ch) { case '&': case '|': case ';': case '\n': case '`': case '$': is_ok = 0; default: break; } } if(is_ok) { return(popen(command, type)); } else { fprintf(stderr, "GTKWAVE | TALOS-2023-1786: popen() command string '%s' may not be properly sanitized, blocking command.\n", command); return(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]); } return(NULL); /* TALOS-2023-1807 */ } 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) { if(!varsplit) { yytext=(char *)realloc_2(yytext, (T_MAX_STR=T_MAX_STR*2)+1); } else /* TALOS-2023-1806 */ { int vsplit_len = varsplit - yytext; /* save old len */ yytext=(char *)realloc_2(yytext, (T_MAX_STR=T_MAX_STR*2)+1); varsplit = yytext+vsplit_len; /* reconstruct old len in new buffer */ } } 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_cache<=v->size) /* TALOS-2023-1804 */ { 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; if(header_over) { chk_report_abort("TALOS-2023-1805: $var after $enddefinitions"); } 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) { if(mti_realparam_fix) { v->vartype = V_REAL; /* MTI fix */ } else { int vlen = v->msi - v->lsi; if(vlen<0) vlen = -vlen; vlen++; v->size = vlen; } } 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_san(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-gtk3-3.3.125/src/helpers/lxt2_write.h0000664000175000017500000002321415047725113020225 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 "wavealloca.h" #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-gtk3-3.3.125/src/helpers/vcd2fst.c0000664000175000017500000011571715047725113017502 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 int mti_realparam_fix = 0; 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); } /******************************************************/ static FILE *popen_san(const char *command, const char *type, int fsdb_suffix_security_override) /* TALOS-2023-1786 */ { const char *p = command; int is_ok = 1; char ch; int len = command ? strlen(command) : 0; const char *mp = NULL; if(fsdb_suffix_security_override && (len > 5) && !strcmp(" 2>&1", p+len-5)) { mp = p+len-5; } while(p && (ch = *(p++))) { if(p == mp) break; /* ensure fsdb filters can run */ switch(ch) { case '&': case '|': case ';': case '\n': case '`': case '$': is_ok = 0; default: break; } } if(is_ok) { return(popen(command, type)); } else { fprintf(stderr, "GTKWAVE | TALOS-2023-1786: popen() command string '%s' may not be properly sanitized, blocking command.\n", command); return(NULL); } } /******************************************************/ /*********************************************************/ /*** 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_san(sbuff, "r", 1); 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_san(sbuff, "r", 1); 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; JRB zerolen_ids = NULL; /* github #446 */ 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) || suffix_check(vname, "."EXTLOAD_SUFFIX".gz") || suffix_check(vname, "."EXTLOAD_SUFFIX".bz2")) { sprintf(bin_fixbuff, EXTCONV_PATH" %s", vname); f = popen_san(bin_fixbuff, "r", 0); 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_san(bin_fixbuff, "r", 0); is_popen = 1; } else #endif #ifdef VCD2FST_EXT3LOAD_CONV if(suffix_check(vname, "."EXT3LOAD_SUFFIX)) { sprintf(bin_fixbuff, EXT3CONV_PATH" %s", vname); f = popen_san(bin_fixbuff, "r", 0); 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(); zerolen_ids = make_jrb(); /* github #446 */ 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 zerolen = 0; 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; if((mti_realparam_fix) && (vartype == FST_VT_VCD_PARAMETER)) { vartype = FST_VT_VCD_REAL_PARAMETER; } else { zerolen = (vartype != FST_VT_VCD_REAL) && (vartype != FST_VT_VCD_REAL_PARAMETER) && (vartype != FST_VT_VCD_REALTIME) && (vartype != FST_VT_SV_SHORTREAL); } } 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(zerolen) /* github #446 */ { node = jrb_find_int(zerolen_ids, hash); if(!node) { /* fprintf(stderr, "VCD2FST | Name '%s'\n", nam); */ Jval val; val.i = vartype; jrb_insert_int(zerolen_ids, hash, val)->val2.i = 0; } } #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; } else if(tv == 1000) /* nonstandard */ { exp+=3; } 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) { if(strstr(pnt, "Questa") || strstr(pnt, "ModelSim")) /* realparam fix only is for MTI, conflicts with Vivado */ { mti_realparam_fix = 1; } 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 */ } if(jrb_empty(zerolen_ids)) /* github #446 */ { jrb_free_tree(zerolen_ids); zerolen_ids = NULL; } 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(zerolen_ids) /* github #446 */ { node = jrb_find_int(zerolen_ids, hash); if(node) { char *hash_str = strndup(sp+1, nl - (sp+1)); fprintf(stderr, "VCD2FST | Warning: write of real value change to nonreal VCD ID %s suppressed.\n", hash_str); /* github #446, Vivado emitting both boolean and real ambiguously to a zero length parameter */ free(hash_str); break; } } 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; } if(zerolen_ids) /* github #446 */ { jrb_free_tree(zerolen_ids); zerolen_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-gtk3-3.3.125/src/helpers/fst2vcd.c0000664000175000017500000001163715047725113017476 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-gtk3-3.3.125/src/helpers/vzt_read.c0000664000175000017500000015753615047725113017752 0ustar bybellbybell/* * Copyright (c) 2003-2016 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 /****************************************************************************/ /* * report abort messages */ static void chk_report_abort(const char *s) { fprintf(stderr,"Triggered %s security check, exiting.\n", s); abort(); } /****************************************************************************/ 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) { char *c; char *beg; vztint32_t val; char **mm = mmx; c = *mm; beg = c; if(!(*c & 0x80)) { while(!(*c & 0x80)) 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) { char *c; char *beg; vztint64_t val; char **mm = mmx; c = *mm; beg = c; if(!(*c & 0x80)) { while(!(*c & 0x80)) 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; { size_t chk_x = num_time_ticks * sizeof(vztint64_t); if((chk_x / sizeof(vztint64_t)) != num_time_ticks) { chk_report_abort("TALOS-2023-1814"); } } 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; { size_t chk_x = num_time_ticks * sizeof(vztint64_t); if((chk_x / sizeof(vztint64_t)) != num_time_ticks) { chk_report_abort("TALOS-2023-1814"); } } 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; if(num_sections && num_dict_entries) { size_t chk_x = (num_sections * num_dict_entries); size_t chk_y = chk_x * sizeof(vztint32_t); if((chk_x/num_sections) != num_dict_entries) { chk_report_abort("TALOS-2023-1815"); } if((chk_y/sizeof(vztint32_t)) != chk_x) { chk_report_abort("TALOS-2023-1815"); } } 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); } } if(num_sections && num_dict_entries) { size_t chk_x = (num_sections * num_dict_entries); size_t chk_y = chk_x * sizeof(vztint32_t); if((chk_x/num_sections) != num_dict_entries) { chk_report_abort("TALOS-2023-1815"); } if((chk_y/sizeof(vztint32_t)) != chk_x) { chk_report_abort("TALOS-2023-1815"); } } 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 ? lt->numrealfacs : 1, sizeof(struct vzt_ncycle_autosort)); /* fix for scan-build on lt->numrealfacs */ 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) { if(i2 < b->num_time_ticks) { struct vzt_ncycle_autosort *t = autosort[i2]; autofacs[idx].next = t; autosort[i2] = autofacs+idx; } else { chk_report_abort("TALOS-2023-1817"); } } 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) { if(i2 < b->num_time_ticks) { struct vzt_ncycle_autosort *ta = autosort[i2]; autofacs[idx].next = ta; autosort[i2] = autofacs+idx; } else { chk_report_abort("TALOS-2023-1817"); } } 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; if(clonecnt > lt->longestname) { chk_report_abort("TALOS-2023-1813"); } for(j=0;jfaccache->bufprev[j]; } char *bufcurr_exceeded = lt->faccache->bufcurr + (lt->longestname+1); do { if(bufcurr_exceeded == pnt) { chk_report_abort("TALOS-2023-1813"); } } 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; { size_t chk_x = lt->numfacs * sizeof(vztint32_t); if((chk_x / sizeof(vztint32_t)) != lt->numfacs) { chk_report_abort("TALOS-2023-1812"); } } 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]; } } if(sizeof(size_t) < sizeof(uint64_t)) { if(lt->longest_len == 0xffffffff) { chk_report_abort("TALOS-2023-1816"); } } 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-gtk3-3.3.125/src/helpers/vztminer.c0000664000175000017500000001656515047725113020006 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-gtk3-3.3.125/src/helpers/lxt_write.c0000664000175000017500000016320615047725113020144 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-gtk3-3.3.125/src/helpers/v2l_debug_lxt2.c0000664000175000017500000000733415047725113020744 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-gtk3-3.3.125/src/helpers/vzt_read.h0000664000175000017500000002275015047725113017744 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-gtk3-3.3.125/src/helpers/lxt_write.h0000664000175000017500000002014415047725113020142 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-gtk3-3.3.125/src/helpers/v2l_debug_lxt2.h0000664000175000017500000000462515047725113020751 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-gtk3-3.3.125/src/helpers/vzt_write.c0000664000175000017500000012217415047725113020157 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++) { if (s->chgx[i] != 0) { lt->use_multi_state = 1; } 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; if (s->chgx[i] != 0) { lt->use_multi_state = 1; } 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 = (~0U << 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 = (~0U << 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 = (~0U << 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 = (~0U << lt->timepos); msk_n = ~msk; if(!lt->emitted) { vzt_wr_emitfacs(lt); lt->emitted = 1; if(!lt->timeset) { vzt_wr_set_time(lt, 0); } } 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-gtk3-3.3.125/src/helpers/vzt_write.h0000664000175000017500000002362515047725113020165 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-gtk3-3.3.125/src/helpers/v2l_debug.c0000664000175000017500000000732715047725113017775 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-gtk3-3.3.125/src/helpers/fst/0000775000175000017500000000000015047725113016543 5ustar bybellbybellgtkwave-gtk3-3.3.125/src/helpers/fst/lz4.h0000664000175000017500000012767115047725113017443 0ustar bybellbybell/* * LZ4 - Fast LZ compression algorithm * Header File * Copyright (C) 2011-2023, 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 homepage : http://www.lz4.org - LZ4 source repository : https://github.com/lz4/lz4 */ #if defined (__cplusplus) extern "C" { #endif #ifndef LZ4_H_2983827168210 #define LZ4_H_2983827168210 /* --- Dependency --- */ #include /* size_t */ /** Introduction LZ4 is lossless compression algorithm, providing compression speed >500 MB/s per core, scalable with multi-cores CPU. It features an extremely fast decoder, with speed in multiple GB/s per core, typically reaching RAM speed limits on multi-core systems. The LZ4 compression library provides in-memory compression and decompression functions. It gives full buffer control to user. Compression can be done in: - a single step (described as Simple Functions) - a single step, reusing a context (described in Advanced Functions) - unbounded multiple steps (described as Streaming compression) lz4.h generates and decodes LZ4-compressed blocks (doc/lz4_Block_format.md). Decompressing such a compressed block requires additional metadata. Exact metadata depends on exact decompression function. For the typical case of LZ4_decompress_safe(), metadata includes block's compressed size, and maximum bound of decompressed size. Each application is free to encode and pass such metadata in whichever way it wants. lz4.h only handle blocks, it can not generate Frames. Blocks are different from Frames (doc/lz4_Frame_format.md). Frames bundle both blocks and metadata in a specified manner. Embedding metadata is required for compressed data to be self-contained and portable. Frame format is delivered through a companion API, declared in lz4frame.h. The `lz4` CLI can only manage frames. */ /*^*************************************************************** * Export parameters *****************************************************************/ /* * LZ4_DLL_EXPORT : * Enable exporting of functions when building a Windows DLL * LZ4LIB_VISIBILITY : * Control library symbols visibility. */ #ifndef LZ4LIB_VISIBILITY # if defined(__GNUC__) && (__GNUC__ >= 4) # define LZ4LIB_VISIBILITY __attribute__ ((visibility ("default"))) # else # define LZ4LIB_VISIBILITY # endif #endif #if defined(LZ4_DLL_EXPORT) && (LZ4_DLL_EXPORT==1) # define LZ4LIB_API __declspec(dllexport) LZ4LIB_VISIBILITY #elif defined(LZ4_DLL_IMPORT) && (LZ4_DLL_IMPORT==1) # define LZ4LIB_API __declspec(dllimport) LZ4LIB_VISIBILITY /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/ #else # define LZ4LIB_API LZ4LIB_VISIBILITY #endif /*! LZ4_FREESTANDING : * When this macro is set to 1, it enables "freestanding mode" that is * suitable for typical freestanding environment which doesn't support * standard C library. * * - LZ4_FREESTANDING is a compile-time switch. * - It requires the following macros to be defined: * LZ4_memcpy, LZ4_memmove, LZ4_memset. * - It only enables LZ4/HC functions which don't use heap. * All LZ4F_* functions are not supported. * - See tests/freestanding.c to check its basic setup. */ #if defined(LZ4_FREESTANDING) && (LZ4_FREESTANDING == 1) # define LZ4_HEAPMODE 0 # define LZ4HC_HEAPMODE 0 # define LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION 1 # if !defined(LZ4_memcpy) # error "LZ4_FREESTANDING requires macro 'LZ4_memcpy'." # endif # if !defined(LZ4_memset) # error "LZ4_FREESTANDING requires macro 'LZ4_memset'." # endif # if !defined(LZ4_memmove) # error "LZ4_FREESTANDING requires macro 'LZ4_memmove'." # endif #elif ! defined(LZ4_FREESTANDING) # define LZ4_FREESTANDING 0 #endif /*------ Version ------*/ #define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */ #define LZ4_VERSION_MINOR 9 /* for new (non-breaking) interface capabilities */ #define LZ4_VERSION_RELEASE 5 /* for tweaks, bug-fixes, or development */ #define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE) #define LZ4_LIB_VERSION LZ4_VERSION_MAJOR.LZ4_VERSION_MINOR.LZ4_VERSION_RELEASE #define LZ4_QUOTE(str) #str #define LZ4_EXPAND_AND_QUOTE(str) LZ4_QUOTE(str) #define LZ4_VERSION_STRING LZ4_EXPAND_AND_QUOTE(LZ4_LIB_VERSION) /* requires v1.7.3+ */ LZ4LIB_API int LZ4_versionNumber (void); /**< library version number; useful to check dll version; requires v1.3.0+ */ LZ4LIB_API const char* LZ4_versionString (void); /**< library version string; useful to check dll version; requires v1.7.5+ */ /*-************************************ * Tuning memory usage **************************************/ /*! * LZ4_MEMORY_USAGE : * Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB) * Increasing memory usage improves compression ratio, generally at the cost of speed. * Reduced memory usage may improve speed at the cost of ratio, thanks to better cache locality. * Default value is 14, for 16KB, which nicely fits into most L1 caches. */ #ifndef LZ4_MEMORY_USAGE # define LZ4_MEMORY_USAGE LZ4_MEMORY_USAGE_DEFAULT #endif #define LZ4_MEMORY_USAGE_MIN 10 #define LZ4_MEMORY_USAGE_DEFAULT 14 #define LZ4_MEMORY_USAGE_MAX 20 #if (LZ4_MEMORY_USAGE < LZ4_MEMORY_USAGE_MIN) # error "LZ4_MEMORY_USAGE is too small !" #endif #if (LZ4_MEMORY_USAGE > LZ4_MEMORY_USAGE_MAX) # error "LZ4_MEMORY_USAGE is too large !" #endif /*-************************************ * Simple Functions **************************************/ /*! LZ4_compress_default() : * Compresses 'srcSize' bytes from buffer 'src' * into already allocated 'dst' buffer of size 'dstCapacity'. * Compression is guaranteed to succeed if 'dstCapacity' >= LZ4_compressBound(srcSize). * It also runs faster, so it's a recommended setting. * If the function cannot compress 'src' into a more limited 'dst' budget, * compression stops *immediately*, and the function result is zero. * In which case, 'dst' content is undefined (invalid). * srcSize : max supported value is LZ4_MAX_INPUT_SIZE. * dstCapacity : size of buffer 'dst' (which must be already allocated) * @return : the number of bytes written into buffer 'dst' (necessarily <= dstCapacity) * or 0 if compression fails * Note : This function is protected against buffer overflow scenarios (never writes outside 'dst' buffer, nor read outside 'source' buffer). */ LZ4LIB_API int LZ4_compress_default(const char* src, char* dst, int srcSize, int dstCapacity); /*! LZ4_decompress_safe() : * @compressedSize : is the exact complete size of the compressed block. * @dstCapacity : is the size of destination buffer (which must be already allocated), * presumed an upper bound of decompressed size. * @return : the number of bytes decompressed into destination buffer (necessarily <= dstCapacity) * If destination buffer is not large enough, decoding will stop and output an error code (negative value). * If the source stream is detected malformed, the function will stop decoding and return a negative result. * Note 1 : This function is protected against malicious data packets : * it will never writes outside 'dst' buffer, nor read outside 'source' buffer, * even if the compressed block is maliciously modified to order the decoder to do these actions. * In such case, the decoder stops immediately, and considers the compressed block malformed. * Note 2 : compressedSize and dstCapacity must be provided to the function, the compressed block does not contain them. * The implementation is free to send / store / derive this information in whichever way is most beneficial. * If there is a need for a different format which bundles together both compressed data and its metadata, consider looking at lz4frame.h instead. */ LZ4LIB_API int LZ4_decompress_safe (const char* src, char* dst, int compressedSize, int dstCapacity); /*-************************************ * Advanced Functions **************************************/ #define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */ #define LZ4_COMPRESSBOUND(isize) ((unsigned)(isize) > (unsigned)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 (destination buffer size). Macro LZ4_COMPRESSBOUND() is also provided for compilation-time evaluation (stack memory allocation for example). Note that LZ4_compress_default() compresses faster when dstCapacity is >= LZ4_compressBound(srcSize) inputSize : max supported value is LZ4_MAX_INPUT_SIZE return : maximum output size in a "worst case" scenario or 0, if input size is incorrect (too large or negative) */ LZ4LIB_API int LZ4_compressBound(int inputSize); /*! LZ4_compress_fast() : Same as LZ4_compress_default(), but allows selection of "acceleration" factor. The larger the acceleration value, the faster the algorithm, but also the lesser the compression. It's a trade-off. It can be fine tuned, with each successive value providing roughly +~3% to speed. An acceleration value of "1" is the same as regular LZ4_compress_default() Values <= 0 will be replaced by LZ4_ACCELERATION_DEFAULT (currently == 1, see lz4.c). Values > LZ4_ACCELERATION_MAX will be replaced by LZ4_ACCELERATION_MAX (currently == 65537, see lz4.c). */ LZ4LIB_API int LZ4_compress_fast (const char* src, char* dst, int srcSize, int dstCapacity, int acceleration); /*! LZ4_compress_fast_extState() : * Same as LZ4_compress_fast(), using an externally allocated memory space for its state. * Use LZ4_sizeofState() to know how much memory must be allocated, * and allocate it on 8-bytes boundaries (using `malloc()` typically). * Then, provide this buffer as `void* state` to compression function. */ LZ4LIB_API int LZ4_sizeofState(void); LZ4LIB_API int LZ4_compress_fast_extState (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration); /*! LZ4_compress_destSize() : * Reverse the logic : compresses as much data as possible from 'src' buffer * into already allocated buffer 'dst', of size >= 'dstCapacity'. * This function either compresses the entire 'src' content into 'dst' if it's large enough, * or fill 'dst' buffer completely with as much data as possible from 'src'. * note: acceleration parameter is fixed to "default". * * *srcSizePtr : in+out parameter. Initially contains size of input. * Will be modified to indicate how many bytes where read from 'src' to fill 'dst'. * New value is necessarily <= input value. * @return : Nb bytes written into 'dst' (necessarily <= dstCapacity) * or 0 if compression fails. * * Note : from v1.8.2 to v1.9.1, this function had a bug (fixed in v1.9.2+): * the produced compressed content could, in specific circumstances, * require to be decompressed into a destination buffer larger * by at least 1 byte than the content to decompress. * If an application uses `LZ4_compress_destSize()`, * it's highly recommended to update liblz4 to v1.9.2 or better. * If this can't be done or ensured, * the receiving decompression function should provide * a dstCapacity which is > decompressedSize, by at least 1 byte. * See https://github.com/lz4/lz4/issues/859 for details */ LZ4LIB_API int LZ4_compress_destSize(const char* src, char* dst, int* srcSizePtr, int targetDstSize); /*! LZ4_decompress_safe_partial() : * Decompress an LZ4 compressed block, of size 'srcSize' at position 'src', * into destination buffer 'dst' of size 'dstCapacity'. * Up to 'targetOutputSize' bytes will be decoded. * The function stops decoding on reaching this objective. * This can be useful to boost performance * whenever only the beginning of a block is required. * * @return : the number of bytes decoded in `dst` (necessarily <= targetOutputSize) * If source stream is detected malformed, function returns a negative result. * * Note 1 : @return can be < targetOutputSize, if compressed block contains less data. * * Note 2 : targetOutputSize must be <= dstCapacity * * Note 3 : this function effectively stops decoding on reaching targetOutputSize, * so dstCapacity is kind of redundant. * This is because in older versions of this function, * decoding operation would still write complete sequences. * Therefore, there was no guarantee that it would stop writing at exactly targetOutputSize, * it could write more bytes, though only up to dstCapacity. * Some "margin" used to be required for this operation to work properly. * Thankfully, this is no longer necessary. * The function nonetheless keeps the same signature, in an effort to preserve API compatibility. * * Note 4 : If srcSize is the exact size of the block, * then targetOutputSize can be any value, * including larger than the block's decompressed size. * The function will, at most, generate block's decompressed size. * * Note 5 : If srcSize is _larger_ than block's compressed size, * then targetOutputSize **MUST** be <= block's decompressed size. * Otherwise, *silent corruption will occur*. */ LZ4LIB_API int LZ4_decompress_safe_partial (const char* src, char* dst, int srcSize, int targetOutputSize, int dstCapacity); /*-********************************************* * Streaming Compression Functions ***********************************************/ typedef union LZ4_stream_u LZ4_stream_t; /* incomplete type (defined later) */ /*! Note about RC_INVOKED - RC_INVOKED is predefined symbol of rc.exe (the resource compiler which is part of MSVC/Visual Studio). https://docs.microsoft.com/en-us/windows/win32/menurc/predefined-macros - Since rc.exe is a legacy compiler, it truncates long symbol (> 30 chars) and reports warning "RC4011: identifier truncated". - To eliminate the warning, we surround long preprocessor symbol with "#if !defined(RC_INVOKED) ... #endif" block that means "skip this block when rc.exe is trying to read it". */ #if !defined(RC_INVOKED) /* https://docs.microsoft.com/en-us/windows/win32/menurc/predefined-macros */ #if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) LZ4LIB_API LZ4_stream_t* LZ4_createStream(void); LZ4LIB_API int LZ4_freeStream (LZ4_stream_t* streamPtr); #endif /* !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) */ #endif /*! LZ4_resetStream_fast() : v1.9.0+ * Use this to prepare an LZ4_stream_t for a new chain of dependent blocks * (e.g., LZ4_compress_fast_continue()). * * An LZ4_stream_t must be initialized once before usage. * This is automatically done when created by LZ4_createStream(). * However, should the LZ4_stream_t be simply declared on stack (for example), * it's necessary to initialize it first, using LZ4_initStream(). * * After init, start any new stream with LZ4_resetStream_fast(). * A same LZ4_stream_t can be re-used multiple times consecutively * and compress multiple streams, * provided that it starts each new stream with LZ4_resetStream_fast(). * * LZ4_resetStream_fast() is much faster than LZ4_initStream(), * but is not compatible with memory regions containing garbage data. * * Note: it's only useful to call LZ4_resetStream_fast() * in the context of streaming compression. * The *extState* functions perform their own resets. * Invoking LZ4_resetStream_fast() before is redundant, and even counterproductive. */ LZ4LIB_API void LZ4_resetStream_fast (LZ4_stream_t* streamPtr); /*! LZ4_loadDict() : * Use this function to reference a static dictionary into LZ4_stream_t. * The dictionary must remain available during compression. * LZ4_loadDict() triggers a reset, so any previous data will be forgotten. * The same dictionary will have to be loaded on decompression side for successful decoding. * Dictionary are useful for better compression of small data (KB range). * While LZ4 itself accepts any input as dictionary, dictionary efficiency is also a topic. * When in doubt, employ the Zstandard's Dictionary Builder. * Loading a size of 0 is allowed, and is the same as reset. * @return : loaded dictionary size, in bytes (note: only the last 64 KB are loaded) */ LZ4LIB_API int LZ4_loadDict (LZ4_stream_t* streamPtr, const char* dictionary, int dictSize); /*! LZ4_compress_fast_continue() : * Compress 'src' content using data from previously compressed blocks, for better compression ratio. * 'dst' buffer must be already allocated. * If dstCapacity >= LZ4_compressBound(srcSize), compression is guaranteed to succeed, and runs faster. * * @return : size of compressed block * or 0 if there is an error (typically, cannot fit into 'dst'). * * Note 1 : Each invocation to LZ4_compress_fast_continue() generates a new block. * Each block has precise boundaries. * Each block must be decompressed separately, calling LZ4_decompress_*() with relevant metadata. * It's not possible to append blocks together and expect a single invocation of LZ4_decompress_*() to decompress them together. * * Note 2 : The previous 64KB of source data is __assumed__ to remain present, unmodified, at same address in memory ! * * Note 3 : When input is structured as a double-buffer, each buffer can have any size, including < 64 KB. * Make sure that buffers are separated, by at least one byte. * This construction ensures that each block only depends on previous block. * * Note 4 : If input buffer is a ring-buffer, it can have any size, including < 64 KB. * * Note 5 : After an error, the stream status is undefined (invalid), it can only be reset or freed. */ LZ4LIB_API int LZ4_compress_fast_continue (LZ4_stream_t* streamPtr, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration); /*! LZ4_saveDict() : * If last 64KB data cannot be guaranteed to remain available at its current memory location, * save it into a safer place (char* safeBuffer). * This is schematically equivalent to a memcpy() followed by LZ4_loadDict(), * but is much faster, because LZ4_saveDict() doesn't need to rebuild tables. * @return : saved dictionary size in bytes (necessarily <= maxDictSize), or 0 if error. */ LZ4LIB_API int LZ4_saveDict (LZ4_stream_t* streamPtr, char* safeBuffer, int maxDictSize); /*-********************************************** * Streaming Decompression Functions * Bufferless synchronous API ************************************************/ typedef union LZ4_streamDecode_u LZ4_streamDecode_t; /* tracking context */ /*! LZ4_createStreamDecode() and LZ4_freeStreamDecode() : * creation / destruction of streaming decompression tracking context. * A tracking context can be re-used multiple times. */ #if !defined(RC_INVOKED) /* https://docs.microsoft.com/en-us/windows/win32/menurc/predefined-macros */ #if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) LZ4LIB_API LZ4_streamDecode_t* LZ4_createStreamDecode(void); LZ4LIB_API int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream); #endif /* !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) */ #endif /*! LZ4_setStreamDecode() : * An LZ4_streamDecode_t context can be allocated once and re-used multiple times. * Use this function to start decompression of a new stream of blocks. * A dictionary can optionally be set. Use NULL or size 0 for a reset order. * Dictionary is presumed stable : it must remain accessible and unmodified during next decompression. * @return : 1 if OK, 0 if error */ LZ4LIB_API int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize); /*! LZ4_decoderRingBufferSize() : v1.8.2+ * Note : in a ring buffer scenario (optional), * blocks are presumed decompressed next to each other * up to the moment there is not enough remaining space for next block (remainingSize < maxBlockSize), * at which stage it resumes from beginning of ring buffer. * When setting such a ring buffer for streaming decompression, * provides the minimum size of this ring buffer * to be compatible with any source respecting maxBlockSize condition. * @return : minimum ring buffer size, * or 0 if there is an error (invalid maxBlockSize). */ LZ4LIB_API int LZ4_decoderRingBufferSize(int maxBlockSize); #define LZ4_DECODER_RING_BUFFER_SIZE(maxBlockSize) (65536 + 14 + (maxBlockSize)) /* for static allocation; maxBlockSize presumed valid */ /*! LZ4_decompress_safe_continue() : * This decoding function allows decompression of consecutive blocks in "streaming" mode. * The difference with the usual independent blocks is that * new blocks are allowed to find references into former blocks. * A block is an unsplittable entity, and must be presented entirely to the decompression function. * LZ4_decompress_safe_continue() only accepts one block at a time. * It's modeled after `LZ4_decompress_safe()` and behaves similarly. * * @LZ4_streamDecode : decompression state, tracking the position in memory of past data * @compressedSize : exact complete size of one compressed block. * @dstCapacity : size of destination buffer (which must be already allocated), * must be an upper bound of decompressed size. * @return : number of bytes decompressed into destination buffer (necessarily <= dstCapacity) * If destination buffer is not large enough, decoding will stop and output an error code (negative value). * If the source stream is detected malformed, the function will stop decoding and return a negative result. * * The last 64KB of previously decoded data *must* remain available and unmodified * at the memory position where they were previously decoded. * If less than 64KB of data has been decoded, all the data must be present. * * Special : if decompression side sets a ring buffer, it must respect one of the following conditions : * - Decompression buffer size is _at least_ LZ4_decoderRingBufferSize(maxBlockSize). * maxBlockSize is the maximum size of any single block. It can have any value > 16 bytes. * In which case, encoding and decoding buffers do not need to be synchronized. * Actually, data can be produced by any source compliant with LZ4 format specification, and respecting maxBlockSize. * - Synchronized mode : * Decompression buffer size is _exactly_ the same as compression buffer size, * and follows exactly same update rule (block boundaries at same positions), * and decoding function is provided with exact decompressed size of each block (exception for last block of the stream), * _then_ decoding & encoding ring buffer can have any size, including small ones ( < 64 KB). * - Decompression buffer is larger than encoding buffer, by a minimum of maxBlockSize more bytes. * In which case, encoding and decoding buffers do not need to be synchronized, * and encoding ring buffer can have any size, including small ones ( < 64 KB). * * Whenever these conditions are not possible, * save the last 64KB of decoded data into a safe buffer where it can't be modified during decompression, * then indicate where this data is saved using LZ4_setStreamDecode(), before decompressing next block. */ LZ4LIB_API int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* src, char* dst, int srcSize, int dstCapacity); /*! LZ4_decompress_safe_usingDict() : * Works the same as * a combination of LZ4_setStreamDecode() followed by LZ4_decompress_safe_continue() * However, it's stateless: it doesn't need any LZ4_streamDecode_t state. * Dictionary is presumed stable : it must remain accessible and unmodified during decompression. * Performance tip : Decompression speed can be substantially increased * when dst == dictStart + dictSize. */ LZ4LIB_API int LZ4_decompress_safe_usingDict(const char* src, char* dst, int srcSize, int dstCapacity, const char* dictStart, int dictSize); /*! LZ4_decompress_safe_partial_usingDict() : * Behaves the same as LZ4_decompress_safe_partial() * with the added ability to specify a memory segment for past data. * Performance tip : Decompression speed can be substantially increased * when dst == dictStart + dictSize. */ LZ4LIB_API int LZ4_decompress_safe_partial_usingDict(const char* src, char* dst, int compressedSize, int targetOutputSize, int maxOutputSize, const char* dictStart, int dictSize); #endif /* LZ4_H_2983827168210 */ /*^************************************* * !!!!!! STATIC LINKING ONLY !!!!!! ***************************************/ /*-**************************************************************************** * Experimental section * * Symbols declared in this section must be considered unstable. Their * signatures or semantics may change, or they may be removed altogether in the * future. They are therefore only safe to depend on when the caller is * statically linked against the library. * * To protect against unsafe usage, not only are the declarations guarded, * the definitions are hidden by default * when building LZ4 as a shared/dynamic library. * * In order to access these declarations, * define LZ4_STATIC_LINKING_ONLY in your application * before including LZ4's headers. * * In order to make their implementations accessible dynamically, you must * define LZ4_PUBLISH_STATIC_FUNCTIONS when building the LZ4 library. ******************************************************************************/ #ifdef LZ4_STATIC_LINKING_ONLY #ifndef LZ4_STATIC_3504398509 #define LZ4_STATIC_3504398509 #ifdef LZ4_PUBLISH_STATIC_FUNCTIONS # define LZ4LIB_STATIC_API LZ4LIB_API #else # define LZ4LIB_STATIC_API #endif /*! LZ4_compress_fast_extState_fastReset() : * A variant of LZ4_compress_fast_extState(). * * Using this variant avoids an expensive initialization step. * It is only safe to call if the state buffer is known to be correctly initialized already * (see above comment on LZ4_resetStream_fast() for a definition of "correctly initialized"). * From a high level, the difference is that * this function initializes the provided state with a call to something like LZ4_resetStream_fast() * while LZ4_compress_fast_extState() starts with a call to LZ4_resetStream(). */ LZ4LIB_STATIC_API int LZ4_compress_fast_extState_fastReset (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration); /*! LZ4_compress_destSize_extState() : * Same as LZ4_compress_destSize(), but using an externally allocated state. * Also: exposes @acceleration */ int LZ4_compress_destSize_extState(void* state, const char* src, char* dst, int* srcSizePtr, int targetDstSize, int acceleration); /*! LZ4_attach_dictionary() : * This is an experimental API that allows * efficient use of a static dictionary many times. * * Rather than re-loading the dictionary buffer into a working context before * each compression, or copying a pre-loaded dictionary's LZ4_stream_t into a * working LZ4_stream_t, this function introduces a no-copy setup mechanism, * in which the working stream references the dictionary stream in-place. * * Several assumptions are made about the state of the dictionary stream. * Currently, only streams which have been prepared by LZ4_loadDict() should * be expected to work. * * Alternatively, the provided dictionaryStream may be NULL, * in which case any existing dictionary stream is unset. * * If a dictionary is provided, it replaces any pre-existing stream history. * The dictionary contents are the only history that can be referenced and * logically immediately precede the data compressed in the first subsequent * compression call. * * The dictionary will only remain attached to the working stream through the * first compression call, at the end of which it is cleared. The dictionary * stream (and source buffer) must remain in-place / accessible / unchanged * through the completion of the first compression call on the stream. */ LZ4LIB_STATIC_API void LZ4_attach_dictionary(LZ4_stream_t* workingStream, const LZ4_stream_t* dictionaryStream); /*! In-place compression and decompression * * It's possible to have input and output sharing the same buffer, * for highly constrained memory environments. * In both cases, it requires input to lay at the end of the buffer, * and decompression to start at beginning of the buffer. * Buffer size must feature some margin, hence be larger than final size. * * |<------------------------buffer--------------------------------->| * |<-----------compressed data--------->| * |<-----------decompressed size------------------>| * |<----margin---->| * * This technique is more useful for decompression, * since decompressed size is typically larger, * and margin is short. * * In-place decompression will work inside any buffer * which size is >= LZ4_DECOMPRESS_INPLACE_BUFFER_SIZE(decompressedSize). * This presumes that decompressedSize > compressedSize. * Otherwise, it means compression actually expanded data, * and it would be more efficient to store such data with a flag indicating it's not compressed. * This can happen when data is not compressible (already compressed, or encrypted). * * For in-place compression, margin is larger, as it must be able to cope with both * history preservation, requiring input data to remain unmodified up to LZ4_DISTANCE_MAX, * and data expansion, which can happen when input is not compressible. * As a consequence, buffer size requirements are much higher, * and memory savings offered by in-place compression are more limited. * * There are ways to limit this cost for compression : * - Reduce history size, by modifying LZ4_DISTANCE_MAX. * Note that it is a compile-time constant, so all compressions will apply this limit. * Lower values will reduce compression ratio, except when input_size < LZ4_DISTANCE_MAX, * so it's a reasonable trick when inputs are known to be small. * - Require the compressor to deliver a "maximum compressed size". * This is the `dstCapacity` parameter in `LZ4_compress*()`. * When this size is < LZ4_COMPRESSBOUND(inputSize), then compression can fail, * in which case, the return code will be 0 (zero). * The caller must be ready for these cases to happen, * and typically design a backup scheme to send data uncompressed. * The combination of both techniques can significantly reduce * the amount of margin required for in-place compression. * * In-place compression can work in any buffer * which size is >= (maxCompressedSize) * with maxCompressedSize == LZ4_COMPRESSBOUND(srcSize) for guaranteed compression success. * LZ4_COMPRESS_INPLACE_BUFFER_SIZE() depends on both maxCompressedSize and LZ4_DISTANCE_MAX, * so it's possible to reduce memory requirements by playing with them. */ #define LZ4_DECOMPRESS_INPLACE_MARGIN(compressedSize) (((compressedSize) >> 8) + 32) #define LZ4_DECOMPRESS_INPLACE_BUFFER_SIZE(decompressedSize) ((decompressedSize) + LZ4_DECOMPRESS_INPLACE_MARGIN(decompressedSize)) /**< note: presumes that compressedSize < decompressedSize. note2: margin is overestimated a bit, since it could use compressedSize instead */ #ifndef LZ4_DISTANCE_MAX /* history window size; can be user-defined at compile time */ # define LZ4_DISTANCE_MAX 65535 /* set to maximum value by default */ #endif #define LZ4_COMPRESS_INPLACE_MARGIN (LZ4_DISTANCE_MAX + 32) /* LZ4_DISTANCE_MAX can be safely replaced by srcSize when it's smaller */ #define LZ4_COMPRESS_INPLACE_BUFFER_SIZE(maxCompressedSize) ((maxCompressedSize) + LZ4_COMPRESS_INPLACE_MARGIN) /**< maxCompressedSize is generally LZ4_COMPRESSBOUND(inputSize), but can be set to any lower value, with the risk that compression can fail (return code 0(zero)) */ #endif /* LZ4_STATIC_3504398509 */ #endif /* LZ4_STATIC_LINKING_ONLY */ #ifndef LZ4_H_98237428734687 #define LZ4_H_98237428734687 /*-************************************************************ * Private Definitions ************************************************************** * Do not use these definitions directly. * They are only exposed to allow static allocation of `LZ4_stream_t` and `LZ4_streamDecode_t`. * Accessing members will expose user code to API and/or ABI break in future versions of the library. **************************************************************/ #define LZ4_HASHLOG (LZ4_MEMORY_USAGE-2) #define LZ4_HASHTABLESIZE (1 << LZ4_MEMORY_USAGE) #define LZ4_HASH_SIZE_U32 (1 << LZ4_HASHLOG) /* required as macro for static allocation */ #if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) # include typedef int8_t LZ4_i8; typedef uint8_t LZ4_byte; typedef uint16_t LZ4_u16; typedef uint32_t LZ4_u32; #else typedef signed char LZ4_i8; typedef unsigned char LZ4_byte; typedef unsigned short LZ4_u16; typedef unsigned int LZ4_u32; #endif /*! LZ4_stream_t : * Never ever use below internal definitions directly ! * These definitions are not API/ABI safe, and may change in future versions. * If you need static allocation, declare or allocate an LZ4_stream_t object. **/ typedef struct LZ4_stream_t_internal LZ4_stream_t_internal; struct LZ4_stream_t_internal { LZ4_u32 hashTable[LZ4_HASH_SIZE_U32]; const LZ4_byte* dictionary; const LZ4_stream_t_internal* dictCtx; LZ4_u32 currentOffset; LZ4_u32 tableType; LZ4_u32 dictSize; /* Implicit padding to ensure structure is aligned */ }; #define LZ4_STREAM_MINSIZE ((1UL << (LZ4_MEMORY_USAGE)) + 32) /* static size, for inter-version compatibility */ union LZ4_stream_u { char minStateSize[LZ4_STREAM_MINSIZE]; LZ4_stream_t_internal internal_donotuse; }; /* previously typedef'd to LZ4_stream_t */ /*! LZ4_initStream() : v1.9.0+ * An LZ4_stream_t structure must be initialized at least once. * This is automatically done when invoking LZ4_createStream(), * but it's not when the structure is simply declared on stack (for example). * * Use LZ4_initStream() to properly initialize a newly declared LZ4_stream_t. * It can also initialize any arbitrary buffer of sufficient size, * and will @return a pointer of proper type upon initialization. * * Note : initialization fails if size and alignment conditions are not respected. * In which case, the function will @return NULL. * Note2: An LZ4_stream_t structure guarantees correct alignment and size. * Note3: Before v1.9.0, use LZ4_resetStream() instead **/ LZ4LIB_API LZ4_stream_t* LZ4_initStream (void* stateBuffer, size_t size); /*! LZ4_streamDecode_t : * Never ever use below internal definitions directly ! * These definitions are not API/ABI safe, and may change in future versions. * If you need static allocation, declare or allocate an LZ4_streamDecode_t object. **/ typedef struct { const LZ4_byte* externalDict; const LZ4_byte* prefixEnd; size_t extDictSize; size_t prefixSize; } LZ4_streamDecode_t_internal; #define LZ4_STREAMDECODE_MINSIZE 32 union LZ4_streamDecode_u { char minStateSize[LZ4_STREAMDECODE_MINSIZE]; LZ4_streamDecode_t_internal internal_donotuse; } ; /* previously typedef'd to LZ4_streamDecode_t */ /*-************************************ * Obsolete Functions **************************************/ /*! Deprecation warnings * * Deprecated functions make the compiler generate a warning when invoked. * This is meant to invite users to update their source code. * Should deprecation warnings be a problem, it is generally possible to disable them, * typically with -Wno-deprecated-declarations for gcc * or _CRT_SECURE_NO_WARNINGS in Visual. * * Another method is to define LZ4_DISABLE_DEPRECATE_WARNINGS * before including the header file. */ #ifdef LZ4_DISABLE_DEPRECATE_WARNINGS # define LZ4_DEPRECATED(message) /* disable deprecation warnings */ #else # if defined (__cplusplus) && (__cplusplus >= 201402) /* C++14 or greater */ # define LZ4_DEPRECATED(message) [[deprecated(message)]] # elif defined(_MSC_VER) # define LZ4_DEPRECATED(message) __declspec(deprecated(message)) # elif defined(__clang__) || (defined(__GNUC__) && (__GNUC__ * 10 + __GNUC_MINOR__ >= 45)) # define LZ4_DEPRECATED(message) __attribute__((deprecated(message))) # elif defined(__GNUC__) && (__GNUC__ * 10 + __GNUC_MINOR__ >= 31) # define LZ4_DEPRECATED(message) __attribute__((deprecated)) # else # pragma message("WARNING: LZ4_DEPRECATED needs custom implementation for this compiler") # define LZ4_DEPRECATED(message) /* disabled */ # endif #endif /* LZ4_DISABLE_DEPRECATE_WARNINGS */ /*! Obsolete compression functions (since v1.7.3) */ LZ4_DEPRECATED("use LZ4_compress_default() instead") LZ4LIB_API int LZ4_compress (const char* src, char* dest, int srcSize); LZ4_DEPRECATED("use LZ4_compress_default() instead") LZ4LIB_API int LZ4_compress_limitedOutput (const char* src, char* dest, int srcSize, int maxOutputSize); LZ4_DEPRECATED("use LZ4_compress_fast_extState() instead") LZ4LIB_API int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize); LZ4_DEPRECATED("use LZ4_compress_fast_extState() instead") LZ4LIB_API int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize); LZ4_DEPRECATED("use LZ4_compress_fast_continue() instead") LZ4LIB_API int LZ4_compress_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize); LZ4_DEPRECATED("use LZ4_compress_fast_continue() instead") LZ4LIB_API int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize, int maxOutputSize); /*! Obsolete decompression functions (since v1.8.0) */ LZ4_DEPRECATED("use LZ4_decompress_fast() instead") LZ4LIB_API int LZ4_uncompress (const char* source, char* dest, int outputSize); LZ4_DEPRECATED("use LZ4_decompress_safe() instead") LZ4LIB_API int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize); /* Obsolete streaming functions (since v1.7.0) * degraded functionality; do not use! * * In order to perform streaming compression, these functions depended on data * that is no longer tracked in the state. They have been preserved as well as * possible: using them will still produce a correct output. However, they don't * actually retain any history between compression calls. The compression ratio * achieved will therefore be no better than compressing each chunk * independently. */ LZ4_DEPRECATED("Use LZ4_createStream() instead") LZ4LIB_API void* LZ4_create (char* inputBuffer); LZ4_DEPRECATED("Use LZ4_createStream() instead") LZ4LIB_API int LZ4_sizeofStreamState(void); LZ4_DEPRECATED("Use LZ4_resetStream() instead") LZ4LIB_API int LZ4_resetStreamState(void* state, char* inputBuffer); LZ4_DEPRECATED("Use LZ4_saveDict() instead") LZ4LIB_API char* LZ4_slideInputBuffer (void* state); /*! Obsolete streaming decoding functions (since v1.7.0) */ LZ4_DEPRECATED("use LZ4_decompress_safe_usingDict() instead") LZ4LIB_API int LZ4_decompress_safe_withPrefix64k (const char* src, char* dst, int compressedSize, int maxDstSize); LZ4_DEPRECATED("use LZ4_decompress_fast_usingDict() instead") LZ4LIB_API int LZ4_decompress_fast_withPrefix64k (const char* src, char* dst, int originalSize); /*! Obsolete LZ4_decompress_fast variants (since v1.9.0) : * These functions used to be faster than LZ4_decompress_safe(), * but this is no longer the case. They are now slower. * This is because LZ4_decompress_fast() doesn't know the input size, * and therefore must progress more cautiously into the input buffer to not read beyond the end of block. * On top of that `LZ4_decompress_fast()` is not protected vs malformed or malicious inputs, making it a security liability. * As a consequence, LZ4_decompress_fast() is strongly discouraged, and deprecated. * * The last remaining LZ4_decompress_fast() specificity is that * it can decompress a block without knowing its compressed size. * Such functionality can be achieved in a more secure manner * by employing LZ4_decompress_safe_partial(). * * Parameters: * originalSize : is the uncompressed size to regenerate. * `dst` must be already allocated, its size must be >= 'originalSize' bytes. * @return : number of bytes read from source buffer (== compressed size). * The function expects to finish at block's end exactly. * If the source stream is detected malformed, the function stops decoding and returns a negative result. * note : LZ4_decompress_fast*() requires originalSize. Thanks to this information, it never writes past the output buffer. * However, since it doesn't know its 'src' size, it may read an unknown amount of input, past input buffer bounds. * Also, since match offsets are not validated, match reads from 'src' may underflow too. * These issues never happen if input (compressed) data is correct. * But they may happen if input data is invalid (error or intentional tampering). * As a consequence, use these functions in trusted environments with trusted data **only**. */ LZ4_DEPRECATED("This function is deprecated and unsafe. Consider using LZ4_decompress_safe_partial() instead") LZ4LIB_API int LZ4_decompress_fast (const char* src, char* dst, int originalSize); LZ4_DEPRECATED("This function is deprecated and unsafe. Consider migrating towards LZ4_decompress_safe_continue() instead. " "Note that the contract will change (requires block's compressed size, instead of decompressed size)") LZ4LIB_API int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* src, char* dst, int originalSize); LZ4_DEPRECATED("This function is deprecated and unsafe. Consider using LZ4_decompress_safe_partial_usingDict() instead") LZ4LIB_API int LZ4_decompress_fast_usingDict (const char* src, char* dst, int originalSize, const char* dictStart, int dictSize); /*! LZ4_resetStream() : * An LZ4_stream_t structure must be initialized at least once. * This is done with LZ4_initStream(), or LZ4_resetStream(). * Consider switching to LZ4_initStream(), * invoking LZ4_resetStream() will trigger deprecation warnings in the future. */ LZ4LIB_API void LZ4_resetStream (LZ4_stream_t* streamPtr); #endif /* LZ4_H_98237428734687 */ #if defined (__cplusplus) } #endif gtkwave-gtk3-3.3.125/src/helpers/fst/block_format.txt0000664000175000017500000000624515047725113021755 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-gtk3-3.3.125/src/helpers/fst/Makefile.in0000664000175000017500000004261515047725113020620 0ustar bybellbybell# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : 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@ GLIB_COMPILE_SCHEMAS = @GLIB_COMPILE_SCHEMAS@ GPERF = @GPERF@ GREP = @GREP@ GSETTINGS_CFLAGS = @GSETTINGS_CFLAGS@ GSETTINGS_DISABLE_SCHEMAS_COMPILE = @GSETTINGS_DISABLE_SCHEMAS_COMPILE@ GTK_CFLAGS = @GTK_CFLAGS@ 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_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_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@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ RANLIB = @RANLIB@ RPC_CFLAGS = @RPC_CFLAGS@ RPC_LDADD = @RPC_LDADD@ 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@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ 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@ gsettingsschemadir = @gsettingsschemadir@ 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 fst_win_unistd.h EXTRA_DIST = block_format.txt CMakeLists.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-gtk3-3.3.125/src/helpers/fst/fastlz.c0000664000175000017500000003237115047725113020220 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. SPDX-License-Identifier: MIT */ #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-gtk3-3.3.125/src/helpers/fst/fst_win_unistd.h0000664000175000017500000000307115047725113021754 0ustar bybellbybell/* * Copyright (c) 2009-2018 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. * * SPDX-License-Identifier: MIT */ #ifndef WIN_UNISTD_H #define WIN_UNISTD_H #include #ifdef _WIN64 #include #else #include #endif #include #define ftruncate _chsize_s #define unlink _unlink #define fileno _fileno #define lseek _lseeki64 #ifdef _WIN64 #define ssize_t __int64 #define SSIZE_MAX 9223372036854775807i64 #else #define ssize_t long #define SSIZE_MAX 2147483647L #endif #include "stdint.h" #endif //WIN_UNISTD_H gtkwave-gtk3-3.3.125/src/helpers/fst/fstapi.c0000664000175000017500000071574015047725113020213 0ustar bybellbybell/* * Copyright (c) 2009-2023 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. * * SPDX-License-Identifier: MIT */ /* * 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 * */ #ifdef FST_INCLUDE_CONFIG #include #endif #include "fstapi.h" #include "fastlz.h" #include "lz4.h" #include #ifndef HAVE_LIBPTHREAD #undef FST_WRITER_PARALLEL #endif #ifdef FST_WRITER_PARALLEL #include #endif #ifdef __MINGW32__ #define WIN32_LEAN_AND_MEAN #include #endif #ifndef PATH_MAX #define PATH_MAX (4096) #endif #if defined(_MSC_VER) typedef int64_t fst_off_t; #else typedef off_t fst_off_t; #endif /* 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; void JenkinsFree(void *base_i, uint32_t hashmask); void **JenkinsIns(void *base_i, const unsigned char *mem, uint32_t length, uint32_t hashmask); #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) #define FST_ZWRAPPER_HDR_SIZE (1 + 8 + 8) #if defined(__APPLE__) && defined(__MACH__) #define FST_MACOSX #include #endif #if defined(FST_MACOSX) || defined(__MINGW32__) || defined(__OpenBSD__) || defined(__FreeBSD__) || \ defined(__NetBSD__) #define FST_UNBUFFERED_IO #endif #ifdef __GNUC__ /* Boolean expression more often true than false */ #define FST_LIKELY(x) __builtin_expect(!!(x), 1) /* Boolean expression more often false than true */ #define FST_UNLIKELY(x) __builtin_expect(!!(x), 0) #else #define FST_LIKELY(x) (!!(x)) #define FST_UNLIKELY(x) (!!(x)) #endif #define FST_APIMESS "FSTAPI | " /***********************/ /*** ***/ /*** common function ***/ /*** ***/ /***********************/ #ifdef __MINGW32__ #include #ifndef HAVE_FSEEKO #define ftello _ftelli64 #define fseeko _fseeki64 #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 */ /* * report abort messages */ static void chk_report_abort(const char *s) { fprintf(stderr, "Triggered %s security check, exiting.\n", s); abort(); } /* * 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, FST_APIMESS "GetTempPath() failed in " __FILE__ " line %d, exiting.\n", __LINE__); exit(255); } else { uRetVal = GetTempFileName(lpTempPathBuffer, TEXT("FSTW"), 0, szTempFileName); if (uRetVal == 0) { fprintf(stderr, FST_APIMESS "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, fst_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 = (char *)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 = (char *)malloc(PATH_MAX + 1); } return (_fullpath(resolved_path, path, PATH_MAX)); #else (void)path; (void)resolved_path; return (NULL); #endif #endif } /* * mmap compatibility */ #if defined __MINGW32__ #include #define fstMmap(__addr, __len, __prot, __flags, __fd, __off) fstMmap2((__len), (__fd), (__off)) #define fstMunmap(__addr, __len) UnmapViewOfFile((LPCVOID)__addr) static void *fstMmap2(size_t __len, int __fd, fst_off_t __off) { DWORD64 len64 = __len; /* Must be 64-bit for shift below */ HANDLE handle = CreateFileMapping((HANDLE)_get_osfhandle(__fd), NULL, PAGE_READWRITE, (DWORD)(len64 >> 32), (DWORD)__len, NULL); if (!handle) { return NULL; } void *ptr = MapViewOfFileEx(handle, FILE_MAP_READ | FILE_MAP_WRITE, 0, (DWORD)__off, (SIZE_T)__len, (LPVOID)NULL); CloseHandle(handle); return ptr; } #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 */ static uint32_t fstGetUint32(unsigned char *mem) { uint32_t u32; unsigned char *buf = (unsigned char *)(&u32); memcpy(buf, mem, sizeof(uint32_t)); return (*(uint32_t *)buf); } 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 < sizeof(uint64_t); i++) { val <<= 8; val |= buf[i]; } return (val); } static uint32_t fstGetVarint32(unsigned char *mem, int *skiplen) { unsigned char *mem_orig = mem; uint32_t rc = 0; while (*mem & 0x80) { mem++; } *skiplen = mem - mem_orig + 1; for (;;) { rc <<= 7; rc |= (uint32_t)(*mem & 0x7f); if (mem == mem_orig) { break; } mem--; } return (rc); } static uint32_t fstGetVarint32Length(unsigned char *mem) { unsigned char *mem_orig = mem; while (*mem & 0x80) { mem++; } return (mem - mem_orig + 1); } static uint32_t fstGetVarint32NoSkip(unsigned char *mem) { unsigned char *mem_orig = mem; uint32_t rc = 0; while (*mem & 0x80) { mem++; } for (;;) { rc <<= 7; rc |= (uint32_t)(*mem & 0x7f); if (mem == mem_orig) { break; } mem--; } return (rc); } static unsigned char *fstCopyVarint32ToLeft(unsigned char *pnt, uint32_t v) { unsigned char *spnt; uint32_t nxt = v; int cnt = 1; int i; while ((nxt = nxt >> 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 < cnt; i++) /* now generate left to right as normal */ { nxt = v >> 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) { const int chk_len_max = 5; /* TALOS-2023-1783 */ int chk_len = chk_len_max; unsigned char buf[chk_len_max]; unsigned char *mem = buf; uint32_t rc = 0; int ch; do { ch = fgetc(f); *(mem++) = ch; } while ((ch & 0x80) && (--chk_len)); if (ch & 0x80) chk_report_abort("TALOS-2023-1783"); 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) { const int chk_len_max = 5; /* TALOS-2023-1783 */ int chk_len = chk_len_max; unsigned char buf[chk_len_max]; unsigned char *mem = buf; uint32_t rc = 0; int ch; do { ch = fgetc(f); *(mem++) = ch; } while ((ch & 0x80) && (--chk_len)); if (ch & 0x80) chk_report_abort("TALOS-2023-1783"); *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) { const int chk_len_max = 16; /* TALOS-2023-1783 */ int chk_len = chk_len_max; unsigned char buf[chk_len_max]; unsigned char *mem = buf; uint64_t rc = 0; int ch; do { ch = fgetc(f); *(mem++) = ch; } while ((ch & 0x80) && (--chk_len)); if (ch & 0x80) chk_report_abort("TALOS-2023-1783"); 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 < siz) && (byt & 0x40)) { rc |= -(one << shift); /* sign extend */ } *skiplen = mem - mem_orig; return (rc); } #ifndef FST_DYNAMIC_ALIAS2_DISABLE static int fstWriterSVarint(FILE *handle, int64_t v) { unsigned char buf[15]; /* ceil(64/7) = 10 + sign byte padded way up */ unsigned char byt; unsigned char *pnt = buf; int more = 1; int len; do { byt = v | 0x80; v >>= 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); } #endif /***********************/ /*** ***/ /*** 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; fst_off_t hier_file_len; uint32_t *valpos_mem; unsigned char *curval_mem; unsigned char *outval_mem; /* for two-state / Verilator-style value changes */ uint32_t outval_alloc_siz; 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; fst_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; fst_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 unsigned in_pthread : 1; 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; fstEnumHandle max_enumhandle; }; static int fstWriterFseeko(struct fstWriterContext *xc, FILE *stream, fst_off_t offset, int whence) { int rc = fseeko(stream, offset, whence); if (rc < 0) { xc->fseek_failed = 1; #ifdef FST_DEBUG fprintf(stderr, FST_APIMESS "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; memcpy(pnt, u, sizeof(uint32_t)); 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; memcpy(pnt, u, sizeof(uint32_t)); 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 fstWriterMmapSanity(void *pnt, const char *file, int line, const char *usage) { if (pnt == NULL #ifdef MAP_FAILED || pnt == MAP_FAILED #endif ) { fprintf(stderr, "fstMmap() assigned to %s failed: errno: %d, file %s, line %d.\n", usage, errno, file, line); #if !defined(__MINGW32__) perror("Why"); #else LPSTR mbuf = NULL; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&mbuf, 0, NULL); fprintf(stderr, "%s", mbuf); LocalFree(mbuf); #endif pnt = NULL; } } static void fstWriterCreateMmaps(struct fstWriterContext *xc) { fst_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); errno = 0; if (xc->maxhandle) { fstWriterMmapSanity(xc->valpos_mem = (uint32_t *)fstMmap(NULL, xc->maxhandle * 4 * sizeof(uint32_t), PROT_READ | PROT_WRITE, MAP_SHARED, fileno(xc->valpos_handle), 0), __FILE__, __LINE__, "xc->valpos_mem"); } } if (!xc->curval_mem) { fflush(xc->curval_handle); errno = 0; if (xc->maxvalpos) { fstWriterMmapSanity(xc->curval_mem = (unsigned char *)fstMmap(NULL, xc->maxvalpos, PROT_READ | PROT_WRITE, MAP_SHARED, fileno(xc->curval_handle), 0), __FILE__, __LINE__, "xc->curval_handle"); } } } 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; 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 */ fstWriterContext *fstWriterCreate(const char *nam, int use_compressed_hier) { fstWriterContext *xc = (fstWriterContext *)calloc(1, sizeof(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 = (char *)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 = (unsigned char *)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(fstWriterContext *xc) { if (xc) { unsigned long destlen; unsigned char *dmem; int rc; destlen = xc->maxvalpos; dmem = (unsigned char *)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(fstWriterContext *xc) #else static void fstWriterFlushContextPrivate(fstWriterContext *xc) #endif { #ifdef FST_DEBUG int cnt = 0; #endif unsigned int i; unsigned char *vchg_mem; FILE *f; fst_off_t fpos, indxpos, endpos; uint32_t prevpos; int zerocnt; unsigned char *scratchpad; unsigned char *scratchpnt; unsigned char *tmem; fst_off_t tlen; fst_off_t unc_memreq = 0; /* for reader */ unsigned char *packmem; unsigned int packmemlen; uint32_t *vm4ip; #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; uint32_t hashmask = xc->maxhandle; hashmask |= hashmask >> 1; hashmask |= hashmask >> 2; hashmask |= hashmask >> 4; hashmask |= hashmask >> 8; hashmask |= hashmask >> 16; #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 = (unsigned char *)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 = (unsigned char *)malloc(packmemlen); /* prevent continual malloc...free every loop iter */ for (i = 0; i < xc->maxhandle; 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; idx < vm4ip[1]; idx++) { if ((pnt[idx] == '0') || (pnt[idx] == '1')) { continue; } else { is_binary = 0; break; } } if (is_binary) { unsigned char acc = 0; /* new algorithm */ idx = ((vm4ip[1] + 7) & ~7); switch (vm4ip[1] & 7) { case 0: do { acc = (pnt[idx + 7 - 8] & 1) << 0; /* fallthrough */ case 7: acc |= (pnt[idx + 6 - 8] & 1) << 1; /* fallthrough */ case 6: acc |= (pnt[idx + 5 - 8] & 1) << 2; /* fallthrough */ case 5: acc |= (pnt[idx + 4 - 8] & 1) << 3; /* fallthrough */ case 4: acc |= (pnt[idx + 3 - 8] & 1) << 4; /* fallthrough */ case 3: acc |= (pnt[idx + 2 - 8] & 1) << 5; /* fallthrough */ case 2: acc |= (pnt[idx + 1 - 8] & 1) << 6; /* fallthrough */ case 1: acc |= (pnt[idx + 0 - 8] & 1) << 7; *(--scratchpnt) = acc; idx -= 8; } while (idx); } scratchpnt = fstCopyVarint32ToLeft(scratchpnt, (time_delta << 1)); } else { scratchpnt -= vm4ip[1]; memcpy(scratchpnt, pnt, vm4ip[1]); scratchpnt = fstCopyVarint32ToLeft(scratchpnt, (time_delta << 1) | 1); } } } wrlen = scratchpad + xc->vchg_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 = (unsigned char *)malloc(compressBound(packmemlen = wrlen)); } rc = compress2(dmem, &destlen, scratchpnt, wrlen, 4); if (rc == Z_OK) { #ifndef FST_DYNAMIC_ALIAS_DISABLE PPvoid_t pv = JenkinsIns(&PJHSArray, dmem, destlen, hashmask); 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 = JenkinsIns(&PJHSArray, scratchpnt, wrlen, hashmask); 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 = (unsigned char *)malloc(packmemlen = (wrlen * 2) + 2); } rc = (xc->fourpack) ? LZ4_compress_default((char *)scratchpnt, (char *)dmem, wrlen, packmemlen) : fastlz_compress(scratchpnt, wrlen, dmem); if (rc < destlen) { #ifndef FST_DYNAMIC_ALIAS_DISABLE PPvoid_t pv = JenkinsIns(&PJHSArray, dmem, rc, hashmask); 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 = JenkinsIns(&PJHSArray, scratchpnt, wrlen, hashmask); 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 = JenkinsIns(&PJHSArray, scratchpnt, wrlen, hashmask); 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 JenkinsFree(&PJHSArray, hashmask); #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; i < xc->maxhandle; 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) { int32_t t_i32 = ((int32_t)(prev_alias = vm4ip[2])); /* vm4ip is generic unsigned data */ int64_t t_i64 = (int64_t)t_i32; /* convert to signed */ uint64_t t_u64 = (uint64_t)t_i64; /* sign extend through 64b */ fpos += fstWriterSVarint( f, (int64_t)((t_u64 << 1) | 1)); /* all in this block was: 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; i < xc->maxhandle; 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, FST_APIMESS "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); errno = 0; fstWriterMmapSanity( tmem = (unsigned char *) fstMmap(NULL, tlen, PROT_READ | PROT_WRITE, MAP_SHARED, fileno(xc->tchn_handle), 0), __FILE__, __LINE__, "tmem"); if (tmem) { unsigned long destlen = tlen; unsigned char *dmem = (unsigned char *)malloc(compressBound(destlen)); int rc = compress2(dmem, &destlen, tmem, tlen, 9); if ((rc == Z_OK) && (((fst_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 >= ((fst_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, FST_APIMESS "<< 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; struct fstWriterContext *xc_parent; pthread_mutex_lock(&(xc->xc_parent->mutex)); fstWriterFlushContextPrivate2(xc); #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); xc_parent = xc->xc_parent; free(xc); xc_parent->in_pthread = 0; pthread_mutex_unlock(&(xc_parent->mutex)); return (NULL); } static void fstWriterFlushContextPrivate(fstWriterContext *xc) { if (xc->parallel_enabled) { struct fstWriterContext *xc2 = (struct fstWriterContext *)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)); if (sizeof(size_t) < sizeof(uint64_t)) { /* TALOS-2023-1777 for 32b overflow */ uint64_t chk_64 = xc->maxhandle * 4 * sizeof(uint32_t); size_t chk_32 = xc->maxhandle * 4 * sizeof(uint32_t); if (chk_64 != chk_32) chk_report_abort("TALOS-2023-1777"); } xc2->valpos_mem = (uint32_t *)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 = (unsigned char *)malloc(xc->maxvalpos); memcpy(xc2->curval_mem, xc->curval_mem, xc->maxvalpos); #endif xc->vchg_mem = (unsigned char *)malloc(xc->vchg_alloc_siz); xc->vchg_mem[0] = '!'; xc->vchg_siz = 1; for (i = 0; i < xc->maxhandle; 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++; while (xc->in_pthread) { pthread_mutex_lock(&xc->mutex); pthread_mutex_unlock(&xc->mutex); }; pthread_mutex_lock(&xc->mutex); xc->in_pthread = 1; pthread_mutex_unlock(&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(fstWriterContext *xc) { if (xc) { if (xc->tchn_idx > 1) { xc->flush_context_pending = 1; } } } /* * close out FST file */ void fstWriterClose(fstWriterContext *xc) { #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 = NULL; fst_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 (FST_UNLIKELY(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); while (xc->in_pthread) { pthread_mutex_lock(&xc->mutex); pthread_mutex_unlock(&xc->mutex); }; #endif } } fstDestroyMmaps(xc, 1); if (xc->outval_mem) { free(xc->outval_mem); xc->outval_mem = NULL; xc->outval_alloc_siz = 0; } /* write out geom section */ fflush(xc->geom_handle); tlen = ftello(xc->geom_handle); errno = 0; if (tlen) { fstWriterMmapSanity(tmem = (unsigned char *)fstMmap(NULL, tlen, PROT_READ | PROT_WRITE, MAP_SHARED, fileno(xc->geom_handle), 0), __FILE__, __LINE__, "tmem"); } if (tmem) { unsigned long destlen = tlen; unsigned char *dmem = (unsigned char *)malloc(compressBound(destlen)); int rc = compress2(dmem, &destlen, tmem, tlen, 9); if ((rc != Z_OK) || (((fst_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((((fst_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; fst_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; i < xc->num_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) { fst_off_t hl, eos; gzFile zhandle; int zfd; int fourpack_duo = 0; #ifndef __MINGW32__ int fnam_len = strlen(xc->filename) + 5 + 1; char *fnam = (char *)malloc(fnam_len); #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 = (unsigned char *)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 = NULL; int packed_len; fflush(xc->handle); lz4_maxlen = LZ4_compressBound(xc->hier_file_len); mem = (unsigned char *)malloc(lz4_maxlen); errno = 0; if (xc->hier_file_len) { fstWriterMmapSanity(hmem = (unsigned char *)fstMmap(NULL, xc->hier_file_len, PROT_READ | PROT_WRITE, MAP_SHARED, fileno(xc->hier_handle), 0), __FILE__, __LINE__, "hmem"); } packed_len = LZ4_compress_default((char *)hmem, (char *)mem, xc->hier_file_len, lz4_maxlen); 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 = (unsigned char *)malloc(lz4_maxlen_duo); packed_len_duo = LZ4_compress_default((char *)mem, (char *)mem_duo, packed_len, lz4_maxlen_duo); 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__ snprintf(fnam, fnam_len, "%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; fst_off_t offpnt, uclen; int flen = strlen(xc->filename); char *hf = (char *)calloc(1, flen + 5); strcpy(hf, xc->filename); strcpy(hf + flen, ".pak"); fp = fopen(hf, "wb"); if (fp) { gzFile 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 = (char *)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) { const uint32_t hashmask = FST_PATH_HASHMASK; JenkinsFree(&(xc->path_array), hashmask); } free(xc->filename); xc->filename = NULL; free(xc); } } /* * functions to set miscellaneous header/block information */ void fstWriterSetDate(fstWriterContext *xc, const char *dat) { if (xc) { char s[FST_HDR_DATE_SIZE]; fst_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(fstWriterContext *xc, const char *vers) { if (xc && vers) { char s[FST_HDR_SIM_VERSION_SIZE]; fst_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(fstWriterContext *xc, enum fstFileType filetype) { if (xc) { if (/*(filetype >= FST_FT_MIN) &&*/ (filetype <= FST_FT_MAX)) { fst_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(fstWriterContext *xc, int typ, uint64_t arg1, uint64_t arg2) { 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(fstWriterContext *xc, const char *comm, int typ, uint64_t arg) { 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(fstWriterContext *xc, const char *path, unsigned int line, unsigned int use_realpath, int typ) { if (xc && path && path[0]) { uint64_t sidx = 0; int slen = strlen(path); const uint32_t hashmask = FST_PATH_HASHMASK; const unsigned char *path2 = (const unsigned char *)path; PPvoid_t pv; pv = JenkinsIns(&(xc->path_array), path2, slen, hashmask); 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((const char *)path2, NULL); } fstWriterSetAttrGeneric(xc, rp ? rp : (const char *)path2, FST_MT_PATHNAME, sidx); if (rp) { free(rp); } } fstWriterSetAttrDoubleArgGeneric(xc, typ, sidx, line); } } void fstWriterSetSourceStem(fstWriterContext *ctx, const char *path, unsigned int line, unsigned int use_realpath) { fstWriterSetSourceStem_2(ctx, path, line, use_realpath, FST_MT_SOURCESTEM); } void fstWriterSetSourceInstantiationStem(fstWriterContext *ctx, const char *path, unsigned int line, unsigned int use_realpath) { fstWriterSetSourceStem_2(ctx, path, line, use_realpath, FST_MT_SOURCEISTEM); } void fstWriterSetComment(fstWriterContext *ctx, const char *comm) { fstWriterSetAttrGeneric(ctx, comm, FST_MT_COMMENT, 0); } void fstWriterSetValueList(fstWriterContext *ctx, const char *vl) { fstWriterSetAttrGeneric(ctx, vl, FST_MT_VALUELIST, 0); } void fstWriterSetEnvVar(fstWriterContext *ctx, const char *envvar) { fstWriterSetAttrGeneric(ctx, envvar, FST_MT_ENVVAR, 0); } void fstWriterSetTimescale(fstWriterContext *xc, int ts) { if (xc) { fst_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(fstWriterContext *xc, const char *s) { 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(xc, seconds_exp); } } void fstWriterSetTimezero(fstWriterContext *xc, int64_t tim) { if (xc) { fst_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(fstWriterContext *xc, enum fstWriterPackType typ) { if (xc) { xc->fastpack = (typ != FST_WR_PT_ZLIB); xc->fourpack = (typ == FST_WR_PT_LZ4); } } void fstWriterSetRepackOnClose(fstWriterContext *xc, int enable) { if (xc) { xc->repack_on_close = (enable != 0); } } void fstWriterSetParallelMode(fstWriterContext *xc, int enable) { 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, FST_APIMESS "fstWriterSetParallelMode(), FST_WRITER_PARALLEL not enabled " "during compile, exiting.\n"); exit(255); } #endif } } void fstWriterSetDumpSizeLimit(fstWriterContext *xc, uint64_t numbytes) { if (xc) { xc->dump_size_limit = numbytes; } } int fstWriterGetDumpSizeLimitReached(fstWriterContext *xc) { if (xc) { return (xc->size_limit_locked != 0); } return (0); } int fstWriterGetFseekFailed(fstWriterContext *xc) { if (xc) { return (xc->fseek_failed != 0); } return (0); } static int fstWriterGetFlushContextPendingInternal(fstWriterContext *xc) { return (xc->vchg_siz >= xc->fst_break_size) || (xc->flush_context_pending); } int fstWriterGetFlushContextPending(fstWriterContext *xc) { return xc && !xc->is_initial_time && fstWriterGetFlushContextPendingInternal(xc); } /* * 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(fstWriterContext *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 << FST_SDT_SVT_SHIFT_COUNT) | (sdt & FST_SDT_ABS_MAX)); return (fstWriterCreateVar(ctx, vt, vd, len, nam, aliasHandle)); } fstHandle fstWriterCreateVar(fstWriterContext *xc, enum fstVarType vt, enum fstVarDir vd, uint32_t len, const char *nam, fstHandle aliasHandle) { unsigned int i; int nlen, is_real; if (xc && nam) { if (xc->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 = (unsigned char *)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; i < len; i++) { fputc('x', xc->curval_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(fstWriterContext *xc, enum fstScopeType scopetype, const char *scopename, const char *scopecomp) { 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(fstWriterContext *xc) { if (xc) { fputc(FST_ST_VCD_UPSCOPE, xc->hier_handle); xc->hier_file_len++; } } void fstWriterSetAttrBegin(fstWriterContext *xc, enum fstAttrType attrtype, int subtype, const char *attrname, uint64_t arg) { 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(fstWriterContext *xc) { if (xc) { fputc(FST_ST_GEN_ATTREND, xc->hier_handle); xc->hier_file_len++; } } fstEnumHandle fstWriterCreateEnumTable(fstWriterContext *xc, const char *name, uint32_t elem_count, unsigned int min_valbits, const char **literal_arr, const char **val_arr) { fstEnumHandle handle = 0; unsigned int *literal_lens = NULL; unsigned int *val_lens = NULL; int lit_len_tot = 0; int val_len_tot = 0; int name_len; char elem_count_buf[16]; int elem_count_len; int total_len; int pos = 0; char *attr_str = NULL; if (xc && name && literal_arr && val_arr && (elem_count != 0)) { uint32_t i; name_len = strlen(name); elem_count_len = snprintf(elem_count_buf, 16, "%" PRIu32, elem_count); literal_lens = (unsigned int *)calloc(elem_count, sizeof(unsigned int)); val_lens = (unsigned int *)calloc(elem_count, sizeof(unsigned int)); for (i = 0; i < elem_count; i++) { literal_lens[i] = strlen(literal_arr[i]); lit_len_tot += fstUtilityBinToEscConvertedLen((unsigned char *)literal_arr[i], literal_lens[i]); val_lens[i] = strlen(val_arr[i]); val_len_tot += fstUtilityBinToEscConvertedLen((unsigned char *)val_arr[i], val_lens[i]); if (min_valbits > 0) { if (val_lens[i] < min_valbits) { val_len_tot += (min_valbits - val_lens[i]); /* additional converted len is same for '0' character */ } } } total_len = name_len + 1 + elem_count_len + 1 + lit_len_tot + elem_count + val_len_tot + elem_count; attr_str = (char *)malloc(total_len); pos = 0; memcpy(attr_str + pos, name, name_len); pos += name_len; attr_str[pos++] = ' '; memcpy(attr_str + pos, elem_count_buf, elem_count_len); pos += elem_count_len; attr_str[pos++] = ' '; for (i = 0; i < elem_count; i++) { pos += fstUtilityBinToEsc((unsigned char *)attr_str + pos, (unsigned char *)literal_arr[i], literal_lens[i]); attr_str[pos++] = ' '; } for (i = 0; i < elem_count; i++) { if (min_valbits > 0) { if (val_lens[i] < min_valbits) { memset(attr_str + pos, '0', min_valbits - val_lens[i]); pos += (min_valbits - val_lens[i]); } } pos += fstUtilityBinToEsc((unsigned char *)attr_str + pos, (unsigned char *)val_arr[i], val_lens[i]); attr_str[pos++] = ' '; } attr_str[pos - 1] = 0; #ifdef FST_DEBUG fprintf(stderr, FST_APIMESS "fstWriterCreateEnumTable() total_len: %d, pos: %d\n", total_len, pos); fprintf(stderr, FST_APIMESS "*%s*\n", attr_str); #endif fstWriterSetAttrBegin(xc, FST_AT_MISC, FST_MT_ENUMTABLE, attr_str, handle = ++xc->max_enumhandle); free(attr_str); free(val_lens); free(literal_lens); } return (handle); } void fstWriterEmitEnumTableRef(fstWriterContext *xc, fstEnumHandle handle) { if (xc && handle) { fstWriterSetAttrBegin(xc, FST_AT_MISC, FST_MT_ENUMTABLE, NULL, handle); } } /* * value and time change emission */ void fstWriterEmitValueChange(fstWriterContext *xc, fstHandle handle, const void *val) { const unsigned char *buf = (const unsigned char *)val; uint32_t offs; int len; if (FST_LIKELY((xc) && (handle <= xc->maxhandle))) { uint32_t fpos; uint32_t *vm4ip; if (FST_UNLIKELY(!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 (FST_LIKELY(len)) /* len of zero = variable length, use fstWriterEmitVariableLengthValueChange */ { if (FST_LIKELY(!xc->is_initial_time)) { fpos = xc->vchg_siz; if (FST_UNLIKELY((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 = (unsigned char *)realloc(xc->vchg_mem, xc->vchg_alloc_siz); if (FST_UNLIKELY(!xc->vchg_mem)) { fprintf(stderr, FST_APIMESS "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; i < len; i++) { if (buf[i] != 'x') break; } if (i < len) return; } else { return; } } } memcpy(xc->curval_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 fstWriterEmitValueChange32(fstWriterContext *ctx, fstHandle handle, uint32_t bits, uint32_t val) { char buf[32]; char *s = buf; uint32_t i; for (i = 0; i < bits; ++i) { *s++ = '0' + ((val >> (bits - i - 1)) & 1); } fstWriterEmitValueChange(ctx, handle, buf); } void fstWriterEmitValueChange64(fstWriterContext *ctx, fstHandle handle, uint32_t bits, uint64_t val) { char buf[64]; char *s = buf; uint32_t i; for (i = 0; i < bits; ++i) { *s++ = '0' + ((val >> (bits - i - 1)) & 1); } fstWriterEmitValueChange(ctx, handle, buf); } void fstWriterEmitValueChangeVec32(fstWriterContext *xc, fstHandle handle, uint32_t bits, const uint32_t *val) { if (FST_UNLIKELY(bits <= 32)) { fstWriterEmitValueChange32(xc, handle, bits, val[0]); } else if (FST_LIKELY(xc)) { int bq = bits / 32; int br = bits & 31; int i; int w; uint32_t v; unsigned char *s; if (FST_UNLIKELY(bits > xc->outval_alloc_siz)) { xc->outval_alloc_siz = bits * 2 + 1; xc->outval_mem = (unsigned char *)realloc(xc->outval_mem, xc->outval_alloc_siz); if (FST_UNLIKELY(!xc->outval_mem)) { fprintf(stderr, FST_APIMESS "Could not realloc() in fstWriterEmitValueChangeVec32, exiting.\n"); exit(255); } } s = xc->outval_mem; { w = bq; v = val[w]; for (i = 0; i < br; ++i) { *s++ = '0' + ((v >> (br - i - 1)) & 1); } } for (w = bq - 1; w >= 0; --w) { v = val[w]; for (i = (32 - 4); i >= 0; i -= 4) { s[0] = '0' + ((v >> (i + 3)) & 1); s[1] = '0' + ((v >> (i + 2)) & 1); s[2] = '0' + ((v >> (i + 1)) & 1); s[3] = '0' + ((v >> (i + 0)) & 1); s += 4; } } fstWriterEmitValueChange(xc, handle, xc->outval_mem); } } void fstWriterEmitValueChangeVec64(fstWriterContext *xc, fstHandle handle, uint32_t bits, const uint64_t *val) { if (FST_UNLIKELY(bits <= 64)) { fstWriterEmitValueChange64(xc, handle, bits, val[0]); } else if (FST_LIKELY(xc)) { int bq = bits / 64; int br = bits & 63; int i; int w; uint32_t v; unsigned char *s; if (FST_UNLIKELY(bits > xc->outval_alloc_siz)) { xc->outval_alloc_siz = bits * 2 + 1; xc->outval_mem = (unsigned char *)realloc(xc->outval_mem, xc->outval_alloc_siz); if (FST_UNLIKELY(!xc->outval_mem)) { fprintf(stderr, FST_APIMESS "Could not realloc() in fstWriterEmitValueChangeVec64, exiting.\n"); exit(255); } } s = xc->outval_mem; { w = bq; v = val[w]; for (i = 0; i < br; ++i) { *s++ = '0' + ((v >> (br - i - 1)) & 1); } } for (w = bq - 1; w >= 0; --w) { v = val[w]; for (i = (64 - 4); i >= 0; i -= 4) { s[0] = '0' + ((v >> (i + 3)) & 1); s[1] = '0' + ((v >> (i + 2)) & 1); s[2] = '0' + ((v >> (i + 1)) & 1); s[3] = '0' + ((v >> (i + 0)) & 1); s += 4; } } fstWriterEmitValueChange(xc, handle, xc->outval_mem); } } void fstWriterEmitVariableLengthValueChange(fstWriterContext *xc, fstHandle handle, const void *val, uint32_t len) { const unsigned char *buf = (const unsigned char *)val; if (FST_LIKELY((xc) && (handle <= xc->maxhandle))) { uint32_t fpos; uint32_t *vm4ip; if (FST_UNLIKELY(!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 (FST_LIKELY(!vm4ip[1])) /* len of zero = variable length */ { fpos = xc->vchg_siz; if (FST_UNLIKELY((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 = (unsigned char *)realloc(xc->vchg_mem, xc->vchg_alloc_siz); if (FST_UNLIKELY(!xc->vchg_mem)) { fprintf(stderr, FST_APIMESS "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(fstWriterContext *xc, uint64_t tim) { unsigned int i; int skip = 0; if (xc) { if (FST_UNLIKELY(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; i < xc->maxhandle; 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 (fstWriterGetFlushContextPendingInternal(xc)) { 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(fstWriterContext *xc, int enable) { if (xc) { struct fstBlackoutChain *b = (struct fstBlackoutChain *)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; fst_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; fst_off_t *rvat_chain_table; uint32_t *rvat_chain_table_lengths; uint64_t rvat_vc_maxhandle; fst_off_t rvat_vc_start; uint32_t *rvat_sig_offs; int rvat_packtype; 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]; char *str_scope_attr; 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, fst_off_t offset, int whence) { int rc = fseeko(stream, offset, whence); if (rc < 0) { xc->fseek_failed = 1; #ifdef FST_DEBUG fprintf(stderr, FST_APIMESS "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, uint32_t len) /* TALOS-2023-1793: change len to unsigned */ { 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(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(fstReaderContext *xc) { if (xc) { return (xc->curr_flat_hier_nam ? xc->curr_flat_hier_nam : ""); } else { return (NULL); } } void *fstReaderGetCurrentScopeUserInfo(fstReaderContext *xc) { if (xc) { return (xc->curr_hier ? xc->curr_hier->user_info : NULL); } else { return (NULL); } } const char *fstReaderPopScope(fstReaderContext *xc) { 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(fstReaderContext *xc) { if (xc) { while (fstReaderPopScope(xc)) ; /* remove any already-built scoping info */ } } const char *fstReaderPushScope(fstReaderContext *xc, const char *nam, void *user_info) { if (xc) { struct fstCurrHier *ch = (struct fstCurrHier *)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 ? (char *)realloc(xc->curr_flat_hier_nam, len + 1) : (char *)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(fstReaderContext *xc) { if (xc && xc->curr_hier) { return (xc->curr_hier->len); } return (0); } int fstReaderGetFseekFailed(fstReaderContext *xc) { if (xc) { return (xc->fseek_failed != 0); } return (0); } /* * iter mask manipulation util functions */ int fstReaderGetFacProcessMask(fstReaderContext *xc, fstHandle facidx) { if (xc) { facidx--; if (facidx < xc->maxhandle) { int process_idx = facidx / 8; int process_bit = facidx & 7; return ((xc->process_mask[process_idx] & (1 << process_bit)) != 0); } } return (0); } void fstReaderSetFacProcessMask(fstReaderContext *xc, fstHandle facidx) { if (xc) { facidx--; if (facidx < xc->maxhandle) { int idx = facidx / 8; int bitpos = facidx & 7; xc->process_mask[idx] |= (1 << bitpos); } } } void fstReaderClrFacProcessMask(fstReaderContext *xc, fstHandle facidx) { if (xc) { facidx--; if (facidx < xc->maxhandle) { int idx = facidx / 8; int bitpos = facidx & 7; xc->process_mask[idx] &= (~(1 << bitpos)); } } } void fstReaderSetFacProcessMaskAll(fstReaderContext *xc) { if (xc) { memset(xc->process_mask, 0xff, (xc->maxhandle + 7) / 8); } } void fstReaderClrFacProcessMaskAll(fstReaderContext *xc) { if (xc) { memset(xc->process_mask, 0x00, (xc->maxhandle + 7) / 8); } } /* * various utility read/write functions */ signed char fstReaderGetTimescale(fstReaderContext *xc) { return (xc ? xc->timescale : 0); } uint64_t fstReaderGetStartTime(fstReaderContext *xc) { return (xc ? xc->start_time : 0); } uint64_t fstReaderGetEndTime(fstReaderContext *xc) { return (xc ? xc->end_time : 0); } uint64_t fstReaderGetMemoryUsedByWriter(fstReaderContext *xc) { return (xc ? xc->mem_used_by_writer : 0); } uint64_t fstReaderGetScopeCount(fstReaderContext *xc) { return (xc ? xc->scope_count : 0); } uint64_t fstReaderGetVarCount(fstReaderContext *xc) { return (xc ? xc->var_count : 0); } fstHandle fstReaderGetMaxHandle(fstReaderContext *xc) { return (xc ? xc->maxhandle : 0); } uint64_t fstReaderGetAliasCount(fstReaderContext *xc) { return (xc ? xc->num_alias : 0); } uint64_t fstReaderGetValueChangeSectionCount(fstReaderContext *xc) { return (xc ? xc->vc_section_count : 0); } int fstReaderGetDoubleEndianMatchState(fstReaderContext *xc) { return (xc ? xc->double_endian_match : 0); } const char *fstReaderGetVersionString(fstReaderContext *xc) { return (xc ? xc->version : NULL); } const char *fstReaderGetDateString(fstReaderContext *xc) { return (xc ? xc->date : NULL); } int fstReaderGetFileType(fstReaderContext *xc) { return (xc ? (int)xc->filetype : (int)FST_FT_VERILOG); } int64_t fstReaderGetTimezero(fstReaderContext *xc) { return (xc ? xc->timezero : 0); } uint32_t fstReaderGetNumberDumpActivityChanges(fstReaderContext *xc) { return (xc ? xc->num_blackouts : 0); } uint64_t fstReaderGetDumpActivityChangeTime(fstReaderContext *xc, uint32_t idx) { if (xc && (idx < xc->num_blackouts) && (xc->blackout_times)) { return (xc->blackout_times[idx]); } else { return (0); } } unsigned char fstReaderGetDumpActivityChangeValue(fstReaderContext *xc, uint32_t idx) { if (xc && (idx < xc->num_blackouts) && (xc->blackout_activity)) { return (xc->blackout_activity[idx]); } else { return (0); } } void fstReaderSetLimitTimeRange(fstReaderContext *xc, uint64_t start_time, uint64_t end_time) { if (xc) { xc->limit_range_valid = 1; xc->limit_range_start = start_time; xc->limit_range_end = end_time; } } void fstReaderSetUnlimitedTimeRange(fstReaderContext *xc) { if (xc) { xc->limit_range_valid = 0; } } void fstReaderSetVcdExtensions(fstReaderContext *xc, int enable) { if (xc) { xc->use_vcd_extensions = (enable != 0); } } void fstReaderIterBlocksSetNativeDoublesOnCallback(fstReaderContext *xc, int enable) { 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; int len = 0; /* zero is illegal for a value...it is assumed they start at one */ while (value && len < 14) { value--; ++len; *(pnt++) = (char)('!' + value % 94); value = value / 94; } return len; } static int fstReaderRecreateHierFile(struct fstReaderContext *xc) { int pass_status = 1; if (!xc->fh) { fst_off_t offs_cache = ftello(xc->f); int fnam_len = strlen(xc->filename) + 6 + 16 + 32 + 1; char *fnam = (char *)malloc(fnam_len); unsigned char *mem = (unsigned char *)malloc(FST_GZIO_LEN); fst_off_t hl, uclen; fst_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; } snprintf(fnam, fnam_len, "%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 = (unsigned char *)malloc(clen); unsigned char *lz4_ucmem = (unsigned char *)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 = (unsigned char *)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 = (unsigned char *)malloc(clen); unsigned char *lz4_ucmem = (unsigned char *)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; if (xc->fh) { fclose(xc->fh); xc->fh = NULL; /* needed in case .hier file is missing and there are no hier sections */ } } free(mem); free(fnam); fstReaderFseeko(xc, xc->f, offs_cache, SEEK_SET); } return (pass_status); } int fstReaderIterateHierRewind(fstReaderContext *xc) { 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(fstReaderContext *xc) { int isfeof; fstHandle alias; char *pnt; int ch; int unnamed_scope_idx = 0; 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); int cl; 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; cl = 0; while ((ch = fgetc(xc->fh))) { if (cl < FST_ID_NAM_SIZ) { pnt[cl++] = ch; } }; /* scopename */ if (!cl) { cl = snprintf(pnt, FST_ID_NAM_SIZ, "$unnamed_scope_%d", unnamed_scope_idx++); } pnt[cl] = 0; xc->hier.u.scope.name_length = cl; xc->hier.u.scope.component = pnt = xc->str_scope_comp; cl = 0; while ((ch = fgetc(xc->fh))) { if (cl < FST_ID_NAM_SIZ) { pnt[cl++] = ch; } }; /* scopecomp */ pnt[cl] = 0; xc->hier.u.scope.component_length = cl; 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); if (!xc->str_scope_attr) { xc->str_scope_attr = (char *)calloc(1, FST_ID_NAM_ATTR_SIZ + 1); } xc->hier.u.attr.name = pnt = xc->str_scope_attr; cl = 0; while ((ch = fgetc(xc->fh))) { if (cl < FST_ID_NAM_ATTR_SIZ) { pnt[cl++] = ch; } }; /* attrname */ pnt[cl] = 0; xc->hier.u.attr.name_length = cl; 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_attr, &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; cl = 0; while ((ch = fgetc(xc->fh))) { if (cl < FST_ID_NAM_SIZ) { pnt[cl++] = ch; } }; /* varname */ pnt[cl] = 0; xc->hier.u.var.name_length = cl; 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(fstReaderContext *xc, FILE *fv) { 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; int cl; int unnamed_scope_idx = 0; 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 = (char *)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; /* fallthrough */ case 0: time_dimension[0] = 0; break; case -1: time_scale = 100; time_dimension[0] = 'm'; break; case -2: time_scale = 10; /* fallthrough */ case -3: time_dimension[0] = 'm'; break; case -4: time_scale = 100; time_dimension[0] = 'u'; break; case -5: time_scale = 10; /* fallthrough */ case -6: time_dimension[0] = 'u'; break; case -10: time_scale = 100; time_dimension[0] = 'p'; break; case -11: time_scale = 10; /* fallthrough */ case -12: time_dimension[0] = 'p'; break; case -13: time_scale = 100; time_dimension[0] = 'f'; break; case -14: time_scale = 10; /* fallthrough */ case -15: time_dimension[0] = 'f'; break; case -16: time_scale = 100; time_dimension[0] = 'a'; break; case -17: time_scale = 10; /* fallthrough */ case -18: time_dimension[0] = 'a'; break; case -19: time_scale = 100; time_dimension[0] = 'z'; break; case -20: time_scale = 10; /* fallthrough */ case -21: time_dimension[0] = 'z'; break; case -7: time_scale = 100; time_dimension[0] = 'n'; break; case -8: time_scale = 10; /* fallthrough */ 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 = (uint32_t *)malloc(num_signal_dyn * sizeof(uint32_t)); free(xc->signal_typs); xc->signal_typs = (unsigned char *)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; cl = 0; while ((ch = fgetc(xc->fh))) { if (cl < FST_ID_NAM_ATTR_SIZ) { pnt[cl++] = ch; } }; /* scopename */ if (!cl) { cl = snprintf(pnt, FST_ID_NAM_SIZ, "$unnamed_scope_%d", unnamed_scope_idx++); } pnt[cl] = 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; cl = 0; while ((ch = fgetc(xc->fh))) { if (cl < FST_ID_NAM_ATTR_SIZ) { pnt[cl++] = ch; } }; /* attrname */ pnt[cl] = 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; cl = 0; while ((ch = fgetc(xc->fh))) { if (cl < FST_ID_NAM_ATTR_SIZ) { pnt[cl++] = ch; } }; /* varname */ pnt[cl] = 0; len = fstReaderVarint32(xc->fh); alias = fstReaderVarint32(xc->fh); if (!alias) { if (xc->maxhandle == num_signal_dyn) { num_signal_dyn *= 2; xc->signal_lens = (uint32_t *)realloc(xc->signal_lens, num_signal_dyn * sizeof(uint32_t)); xc->signal_typs = (unsigned char *)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 = (uint32_t *)realloc(xc->signal_lens, maxhandle_scanbuild * sizeof(uint32_t)); xc->signal_typs = (unsigned char *)realloc(xc->signal_typs, maxhandle_scanbuild * sizeof(unsigned char)); free(xc->process_mask); xc->process_mask = (unsigned char *)calloc(1, (maxhandle_scanbuild + 7) / 8); free(xc->temp_signal_value_buf); xc->temp_signal_value_buf = (unsigned char *)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) { fst_off_t blkpos = 0; fst_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; fst_off_t offpnt, uclen; char gz_membuf[FST_GZIO_LEN]; gzFile zhandle; int zfd; int flen = strlen(xc->filename); char *hf; int hf_len; seclen = fstReaderUint64(xc->f); uclen = fstReaderUint64(xc->f); if (!seclen) return (0); /* not finished compressing, this is a failed read */ hf_len = flen + 16 + 32 + 1; hf = (char *)calloc(1, hf_len); snprintf(hf, hf_len, "%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_UNBUFFERED_IO) setvbuf(fcomp, (char *)NULL, _IONBF, 0); /* keeps gzip from acting weird in tandem with fopen */ #endif #ifdef __MINGW32__ xc->filename_unpacked = hf; #else if (hf) { unlink(hf); free(hf); } #endif fstReaderFseeko(xc, xc->f, FST_ZWRAPPER_HDR_SIZE, SEEK_SET); #ifndef __MINGW32__ fflush(xc->f); #else /* Windows UCRT runtime library reads one byte ahead in the file even with buffering disabled and does not synchronise the file position after fseek. */ _lseek(fileno(xc->f), FST_ZWRAPPER_HDR_SIZE, SEEK_SET); #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 = (unsigned char *)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 = (unsigned char *)calloc(1, (xc->maxhandle + 7) / 8); if (clen != uclen) { unsigned char *cdata = (unsigned char *)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) { fprintf(stderr, FST_APIMESS "fstReaderInit(), geom uncompress rc = %d, exiting.\n", rc); exit(255); } free(cdata); } else { fstFread(ucdata, uclen, 1, xc->f); } free(xc->signal_lens); xc->signal_lens = (uint32_t *)malloc(sizeof(uint32_t) * xc->maxhandle); free(xc->signal_typs); xc->signal_typs = (unsigned char *)malloc(sizeof(unsigned char) * xc->maxhandle); for (i = 0; i < xc->maxhandle; 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 = (unsigned char *)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 = (uint64_t *)calloc(xc->num_blackouts, sizeof(uint64_t)); free(xc->blackout_activity); xc->blackout_activity = (unsigned char *)calloc(xc->num_blackouts, sizeof(unsigned char)); for (i = 0; i < xc->num_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); } fstReaderContext *fstReaderOpenForUtilitiesOnly(void) { fstReaderContext *xc = (fstReaderContext *)calloc(1, sizeof(fstReaderContext)); return (xc); } fstReaderContext *fstReaderOpen(const char *nam) { fstReaderContext *xc = (fstReaderContext *)calloc(1, sizeof(fstReaderContext)); if ((!nam) || (!(xc->f = fopen(nam, "rb")))) { free(xc); xc = NULL; } else { int flen = strlen(nam); char *hf = (char *)calloc(1, flen + 6); int rc; #if defined(FST_UNBUFFERED_IO) 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 if (!rc) { fstReaderClose(xc); xc = NULL; } } return (xc); } static void fstReaderDeallocateRvatData(fstReaderContext *xc) { 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(fstReaderContext *xc) { 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; free(xc->str_scope_attr); xc->str_scope_attr = 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(fstReaderContext *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(fstReaderContext *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; fst_off_t blkpos = 0; uint64_t seclen, beg_tim; uint64_t end_tim; uint64_t frame_uclen, frame_clen, frame_maxhandle, vc_maxhandle; fst_off_t vc_start; fst_off_t indx_pntr, indx_pos; fst_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] */ int dumpvars_state = 0; if (!xc) return (0); scatterptr = (uint32_t *)calloc(xc->maxhandle, sizeof(uint32_t)); headptr = (uint32_t *)calloc(xc->maxhandle, sizeof(uint32_t)); length_remaining = (uint32_t *)calloc(xc->maxhandle, sizeof(uint32_t)); if (fv) { #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; uint32_t tc_head_items = 0; 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, FST_APIMESS "<< 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); end_tim = fstReaderUint64(xc->f); if (xc->limit_range_valid) { if (end_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) + 66; /* add in potential fastlz overhead */ mem_for_traversal = (unsigned char *)malloc(mem_required_for_traversal); #ifdef FST_DEBUG fprintf(stderr, FST_APIMESS "sec: %u seclen: %d begtim: %d endtim: %d\n", secnum, (int)seclen, (int)beg_tim, (int)end_tim); fprintf(stderr, FST_APIMESS "mem_required_for_traversal: %d\n", (int)mem_required_for_traversal - 66); #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, FST_APIMESS "time 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 = (unsigned char *)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 - ((fst_off_t)tsec_clen), SEEK_CUR); if (tsec_uclen != tsec_clen) { cdata = (unsigned char *)malloc(tsec_clen); fstFread(cdata, tsec_clen, 1, xc->f); rc = uncompress(ucdata, &destlen, cdata, sourcelen); if (rc != Z_OK) { fprintf(stderr, FST_APIMESS "fstReaderIterBlocks2(), tsec uncompress rc = %d, exiting.\n", rc); exit(255); } free(cdata); } else { fstFread(ucdata, tsec_uclen, 1, xc->f); } free(time_table); if (sizeof(size_t) < sizeof(uint64_t)) { /* TALOS-2023-1792 for 32b overflow */ uint64_t chk_64 = tsec_nitems * sizeof(uint64_t); size_t chk_32 = ((size_t)tsec_nitems) * sizeof(uint64_t); if (chk_64 != chk_32) chk_report_abort("TALOS-2023-1792"); } else { uint64_t chk_64 = tsec_nitems * sizeof(uint64_t); if ((chk_64 / sizeof(uint64_t)) != tsec_nitems) { chk_report_abort("TALOS-2023-1792"); } } time_table = (uint64_t *)calloc(tsec_nitems, sizeof(uint64_t)); tpnt = ucdata; tpval = 0; for (ti = 0; ti < tsec_nitems; ti++) { int skiplen; uint64_t val = fstGetVarint64(tpnt, &skiplen); tpval = time_table[ti] = tpval + val; tpnt += skiplen; } tc_head_items = tsec_nitems /* scan-build */ ? tsec_nitems : 1; if (sizeof(size_t) < sizeof(uint64_t)) { /* TALOS-2023-1792 for 32b overflow */ uint64_t chk_64 = tc_head_items * sizeof(uint32_t); size_t chk_32 = ((size_t)tc_head_items) * sizeof(uint32_t); if (chk_64 != chk_32) chk_report_abort("TALOS-2023-1792"); } else { uint64_t chk_64 = tc_head_items * sizeof(uint32_t); if ((chk_64 / sizeof(uint32_t)) != tc_head_items) { chk_report_abort("TALOS-2023-1792"); } } tc_head = (uint32_t *)calloc(tc_head_items, sizeof(uint32_t)); free(ucdata); } fstReaderFseeko(xc, xc->f, 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 = (unsigned char *)malloc(frame_uclen); uint32_t sig_offs = 0; if (fv) { char wx_buf[32]; int wx_len; if (beg_tim) { if (dumpvars_state == 1) { wx_len = snprintf(wx_buf, 32, "$end\n"); fstWritex(xc, wx_buf, wx_len); dumpvars_state = 2; } wx_len = snprintf(wx_buf, 32, "#%" PRIu64 "\n", beg_tim); fstWritex(xc, wx_buf, wx_len); if (!dumpvars_state) { wx_len = snprintf(wx_buf, 32, "$dumpvars\n"); fstWritex(xc, wx_buf, wx_len); dumpvars_state = 1; } } if ((xc->num_blackouts) && (cur_blackout != xc->num_blackouts)) { if (beg_tim == xc->blackout_times[cur_blackout]) { wx_len = snprintf(wx_buf, 32, "$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 = (unsigned char *)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) { fprintf(stderr, FST_APIMESS "fstReaderIterBlocks2(), frame uncompress rc: %d, exiting.\n", rc); exit(255); } free(mc); } for (idx = 0; idx < frame_maxhandle; idx++) { int process_idx = idx / 8; int process_bit = idx & 7; if (xc->process_mask[process_idx] & (1 << process_bit)) { if (xc->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) { if (xc->signal_lens[idx] > xc->longest_signal_value_len) { chk_report_abort("TALOS-2023-1797"); } 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); if ((sig_offs + xc->signal_lens[idx]) > frame_uclen) { chk_report_abort("TALOS-2023-1793"); } 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]; } } snprintf((char *)xc->temp_signal_value_buf, xc->longest_signal_value_len + 1, "%.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 = snprintf(wx_buf, 64, "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, -((fst_off_t)frame_clen), SEEK_CUR); } } fstReaderFseeko(xc, xc->f, (fst_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, FST_APIMESS "frame_uclen: %d, frame_clen: %d, frame_maxhandle: %d\n", (int)frame_uclen, (int)frame_clen, (int)frame_maxhandle); fprintf(stderr, FST_APIMESS "vc_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, FST_APIMESS "indx_pos: %d (%d bytes)\n", (int)indx_pos, (int)chain_clen); #endif chain_cmem = (unsigned char *)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; if (!(vc_maxhandle + 1)) { chk_report_abort("TALOS-2023-1798"); } if (sizeof(size_t) < sizeof(uint64_t)) { /* TALOS-2023-1798 for 32b overflow */ uint64_t chk_64 = (vc_maxhandle + 1) * sizeof(fst_off_t); size_t chk_32 = ((size_t)(vc_maxhandle + 1)) * sizeof(fst_off_t); if (chk_64 != chk_32) chk_report_abort("TALOS-2023-1798"); } else { uint64_t chk_64 = (vc_maxhandle + 1) * sizeof(fst_off_t); if ((chk_64 / sizeof(fst_off_t)) != (vc_maxhandle + 1)) { chk_report_abort("TALOS-2023-1798"); } } chain_table = (fst_off_t *)calloc((vc_maxhandle + 1), sizeof(fst_off_t)); if (sizeof(size_t) < sizeof(uint64_t)) { /* TALOS-2023-1798 for 32b overflow */ uint64_t chk_64 = (vc_maxhandle + 1) * sizeof(uint32_t); size_t chk_32 = ((size_t)(vc_maxhandle + 1)) * sizeof(uint32_t); if (chk_64 != chk_32) chk_report_abort("TALOS-2023-1798"); } else { uint64_t chk_64 = (vc_maxhandle + 1) * sizeof(uint32_t); if ((chk_64 / sizeof(uint32_t)) != (vc_maxhandle + 1)) { chk_report_abort("TALOS-2023-1798"); } } chain_table_lengths = (uint32_t *)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; if ((idx + loopcnt - 1) > vc_maxhandle) /* TALOS-2023-1789 */ { chk_report_abort("TALOS-2023-1789"); } for (i = 0; i < loopcnt; i++) { chain_table[idx++] = 0; } } pnt += skiplen; } while (pnt != (chain_cmem + chain_clen)); } else { do { int skiplen; uint64_t val = fstGetVarint32(pnt, &skiplen); if (!val) { pnt += skiplen; val = fstGetVarint32(pnt, &skiplen); chain_table[idx] = 0; /* need to explicitly zero as calloc above might not run */ chain_table_lengths[idx] = -val; /* because during this loop iter would give stale data! */ idx++; } else if (val & 1) { pval = chain_table[idx] = pval + (val >> 1); if (idx) { chain_table_lengths[pidx] = pval - chain_table[pidx]; } pidx = idx++; } else { fstHandle loopcnt = val >> 1; if ((idx + loopcnt - 1) > vc_maxhandle) /* TALOS-2023-1789 */ { chk_report_abort("TALOS-2023-1789"); } for (i = 0; i < loopcnt; i++) { chain_table[idx++] = 0; } } pnt += skiplen; } while (pnt != (chain_cmem + chain_clen)); } chain_table[idx] = indx_pos - vc_start; chain_table_lengths[pidx] = chain_table[idx] - chain_table[pidx]; for (i = 0; i < idx; i++) { int32_t v32 = chain_table_lengths[i]; if ((v32 < 0) && (!chain_table[i])) { v32 = -v32; v32--; if (((uint32_t)v32) < i) /* sanity check */ { chain_table[i] = chain_table[v32]; chain_table_lengths[i] = chain_table_lengths[v32]; } } } #ifdef FST_DEBUG fprintf(stderr, FST_APIMESS "decompressed chain idx len: %" PRIu32 "\n", idx); #endif mc_mem_len = 16384; mc_mem = (unsigned char *)malloc(mc_mem_len); /* buffer for compressed reads */ /* check compressed VC data */ if (idx > xc->maxhandle) idx = xc->maxhandle; for (i = 0; i < idx; i++) { if (chain_table[i]) { int process_idx = i / 8; int process_bit = i & 7; if (xc->process_mask[process_idx] & (1 << process_bit)) { int rc = Z_OK; uint32_t val; uint32_t skiplen; uint32_t tdelta; fstReaderFseeko(xc, xc->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 (traversal_mem_offs >= mem_required_for_traversal) { chk_report_abort("TALOS-2023-1785"); } if (mc_mem_len < chain_table_lengths[i]) { free(mc_mem); mc_mem = (unsigned char *)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;j= mem_required_for_traversal) { chk_report_abort("TALOS-2023-1785"); } fstFread(mu, destlen, 1, xc->f); /* 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; } if (tdelta >= tc_head_items) { chk_report_abort("TALOS-2023-1791"); } 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; i < tsec_nitems; i++) { uint32_t tdelta; int skiplen, skiplen2; uint32_t vli; if (fv) { char wx_buf[32]; int wx_len; if (time_table[i] != previous_time) { if (xc->limit_range_valid) { if (time_table[i] > xc->limit_range_end) { break; } } if (dumpvars_state == 1) { wx_len = snprintf(wx_buf, 32, "$end\n"); fstWritex(xc, wx_buf, wx_len); dumpvars_state = 2; } wx_len = snprintf(wx_buf, 32, "#%" PRIu64 "\n", time_table[i]); fstWritex(xc, wx_buf, wx_len); if (!dumpvars_state) { wx_len = snprintf(wx_buf, 32, "$dumpvars\n"); fstWritex(xc, wx_buf, wx_len); dumpvars_state = 1; } if ((xc->num_blackouts) && (cur_blackout != xc->num_blackouts)) { if (time_table[i] == xc->blackout_times[cur_blackout]) { wx_len = snprintf(wx_buf, 32, "$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; if ((tdelta + i) >= tc_head_items) { chk_report_abort("TALOS-2023-1791"); } 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); { if (sizeof(size_t) < sizeof(uint64_t)) { /* TALOS-2023-1790 for 32b overflow */ uint64_t chk_64 = len * 4 + 1; size_t chk_32 = len * 4 + 1; if (chk_64 != chk_32) chk_report_abort("TALOS-2023-1790"); } unsigned char *vesc = (unsigned char *)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; if ((tdelta + i) >= tc_head_items) { chk_report_abort("TALOS-2023-1791"); } 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 (len > xc->longest_signal_value_len) { chk_report_abort("TALOS-2023-1797"); } if (!(vli & 1)) { int byte = 0; int bit; unsigned int j; for (j = 0; j < len; j++) { unsigned char ch; byte = j / 8; bit = 7 - (j & 7); ch = ((vdata[byte] >> 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'; uint64_t mem_required_for_traversal_chk = vdata - mem_for_traversal + len; fstWritex(xc, &ch_bp, 1); if (mem_required_for_traversal_chk > mem_required_for_traversal) { chk_report_abort("TALOS-2023-1793"); } 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]; } } snprintf((char *)xc->temp_signal_value_buf, xc->longest_signal_value_len + 1, "%.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 = snprintf(wx_buf, 32, "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; if ((tdelta + i) >= tc_head_items) { chk_report_abort("TALOS-2023-1791"); } 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(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]; } } snprintf((char *)buf, 32, "%.16g", d); /* this will write 18 bytes */ } } return (buf); } char *fstReaderGetValueFromHandleAtTime(fstReaderContext *xc, uint64_t tim, fstHandle facidx, char *buf) { fst_off_t blkpos = 0, prev_blkpos; uint64_t beg_tim, end_tim, beg_tim2, end_tim2; int sectype; #ifdef FST_DEBUG unsigned int secnum = 0; #endif 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 fst_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 = (uint32_t *)calloc(xc->maxhandle, sizeof(uint32_t)); for (i = 0; i < xc->maxhandle; 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)) { fst_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; #ifdef FST_DEBUG secnum++; #endif } 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, FST_APIMESS "rvat sec: %u seclen: %d begtim: %d endtim: %d\n", secnum, (int)seclen, (int)beg_tim, (int)end_tim); fprintf(stderr, FST_APIMESS "mem_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, FST_APIMESS "time section unc: %d, com: %d (%d items)\n", (int)tsec_uclen, (int)tsec_clen, (int)tsec_nitems); #endif ucdata = (unsigned char *)malloc(tsec_uclen); destlen = tsec_uclen; sourcelen = tsec_clen; fstReaderFseeko(xc, xc->f, -24 - ((fst_off_t)tsec_clen), SEEK_CUR); if (tsec_uclen != tsec_clen) { cdata = (unsigned char *)malloc(tsec_clen); fstFread(cdata, tsec_clen, 1, xc->f); rc = uncompress(ucdata, &destlen, cdata, sourcelen); if (rc != Z_OK) { fprintf(stderr, FST_APIMESS "fstReaderGetValueFromHandleAtTime(), tsec uncompress rc = %d, exiting.\n", rc); exit(255); } free(cdata); } else { fstFread(ucdata, tsec_uclen, 1, xc->f); } xc->rvat_time_table = (uint64_t *)calloc(tsec_nitems, sizeof(uint64_t)); tpnt = ucdata; tpval = 0; for (ti = 0; ti < tsec_nitems; ti++) { int skiplen; uint64_t val = fstGetVarint64(tpnt, &skiplen); tpval = xc->rvat_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 = (unsigned char *)malloc(frame_uclen); if (frame_uclen == frame_clen) { fstFread(xc->rvat_frame_data, frame_uclen, 1, xc->f); } else { unsigned char *mc = (unsigned char *)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) { fprintf(stderr, FST_APIMESS "fstReaderGetValueFromHandleAtTime(), frame decompress rc: %d, exiting.\n", rc); exit(255); } free(mc); } xc->rvat_vc_maxhandle = fstReaderVarint64(xc->f); xc->rvat_vc_start = ftello(xc->f); /* points to '!' character */ xc->rvat_packtype = fgetc(xc->f); #ifdef FST_DEBUG fprintf(stderr, FST_APIMESS "frame_uclen: %d, frame_clen: %d, frame_maxhandle: %d\n", (int)frame_uclen, (int)frame_clen, (int)xc->rvat_frame_maxhandle); fprintf(stderr, FST_APIMESS "vc_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, FST_APIMESS "indx_pos: %d (%d bytes)\n", (int)indx_pos, (int)chain_clen); #endif chain_cmem = (unsigned char *)malloc(chain_clen); fstReaderFseeko(xc, xc->f, indx_pos, SEEK_SET); fstFread(chain_cmem, chain_clen, 1, xc->f); xc->rvat_chain_table = (fst_off_t *)calloc((xc->rvat_vc_maxhandle + 1), sizeof(fst_off_t)); xc->rvat_chain_table_lengths = (uint32_t *)calloc((xc->rvat_vc_maxhandle + 1), sizeof(uint32_t)); 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 = xc->rvat_chain_table[idx] = pval + shval; if (idx) { xc->rvat_chain_table_lengths[pidx] = pval - xc->rvat_chain_table[pidx]; } pidx = idx++; } else if (shval < 0) { xc->rvat_chain_table[idx] = 0; /* need to explicitly zero as calloc above might not run */ xc->rvat_chain_table_lengths[idx] = prev_alias = shval; /* because during this loop iter would give stale data! */ idx++; } else { xc->rvat_chain_table[idx] = 0; /* need to explicitly zero as calloc above might not run */ xc->rvat_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 < loopcnt; i++) { xc->rvat_chain_table[idx++] = 0; } } pnt += skiplen; } while (pnt != (chain_cmem + chain_clen)); } else { 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; i < loopcnt; i++) { xc->rvat_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; i < idx; i++) { int32_t v32 = xc->rvat_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, FST_APIMESS "decompressed 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 = (unsigned char *)malloc(xc->rvat_chain_len); unsigned char *mc = (unsigned char *)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 = Z_OK; fstFread(mc, xc->rvat_chain_table_lengths[facidx], 1, xc->f); switch (xc->rvat_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; } free(mc); if (rc != Z_OK) { fprintf(stderr, FST_APIMESS "fstReaderGetValueFromHandleAtTime(), rvat decompress clen: %d " "(rc=%d), exiting.\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 = (unsigned char *)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 (i < xc->rvat_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 (i < xc->rvat_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; j < xc->signal_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]; } } snprintf(buf, 32, "r%.16g", d); /* this will write 19 bytes */ return (buf); } } else { return (fstExtractRvatDataFromFrame(xc, facidx, buf)); } } } /* return(NULL); */ } /***********************/ /*** ***/ /*** 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); /* fallthrough */ case 10: c += ((uint32_t)k[9] << 16); /* fallthrough */ case 9: c += ((uint32_t)k[8] << 8); /* fallthrough */ /* the first byte of c is reserved for the length */ case 8: b += ((uint32_t)k[7] << 24); /* fallthrough */ case 7: b += ((uint32_t)k[6] << 16); /* fallthrough */ case 6: b += ((uint32_t)k[5] << 8); /* fallthrough */ case 5: b += k[4]; /* fallthrough */ case 4: a += ((uint32_t)k[3] << 24); /* fallthrough */ case 3: a += ((uint32_t)k[2] << 16); /* fallthrough */ case 2: a += ((uint32_t)k[1] << 8); /* fallthrough */ 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 = (struct collchain_t **)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 = (struct collchain_t *)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; } } /**********************************************************************/ /************************/ /*** ***/ /*** utility function ***/ /*** ***/ /************************/ int fstUtilityBinToEscConvertedLen(const unsigned char *s, int len) { const unsigned char *src = s; int dlen = 0; int i; for (i = 0; i < len; i++) { switch (src[i]) { case '\a': /* fallthrough */ case '\b': /* fallthrough */ case '\f': /* fallthrough */ case '\n': /* fallthrough */ case '\r': /* fallthrough */ case '\t': /* fallthrough */ case '\v': /* fallthrough */ case '\'': /* fallthrough */ case '\"': /* fallthrough */ case '\\': /* fallthrough */ case '\?': dlen += 2; break; default: if ((src[i] > ' ') && (src[i] <= '~')) /* no white spaces in output */ { dlen++; } else { dlen += 4; } break; } } return (dlen); } int fstUtilityBinToEsc(unsigned char *d, const unsigned char *s, int len) { const unsigned char *src = s; unsigned char *dst = d; unsigned char val; int i; for (i = 0; i < len; i++) { switch (src[i]) { case '\a': *(dst++) = '\\'; *(dst++) = 'a'; break; case '\b': *(dst++) = '\\'; *(dst++) = 'b'; break; case '\f': *(dst++) = '\\'; *(dst++) = 'f'; break; case '\n': *(dst++) = '\\'; *(dst++) = 'n'; break; case '\r': *(dst++) = '\\'; *(dst++) = 'r'; break; case '\t': *(dst++) = '\\'; *(dst++) = 't'; break; case '\v': *(dst++) = '\\'; *(dst++) = 'v'; break; case '\'': *(dst++) = '\\'; *(dst++) = '\''; break; case '\"': *(dst++) = '\\'; *(dst++) = '\"'; break; case '\\': *(dst++) = '\\'; *(dst++) = '\\'; break; case '\?': *(dst++) = '\\'; *(dst++) = '\?'; break; default: if ((src[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 < len; i++) { if (src[i] != '\\') { *(dst++) = src[i]; } else { switch (src[++i]) { case 'a': *(dst++) = '\a'; break; case 'b': *(dst++) = '\b'; break; case 'f': *(dst++) = '\f'; break; case 'n': *(dst++) = '\n'; break; case 'r': *(dst++) = '\r'; break; case 't': *(dst++) = '\t'; break; case 'v': *(dst++) = '\v'; break; case '\'': *(dst++) = '\''; break; case '\"': *(dst++) = '\"'; break; case '\\': *(dst++) = '\\'; break; case '\?': *(dst++) = '\?'; break; case 'x': val[0] = toupper(src[++i]); val[1] = toupper(src[++i]); val[0] = ((val[0] >= '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); } struct fstETab *fstUtilityExtractEnumTableFromString(const char *s) { struct fstETab *et = NULL; int num_spaces = 0; int i; int newlen; if (s) { const char *csp = strchr(s, ' '); int cnt = atoi(csp + 1); for (;;) { csp = strchr(csp + 1, ' '); if (csp) { num_spaces++; } else { break; } } if (num_spaces == (2 * cnt)) { char *sp, *sp2; et = (struct fstETab *)calloc(1, sizeof(struct fstETab)); et->elem_count = cnt; et->name = strdup(s); et->literal_arr = (char **)calloc(cnt, sizeof(char *)); et->val_arr = (char **)calloc(cnt, sizeof(char *)); sp = strchr(et->name, ' '); *sp = 0; sp = strchr(sp + 1, ' '); for (i = 0; i < cnt; i++) { sp2 = strchr(sp + 1, ' '); *(char *)sp2 = 0; et->literal_arr[i] = sp + 1; sp = sp2; newlen = fstUtilityEscToBin(NULL, (unsigned char *)et->literal_arr[i], strlen(et->literal_arr[i])); et->literal_arr[i][newlen] = 0; } for (i = 0; i < cnt; i++) { sp2 = strchr(sp + 1, ' '); if (sp2) { *sp2 = 0; } et->val_arr[i] = sp + 1; sp = sp2; newlen = fstUtilityEscToBin(NULL, (unsigned char *)et->val_arr[i], strlen(et->val_arr[i])); et->val_arr[i][newlen] = 0; } } } return (et); } void fstUtilityFreeEnumTable(struct fstETab *etab) { if (etab) { free(etab->literal_arr); free(etab->val_arr); free(etab->name); free(etab); } } gtkwave-gtk3-3.3.125/src/helpers/fst/fastlz.h0000664000175000017500000000714515047725113020226 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. SPDX-License-Identifier: MIT */ #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-gtk3-3.3.125/src/helpers/fst/Makefile.am0000664000175000017500000000036015047725113020576 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 fst_win_unistd.h EXTRA_DIST= block_format.txt CMakeLists.txt gtkwave-gtk3-3.3.125/src/helpers/fst/lz4.c0000664000175000017500000034160315047725113017427 0ustar bybellbybell/* LZ4 - Fast LZ compression algorithm Copyright (C) 2011-2023, 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 homepage : http://www.lz4.org - LZ4 source repository : https://github.com/lz4/lz4 */ /*-************************************ * Tuning parameters **************************************/ /* * LZ4_HEAPMODE : * Select how stateless compression functions like `LZ4_compress_default()` * allocate memory for their hash table, * in memory stack (0:default, fastest), or in memory heap (1:requires malloc()). */ #ifndef LZ4_HEAPMODE # define LZ4_HEAPMODE 0 #endif /* * LZ4_ACCELERATION_DEFAULT : * Select "acceleration" for LZ4_compress_fast() when parameter value <= 0 */ #define LZ4_ACCELERATION_DEFAULT 1 /* * LZ4_ACCELERATION_MAX : * Any "acceleration" value higher than this threshold * get treated as LZ4_ACCELERATION_MAX instead (fix #876) */ #define LZ4_ACCELERATION_MAX 65537 /*-************************************ * CPU Feature Detection **************************************/ /* LZ4_FORCE_MEMORY_ACCESS * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. * The below switch allow to select different access method for improved performance. * Method 0 (default) : use `memcpy()`. Safe and portable. * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable). * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. * Method 2 : direct access. This method is portable but violate C standard. * It can generate buggy code on targets which assembly generation depends on alignment. * But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6) * See https://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details. * Prefer these methods in priority order (0 > 1 > 2) */ #ifndef LZ4_FORCE_MEMORY_ACCESS /* can be defined externally */ # if defined(__GNUC__) && \ ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) \ || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) # define LZ4_FORCE_MEMORY_ACCESS 2 # elif (defined(__INTEL_COMPILER) && !defined(_WIN32)) || defined(__GNUC__) || defined(_MSC_VER) # define LZ4_FORCE_MEMORY_ACCESS 1 # endif #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 WinCE doesn't support Hardware bit count */ # undef LZ4_FORCE_SW_BITCOUNT /* avoid double def */ # define LZ4_FORCE_SW_BITCOUNT #endif /*-************************************ * Dependency **************************************/ /* * LZ4_SRC_INCLUDED: * Amalgamation flag, whether lz4.c is included */ #ifndef LZ4_SRC_INCLUDED # define LZ4_SRC_INCLUDED 1 #endif #ifndef LZ4_DISABLE_DEPRECATE_WARNINGS # define LZ4_DISABLE_DEPRECATE_WARNINGS /* due to LZ4_decompress_safe_withPrefix64k */ #endif #ifndef LZ4_STATIC_LINKING_ONLY # define LZ4_STATIC_LINKING_ONLY #endif #include "lz4.h" /* see also "memory routines" below */ /*-************************************ * Compiler Options **************************************/ #if defined(_MSC_VER) && (_MSC_VER >= 1400) /* Visual Studio 2005+ */ # include /* only present in VS2005+ */ # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ # pragma warning(disable : 6237) /* disable: C6237: conditional expression is always 0 */ #endif /* _MSC_VER */ #ifndef LZ4_FORCE_INLINE # ifdef _MSC_VER /* Visual Studio */ # define LZ4_FORCE_INLINE static __forceinline # else # if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ # ifdef __GNUC__ # define LZ4_FORCE_INLINE static inline __attribute__((always_inline)) # else # define LZ4_FORCE_INLINE static inline # endif # else # define LZ4_FORCE_INLINE static # endif /* __STDC_VERSION__ */ # endif /* _MSC_VER */ #endif /* LZ4_FORCE_INLINE */ /* LZ4_FORCE_O2 and LZ4_FORCE_INLINE * gcc on ppc64le generates an unrolled SIMDized loop for LZ4_wildCopy8, * together with a simple 8-byte copy loop as a fall-back path. * However, this optimization hurts the decompression speed by >30%, * because the execution does not go to the optimized loop * for typical compressible data, and all of the preamble checks * before going to the fall-back path become useless overhead. * This optimization happens only with the -O3 flag, and -O2 generates * a simple 8-byte copy loop. * With gcc on ppc64le, all of the LZ4_decompress_* and LZ4_wildCopy8 * functions are annotated with __attribute__((optimize("O2"))), * and also LZ4_wildCopy8 is forcibly inlined, so that the O2 attribute * of LZ4_wildCopy8 does not affect the compression speed. */ #if defined(__PPC64__) && defined(__LITTLE_ENDIAN__) && defined(__GNUC__) && !defined(__clang__) # define LZ4_FORCE_O2 __attribute__((optimize("O2"))) # undef LZ4_FORCE_INLINE # define LZ4_FORCE_INLINE static __inline __attribute__((optimize("O2"),always_inline)) #else # define LZ4_FORCE_O2 #endif #if (defined(__GNUC__) && (__GNUC__ >= 3)) || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) || defined(__clang__) # define expect(expr,value) (__builtin_expect ((expr),(value)) ) #else # define expect(expr,value) (expr) #endif #ifndef likely #define likely(expr) expect((expr) != 0, 1) #endif #ifndef unlikely #define unlikely(expr) expect((expr) != 0, 0) #endif /* Should the alignment test prove unreliable, for some reason, * it can be disabled by setting LZ4_ALIGN_TEST to 0 */ #ifndef LZ4_ALIGN_TEST /* can be externally provided */ # define LZ4_ALIGN_TEST 1 #endif /*-************************************ * Memory routines **************************************/ /*! LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION : * Disable relatively high-level LZ4/HC functions that use dynamic memory * allocation functions (malloc(), calloc(), free()). * * Note that this is a compile-time switch. And since it disables * public/stable LZ4 v1 API functions, we don't recommend using this * symbol to generate a library for distribution. * * The following public functions are removed when this symbol is defined. * - lz4 : LZ4_createStream, LZ4_freeStream, * LZ4_createStreamDecode, LZ4_freeStreamDecode, LZ4_create (deprecated) * - lz4hc : LZ4_createStreamHC, LZ4_freeStreamHC, * LZ4_createHC (deprecated), LZ4_freeHC (deprecated) * - lz4frame, lz4file : All LZ4F_* functions */ #if defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) # define ALLOC(s) lz4_error_memory_allocation_is_disabled # define ALLOC_AND_ZERO(s) lz4_error_memory_allocation_is_disabled # define FREEMEM(p) lz4_error_memory_allocation_is_disabled #elif defined(LZ4_USER_MEMORY_FUNCTIONS) /* memory management functions can be customized by user project. * Below functions must exist somewhere in the Project * and be available at link time */ void* LZ4_malloc(size_t s); void* LZ4_calloc(size_t n, size_t s); void LZ4_free(void* p); # define ALLOC(s) LZ4_malloc(s) # define ALLOC_AND_ZERO(s) LZ4_calloc(1,s) # define FREEMEM(p) LZ4_free(p) #else # include /* malloc, calloc, free */ # define ALLOC(s) malloc(s) # define ALLOC_AND_ZERO(s) calloc(1,s) # define FREEMEM(p) free(p) #endif #if ! LZ4_FREESTANDING # include /* memset, memcpy */ #endif #if !defined(LZ4_memset) # define LZ4_memset(p,v,s) memset((p),(v),(s)) #endif #define MEM_INIT(p,v,s) LZ4_memset((p),(v),(s)) /*-************************************ * Common Constants **************************************/ #define MINMATCH 4 #define WILDCOPYLENGTH 8 #define LASTLITERALS 5 /* see ../doc/lz4_Block_format.md#parsing-restrictions */ #define MFLIMIT 12 /* see ../doc/lz4_Block_format.md#parsing-restrictions */ #define MATCH_SAFEGUARD_DISTANCE ((2*WILDCOPYLENGTH) - MINMATCH) /* ensure it's possible to write 2 x wildcopyLength without overflowing output buffer */ #define FASTLOOP_SAFE_DISTANCE 64 static const int LZ4_minLength = (MFLIMIT+1); #define KB *(1 <<10) #define MB *(1 <<20) #define GB *(1U<<30) #define LZ4_DISTANCE_ABSOLUTE_MAX 65535 #if (LZ4_DISTANCE_MAX > LZ4_DISTANCE_ABSOLUTE_MAX) /* max supported by LZ4 format */ # error "LZ4_DISTANCE_MAX is too big : must be <= 65535" #endif #define ML_BITS 4 #define ML_MASK ((1U<=1) # include #else # ifndef assert # define assert(condition) ((void)0) # endif #endif #define LZ4_STATIC_ASSERT(c) { enum { LZ4_static_assert = 1/(int)(!!(c)) }; } /* use after variable declarations */ #if defined(LZ4_DEBUG) && (LZ4_DEBUG>=2) # include static int g_debuglog_enable = 1; # define DEBUGLOG(l, ...) { \ if ((g_debuglog_enable) && (l<=LZ4_DEBUG)) { \ fprintf(stderr, __FILE__ " %i: ", __LINE__); \ fprintf(stderr, __VA_ARGS__); \ fprintf(stderr, " \n"); \ } } #else # define DEBUGLOG(l, ...) {} /* disabled */ #endif static int LZ4_isAligned(const void* ptr, size_t alignment) { return ((size_t)ptr & (alignment -1)) == 0; } /*-************************************ * Types **************************************/ #include #if defined(__cplusplus) || (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; typedef uintptr_t uptrval; #else # if UINT_MAX != 4294967295UL # error "LZ4 code (when not C++ or C99) assumes that sizeof(int) == 4" # endif typedef unsigned char BYTE; typedef unsigned short U16; typedef unsigned int U32; typedef signed int S32; typedef unsigned long long U64; typedef size_t uptrval; /* generally true, except OpenVMS-64 */ #endif #if defined(__x86_64__) typedef U64 reg_t; /* 64-bits in x32 mode */ #else typedef size_t reg_t; /* 32-bits in x32 mode */ #endif typedef enum { notLimited = 0, limitedOutput = 1, fillOutput = 2 } limitedOutput_directive; /*-************************************ * Reading and writing into memory **************************************/ /** * LZ4 relies on memcpy with a constant size being inlined. In freestanding * environments, the compiler can't assume the implementation of memcpy() is * standard compliant, so it can't apply its specialized memcpy() inlining * logic. When possible, use __builtin_memcpy() to tell the compiler to analyze * memcpy() as if it were standard compliant, so it can inline it in freestanding * environments. This is needed when decompressing the Linux Kernel, for example. */ #if !defined(LZ4_memcpy) # if defined(__GNUC__) && (__GNUC__ >= 4) # define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size) # else # define LZ4_memcpy(dst, src, size) memcpy(dst, src, size) # endif #endif #if !defined(LZ4_memmove) # if defined(__GNUC__) && (__GNUC__ >= 4) # define LZ4_memmove __builtin_memmove # else # define LZ4_memmove memmove # endif #endif static unsigned LZ4_isLittleEndian(void) { const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */ return one.c[0]; } #if defined(__GNUC__) || defined(__INTEL_COMPILER) #define LZ4_PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__)) #elif defined(_MSC_VER) #define LZ4_PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop)) #endif #if defined(LZ4_FORCE_MEMORY_ACCESS) && (LZ4_FORCE_MEMORY_ACCESS==2) /* lie to the compiler about data alignment; use with caution */ static U16 LZ4_read16(const void* memPtr) { return *(const U16*) memPtr; } static U32 LZ4_read32(const void* memPtr) { return *(const U32*) memPtr; } static reg_t LZ4_read_ARCH(const void* memPtr) { return *(const reg_t*) memPtr; } static void LZ4_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; } static void LZ4_write32(void* memPtr, U32 value) { *(U32*)memPtr = value; } #elif defined(LZ4_FORCE_MEMORY_ACCESS) && (LZ4_FORCE_MEMORY_ACCESS==1) /* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ /* currently only defined for gcc and icc */ LZ4_PACK(typedef struct { U16 u16; }) LZ4_unalign16; LZ4_PACK(typedef struct { U32 u32; }) LZ4_unalign32; LZ4_PACK(typedef struct { reg_t uArch; }) LZ4_unalignST; static U16 LZ4_read16(const void* ptr) { return ((const LZ4_unalign16*)ptr)->u16; } static U32 LZ4_read32(const void* ptr) { return ((const LZ4_unalign32*)ptr)->u32; } static reg_t LZ4_read_ARCH(const void* ptr) { return ((const LZ4_unalignST*)ptr)->uArch; } static void LZ4_write16(void* memPtr, U16 value) { ((LZ4_unalign16*)memPtr)->u16 = value; } static void LZ4_write32(void* memPtr, U32 value) { ((LZ4_unalign32*)memPtr)->u32 = value; } #else /* safe and portable access using memcpy() */ static U16 LZ4_read16(const void* memPtr) { U16 val; LZ4_memcpy(&val, memPtr, sizeof(val)); return val; } static U32 LZ4_read32(const void* memPtr) { U32 val; LZ4_memcpy(&val, memPtr, sizeof(val)); return val; } static reg_t LZ4_read_ARCH(const void* memPtr) { reg_t val; LZ4_memcpy(&val, memPtr, sizeof(val)); return val; } static void LZ4_write16(void* memPtr, U16 value) { LZ4_memcpy(memPtr, &value, sizeof(value)); } static void LZ4_write32(void* memPtr, U32 value) { LZ4_memcpy(memPtr, &value, sizeof(value)); } #endif /* LZ4_FORCE_MEMORY_ACCESS */ static U16 LZ4_readLE16(const void* memPtr) { if (LZ4_isLittleEndian()) { return LZ4_read16(memPtr); } else { const BYTE* p = (const BYTE*)memPtr; return (U16)((U16)p[0] + (p[1]<<8)); } } #ifdef LZ4_STATIC_LINKING_ONLY_ENDIANNESS_INDEPENDENT_OUTPUT static U32 LZ4_readLE32(const void* memPtr) { if (LZ4_isLittleEndian()) { return LZ4_read32(memPtr); } else { const BYTE* p = (const BYTE*)memPtr; return (U32)p[0] + (p[1]<<8) + (p[2]<<16) + (p[3]<<24); } } #endif static void LZ4_writeLE16(void* memPtr, U16 value) { if (LZ4_isLittleEndian()) { LZ4_write16(memPtr, value); } else { BYTE* p = (BYTE*)memPtr; p[0] = (BYTE) value; p[1] = (BYTE)(value>>8); } } /* customized variant of memcpy, which can overwrite up to 8 bytes beyond dstEnd */ LZ4_FORCE_INLINE void LZ4_wildCopy8(void* dstPtr, const void* srcPtr, void* dstEnd) { BYTE* d = (BYTE*)dstPtr; const BYTE* s = (const BYTE*)srcPtr; BYTE* const e = (BYTE*)dstEnd; do { LZ4_memcpy(d,s,8); d+=8; s+=8; } while (d= 16. */ LZ4_FORCE_INLINE void LZ4_wildCopy32(void* dstPtr, const void* srcPtr, void* dstEnd) { BYTE* d = (BYTE*)dstPtr; const BYTE* s = (const BYTE*)srcPtr; BYTE* const e = (BYTE*)dstEnd; do { LZ4_memcpy(d,s,16); LZ4_memcpy(d+16,s+16,16); d+=32; s+=32; } while (d= dstPtr + MINMATCH * - there is at least 8 bytes available to write after dstEnd */ LZ4_FORCE_INLINE void LZ4_memcpy_using_offset(BYTE* dstPtr, const BYTE* srcPtr, BYTE* dstEnd, const size_t offset) { BYTE v[8]; assert(dstEnd >= dstPtr + MINMATCH); switch(offset) { case 1: MEM_INIT(v, *srcPtr, 8); break; case 2: LZ4_memcpy(v, srcPtr, 2); LZ4_memcpy(&v[2], srcPtr, 2); #if defined(_MSC_VER) && (_MSC_VER <= 1937) /* MSVC 2022 ver 17.7 or earlier */ # pragma warning(push) # pragma warning(disable : 6385) /* warning C6385: Reading invalid data from 'v'. */ #endif LZ4_memcpy(&v[4], v, 4); #if defined(_MSC_VER) && (_MSC_VER <= 1937) /* MSVC 2022 ver 17.7 or earlier */ # pragma warning(pop) #endif break; case 4: LZ4_memcpy(v, srcPtr, 4); LZ4_memcpy(&v[4], srcPtr, 4); break; default: LZ4_memcpy_using_offset_base(dstPtr, srcPtr, dstEnd, offset); return; } LZ4_memcpy(dstPtr, v, 8); dstPtr += 8; while (dstPtr < dstEnd) { LZ4_memcpy(dstPtr, v, 8); dstPtr += 8; } } #endif /*-************************************ * Common functions **************************************/ static unsigned LZ4_NbCommonBytes (reg_t val) { assert(val != 0); if (LZ4_isLittleEndian()) { if (sizeof(val) == 8) { # if defined(_MSC_VER) && (_MSC_VER >= 1800) && (defined(_M_AMD64) && !defined(_M_ARM64EC)) && !defined(LZ4_FORCE_SW_BITCOUNT) /*-************************************************************************************************* * ARM64EC is a Microsoft-designed ARM64 ABI compatible with AMD64 applications on ARM64 Windows 11. * The ARM64EC ABI does not support AVX/AVX2/AVX512 instructions, nor their relevant intrinsics * including _tzcnt_u64. Therefore, we need to neuter the _tzcnt_u64 code path for ARM64EC. ****************************************************************************************************/ # if defined(__clang__) && (__clang_major__ < 10) /* Avoid undefined clang-cl intrinsics issue. * See https://github.com/lz4/lz4/pull/1017 for details. */ return (unsigned)__builtin_ia32_tzcnt_u64(val) >> 3; # else /* x64 CPUS without BMI support interpret `TZCNT` as `REP BSF` */ return (unsigned)_tzcnt_u64(val) >> 3; # endif # elif defined(_MSC_VER) && defined(_WIN64) && !defined(LZ4_FORCE_SW_BITCOUNT) unsigned long r = 0; _BitScanForward64(&r, (U64)val); return (unsigned)r >> 3; # elif (defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 3) || \ ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))))) && \ !defined(LZ4_FORCE_SW_BITCOUNT) return (unsigned)__builtin_ctzll((U64)val) >> 3; # else const U64 m = 0x0101010101010101ULL; val ^= val - 1; return (unsigned)(((U64)((val & (m - 1)) * m)) >> 56); # endif } else /* 32 bits */ { # if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(LZ4_FORCE_SW_BITCOUNT) unsigned long r; _BitScanForward(&r, (U32)val); return (unsigned)r >> 3; # elif (defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 3) || \ ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))))) && \ !defined(__TINYC__) && !defined(LZ4_FORCE_SW_BITCOUNT) return (unsigned)__builtin_ctz((U32)val) >> 3; # else const U32 m = 0x01010101; return (unsigned)((((val - 1) ^ val) & (m - 1)) * m) >> 24; # endif } } else /* Big Endian CPU */ { if (sizeof(val)==8) { # if (defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 3) || \ ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))))) && \ !defined(__TINYC__) && !defined(LZ4_FORCE_SW_BITCOUNT) return (unsigned)__builtin_clzll((U64)val) >> 3; # else #if 1 /* this method is probably faster, * but adds a 128 bytes lookup table */ static const unsigned char ctz7_tab[128] = { 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, }; U64 const mask = 0x0101010101010101ULL; U64 const t = (((val >> 8) - mask) | val) & mask; return ctz7_tab[(t * 0x0080402010080402ULL) >> 57]; #else /* this method doesn't consume memory space like the previous one, * but it contains several branches, * that may end up slowing execution */ static const U32 by32 = sizeof(val)*4; /* 32 on 64 bits (goal), 16 on 32 bits. Just to avoid some static analyzer complaining about shift by 32 on 32-bits target. Note that this code path is never triggered in 32-bits mode. */ unsigned r; if (!(val>>by32)) { r=4; } else { r=0; val>>=by32; } if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; } r += (!val); return r; #endif # endif } else /* 32 bits */ { # if (defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 3) || \ ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))))) && \ !defined(LZ4_FORCE_SW_BITCOUNT) return (unsigned)__builtin_clz((U32)val) >> 3; # else val >>= 8; val = ((((val + 0x00FFFF00) | 0x00FFFFFF) + val) | (val + 0x00FF0000)) >> 24; return (unsigned)val ^ 3; # endif } } } #define STEPSIZE sizeof(reg_t) LZ4_FORCE_INLINE unsigned LZ4_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* pInLimit) { const BYTE* const pStart = pIn; if (likely(pIn < pInLimit-(STEPSIZE-1))) { reg_t const diff = LZ4_read_ARCH(pMatch) ^ LZ4_read_ARCH(pIn); if (!diff) { pIn+=STEPSIZE; pMatch+=STEPSIZE; } else { return LZ4_NbCommonBytes(diff); } } while (likely(pIn < pInLimit-(STEPSIZE-1))) { reg_t const diff = LZ4_read_ARCH(pMatch) ^ LZ4_read_ARCH(pIn); if (!diff) { pIn+=STEPSIZE; pMatch+=STEPSIZE; continue; } pIn += LZ4_NbCommonBytes(diff); return (unsigned)(pIn - pStart); } if ((STEPSIZE==8) && (pIn<(pInLimit-3)) && (LZ4_read32(pMatch) == LZ4_read32(pIn))) { pIn+=4; pMatch+=4; } if ((pIn<(pInLimit-1)) && (LZ4_read16(pMatch) == LZ4_read16(pIn))) { pIn+=2; pMatch+=2; } if ((pIn compression run slower on incompressible data */ /*-************************************ * Local Structures and types **************************************/ typedef enum { clearedTable = 0, byPtr, byU32, byU16 } tableType_t; /** * This enum distinguishes several different modes of accessing previous * content in the stream. * * - noDict : There is no preceding content. * - withPrefix64k : Table entries up to ctx->dictSize before the current blob * blob being compressed are valid and refer to the preceding * content (of length ctx->dictSize), which is available * contiguously preceding in memory the content currently * being compressed. * - usingExtDict : Like withPrefix64k, but the preceding content is somewhere * else in memory, starting at ctx->dictionary with length * ctx->dictSize. * - usingDictCtx : Everything concerning the preceding content is * in a separate context, pointed to by ctx->dictCtx. * ctx->dictionary, ctx->dictSize, and table entries * in the current context that refer to positions * preceding the beginning of the current compression are * ignored. Instead, ctx->dictCtx->dictionary and ctx->dictCtx * ->dictSize describe the location and size of the preceding * content, and matches are found by looking in the ctx * ->dictCtx->hashTable. */ typedef enum { noDict = 0, withPrefix64k, usingExtDict, usingDictCtx } dict_directive; typedef enum { noDictIssue = 0, dictSmall } dictIssue_directive; /*-************************************ * Local Utils **************************************/ int LZ4_versionNumber (void) { return LZ4_VERSION_NUMBER; } const char* LZ4_versionString(void) { return LZ4_VERSION_STRING; } int LZ4_compressBound(int isize) { return LZ4_COMPRESSBOUND(isize); } int LZ4_sizeofState(void) { return sizeof(LZ4_stream_t); } /*-**************************************** * Internal Definitions, used only in Tests *******************************************/ #if defined (__cplusplus) extern "C" { #endif int LZ4_compress_forceExtDict (LZ4_stream_t* LZ4_dict, const char* source, char* dest, int srcSize); int LZ4_decompress_safe_forceExtDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const void* dictStart, size_t dictSize); int LZ4_decompress_safe_partial_forceExtDict(const char* source, char* dest, int compressedSize, int targetOutputSize, int dstCapacity, const void* dictStart, size_t dictSize); #if defined (__cplusplus) } #endif /*-****************************** * Compression functions ********************************/ LZ4_FORCE_INLINE U32 LZ4_hash4(U32 sequence, tableType_t const tableType) { if (tableType == byU16) return ((sequence * 2654435761U) >> ((MINMATCH*8)-(LZ4_HASHLOG+1))); else return ((sequence * 2654435761U) >> ((MINMATCH*8)-LZ4_HASHLOG)); } LZ4_FORCE_INLINE U32 LZ4_hash5(U64 sequence, tableType_t const tableType) { const U32 hashLog = (tableType == byU16) ? LZ4_HASHLOG+1 : LZ4_HASHLOG; if (LZ4_isLittleEndian()) { const U64 prime5bytes = 889523592379ULL; return (U32)(((sequence << 24) * prime5bytes) >> (64 - hashLog)); } else { const U64 prime8bytes = 11400714785074694791ULL; return (U32)(((sequence >> 24) * prime8bytes) >> (64 - hashLog)); } } LZ4_FORCE_INLINE U32 LZ4_hashPosition(const void* const p, tableType_t const tableType) { if ((sizeof(reg_t)==8) && (tableType != byU16)) return LZ4_hash5(LZ4_read_ARCH(p), tableType); #ifdef LZ4_STATIC_LINKING_ONLY_ENDIANNESS_INDEPENDENT_OUTPUT return LZ4_hash4(LZ4_readLE32(p), tableType); #else return LZ4_hash4(LZ4_read32(p), tableType); #endif } LZ4_FORCE_INLINE void LZ4_clearHash(U32 h, void* tableBase, tableType_t const tableType) { switch (tableType) { default: /* fallthrough */ case clearedTable: { /* illegal! */ assert(0); return; } case byPtr: { const BYTE** hashTable = (const BYTE**)tableBase; hashTable[h] = NULL; return; } case byU32: { U32* hashTable = (U32*) tableBase; hashTable[h] = 0; return; } case byU16: { U16* hashTable = (U16*) tableBase; hashTable[h] = 0; return; } } } LZ4_FORCE_INLINE void LZ4_putIndexOnHash(U32 idx, U32 h, void* tableBase, tableType_t const tableType) { switch (tableType) { default: /* fallthrough */ case clearedTable: /* fallthrough */ case byPtr: { /* illegal! */ assert(0); return; } case byU32: { U32* hashTable = (U32*) tableBase; hashTable[h] = idx; return; } case byU16: { U16* hashTable = (U16*) tableBase; assert(idx < 65536); hashTable[h] = (U16)idx; return; } } } /* LZ4_putPosition*() : only used in byPtr mode */ LZ4_FORCE_INLINE void LZ4_putPositionOnHash(const BYTE* p, U32 h, void* tableBase, tableType_t const tableType) { const BYTE** const hashTable = (const BYTE**)tableBase; assert(tableType == byPtr); (void)tableType; hashTable[h] = p; } LZ4_FORCE_INLINE void LZ4_putPosition(const BYTE* p, void* tableBase, tableType_t tableType) { U32 const h = LZ4_hashPosition(p, tableType); LZ4_putPositionOnHash(p, h, tableBase, tableType); } /* LZ4_getIndexOnHash() : * Index of match position registered in hash table. * hash position must be calculated by using base+index, or dictBase+index. * Assumption 1 : only valid if tableType == byU32 or byU16. * Assumption 2 : h is presumed valid (within limits of hash table) */ LZ4_FORCE_INLINE U32 LZ4_getIndexOnHash(U32 h, const void* tableBase, tableType_t tableType) { LZ4_STATIC_ASSERT(LZ4_MEMORY_USAGE > 2); if (tableType == byU32) { const U32* const hashTable = (const U32*) tableBase; assert(h < (1U << (LZ4_MEMORY_USAGE-2))); return hashTable[h]; } if (tableType == byU16) { const U16* const hashTable = (const U16*) tableBase; assert(h < (1U << (LZ4_MEMORY_USAGE-1))); return hashTable[h]; } assert(0); return 0; /* forbidden case */ } static const BYTE* LZ4_getPositionOnHash(U32 h, const void* tableBase, tableType_t tableType) { assert(tableType == byPtr); (void)tableType; { const BYTE* const* hashTable = (const BYTE* const*) tableBase; return hashTable[h]; } } LZ4_FORCE_INLINE const BYTE* LZ4_getPosition(const BYTE* p, const void* tableBase, tableType_t tableType) { U32 const h = LZ4_hashPosition(p, tableType); return LZ4_getPositionOnHash(h, tableBase, tableType); } LZ4_FORCE_INLINE void LZ4_prepareTable(LZ4_stream_t_internal* const cctx, const int inputSize, const tableType_t tableType) { /* If the table hasn't been used, it's guaranteed to be zeroed out, and is * therefore safe to use no matter what mode we're in. Otherwise, we figure * out if it's safe to leave as is or whether it needs to be reset. */ if ((tableType_t)cctx->tableType != clearedTable) { assert(inputSize >= 0); if ((tableType_t)cctx->tableType != tableType || ((tableType == byU16) && cctx->currentOffset + (unsigned)inputSize >= 0xFFFFU) || ((tableType == byU32) && cctx->currentOffset > 1 GB) || tableType == byPtr || inputSize >= 4 KB) { DEBUGLOG(4, "LZ4_prepareTable: Resetting table in %p", cctx); MEM_INIT(cctx->hashTable, 0, LZ4_HASHTABLESIZE); cctx->currentOffset = 0; cctx->tableType = (U32)clearedTable; } else { DEBUGLOG(4, "LZ4_prepareTable: Re-use hash table (no reset)"); } } /* Adding a gap, so all previous entries are > LZ4_DISTANCE_MAX back, * is faster than compressing without a gap. * However, compressing with currentOffset == 0 is faster still, * so we preserve that case. */ if (cctx->currentOffset != 0 && tableType == byU32) { DEBUGLOG(5, "LZ4_prepareTable: adding 64KB to currentOffset"); cctx->currentOffset += 64 KB; } /* Finally, clear history */ cctx->dictCtx = NULL; cctx->dictionary = NULL; cctx->dictSize = 0; } /** LZ4_compress_generic_validated() : * inlined, to ensure branches are decided at compilation time. * The following conditions are presumed already validated: * - source != NULL * - inputSize > 0 */ LZ4_FORCE_INLINE int LZ4_compress_generic_validated( LZ4_stream_t_internal* const cctx, const char* const source, char* const dest, const int inputSize, int* inputConsumed, /* only written when outputDirective == fillOutput */ const int maxOutputSize, const limitedOutput_directive outputDirective, const tableType_t tableType, const dict_directive dictDirective, const dictIssue_directive dictIssue, const int acceleration) { int result; const BYTE* ip = (const BYTE*)source; U32 const startIndex = cctx->currentOffset; const BYTE* base = (const BYTE*)source - startIndex; const BYTE* lowLimit; const LZ4_stream_t_internal* dictCtx = (const LZ4_stream_t_internal*) cctx->dictCtx; const BYTE* const dictionary = dictDirective == usingDictCtx ? dictCtx->dictionary : cctx->dictionary; const U32 dictSize = dictDirective == usingDictCtx ? dictCtx->dictSize : cctx->dictSize; const U32 dictDelta = (dictDirective == usingDictCtx) ? startIndex - dictCtx->currentOffset : 0; /* make indexes in dictCtx comparable with indexes in current context */ int const maybe_extMem = (dictDirective == usingExtDict) || (dictDirective == usingDictCtx); U32 const prefixIdxLimit = startIndex - dictSize; /* used when dictDirective == dictSmall */ const BYTE* const dictEnd = dictionary ? dictionary + dictSize : dictionary; const BYTE* anchor = (const BYTE*) source; const BYTE* const iend = ip + inputSize; const BYTE* const mflimitPlusOne = iend - MFLIMIT + 1; const BYTE* const matchlimit = iend - LASTLITERALS; /* the dictCtx currentOffset is indexed on the start of the dictionary, * while a dictionary in the current context precedes the currentOffset */ const BYTE* dictBase = (dictionary == NULL) ? NULL : (dictDirective == usingDictCtx) ? dictionary + dictSize - dictCtx->currentOffset : dictionary + dictSize - startIndex; BYTE* op = (BYTE*) dest; BYTE* const olimit = op + maxOutputSize; U32 offset = 0; U32 forwardH; DEBUGLOG(5, "LZ4_compress_generic_validated: srcSize=%i, tableType=%u", inputSize, tableType); assert(ip != NULL); if (tableType == byU16) assert(inputSize= 1); lowLimit = (const BYTE*)source - (dictDirective == withPrefix64k ? dictSize : 0); /* Update context state */ if (dictDirective == usingDictCtx) { /* Subsequent linked blocks can't use the dictionary. */ /* Instead, they use the block we just compressed. */ cctx->dictCtx = NULL; cctx->dictSize = (U32)inputSize; } else { cctx->dictSize += (U32)inputSize; } cctx->currentOffset += (U32)inputSize; cctx->tableType = (U32)tableType; if (inputSizehashTable, byPtr); } else { LZ4_putIndexOnHash(startIndex, h, cctx->hashTable, tableType); } } ip++; forwardH = LZ4_hashPosition(ip, tableType); /* Main Loop */ for ( ; ; ) { const BYTE* match; BYTE* token; const BYTE* filledIp; /* Find a match */ if (tableType == byPtr) { const BYTE* forwardIp = ip; int step = 1; int searchMatchNb = acceleration << LZ4_skipTrigger; do { U32 const h = forwardH; ip = forwardIp; forwardIp += step; step = (searchMatchNb++ >> LZ4_skipTrigger); if (unlikely(forwardIp > mflimitPlusOne)) goto _last_literals; assert(ip < mflimitPlusOne); match = LZ4_getPositionOnHash(h, cctx->hashTable, tableType); forwardH = LZ4_hashPosition(forwardIp, tableType); LZ4_putPositionOnHash(ip, h, cctx->hashTable, tableType); } while ( (match+LZ4_DISTANCE_MAX < ip) || (LZ4_read32(match) != LZ4_read32(ip)) ); } else { /* byU32, byU16 */ const BYTE* forwardIp = ip; int step = 1; int searchMatchNb = acceleration << LZ4_skipTrigger; do { U32 const h = forwardH; U32 const current = (U32)(forwardIp - base); U32 matchIndex = LZ4_getIndexOnHash(h, cctx->hashTable, tableType); assert(matchIndex <= current); assert(forwardIp - base < (ptrdiff_t)(2 GB - 1)); ip = forwardIp; forwardIp += step; step = (searchMatchNb++ >> LZ4_skipTrigger); if (unlikely(forwardIp > mflimitPlusOne)) goto _last_literals; assert(ip < mflimitPlusOne); if (dictDirective == usingDictCtx) { if (matchIndex < startIndex) { /* there was no match, try the dictionary */ assert(tableType == byU32); matchIndex = LZ4_getIndexOnHash(h, dictCtx->hashTable, byU32); match = dictBase + matchIndex; matchIndex += dictDelta; /* make dictCtx index comparable with current context */ lowLimit = dictionary; } else { match = base + matchIndex; lowLimit = (const BYTE*)source; } } else if (dictDirective == usingExtDict) { if (matchIndex < startIndex) { DEBUGLOG(7, "extDict candidate: matchIndex=%5u < startIndex=%5u", matchIndex, startIndex); assert(startIndex - matchIndex >= MINMATCH); assert(dictBase); match = dictBase + matchIndex; lowLimit = dictionary; } else { match = base + matchIndex; lowLimit = (const BYTE*)source; } } else { /* single continuous memory segment */ match = base + matchIndex; } forwardH = LZ4_hashPosition(forwardIp, tableType); LZ4_putIndexOnHash(current, h, cctx->hashTable, tableType); DEBUGLOG(7, "candidate at pos=%u (offset=%u \n", matchIndex, current - matchIndex); if ((dictIssue == dictSmall) && (matchIndex < prefixIdxLimit)) { continue; } /* match outside of valid area */ assert(matchIndex < current); if ( ((tableType != byU16) || (LZ4_DISTANCE_MAX < LZ4_DISTANCE_ABSOLUTE_MAX)) && (matchIndex+LZ4_DISTANCE_MAX < current)) { continue; } /* too far */ assert((current - matchIndex) <= LZ4_DISTANCE_MAX); /* match now expected within distance */ if (LZ4_read32(match) == LZ4_read32(ip)) { if (maybe_extMem) offset = current - matchIndex; break; /* match found */ } } while(1); } /* Catch up */ filledIp = ip; assert(ip > anchor); /* this is always true as ip has been advanced before entering the main loop */ if ((match > lowLimit) && unlikely(ip[-1] == match[-1])) { do { ip--; match--; } while (((ip > anchor) & (match > lowLimit)) && (unlikely(ip[-1] == match[-1]))); } /* Encode Literals */ { unsigned const litLength = (unsigned)(ip - anchor); token = op++; if ((outputDirective == limitedOutput) && /* Check output buffer overflow */ (unlikely(op + litLength + (2 + 1 + LASTLITERALS) + (litLength/255) > olimit)) ) { return 0; /* cannot compress within `dst` budget. Stored indexes in hash table are nonetheless fine */ } if ((outputDirective == fillOutput) && (unlikely(op + (litLength+240)/255 /* litlen */ + litLength /* literals */ + 2 /* offset */ + 1 /* token */ + MFLIMIT - MINMATCH /* min last literals so last match is <= end - MFLIMIT */ > olimit))) { op--; goto _last_literals; } 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< olimit)) { /* the match was too close to the end, rewind and go to last literals */ op = token; goto _last_literals; } /* Encode Offset */ if (maybe_extMem) { /* static test */ DEBUGLOG(6, " with offset=%u (ext if > %i)", offset, (int)(ip - (const BYTE*)source)); assert(offset <= LZ4_DISTANCE_MAX && offset > 0); LZ4_writeLE16(op, (U16)offset); op+=2; } else { DEBUGLOG(6, " with offset=%u (same segment)", (U32)(ip - match)); assert(ip-match <= LZ4_DISTANCE_MAX); LZ4_writeLE16(op, (U16)(ip - match)); op+=2; } /* Encode MatchLength */ { unsigned matchCode; if ( (dictDirective==usingExtDict || dictDirective==usingDictCtx) && (lowLimit==dictionary) /* match within extDict */ ) { const BYTE* limit = ip + (dictEnd-match); assert(dictEnd > match); if (limit > matchlimit) limit = matchlimit; matchCode = LZ4_count(ip+MINMATCH, match+MINMATCH, limit); ip += (size_t)matchCode + MINMATCH; if (ip==limit) { unsigned const more = LZ4_count(limit, (const BYTE*)source, matchlimit); matchCode += more; ip += more; } DEBUGLOG(6, " with matchLength=%u starting in extDict", matchCode+MINMATCH); } else { matchCode = LZ4_count(ip+MINMATCH, match+MINMATCH, matchlimit); ip += (size_t)matchCode + MINMATCH; DEBUGLOG(6, " with matchLength=%u", matchCode+MINMATCH); } if ((outputDirective) && /* Check output buffer overflow */ (unlikely(op + (1 + LASTLITERALS) + (matchCode+240)/255 > olimit)) ) { if (outputDirective == fillOutput) { /* Match description too long : reduce it */ U32 newMatchCode = 15 /* in token */ - 1 /* to avoid needing a zero byte */ + ((U32)(olimit - op) - 1 - LASTLITERALS) * 255; ip -= matchCode - newMatchCode; assert(newMatchCode < matchCode); matchCode = newMatchCode; if (unlikely(ip <= filledIp)) { /* We have already filled up to filledIp so if ip ends up less than filledIp * we have positions in the hash table beyond the current position. This is * a problem if we reuse the hash table. So we have to remove these positions * from the hash table. */ const BYTE* ptr; DEBUGLOG(5, "Clearing %u positions", (U32)(filledIp - ip)); for (ptr = ip; ptr <= filledIp; ++ptr) { U32 const h = LZ4_hashPosition(ptr, tableType); LZ4_clearHash(h, cctx->hashTable, tableType); } } } else { assert(outputDirective == limitedOutput); return 0; /* cannot compress within `dst` budget. Stored indexes in hash table are nonetheless fine */ } } if (matchCode >= ML_MASK) { *token += ML_MASK; matchCode -= ML_MASK; LZ4_write32(op, 0xFFFFFFFF); while (matchCode >= 4*255) { op+=4; LZ4_write32(op, 0xFFFFFFFF); matchCode -= 4*255; } op += matchCode / 255; *op++ = (BYTE)(matchCode % 255); } else *token += (BYTE)(matchCode); } /* Ensure we have enough space for the last literals. */ assert(!(outputDirective == fillOutput && op + 1 + LASTLITERALS > olimit)); anchor = ip; /* Test end of chunk */ if (ip >= mflimitPlusOne) break; /* Fill table */ { U32 const h = LZ4_hashPosition(ip-2, tableType); if (tableType == byPtr) { LZ4_putPositionOnHash(ip-2, h, cctx->hashTable, byPtr); } else { U32 const idx = (U32)((ip-2) - base); LZ4_putIndexOnHash(idx, h, cctx->hashTable, tableType); } } /* Test next position */ if (tableType == byPtr) { match = LZ4_getPosition(ip, cctx->hashTable, tableType); LZ4_putPosition(ip, cctx->hashTable, tableType); if ( (match+LZ4_DISTANCE_MAX >= ip) && (LZ4_read32(match) == LZ4_read32(ip)) ) { token=op++; *token=0; goto _next_match; } } else { /* byU32, byU16 */ U32 const h = LZ4_hashPosition(ip, tableType); U32 const current = (U32)(ip-base); U32 matchIndex = LZ4_getIndexOnHash(h, cctx->hashTable, tableType); assert(matchIndex < current); if (dictDirective == usingDictCtx) { if (matchIndex < startIndex) { /* there was no match, try the dictionary */ assert(tableType == byU32); matchIndex = LZ4_getIndexOnHash(h, dictCtx->hashTable, byU32); match = dictBase + matchIndex; lowLimit = dictionary; /* required for match length counter */ matchIndex += dictDelta; } else { match = base + matchIndex; lowLimit = (const BYTE*)source; /* required for match length counter */ } } else if (dictDirective==usingExtDict) { if (matchIndex < startIndex) { assert(dictBase); match = dictBase + matchIndex; lowLimit = dictionary; /* required for match length counter */ } else { match = base + matchIndex; lowLimit = (const BYTE*)source; /* required for match length counter */ } } else { /* single memory segment */ match = base + matchIndex; } LZ4_putIndexOnHash(current, h, cctx->hashTable, tableType); assert(matchIndex < current); if ( ((dictIssue==dictSmall) ? (matchIndex >= prefixIdxLimit) : 1) && (((tableType==byU16) && (LZ4_DISTANCE_MAX == LZ4_DISTANCE_ABSOLUTE_MAX)) ? 1 : (matchIndex+LZ4_DISTANCE_MAX >= current)) && (LZ4_read32(match) == LZ4_read32(ip)) ) { token=op++; *token=0; if (maybe_extMem) offset = current - matchIndex; DEBUGLOG(6, "seq.start:%i, literals=%u, match.start:%i", (int)(anchor-(const BYTE*)source), 0, (int)(ip-(const BYTE*)source)); goto _next_match; } } /* Prepare next loop */ forwardH = LZ4_hashPosition(++ip, tableType); } _last_literals: /* Encode Last Literals */ { size_t lastRun = (size_t)(iend - anchor); if ( (outputDirective) && /* Check output buffer overflow */ (op + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > olimit)) { if (outputDirective == fillOutput) { /* adapt lastRun to fill 'dst' */ assert(olimit >= op); lastRun = (size_t)(olimit-op) - 1/*token*/; lastRun -= (lastRun + 256 - RUN_MASK) / 256; /*additional length tokens*/ } else { assert(outputDirective == limitedOutput); return 0; /* cannot compress within `dst` budget. Stored indexes in hash table are nonetheless fine */ } } DEBUGLOG(6, "Final literal run : %i literals", (int)lastRun); if (lastRun >= RUN_MASK) { size_t accumulator = lastRun - RUN_MASK; *op++ = RUN_MASK << ML_BITS; for(; accumulator >= 255 ; accumulator-=255) *op++ = 255; *op++ = (BYTE) accumulator; } else { *op++ = (BYTE)(lastRun< 0); DEBUGLOG(5, "LZ4_compress_generic: compressed %i bytes into %i bytes", inputSize, result); return result; } /** LZ4_compress_generic() : * inlined, to ensure branches are decided at compilation time; * takes care of src == (NULL, 0) * and forward the rest to LZ4_compress_generic_validated */ LZ4_FORCE_INLINE int LZ4_compress_generic( LZ4_stream_t_internal* const cctx, const char* const src, char* const dst, const int srcSize, int *inputConsumed, /* only written when outputDirective == fillOutput */ const int dstCapacity, const limitedOutput_directive outputDirective, const tableType_t tableType, const dict_directive dictDirective, const dictIssue_directive dictIssue, const int acceleration) { DEBUGLOG(5, "LZ4_compress_generic: srcSize=%i, dstCapacity=%i", srcSize, dstCapacity); if ((U32)srcSize > (U32)LZ4_MAX_INPUT_SIZE) { return 0; } /* Unsupported srcSize, too large (or negative) */ if (srcSize == 0) { /* src == NULL supported if srcSize == 0 */ if (outputDirective != notLimited && dstCapacity <= 0) return 0; /* no output, can't write anything */ DEBUGLOG(5, "Generating an empty block"); assert(outputDirective == notLimited || dstCapacity >= 1); assert(dst != NULL); dst[0] = 0; if (outputDirective == fillOutput) { assert (inputConsumed != NULL); *inputConsumed = 0; } return 1; } assert(src != NULL); return LZ4_compress_generic_validated(cctx, src, dst, srcSize, inputConsumed, /* only written into if outputDirective == fillOutput */ dstCapacity, outputDirective, tableType, dictDirective, dictIssue, acceleration); } int LZ4_compress_fast_extState(void* state, const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration) { LZ4_stream_t_internal* const ctx = & LZ4_initStream(state, sizeof(LZ4_stream_t)) -> internal_donotuse; assert(ctx != NULL); if (acceleration < 1) acceleration = LZ4_ACCELERATION_DEFAULT; if (acceleration > LZ4_ACCELERATION_MAX) acceleration = LZ4_ACCELERATION_MAX; if (maxOutputSize >= LZ4_compressBound(inputSize)) { if (inputSize < LZ4_64Klimit) { return LZ4_compress_generic(ctx, source, dest, inputSize, NULL, 0, notLimited, byU16, noDict, noDictIssue, acceleration); } else { const tableType_t tableType = ((sizeof(void*)==4) && ((uptrval)source > LZ4_DISTANCE_MAX)) ? byPtr : byU32; return LZ4_compress_generic(ctx, source, dest, inputSize, NULL, 0, notLimited, tableType, noDict, noDictIssue, acceleration); } } else { if (inputSize < LZ4_64Klimit) { return LZ4_compress_generic(ctx, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration); } else { const tableType_t tableType = ((sizeof(void*)==4) && ((uptrval)source > LZ4_DISTANCE_MAX)) ? byPtr : byU32; return LZ4_compress_generic(ctx, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, noDict, noDictIssue, acceleration); } } } /** * LZ4_compress_fast_extState_fastReset() : * A variant of LZ4_compress_fast_extState(). * * Using this variant avoids an expensive initialization step. It is only safe * to call if the state buffer is known to be correctly initialized already * (see comment in lz4.h on LZ4_resetStream_fast() for a definition of * "correctly initialized"). */ int LZ4_compress_fast_extState_fastReset(void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration) { LZ4_stream_t_internal* const ctx = &((LZ4_stream_t*)state)->internal_donotuse; if (acceleration < 1) acceleration = LZ4_ACCELERATION_DEFAULT; if (acceleration > LZ4_ACCELERATION_MAX) acceleration = LZ4_ACCELERATION_MAX; assert(ctx != NULL); if (dstCapacity >= LZ4_compressBound(srcSize)) { if (srcSize < LZ4_64Klimit) { const tableType_t tableType = byU16; LZ4_prepareTable(ctx, srcSize, tableType); if (ctx->currentOffset) { return LZ4_compress_generic(ctx, src, dst, srcSize, NULL, 0, notLimited, tableType, noDict, dictSmall, acceleration); } else { return LZ4_compress_generic(ctx, src, dst, srcSize, NULL, 0, notLimited, tableType, noDict, noDictIssue, acceleration); } } else { const tableType_t tableType = ((sizeof(void*)==4) && ((uptrval)src > LZ4_DISTANCE_MAX)) ? byPtr : byU32; LZ4_prepareTable(ctx, srcSize, tableType); return LZ4_compress_generic(ctx, src, dst, srcSize, NULL, 0, notLimited, tableType, noDict, noDictIssue, acceleration); } } else { if (srcSize < LZ4_64Klimit) { const tableType_t tableType = byU16; LZ4_prepareTable(ctx, srcSize, tableType); if (ctx->currentOffset) { return LZ4_compress_generic(ctx, src, dst, srcSize, NULL, dstCapacity, limitedOutput, tableType, noDict, dictSmall, acceleration); } else { return LZ4_compress_generic(ctx, src, dst, srcSize, NULL, dstCapacity, limitedOutput, tableType, noDict, noDictIssue, acceleration); } } else { const tableType_t tableType = ((sizeof(void*)==4) && ((uptrval)src > LZ4_DISTANCE_MAX)) ? byPtr : byU32; LZ4_prepareTable(ctx, srcSize, tableType); return LZ4_compress_generic(ctx, src, dst, srcSize, NULL, dstCapacity, limitedOutput, tableType, noDict, noDictIssue, acceleration); } } } int LZ4_compress_fast(const char* src, char* dest, int srcSize, int dstCapacity, int acceleration) { int result; #if (LZ4_HEAPMODE) LZ4_stream_t* const ctxPtr = (LZ4_stream_t*)ALLOC(sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */ if (ctxPtr == NULL) return 0; #else LZ4_stream_t ctx; LZ4_stream_t* const ctxPtr = &ctx; #endif result = LZ4_compress_fast_extState(ctxPtr, src, dest, srcSize, dstCapacity, acceleration); #if (LZ4_HEAPMODE) FREEMEM(ctxPtr); #endif return result; } int LZ4_compress_default(const char* src, char* dst, int srcSize, int dstCapacity) { return LZ4_compress_fast(src, dst, srcSize, dstCapacity, 1); } /* Note!: This function leaves the stream in an unclean/broken state! * It is not safe to subsequently use the same state with a _fastReset() or * _continue() call without resetting it. */ static int LZ4_compress_destSize_extState_internal(LZ4_stream_t* state, const char* src, char* dst, int* srcSizePtr, int targetDstSize, int acceleration) { void* const s = LZ4_initStream(state, sizeof (*state)); assert(s != NULL); (void)s; if (targetDstSize >= LZ4_compressBound(*srcSizePtr)) { /* compression success is guaranteed */ return LZ4_compress_fast_extState(state, src, dst, *srcSizePtr, targetDstSize, acceleration); } else { if (*srcSizePtr < LZ4_64Klimit) { return LZ4_compress_generic(&state->internal_donotuse, src, dst, *srcSizePtr, srcSizePtr, targetDstSize, fillOutput, byU16, noDict, noDictIssue, acceleration); } else { tableType_t const addrMode = ((sizeof(void*)==4) && ((uptrval)src > LZ4_DISTANCE_MAX)) ? byPtr : byU32; return LZ4_compress_generic(&state->internal_donotuse, src, dst, *srcSizePtr, srcSizePtr, targetDstSize, fillOutput, addrMode, noDict, noDictIssue, acceleration); } } } int LZ4_compress_destSize_extState(void* state, const char* src, char* dst, int* srcSizePtr, int targetDstSize, int acceleration) { int const r = LZ4_compress_destSize_extState_internal((LZ4_stream_t*)state, src, dst, srcSizePtr, targetDstSize, acceleration); /* clean the state on exit */ LZ4_initStream(state, sizeof (LZ4_stream_t)); return r; } int LZ4_compress_destSize(const char* src, char* dst, int* srcSizePtr, int targetDstSize) { #if (LZ4_HEAPMODE) LZ4_stream_t* const ctx = (LZ4_stream_t*)ALLOC(sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */ if (ctx == NULL) return 0; #else LZ4_stream_t ctxBody; LZ4_stream_t* const ctx = &ctxBody; #endif int result = LZ4_compress_destSize_extState_internal(ctx, src, dst, srcSizePtr, targetDstSize, 1); #if (LZ4_HEAPMODE) FREEMEM(ctx); #endif return result; } /*-****************************** * Streaming functions ********************************/ #if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) LZ4_stream_t* LZ4_createStream(void) { LZ4_stream_t* const lz4s = (LZ4_stream_t*)ALLOC(sizeof(LZ4_stream_t)); LZ4_STATIC_ASSERT(sizeof(LZ4_stream_t) >= sizeof(LZ4_stream_t_internal)); DEBUGLOG(4, "LZ4_createStream %p", lz4s); if (lz4s == NULL) return NULL; LZ4_initStream(lz4s, sizeof(*lz4s)); return lz4s; } #endif static size_t LZ4_stream_t_alignment(void) { #if LZ4_ALIGN_TEST typedef struct { char c; LZ4_stream_t t; } t_a; return sizeof(t_a) - sizeof(LZ4_stream_t); #else return 1; /* effectively disabled */ #endif } LZ4_stream_t* LZ4_initStream (void* buffer, size_t size) { DEBUGLOG(5, "LZ4_initStream"); if (buffer == NULL) { return NULL; } if (size < sizeof(LZ4_stream_t)) { return NULL; } if (!LZ4_isAligned(buffer, LZ4_stream_t_alignment())) return NULL; MEM_INIT(buffer, 0, sizeof(LZ4_stream_t_internal)); return (LZ4_stream_t*)buffer; } /* resetStream is now deprecated, * prefer initStream() which is more general */ void LZ4_resetStream (LZ4_stream_t* LZ4_stream) { DEBUGLOG(5, "LZ4_resetStream (ctx:%p)", LZ4_stream); MEM_INIT(LZ4_stream, 0, sizeof(LZ4_stream_t_internal)); } void LZ4_resetStream_fast(LZ4_stream_t* ctx) { LZ4_prepareTable(&(ctx->internal_donotuse), 0, byU32); } #if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) int LZ4_freeStream (LZ4_stream_t* LZ4_stream) { if (!LZ4_stream) return 0; /* support free on NULL */ DEBUGLOG(5, "LZ4_freeStream %p", LZ4_stream); FREEMEM(LZ4_stream); return (0); } #endif #define HASH_UNIT sizeof(reg_t) int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize) { LZ4_stream_t_internal* const dict = &LZ4_dict->internal_donotuse; const tableType_t tableType = byU32; const BYTE* p = (const BYTE*)dictionary; const BYTE* const dictEnd = p + dictSize; U32 idx32; DEBUGLOG(4, "LZ4_loadDict (%i bytes from %p into %p)", dictSize, dictionary, LZ4_dict); /* It's necessary to reset the context, * and not just continue it with prepareTable() * to avoid any risk of generating overflowing matchIndex * when compressing using this dictionary */ LZ4_resetStream(LZ4_dict); /* We always increment the offset by 64 KB, since, if the dict is longer, * we truncate it to the last 64k, and if it's shorter, we still want to * advance by a whole window length so we can provide the guarantee that * there are only valid offsets in the window, which allows an optimization * in LZ4_compress_fast_continue() where it uses noDictIssue even when the * dictionary isn't a full 64k. */ dict->currentOffset += 64 KB; if (dictSize < (int)HASH_UNIT) { return 0; } if ((dictEnd - p) > 64 KB) p = dictEnd - 64 KB; dict->dictionary = p; dict->dictSize = (U32)(dictEnd - p); dict->tableType = (U32)tableType; idx32 = dict->currentOffset - dict->dictSize; while (p <= dictEnd-HASH_UNIT) { U32 const h = LZ4_hashPosition(p, tableType); LZ4_putIndexOnHash(idx32, h, dict->hashTable, tableType); p+=3; idx32+=3; } return (int)dict->dictSize; } void LZ4_attach_dictionary(LZ4_stream_t* workingStream, const LZ4_stream_t* dictionaryStream) { const LZ4_stream_t_internal* dictCtx = (dictionaryStream == NULL) ? NULL : &(dictionaryStream->internal_donotuse); DEBUGLOG(4, "LZ4_attach_dictionary (%p, %p, size %u)", workingStream, dictionaryStream, dictCtx != NULL ? dictCtx->dictSize : 0); if (dictCtx != NULL) { /* If the current offset is zero, we will never look in the * external dictionary context, since there is no value a table * entry can take that indicate a miss. In that case, we need * to bump the offset to something non-zero. */ if (workingStream->internal_donotuse.currentOffset == 0) { workingStream->internal_donotuse.currentOffset = 64 KB; } /* Don't actually attach an empty dictionary. */ if (dictCtx->dictSize == 0) { dictCtx = NULL; } } workingStream->internal_donotuse.dictCtx = dictCtx; } static void LZ4_renormDictT(LZ4_stream_t_internal* LZ4_dict, int nextSize) { assert(nextSize >= 0); if (LZ4_dict->currentOffset + (unsigned)nextSize > 0x80000000) { /* potential ptrdiff_t overflow (32-bits mode) */ /* rescale hash table */ U32 const delta = LZ4_dict->currentOffset - 64 KB; const BYTE* dictEnd = LZ4_dict->dictionary + LZ4_dict->dictSize; int i; DEBUGLOG(4, "LZ4_renormDictT"); 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; } } int LZ4_compress_fast_continue (LZ4_stream_t* LZ4_stream, const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration) { const tableType_t tableType = byU32; LZ4_stream_t_internal* const streamPtr = &LZ4_stream->internal_donotuse; const char* dictEnd = streamPtr->dictSize ? (const char*)streamPtr->dictionary + streamPtr->dictSize : NULL; DEBUGLOG(5, "LZ4_compress_fast_continue (inputSize=%i, dictSize=%u)", inputSize, streamPtr->dictSize); LZ4_renormDictT(streamPtr, inputSize); /* fix index overflow */ if (acceleration < 1) acceleration = LZ4_ACCELERATION_DEFAULT; if (acceleration > LZ4_ACCELERATION_MAX) acceleration = LZ4_ACCELERATION_MAX; /* invalidate tiny dictionaries */ if ( (streamPtr->dictSize < 4) /* tiny dictionary : not enough for a hash */ && (dictEnd != source) /* prefix mode */ && (inputSize > 0) /* tolerance : don't lose history, in case next invocation would use prefix mode */ && (streamPtr->dictCtx == NULL) /* usingDictCtx */ ) { DEBUGLOG(5, "LZ4_compress_fast_continue: dictSize(%u) at addr:%p is too small", streamPtr->dictSize, streamPtr->dictionary); /* remove dictionary existence from history, to employ faster prefix mode */ streamPtr->dictSize = 0; streamPtr->dictionary = (const BYTE*)source; dictEnd = source; } /* Check overlapping input/dictionary space */ { const char* const sourceEnd = source + inputSize; if ((sourceEnd > (const char*)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 = (const BYTE*)dictEnd - streamPtr->dictSize; } } /* prefix mode : source data follows dictionary */ if (dictEnd == source) { if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset)) return LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, withPrefix64k, dictSmall, acceleration); else return LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, withPrefix64k, noDictIssue, acceleration); } /* external dictionary mode */ { int result; if (streamPtr->dictCtx) { /* We depend here on the fact that dictCtx'es (produced by * LZ4_loadDict) guarantee that their tables contain no references * to offsets between dictCtx->currentOffset - 64 KB and * dictCtx->currentOffset - dictCtx->dictSize. This makes it safe * to use noDictIssue even when the dict isn't a full 64 KB. */ if (inputSize > 4 KB) { /* For compressing large blobs, it is faster to pay the setup * cost to copy the dictionary's tables into the active context, * so that the compression loop is only looking into one table. */ LZ4_memcpy(streamPtr, streamPtr->dictCtx, sizeof(*streamPtr)); result = LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, usingExtDict, noDictIssue, acceleration); } else { result = LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, usingDictCtx, noDictIssue, acceleration); } } else { /* small data <= 4 KB */ if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset)) { result = LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, usingExtDict, dictSmall, acceleration); } else { result = LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, usingExtDict, noDictIssue, acceleration); } } streamPtr->dictionary = (const BYTE*)source; streamPtr->dictSize = (U32)inputSize; return result; } } /* Hidden debug function, to force-test external dictionary mode */ int LZ4_compress_forceExtDict (LZ4_stream_t* LZ4_dict, const char* source, char* dest, int srcSize) { LZ4_stream_t_internal* const streamPtr = &LZ4_dict->internal_donotuse; int result; LZ4_renormDictT(streamPtr, srcSize); if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset)) { result = LZ4_compress_generic(streamPtr, source, dest, srcSize, NULL, 0, notLimited, byU32, usingExtDict, dictSmall, 1); } else { result = LZ4_compress_generic(streamPtr, source, dest, srcSize, NULL, 0, notLimited, byU32, usingExtDict, noDictIssue, 1); } streamPtr->dictionary = (const BYTE*)source; streamPtr->dictSize = (U32)srcSize; return result; } /*! 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 : no need to call LZ4_loadDict() afterwards, dictionary is immediately usable, * one can therefore call LZ4_compress_fast_continue() right after. * @return : saved dictionary size in bytes (necessarily <= dictSize), or 0 if error. */ int LZ4_saveDict (LZ4_stream_t* LZ4_dict, char* safeBuffer, int dictSize) { LZ4_stream_t_internal* const dict = &LZ4_dict->internal_donotuse; DEBUGLOG(5, "LZ4_saveDict : dictSize=%i, safeBuffer=%p", dictSize, safeBuffer); if ((U32)dictSize > 64 KB) { dictSize = 64 KB; } /* useless to define a dictionary > 64 KB */ if ((U32)dictSize > dict->dictSize) { dictSize = (int)dict->dictSize; } if (safeBuffer == NULL) assert(dictSize == 0); if (dictSize > 0) { const BYTE* const previousDictEnd = dict->dictionary + dict->dictSize; assert(dict->dictionary); LZ4_memmove(safeBuffer, previousDictEnd - dictSize, (size_t)dictSize); } dict->dictionary = (const BYTE*)safeBuffer; dict->dictSize = (U32)dictSize; return dictSize; } /*-******************************* * Decompression functions ********************************/ typedef enum { decode_full_block = 0, partial_decode = 1 } earlyEnd_directive; #undef MIN #define MIN(a,b) ( (a) < (b) ? (a) : (b) ) /* variant for decompress_unsafe() * does not know end of input * presumes input is well formed * note : will consume at least one byte */ static size_t read_long_length_no_check(const BYTE** pp) { size_t b, l = 0; do { b = **pp; (*pp)++; l += b; } while (b==255); DEBUGLOG(6, "read_long_length_no_check: +length=%zu using %zu input bytes", l, l/255 + 1) return l; } /* core decoder variant for LZ4_decompress_fast*() * for legacy support only : these entry points are deprecated. * - Presumes input is correctly formed (no defense vs malformed inputs) * - Does not know input size (presume input buffer is "large enough") * - Decompress a full block (only) * @return : nb of bytes read from input. * Note : this variant is not optimized for speed, just for maintenance. * the goal is to remove support of decompress_fast*() variants by v2.0 **/ LZ4_FORCE_INLINE int LZ4_decompress_unsafe_generic( const BYTE* const istart, BYTE* const ostart, int decompressedSize, size_t prefixSize, const BYTE* const dictStart, /* only if dict==usingExtDict */ const size_t dictSize /* note: =0 if dictStart==NULL */ ) { const BYTE* ip = istart; BYTE* op = (BYTE*)ostart; BYTE* const oend = ostart + decompressedSize; const BYTE* const prefixStart = ostart - prefixSize; DEBUGLOG(5, "LZ4_decompress_unsafe_generic"); if (dictStart == NULL) assert(dictSize == 0); while (1) { /* start new sequence */ unsigned token = *ip++; /* literals */ { size_t ll = token >> ML_BITS; if (ll==15) { /* long literal length */ ll += read_long_length_no_check(&ip); } if ((size_t)(oend-op) < ll) return -1; /* output buffer overflow */ LZ4_memmove(op, ip, ll); /* support in-place decompression */ op += ll; ip += ll; if ((size_t)(oend-op) < MFLIMIT) { if (op==oend) break; /* end of block */ DEBUGLOG(5, "invalid: literals end at distance %zi from end of block", oend-op); /* incorrect end of block : * last match must start at least MFLIMIT==12 bytes before end of output block */ return -1; } } /* match */ { size_t ml = token & 15; size_t const offset = LZ4_readLE16(ip); ip+=2; if (ml==15) { /* long literal length */ ml += read_long_length_no_check(&ip); } ml += MINMATCH; if ((size_t)(oend-op) < ml) return -1; /* output buffer overflow */ { const BYTE* match = op - offset; /* out of range */ if (offset > (size_t)(op - prefixStart) + dictSize) { DEBUGLOG(6, "offset out of range"); return -1; } /* check special case : extDict */ if (offset > (size_t)(op - prefixStart)) { /* extDict scenario */ const BYTE* const dictEnd = dictStart + dictSize; const BYTE* extMatch = dictEnd - (offset - (size_t)(op-prefixStart)); size_t const extml = (size_t)(dictEnd - extMatch); if (extml > ml) { /* match entirely within extDict */ LZ4_memmove(op, extMatch, ml); op += ml; ml = 0; } else { /* match split between extDict & prefix */ LZ4_memmove(op, extMatch, extml); op += extml; ml -= extml; } match = prefixStart; } /* match copy - slow variant, supporting overlap copy */ { size_t u; for (u=0; u= ipmax before start of loop. Returns initial_error if so. * @error (output) - error code. Must be set to 0 before call. **/ typedef size_t Rvl_t; static const Rvl_t rvl_error = (Rvl_t)(-1); LZ4_FORCE_INLINE Rvl_t read_variable_length(const BYTE** ip, const BYTE* ilimit, int initial_check) { Rvl_t s, length = 0; assert(ip != NULL); assert(*ip != NULL); assert(ilimit != NULL); if (initial_check && unlikely((*ip) >= ilimit)) { /* read limit reached */ return rvl_error; } s = **ip; (*ip)++; length += s; if (unlikely((*ip) > ilimit)) { /* read limit reached */ return rvl_error; } /* accumulator overflow detection (32-bit mode only) */ if ((sizeof(length) < 8) && unlikely(length > ((Rvl_t)(-1)/2)) ) { return rvl_error; } if (likely(s != 255)) return length; do { s = **ip; (*ip)++; length += s; if (unlikely((*ip) > ilimit)) { /* read limit reached */ return rvl_error; } /* accumulator overflow detection (32-bit mode only) */ if ((sizeof(length) < 8) && unlikely(length > ((Rvl_t)(-1)/2)) ) { return rvl_error; } } while (s == 255); return length; } /*! LZ4_decompress_generic() : * This generic decompression function covers all use cases. * It shall be instantiated several times, using different sets of directives. * Note that it is important for performance that this function really get inlined, * in order to remove useless branches during compilation optimization. */ LZ4_FORCE_INLINE int LZ4_decompress_generic( const char* const src, char* const dst, int srcSize, int outputSize, /* If endOnInput==endOnInputSize, this value is `dstCapacity` */ earlyEnd_directive partialDecoding, /* full, partial */ dict_directive dict, /* noDict, withPrefix64k, usingExtDict */ const BYTE* const lowPrefix, /* always <= dst, == dst when no prefix */ const BYTE* const dictStart, /* only if dict==usingExtDict */ const size_t dictSize /* note : = 0 if noDict */ ) { if ((src == NULL) || (outputSize < 0)) { return -1; } { const BYTE* ip = (const BYTE*) src; const BYTE* const iend = ip + srcSize; BYTE* op = (BYTE*) dst; BYTE* const oend = op + outputSize; BYTE* cpy; const BYTE* const dictEnd = (dictStart == NULL) ? NULL : dictStart + dictSize; const int checkOffset = (dictSize < (int)(64 KB)); /* Set up the "end" pointers for the shortcut. */ const BYTE* const shortiend = iend - 14 /*maxLL*/ - 2 /*offset*/; const BYTE* const shortoend = oend - 14 /*maxLL*/ - 18 /*maxML*/; const BYTE* match; size_t offset; unsigned token; size_t length; DEBUGLOG(5, "LZ4_decompress_generic (srcSize:%i, dstSize:%i)", srcSize, outputSize); /* Special cases */ assert(lowPrefix <= op); if (unlikely(outputSize==0)) { /* Empty output buffer */ if (partialDecoding) return 0; return ((srcSize==1) && (*ip==0)) ? 0 : -1; } if (unlikely(srcSize==0)) { return -1; } /* LZ4_FAST_DEC_LOOP: * designed for modern OoO performance cpus, * where copying reliably 32-bytes is preferable to an unpredictable branch. * note : fast loop may show a regression for some client arm chips. */ #if LZ4_FAST_DEC_LOOP if ((oend - op) < FASTLOOP_SAFE_DISTANCE) { DEBUGLOG(6, "skip fast decode loop"); goto safe_decode; } /* Fast loop : decode sequences as long as output < oend-FASTLOOP_SAFE_DISTANCE */ DEBUGLOG(6, "using fast decode loop"); while (1) { /* Main fastloop assertion: We can always wildcopy FASTLOOP_SAFE_DISTANCE */ assert(oend - op >= FASTLOOP_SAFE_DISTANCE); assert(ip < iend); token = *ip++; length = token >> ML_BITS; /* literal length */ /* decode literal length */ if (length == RUN_MASK) { size_t const addl = read_variable_length(&ip, iend-RUN_MASK, 1); if (addl == rvl_error) { DEBUGLOG(6, "error reading long literal length"); goto _output_error; } length += addl; if (unlikely((uptrval)(op)+length<(uptrval)(op))) { goto _output_error; } /* overflow detection */ if (unlikely((uptrval)(ip)+length<(uptrval)(ip))) { goto _output_error; } /* overflow detection */ /* copy literals */ LZ4_STATIC_ASSERT(MFLIMIT >= WILDCOPYLENGTH); if ((op+length>oend-32) || (ip+length>iend-32)) { goto safe_literal_copy; } LZ4_wildCopy32(op, ip, op+length); ip += length; op += length; } else if (ip <= iend-(16 + 1/*max lit + offset + nextToken*/)) { /* We don't need to check oend, since we check it once for each loop below */ DEBUGLOG(7, "copy %u bytes in a 16-bytes stripe", (unsigned)length); /* Literals can only be <= 14, but hope compilers optimize better when copy by a register size */ LZ4_memcpy(op, ip, 16); ip += length; op += length; } else { goto safe_literal_copy; } /* get offset */ offset = LZ4_readLE16(ip); ip+=2; DEBUGLOG(6, " offset = %zu", offset); match = op - offset; assert(match <= op); /* overflow check */ /* get matchlength */ length = token & ML_MASK; if (length == ML_MASK) { size_t const addl = read_variable_length(&ip, iend - LASTLITERALS + 1, 0); if (addl == rvl_error) { DEBUGLOG(6, "error reading long match length"); goto _output_error; } length += addl; length += MINMATCH; if (unlikely((uptrval)(op)+length<(uptrval)op)) { goto _output_error; } /* overflow detection */ if (op + length >= oend - FASTLOOP_SAFE_DISTANCE) { goto safe_match_copy; } } else { length += MINMATCH; if (op + length >= oend - FASTLOOP_SAFE_DISTANCE) { goto safe_match_copy; } /* Fastpath check: skip LZ4_wildCopy32 when true */ if ((dict == withPrefix64k) || (match >= lowPrefix)) { if (offset >= 8) { assert(match >= lowPrefix); assert(match <= op); assert(op + 18 <= oend); LZ4_memcpy(op, match, 8); LZ4_memcpy(op+8, match+8, 8); LZ4_memcpy(op+16, match+16, 2); op += length; continue; } } } if ( checkOffset && (unlikely(match + dictSize < lowPrefix)) ) { DEBUGLOG(6, "Error : pos=%zi, offset=%zi => outside buffers", op-lowPrefix, op-match); goto _output_error; } /* match starting within external dictionary */ if ((dict==usingExtDict) && (match < lowPrefix)) { assert(dictEnd != NULL); if (unlikely(op+length > oend-LASTLITERALS)) { if (partialDecoding) { DEBUGLOG(7, "partialDecoding: dictionary match, close to dstEnd"); length = MIN(length, (size_t)(oend-op)); } else { DEBUGLOG(6, "end-of-block condition violated") goto _output_error; } } if (length <= (size_t)(lowPrefix-match)) { /* match fits entirely within external dictionary : just copy */ LZ4_memmove(op, dictEnd - (lowPrefix-match), length); op += length; } else { /* match stretches into both external dictionary and current block */ size_t const copySize = (size_t)(lowPrefix - match); size_t const restSize = length - copySize; LZ4_memcpy(op, dictEnd - copySize, copySize); op += copySize; if (restSize > (size_t)(op - lowPrefix)) { /* overlap copy */ BYTE* const endOfMatch = op + restSize; const BYTE* copyFrom = lowPrefix; while (op < endOfMatch) { *op++ = *copyFrom++; } } else { LZ4_memcpy(op, lowPrefix, restSize); op += restSize; } } continue; } /* copy match within block */ cpy = op + length; assert((op <= oend) && (oend-op >= 32)); if (unlikely(offset<16)) { LZ4_memcpy_using_offset(op, match, cpy, offset); } else { LZ4_wildCopy32(op, match, cpy); } op = cpy; /* wildcopy correction */ } safe_decode: #endif /* Main Loop : decode remaining sequences where output < FASTLOOP_SAFE_DISTANCE */ DEBUGLOG(6, "using safe decode loop"); while (1) { assert(ip < iend); token = *ip++; length = token >> ML_BITS; /* literal length */ /* A two-stage shortcut for the most common case: * 1) If the literal length is 0..14, and there is enough space, * enter the shortcut and copy 16 bytes on behalf of the literals * (in the fast mode, only 8 bytes can be safely copied this way). * 2) Further if the match length is 4..18, copy 18 bytes in a similar * manner; but we ensure that there's enough space in the output for * those 18 bytes earlier, upon entering the shortcut (in other words, * there is a combined check for both stages). */ if ( (length != RUN_MASK) /* strictly "less than" on input, to re-enter the loop with at least one byte */ && likely((ip < shortiend) & (op <= shortoend)) ) { /* Copy the literals */ LZ4_memcpy(op, ip, 16); op += length; ip += length; /* The second stage: prepare for match copying, decode full info. * If it doesn't work out, the info won't be wasted. */ length = token & ML_MASK; /* match length */ offset = LZ4_readLE16(ip); ip += 2; match = op - offset; assert(match <= op); /* check overflow */ /* Do not deal with overlapping matches. */ if ( (length != ML_MASK) && (offset >= 8) && (dict==withPrefix64k || match >= lowPrefix) ) { /* Copy the match. */ LZ4_memcpy(op + 0, match + 0, 8); LZ4_memcpy(op + 8, match + 8, 8); LZ4_memcpy(op +16, match +16, 2); op += length + MINMATCH; /* Both stages worked, load the next token. */ continue; } /* The second stage didn't work out, but the info is ready. * Propel it right to the point of match copying. */ goto _copy_match; } /* decode literal length */ if (length == RUN_MASK) { size_t const addl = read_variable_length(&ip, iend-RUN_MASK, 1); if (addl == rvl_error) { goto _output_error; } length += addl; if (unlikely((uptrval)(op)+length<(uptrval)(op))) { goto _output_error; } /* overflow detection */ if (unlikely((uptrval)(ip)+length<(uptrval)(ip))) { goto _output_error; } /* overflow detection */ } #if LZ4_FAST_DEC_LOOP safe_literal_copy: #endif /* copy literals */ cpy = op+length; LZ4_STATIC_ASSERT(MFLIMIT >= WILDCOPYLENGTH); if ((cpy>oend-MFLIMIT) || (ip+length>iend-(2+1+LASTLITERALS))) { /* We've either hit the input parsing restriction or the output parsing restriction. * In the normal scenario, decoding a full block, it must be the last sequence, * otherwise it's an error (invalid input or dimensions). * In partialDecoding scenario, it's necessary to ensure there is no buffer overflow. */ if (partialDecoding) { /* Since we are partial decoding we may be in this block because of the output parsing * restriction, which is not valid since the output buffer is allowed to be undersized. */ DEBUGLOG(7, "partialDecoding: copying literals, close to input or output end") DEBUGLOG(7, "partialDecoding: literal length = %u", (unsigned)length); DEBUGLOG(7, "partialDecoding: remaining space in dstBuffer : %i", (int)(oend - op)); DEBUGLOG(7, "partialDecoding: remaining space in srcBuffer : %i", (int)(iend - ip)); /* Finishing in the middle of a literals segment, * due to lack of input. */ if (ip+length > iend) { length = (size_t)(iend-ip); cpy = op + length; } /* Finishing in the middle of a literals segment, * due to lack of output space. */ if (cpy > oend) { cpy = oend; assert(op<=oend); length = (size_t)(oend-op); } } else { /* We must be on the last sequence (or invalid) because of the parsing limitations * so check that we exactly consume the input and don't overrun the output buffer. */ if ((ip+length != iend) || (cpy > oend)) { DEBUGLOG(6, "should have been last run of literals") DEBUGLOG(6, "ip(%p) + length(%i) = %p != iend (%p)", ip, (int)length, ip+length, iend); DEBUGLOG(6, "or cpy(%p) > oend(%p)", cpy, oend); goto _output_error; } } LZ4_memmove(op, ip, length); /* supports overlapping memory regions, for in-place decompression scenarios */ ip += length; op += length; /* Necessarily EOF when !partialDecoding. * When partialDecoding, it is EOF if we've either * filled the output buffer or * can't proceed with reading an offset for following match. */ if (!partialDecoding || (cpy == oend) || (ip >= (iend-2))) { break; } } else { LZ4_wildCopy8(op, ip, cpy); /* can overwrite up to 8 bytes beyond cpy */ ip += length; op = cpy; } /* get offset */ offset = LZ4_readLE16(ip); ip+=2; match = op - offset; /* get matchlength */ length = token & ML_MASK; _copy_match: if (length == ML_MASK) { size_t const addl = read_variable_length(&ip, iend - LASTLITERALS + 1, 0); if (addl == rvl_error) { goto _output_error; } length += addl; if (unlikely((uptrval)(op)+length<(uptrval)op)) goto _output_error; /* overflow detection */ } length += MINMATCH; #if LZ4_FAST_DEC_LOOP safe_match_copy: #endif if ((checkOffset) && (unlikely(match + dictSize < lowPrefix))) goto _output_error; /* Error : offset outside buffers */ /* match starting within external dictionary */ if ((dict==usingExtDict) && (match < lowPrefix)) { assert(dictEnd != NULL); if (unlikely(op+length > oend-LASTLITERALS)) { if (partialDecoding) length = MIN(length, (size_t)(oend-op)); else goto _output_error; /* doesn't respect parsing restriction */ } if (length <= (size_t)(lowPrefix-match)) { /* match fits entirely within external dictionary : just copy */ LZ4_memmove(op, dictEnd - (lowPrefix-match), length); op += length; } else { /* match stretches into both external dictionary and current block */ size_t const copySize = (size_t)(lowPrefix - match); size_t const restSize = length - copySize; LZ4_memcpy(op, dictEnd - copySize, copySize); op += copySize; if (restSize > (size_t)(op - lowPrefix)) { /* overlap copy */ BYTE* const endOfMatch = op + restSize; const BYTE* copyFrom = lowPrefix; while (op < endOfMatch) *op++ = *copyFrom++; } else { LZ4_memcpy(op, lowPrefix, restSize); op += restSize; } } continue; } assert(match >= lowPrefix); /* copy match within block */ cpy = op + length; /* partialDecoding : may end anywhere within the block */ assert(op<=oend); if (partialDecoding && (cpy > oend-MATCH_SAFEGUARD_DISTANCE)) { size_t const mlen = MIN(length, (size_t)(oend-op)); const BYTE* const matchEnd = match + mlen; BYTE* const copyEnd = op + mlen; if (matchEnd > op) { /* overlap copy */ while (op < copyEnd) { *op++ = *match++; } } else { LZ4_memcpy(op, match, mlen); } op = copyEnd; if (op == oend) { break; } continue; } if (unlikely(offset<8)) { LZ4_write32(op, 0); /* silence msan warning when offset==0 */ op[0] = match[0]; op[1] = match[1]; op[2] = match[2]; op[3] = match[3]; match += inc32table[offset]; LZ4_memcpy(op+4, match, 4); match -= dec64table[offset]; } else { LZ4_memcpy(op, match, 8); match += 8; } op += 8; if (unlikely(cpy > oend-MATCH_SAFEGUARD_DISTANCE)) { BYTE* const oCopyLimit = oend - (WILDCOPYLENGTH-1); if (cpy > oend-LASTLITERALS) { goto _output_error; } /* Error : last LASTLITERALS bytes must be literals (uncompressed) */ if (op < oCopyLimit) { LZ4_wildCopy8(op, match, oCopyLimit); match += oCopyLimit - op; op = oCopyLimit; } while (op < cpy) { *op++ = *match++; } } else { LZ4_memcpy(op, match, 8); if (length > 16) { LZ4_wildCopy8(op+8, match+8, cpy); } } op = cpy; /* wildcopy correction */ } /* end of decoding */ DEBUGLOG(5, "decoded %i bytes", (int) (((char*)op)-dst)); return (int) (((char*)op)-dst); /* Nb of output bytes decoded */ /* Overflow error detected */ _output_error: return (int) (-(((const char*)ip)-src))-1; } } /*===== Instantiate the API decoding functions. =====*/ LZ4_FORCE_O2 int LZ4_decompress_safe(const char* source, char* dest, int compressedSize, int maxDecompressedSize) { return LZ4_decompress_generic(source, dest, compressedSize, maxDecompressedSize, decode_full_block, noDict, (BYTE*)dest, NULL, 0); } LZ4_FORCE_O2 int LZ4_decompress_safe_partial(const char* src, char* dst, int compressedSize, int targetOutputSize, int dstCapacity) { dstCapacity = MIN(targetOutputSize, dstCapacity); return LZ4_decompress_generic(src, dst, compressedSize, dstCapacity, partial_decode, noDict, (BYTE*)dst, NULL, 0); } LZ4_FORCE_O2 int LZ4_decompress_fast(const char* source, char* dest, int originalSize) { DEBUGLOG(5, "LZ4_decompress_fast"); return LZ4_decompress_unsafe_generic( (const BYTE*)source, (BYTE*)dest, originalSize, 0, NULL, 0); } /*===== Instantiate a few more decoding cases, used more than once. =====*/ LZ4_FORCE_O2 /* Exported, an obsolete API function. */ int LZ4_decompress_safe_withPrefix64k(const char* source, char* dest, int compressedSize, int maxOutputSize) { return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, decode_full_block, withPrefix64k, (BYTE*)dest - 64 KB, NULL, 0); } LZ4_FORCE_O2 static int LZ4_decompress_safe_partial_withPrefix64k(const char* source, char* dest, int compressedSize, int targetOutputSize, int dstCapacity) { dstCapacity = MIN(targetOutputSize, dstCapacity); return LZ4_decompress_generic(source, dest, compressedSize, dstCapacity, partial_decode, withPrefix64k, (BYTE*)dest - 64 KB, NULL, 0); } /* Another obsolete API function, paired with the previous one. */ int LZ4_decompress_fast_withPrefix64k(const char* source, char* dest, int originalSize) { return LZ4_decompress_unsafe_generic( (const BYTE*)source, (BYTE*)dest, originalSize, 64 KB, NULL, 0); } LZ4_FORCE_O2 static int LZ4_decompress_safe_withSmallPrefix(const char* source, char* dest, int compressedSize, int maxOutputSize, size_t prefixSize) { return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, decode_full_block, noDict, (BYTE*)dest-prefixSize, NULL, 0); } LZ4_FORCE_O2 static int LZ4_decompress_safe_partial_withSmallPrefix(const char* source, char* dest, int compressedSize, int targetOutputSize, int dstCapacity, size_t prefixSize) { dstCapacity = MIN(targetOutputSize, dstCapacity); return LZ4_decompress_generic(source, dest, compressedSize, dstCapacity, partial_decode, noDict, (BYTE*)dest-prefixSize, NULL, 0); } LZ4_FORCE_O2 int LZ4_decompress_safe_forceExtDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const void* dictStart, size_t dictSize) { DEBUGLOG(5, "LZ4_decompress_safe_forceExtDict"); return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, decode_full_block, usingExtDict, (BYTE*)dest, (const BYTE*)dictStart, dictSize); } LZ4_FORCE_O2 int LZ4_decompress_safe_partial_forceExtDict(const char* source, char* dest, int compressedSize, int targetOutputSize, int dstCapacity, const void* dictStart, size_t dictSize) { dstCapacity = MIN(targetOutputSize, dstCapacity); return LZ4_decompress_generic(source, dest, compressedSize, dstCapacity, partial_decode, usingExtDict, (BYTE*)dest, (const BYTE*)dictStart, dictSize); } LZ4_FORCE_O2 static int LZ4_decompress_fast_extDict(const char* source, char* dest, int originalSize, const void* dictStart, size_t dictSize) { return LZ4_decompress_unsafe_generic( (const BYTE*)source, (BYTE*)dest, originalSize, 0, (const BYTE*)dictStart, dictSize); } /* The "double dictionary" mode, for use with e.g. ring buffers: the first part * of the dictionary is passed as prefix, and the second via dictStart + dictSize. * These routines are used only once, in LZ4_decompress_*_continue(). */ LZ4_FORCE_INLINE int LZ4_decompress_safe_doubleDict(const char* source, char* dest, int compressedSize, int maxOutputSize, size_t prefixSize, const void* dictStart, size_t dictSize) { return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, decode_full_block, usingExtDict, (BYTE*)dest-prefixSize, (const BYTE*)dictStart, dictSize); } /*===== streaming decompression functions =====*/ #if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) LZ4_streamDecode_t* LZ4_createStreamDecode(void) { LZ4_STATIC_ASSERT(sizeof(LZ4_streamDecode_t) >= sizeof(LZ4_streamDecode_t_internal)); return (LZ4_streamDecode_t*) ALLOC_AND_ZERO(sizeof(LZ4_streamDecode_t)); } int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream) { if (LZ4_stream == NULL) { return 0; } /* support free on NULL */ FREEMEM(LZ4_stream); return 0; } #endif /*! LZ4_setStreamDecode() : * Use this function to instruct where to find the dictionary. * This function is not necessary if previous data is still available where it was decoded. * Loading a size of 0 is allowed (same effect as no dictionary). * @return : 1 if OK, 0 if error */ int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize) { LZ4_streamDecode_t_internal* lz4sd = &LZ4_streamDecode->internal_donotuse; lz4sd->prefixSize = (size_t)dictSize; if (dictSize) { assert(dictionary != NULL); lz4sd->prefixEnd = (const BYTE*) dictionary + dictSize; } else { lz4sd->prefixEnd = (const BYTE*) dictionary; } lz4sd->externalDict = NULL; lz4sd->extDictSize = 0; return 1; } /*! LZ4_decoderRingBufferSize() : * when setting a ring buffer for streaming decompression (optional scenario), * provides the minimum size of this ring buffer * to be compatible with any source respecting maxBlockSize condition. * Note : in a ring buffer scenario, * blocks are presumed decompressed next to each other. * When not enough space remains for next block (remainingSize < maxBlockSize), * decoding resumes from beginning of ring buffer. * @return : minimum ring buffer size, * or 0 if there is an error (invalid maxBlockSize). */ int LZ4_decoderRingBufferSize(int maxBlockSize) { if (maxBlockSize < 0) return 0; if (maxBlockSize > LZ4_MAX_INPUT_SIZE) return 0; if (maxBlockSize < 16) maxBlockSize = 16; return LZ4_DECODER_RING_BUFFER_SIZE(maxBlockSize); } /* *_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() */ LZ4_FORCE_O2 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->internal_donotuse; int result; if (lz4sd->prefixSize == 0) { /* The first call, no dictionary yet. */ assert(lz4sd->extDictSize == 0); result = LZ4_decompress_safe(source, dest, compressedSize, maxOutputSize); if (result <= 0) return result; lz4sd->prefixSize = (size_t)result; lz4sd->prefixEnd = (BYTE*)dest + result; } else if (lz4sd->prefixEnd == (BYTE*)dest) { /* They're rolling the current segment. */ if (lz4sd->prefixSize >= 64 KB - 1) result = LZ4_decompress_safe_withPrefix64k(source, dest, compressedSize, maxOutputSize); else if (lz4sd->extDictSize == 0) result = LZ4_decompress_safe_withSmallPrefix(source, dest, compressedSize, maxOutputSize, lz4sd->prefixSize); else result = LZ4_decompress_safe_doubleDict(source, dest, compressedSize, maxOutputSize, lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize); if (result <= 0) return result; lz4sd->prefixSize += (size_t)result; lz4sd->prefixEnd += result; } else { /* The buffer wraps around, or they're switching to another buffer. */ lz4sd->extDictSize = lz4sd->prefixSize; lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize; result = LZ4_decompress_safe_forceExtDict(source, dest, compressedSize, maxOutputSize, lz4sd->externalDict, lz4sd->extDictSize); if (result <= 0) return result; lz4sd->prefixSize = (size_t)result; lz4sd->prefixEnd = (BYTE*)dest + result; } return result; } LZ4_FORCE_O2 int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize) { LZ4_streamDecode_t_internal* const lz4sd = (assert(LZ4_streamDecode!=NULL), &LZ4_streamDecode->internal_donotuse); int result; DEBUGLOG(5, "LZ4_decompress_fast_continue (toDecodeSize=%i)", originalSize); assert(originalSize >= 0); if (lz4sd->prefixSize == 0) { DEBUGLOG(5, "first invocation : no prefix nor extDict"); assert(lz4sd->extDictSize == 0); result = LZ4_decompress_fast(source, dest, originalSize); if (result <= 0) return result; lz4sd->prefixSize = (size_t)originalSize; lz4sd->prefixEnd = (BYTE*)dest + originalSize; } else if (lz4sd->prefixEnd == (BYTE*)dest) { DEBUGLOG(5, "continue using existing prefix"); result = LZ4_decompress_unsafe_generic( (const BYTE*)source, (BYTE*)dest, originalSize, lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize); if (result <= 0) return result; lz4sd->prefixSize += (size_t)originalSize; lz4sd->prefixEnd += originalSize; } else { DEBUGLOG(5, "prefix becomes extDict"); lz4sd->extDictSize = lz4sd->prefixSize; lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize; result = LZ4_decompress_fast_extDict(source, dest, originalSize, lz4sd->externalDict, lz4sd->extDictSize); if (result <= 0) return result; lz4sd->prefixSize = (size_t)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 */ int LZ4_decompress_safe_usingDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const char* dictStart, int dictSize) { if (dictSize==0) return LZ4_decompress_safe(source, dest, compressedSize, maxOutputSize); if (dictStart+dictSize == dest) { if (dictSize >= 64 KB - 1) { return LZ4_decompress_safe_withPrefix64k(source, dest, compressedSize, maxOutputSize); } assert(dictSize >= 0); return LZ4_decompress_safe_withSmallPrefix(source, dest, compressedSize, maxOutputSize, (size_t)dictSize); } assert(dictSize >= 0); return LZ4_decompress_safe_forceExtDict(source, dest, compressedSize, maxOutputSize, dictStart, (size_t)dictSize); } int LZ4_decompress_safe_partial_usingDict(const char* source, char* dest, int compressedSize, int targetOutputSize, int dstCapacity, const char* dictStart, int dictSize) { if (dictSize==0) return LZ4_decompress_safe_partial(source, dest, compressedSize, targetOutputSize, dstCapacity); if (dictStart+dictSize == dest) { if (dictSize >= 64 KB - 1) { return LZ4_decompress_safe_partial_withPrefix64k(source, dest, compressedSize, targetOutputSize, dstCapacity); } assert(dictSize >= 0); return LZ4_decompress_safe_partial_withSmallPrefix(source, dest, compressedSize, targetOutputSize, dstCapacity, (size_t)dictSize); } assert(dictSize >= 0); return LZ4_decompress_safe_partial_forceExtDict(source, dest, compressedSize, targetOutputSize, dstCapacity, dictStart, (size_t)dictSize); } int LZ4_decompress_fast_usingDict(const char* source, char* dest, int originalSize, const char* dictStart, int dictSize) { if (dictSize==0 || dictStart+dictSize == dest) return LZ4_decompress_unsafe_generic( (const BYTE*)source, (BYTE*)dest, originalSize, (size_t)dictSize, NULL, 0); assert(dictSize >= 0); return LZ4_decompress_fast_extDict(source, dest, originalSize, dictStart, (size_t)dictSize); } /*=************************************************* * Obsolete Functions ***************************************************/ /* obsolete compression functions */ int LZ4_compress_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize) { return LZ4_compress_default(source, dest, inputSize, maxOutputSize); } int LZ4_compress(const char* src, char* dest, int srcSize) { return LZ4_compress_default(src, dest, srcSize, LZ4_compressBound(srcSize)); } int LZ4_compress_limitedOutput_withState (void* state, const char* src, char* dst, int srcSize, int dstSize) { return LZ4_compress_fast_extState(state, src, dst, srcSize, dstSize, 1); } int LZ4_compress_withState (void* state, const char* src, char* dst, int srcSize) { return LZ4_compress_fast_extState(state, src, dst, srcSize, LZ4_compressBound(srcSize), 1); } int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_stream, const char* src, char* dst, int srcSize, int dstCapacity) { return LZ4_compress_fast_continue(LZ4_stream, src, dst, srcSize, dstCapacity, 1); } int LZ4_compress_continue (LZ4_stream_t* LZ4_stream, const char* source, char* dest, int inputSize) { return LZ4_compress_fast_continue(LZ4_stream, source, dest, inputSize, LZ4_compressBound(inputSize), 1); } /* These decompression functions 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(void) { return sizeof(LZ4_stream_t); } int LZ4_resetStreamState(void* state, char* inputBuffer) { (void)inputBuffer; LZ4_resetStream((LZ4_stream_t*)state); return 0; } #if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION) void* LZ4_create (char* inputBuffer) { (void)inputBuffer; return LZ4_createStream(); } #endif char* LZ4_slideInputBuffer (void* state) { /* avoid const char * -> char * conversion warning */ return (char *)(uptrval)((LZ4_stream_t*)state)->internal_donotuse.dictionary; } #endif /* LZ4_COMMONDEFS_ONLY */ gtkwave-gtk3-3.3.125/src/helpers/fst/fstapi.h0000664000175000017500000004601115047725113020204 0ustar bybellbybell/* * Copyright (c) 2009-2018 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. * * SPDX-License-Identifier: MIT */ #ifndef FST_API_H #define FST_API_H #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include #include #if defined(_MSC_VER) #include "fst_win_unistd.h" #else #include #endif #include typedef uint32_t fstHandle; typedef uint32_t fstEnumHandle; 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_TREEBEGIN and FST_HT_TREEEND are not yet used by FST but are currently used when fstHier bridges other formats */ FST_HT_TREEBEGIN = 5, FST_HT_TREEEND = 6, FST_HT_MAX = 6 }; 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_ENUMTABLE = 7, /* use fstWriterCreateEnumTable() and fstWriterEmitEnumTableRef() to emit */ FST_MT_UNKNOWN = 8, FST_MT_MAX = 8 }; 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_REG = 14, FST_EV_TIME = 15, FST_EV_MAX = 15 }; 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; }; struct fstETab { char *name; uint32_t elem_count; char **literal_arr; char **val_arr; }; /* * writer functions */ typedef struct fstWriterContext fstWriterContext; void fstWriterClose(fstWriterContext *ctx); fstWriterContext *fstWriterCreate(const char *nam, int use_compressed_hier); fstEnumHandle fstWriterCreateEnumTable(fstWriterContext *ctx, const char *name, uint32_t elem_count, unsigned int min_valbits, const char **literal_arr, const char **val_arr); /* used for Verilog/SV */ fstHandle fstWriterCreateVar(fstWriterContext *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(fstWriterContext *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 fstWriterEmitDumpActive(fstWriterContext *ctx, int enable); void fstWriterEmitEnumTableRef(fstWriterContext *ctx, fstEnumHandle handle); void fstWriterEmitValueChange(fstWriterContext *ctx, fstHandle handle, const void *val); void fstWriterEmitValueChange32(fstWriterContext *ctx, fstHandle handle, uint32_t bits, uint32_t val); void fstWriterEmitValueChange64(fstWriterContext *ctx, fstHandle handle, uint32_t bits, uint64_t val); void fstWriterEmitValueChangeVec32(fstWriterContext *ctx, fstHandle handle, uint32_t bits, const uint32_t *val); void fstWriterEmitValueChangeVec64(fstWriterContext *ctx, fstHandle handle, uint32_t bits, const uint64_t *val); void fstWriterEmitVariableLengthValueChange(fstWriterContext *ctx, fstHandle handle, const void *val, uint32_t len); void fstWriterEmitTimeChange(fstWriterContext *ctx, uint64_t tim); void fstWriterFlushContext(fstWriterContext *ctx); int fstWriterGetDumpSizeLimitReached(fstWriterContext *ctx); int fstWriterGetFseekFailed(fstWriterContext *ctx); int fstWriterGetFlushContextPending(fstWriterContext *ctx); void fstWriterSetAttrBegin(fstWriterContext *ctx, enum fstAttrType attrtype, int subtype, const char *attrname, uint64_t arg); void fstWriterSetAttrEnd(fstWriterContext *ctx); void fstWriterSetComment(fstWriterContext *ctx, const char *comm); void fstWriterSetDate(fstWriterContext *ctx, const char *dat); void fstWriterSetDumpSizeLimit(fstWriterContext *ctx, uint64_t numbytes); void fstWriterSetEnvVar(fstWriterContext *ctx, const char *envvar); void fstWriterSetFileType(fstWriterContext *ctx, enum fstFileType filetype); void fstWriterSetPackType(fstWriterContext *ctx, enum fstWriterPackType typ); void fstWriterSetParallelMode(fstWriterContext *ctx, int enable); void fstWriterSetRepackOnClose(fstWriterContext *ctx, int enable); /* type = 0 (none), 1 (libz) */ void fstWriterSetScope(fstWriterContext *ctx, enum fstScopeType scopetype, const char *scopename, const char *scopecomp); void fstWriterSetSourceInstantiationStem(fstWriterContext *ctx, const char *path, unsigned int line, unsigned int use_realpath); void fstWriterSetSourceStem(fstWriterContext *ctx, const char *path, unsigned int line, unsigned int use_realpath); void fstWriterSetTimescale(fstWriterContext *ctx, int ts); void fstWriterSetTimescaleFromString(fstWriterContext *ctx, const char *s); void fstWriterSetTimezero(fstWriterContext *ctx, int64_t tim); void fstWriterSetUpscope(fstWriterContext *ctx); void fstWriterSetValueList(fstWriterContext *ctx, const char *vl); void fstWriterSetVersion(fstWriterContext *ctx, const char *vers); /* * reader functions */ typedef struct fstReaderContext fstReaderContext; void fstReaderClose(fstReaderContext *ctx); void fstReaderClrFacProcessMask(fstReaderContext *ctx, fstHandle facidx); void fstReaderClrFacProcessMaskAll(fstReaderContext *ctx); uint64_t fstReaderGetAliasCount(fstReaderContext *ctx); const char *fstReaderGetCurrentFlatScope(fstReaderContext *ctx); void *fstReaderGetCurrentScopeUserInfo(fstReaderContext *ctx); int fstReaderGetCurrentScopeLen(fstReaderContext *ctx); const char *fstReaderGetDateString(fstReaderContext *ctx); int fstReaderGetDoubleEndianMatchState(fstReaderContext *ctx); uint64_t fstReaderGetDumpActivityChangeTime(fstReaderContext *ctx, uint32_t idx); unsigned char fstReaderGetDumpActivityChangeValue(fstReaderContext *ctx, uint32_t idx); uint64_t fstReaderGetEndTime(fstReaderContext *ctx); int fstReaderGetFacProcessMask(fstReaderContext *ctx, fstHandle facidx); int fstReaderGetFileType(fstReaderContext *ctx); int fstReaderGetFseekFailed(fstReaderContext *ctx); fstHandle fstReaderGetMaxHandle(fstReaderContext *ctx); uint64_t fstReaderGetMemoryUsedByWriter(fstReaderContext *ctx); uint32_t fstReaderGetNumberDumpActivityChanges(fstReaderContext *ctx); uint64_t fstReaderGetScopeCount(fstReaderContext *ctx); uint64_t fstReaderGetStartTime(fstReaderContext *ctx); signed char fstReaderGetTimescale(fstReaderContext *ctx); int64_t fstReaderGetTimezero(fstReaderContext *ctx); uint64_t fstReaderGetValueChangeSectionCount(fstReaderContext *ctx); char *fstReaderGetValueFromHandleAtTime(fstReaderContext *ctx, uint64_t tim, fstHandle facidx, char *buf); uint64_t fstReaderGetVarCount(fstReaderContext *ctx); const char *fstReaderGetVersionString(fstReaderContext *ctx); struct fstHier *fstReaderIterateHier(fstReaderContext *ctx); int fstReaderIterateHierRewind(fstReaderContext *ctx); int fstReaderIterBlocks(fstReaderContext *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(fstReaderContext *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(fstReaderContext *ctx, int enable); fstReaderContext *fstReaderOpen(const char *nam); fstReaderContext *fstReaderOpenForUtilitiesOnly(void); const char *fstReaderPopScope(fstReaderContext *ctx); int fstReaderProcessHier(fstReaderContext *ctx, FILE *vcdhandle); const char *fstReaderPushScope(fstReaderContext *ctx, const char *nam, void *user_info); void fstReaderResetScope(fstReaderContext *ctx); void fstReaderSetFacProcessMask(fstReaderContext *ctx, fstHandle facidx); void fstReaderSetFacProcessMaskAll(fstReaderContext *ctx); void fstReaderSetLimitTimeRange(fstReaderContext *ctx, uint64_t start_time, uint64_t end_time); void fstReaderSetUnlimitedTimeRange(fstReaderContext *ctx); void fstReaderSetVcdExtensions(fstReaderContext *ctx, int enable); /* * utility functions */ int fstUtilityBinToEscConvertedLen(const unsigned char *s, int len); /* used for mallocs for fstUtilityBinToEsc() */ int fstUtilityBinToEsc(unsigned char *d, const unsigned char *s, int len); int fstUtilityEscToBin(unsigned char *d, unsigned char *s, int len); struct fstETab *fstUtilityExtractEnumTableFromString(const char *s); void fstUtilityFreeEnumTable(struct fstETab *etab); /* must use to free fstETab properly */ #ifdef __cplusplus } #endif #endif gtkwave-gtk3-3.3.125/src/helpers/fst/CMakeLists.txt0000664000175000017500000000202715047725113021304 0ustar bybellbybellcmake_minimum_required (VERSION 3.0) project (fstlib) ######################################################################################################################## # Easiest way to get ZLib on windows is using vcpkg, to load vcpkg: # cmake -DCMAKE_TOOLCHAIN_FILE=[path to vcpkg]/scripts/buildsystems/vcpkg.cmake if(CMAKE_TOOLCHAIN_FILE) message(STATUS "Using VCPKG from ${CMAKE_TOOLCHAIN_FILE}") endif() ######################################################################################################################## find_package(ZLIB REQUIRED) add_library(fstapi fstapi.c fstapi.h fst_win_unistd.h) target_link_libraries(fstapi PRIVATE ZLIB::ZLIB) # hack to avoid creating dummy config.h target_compile_definitions(fstapi PRIVATE -DFST_CONFIG_INCLUDE="fstapi.h") if(MSVC) # define __MINGW32__ to minimize changes to upstream target_compile_definitions(fstapi PRIVATE __MINGW32__ _CRT_SECURE_NO_WARNINGS FST_DO_MISALIGNED_OPS) target_compile_options(fstapi PRIVATE /wd4244 /wd4267 /wd4146 /wd4996) endif() gtkwave-gtk3-3.3.125/src/helpers/v2l_analyzer.h0000664000175000017500000000714015047725113020532 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-gtk3-3.3.125/src/helpers/scopenav.c0000664000175000017500000000630415047725113017734 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-gtk3-3.3.125/src/helpers/v2l_debug.h0000664000175000017500000000550415047725113017775 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-gtk3-3.3.125/src/main.c0000664000175000017500000030653615047725113015412 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2017. * * 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 #else #if GTK_CHECK_VERSION(3,0,0) #include #endif #endif /* #define WAVE_CRASH_ON_GTK_WARNING */ #include "wave_locale.h" #if !defined __MINGW32__ #include #include #include #include #include #endif #if !defined __MINGW32__ #define WAVE_USE_XID #else #undef WAVE_USE_XID #endif #ifdef HAVE_GETOPT_LONG #include #else #include "gnu-getopt.h" #include #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, gpointer *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->mti_realparam_fix = g_old->mti_realparam_fix; 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->fullscreen = g_old->fullscreen; GLOBALS->show_toolbar = g_old->show_toolbar; GLOBALS->time_mainbox = g_old->time_mainbox; GLOBALS->highlight_wavewindow = g_old->highlight_wavewindow; GLOBALS->fill_waveform = g_old->fill_waveform; GLOBALS->lz_removal = g_old->lz_removal; GLOBALS->use_standard_trace_select = g_old->use_standard_trace_select; GLOBALS->disable_mouseover = g_old->disable_mouseover; GLOBALS->clipboard_mouseover = g_old->clipboard_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; GLOBALS->hier_ignore_escapes = g_old->hier_ignore_escapes; GLOBALS->sst_dbl_action_type = g_old->sst_dbl_action_type; GLOBALS->use_gestures = g_old->use_gestures; GLOBALS->use_dark = g_old->use_dark; GLOBALS->save_on_exit = g_old->save_on_exit; #ifdef WAVE_ALLOW_GTK3_HEADER_BAR GLOBALS->header_bar = g_old->header_bar; GLOBALS->main_popup_menu = g_old->main_popup_menu; GLOBALS->main_popup_menu_button = g_old->main_popup_menu_button; GLOBALS->top_table = g_old->top_table; #endif 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(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; } } 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); } } #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 #ifdef WAVE_FSDB_READER_IS_PRESENT static void close_all_fsdb_files(void) /* otherwise fsdb can leave around stray files if .gz/.bz2 was in use */ { unsigned int i; for(i=0;inum_notebook_pages;i++) { if((*GLOBALS->contexts)[i]->extload_ffr_ctx) { fsdbReaderClose((*GLOBALS->contexts)[i]->extload_ffr_ctx); (*GLOBALS->contexts)[i]->extload_ffr_ctx = NULL; } } } #endif #ifdef WAVE_ALLOW_GTK3_HEADER_BAR static void service_pan_up(GtkWidget *text, gpointer data) { (void)text; (void)data; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nHide Toolbar"); help_text( " hides the toolbar (or optionally enabled traditional button layout) in order to provide more screen space for viewing traces." ); return; } gtk_widget_hide(GLOBALS->top_table); } static void service_pan_dn(GtkWidget *text, gpointer data) { (void)text; (void)data; if(GLOBALS->helpbox_is_active) { help_text_bold("\n\nShow Toolbar"); help_text( " restores the toolbar (or optionally enabled traditional button layout) that was hidden by Hide Toolbar." ); return; } gtk_widget_show(GLOBALS->top_table); } #endif void wave_gtk_window_set_title(GtkWindow *window, const gchar *title, int typ, int pct) { #ifdef WAVE_ALLOW_GTK3_HEADER_BAR if(!window || !title || GLOBALS->socket_xid) return; if(!GLOBALS->disable_menus) { if(!GLOBALS->header_bar) { GLOBALS->header_bar = gtk_header_bar_new(); if(GLOBALS->header_bar) { gtk_header_bar_set_show_close_button (GTK_HEADER_BAR (GLOBALS->header_bar), TRUE); gtk_header_bar_set_title(GTK_HEADER_BAR(GLOBALS->header_bar), title); gtk_header_bar_set_has_subtitle (GTK_HEADER_BAR(GLOBALS->header_bar), TRUE); gtk_header_bar_set_subtitle(GTK_HEADER_BAR(GLOBALS->header_bar), WAVE_VERSION_INFO); gtk_window_set_titlebar (GTK_WINDOW (window), GLOBALS->header_bar); GtkWidget *pan_up = gtk_button_new_from_icon_name("pan-up-symbolic", GTK_ICON_SIZE_BUTTON); gtk_header_bar_pack_start(GTK_HEADER_BAR(GLOBALS->header_bar),pan_up); gtk_widget_show(pan_up); gtk_tooltips_set_tip_2(pan_up, "Hide toolbar"); GtkWidget *pan_dn = gtk_button_new_from_icon_name("pan-down-symbolic", GTK_ICON_SIZE_BUTTON); gtk_header_bar_pack_start(GTK_HEADER_BAR(GLOBALS->header_bar),pan_dn); gtk_widget_show(pan_dn); gtk_tooltips_set_tip_2(pan_dn, "Show toolbar"); GtkWidget *fs = gtk_button_new_from_icon_name("view-fullscreen-symbolic", GTK_ICON_SIZE_BUTTON); gtk_header_bar_pack_end(GTK_HEADER_BAR(GLOBALS->header_bar),fs); gtk_widget_show(fs); gtk_tooltips_set_tip_2(fs, "Fullscreen"); gtk_header_bar_set_decoration_layout(GTK_HEADER_BAR(GLOBALS->header_bar), ":minimize,maximize,close"); gtk_widget_show(GLOBALS->header_bar); g_signal_connect (XXX_GTK_OBJECT (pan_up), "released", G_CALLBACK(service_pan_up), NULL); g_signal_connect (XXX_GTK_OBJECT (pan_dn), "released", G_CALLBACK(service_pan_dn), NULL); g_signal_connect (XXX_GTK_OBJECT (fs), "released", G_CALLBACK(service_fullscreen), NULL); } } else { switch(typ) { case WAVE_SET_TITLE_MODIFIED: { const char *pfx = "[Modified] "; char *t = wave_alloca(strlen(pfx) + strlen(title) + 1); strcpy(t, pfx); strcat(t, title); gtk_header_bar_set_title(GTK_HEADER_BAR(GLOBALS->header_bar), t); } break; case WAVE_SET_TITLE_LOADING: { char *t = wave_alloca(64 + strlen(title) + 1); /* make extra long */ sprintf(t, "[Loading %d%%] %s", pct, title); gtk_header_bar_set_title(GTK_HEADER_BAR(GLOBALS->header_bar), t); } break; case WAVE_SET_TITLE_NONE: default: gtk_header_bar_set_title(GTK_HEADER_BAR(GLOBALS->header_bar), title); break; } } } else #endif if(window && title) { switch(typ) { case WAVE_SET_TITLE_MODIFIED: { const char *pfx = "[Modified] "; char *t = wave_alloca(strlen(pfx) + strlen(title) + 1); strcpy(t, pfx); strcat(t, title); gtk_window_set_title(window, t); } break; case WAVE_SET_TITLE_LOADING: { char *t = wave_alloca(64 + strlen(title) + 1); /* make extra long */ sprintf(t, "[Loading %d%%] %s", pct, title); gtk_window_set_title(window, t); } break; case WAVE_SET_TITLE_NONE: default: gtk_window_set_title(window, title); break; } } } 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 __MINGW32__ #if defined(EXTLOAD_SUFFIX) && defined(EXTCONV_PATH) ,ucase_ext #endif #endif ); #ifdef __MINGW32__ fflush(stdout); /* fix for possible problem with mingw/msys shells */ #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 __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,G_CALLBACK(wave_get_filename_cleanup), G_CALLBACK(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 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->iter_status_c_3 = old_g->iter_status_c_3; GLOBALS->bold_tag_status_c_3 = old_g->bold_tag_status_c_3; /* 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_highfill = old_g->color_highfill; GLOBALS->color_low = old_g->color_low; GLOBALS->color_1 = old_g->color_1; GLOBALS->color_1fill = old_g->color_1fill; 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->mti_realparam_fix = old_g->mti_realparam_fix; 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->clipboard_mouseover = old_g->clipboard_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->fill_waveform = old_g->fill_waveform; GLOBALS->lz_removal = old_g->lz_removal; 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->fullscreen = old_g->fullscreen; GLOBALS->show_toolbar = old_g->show_toolbar; GLOBALS->time_mainbox = old_g->time_mainbox; 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->hier_ignore_escapes = old_g->hier_ignore_escapes; 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->dragzoom_threshold = old_g->dragzoom_threshold; GLOBALS->use_toolbutton_interface = old_g->use_toolbutton_interface; GLOBALS->use_scrollwheel_as_y = old_g->use_scrollwheel_as_y; #ifdef WAVE_ALLOW_SLIDER_ZOOM GLOBALS->enable_slider_zoom = old_g->enable_slider_zoom; #endif 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; GLOBALS->extload_max_tree = old_g->extload_max_tree; GLOBALS->do_hier_compress = old_g->do_hier_compress; GLOBALS->disable_auto_comphier = old_g->disable_auto_comphier; GLOBALS->sst_dbl_action_type = old_g->sst_dbl_action_type; GLOBALS->use_gestures = old_g->use_gestures; GLOBALS->use_dark = old_g->use_dark; GLOBALS->save_on_exit = old_g->save_on_exit; GLOBALS->cr_line_width = old_g->cr_line_width; GLOBALS->cairo_050_offset = old_g->cairo_050_offset; #ifdef WAVE_ALLOW_GTK3_HEADER_BAR GLOBALS->header_bar = old_g->header_bar; GLOBALS->main_popup_menu = old_g->main_popup_menu; GLOBALS->main_popup_menu_button = old_g->main_popup_menu_button; GLOBALS->top_table = old_g->top_table; #endif strcpy2_into_new_context(GLOBALS, &GLOBALS->sst_exclude_filename, &old_g->sst_exclude_filename); 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_GTK3_GLIB_WARNING_SUPPRESS g_log_set_writer_func (gtkwave_glib_log_handler, NULL, NULL); #endif #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 #ifdef WAVE_FSDB_READER_IS_PRESENT atexit(close_all_fsdb_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'}, {"rcvar", 1, 0, '4'}, {"sstexclude", 1, 0, '5'}, {"dark", 0, 0, '6'}, {"saveonexit", 0, 0, '7'}, {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:34:5:67", 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': is_interactive = 1; break; case 'L': is_legacy = 1; break; case 'D': { 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); } 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': #if GTK_CHECK_VERSION(3,0,0) sscanf(optarg, "%lx", &GLOBALS->socket_xid); #else sscanf(optarg, "%x", &GLOBALS->socket_xid); #endif 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': { 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); } } break; case '3': #if defined(WAVE_HAVE_GCONF) || defined(WAVE_HAVE_GSETTINGS) { 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 '4': { struct rc_override *rco = calloc_2(1, sizeof(struct rc_override)); rco->str = strdup_2(optarg); if(rc_override_curr) { rc_override_curr->next = rco; rc_override_curr = rco; } else { rc_override_head = rc_override_curr = rco; } } break; case '5': { if(GLOBALS->sst_exclude_filename) { free_2(GLOBALS->sst_exclude_filename); } GLOBALS->sst_exclude_filename = strdup_2(optarg); } break; case '6': GLOBALS->use_dark = TRUE; break; case '7': GLOBALS->save_on_exit = TRUE; 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(GLOBALS->stems_name) free_2(GLOBALS->stems_name); GLOBALS->stems_name = malloc_2(strlen(optarg)+1); strcpy(GLOBALS->stems_name, optarg); break; case 'c': #if !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': #ifdef WAVE_ALLOW_SLIDER_ZOOM GLOBALS->enable_slider_zoom = 1; #else fprintf(stderr, "GTKWAVE | --slider-zoom option does not work with this version of GTK, ignoring!\n"); #endif 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 { char *dfn = NULL; char *sfn = NULL; off_t dumpsiz = -1; time_t dumptim = -1; read_save_helper(GLOBALS->loaded_file_name, &dfn, &sfn, &dumpsiz, &dumptim, &opt_vcd); fprintf(stderr, "GTKWAVE | Could not initialize '%s' found in '%s', exiting.\n", dfn ? dfn : "(null)", GLOBALS->loaded_file_name); if(dfn) free_2(dfn); if(sfn) free_2(sfn); exit(255); } } 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(!GLOBALS->loaded_file_name) { char *dfn = NULL; char *sfn = NULL; off_t dumpsiz = -1; time_t dumptim = -1; read_save_helper(wname, &dfn, &sfn, &dumpsiz, &dumptim, &opt_vcd); fprintf(stderr, "GTKWAVE | Could not initialize '%s' found in '%s', exiting.\n", dfn ? dfn : "(null)", wname); if(dfn) free_2(dfn); if(sfn) free_2(sfn); exit(255); } } 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 __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;iargstr); rco_succ = insert_rc_variable(rc_override_head->str); fprintf(stderr, "RCVAR | '%s' %s\n", rco_copy_str, rco_succ ? "FOUND" : "NOT FOUND"); free_2(rco_copy_str); rc_override_curr = rc_override_head->next; free_2(rc_override_head->str); free_2(rc_override_head); rc_override_head = rc_override_curr; } } if(!is_wish) { if(tcl_interpreter_needs_making) { GLOBALS->argvlist = 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); sst_exclusion_loader(); 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) || (suffix_check(GLOBALS->loaded_file_name, ".vf" ) && !opt_vcd) || /* virtual file */ (suffix_check(GLOBALS->loaded_file_name, "."EXTLOAD_SUFFIX".gz" ) && !opt_vcd) || /* loader automatically does gzip -cd */ (suffix_check(GLOBALS->loaded_file_name, "."EXTLOAD_SUFFIX".bz2") && !opt_vcd) /* loader automatically does bzip2 -cd */ ) { 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 { 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); 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")) { 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); 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")) { 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); 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")) { 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); 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? */ { 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); 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 __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(is_interactive) { GLOBALS->loaded_file_type = DUMPLESS_FILE; vcd_partial_main(GLOBALS->loaded_file_name); } else { 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_san(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_san(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->default_fpshift = 0; 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->default_fpshift = 0; 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 { #if GTK_CHECK_VERSION(3,0,0) if(GLOBALS->use_dark) { g_object_set(gtk_settings_get_default(), "gtk-application-prefer-dark-theme", TRUE, NULL); } #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); } g_signal_connect(XXX_GTK_OBJECT(GLOBALS->mainwindow), "delete_event", /* formerly was "destroy" */G_CALLBACK(file_quit_cmd_callback), "WM destroy"); gtk_widget_show(GLOBALS->mainwindow); } #ifdef WAVE_USE_XID else { #ifdef GDK_WINDOWING_X11 GLOBALS->mainwindow = gtk_plug_new(GLOBALS->socket_xid); gtk_widget_show(GLOBALS->mainwindow); g_signal_connect(XXX_GTK_OBJECT(GLOBALS->mainwindow), "destroy", /* formerly was "destroy" */G_CALLBACK(plug_destroy),"Plug destroy"); #else fprintf(stderr, "GTKWAVE | GtkPlug widget is unavailable\n"); exit(1); #endif } #endif } #ifdef MAC_INTEGRATION dock_pb = #endif make_pixmaps(GLOBALS->mainwindow); if(GLOBALS->use_toolbutton_interface) { GtkWidget *tb; GtkWidget *stock; #if !GTK_CHECK_VERSION(3,0,0) GtkStyle *style; #endif int tb_pos; if(!mainwindow_already_built) { main_vbox = XXX_gtk_vbox_new(FALSE, 5); gtk_container_set_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_XID if(GLOBALS->socket_xid) kill_main_menu_accelerators(); #endif menubar = alt_menu_top(GLOBALS->mainwindow); #ifndef WAVE_ALLOW_GTK3_HEADER_BAR gtk_widget_show(menubar); #endif #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 !GTK_CHECK_VERSION(3,0,0) 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 #endif { #ifndef WAVE_ALLOW_GTK3_HEADER_BAR gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0); #endif } } whole_table = XXX_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 !GTK_CHECK_VERSION(3,0,0) if(GLOBALS->force_toolbars) { toolhandle=gtk_handle_box_new(); gtk_widget_show(toolhandle); gtk_container_add(GTK_CONTAINER(toolhandle), top_table); } #endif #ifdef WAVE_ALLOW_GTK3_HEADER_BAR GLOBALS->main_popup_menu_button = stock = XXX_gtk_toolbar_insert_stock(GTK_TOOLBAR(tb), "open-menu-symbolic", "Menu", NULL, G_CALLBACK(do_popup_main_menu), NULL, tb_pos++); gtk_widget_show(stock); #endif stock = XXX_gtk_toolbar_insert_stock(GTK_TOOLBAR(tb), XXX_GTK_STOCK_CUT, "Cut Traces", NULL, G_CALLBACK(menu_cut_traces), NULL, tb_pos++); #if !GTK_CHECK_VERSION(3,0,0) style = gtk_widget_get_style(stock); style->xthickness = style->ythickness = 0; gtk_widget_set_style (stock, style); #endif gtk_widget_show(stock); stock = XXX_gtk_toolbar_insert_stock(GTK_TOOLBAR(tb), XXX_GTK_STOCK_COPY, "Copy Traces", NULL, G_CALLBACK(menu_copy_traces), NULL, tb_pos++); #if !GTK_CHECK_VERSION(3,0,0) style = gtk_widget_get_style(stock); style->xthickness = style->ythickness = 0; gtk_widget_set_style (stock, style); #endif gtk_widget_show(stock); stock = XXX_gtk_toolbar_insert_stock(GTK_TOOLBAR(tb), XXX_GTK_STOCK_PASTE, "Paste Traces", NULL, G_CALLBACK(menu_paste_traces), NULL, tb_pos++); #if !GTK_CHECK_VERSION(3,0,0) style = gtk_widget_get_style(stock); style->xthickness = style->ythickness = 0; gtk_widget_set_style (stock, style); #endif gtk_widget_show(stock); XXX_gtk_toolbar_insert_space(GTK_TOOLBAR(tb), tb_pos++); stock = XXX_gtk_toolbar_insert_stock(GTK_TOOLBAR(tb), XXX_GTK_STOCK_ZOOM_FIT, "Zoom Fit", NULL, G_CALLBACK(service_zoom_fit), NULL, tb_pos++); #if !GTK_CHECK_VERSION(3,0,0) style = gtk_widget_get_style(stock); style->xthickness = style->ythickness = 0; gtk_widget_set_style (stock, style); #endif gtk_widget_show(stock); stock = XXX_gtk_toolbar_insert_stock(GTK_TOOLBAR(tb), XXX_GTK_STOCK_ZOOM_IN, "Zoom In", NULL, G_CALLBACK(service_zoom_in), NULL, tb_pos++); #if !GTK_CHECK_VERSION(3,0,0) style = gtk_widget_get_style(stock); style->xthickness = style->ythickness = 0; gtk_widget_set_style (stock, style); #endif gtk_widget_show(stock); stock = XXX_gtk_toolbar_insert_stock(GTK_TOOLBAR(tb), XXX_GTK_STOCK_ZOOM_OUT, "Zoom Out", NULL, G_CALLBACK(service_zoom_out), NULL, tb_pos++); #if !GTK_CHECK_VERSION(3,0,0) style = gtk_widget_get_style(stock); style->xthickness = style->ythickness = 0; gtk_widget_set_style (stock, style); #endif gtk_widget_show(stock); stock = XXX_gtk_toolbar_insert_stock(GTK_TOOLBAR(tb), XXX_GTK_STOCK_UNDO, "Zoom Undo", NULL, G_CALLBACK(service_zoom_undo), NULL, tb_pos++); #if !GTK_CHECK_VERSION(3,0,0) style = gtk_widget_get_style(stock); style->xthickness = style->ythickness = 0; gtk_widget_set_style (stock, style); #endif gtk_widget_show(stock); stock = XXX_gtk_toolbar_insert_stock(GTK_TOOLBAR(tb), XXX_GTK_STOCK_GOTO_FIRST, "Zoom to Start", NULL, G_CALLBACK(service_zoom_left), NULL, tb_pos++); #if !GTK_CHECK_VERSION(3,0,0) style = gtk_widget_get_style(stock); style->xthickness = style->ythickness = 0; gtk_widget_set_style (stock, style); #endif gtk_widget_show(stock); stock = XXX_gtk_toolbar_insert_stock(GTK_TOOLBAR(tb), XXX_GTK_STOCK_GOTO_LAST, "Zoom to End", NULL, G_CALLBACK(service_zoom_right), NULL, tb_pos++); #if !GTK_CHECK_VERSION(3,0,0) style = gtk_widget_get_style(stock); style->xthickness = style->ythickness = 0; gtk_widget_set_style (stock, style); #endif gtk_widget_show(stock); XXX_gtk_toolbar_insert_space(GTK_TOOLBAR(tb), tb_pos++); stock = XXX_gtk_toolbar_insert_stock(GTK_TOOLBAR(tb), XXX_GTK_STOCK_GO_BACK, "Find Previous Edge", NULL, G_CALLBACK(service_left_edge), NULL, tb_pos++); #if !GTK_CHECK_VERSION(3,0,0) style = gtk_widget_get_style(stock); style->xthickness = style->ythickness = 0; gtk_widget_set_style (stock, style); #endif gtk_widget_show(stock); stock = XXX_gtk_toolbar_insert_stock(GTK_TOOLBAR(tb), XXX_GTK_STOCK_GO_FORWARD, "Find Next Edge", NULL, G_CALLBACK(service_right_edge), NULL, tb_pos++); #if !GTK_CHECK_VERSION(3,0,0) style = gtk_widget_get_style(stock); style->xthickness = style->ythickness = 0; gtk_widget_set_style (stock, style); #endif gtk_widget_show(stock); XXX_gtk_toolbar_insert_space(GTK_TOOLBAR(tb), tb_pos++); entry = create_entry_box(); gtk_widget_show(entry); XXX_gtk_toolbar_insert_widget(GTK_TOOLBAR(tb), entry, NULL, NULL, tb_pos++); XXX_gtk_toolbar_insert_space(GTK_TOOLBAR(tb), tb_pos++); if((GLOBALS->loaded_file_type != DUMPLESS_FILE)&&(!GLOBALS->disable_menus)) { stock = XXX_gtk_toolbar_insert_stock(GTK_TOOLBAR(tb), XXX_GTK_STOCK_REFRESH, "Reload", NULL, G_CALLBACK(menu_reload_waveform_marshal), NULL, tb_pos++); #if !GTK_CHECK_VERSION(3,0,0) style = gtk_widget_get_style(stock); style->xthickness = style->ythickness = 0; gtk_widget_set_style (stock, style); #endif gtk_widget_show(stock); XXX_gtk_toolbar_insert_space(GTK_TOOLBAR(tb), tb_pos++); } timebox = create_time_box(); gtk_widget_show (timebox); XXX_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) { #ifndef WAVE_ALLOW_GTK3_HEADER_BAR gtk_widget_set_sensitive(GLOBALS->missing_file_toolbar, FALSE); #else GList *chld = gtk_container_get_children (GTK_CONTAINER(GLOBALS->missing_file_toolbar)); GList *p = chld; while(p) { GtkWidget *wp = p->data; if(p != chld) gtk_widget_set_sensitive(GTK_WIDGET(wp), FALSE); p = p->next; } g_list_free(chld); #endif } } /* of ...if(mainwindow_already_built) */ } else { if(!mainwindow_already_built) { main_vbox = XXX_gtk_vbox_new(FALSE, 5); gtk_container_set_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) { menubar = alt_menu_top(GLOBALS->mainwindow); 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 !GTK_CHECK_VERSION(3,0,0) 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 #endif { gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0); } } top_table = XXX_gtk_table_new (1, 284, FALSE); #if !GTK_CHECK_VERSION(3,0,0) if(GLOBALS->force_toolbars) { toolhandle=gtk_handle_box_new(); gtk_widget_show(toolhandle); gtk_container_add(GTK_CONTAINER(toolhandle), top_table); } #endif whole_table = XXX_gtk_table_new (256, 16, FALSE); text1 = create_text (); XXX_gtk_table_attach (XXX_GTK_TABLE (top_table), text1, 0, 141, 0, 1, GTK_FILL, GTK_FILL | GTK_SHRINK, 0, 0); gtk_widget_set_size_request(GTK_WIDGET(text1), 200, -1); gtk_widget_show (text1); dummy1=gtk_label_new(""); XXX_gtk_table_attach (XXX_GTK_TABLE (top_table), dummy1, 141, 171, 0, 1, GTK_FILL, GTK_SHRINK, 0, 0); gtk_widget_show (dummy1); zoombuttons = create_zoom_buttons (); XXX_gtk_table_attach (XXX_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 (); XXX_gtk_table_attach (XXX_GTK_TABLE (top_table), pagebuttons, 173, 174, 0, 1, GTK_FILL, GTK_SHRINK, 0, 0); gtk_widget_show (pagebuttons); fetchbuttons = create_fetch_buttons (); XXX_gtk_table_attach (XXX_GTK_TABLE (top_table), fetchbuttons, 174, 175, 0, 1, GTK_FILL, GTK_SHRINK, 0, 0); gtk_widget_show (fetchbuttons); discardbuttons = create_discard_buttons (); XXX_gtk_table_attach (XXX_GTK_TABLE (top_table), discardbuttons, 175, 176, 0, 1, GTK_FILL, GTK_SHRINK, 0, 0); gtk_widget_show (discardbuttons); shiftbuttons = create_shift_buttons (); XXX_gtk_table_attach (XXX_GTK_TABLE (top_table), shiftbuttons, 176, 177, 0, 1, GTK_FILL, GTK_SHRINK, 0, 0); gtk_widget_show (shiftbuttons); } edgebuttons = create_edge_buttons (); XXX_gtk_table_attach (XXX_GTK_TABLE (top_table), edgebuttons, 177, 178, 0, 1, GTK_FILL, GTK_SHRINK, 0, 0); gtk_widget_show (edgebuttons); dummy2=gtk_label_new(""); XXX_gtk_table_attach (XXX_GTK_TABLE (top_table), dummy2, 178, 215, 0, 1, GTK_FILL, GTK_SHRINK, 0, 0); gtk_widget_show (dummy2); entry = create_entry_box(); XXX_gtk_table_attach (XXX_GTK_TABLE (top_table), entry, 215, 216, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0); gtk_widget_show(entry); timebox = create_time_box(); XXX_gtk_table_attach (XXX_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_pixbuf = gtk_image_new_from_pixbuf (GLOBALS->redo_pixbuf); GtkWidget *main_vbox1; GtkWidget *table, *table2; GtkWidget *b1, *frame; gtk_widget_show(r_pixbuf); table = XXX_gtk_table_new (1, 1, FALSE); main_vbox1 = XXX_gtk_vbox_new (FALSE, 1); gtk_container_set_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 = XXX_gtk_table_new (2, 1, FALSE); b1 = gtk_button_new(); gtk_container_add(GTK_CONTAINER(b1), r_pixbuf); XXX_gtk_table_attach (XXX_GTK_TABLE (table2), b1, 0, 1, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); g_signal_connect_swapped (XXX_GTK_OBJECT (b1), "clicked", G_CALLBACK(menu_reload_waveform_marshal), XXX_GTK_OBJECT (table2)); gtk_tooltips_set_tip_2(b1, "Reload waveform"); gtk_widget_show(b1); gtk_container_add (GTK_CONTAINER (frame), table2); gtk_widget_show(table2); XXX_gtk_table_attach (XXX_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_size_request(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_size_request(GTK_WIDGET(GLOBALS->signalwindow), os+30, -1); } } gtk_widget_show(GLOBALS->signalwindow); if((!GLOBALS->hide_sst)&&(GLOBALS->loaded_file_type != MISSING_FILE)) { GLOBALS->toppanedwindow = XXX_gtk_hpaned_new(0); GLOBALS->sstpane = treeboxframe("SST", G_CALLBACK(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); } GLOBALS->panedwindow = panedwindow = XXX_gtk_hpaned_new(0); 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((!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); } if(GLOBALS->treeopen_chain_head) { struct string_chain_t *t = GLOBALS->treeopen_chain_head; struct string_chain_t *t2; while(t) { if(GLOBALS->treestore_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; } if(!mainwindow_already_built) { gtk_widget_show(top_table); #ifdef WAVE_ALLOW_GTK3_HEADER_BAR GLOBALS->top_table = top_table; #endif #if GTK_CHECK_VERSION(3,0,0) XXX_gtk_table_attach (XXX_GTK_TABLE (whole_table), top_table, 0, 16, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 0); #else XXX_gtk_table_attach (XXX_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); #endif if(!GLOBALS->do_resize_signals) { int dri; for(dri=0;dri<2;dri++) { GLOBALS->signalwindow_width_dirty=1; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } } 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 */ g_signal_connect(XXX_GTK_OBJECT(GLOBALS->notebook), "switch-page", G_CALLBACK(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); } XXX_gtk_table_attach (XXX_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); #if GTK_CHECK_VERSION(3,0,0) gtk_box_pack_end(GTK_BOX(main_vbox), whole_table, TRUE, TRUE, 0); /* prevents shrinkage of signal/waves windows if no waves loaded */ #else gtk_container_add (GTK_CONTAINER (main_vbox), whole_table); #endif 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 #if defined(HAVE_LIBTCL) && GLOBALS->interp #endif ) { execute_script(scriptfile, 1); /* deallocate the name in the script because context might swap out from under us! */ scriptfile=NULL; } #if defined(WAVE_HAVE_GCONF) || defined(WAVE_HAVE_GSETTINGS) 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(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); gtk_adjustment_set_value(hadj, 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 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); } 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; gtk_window_get_position(GTK_WINDOW(GLOBALS->mainwindow), root_x, root_y); if(!GLOBALS->initial_window_get_valid) { if((gtk_widget_get_window(GLOBALS->mainwindow))) { 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; } } } 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__ 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; } gtk_window_move(GTK_WINDOW(GLOBALS->mainwindow), GLOBALS->initial_window_xpos, GLOBALS->initial_window_ypos); 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 */ 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); } void activate_stems_reader(char *stems_name) { #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; struct gtkwave_annotate_ipc_t *anno_ctx = shmat(shmid, NULL, 0); if(anno_ctx != (void *) -1) { pid_t pid; GLOBALS->anno_ctx = anno_ctx; 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"); } } #if !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-gtk3-3.3.125/src/treesearch.c0000664000175000017500000022306115047725113016602 0ustar bybellbybell/* * Copyright (c) Tristan Gingold and Tony Bybell 2006-2017. * * 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 "gtk23compat.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" 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 XXX_create_sst_nodes_if_necessary(GtkTreeModel *model, GtkTreeIter *iter, GtkTreePath *path) { #ifndef WAVE_DISABLE_FAST_TREE struct tree *t; gtk_tree_model_get(model, iter, XXX_TREE_COLUMN, &t, -1); if(t->child) { GtkTreePath *path2 = gtk_tree_path_copy(path); GtkTreeIter iter2; gtk_tree_path_down(path2); while(path2) { if (!gtk_tree_model_get_iter(model, &iter2, path2)) { break; } gtk_tree_model_get(model, &iter2, XXX_TREE_COLUMN, &t, -1); if(t->t_which < 0) { if(!t->children_in_gui) { GtkTreeIter iter2_copy = iter2; t->children_in_gui = 1; if(t->child) XXX_maketree2(&iter2_copy, t->child, 0); } } gtk_tree_path_next(path2); } gtk_tree_path_free(path2); } #endif } int force_open_tree_node(char *name, int keep_path_nodes_open, struct tree **t_pnt) { GtkTreeModel *model = GTK_TREE_MODEL(GLOBALS->treestore_main); GtkTreeIter iter; int rv = SST_NODE_NOT_EXIST; /* can possibly open */ if(model && gtk_tree_model_get_iter_first(model, &iter)) { if (1) { int namlen = strlen (name); char *namecache = wave_alloca (namlen + 1); char *name_end = name + namlen - 1; char *zap = name; int depth = 1; strcpy (namecache, name); for (;;) { struct tree *t; gtk_tree_model_get(model, &iter, XXX_TREE_COLUMN, &t, -1); 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) { GtkTreePath *path = gtk_tree_model_get_path (model, &iter); GtkTreePath *path2 = gtk_tree_model_get_path (model, &iter); gboolean *exphist = wave_alloca (depth * sizeof (gboolean)); GtkTreePath **pathhist = wave_alloca (depth * sizeof (GtkTreePath *)); int i = depth - 1; memset(exphist, 0, depth * sizeof (gboolean)); /* scan-build */ memset(pathhist, 0, depth * sizeof (GtkTreePath *)); /* scan-build */ while(gtk_tree_path_up(path2)) { exphist[i] = gtk_tree_view_row_expanded(GTK_TREE_VIEW(GLOBALS->treeview_main), path2); pathhist[i] = gtk_tree_path_copy(path2); i--; } gtk_tree_path_free(path2); for(i=0;itreeview_main), pathhist[i], 0); } gtk_tree_view_expand_row(GTK_TREE_VIEW(GLOBALS->treeview_main), path, 0); for (i = depth - 1; i >= 0; i--) /* collapse back up */ { if(!keep_path_nodes_open && !exphist[i]) { gtk_tree_view_collapse_row(GTK_TREE_VIEW(GLOBALS->treeview_main), pathhist[i]); } gtk_tree_path_free(pathhist[i]); } gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW(GLOBALS->treeview_main), path, NULL, TRUE, 0.5, 0.5); gtk_tree_path_free(path); rv = SST_NODE_FOUND; /* opened */ GLOBALS->open_tree_nodes = xl_insert (namecache, GLOBALS->open_tree_nodes, NULL); return rv; /* break; */ } else { depth++; GtkTreePath *path = gtk_tree_model_get_path (model, &iter); XXX_create_sst_nodes_if_necessary (model, &iter, path); gtk_tree_path_down(path); gboolean child_exists = gtk_tree_model_get_iter(model, &iter, path); gtk_tree_path_free(path); if (!child_exists) { break; } name = ++zap; continue; } } if(!gtk_tree_model_iter_next (model, &iter)) { return(rv); } } } } return(SST_TREE_NOT_EXIST); } 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); } } void select_tree_node(char *name) { GtkTreeModel *model = GTK_TREE_MODEL(GLOBALS->treestore_main); GtkTreeIter iter; if(model && gtk_tree_model_get_iter_first(model, &iter)) { if (1) { int namlen = strlen (name); char *namecache = wave_alloca (namlen + 1); char *name_end = name + namlen - 1; char *zap = name; int depth = 1; strcpy (namecache, name); for (;;) { struct tree *t; gtk_tree_model_get(model, &iter, XXX_TREE_COLUMN, &t, -1); 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); */ GtkTreePath *path = gtk_tree_model_get_path (model, &iter); gtk_tree_view_set_cursor (GTK_TREE_VIEW(GLOBALS->treeview_main), path, NULL, FALSE); gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW(GLOBALS->treeview_main), path, NULL, TRUE, 0.5, 0.5); gtk_tree_path_free(path); GLOBALS->sst_sig_root_treesearch_gtk2_c_1 = t; GLOBALS->sig_root_treesearch_gtk2_c_1 = t->child; fill_sig_store (); return; } else { depth++; GtkTreePath *path = gtk_tree_model_get_path (model, &iter); XXX_create_sst_nodes_if_necessary (model, &iter, path); gtk_tree_path_down(path); gboolean child_exists = gtk_tree_model_get_iter(model, &iter, path); gtk_tree_path_free(path); if (!child_exists) { break; } name = ++zap; continue; } } if(!gtk_tree_model_iter_next (model, &iter)) { return; } } } } } /* Callbacks for tree area when a row is selected/deselected. */ static void XXX_select_row_callback( GtkTreeModel *model, GtkTreePath *path) { GtkTreeIter iter; struct tree *t; struct tree **gctr; int depth, i; int len = 1; char *tstring; char hier_suffix[2]; GtkTreePath *path2; if (!gtk_tree_model_get_iter(model, &iter, path)) { return; /* path describes a non-existing row - should not happen */ } hier_suffix[0] = GLOBALS->hier_delimeter; hier_suffix[1] = 0; depth = gtk_tree_store_iter_depth (GLOBALS->treestore_main, &iter); depth++; path2 = gtk_tree_path_copy(path); gctr = wave_alloca(depth * sizeof(struct tree *)); for(i=depth-1;i>=0;i--) { gtk_tree_model_get_iter(model, &iter, path2); gtk_tree_model_get(model, &iter, XXX_TREE_COLUMN, &gctr[i], -1); t = gctr[i]; len += (strlen(t->name) + 1); gtk_tree_path_up (path2); } gtk_tree_path_free(path2); tstring = wave_alloca(len); memset(tstring, 0, len); for(i=0;iname); strcat(tstring, hier_suffix); } if(GLOBALS->selected_hierarchy_name) { free_2(GLOBALS->selected_hierarchy_name); } GLOBALS->selected_hierarchy_name = strdup_2(tstring); t = gctr[depth-1]; 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 XXX_unselect_row_callback( GtkTreeModel *model, GtkTreePath *path) { GtkTreeIter iter; struct tree *t; if (!gtk_tree_model_get_iter(model, &iter, path)) { return; /* path describes a non-existing row - should not happen */ } 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; } gtk_tree_model_get(model, &iter, XXX_TREE_COLUMN, &t, -1); 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_KEY_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; } static gboolean XXX_view_selection_func (GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean path_currently_selected, gpointer userdata) { (void) selection; (void) userdata; if(!path_currently_selected) { XXX_select_row_callback(model, path); } else { XXX_unselect_row_callback(model, path); } return(TRUE); } static void XXX_generic_tree_expand_collapse_callback(int is_expand, GtkTreeModel *model, GtkTreeIter *iter, GtkTreePath *path) { struct tree *t; struct tree **gctr; int depth, i; int len = 1; char *tstring; char hier_suffix[2]; GtkTreePath *path2; int found; if (!gtk_tree_model_get_iter(model, iter, path)) { return; /* path describes a non-existing row - should not happen */ } hier_suffix[0] = GLOBALS->hier_delimeter; hier_suffix[1] = 0; depth = gtk_tree_store_iter_depth (GLOBALS->treestore_main, iter); depth++; path2 = gtk_tree_path_copy(path); gctr = wave_alloca(depth * sizeof(struct tree *)); for(i=depth-1;i>=0;i--) { gtk_tree_model_get_iter(model, iter, path2); gtk_tree_model_get(model, iter, XXX_TREE_COLUMN, &gctr[i], -1); t = gctr[i]; len += (strlen(t->name) + 1); gtk_tree_path_up (path2); } gtk_tree_path_free(path2); tstring = wave_alloca(len); memset(tstring, 0, len); for(i=0;iname); 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 XXX_tree_expand_callback(GtkTreeView *tree_view, GtkTreeIter *iter, GtkTreePath *path, gpointer user_data) { (void) tree_view; (void) user_data; XXX_create_sst_nodes_if_necessary(gtk_tree_view_get_model(GTK_TREE_VIEW(GLOBALS->treeview_main)), iter, path); XXX_generic_tree_expand_collapse_callback(1, gtk_tree_view_get_model(GTK_TREE_VIEW(GLOBALS->treeview_main)), iter, path); #ifdef WAVE_GTK3_SIZE_ALLOCATE_WORKAROUND_TREESEARCH gtk_widget_queue_resize(GTK_WIDGET(GLOBALS->treeview_main)); #endif #ifdef WAVE_ALLOW_QUARTZ_FLUSH_WORKAROUND #ifdef MAC_INTEGRATION /* workaround for ctree not rendering properly in OSX */ gtk_widget_hide(GTK_WIDGET(GLOBALS->treeview_main)); gtk_widget_show(GTK_WIDGET(GLOBALS->treeview_main)); #endif #endif } static void XXX_tree_collapse_callback(GtkTreeView *tree_view, GtkTreeIter *iter, GtkTreePath *path, gpointer user_data) { (void) tree_view; (void) user_data; XXX_generic_tree_expand_collapse_callback(0, gtk_tree_view_get_model(GTK_TREE_VIEW(GLOBALS->treeview_main)), iter, path); #ifdef WAVE_ALLOW_QUARTZ_FLUSH_WORKAROUND #ifdef MAC_INTEGRATION /* workaround for ctree not rendering properly in OSX */ gtk_widget_hide(GTK_WIDGET(GLOBALS->treeview_main)); gtk_widget_show(GTK_WIDGET(GLOBALS->treeview_main)); #endif #endif } /* * 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_KEY_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); } /***************************************************************************/ /* Callback for insert/replace/append buttions. This call-back is called for every signal selected. */ static void sig_selection_foreach (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) { (void)path; (void)data; struct tree *sel; /* const enum sst_cb_action action = (enum sst_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 sst_cb_action action = (enum sst_cb_action)data; if (action == SST_ACTION_REPLACE || action == SST_ACTION_INSERT || action == SST_ACTION_PREPEND) { Trptr tfirst=NULL, tlast=NULL; Trptr t; Trptr *tp = NULL; int numhigh = 0; int it; if (action == SST_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 == SST_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 == SST_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 == SST_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 sst_cb_action action = (enum sst_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 sst_cb_action action) { if(action == SST_ACTION_NONE) return; /* only used for double-click in signals pane of SST */ 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 == SST_ACTION_INSERT || action == SST_ACTION_REPLACE || action == SST_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 == SST_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 (SST_ACTION_INSERT); set_window_idle(widget); } static void replace_callback(GtkWidget *widget, GtkWidget *nothing) { (void)nothing; set_window_busy(widget); action_callback (SST_ACTION_REPLACE); set_window_idle(widget); } static void ok_callback(GtkWidget *widget, GtkWidget *nothing) { (void)nothing; set_window_busy(widget); action_callback (SST_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->treeview_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); action_callback(GLOBALS->sst_dbl_action_type); } } 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, GCallback func, GtkWidget *old_window) { GtkWidget *scrolled_win, *sig_scroll_win; GtkWidget *hbox; GtkWidget *button1, *button2, *button4, *button5; GtkWidget *frameh, *sig_frame; GtkWidget *vbox, *vpan, *filter_hbox; GtkWidget *filter_label; GtkWidget *sig_view; /* fix problem where ungrab doesn't occur if button pressed + simultaneous accelerator key occurs */ if(GLOBALS->in_button_press_wavewindow_c_1) { XXX_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(gtk_widget_get_window(GLOBALS->window_treesearch_gtk2_c_12)); } else { if(GLOBALS->expanderwindow) { gtk_expander_set_expanded(GTK_EXPANDER(GLOBALS->expanderwindow), TRUE); } } 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(XXX_GTK_OBJECT (GLOBALS->window_treesearch_gtk2_c_12), "delete_event",(GCallback) destroy_callback, NULL); do_tooltips: GLOBALS->treesearch_gtk2_window_vbox = vbox = XXX_gtk_vbox_new (FALSE, 1); gtk_widget_show (vbox); vpan = XXX_gtk_vpaned_new (0); gtk_widget_show (vpan); #if GTK_CHECK_VERSION(3,0,0) gtk_widget_set_vexpand(vpan, TRUE); #endif gtk_box_pack_start (GTK_BOX (vbox), vpan, TRUE, TRUE, 1); /* Hierarchy. */ GLOBALS->gtk2_tree_frame = gtk_frame_new (NULL); gtk_container_set_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); decorated_module_cleanup(); XXX_maketree(NULL, GLOBALS->treeroot); gtk_tree_selection_set_select_function (gtk_tree_view_get_selection(GTK_TREE_VIEW(GLOBALS->treeview_main)), XXX_view_selection_func, NULL, NULL); gtk_tree_selection_set_mode (gtk_tree_view_get_selection(GTK_TREE_VIEW(GLOBALS->treeview_main)), GTK_SELECTION_SINGLE); gtkwave_signal_connect_object (XXX_GTK_OBJECT (GLOBALS->treeview_main), "row-expanded", G_CALLBACK(XXX_tree_expand_callback), NULL); gtkwave_signal_connect_object (XXX_GTK_OBJECT (GLOBALS->treeview_main), "row-collapsed", G_CALLBACK(XXX_tree_collapse_callback), NULL); scrolled_win = gtk_scrolled_window_new (NULL, NULL); gtk_widget_set_size_request( 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->treeview_main)); gtk_container_add (GTK_CONTAINER (GLOBALS->gtk2_tree_frame), scrolled_win); gtkwave_signal_connect(XXX_GTK_OBJECT(GLOBALS->gtk2_tree_frame), "button_press_event",G_CALLBACK(hier_top_button_press_event_std), NULL); /* 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(XXX_GTK_OBJECT(sig_view), "button_press_event",G_CALLBACK(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); } /* fallthrough */ 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(XXX_GTK_OBJECT(sig_view), "button_press_event",G_CALLBACK(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_set_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_size_request (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 = XXX_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(XXX_GTK_OBJECT(GLOBALS->filter_entry), "activate", G_CALLBACK(press_callback), NULL); if(!GLOBALS->do_dynamic_treefilter) { gtkwave_signal_connect(XXX_GTK_OBJECT (GLOBALS->filter_entry), "key_press_event", (GCallback) filter_edit_cb, NULL); } else { gtkwave_signal_connect(XXX_GTK_OBJECT(GLOBALS->filter_entry), "changed", G_CALLBACK(press_callback), NULL); } gtk_tooltips_set_tip_2(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." ); 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_set_border_width (GTK_CONTAINER (frameh), 3); gtk_widget_show(frameh); gtk_box_pack_start (GTK_BOX (vbox), frameh, FALSE, FALSE, 1); hbox = XXX_gtk_hbox_new (FALSE, 1); gtk_widget_show (hbox); button1 = gtk_button_new_with_label ("Append"); gtk_container_set_border_width (GTK_CONTAINER (button1), 3); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button1), "clicked",G_CALLBACK(ok_callback),XXX_GTK_OBJECT (GLOBALS->window_treesearch_gtk2_c_12)); gtk_widget_show (button1); gtk_tooltips_set_tip_2(button1, "Add selected signal hierarchy to end of the display on the main window."); gtk_box_pack_start (GTK_BOX (hbox), button1, TRUE, FALSE, 0); button2 = gtk_button_new_with_label (" Insert "); gtk_container_set_border_width (GTK_CONTAINER (button2), 3); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button2), "clicked",G_CALLBACK(insert_callback),XXX_GTK_OBJECT (GLOBALS->window_treesearch_gtk2_c_12)); gtk_widget_show (button2); gtk_tooltips_set_tip_2(button2, "Add selected signal hierarchy after last highlighted signal on the main window."); gtk_box_pack_start (GTK_BOX (hbox), button2, TRUE, FALSE, 0); button4 = gtk_button_new_with_label (" Replace "); gtk_container_set_border_width (GTK_CONTAINER (button4), 3); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button4), "clicked",G_CALLBACK(replace_callback),XXX_GTK_OBJECT (GLOBALS->window_treesearch_gtk2_c_12)); gtk_widget_show (button4); gtk_tooltips_set_tip_2(button4, "Replace highlighted signals on the main window with signals selected above."); gtk_box_pack_start (GTK_BOX (hbox), button4, TRUE, FALSE, 0); button5 = gtk_button_new_with_label (" Exit "); gtk_container_set_border_width (GTK_CONTAINER (button5), 3); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button5), "clicked",G_CALLBACK(destroy_callback),XXX_GTK_OBJECT (GLOBALS->window_treesearch_gtk2_c_12)); gtk_tooltips_set_tip_2(button5, "Do nothing and return to the main window."); 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, GCallback func) { (void)title; GtkWidget *scrolled_win, *sig_scroll_win; GtkWidget *hbox; GtkWidget *button1, *button2, *button4; GtkWidget *sig_frame; GtkWidget *vbox, *vpan, *filter_hbox; GtkWidget *filter_label; GtkWidget *sig_view; GLOBALS->is_active_treesearch_gtk2_c_6=1; GLOBALS->cleanup_treesearch_gtk2_c_8=func; /* create a new modal window */ vbox = XXX_gtk_vbox_new (FALSE, 1); gtk_widget_show (vbox); vpan = XXX_gtk_vpaned_new (0); /* 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); #if GTK_CHECK_VERSION(3,0,0) gtk_widget_set_vexpand(vpan, TRUE); /* needed for gtk3, otherwise box does not grow vertically */ #endif /* Hierarchy. */ GLOBALS->gtk2_tree_frame = gtk_frame_new (NULL); gtk_container_set_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); decorated_module_cleanup(); XXX_maketree(NULL, GLOBALS->treeroot); gtk_tree_selection_set_select_function (gtk_tree_view_get_selection(GTK_TREE_VIEW(GLOBALS->treeview_main)), XXX_view_selection_func, NULL, NULL); gtk_tree_selection_set_mode (gtk_tree_view_get_selection(GTK_TREE_VIEW(GLOBALS->treeview_main)), GTK_SELECTION_SINGLE); gtkwave_signal_connect_object (XXX_GTK_OBJECT (GLOBALS->treeview_main), "row-expanded", G_CALLBACK(XXX_tree_expand_callback), NULL); gtkwave_signal_connect_object (XXX_GTK_OBJECT (GLOBALS->treeview_main), "row-collapsed", G_CALLBACK(XXX_tree_collapse_callback), NULL); scrolled_win = gtk_scrolled_window_new (NULL, NULL); gtk_widget_set_size_request( 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->treeview_main)); gtkwave_signal_connect(XXX_GTK_OBJECT(GLOBALS->treeview_main), "button_press_event",G_CALLBACK(hier_top_button_press_event_std), NULL); 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(XXX_GTK_OBJECT(sig_view), "button_press_event",G_CALLBACK(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); } /* fallthrough */ 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(XXX_GTK_OBJECT(sig_view), "button_press_event",G_CALLBACK(button_press_event_std), NULL); } GLOBALS->dnd_sigview = sig_view; sig_frame = gtk_frame_new (NULL); gtk_container_set_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_size_request (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 = XXX_gtk_hbox_new (FALSE, 1); gtk_container_set_border_width (GTK_CONTAINER (filter_hbox), 2); gtk_widget_show (filter_hbox); #if GTK_CHECK_VERSION(3,0,0) GLOBALS->filter_entry = gtk_search_entry_new (); #else GLOBALS->filter_entry = gtk_entry_new (); #endif 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(XXX_GTK_OBJECT(GLOBALS->filter_entry), "activate", G_CALLBACK(press_callback), NULL); if(!GLOBALS->do_dynamic_treefilter) { gtkwave_signal_connect(XXX_GTK_OBJECT (GLOBALS->filter_entry), "key_press_event", (GCallback) filter_edit_cb, NULL); } else { gtkwave_signal_connect(XXX_GTK_OBJECT(GLOBALS->filter_entry), "changed", G_CALLBACK(press_callback), NULL); } gtk_tooltips_set_tip_2(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." ); gtk_box_pack_start (GTK_BOX (filter_hbox), GLOBALS->filter_entry, TRUE, TRUE, 1); gtk_box_pack_start (GTK_BOX (vbox), filter_hbox, FALSE, FALSE, 1); /* Buttons. */ hbox = XXX_gtk_hbox_new (FALSE, 1); gtk_widget_show (hbox); button1 = gtk_button_new_with_label ("Append"); gtk_container_set_border_width (GTK_CONTAINER (button1), 3); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button1), "clicked", G_CALLBACK(ok_callback), XXX_GTK_OBJECT (GLOBALS->gtk2_tree_frame)); gtk_widget_show (button1); gtk_tooltips_set_tip_2(button1, "Add selected signal hierarchy to end of the display on the main window."); gtk_box_pack_start (GTK_BOX (hbox), button1, TRUE, FALSE, 0); button2 = gtk_button_new_with_label (" Insert "); gtk_container_set_border_width (GTK_CONTAINER (button2), 3); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button2), "clicked", G_CALLBACK(insert_callback), XXX_GTK_OBJECT (GLOBALS->gtk2_tree_frame)); gtk_widget_show (button2); gtk_tooltips_set_tip_2(button2, "Add selected signal hierarchy after last highlighted signal on the main window."); gtk_box_pack_start (GTK_BOX (hbox), button2, TRUE, FALSE, 0); button4 = gtk_button_new_with_label (" Replace "); gtk_container_set_border_width (GTK_CONTAINER (button4), 3); gtkwave_signal_connect_object (XXX_GTK_OBJECT (button4), "clicked", G_CALLBACK(replace_callback), XXX_GTK_OBJECT (GLOBALS->gtk2_tree_frame)); gtk_widget_show (button4); gtk_tooltips_set_tip_2(button4, "Replace highlighted signals on the main window with signals selected above."); gtk_box_pack_start (GTK_BOX (hbox), button4, TRUE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 1); 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->sig_view_search) { GLOBALS->tree_dnd_begin = SEARCH_TO_VIEW_DRAG_ACTIVE; } else { GLOBALS->tree_dnd_begin = TREE_TO_VIEW_DRAG_ACTIVE; } } } /* * DND "drag_failed" handler, this is called when a drag and drop has * failed (e.g., by pressing ESC). */ static gboolean DNDFailedCB( GtkWidget *widget, GdkDragContext *context, GtkDragResult result) { (void)widget; (void)context; (void)result; GLOBALS->dnd_state = 0; GLOBALS->tree_dnd_begin = VIEW_DRAG_INACTIVE; GLOBALS->tree_dnd_requested = 0; MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); return(FALSE); } /* * 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; gint xi, yi; /* Put any needed drag end cleanup code here. */ if(GLOBALS->dnd_tgt_on_signalarea_treesearch_gtk2_c_1) { WAVE_GDK_GET_POINTER(gtk_widget_get_window(GLOBALS->signalarea), &x, &y, &xi, &yi, &state); WAVE_GDK_GET_POINTER_COPY; GtkAllocation allocation; gtk_widget_get_allocation(GLOBALS->signalarea, &allocation); if((x<0)||(y<0)||(x>=allocation.width)||(y>=allocation.height)) return; } else if(GLOBALS->dnd_tgt_on_wavearea_treesearch_gtk2_c_1) { WAVE_GDK_GET_POINTER(gtk_widget_get_window(GLOBALS->wavearea), &x, &y, &xi, &yi, &state); WAVE_GDK_GET_POINTER_COPY; GtkAllocation allocation; gtk_widget_get_allocation(GLOBALS->wavearea, &allocation); if((x<0)||(y<0)||(x>=allocation.width)||(y>=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(SST_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 (SST_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(gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE) gdk_drag_status(dc, GDK_ACTION_MOVE, t); /* Only copy? */ else if(gdk_drag_context_get_actions(dc) == GDK_ACTION_COPY) gdk_drag_status(dc, GDK_ACTION_COPY, t); /* Only link? */ else if(gdk_drag_context_get_actions(dc) == GDK_ACTION_LINK) gdk_drag_status(dc, GDK_ACTION_LINK, t); /* Other action, check if listed in our actions list? */ else if(gdk_drag_context_get_actions(dc) & 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->sig_view_search) /* 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(gtk_selection_data_get_length(selection_data) < 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->sig_view_search) || /* 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 *)gtk_selection_data_get_data(selection_data)); #else if(!GLOBALS->dnd_helper_quartz) { GLOBALS->dnd_helper_quartz = strdup_2((const char *)gtk_selection_data_get_data(selection_data)); } #endif } } void DND_helper_quartz(char *data) { int num_found; if(!GLOBALS->splash_is_loading) { if(!GLOBALS->pFileChoose) { 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); } } else { MaxSignalLength(); signalarea_configure_event(GLOBALS->signalarea, NULL); wavearea_configure_event(GLOBALS->wavearea, NULL); } } } /* * 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_get_has_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(XXX_GTK_OBJECT(w), "drag_motion", G_CALLBACK(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(XXX_GTK_OBJECT(src), "drag_begin", G_CALLBACK(DNDBeginCB), win); gtkwave_signal_connect(XXX_GTK_OBJECT(src), "drag_end", G_CALLBACK(DNDEndCB), win); gtkwave_signal_connect(XXX_GTK_OBJECT(src), "drag_data_get", G_CALLBACK(DNDDataRequestCB), win); gtkwave_signal_connect(XXX_GTK_OBJECT(src), "drag_data_delete", G_CALLBACK(DNDDataDeleteCB), win); gtkwave_signal_connect(XXX_GTK_OBJECT(src), "drag_failed", G_CALLBACK(DNDFailedCB), win); } if(enable_receive) gtkwave_signal_connect(XXX_GTK_OBJECT(w), "drag_data_received", G_CALLBACK(DNDDataReceivedCB), win); } } /***************************************************************************/ static void recurse_append_callback(GtkWidget *widget, gpointer data) { int i; if(!GLOBALS->sst_sig_root_treesearch_gtk2_c_1 || !data) return; set_window_busy(widget); for(i=GLOBALS->fetchlow;i<=GLOBALS->fetchhigh;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=GLOBALS->fetchlow;i<=GLOBALS->fetchhigh;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=GLOBALS->fetchlow;i<=GLOBALS->fetchhigh;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 recurse_insert_callback(GtkWidget *widget, gpointer data) { Traces tcache; int i; if(!GLOBALS->sst_sig_root_treesearch_gtk2_c_1 || !data) return; memcpy(&tcache,&GLOBALS->traces,sizeof(Traces)); GLOBALS->traces.total=0; GLOBALS->traces.first=GLOBALS->traces.last=NULL; set_window_busy(widget); for(i=GLOBALS->fetchlow;i<=GLOBALS->fetchhigh;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=GLOBALS->fetchlow;i<=GLOBALS->fetchhigh;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=GLOBALS->fetchlow;i<=GLOBALS->fetchhigh;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 recurse_replace_callback(GtkWidget *widget, gpointer data) { Traces tcache; int i; Trptr tfirst=NULL, tlast=NULL; if(!GLOBALS->sst_sig_root_treesearch_gtk2_c_1 || !data) return; memcpy(&tcache,&GLOBALS->traces,sizeof(Traces)); GLOBALS->traces.total=0; GLOBALS->traces.first=GLOBALS->traces.last=NULL; set_window_busy(widget); for(i=GLOBALS->fetchlow;i<=GLOBALS->fetchhigh;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=GLOBALS->fetchlow;i<=GLOBALS->fetchhigh;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=GLOBALS->fetchlow;i<=GLOBALS->fetchhigh;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); } void recurse_import(GtkWidget *widget, guint callback_action) { if(GLOBALS->sst_sig_root_treesearch_gtk2_c_1) { int fz; GLOBALS->fetchlow = GLOBALS->fetchhigh = -1; if(GLOBALS->sst_sig_root_treesearch_gtk2_c_1->child) recurse_fetch_high_low(GLOBALS->sst_sig_root_treesearch_gtk2_c_1->child); fz = GLOBALS->fetchhigh - GLOBALS->fetchlow + 1; void (*func)(GtkWidget *, gpointer); switch(callback_action) { case WV_RECURSE_INSERT: func = recurse_insert_callback; break; case WV_RECURSE_REPLACE: func = recurse_replace_callback; break; case WV_RECURSE_APPEND: default: func = recurse_append_callback; break; } if((GLOBALS->fetchlow >= 0) && (GLOBALS->fetchhigh >= 0)) { widget = GLOBALS->mainwindow; /* otherwise using widget passed from the menu item crashes on OSX */ if(fz > WV_RECURSE_IMPORT_WARN) { char recwarn[128]; sprintf(recwarn, "Really import %d facilit%s?", fz, (fz==1)?"y":"ies"); simplereqbox("Recurse Warning",300,recwarn,"Yes", "No", G_CALLBACK(func), 0); } else { func(widget, (gpointer)1); } } } } /***************************************************************************/ void mkmenu_treesearch_cleanup(GtkWidget *widget, gpointer data) { (void)widget; (void)data; /* nothing */ } /***************************************************************************/ gtkwave-gtk3-3.3.125/src/fonts.c0000664000175000017500000001156415047725113015611 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 "gtk23compat.h" #include "currenttime.h" #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; 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) { GdkScreen *fonts_screen = gdk_screen_get_default(); 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; } /***/ gint font_engine_string_measure (struct font_engine_font_t *font, const gchar *string) { gint rc = 1; /* dummy value */ 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; } return(rc); } void load_all_fonts(void) { if(GLOBALS->use_pango_fonts) { pango_load_all_fonts(); } else { printf("GDK X11 fonts are no longer supported, exiting.\n"); exit(255); } } void XXX_font_engine_draw_string (cairo_t *cr, struct font_engine_font_t *font, wave_rgb_t *gc, gint x, gint y, const gchar *string) { /* 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); */ cairo_set_source_rgba (cr, gc->r, gc->g, gc->b, gc->a); cairo_move_to (cr, x, y-font->ascent); pango_cairo_show_layout (cr, GLOBALS->fonts_layout); } gtkwave-gtk3-3.3.125/src/main.h0000664000175000017500000000357315047725113015412 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); void wave_gtk_window_set_title(GtkWindow *window, const gchar *title, int typ, int pct); /* 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); void kill_stems_browser(void); 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-gtk3-3.3.125/src/treesearch.h0000664000175000017500000000230715047725113016605 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2010-2017 * * 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, GCallback func, GtkWidget *old_window); GtkWidget* treeboxframe(char *title, GCallback 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 */ int treebox_is_active(void); void DND_helper_quartz(char *data); void recurse_import(GtkWidget *widget, guint callback_action); #define WV_RECURSE_IMPORT_WARN (0) enum sst_cb_action { SST_ACTION_INSERT, SST_ACTION_REPLACE, SST_ACTION_APPEND, SST_ACTION_PREPEND, SST_ACTION_NONE }; #endif gtkwave-gtk3-3.3.125/src/wavewindow.c0000664000175000017500000047712315047725113016661 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2019. * * 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 "gtk23compat.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 #define WAVE_CAIRO_050_OFFSET (GLOBALS->cairo_050_offset) 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 */ #ifndef WAVE_ALLOW_GTK3_SEAT_VS_POINTER_GRAB_UNGRAB static const GdkEventMask m_bmask[4]= {0, GDK_BUTTON1_MOTION_MASK, 0, GDK_BUTTON3_MOTION_MASK }; /* button 1, 3 motion encodings */ #endif void wavewindow_paint(cairo_t *cr) { int scale_factor = XXX_gtk_widget_get_scale_factor(GLOBALS->signalarea); cairo_matrix_t prev_matrix; cairo_get_matrix(cr, &prev_matrix); cairo_scale(cr, 1.0/scale_factor, 1.0/scale_factor); cairo_set_source_surface(cr, GLOBALS->surface_wavepixmap_wavewindow_c_1, 0, 0); cairo_paint (cr); cairo_set_matrix(cr, &prev_matrix); } /******************************************************************/ 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; } } /******************************************************************/ #if GTK_CHECK_VERSION(3,0,0) static int gesture_filter_set = 0; /* to prevent floods of gesture events before next draw */ static int gesture_filter_cnt = 0; /* to prevent floods of gesture events before next draw */ static int gesture_in_zoom = 0; /* for suppression of filtering of redraws: indicates zoom state change, service_hslider() decrements this */ #endif #ifdef WAVE_ALLOW_SLIDER_ZOOM #if GTK_CHECK_VERSION(3,0,0) static void (*draw_slider_p) (GtkStyle *style, cairo_t *cr, GtkStateType state_type, GtkShadowType shadow_type, 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, cairo_t *cr, GtkStateType state_type, GtkShadowType shadow_type, GtkWidget *widget, const gchar *detail, gint x, gint y, gint width, gint height, GtkOrientation orientation) { if((GLOBALS)&&(widget == GLOBALS->hscroll_wavewindow_c_2)) { GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); GLOBALS->str_wid_x = x - allocation.x; GLOBALS->str_wid_width = width; GLOBALS->str_wid_bigw = allocation.width; GLOBALS->str_wid_height = height; } draw_slider_p(style, cr, state_type, shadow_type, widget, detail, x, y, width, height, orientation); } #else 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)) { GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); GLOBALS->str_wid_x = x - allocation.x; GLOBALS->str_wid_width = width; GLOBALS->str_wid_bigw = allocation.width; GLOBALS->str_wid_height = height; } draw_slider_p(style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, orientation); } #endif 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; GdkModifierType state; gdouble my_x, xmax, ratio; TimeType l_margin, r_margin; gint xi, yi; 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); } 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 /******************************************************************/ void XXX_gdk_draw_line(cairo_t *cr, wave_rgb_t gc, gint _x1, gint _y1, gint _x2, gint _y2) { cairo_set_source_rgba (cr, gc.r, gc.g, gc.b, gc.a); cairo_move_to (cr, _x1+WAVE_CAIRO_050_OFFSET, _y1+WAVE_CAIRO_050_OFFSET); cairo_line_to (cr, _x2+WAVE_CAIRO_050_OFFSET, _y2+WAVE_CAIRO_050_OFFSET); cairo_stroke (cr); } void XXX_gdk_draw_rectangle(cairo_t *cr, wave_rgb_t gc, gboolean filled, gint _x1, gint _y1, gint _w, gint _h) { cairo_set_source_rgba (cr, gc.r, gc.g, gc.b, gc.a); if(filled) { cairo_rectangle (cr, _x1, _y1, _w, _h); cairo_fill(cr); } else { cairo_rectangle (cr, _x1+WAVE_CAIRO_050_OFFSET, _y1+WAVE_CAIRO_050_OFFSET, _w, _h); cairo_stroke(cr); } } /* * 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; } } } } GtkAllocation allocation; gtk_widget_get_allocation(GLOBALS->wavearea, &allocation); num_traces_displayable=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, wave_rgb_t gc, int blackout) { gdouble pixstep; gint xl; 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)) { static const double dashed1[] = { 5.0, 3.0 }; char nbuff[16]; make_bijective_marker_id_string(nbuff, i); cairo_set_dash(GLOBALS->cr_wavepixmap_wavewindow_c_1, dashed1, sizeof(dashed1) / sizeof(dashed1[0]), 0); XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, gc, xl, GLOBALS->fontheight-1, xl, GLOBALS->waveheight-1); cairo_set_dash(GLOBALS->cr_wavepixmap_wavewindow_c_1, dashed1, 0, 0); if((!GLOBALS->marker_names[i])||(!GLOBALS->marker_names[i][0])) { XXX_font_engine_draw_string(GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->wavefont_smaller, &gc, xl-(font_engine_string_measure(GLOBALS->wavefont_smaller, nbuff)>>1)+WAVE_CAIRO_050_OFFSET, GLOBALS->fontheight-2+WAVE_CAIRO_050_OFFSET, 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 */ { XXX_gdk_draw_rectangle(GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->rgb_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); } XXX_font_engine_draw_string(GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->wavefont_smaller, &gc, xl-(width>>1)+WAVE_CAIRO_050_OFFSET, GLOBALS->fontheight-2+WAVE_CAIRO_050_OFFSET, GLOBALS->marker_names[i]); } } } } } static void draw_named_markers(void) { int i; if(!GLOBALS->cr_wavepixmap_wavewindow_c_1) return; for(i=0;inamed_marker_lock_idx) { render_individual_named_marker(i, GLOBALS->rgb_gc.gc_mark_wavewindow_c_1, 0); } } if(GLOBALS->named_marker_lock_idx >= 0) { render_individual_named_marker(GLOBALS->named_marker_lock_idx, GLOBALS->rgb_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; /* additional case for race conditions with MaxSignalLength */ if(((GLOBALS->tims.resizemarker==-1)||(GLOBALS->tims.resizemarker2==-1)) && (GLOBALS->tims.resizemarker!=GLOBALS->tims.resizemarker2)) { GLOBALS->signalwindow_width_dirty=1; } } static void draw_marker(void) { gdouble pixstep; gint xl; if(!gtk_widget_get_window(GLOBALS->wavearea)) return; #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX GdkDrawingContext *gdc; #endif cairo_t* cr = XXX_gdk_cairo_create (XXX_GDK_DRAWABLE (gtk_widget_get_window(GLOBALS->wavearea)), &gdc); cairo_set_line_width(cr, GLOBALS->cr_line_width); cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE); 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)) { XXX_gdk_draw_line(cr,GLOBALS->rgb_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)) { XXX_gdk_draw_line(cr,GLOBALS->rgb_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)) { XXX_gdk_draw_line(cr,GLOBALS->rgb_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(); #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX gdk_window_end_draw_frame(gtk_widget_get_window(GLOBALS->wavearea), gdc); #else cairo_destroy (cr); #endif #ifdef GDK_WINDOWING_WAYLAND if(GLOBALS->wayland_marker_timer_hack) { GLOBALS->wayland_marker_timer_hack--; if(GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default())) gtk_widget_queue_draw(GLOBALS->wavearea); /* we need this, but if called constantly will spike CPU usage */ } #endif } static void draw_marker_partitions(void) { draw_marker(); #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX GdkDrawingContext *gdc; #endif cairo_t* cr = XXX_gdk_cairo_create (XXX_GDK_DRAWABLE (gtk_widget_get_window(GLOBALS->wavearea)), &gdc); wavewindow_paint(cr); #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX gdk_window_end_draw_frame(gtk_widget_get_window(GLOBALS->wavearea), gdc); #else cairo_destroy (cr); #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); XXX_gdk_draw_rectangle(GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->rgb_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->cr_wavepixmap_wavewindow_c_1)&&(GLOBALS->wavewidth>1)) { #ifdef WAVE_ALLOW_GTK3_GESTURE_EVENT TimeType old_start = GLOBALS->tims.start; #endif GtkAdjustment *hadj = GTK_ADJUSTMENT(GLOBALS->wave_hslider); if(!GLOBALS->tims.timecache) { GLOBALS->tims.start=time_trunc(gtk_adjustment_get_value(hadj)); } 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; #ifdef WAVE_ALLOW_GTK3_GESTURE_EVENT if((gesture_in_zoom)||(!GLOBALS->swipe_init_time)||(GLOBALS->wavearea_gesture_swipe_velocity_x == 0.0)||(old_start != GLOBALS->tims.start)) /* cut down on redundant draws when swiping */ #endif { XXX_gdk_draw_rectangle(GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->rgb_gc.gc_back_wavewindow_c_1, TRUE, 0, 0,GLOBALS->wavewidth, GLOBALS->waveheight); rendertimebar(); } #ifdef WAVE_ALLOW_GTK3_GESTURE_EVENT if(gesture_in_zoom) gesture_in_zoom--; #endif } } #ifndef WAVE_GTK3_SIZE_ALLOCATE_WORKAROUND_WAVE_VSLIDER static #endif void service_vslider(GtkWidget *text, gpointer data) { (void)text; (void)data; GtkAdjustment *sadj, *hadj; int trtarget; int xsrc; if(GLOBALS->cr_signalpixmap) { hadj=GTK_ADJUSTMENT(GLOBALS->signal_hslider); sadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider); xsrc=(gint)gtk_adjustment_get_value(hadj); trtarget=(int)(gtk_adjustment_get_value(sadj)); DEBUG(printf("Wave VSlider Moved to %d\n",trtarget)); GtkAllocation allocation; gtk_widget_get_allocation(GLOBALS->signalarea, &allocation); cairo_set_source_rgba (GLOBALS->cr_signalpixmap, GLOBALS->rgb_gc.gc_ltgray.r, GLOBALS->rgb_gc.gc_ltgray.g, GLOBALS->rgb_gc.gc_ltgray.b, GLOBALS->rgb_gc.gc_ltgray.a); cairo_rectangle (GLOBALS->cr_signalpixmap, 0, 0, GLOBALS->signal_fill_width, allocation.height); cairo_fill (GLOBALS->cr_signalpixmap); sync_marker(); RenderSigs(trtarget,(GLOBALS->old_wvalue==gtk_adjustment_get_value(sadj))?0:1); GLOBALS->old_wvalue=gtk_adjustment_get_value(sadj); draw_named_markers(); if(GLOBALS->signalarea_has_focus) { #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX GdkDrawingContext *gdc; #endif cairo_t* cr = XXX_gdk_cairo_create (XXX_GDK_DRAWABLE (gtk_widget_get_window(GLOBALS->signalarea)), &gdc); cairo_rectangle (cr, 0, 0, allocation.width, allocation.height); cairo_clip (cr); signalwindow_paint(cr); draw_signalarea_focus(cr); #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX gdk_window_end_draw_frame(gtk_widget_get_window(GLOBALS->signalarea), gdc); #else cairo_destroy (cr); #endif } else { #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX GdkDrawingContext *gdc; #endif cairo_t* cr = XXX_gdk_cairo_create (XXX_GDK_DRAWABLE (gtk_widget_get_window(GLOBALS->signalarea)), &gdc); cairo_rectangle (cr, 0, 0, allocation.width, allocation.height); cairo_clip (cr); signalwindow_paint(cr); #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX gdk_window_end_draw_frame(gtk_widget_get_window(GLOBALS->signalarea), gdc); #else cairo_destroy (cr); #endif } draw_marker(); } } void button_press_release_common(void) { MaxSignalLength(); GtkAllocation allocation; gtk_widget_get_allocation(GLOBALS->signalarea, &allocation); cairo_set_source_rgba (GLOBALS->cr_signalpixmap, GLOBALS->rgb_gc.gc_ltgray.r, GLOBALS->rgb_gc.gc_ltgray.g, GLOBALS->rgb_gc.gc_ltgray.b, GLOBALS->rgb_gc.gc_ltgray.a); cairo_rectangle (GLOBALS->cr_signalpixmap, 0, 0, GLOBALS->signal_fill_width, allocation.height); cairo_fill (GLOBALS->cr_signalpixmap); { char signalwindow_width_dirty = GLOBALS->signalwindow_width_dirty; sync_marker(); if(!signalwindow_width_dirty && GLOBALS->signalwindow_width_dirty) { MaxSignalLength_2(1); } } RenderSigs((int)(gtk_adjustment_get_value(GTK_ADJUSTMENT(GLOBALS->wave_vslider))),0); if(GLOBALS->signalarea_has_focus) { #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX GdkDrawingContext *gdc; #endif cairo_t* cr = XXX_gdk_cairo_create (XXX_GDK_DRAWABLE (gtk_widget_get_window(GLOBALS->signalarea)), &gdc); cairo_rectangle (cr, 0, 0, allocation.width, allocation.height); cairo_clip (cr); signalwindow_paint(cr); draw_signalarea_focus(cr); #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX gdk_window_end_draw_frame(gtk_widget_get_window(GLOBALS->signalarea), gdc); #else cairo_destroy (cr); #endif } else { #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX GdkDrawingContext *gdc; #endif cairo_t* cr = XXX_gdk_cairo_create (XXX_GDK_DRAWABLE (gtk_widget_get_window(GLOBALS->signalarea)), &gdc); cairo_rectangle (cr, 0, 0, allocation.width, allocation.height); cairo_clip (cr); signalwindow_paint(cr); #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX gdk_window_end_draw_frame(gtk_widget_get_window(GLOBALS->signalarea), gdc); #else cairo_destroy (cr); #endif } } 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; } newcurr = time_trunc(newcurr); if(newcurr < 0) newcurr = GLOBALS->min_time; /* prevents marker from disappearing? */ if(!is_button_2) { update_markertime(GLOBALS->tims.marker=cook_markertime(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(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; gint xi, yi; 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_set_value(GTK_ADJUSTMENT(GLOBALS->wave_hslider),GLOBALS->tims.marker=time_trunc(GLOBALS->tims.timecache=GLOBALS->tims.start)); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); g_signal_emit_by_name (XXX_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_set_value(GTK_ADJUSTMENT(GLOBALS->wave_hslider),GLOBALS->tims.timecache=GLOBALS->tims.start); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); g_signal_emit_by_name (XXX_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->use_gestures > 0) ? NULL : 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); } static void alternate_y_scroll(int delta) { GtkAdjustment *wadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider); int value = (int)gtk_adjustment_get_value(wadj); int target = value + delta; GtkAllocation allocation; gtk_widget_get_allocation(GLOBALS->signalarea, &allocation); int num_traces_displayable=(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; gtk_adjustment_set_value(wadj, target); g_signal_emit_by_name (XXX_GTK_OBJECT (wadj), "changed"); /* force bar update */ g_signal_emit_by_name (XXX_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_set_value(GTK_ADJUSTMENT(GLOBALS->wave_hslider),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_set_value(GTK_ADJUSTMENT(GLOBALS->wave_hslider),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; #ifdef WAVE_CTRL_SCROLL_ZOOM_FACTOR GLOBALS->tims.zoom-=WAVE_CTRL_SCROLL_ZOOM_FACTOR; #else GLOBALS->tims.zoom--; #endif 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_set_value(GTK_ADJUSTMENT(GLOBALS->wave_hslider),GLOBALS->tims.timecache=GLOBALS->tims.start); } else { GLOBALS->tims.timecache=0; } fix_wavehadj(); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */ g_signal_emit_by_name (XXX_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; #ifdef WAVE_CTRL_SCROLL_ZOOM_FACTOR GLOBALS->tims.zoom+=WAVE_CTRL_SCROLL_ZOOM_FACTOR; #else GLOBALS->tims.zoom++; #endif 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_set_value(GTK_ADJUSTMENT(GLOBALS->wave_hslider),GLOBALS->tims.timecache=GLOBALS->tims.start); } else { GLOBALS->tims.timecache=0; } fix_wavehadj(); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */ g_signal_emit_by_name (XXX_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; GtkAllocation allocation; gtk_widget_get_allocation(GLOBALS->signalarea, &allocation); int num_traces_displayable=(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); } 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; #ifdef WAVE_ALLOW_GTK3_SEAT_VS_POINTER_GRAB_UNGRAB GdkDisplay *display = gdk_display_get_default(); GdkSeat *seat = gdk_display_get_default_seat (display); gdk_seat_grab (seat, gtk_widget_get_window(widget), GDK_SEAT_CAPABILITY_ALL_POINTING, FALSE, NULL, (GLOBALS->use_gestures > 0) ? NULL : (GdkEvent *)event, /* GdkEvent is a union with type as 1st element */ NULL, NULL); #else gdk_pointer_grab(gtk_widget_get_window(widget), 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); #endif #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->use_gestures > 0) ? NULL : 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->use_gestures > 0) ? NULL : 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; XXX_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); } #ifdef WAVE_ALLOW_GTK3_GESTURE_EVENT static void wavearea_zero_out_swipe_velocity(void) { GLOBALS->wavearea_gesture_swipe_velocity_x = 0.0; if(GLOBALS->swipe_init_time) { g_date_time_unref(GLOBALS->swipe_init_time); GLOBALS->swipe_init_time = NULL; } } void wavearea_pressed_event(GtkGestureMultiPress *gesture, gint n_press, gdouble x, gdouble y, gpointer user_data) { (void) gesture; (void) n_press; (void) user_data; GdkEventButton ev; if(gesture_filter_cnt) { return; } wavearea_zero_out_swipe_velocity(); memset(&ev, 0, sizeof(GdkEventButton)); ev.button = gtk_gesture_single_get_current_button(GTK_GESTURE_SINGLE(gesture)); ev.x = x; ev.y = y; if((n_press != 2) || (ev.button != 1)) { button_press_event(GLOBALS->wavearea, &ev); } else { delete_unnamed_marker(NULL, 0, NULL); /* double click gesture deletes primary marker */ } } void wavearea_released_event(GtkGestureMultiPress *gesture, gint n_press, gdouble x, gdouble y, gpointer user_data) { (void) gesture; (void) n_press; (void) user_data; GdkEventButton ev; memset(&ev, 0, sizeof(GdkEventButton)); ev.button = gtk_gesture_single_get_current_button(GTK_GESTURE_SINGLE(gesture)); ev.x = x; ev.y = y; button_release_event(GLOBALS->wavearea, &ev); } void wavearea_long_pressed_event(GtkGestureMultiPress *gesture, gdouble x, gdouble y, gpointer user_data) { (void) gesture; (void) user_data; GdkEventButton ev; wavearea_zero_out_swipe_velocity(); memset(&ev, 0, sizeof(GdkEventButton)); ev.button = 2; ev.x = x; ev.y = y; button_press_event(GLOBALS->wavearea, &ev); } void wavearea_drag_begin_event (GtkGestureDrag *gesture, gdouble start_x, gdouble start_y, gpointer user_data) { (void) gesture; (void) user_data; GLOBALS->wavearea_drag_start_x = start_x; GLOBALS->wavearea_drag_start_y = start_y; if(gesture_filter_cnt) { GLOBALS->wavearea_drag_start_x = GLOBALS->wavearea_drag_start_y = -1.0; return; } } void wavearea_drag_update_event (GtkGestureDrag *gesture, gdouble offset_x, gdouble offset_y, gpointer user_data) { (void) gesture; (void) user_data; GdkEventMotion ev; if(GLOBALS->wavearea_drag_start_x < 0.0) return; #ifdef GDK_WINDOWING_WAYLAND if(GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default())) { if(gesture_filter_set) return; /* to prevent floods of drag update events in wayland */ gesture_filter_set = 1; } #endif memset(&ev, 0, sizeof(GdkEventMotion)); ev.is_hint = 0; #ifdef WAVE_ALLOW_GTK3_GESTURE_MIDDLE_RIGHT_BUTTON ev.state = (gtk_gesture_single_get_current_button(GTK_GESTURE_SINGLE(gesture)) == 3) ? GDK_BUTTON3_MASK : GDK_BUTTON1_MASK; #else ev.state = GDK_BUTTON1_MASK; #endif ev.x = GLOBALS->wavearea_drag_start_x + offset_x; ev.y = GLOBALS->wavearea_drag_start_y + offset_y; ev.window = gtk_widget_get_window(GLOBALS->wavearea); GLOBALS->wavearea_drag_active = 1; motion_notify_event(GLOBALS->wavearea, &ev); } void wavearea_drag_end_event (GtkGestureDrag *gesture, gdouble offset_x, gdouble offset_y, gpointer user_data) { wavearea_drag_update_event(gesture, offset_x, offset_y, user_data); GLOBALS->wavearea_drag_active = 0; } #endif void make_sigarea_gcs(GtkWidget *signalarea) { (void) signalarea; if(!GLOBALS->made_sgc_contexts_wavewindow_c_1) { gboolean dark = GLOBALS->use_dark; #if GTK_CHECK_VERSION(3,0,0) if(!dark) { g_object_get(gtk_settings_get_default(), "gtk-application-prefer-dark-theme", &dark, NULL); GLOBALS->use_dark = dark; } #endif GLOBALS->rgb_gc_white = dark ? XXX_alloc_color(GLOBALS->color_black) : XXX_alloc_color(GLOBALS->color_white); GLOBALS->rgb_gc_black = dark ? XXX_alloc_color(GLOBALS->color_white) : XXX_alloc_color(GLOBALS->color_black); GLOBALS->rgb_gc.gc_ltgray= dark ? XXX_alloc_color(GLOBALS->color_black) : XXX_alloc_color(GLOBALS->color_ltgray); GLOBALS->rgb_gc.gc_normal= XXX_alloc_color(GLOBALS->color_normal); GLOBALS->rgb_gc.gc_mdgray= dark ? XXX_alloc_color(GLOBALS->color_dkgray) : XXX_alloc_color(GLOBALS->color_mdgray); GLOBALS->rgb_gc.gc_dkgray= dark ? XXX_alloc_color(GLOBALS->color_white) : XXX_alloc_color(GLOBALS->color_dkgray); GLOBALS->rgb_gc.gc_dkblue= XXX_alloc_color(GLOBALS->color_dkblue); GLOBALS->rgb_gc.gc_brkred= XXX_alloc_color(GLOBALS->color_brkred); GLOBALS->rgb_gc.gc_ltblue= XXX_alloc_color(GLOBALS->color_ltblue); GLOBALS->rgb_gc.gc_gmstrd= XXX_alloc_color(GLOBALS->color_gmstrd); 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)||(!gtk_widget_get_window(widget))) return(TRUE); GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); int scale_factor = XXX_gtk_widget_get_scale_factor(widget); DEBUG(printf("WaveWin Configure Event h: %d, w: %d\n",allocation.height, allocation.width)); if(GLOBALS->cr_wavepixmap_wavewindow_c_1) { if((GLOBALS->wavewidth!=allocation.width)||(GLOBALS->waveheight!=allocation.height)) { GLOBALS->wavewidth=allocation.width; GLOBALS->waveheight=allocation.height; cairo_destroy (GLOBALS->cr_wavepixmap_wavewindow_c_1); cairo_surface_destroy (GLOBALS->surface_wavepixmap_wavewindow_c_1); GLOBALS->surface_wavepixmap_wavewindow_c_1 = cairo_image_surface_create (CAIRO_FORMAT_RGB24, GLOBALS->wavewidth*scale_factor, allocation.height*scale_factor); GLOBALS->cr_wavepixmap_wavewindow_c_1 = cairo_create (GLOBALS->surface_wavepixmap_wavewindow_c_1); cairo_scale(GLOBALS->cr_wavepixmap_wavewindow_c_1, scale_factor, scale_factor); cairo_set_line_width(GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->cr_line_width); cairo_set_line_cap(GLOBALS->cr_wavepixmap_wavewindow_c_1, CAIRO_LINE_CAP_SQUARE); } GLOBALS->old_wvalue=-1.0; } else { GLOBALS->wavewidth=allocation.width; GLOBALS->waveheight=allocation.height; GLOBALS->surface_wavepixmap_wavewindow_c_1 = cairo_image_surface_create (CAIRO_FORMAT_RGB24, GLOBALS->wavewidth*scale_factor, allocation.height*scale_factor); GLOBALS->cr_wavepixmap_wavewindow_c_1 = cairo_create (GLOBALS->surface_wavepixmap_wavewindow_c_1); cairo_scale(GLOBALS->cr_wavepixmap_wavewindow_c_1, scale_factor, scale_factor); cairo_set_line_width(GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->cr_line_width); cairo_set_line_cap(GLOBALS->cr_wavepixmap_wavewindow_c_1, CAIRO_LINE_CAP_SQUARE); } if(!GLOBALS->made_gc_contexts_wavewindow_c_1) { int i; GLOBALS->rgb_gc.gc_back_wavewindow_c_1 = XXX_alloc_color(GLOBALS->color_back); GLOBALS->rgb_gc.gc_baseline_wavewindow_c_1 = XXX_alloc_color(GLOBALS->color_baseline); GLOBALS->rgb_gc.gc_grid_wavewindow_c_1 = XXX_alloc_color(GLOBALS->color_grid); GLOBALS->rgb_gc.gc_grid2_wavewindow_c_1 = XXX_alloc_color(GLOBALS->color_grid2); GLOBALS->rgb_gc.gc_time_wavewindow_c_1 = XXX_alloc_color(GLOBALS->color_time); GLOBALS->rgb_gc.gc_timeb_wavewindow_c_1 = XXX_alloc_color(GLOBALS->color_timeb); GLOBALS->rgb_gc.gc_value_wavewindow_c_1 = XXX_alloc_color(GLOBALS->color_value); GLOBALS->rgb_gc.gc_low_wavewindow_c_1 = XXX_alloc_color(GLOBALS->color_low); GLOBALS->rgb_gc.gc_highfill_wavewindow_c_1=XXX_alloc_color(GLOBALS->color_highfill); GLOBALS->rgb_gc.gc_high_wavewindow_c_1 = XXX_alloc_color(GLOBALS->color_high); GLOBALS->rgb_gc.gc_trans_wavewindow_c_1 = XXX_alloc_color(GLOBALS->color_trans); GLOBALS->rgb_gc.gc_mid_wavewindow_c_1 = XXX_alloc_color(GLOBALS->color_mid); GLOBALS->rgb_gc.gc_xfill_wavewindow_c_1 = XXX_alloc_color(GLOBALS->color_xfill); GLOBALS->rgb_gc.gc_x_wavewindow_c_1 = XXX_alloc_color(GLOBALS->color_x); GLOBALS->rgb_gc.gc_vbox_wavewindow_c_1 = XXX_alloc_color(GLOBALS->color_vbox); GLOBALS->rgb_gc.gc_vtrans_wavewindow_c_1 = XXX_alloc_color(GLOBALS->color_vtrans); GLOBALS->rgb_gc.gc_mark_wavewindow_c_1 = XXX_alloc_color(GLOBALS->color_mark); GLOBALS->rgb_gc.gc_umark_wavewindow_c_1 = XXX_alloc_color(GLOBALS->color_umark); GLOBALS->rgb_gc.gc_0_wavewindow_c_1 = XXX_alloc_color(GLOBALS->color_0); GLOBALS->rgb_gc.gc_1fill_wavewindow_c_1 = XXX_alloc_color(GLOBALS->color_1fill); GLOBALS->rgb_gc.gc_1_wavewindow_c_1 = XXX_alloc_color(GLOBALS->color_1); GLOBALS->rgb_gc.gc_ufill_wavewindow_c_1 = XXX_alloc_color(GLOBALS->color_ufill); GLOBALS->rgb_gc.gc_u_wavewindow_c_1 = XXX_alloc_color(GLOBALS->color_u); GLOBALS->rgb_gc.gc_wfill_wavewindow_c_1 = XXX_alloc_color(GLOBALS->color_wfill); GLOBALS->rgb_gc.gc_w_wavewindow_c_1 = XXX_alloc_color(GLOBALS->color_w); GLOBALS->rgb_gc.gc_dashfill_wavewindow_c_1= XXX_alloc_color(GLOBALS->color_dashfill); GLOBALS->rgb_gc.gc_dash_wavewindow_c_1 = XXX_alloc_color(GLOBALS->color_dash); GLOBALS->made_gc_contexts_wavewindow_c_1=~0; memcpy(&GLOBALS->rgb_gccache, &GLOBALS->rgb_gc, sizeof(struct wave_rgbmaster_t)); /* add rainbow colors */ for(i=0;irgb_gc_rainbow[i*2] = XXX_alloc_color(col); col >>= 1; col &= 0x007F7F7F; GLOBALS->rgb_gc_rainbow[i*2+1] = XXX_alloc_color(col); } } 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); gtk_adjustment_set_value(hadj, (gdouble)(GLOBALS->timestart_from_savefile)); fix_wavehadj(); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed"); /* force zoom update */ g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */ } GLOBALS->timestart_from_savefile_valid--; /* for previous gtk toolkit versions could set this directly to zero */ } if(GLOBALS->wavewidth>1) { if((!GLOBALS->do_initial_zoom_fit)||(GLOBALS->do_initial_zoom_fit_used)) { calczoom(GLOBALS->tims.zoom); fix_wavehadj(); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed"); /* force zoom update */ g_signal_emit_by_name (XXX_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->rgb_gc.gc_ltgray= GLOBALS->rgb_gc_white ; GLOBALS->rgb_gc.gc_normal= GLOBALS->rgb_gc_white ; GLOBALS->rgb_gc.gc_mdgray= GLOBALS->rgb_gc_white ; GLOBALS->rgb_gc.gc_dkgray= GLOBALS->rgb_gc_white ; GLOBALS->rgb_gc.gc_dkblue= GLOBALS->rgb_gc_black ; GLOBALS->rgb_gc.gc_brkred= GLOBALS->rgb_gc_black ; GLOBALS->rgb_gc.gc_ltblue= GLOBALS->rgb_gc_black ; GLOBALS->rgb_gc.gc_gmstrd= GLOBALS->rgb_gc_black ; GLOBALS->rgb_gc.gc_back_wavewindow_c_1 = GLOBALS->rgb_gc_white ; GLOBALS->rgb_gc.gc_baseline_wavewindow_c_1 = GLOBALS->rgb_gc_black; GLOBALS->rgb_gc.gc_grid_wavewindow_c_1 = GLOBALS->rgb_gc_black; GLOBALS->rgb_gc.gc_grid2_wavewindow_c_1 = GLOBALS->rgb_gc_black; GLOBALS->rgb_gc.gc_time_wavewindow_c_1 = GLOBALS->rgb_gc_black; GLOBALS->rgb_gc.gc_timeb_wavewindow_c_1 = GLOBALS->rgb_gc_white; GLOBALS->rgb_gc.gc_value_wavewindow_c_1 = GLOBALS->rgb_gc_black; GLOBALS->rgb_gc.gc_low_wavewindow_c_1 = GLOBALS->rgb_gc_black; GLOBALS->rgb_gc.gc_highfill_wavewindow_c_1= GLOBALS->rgb_gc_black; GLOBALS->rgb_gc.gc_high_wavewindow_c_1 = GLOBALS->rgb_gc_black; GLOBALS->rgb_gc.gc_trans_wavewindow_c_1 = GLOBALS->rgb_gc_black; GLOBALS->rgb_gc.gc_mid_wavewindow_c_1 = GLOBALS->rgb_gc_black; GLOBALS->rgb_gc.gc_xfill_wavewindow_c_1 = GLOBALS->rgb_gc_black; GLOBALS->rgb_gc.gc_x_wavewindow_c_1 = GLOBALS->rgb_gc_black; GLOBALS->rgb_gc.gc_vbox_wavewindow_c_1 = GLOBALS->rgb_gc_black; GLOBALS->rgb_gc.gc_vtrans_wavewindow_c_1 = GLOBALS->rgb_gc_black; GLOBALS->rgb_gc.gc_mark_wavewindow_c_1 = GLOBALS->rgb_gc_black; GLOBALS->rgb_gc.gc_umark_wavewindow_c_1 = GLOBALS->rgb_gc_black; GLOBALS->rgb_gc.gc_0_wavewindow_c_1 = GLOBALS->rgb_gc_black; GLOBALS->rgb_gc.gc_1fill_wavewindow_c_1 = GLOBALS->rgb_gc_black; GLOBALS->rgb_gc.gc_1_wavewindow_c_1 = GLOBALS->rgb_gc_black; GLOBALS->rgb_gc.gc_ufill_wavewindow_c_1 = GLOBALS->rgb_gc_black; GLOBALS->rgb_gc.gc_u_wavewindow_c_1 = GLOBALS->rgb_gc_black; GLOBALS->rgb_gc.gc_wfill_wavewindow_c_1 = GLOBALS->rgb_gc_black; GLOBALS->rgb_gc.gc_w_wavewindow_c_1 = GLOBALS->rgb_gc_black; GLOBALS->rgb_gc.gc_dashfill_wavewindow_c_1= GLOBALS->rgb_gc_black; GLOBALS->rgb_gc.gc_dash_wavewindow_c_1 = GLOBALS->rgb_gc_black; } void force_normal_gcs(void) { GLOBALS->black_and_white = 0; memcpy(&GLOBALS->rgb_gc, &GLOBALS->rgb_gccache, sizeof(struct wave_rgbmaster_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); } #if GTK_CHECK_VERSION(3,0,0) static gint draw_event(GtkWidget *widget, cairo_t *cr, gpointer user_data) { (void) widget; (void) user_data; gint rc = FALSE; gint page_num = gtk_notebook_get_current_page(GTK_NOTEBOOK(GLOBALS->notebook)); /* struct Global *g_old = GLOBALS; */ set_GLOBALS((*GLOBALS->contexts)[page_num]); wavewindow_paint(cr); draw_marker(); /* seems to cause a conflict flipping back so don't! */ /* set_GLOBALS(g_old); */ if(gesture_filter_set) gesture_filter_set = 0; return(rc); } #else static gint expose_event(GtkWidget *widget, GdkEventExpose *event) { #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX GdkDrawingContext *gdc; #endif cairo_t* cr = XXX_gdk_cairo_create (XXX_GDK_DRAWABLE (gtk_widget_get_window(widget)), &gdc); gdk_cairo_region (cr, event->region); cairo_clip (cr); wavewindow_paint(cr); #ifdef WAVE_ALLOW_GTK3_CAIRO_CREATE_FIX gdk_window_end_draw_frame(gtk_widget_get_window(widget), gdc); #else cairo_destroy (cr); #endif 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); } #endif #ifdef WAVE_GTK3_SIZE_ALLOCATE_WORKAROUND_WAVE_VSLIDER static gboolean wave_vslider_gtc(GtkWidget *widget, GdkFrameClock *frame_clock, gpointer user_data) { if(GLOBALS && GLOBALS->wave_vslider_valid && GLOBALS->wave_vslider && GLOBALS->signal_hslider) { GtkAdjustment *wadj=GTK_ADJUSTMENT(GLOBALS->wave_vslider); GtkAdjustment *hadj=GTK_ADJUSTMENT(GLOBALS->wave_hslider); gtk_adjustment_set_page_size(wadj, GLOBALS->wave_vslider_page_size); gtk_adjustment_set_page_increment(wadj, GLOBALS->wave_vslider_page_increment); gtk_adjustment_set_step_increment(wadj, GLOBALS->wave_vslider_step_increment); gtk_adjustment_set_lower(wadj, GLOBALS->wave_vslider_lower); gtk_adjustment_set_upper(wadj, GLOBALS->wave_vslider_upper); gtk_adjustment_set_value(wadj, GLOBALS->wave_vslider_value); GLOBALS->wave_vslider_valid = 0; g_signal_emit_by_name (XXX_GTK_OBJECT (wadj), "changed"); /* force bar update */ g_signal_emit_by_name (XXX_GTK_OBJECT (wadj), "value_changed"); /* force text update */ g_signal_emit_by_name (XXX_GTK_OBJECT (hadj), "changed"); /* force bar update */ } return(G_SOURCE_CONTINUE); } #endif #ifdef WAVE_ALLOW_GTK3_GESTURE_EVENT #ifdef WAVE_GTK3_GESTURE_ZOOM_IS_1D static int wavearea_zoom_get_gesture_xy_points(GtkGesture *gesture, gdouble *x1p, gdouble *y1p, gdouble *x2p, gdouble *y2p) { GList *sequences; int rc = 0; if(gesture) { sequences = gtk_gesture_get_sequences (gesture); if(sequences) { if(sequences->next) { rc = 1; gdouble x1, y1, x2, y2; gtk_gesture_get_point (gesture, sequences->data, &x1, &y1); gtk_gesture_get_point (gesture, sequences->next->data, &x2, &y2); if(x1 < x2) /* order coordinates so x1 is leftmost point */ { *x1p = x1; *y1p = y1; *x2p = x2; *y2p = y2; } else { *x1p = x2; *y1p = y2; *x2p = x1; *y2p = y1; } } g_list_free (sequences); } } return(rc); } #endif static void wavearea_zoom_begin_event (GtkGesture *gesture, GdkEventSequence *sequence, gpointer user_data) { (void) sequence; (void) user_data; gdouble x1, y1, x2, y2; gesture_in_zoom = 1; GLOBALS->wavearea_gesture_initial_zoom = GLOBALS->tims.zoom; #ifdef WAVE_GTK3_GESTURE_ZOOM_IS_1D if(wavearea_zoom_get_gesture_xy_points(gesture, &x1, &y1, &x2, &y2)) { GLOBALS->wavearea_gesture_initial_x1tim = GLOBALS->tims.start + (x1 * GLOBALS->nspx); GLOBALS->wavearea_gesture_initial_zoom_x_distance = x2 - x1; if(GLOBALS->wavearea_gesture_initial_zoom_x_distance < 1.0) GLOBALS->wavearea_gesture_initial_zoom_x_distance = 1.0; /* min resolution is one pixel */ } else { TimeType middle=(GLOBALS->tims.start/2)+(GLOBALS->tims.end/2); GLOBALS->wavearea_gesture_initial_x1tim = middle; GLOBALS->wavearea_gesture_initial_zoom_x_distance = 1.0; /* min resolution is one pixel */ } if(GLOBALS->wavearea_gesture_initial_x1tim < GLOBALS->tims.first) GLOBALS->wavearea_gesture_initial_x1tim = GLOBALS->tims.first; if(GLOBALS->wavearea_gesture_initial_x1tim > GLOBALS->tims.last) GLOBALS->wavearea_gesture_initial_x1tim = GLOBALS->tims.last; #endif #ifdef WAVE_GTK3_GESTURE_ZOOM_USES_GTK_PHASE_CAPTURE gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED); #endif } static void wavearea_zoom_scale_changed_event (GtkGestureZoom *controller, gdouble scale, gpointer user_data) { (void) controller; gdouble zb, ls, lzb, r, z0; #ifdef WAVE_GTK3_GESTURE_ZOOM_IS_1D gdouble x1 = 0.0, y1 = 0.0, x2 = 0.0, y2 = 0.0; if(gesture_filter_set) return; /* to prevent floods of zoom events */ gesture_filter_set = 1; #endif gesture_in_zoom = 1; zb = GLOBALS->zoombase; lzb = log(zb); #ifdef WAVE_GTK3_GESTURE_ZOOM_IS_1D { GtkGesture *gesture = (GtkGesture *)user_data; gdouble dist; if(wavearea_zoom_get_gesture_xy_points(gesture, &x1, &y1, &x2, &y2)) { dist = x2 - x1; if(dist < 1.0) dist = 1.0; /* min resolution is one pixel */ } else { dist = 1.0; /* min resolution is one pixel */ } if(GLOBALS->wavearea_gesture_initial_zoom_x_distance < 1.0) GLOBALS->wavearea_gesture_initial_zoom_x_distance = 1.0; /* min resolution is one pixel */ scale = GLOBALS->wavearea_gesture_initial_zoom_x_distance / dist; } #else { if(scale < 0.00001) scale = 0.00001; scale = (1.0 / scale); /* matches version for WAVE_GTK3_GESTURE_ZOOM_IS_1D which is initial_distance/distance instead of distance/priv->initial_distance from gtk */ } #endif ls = log(scale); if((lzb != 0.0) && (scale > 0.0)) { r = ls / lzb; z0 = GLOBALS->wavearea_gesture_initial_zoom - r; if((z0 <= 0.0) && (isnormal(z0))) { /* printf("XXX %e %e\n", scale, z0); */ #ifdef WAVE_GTK3_GESTURE_ZOOM_IS_1D { TimeType width, new_x1tim; calczoom(GLOBALS->tims.zoom = z0); width = (TimeType)(((gdouble)GLOBALS->wavewidth) * GLOBALS->nspx); GLOBALS->tims.start = GLOBALS->wavearea_gesture_initial_x1tim - (x1 * GLOBALS->nspx); new_x1tim = GLOBALS->tims.start + (x1 * GLOBALS->nspx); GLOBALS->tims.start += (GLOBALS->wavearea_gesture_initial_x1tim - new_x1tim); GLOBALS->tims.marker = new_x1tim; GLOBALS->tims.baseline = GLOBALS->tims.start + (x2 * GLOBALS->nspx); GLOBALS->tims.lmbcache = -1; GLOBALS->in_button_press_wavewindow_c_1 = 0; if(GLOBALS->tims.start + width > GLOBALS->tims.last) GLOBALS->tims.start = time_trunc(GLOBALS->tims.last - width); if(GLOBALS->tims.start < GLOBALS->tims.first) GLOBALS->tims.start = GLOBALS->tims.first; gtk_adjustment_set_value(GTK_ADJUSTMENT(GLOBALS->wave_hslider), GLOBALS->tims.timecache = GLOBALS->tims.start); fix_wavehadj(); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */ g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed"); /* force zoom update */ } #else { GLOBALS->tims.zoom = z0 + 1.0; /* 1.0 compensates for what service_zoom_out does */ service_zoom_out(NULL, NULL); } #endif GLOBALS->tims.prevzoom = GLOBALS->wavearea_gesture_initial_zoom; } } } #ifdef WAVE_GTK3_GESTURE_ZOOM_USES_GTK_PHASE_CAPTURE static void wavearea_zoom_update_event (GtkGestureZoom *gesture, GdkEventSequence *sequence, gpointer user_data) { (void) sequence; wavearea_zoom_scale_changed_event(gesture, gtk_gesture_zoom_get_scale_delta (gesture), user_data); } #endif static void wavearea_zoom_end_event (GtkGestureZoom *gesture, GdkEventSequence *sequence, gpointer user_data) { (void) gesture; (void) sequence; (void) user_data; GLOBALS->tims.marker = -1; GLOBALS->tims.baseline = -1; GLOBALS->tims.lmbcache = -1; GLOBALS->in_button_press_wavewindow_c_1 = 0; g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */ g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed"); /* force zoom update */ gesture_in_zoom = 1; #ifdef GDK_WINDOWING_WAYLAND if(GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default())) { /* nothing for wayland */ } else #endif { gesture_filter_cnt = 10; /* to prevent mouse pointer from flying all over at zoom release */ } } void wavearea_swipe_event (GtkGestureSwipe *gesture, gdouble velocity_x, gdouble velocity_y, gpointer user_data) { (void) gesture; (void) user_data; (void) velocity_y; if(gesture_filter_cnt) { wavearea_zero_out_swipe_velocity(); return; } GLOBALS->wavearea_gesture_swipe_velocity_x = velocity_x; if(GLOBALS->swipe_init_time) { g_date_time_unref(GLOBALS->swipe_init_time); } GLOBALS->swipe_init_time = g_date_time_new_now_utc(); GLOBALS->swipe_init_start = GLOBALS->tims.start; } void wavearea_swipe_update_event (GtkGesture *gesture, GdkEventSequence *sequence, gpointer user_data) { (void) gesture; (void) sequence; (void) user_data; gdouble velocity_x, velocity_y; gboolean rc = gtk_gesture_swipe_get_velocity (GTK_GESTURE_SWIPE(GLOBALS->wavearea_gesture_swipe), &velocity_x, &velocity_y); if(rc && !gesture_filter_cnt) { GLOBALS->wavearea_gesture_swipe_velocity_x = velocity_x; } } static gboolean wavearea_swipe_tick(GtkWidget *widget, GdkFrameClock *frame_clock, gpointer user_data) { (void) widget; (void) frame_clock; (void) user_data; if(gesture_filter_cnt > 0) /* for X11 */ { wavearea_zero_out_swipe_velocity(); gesture_filter_cnt--; return(G_SOURCE_CONTINUE); } if(GLOBALS->swipe_init_time) { GDateTime *gd2 = g_date_time_new_now_utc(); GTimeSpan elapsed = g_date_time_difference(gd2, GLOBALS->swipe_init_time); gdouble decaying = 0.0; g_date_time_unref(gd2); if(elapsed < WAVE_GTK3_SWIPE_MICROSECONDS) { decaying = exp(-elapsed / ((gdouble)WAVE_GTK3_SWIPE_TIME_CONSTANT)); } if(GLOBALS->wavearea_gesture_swipe_velocity_x < -1.0) { GtkAdjustment *hadj; gfloat inc; TimeType ntinc, pageinc; if(!GLOBALS->wavearea_drag_active) { TimeType dest = GLOBALS->swipe_init_start - (GLOBALS->wavearea_gesture_swipe_velocity_x * GLOBALS->nspx * WAVE_GTK3_SWIPE_VEL_VS_DIST_FACTOR) * (1.0 - decaying); /* gdouble vp = -GLOBALS->wavearea_gesture_swipe_velocity_x; */ hadj=GTK_ADJUSTMENT(GLOBALS->wave_hslider); ntinc = inc = dest - gtk_adjustment_get_value(hadj); if(ntinc) { pageinc=(TimeType)(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx); if(dest <= (GLOBALS->tims.last-pageinc)) gtk_adjustment_set_value(hadj, GLOBALS->tims.timecache = dest); else { gtk_adjustment_set_value(hadj, GLOBALS->tims.timecache = GLOBALS->tims.last-pageinc); elapsed = WAVE_GTK3_SWIPE_MICROSECONDS; } if(GLOBALS->tims.timecachetims.first) GLOBALS->tims.timecache=GLOBALS->tims.first; time_update(); } } if(elapsed >= WAVE_GTK3_SWIPE_MICROSECONDS) { wavearea_zero_out_swipe_velocity(); GLOBALS->tims.baseline = -1; GLOBALS->tims.lmbcache = -1; GLOBALS->in_button_press_wavewindow_c_1 = 0; } } if(GLOBALS->wavearea_gesture_swipe_velocity_x > 1.0) { GtkAdjustment *hadj; if(!GLOBALS->wavearea_drag_active) { TimeType dest = GLOBALS->swipe_init_start - (GLOBALS->wavearea_gesture_swipe_velocity_x * GLOBALS->nspx * WAVE_GTK3_SWIPE_VEL_VS_DIST_FACTOR) * (1.0 - decaying); /* gdouble vp = GLOBALS->wavearea_gesture_swipe_velocity_x; */ hadj=GTK_ADJUSTMENT(GLOBALS->wave_hslider); if(dest>=GLOBALS->tims.first) gtk_adjustment_set_value(hadj, dest); else { gtk_adjustment_set_value(hadj, GLOBALS->tims.first); ; elapsed = WAVE_GTK3_SWIPE_MICROSECONDS; } if(dest>=GLOBALS->tims.first) GLOBALS->tims.timecache=dest; else { GLOBALS->tims.timecache=GLOBALS->tims.first; elapsed = WAVE_GTK3_SWIPE_MICROSECONDS; } time_update(); } if(elapsed >= WAVE_GTK3_SWIPE_MICROSECONDS) { wavearea_zero_out_swipe_velocity(); GLOBALS->tims.baseline = -1; GLOBALS->tims.lmbcache = -1; GLOBALS->in_button_press_wavewindow_c_1 = 0; } } } GdkWindow *gw = gtk_widget_get_window(GLOBALS->wavearea); if(gw) { gdouble x = 0, pixstep, offset; TimeType newcurr = 0; GdkModifierType state = 0; gint xi = 0, yi = 0; int dummy_x, dummy_y; get_window_xypos(&dummy_x, &dummy_y); WAVE_GDK_GET_POINTER(gtk_widget_get_window(GLOBALS->wavearea), &x, &y, &xi, &yi, &state); WAVE_GDK_GET_POINTER_COPY_XONLY; if((x >= 0) && (x < GLOBALS->wavewidth)) { 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; } } } return(G_SOURCE_CONTINUE); } #endif GtkWidget * create_wavewindow(void) { GtkWidget *table; GtkWidget *frame; GtkAdjustment *hadj, *vadj; table = XXX_gtk_table_new(10, 10, FALSE); #ifdef WAVE_GTK3_SIZE_ALLOCATE_WORKAROUND_DEPRECATED_API /* this removes the warning generated from XXX_gtk_table_attach() on GLOBALS->vscroll_wavewindow_c_1 below */ gtk_container_set_resize_mode(GTK_CONTAINER(table), GTK_RESIZE_IMMEDIATE); #endif GLOBALS->wavearea=gtk_drawing_area_new(); gtk_widget_show(GLOBALS->wavearea); gtk_widget_set_events(GLOBALS->wavearea, GDK_SCROLL_MASK | GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK #ifdef WAVE_ALLOW_GTK3_GESTURE_EVENT | GDK_TOUCH_MASK | GDK_TABLET_PAD_MASK | GDK_TOUCHPAD_GESTURE_MASK #endif ); g_signal_connect(XXX_GTK_OBJECT(GLOBALS->wavearea), "configure_event",G_CALLBACK(wavearea_configure_event_local), NULL); #if GTK_CHECK_VERSION(3,0,0) g_signal_connect(XXX_GTK_OBJECT(GLOBALS->wavearea), "draw",G_CALLBACK(draw_event), NULL); #else g_signal_connect(XXX_GTK_OBJECT(GLOBALS->wavearea), "expose_event",G_CALLBACK(expose_event_local), NULL); #endif #ifdef WAVE_ALLOW_GTK3_GESTURE_EVENT if(GLOBALS->use_gestures < 0) /* <0 means "maybe (if available, enable)" */ { GdkDisplay *display = gdk_display_get_default(); GdkSeat *seat = gdk_display_get_default_seat (display); GdkSeatCapabilities gsc = gdk_seat_get_capabilities(seat); if(gsc & GDK_SEAT_CAPABILITY_TOUCH) { printf("GTKWAVE | Touch screen detected, enabling gestures.\n"); GLOBALS->use_gestures = 1; } else { GLOBALS->use_gestures = 0; } } if(GLOBALS->use_gestures) { /* so far is mutually exclusive with existing motion/button action below */ GtkGesture *gs; GLOBALS->wavearea_gesture_initial_zoom = GLOBALS->tims.zoom; gs = gtk_gesture_zoom_new(GLOBALS->wavearea); gtkwave_signal_connect(XXX_GTK_OBJECT(gs), "begin", G_CALLBACK(wavearea_zoom_begin_event), gs); gtkwave_signal_connect(XXX_GTK_OBJECT(gs), "end", G_CALLBACK(wavearea_zoom_end_event), gs); #ifdef WAVE_GTK3_GESTURE_ZOOM_USES_GTK_PHASE_CAPTURE gtkwave_signal_connect(XXX_GTK_OBJECT(gs), "update", G_CALLBACK(wavearea_zoom_update_event), gs); gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER(gs), GTK_PHASE_CAPTURE); #else gtkwave_signal_connect(XXX_GTK_OBJECT(gs), "scale-changed", G_CALLBACK(wavearea_zoom_scale_changed_event), gs); #endif gs = gtk_gesture_multi_press_new (GLOBALS->wavearea); gtkwave_signal_connect(XXX_GTK_OBJECT(gs), "pressed", G_CALLBACK(wavearea_pressed_event), NULL); gtkwave_signal_connect(XXX_GTK_OBJECT(gs), "released", G_CALLBACK(wavearea_released_event), NULL); #ifdef WAVE_ALLOW_GTK3_GESTURE_MIDDLE_RIGHT_BUTTON gtk_gesture_single_set_button(GTK_GESTURE_SINGLE(gs), 0); #endif gs = gtk_gesture_long_press_new (GLOBALS->wavearea); gtkwave_signal_connect(XXX_GTK_OBJECT(gs), "pressed", G_CALLBACK(wavearea_long_pressed_event), NULL); gs = gtk_gesture_drag_new (GLOBALS->wavearea); gtkwave_signal_connect(XXX_GTK_OBJECT(gs), "drag_begin", G_CALLBACK(wavearea_drag_begin_event), NULL); gtkwave_signal_connect(XXX_GTK_OBJECT(gs), "drag_update", G_CALLBACK(wavearea_drag_update_event), NULL); gtkwave_signal_connect(XXX_GTK_OBJECT(gs), "drag_end", G_CALLBACK(wavearea_drag_end_event), NULL); #ifdef WAVE_ALLOW_GTK3_GESTURE_MIDDLE_RIGHT_BUTTON gtk_gesture_single_set_button(GTK_GESTURE_SINGLE(gs), 0); #endif GLOBALS->wavearea_gesture_swipe = gtk_gesture_swipe_new (GLOBALS->wavearea); gtkwave_signal_connect(XXX_GTK_OBJECT(GLOBALS->wavearea_gesture_swipe), "swipe", G_CALLBACK(wavearea_swipe_event), GLOBALS); gtkwave_signal_connect(XXX_GTK_OBJECT(GLOBALS->wavearea_gesture_swipe), "update", G_CALLBACK(wavearea_swipe_update_event), GLOBALS); gtk_widget_add_tick_callback (GTK_WIDGET(GLOBALS->wavearea), wavearea_swipe_tick, NULL, NULL); } else #endif { gtkwave_signal_connect(XXX_GTK_OBJECT(GLOBALS->wavearea), "motion_notify_event",G_CALLBACK(motion_notify_event), NULL); gtkwave_signal_connect(XXX_GTK_OBJECT(GLOBALS->wavearea), "button_press_event",G_CALLBACK(button_press_event), NULL); gtkwave_signal_connect(XXX_GTK_OBJECT(GLOBALS->wavearea), "button_release_event",G_CALLBACK(button_release_event), NULL); } gtkwave_signal_connect(XXX_GTK_OBJECT(GLOBALS->wavearea), "scroll_event",G_CALLBACK(scroll_event), NULL); gtk_widget_set_can_focus(GTK_WIDGET(GLOBALS->wavearea), TRUE); XXX_gtk_table_attach (XXX_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(XXX_GTK_OBJECT(GLOBALS->wave_vslider), "value_changed",G_CALLBACK(service_vslider), NULL); GLOBALS->vscroll_wavewindow_c_1=XXX_gtk_vscrollbar_new(vadj); /* GTK_WIDGET_SET_FLAGS(GLOBALS->vscroll_wavewindow_c_1, GTK_CAN_FOCUS); */ gtk_widget_show(GLOBALS->vscroll_wavewindow_c_1); /* this moves GLOBALS->wave_vslider updates out from signalarea_configure_event where it was causing size allocation warnings */ #ifdef WAVE_GTK3_SIZE_ALLOCATE_WORKAROUND_WAVE_VSLIDER gtk_widget_add_tick_callback (GTK_WIDGET(GLOBALS->vscroll_wavewindow_c_1), wave_vslider_gtc, NULL, NULL); #endif #ifdef WAVE_ALLOW_GTK3_GRID XXX_gtk_table_attach (XXX_GTK_TABLE (table), GLOBALS->vscroll_wavewindow_c_1, 9, 10, 0, 9, 0, GTK_SHRINK, 3, 3); #else XXX_gtk_table_attach (XXX_GTK_TABLE (table), GLOBALS->vscroll_wavewindow_c_1, 9, 10, 0, 9, GTK_FILL, GTK_FILL | GTK_SHRINK, 3, 3); #endif 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(XXX_GTK_OBJECT(GLOBALS->wave_hslider), "value_changed",G_CALLBACK(service_hslider), NULL); GLOBALS->hscroll_wavewindow_c_2=XXX_gtk_hscrollbar_new(hadj); /* GTK_WIDGET_SET_FLAGS(GLOBALS->hscroll_wavewindow_c_2, GTK_CAN_FOCUS); */ gtk_widget_show(GLOBALS->hscroll_wavewindow_c_2); #ifdef WAVE_ALLOW_SLIDER_ZOOM 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(XXX_GTK_OBJECT(GLOBALS->hscroll_wavewindow_c_2), "button_press_event",G_CALLBACK(slider_bpr), NULL); gtkwave_signal_connect(XXX_GTK_OBJECT(GLOBALS->hscroll_wavewindow_c_2), "button_release_event",G_CALLBACK(slider_brr), NULL); gtkwave_signal_connect(XXX_GTK_OBJECT(GLOBALS->hscroll_wavewindow_c_2), "motion_notify_event",G_CALLBACK(slider_mnr), NULL); } #endif #ifdef WAVE_ALLOW_GTK3_GRID XXX_gtk_table_attach (XXX_GTK_TABLE (table), GLOBALS->hscroll_wavewindow_c_2, 0, 9, 9, 10, 0, GTK_SHRINK, 3, 4); #else XXX_gtk_table_attach (XXX_GTK_TABLE (table), GLOBALS->hscroll_wavewindow_c_2, 0, 9, 9, 10, GTK_FILL, GTK_FILL | GTK_SHRINK, 3, 4); #endif gtk_widget_show(table); frame=gtk_frame_new("Waves"); gtk_container_set_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)gtk_adjustment_get_value(hadj); GtkAllocation allocation; gtk_widget_get_allocation(GLOBALS->signalarea, &allocation); num_traces_displayable=allocation.height/(GLOBALS->fontheight); num_traces_displayable--; /* for the time trace that is always there */ if(!GLOBALS->use_dark) { cairo_set_source_rgba (GLOBALS->cr_signalpixmap, GLOBALS->rgb_gc.gc_mdgray.r, GLOBALS->rgb_gc.gc_mdgray.g, GLOBALS->rgb_gc.gc_mdgray.b, GLOBALS->rgb_gc.gc_mdgray.a); cairo_rectangle (GLOBALS->cr_signalpixmap, 0, -1, GLOBALS->signal_fill_width, GLOBALS->fontheight); cairo_fill (GLOBALS->cr_signalpixmap); } cairo_set_source_rgba (GLOBALS->cr_signalpixmap, GLOBALS->rgb_gc_white.r, GLOBALS->rgb_gc_white.g, GLOBALS->rgb_gc_white.b, GLOBALS->rgb_gc_white.a); cairo_move_to (GLOBALS->cr_signalpixmap, WAVE_CAIRO_050_OFFSET, GLOBALS->fontheight-1+WAVE_CAIRO_050_OFFSET); cairo_line_to (GLOBALS->cr_signalpixmap, GLOBALS->signal_fill_width-1+WAVE_CAIRO_050_OFFSET, GLOBALS->fontheight-1+WAVE_CAIRO_050_OFFSET); cairo_stroke (GLOBALS->cr_signalpixmap); if(!GLOBALS->use_dark) { XXX_font_engine_draw_string(GLOBALS->cr_signalpixmap, GLOBALS->signalfont, &(GLOBALS->rgb_gc_black), 3+xsrc+WAVE_CAIRO_050_OFFSET, GLOBALS->fontheight-4+WAVE_CAIRO_050_OFFSET, "Time"); } t=GLOBALS->traces.first; trwhich=0; while(t) { if((trwhichtopmost_trace=t; if(t) { for(i=0;(isignalarea_has_focus) { cairo_set_source_rgba (GLOBALS->cr_signalpixmap, GLOBALS->rgb_gc_black.r, GLOBALS->rgb_gc_black.g, GLOBALS->rgb_gc_black.b, GLOBALS->rgb_gc_black.a); cairo_rectangle (GLOBALS->cr_signalpixmap, 0, 0, GLOBALS->signal_fill_width-1, allocation.height-1); cairo_stroke (GLOBALS->cr_signalpixmap); } if((GLOBALS->cr_wavepixmap_wavewindow_c_1)&&(update_waves)) { XXX_gdk_draw_rectangle(GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->rgb_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) {memcpy (pch,"[+]", 3); } } else { pch = strstr (ptr,"[+]"); if(pch) {memcpy (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 */ } } } #ifdef GDK_WINDOWING_WAYLAND if(GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default())) gtk_widget_queue_draw(GLOBALS->signalarea); #endif } /***************************************************************************/ int RenderSig(Trptr t, int i, int dobackground) { int texty, liney; int retval; char buf[2048]; wave_rgb_t clr_comment; wave_rgb_t clr_group; wave_rgb_t clr_shadowed; wave_rgb_t clr_signal; wave_rgb_t bg_color; wave_rgb_t 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->rgb_gc.gc_brkred; clr_group = GLOBALS->rgb_gc.gc_gmstrd; clr_shadowed = GLOBALS->rgb_gc.gc_ltblue; clr_signal = GLOBALS->rgb_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->rgb_gc_white; } else { bg_color = (dobackground==2) ? GLOBALS->rgb_gc.gc_normal : GLOBALS->rgb_gc.gc_ltgray; if(HasWave(t)) { text_color = GLOBALS->rgb_gc_black; } else { text_color = (IsGroupBegin(t) || IsGroupEnd(t)) ? clr_group : clr_comment; } } if (dobackground || IsSelected(t)) { cairo_set_source_rgba (GLOBALS->cr_signalpixmap, bg_color.r, bg_color.g, bg_color.b, bg_color.a); cairo_rectangle (GLOBALS->cr_signalpixmap, 0, retval, GLOBALS->signal_fill_width, GLOBALS->fontheight-1); cairo_fill (GLOBALS->cr_signalpixmap); } cairo_set_source_rgba (GLOBALS->cr_signalpixmap, GLOBALS->rgb_gc_white.r, GLOBALS->rgb_gc_white.g, GLOBALS->rgb_gc_white.b, GLOBALS->rgb_gc_white.a); cairo_move_to (GLOBALS->cr_signalpixmap, WAVE_CAIRO_050_OFFSET, liney+WAVE_CAIRO_050_OFFSET); cairo_line_to (GLOBALS->cr_signalpixmap, GLOBALS->signal_fill_width-1+WAVE_CAIRO_050_OFFSET, liney+WAVE_CAIRO_050_OFFSET); cairo_stroke (GLOBALS->cr_signalpixmap); if((t->name)||(subname)) { XXX_font_engine_draw_string(GLOBALS->cr_signalpixmap, GLOBALS->signalfont, &text_color, (left_justify?3:3+GLOBALS->max_signal_name_pixel_width- font_engine_string_measure(GLOBALS->signalfont, buf))+WAVE_CAIRO_050_OFFSET, texty+WAVE_CAIRO_050_OFFSET, buf); } if (HasWave(t) || bv) { if((t->asciivalue)&&(!(t->flags&TR_EXCLUDE))) XXX_font_engine_draw_string(GLOBALS->cr_signalpixmap, GLOBALS->signalfont, &text_color, GLOBALS->max_signal_name_pixel_width+6+WAVE_CAIRO_050_OFFSET, texty+WAVE_CAIRO_050_OFFSET, 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 */ } GLOBALS->tims.resizemarker2 = GLOBALS->tims.resizemarker; GLOBALS->tims.resizemarker = GLOBALS->tims.marker; if(GLOBALS->signal_pixmap_width<60) GLOBALS->signal_pixmap_width=60; MaxSignalLength_2(dirty_kick); } void MaxSignalLength_2(char dirty_kick) { 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) { GtkAllocation allocation; gtk_widget_get_allocation(GLOBALS->signalwindow, &allocation); /* printf("VALUES: %d %d %d\n", GLOBALS->initial_signal_window_width, 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_size_request(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; } GtkAllocation allocation; gtk_widget_get_allocation(GLOBALS->signalwindow, &allocation); oldusize=allocation.width; if((oldusize!=rs)||(dirty_kick)) { /* keep signalwindow from expanding arbitrarily large */ int wx, wy; get_window_size(&wx, &wy); if((3*rs) < (2*wx)) /* 2/3 width max */ { int os; os=rs; os=(os<48)?48:os; gtk_widget_set_size_request(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_size_request(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; } } cairo_set_source_rgba (GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->rgb_gc.gc_grid_wavewindow_c_1.r, GLOBALS->rgb_gc.gc_grid_wavewindow_c_1.g, GLOBALS->rgb_gc.gc_grid_wavewindow_c_1.b, GLOBALS->rgb_gc.gc_grid_wavewindow_c_1.a); cairo_move_to (GLOBALS->cr_wavepixmap_wavewindow_c_1, x+WAVE_CAIRO_050_OFFSET, WAVE_CAIRO_050_OFFSET); cairo_line_to (GLOBALS->cr_wavepixmap_wavewindow_c_1, x+WAVE_CAIRO_050_OFFSET, (((!timearray_encountered)&&(GLOBALS->display_grid)&&(GLOBALS->enable_vert_grid))?GLOBALS->waveheight:fhminus2)+WAVE_CAIRO_050_OFFSET); cairo_stroke (GLOBALS->cr_wavepixmap_wavewindow_c_1); 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; cairo_move_to (GLOBALS->cr_wavepixmap_wavewindow_c_1, x+WAVE_CAIRO_050_OFFSET, GLOBALS->wavecrosspiece+WAVE_CAIRO_050_OFFSET); cairo_line_to (GLOBALS->cr_wavepixmap_wavewindow_c_1, rhs+WAVE_CAIRO_050_OFFSET, GLOBALS->wavecrosspiece+WAVE_CAIRO_050_OFFSET); cairo_stroke (GLOBALS->cr_wavepixmap_wavewindow_c_1); dx = x + (hashoffset=GLOBALS->hashstep); x = dx; while((hashoffsetpixelsperframe)&&(x<=rhs)&&(iter<9)) { cairo_move_to (GLOBALS->cr_wavepixmap_wavewindow_c_1, x+WAVE_CAIRO_050_OFFSET, GLOBALS->wavecrosspiece+WAVE_CAIRO_050_OFFSET); cairo_line_to (GLOBALS->cr_wavepixmap_wavewindow_c_1, x+WAVE_CAIRO_050_OFFSET, fhminus2+WAVE_CAIRO_050_OFFSET); cairo_stroke (GLOBALS->cr_wavepixmap_wavewindow_c_1); 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; static const double dashed1[] = { 8.0, 8.0 }; renderblackout(); tim=GLOBALS->tims.start; GLOBALS->tims.end=GLOBALS->tims.start+(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx); /***********/ WAVE_STRACE_ITERATOR_FWD(s_ctx_iter) { wave_rgb_t gc; if(!s_ctx_iter) { gc = GLOBALS->rgb_gc.gc_grid_wavewindow_c_1; cairo_set_dash(GLOBALS->cr_wavepixmap_wavewindow_c_1, dashed1, 0, 0); } else { gc = GLOBALS->rgb_gc.gc_grid2_wavewindow_c_1; /* gdk_gc_set_line_attributes(gc, 1, GDK_LINE_ON_OFF_DASH, GDK_CAP_BUTT, GDK_JOIN_BEVEL); */ cairo_set_dash(GLOBALS->cr_wavepixmap_wavewindow_c_1, dashed1, sizeof(dashed1) / sizeof(dashed1[0]), 0); } cairo_set_source_rgba (GLOBALS->cr_wavepixmap_wavewindow_c_1, gc.r, gc.g, gc.b, gc.a); 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; cairo_move_to (GLOBALS->cr_wavepixmap_wavewindow_c_1, x+WAVE_CAIRO_050_OFFSET, y+WAVE_CAIRO_050_OFFSET); cairo_line_to (GLOBALS->cr_wavepixmap_wavewindow_c_1, x+WAVE_CAIRO_050_OFFSET, GLOBALS->waveheight+WAVE_CAIRO_050_OFFSET); cairo_stroke (GLOBALS->cr_wavepixmap_wavewindow_c_1); } else { break; } } } } } 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]; /***********/ cairo_set_dash(GLOBALS->cr_wavepixmap_wavewindow_c_1, dashed1, 0, 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; cairo_set_source_rgba (GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->rgb_gc.gc_grid_wavewindow_c_1.r, GLOBALS->rgb_gc.gc_grid_wavewindow_c_1.g, GLOBALS->rgb_gc.gc_grid_wavewindow_c_1.b, GLOBALS->rgb_gc.gc_grid_wavewindow_c_1.a); 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; cairo_move_to (GLOBALS->cr_wavepixmap_wavewindow_c_1, x+WAVE_CAIRO_050_OFFSET, y+WAVE_CAIRO_050_OFFSET); cairo_line_to (GLOBALS->cr_wavepixmap_wavewindow_c_1, x+WAVE_CAIRO_050_OFFSET, GLOBALS->waveheight+WAVE_CAIRO_050_OFFSET); cairo_stroke (GLOBALS->cr_wavepixmap_wavewindow_c_1); } } /***********/ 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)) { XXX_font_engine_draw_string(GLOBALS->cr_wavepixmap_wavewindow_c_1,GLOBALS->wavefont,&GLOBALS->rgb_gc.gc_time_wavewindow_c_1,x-lenhalf+WAVE_CAIRO_050_OFFSET, GLOBALS->wavefont->ascent-1+WAVE_CAIRO_050_OFFSET,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) { XXX_gdk_draw_rectangle(GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->rgb_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_rgbmaster_t *gc_sav) { if((!GLOBALS->black_and_white) && (t->t_color)) { int color = t->t_color; color--; memcpy(gc_sav, &GLOBALS->rgb_gc, sizeof(struct wave_rgbmaster_t)); if(color < WAVE_NUM_RAINBOW) { XXX_set_alternate_gcs(GLOBALS->rgb_gc_rainbow[2*color], GLOBALS->rgb_gc_rainbow[2*color+1]); } } } static void gc_restore(Trptr t, struct wave_rgbmaster_t *gc_sav) { if((!GLOBALS->black_and_white) && (t->t_color)) { memcpy(&GLOBALS->rgb_gc, gc_sav, sizeof(struct wave_rgbmaster_t)); } } static void rendertraces(void) { struct wave_rgbmaster_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; GtkAllocation allocation; gtk_widget_get_allocation(GLOBALS->wavearea, &allocation); num_traces_displayable=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); } #ifdef GDK_WINDOWING_WAYLAND if(GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default())) gtk_widget_queue_draw(GLOBALS->wavearea); #endif } /* * 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; wave_rgb_t c; wave_rgb_t 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->highlight_wavewindow) && (t) && (t->flags & TR_HIGHLIGHT) && (!GLOBALS->black_and_white) && (!kill_grid)) { XXX_gdk_draw_rectangle(GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->rgb_gc.gc_grid_wavewindow_c_1, TRUE,0, liney - GLOBALS->fontheight, GLOBALS->wavewidth, GLOBALS->fontheight); } else if((GLOBALS->display_grid)&&(GLOBALS->enable_horiz_grid)&&(!kill_grid)) { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->rgb_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->rgb_gc.gc_x_wavewindow_c_1; break; case AN_U: c = GLOBALS->rgb_gc.gc_u_wavewindow_c_1; break; case AN_W: c = GLOBALS->rgb_gc.gc_w_wavewindow_c_1; break; case AN_DASH: c = GLOBALS->rgb_gc.gc_dash_wavewindow_c_1; break; default: c = (h->v.h_val == AN_X) ? GLOBALS->rgb_gc.gc_x_wavewindow_c_1: GLOBALS->rgb_gc.gc_trans_wavewindow_c_1; } XXX_gdk_draw_line(GLOBALS->cr_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) { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->rgb_gc.gc_w_wavewindow_c_1, _x0, _y0, _x0, _y1); XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->rgb_gc.gc_w_wavewindow_c_1, _x0, _y1, _x0+2, _y1+2); XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->rgb_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->rgb_gc.gc_x_wavewindow_c_1; break; case AN_U: c = GLOBALS->rgb_gc.gc_u_wavewindow_c_1; break; case AN_W: c = GLOBALS->rgb_gc.gc_w_wavewindow_c_1; break; case AN_DASH: c = GLOBALS->rgb_gc.gc_dash_wavewindow_c_1; break; default: c = (hval == AN_X) ? GLOBALS->rgb_gc.gc_x_wavewindow_c_1: GLOBALS->rgb_gc.gc_trans_wavewindow_c_1; } switch(hval) { case AN_0: /* 0 */ case AN_L: /* L */ if(GLOBALS->fill_waveform && invert) { switch(hval) { case AN_0: gcxf = GLOBALS->rgb_gc.gc_1fill_wavewindow_c_1; break; case AN_L: gcxf = GLOBALS->rgb_gc.gc_highfill_wavewindow_c_1; break; } XXX_gdk_draw_rectangle(GLOBALS->cr_wavepixmap_wavewindow_c_1, gcxf, TRUE,_x0+1, _y0, _x1-_x0, _y1-_y0+1); } XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, (hval==AN_0) ? GLOBALS->rgb_gc.gc_0_wavewindow_c_1 : GLOBALS->rgb_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: XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, c, _x1, _y0, _x1, yu); break; default: XXX_gdk_draw_line(GLOBALS->cr_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->rgb_gc.gc_x_wavewindow_c_1; gcxf = GLOBALS->rgb_gc.gc_xfill_wavewindow_c_1; identifier_str[0] = 0; break; case AN_W: c = gcx = GLOBALS->rgb_gc.gc_w_wavewindow_c_1; gcxf = GLOBALS->rgb_gc.gc_wfill_wavewindow_c_1; identifier_str[0] = 'W'; break; case AN_U: c = gcx = GLOBALS->rgb_gc.gc_u_wavewindow_c_1; gcxf = GLOBALS->rgb_gc.gc_ufill_wavewindow_c_1; identifier_str[0] = 'U'; break; default: c = gcx = GLOBALS->rgb_gc.gc_dash_wavewindow_c_1; gcxf = GLOBALS->rgb_gc.gc_dashfill_wavewindow_c_1; identifier_str[0] = '-'; break; } if(invert) { XXX_gdk_draw_rectangle(GLOBALS->cr_wavepixmap_wavewindow_c_1, gcx, TRUE,_x0+1, _y0, _x1-_x0, _y1-_y0+1); } else { XXX_gdk_draw_rectangle(GLOBALS->cr_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)) { XXX_font_engine_draw_string(GLOBALS->cr_wavepixmap_wavewindow_c_1,GLOBALS->wavefont, &GLOBALS->rgb_gc.gc_value_wavewindow_c_1, _x0+2+WAVE_CAIRO_050_OFFSET,ytext+WAVE_CAIRO_050_OFFSET,identifier_str); } } } XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, gcx,_x0, _y0,_x1, _y0); XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, gcx,_x0, _y1,_x1, _y1); if(h2tim<=GLOBALS->tims.end) XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, c, _x1, _y0, _x1, _y1); break; case AN_Z: /* Z */ XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->rgb_gc.gc_mid_wavewindow_c_1,_x0, yu,_x1, yu); if(h2tim<=GLOBALS->tims.end) switch(h2val) { case AN_0: case AN_L: XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, c, _x1, yu, _x1, _y0); break; case AN_1: case AN_H: XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, c, _x1, yu, _x1, _y1); break; default: XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, c, _x1, _y0, _x1, _y1); break; } break; case AN_1: /* 1 */ case AN_H: /* 1 */ if(GLOBALS->fill_waveform && !invert) { switch(hval) { case AN_1: gcxf = GLOBALS->rgb_gc.gc_1fill_wavewindow_c_1; break; case AN_H: gcxf = GLOBALS->rgb_gc.gc_highfill_wavewindow_c_1; break; } XXX_gdk_draw_rectangle(GLOBALS->cr_wavepixmap_wavewindow_c_1, gcxf, TRUE,_x0+1, _y1, _x1-_x0, _y0-_y1+1); } XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, (hval==AN_1) ? GLOBALS->rgb_gc.gc_1_wavewindow_c_1 : GLOBALS->rgb_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: XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, c, _x1, _y1, _x1, _y0); break; case AN_Z: XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, c, _x1, _y1, _x1, yu); break; default: XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, c, _x1, _y0, _x1, _y1); break; } break; default: break; } } else { if(!is_event) { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->rgb_gc.gc_trans_wavewindow_c_1, _x1, _y0, _x1, _y1); } else { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->rgb_gc.gc_w_wavewindow_c_1, _x1, _y0, _x1, _y1); XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->rgb_gc.gc_w_wavewindow_c_1, _x0, _y1, _x0+2, _y1+2); XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->rgb_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; } } if((h->flags & HIST_GLITCH) && (GLOBALS->vcd_preserve_glitches)) { XXX_gdk_draw_rectangle(GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->rgb_gc.gc_mid_wavewindow_c_1, TRUE,_x1-1, yu-1, 3, 3); } h=h->next; } 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 */ wave_rgb_t c, ci; wave_rgb_t cnan = GLOBALS->rgb_gc.gc_u_wavewindow_c_1; wave_rgb_t cinf = GLOBALS->rgb_gc.gc_w_wavewindow_c_1; wave_rgb_t 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->rgb_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_COUNT; 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_X) { c = GLOBALS->rgb_gc.gc_vbox_wavewindow_c_1; } else { c = GLOBALS->rgb_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) { XXX_gdk_draw_rectangle(GLOBALS->cr_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)) { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, ci,_x1-1, yt1,_x1+1, yt1); XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, ci,_x1, yt1-1,_x1, yt1+1); XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, ci,_x0-1, _y0,_x0+1, _y0); XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, ci,_x0, _y0-1,_x0, _y0+1); XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, ci,_x0-1, _y1,_x0+1, _y1); XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, ci,_x0, _y1-1,_x0, _y1+1); } } if(is_nan2) { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, cfixed,_x0, yt0, _x1, yt0); if((t->flags & (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP)) == (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP)) { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, cnan,_x1, yt1,_x1, yt0); XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, ci,_x1-1, _y0,_x1+1, _y0); XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, ci,_x1, _y0-1,_x1, _y0+1); XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, ci,_x1-1, _y1,_x1+1, _y1); XXX_gdk_draw_line(GLOBALS->cr_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) { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, ci,_x0-1, yt0,_x0+1, yt0); XXX_gdk_draw_line(GLOBALS->cr_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))) { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, cfixed,0, yt0,_x1,yt1); } else { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, cfixed,_x0, yt0,_x1,yt1); } } else { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, cfixed,_x0, yt0,_x1,yt1); } } else /* if(t->flags & TR_ANALOG_STEP) */ { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, cfixed,_x0, yt0,_x1, yt0); if(is_inf2) cfixed = cinf; XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, cfixed,_x1, yt0,_x1, yt1); if ((t->flags & (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP)) == (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP)) { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, ci,_x0-1, yt0,_x0+1, yt0); XXX_gdk_draw_line(GLOBALS->cr_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 */ } } /* * 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; wave_rgb_t 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->highlight_wavewindow) && (t) && (t->flags & TR_HIGHLIGHT) && (!GLOBALS->black_and_white)) { Trptr tn = GiveNextTrace(t); if((t->flags & TR_ANALOGMASK) && (tn) && (tn->flags & TR_ANALOG_BLANK_STRETCH)) { XXX_gdk_draw_rectangle(GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->rgb_gc.gc_grid_wavewindow_c_1, TRUE,0, liney - GLOBALS->fontheight, GLOBALS->wavewidth, GLOBALS->fontheight); } else { XXX_gdk_draw_rectangle(GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->rgb_gc.gc_grid_wavewindow_c_1, TRUE,0, liney - GLOBALS->fontheight, GLOBALS->wavewidth, GLOBALS->fontheight); } } else 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 { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->rgb_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)) { XXX_gdk_draw_rectangle(GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->rgb_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_COUNT; 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_COUNT; */ if(_x0>-1) { wave_rgb_t gltype, gtype; switch(lasttype) { case AN_X: gltype = GLOBALS->rgb_gc.gc_x_wavewindow_c_1; break; case AN_U: gltype = GLOBALS->rgb_gc.gc_u_wavewindow_c_1; break; default: gltype = GLOBALS->rgb_gc.gc_vtrans_wavewindow_c_1; break; } switch(type) { case AN_X: gtype = GLOBALS->rgb_gc.gc_x_wavewindow_c_1; break; case AN_U: gtype = GLOBALS->rgb_gc.gc_u_wavewindow_c_1; break; default: gtype = GLOBALS->rgb_gc.gc_vtrans_wavewindow_c_1; break; } if(GLOBALS->use_roundcaps) { if (type == AN_Z) { if (lasttype != -1) { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, gltype,_x0-1, _y0,_x0, yu); if(lasttype != AN_0) XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, gltype,_x0, yu,_x0-1, _y1); } } else if (lasttype==AN_Z) { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, gtype,_x0+1, _y0,_x0, yu); if( type != AN_0) XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, gtype,_x0, yu,_x0+1, _y1); } else { if (lasttype != type) { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, gltype,_x0-1, _y0,_x0, yu); if(lasttype != AN_0) XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, gltype,_x0, yu,_x0-1, _y1); XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, gtype,_x0+1, _y0,_x0, yu); if( type != AN_0) XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, gtype,_x0, yu,_x0+1, _y1); } else { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, gtype,_x0-2, _y0,_x0+2, _y1); XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, gtype,_x0+2, _y0,_x0-2, _y1); } } } else { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, gtype,_x0, _y0,_x0, _y1); } } if(_x0!=_x1) { if (type == AN_Z) { if(GLOBALS->use_roundcaps) { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->rgb_gc.gc_mid_wavewindow_c_1,_x0+1, yu,_x1-1, yu); } else { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->rgb_gc.gc_mid_wavewindow_c_1,_x0, yu,_x1, yu); } } else { if((type != AN_X) && (type != AN_U)) { c = GLOBALS->rgb_gc.gc_vbox_wavewindow_c_1; } else { c = GLOBALS->rgb_gc.gc_x_wavewindow_c_1; } if(GLOBALS->use_roundcaps) { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, c,_x0+2, _y0,_x1-2, _y0); if(type != AN_0) XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, c,_x0+2, _y1,_x1-2, _y1); if(type == AN_1) XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, c,_x0+2, _y1+1,_x1-2, _y1+1); } else { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, c,_x0, _y0,_x1, _y0); if(type != AN_0) XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, c,_x0, _y1,_x1, _y1); if(type == AN_1) XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, c,_x0, _y1+1,_x1, _y1+1); } 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 == '?') { wave_rgb_t cb; char *srch_for_color = strchr(ascii+1, '?'); if(srch_for_color) { *srch_for_color = 0; cb = XXX_get_gc_from_name(ascii+1); if(cb.a != 0.0) { ascii2 = srch_for_color + 1; if(memcmp(&GLOBALS->rgb_gc.gc_back_wavewindow_c_1, &GLOBALS->rgb_gc_white, sizeof(wave_rgb_t))) { if(!GLOBALS->black_and_white) XXX_gdk_draw_rectangle(GLOBALS->cr_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)) { XXX_font_engine_draw_string(GLOBALS->cr_wavepixmap_wavewindow_c_1,GLOBALS->wavefont,&GLOBALS->rgb_gc.gc_value_wavewindow_c_1,_x0+2+WAVE_CAIRO_050_OFFSET,ytext+WAVE_CAIRO_050_OFFSET,ascii2); } else { char *mod; mod=bsearch_trunc(ascii2,width-GLOBALS->vector_padding); if(mod) { *mod='+'; *(mod+1)=0; XXX_font_engine_draw_string(GLOBALS->cr_wavepixmap_wavewindow_c_1,GLOBALS->wavefont,&GLOBALS->rgb_gc.gc_value_wavewindow_c_1,_x0+2+WAVE_CAIRO_050_OFFSET,ytext+WAVE_CAIRO_050_OFFSET,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 == '?') { wave_rgb_t cb; char *srch_for_color = strchr(ascii+1, '?'); if(srch_for_color) { *srch_for_color = 0; cb = XXX_get_gc_from_name(ascii+1); if(cb.a != 0.0) { /* ascii2 = srch_for_color + 1; */ /* scan-build */ if(memcmp(&GLOBALS->rgb_gc.gc_back_wavewindow_c_1, &GLOBALS->rgb_gc_white, sizeof(wave_rgb_t))) { if(!GLOBALS->black_and_white) XXX_gdk_draw_rectangle(GLOBALS->cr_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; 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 */ wave_rgb_t c, ci; wave_rgb_t cnan = GLOBALS->rgb_gc.gc_u_wavewindow_c_1; wave_rgb_t cinf = GLOBALS->rgb_gc.gc_w_wavewindow_c_1; wave_rgb_t 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->rgb_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_X) { c = GLOBALS->rgb_gc.gc_vbox_wavewindow_c_1; } else { c = GLOBALS->rgb_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) { XXX_gdk_draw_rectangle(GLOBALS->cr_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)) { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, ci,_x1-1, yt1,_x1+1, yt1); XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, ci,_x1, yt1-1,_x1, yt1+1); XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, ci,_x0-1, _y0,_x0+1, _y0); XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, ci,_x0, _y0-1,_x0, _y0+1); XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, ci,_x0-1, _y1,_x0+1, _y1); XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, ci,_x0, _y1-1,_x0, _y1+1); } } if(is_nan2) { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, cfixed,_x0, yt0, _x1, yt0); if((t->flags & (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP)) == (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP)) { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, cnan,_x1, yt1,_x1, yt0); XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, ci,_x1-1, _y0,_x1+1, _y0); XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, ci,_x1, _y0-1,_x1, _y0+1); XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, ci,_x1-1, _y1,_x1+1, _y1); XXX_gdk_draw_line(GLOBALS->cr_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) { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, ci,_x0-1, yt0,_x0+1, yt0); XXX_gdk_draw_line(GLOBALS->cr_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))) { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, cfixed,0, yt0,_x1,yt1); } else { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, cfixed,_x0, yt0,_x1,yt1); } } else { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, cfixed,_x0, yt0,_x1,yt1); } } else /* if(t->flags & TR_ANALOG_STEP) */ { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, cfixed,_x0, yt0,_x1, yt0); if(is_inf2) cfixed = cinf; XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, cfixed,_x1, yt0,_x1, yt1); if ((t->flags & (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP)) == (TR_ANALOG_INTERPOLATED|TR_ANALOG_STEP)) { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, ci,_x0-1, yt0,_x0+1, yt0); XXX_gdk_draw_line(GLOBALS->cr_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; */ } 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; wave_rgb_t 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->highlight_wavewindow) && (t) && (t->flags & TR_HIGHLIGHT) && (!GLOBALS->black_and_white)) { Trptr tn = GiveNextTrace(t); if((t->flags & TR_ANALOGMASK) && (tn) && (tn->flags & TR_ANALOG_BLANK_STRETCH)) { XXX_gdk_draw_rectangle(GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->rgb_gc.gc_grid_wavewindow_c_1, TRUE,0, liney - GLOBALS->fontheight, GLOBALS->wavewidth, GLOBALS->fontheight); } else { XXX_gdk_draw_rectangle(GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->rgb_gc.gc_grid_wavewindow_c_1, TRUE,0, liney - GLOBALS->fontheight, GLOBALS->wavewidth, GLOBALS->fontheight); } } else 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 { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->rgb_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)) { XXX_gdk_draw_rectangle(GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->rgb_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) { wave_rgb_t gltype, gtype; switch(lasttype) { case AN_X: gltype = GLOBALS->rgb_gc.gc_x_wavewindow_c_1; break; case AN_U: gltype = GLOBALS->rgb_gc.gc_u_wavewindow_c_1; break; default: gltype = GLOBALS->rgb_gc.gc_vtrans_wavewindow_c_1; break; } switch(type) { case AN_X: gtype = GLOBALS->rgb_gc.gc_x_wavewindow_c_1; break; case AN_U: gtype = GLOBALS->rgb_gc.gc_u_wavewindow_c_1; break; default: gtype = GLOBALS->rgb_gc.gc_vtrans_wavewindow_c_1; break; } if(GLOBALS->use_roundcaps) { if (type == AN_Z) { if (lasttype != -1) { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, gltype,_x0-1, _y0,_x0, yu); if(lasttype != AN_0) XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, gltype,_x0, yu,_x0-1, _y1); } } else if (lasttype==AN_Z) { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, gtype,_x0+1, _y0,_x0, yu); if( type != AN_0) XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, gtype,_x0, yu,_x0+1, _y1); } else { if (lasttype != type) { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, gltype,_x0-1, _y0,_x0, yu); if(lasttype != AN_0) XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, gltype,_x0, yu,_x0-1, _y1); XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, gtype,_x0+1, _y0,_x0, yu); if( type != AN_0) XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, gtype,_x0, yu,_x0+1, _y1); } else { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, gtype,_x0-2, _y0,_x0+2, _y1); XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, gtype,_x0+2, _y0,_x0-2, _y1); } } } else { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, gtype,_x0, _y0,_x0, _y1); } } if(_x0!=_x1) { if (type == AN_Z) { if(GLOBALS->use_roundcaps) { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->rgb_gc.gc_mid_wavewindow_c_1,_x0+1, yu,_x1-1, yu); } else { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, GLOBALS->rgb_gc.gc_mid_wavewindow_c_1,_x0, yu,_x1, yu); } } else { if((type != AN_X) && (type != AN_U)) { c = GLOBALS->rgb_gc.gc_vbox_wavewindow_c_1; } else { c = GLOBALS->rgb_gc.gc_x_wavewindow_c_1; } if(GLOBALS->use_roundcaps) { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, c,_x0+2, _y0,_x1-2, _y0); if(type != AN_0) XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, c,_x0+2, _y1,_x1-2, _y1); if(type == AN_1) XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, c,_x0+2, _y1+1,_x1-2, _y1+1); } else { XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, c,_x0, _y0,_x1, _y0); if(type != AN_0) XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, c,_x0, _y1,_x1, _y1); if(type == AN_1) XXX_gdk_draw_line(GLOBALS->cr_wavepixmap_wavewindow_c_1, c,_x0, _y1+1,_x1, _y1+1); } 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 == '?') { wave_rgb_t cb; char *srch_for_color = strchr(ascii+1, '?'); if(srch_for_color) { *srch_for_color = 0; cb = XXX_get_gc_from_name(ascii+1); if(cb.a != 0.0) { ascii2 = srch_for_color + 1; if(!GLOBALS->black_and_white) XXX_gdk_draw_rectangle(GLOBALS->cr_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)) { XXX_font_engine_draw_string(GLOBALS->cr_wavepixmap_wavewindow_c_1,GLOBALS->wavefont,&GLOBALS->rgb_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; XXX_font_engine_draw_string(GLOBALS->cr_wavepixmap_wavewindow_c_1,GLOBALS->wavefont,&GLOBALS->rgb_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 == '?') { wave_rgb_t cb; char *srch_for_color = strchr(ascii+1, '?'); if(srch_for_color) { *srch_for_color = 0; cb = XXX_get_gc_from_name(ascii+1); if(cb.a != 0.0) { /* ascii2 = srch_for_color + 1; */ if(memcmp(&GLOBALS->rgb_gc.gc_back_wavewindow_c_1, &GLOBALS->rgb_gc_white, sizeof(wave_rgb_t))) { if(!GLOBALS->black_and_white) XXX_gdk_draw_rectangle(GLOBALS->cr_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; GLOBALS->tims.start+=GLOBALS->shift_timebase; GLOBALS->tims.end+=GLOBALS->shift_timebase; } gtkwave-gtk3-3.3.125/src/fonts.h0000664000175000017500000000221715047725113015611 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 #include #include #include struct font_engine_font_t { PangoFontDescription *desc; PangoFont *font; PangoFontMetrics *metrics; int ascent, descent; int mono_width; /* GdkFont *gdkfont; */ unsigned is_mono : 1; }; void load_all_fonts(void); gint font_engine_string_measure (struct font_engine_font_t *font, const gchar *string); void XXX_font_engine_draw_string (cairo_t *cr, struct font_engine_font_t *font, wave_rgb_t *gc, gint x, gint y, const gchar *string); #endif gtkwave-gtk3-3.3.125/src/savefile.c0000664000175000017500000016762015047725113016263 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2012-2016. * * 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; TraceFlagsType 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(GLOBALS->open_tree_nodes) { dump_open_tree_nodes(wave, GLOBALS->open_tree_nodes); } 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))); } } 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,"@%"TRACEFLAGSPRIFMT"\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_FPDECSHIFT) { fprintf(wave, "[fpshift_count] %d\n", t->t_fpdecshift); } if(t->flags & TR_FTRANSLATED) { if(t->f_filter && GLOBALS->filesel_filter[t->f_filter]) { #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED || defined __CYGWIN__ || defined HAVE_REALPATH || defined __MINGW32__ char *can = realpath_2(GLOBALS->filesel_filter[t->f_filter], NULL); fprintf(wave, "^%d %s\n", t->f_filter, can); free(can); #else fprintf(wave, "^%d %s\n", t->f_filter, GLOBALS->filesel_filter[t->f_filter]); #endif } else { fprintf(wave, "^%d %s\n", 0, "disabled"); } } else if(t->flags & TR_PTRANSLATED) { if(t->p_filter && GLOBALS->procsel_filter[t->p_filter]) { #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED || defined __CYGWIN__ || defined HAVE_REALPATH || defined __MINGW32__ char *can = realpath_2(GLOBALS->procsel_filter[t->p_filter], NULL); fprintf(wave, "^>%d %s\n", t->p_filter, can); free(can); #else fprintf(wave, "^>%d %s\n", t->p_filter, GLOBALS->procsel_filter[t->p_filter]); #endif } 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" %"TRACEFLAGSPRIFMT, 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,"@%"TRACEFLAGSPRIFMT"\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" %"TRACEFLAGSPRIFMT, 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_san(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 __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_san(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->default_fpshift=0; 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->default_fpshift=0; 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; int current_grp_depth = -1; 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, "%"TRACEFLAGSSCNFMT, &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(GLOBALS->default_flags&TR_GRP_BEGIN) { current_grp_depth = GLOBALS->group_depth; } if(b) { if((v=bits2vector(b))) { v->bits=b; /* only needed for savefile function */ AddVector(v, alias); free_2(b->name); b->name=NULL; goto grp_bot; } 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 } } } grp_bot: if((GLOBALS->default_flags&TR_GRP_BEGIN) && (current_grp_depth >= 0) && (current_grp_depth == GLOBALS->group_depth)) { AddBlankTrace(prefix+1); } 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) { gtk_paned_set_position(GTK_PANED(GLOBALS->toppanedwindow), x); } 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) { gtk_paned_set_position(GTK_PANED(GLOBALS->panedwindow), x); } 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(!GLOBALS->block_xy_update) { if(GLOBALS->expanderwindow) { gtk_expander_set_expanded(GTK_EXPANDER(GLOBALS->expanderwindow), GLOBALS->sst_expanded); } } } } 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) { gtk_paned_set_position(GTK_PANED(GLOBALS->sst_vpaned), x); } 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, "fpshift_count") == 0) { int fpshift_count = 0; sscanf (w, "%d", &fpshift_count); if((fpshift_count<0)||(fpshift_count>255)) { fpshift_count = 0; } GLOBALS->default_fpshift = fpshift_count; } 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 = 2; } else if (strcmp (w2, "treeopen") == 0) { while(*w) { if(!isspace((int)(unsigned char)*w)) { break; } w++; } if(GLOBALS->treestore_main) { force_open_tree_node(w, 0, NULL); } else { /* cache values until treestore_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; } } } 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 __MINGW32__ #define ABSOLUTE_NAME_START 3 #else #define ABSOLUTE_NAME_START 1 #endif /* set this to '\\' for DOS or '/' for UNIX */ #if 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_2(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); } char *find_dumpfile(char *orig_save, char *orig_dump, char *this_save) { char *dfile = NULL; dfile = find_dumpfile_2(orig_save, orig_dump, this_save); if(!dfile && orig_save && orig_dump) { const char *pfx = "/././"; int pfxlen = strlen(pfx); char *orig_save2 = malloc_2(strlen(orig_save) + pfxlen + 1); char *orig_dump2 = malloc_2(strlen(orig_dump) + pfxlen + 1); strcpy(orig_save2, pfx); strcat(orig_save2, orig_save); strcpy(orig_dump2, pfx); strcat(orig_dump2, orig_dump); dfile = find_dumpfile_2(orig_save2, orig_dump2, this_save); if(!dfile) { free_2(orig_dump2); free_2(orig_save2); } } return(dfile); } /******************************************************************/ /* * 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-gtk3-3.3.125/ChangeLog0000664000175000017500000027511515047725113015303 0ustar bybellbybell3.0.0 01may06 Initial release after promotion from 1.3.86 in order to reduce confusion with 2.x series. Added user's manual pdf file to distribution in doc/. Added vertex and rtlbrowse for sourcecode annotation. 3.0.1 09may06 Automatically add extensions to save filenames in gtkwave. Cygwin compile fixes. Add Cygwin functionality for fork() related ops that do in fact work properly. 3.0.2 09may06 More fixes for full function (except pthreads) in Cygwin. Requires usage of Cygserver if rtlbrowse is to work. Fixed fonts for Cygwin to improve readability. The Courier font is very bad looking and blitter mangled under cygwin. 3.0.3 29may06 Changed yylineno references in vlex.l in rtlbrowse to my_yylineno as newer versions of flex automatically define this and cause duplicate symbols. Saw there were still problems with courier on debian. Also check for misc-fixed on non-cygwin systems just in case. 3.0.4 30may06 Added busy watch (hourglass) for long ops that lock the GUI. Fixed replace function in treesearch_gtk2 so it doesn't simply replace with the last signal. (Iterator shouldn't be used the way it was.) 3.0.5 08jun06 Reworked tree structure code to handle new tree layout such that strings are embedded at the end of struct. This reduces memory usage overall. Added in implicit hierarchy split on pipe character in symbol names as these only really happen in netlists that have escaped identifiers. For vzt and lxt2 loaders added block allocation of symbols and nodes during init in order to allow denser memory allocation as the bookkeeping overhead between allocations internal to malloc() is unnecessary as the number of elements is known at the outset. Also removed hashing in aet2, lxt, lxt2, vzt as sym[hv] is unused on sorted facs. Removed unnecessary strlen() calls after sprintf() in the dumpfile loaders as the string length is known from the rc of sprintf. Fixed T_SCOPE rule in vcd.c as dotted hierarchies would throw off the parser as hierarchies themselves are (in practice) never really escaped. In tree.c, treenamefix() would recurse more than necessary such that some dotted hierarchies would cause an order of n squared recursion and as such never complete running due to the size of the hierarchy. Found non _2 versions of memory allocate/free being used in various non-library places. Fixed signal aliasing problems in GHW traces that have memories or aliased signals in ghw.c. Added handling for e8 datatypes and arrays in ghwlib.c and ghw.c. Updated ghwlib.c and main.c in order to handle gzip or bzip2 compressed files. Extension can be .ghw, .ghw.gz, or .ghw.bz2 and the file will be handled properly. Note that as the matchword is consulted, just .ghw can be used to specify a gzip or bzip2 file implicitly. Added ghwdump and ghwdump.1 to the distribution (from ghdl) as it is helpful for debugging ghw file failures. 3.0.6 14jul06 Added "Real" option for data type display as passing around real numbers in Verilog across modules needs to be done with $realtobits and $bitstoreal. Added scripting command flag --script in order to allow autosetup of things that are outside of config file control. This also allows doing things such as automated print jobs. Added --nowm to remove window manager control on most windows the viewer brings up. Added --xid to allow turning the viewer into a plug-in for calling by foreign applications. This will allow integration of the viewer into a single window for example, with IDEs. Added --nomenus to remove menus for the case when used in conjunction with --xid and it is desired to create an embedded wave viewer applet that cannot initiate file I/O on its own. Note that earlier versions of GTK+ cannot handle menu events properly from a GtkPlug. Fixed problem with dead memory allocations for GtkColor structs in color.c as found by Valgrind. Moved .odt version of the user's guide into doc/ rather than the pdf version as this is a sourcecode distribution so the original word processor document should be there. The .pdf will still be up on the homepage on the website. Added example script (for use with the -S option) in the examples/ directory that prints some waves then exits. Found problem with directive-based string embedding in older gcc compiler versions. GTK+-1.2 doesn't handle GtkPlug. 3.0.7 17jul06 Added support for dualview of waveforms using GtkPlug and shared memory IPC through use of the "twinwave" front end. Updated documentation to add a section on twinwave. 3.0.8 04aug06 Modified order of flags in twinwave as appending flags does not work when longopt isn't used. Subscripted GtkItemFactoryEntry menu_items for AIX compile. More AIX fixes such as conditional alloca.h usage and not including getopt.h. Removed unused "bus" element from struct fac. Added interactive loading of vcd files with the routines in vcd_partial.c. Added shmidcat to the distribition to test this new interactive loading functionality. Added real_parameter vartype (Riviera Aldec 2006.6) in all vcd loaders. 3.0.9 10aug06 Fixing compiler warnings across various systems. Minor speedup in sigcmp() in bitvec.c for EOS detection. Fix in vcd_partial.c loader that crashed on interactive loads when blank traces are present in the save file. 3.0.10 13aug06 Found inadvertant 64/32 bit conversion in regex.c that was from not including "debug.h" header file. Missing headers for gcc-3.2.x and earlier dealing with select(). Converted fgetmalloc() to use vlists in order to cut down on the backflips and traversal required for the old one character per struct method. Added VCD recoder that stores the VCD in memory using a new recoding scheme rather than histents. HistEnt structs are created as needed. The old VCD loader is still used for --interactive, or if --legacy is used at the command line. Added dynamic zlib compression support to VCD recoder and vlist_compression_depth rc variable. -1 disables, 0-9 mirror zlib compression depths. 3.0.11 12sep06 Updated documentation to include section on VCD recoding strategy and LXT (version 1) file format. Removed unnecessary mallocs and functions in vcd_recoder.c. Cleanup of all warnings with gcc -pedantic in gcc3 excluding long long integer constant and string constant length warnings. Disabled splash screen when loading VCD from stdin. Cygwin compile fixes (3.0.10 broke the compile). 3.0.12 19sep06 Updated production rule in verilog.g to handle compiling parameterized components in opensparc without dying. Integrated a lot of compatibility fixes from Peter O'Gorman. Actually use config.h for better compatibility now. Check for endianness in vzt read/write if XDRs not available rather than assuming windows will byte reverse. Fixed single time read in vzt_read.c as it wasn't working properly in rtlbrowse. Added -f (insert args from file) option to vertex. 3.0.13 06oct06 Updated odt file documentation to make chapter-like page breaks. Updated lxt2vcd and vzt2vcd to emit proper VCD headers for other tools that expect them. Added attempt_vecmatch() in bitvec.c to match vectors based on numbers inside nets in order to match on vectors inside of flattened netlist latches (e.g., top.xyz[0:7]_Z). Fixed regex compare on illegal regexs that caused viewer crash (e.g., when comparing on a single left bracket or any other illegal regex). 3.0.14 17oct06 Fixed vztminer and lxt2miner so not specifying -n actually works. Updated manpages and UM for those executables to fix description errors. Now can snap cursor to named markers--this was overlooked. Changed recoder scheme for single bits slightly in order to pack 2 more bits in for 0/1 transitions. This implies that 0..31 timesteps can be encoded in 1 byte for the common case. 3.0.15 27oct06 Added getopt_long from GNU project. Fixed broken compile under GTK1 for rtlbrowse makefile. Now can recoalesce bitblasted vectors in rtlbrowse. Updated finalize in vcd recoder to add fake 'x' vch for non-aliased facilities. Normally all facs are initialized, but noticed that libvcddump doesn't do this. 3.0.16 13nov06 Patches to remove some compile warnings under Cygwin. Changed maxdata linker flag for AIX to allow 3.25GB of data segment area for AIX5.3. Changed unsigned integer splay comparisons in vzt_write.c for a slight speedup. Updated configure patch scripts to patch over a "LEX = :" glitch for AIX5.3 and also to use gcc in AIX for the pccts compile because of xlc incompatibilities with it. Fixed bug in draw_hptr_trace_vector_analog() that would cause crashes on pure real vectors when zoomed out fully. Added dynamic tooltips on current marker values for both the left and middle mouse buttons (not tested for Win32 yet so disabled there). Added preliminary support for changing menu accelerators through the rc file with an "accel" statement. 3.0.17 27nov06 Fix in vcd recoder for SystemC which doesn't emit time zero in the initial dumpvars. (would be needed anyway for dumpers that for some reason don't as the 1st value change collapses into the second) 3.0.18 28nov06 Fix in vcd saver for when units are in seconds: keeps timescale of "ss" being used instead of just "s". Locale problem in printing of floating point numbers fixed by setting up a local fixer routine in config.h for availability across all executables. Fix in all vcd loaders to handle "port" (along with other keywords) that appear in non-keyword parts of the $VAR declaration sequence. Fixed long standing LXT bug with integer datatype on trivial LXT files. (Overflow in lt_buf decoder buffer.) 3.0.19 21dec06 More locale fixing with LC_ALL. Added user patches from NIIBE Yutaka to remove requirement for the GTK_ENABLE_BROKEN flag in GTK2 compilation. 3.0.20 21jan07 Fixed string/real handling in VCD recoder as it did not properly add the right-hand side endcaps which would crash pattern search. Made vcd recoder more robust to be able to handle 'b' value changes for string data as well as wires with 's' type data (for FlashSim). Updated strace.c to allow forward/backward on strings and reals. 3.0.21 02feb07 Added support for in/out/inout evcd ports generated by dumpports in ModelSim. Fixed problem with hierarchy being out of order as treegraft needed to be followed by treesort. This mostly impacted recursive hierarchy imports by only allowing two signals to import rather than all of them. Also there was an inconsistency with the signal ordering with VCD vs the database formats because of this. 3.0.22 19feb07 Bumped up hash size from 65519 to 500009 entries for VCD parsers. Bumped up max VCDID fastindex size to 8M entries. Now use gperf for verilog datatypes for some speedup in gtkwave vcd loaders. create_sorted_table() changed to deallocate long names in vcd converters as the names are no longer needed once the writer has them. Fixed GTK1 makefile in src/ as twinwave had pkg-config for GTK2. Stray getopt.h include in v2l_analyzer_lxt2.h needed to be #ifdef'ed with HAVE_GETOPT_H for Solaris. XDR library -lnsl explicitly listed for Solaris. PATH_MAX set if not defined in verilog.g for Vertex. Regenerated configure for setenv()/unsetenv() presence which impacts Solaris (use putenv() instead). Regenerated configure to handle auto detect of -lnsl, -lrpc, and -lpthread. Added -c to file install in top-level makefile (Solaris). Use _LARGEFILE_SOURCE value from configure with linux rather than assuming it is always 1 with linux. Fix to preproc.c in vertex as it was attempting to parse directories. This works ok under linux with EOF but causes problems under AIX. 3.0.23 19mar07 Added corresponding va_end() for all va_start(). Added optional frequency display between markers, also added rc variable of use_frequency_display and menu options to support this. Placed mainbox for marker text label widgets inside an event box as this seems to fix the centering problems with GTK2. 3.0.24 02apr07 Fixed makefile generation so 32bit AIX will use >256MB in src/helpers. Updated vzt2vcd and lxt2vcd so it handles the zero index of bitblasted vectors (from ncsim). Updated vzt reader so it can re-coalesce bitblasted vectors provided the dumped bits are adjacent/in order. Minor bugfixes to vztminer and lxt2miner with respect to dumpon/dumpoff (don't emit $dumpon/$dumpoff strings as that code was leftover from the vzt2vcd). Updated manpages for vzt2vcd, lxt2vcd, and vztminer. On concatenated vector loads ('#'/':' in savefile), attempts to do a load of a monolithic vector on fail. This is somewhat related to the re-coalesce vectors feature above. Implemented reverse of this for monolithic vectors into the '#' bitstrand variants. 3.0.25 10apr07 System Verilog with MTI fix for VCD declarations of form $var reg 64 >w #implicit-var###VarElem:ram_di[0.0] [63:0] $end ...debussy implicitly escapes the varname during loading so gtkwave does it too now for all VCD loaders. More System Verilog with MTI fixes: VCD (parameter) vars of length zero are representative of reals with MTI: they don't use real_parameter like Riviera does. Updated vcd_saver.c to handle saving these implicit-var facilities correctly. Likewise updated lxt-write.c, lxt2_write.c, and vzt_write.c to handle correct bracket stripping for the [0.0] semantics. Modified dynamic resize routine so large escaped names don't cause issues with the signal window crowding out the wave window. 3.0.26 18apr07 Fixed various compiler warnings discovered from looking at Fedora Core compile logs and later compiling against Centos/RHEL5. Commented out GTK_CAN_FOCUS for scollbars in wavewindow as it was causing rendering problems with newer versions of GTK. 3.0.27 27apr07 Renamed vertex to vermin to avoid name clashes with existing 3D "vertex" package on debian systems. Reverted back to using Open Office 2 Beta rather than Open Office 2 as it was causing .odt docs corruption. 3.0.28 30apr07 Changed anonymous union in struct Node as it is a gcc extension. Fixed some vcd parser memory leaks found by Valgrind. Moved errno check in vcd parser as it seems that the GTK event loop called in splash_sync() calls it on gnome 2.18 for some reason (reported by Gentoo gtkwave package maintainer). 3.0.29 27may07 Added viewer support for arrays (currently AE2 only). Integrated (standard) ./configure scheme thanks to Dan McMahill Added strdup_2 to debug.c for memory tracking (found stray strdup() instances in ghw.c). 3.0.30 24jul07 Removed variable declaration in menu.h that tcc complained about (should have been an extern). Updated configure.ac to use AC_SYS_LARGEFILE for > 2GB file compatibility with older linux systems. (This was accidentally left out in 3.0.29.) Added ignore_savefile_pos and ignore_savefile_size rc variables. (Requested by Edward Ash.) Added ability to specify trace background color in filter processes by prefixing the return string with ?color? as in "?CadetBlue?xor r0,r0,r0". The colors used must already be specified in the rgb.c file. Removed check for c++ compiler presence in the autoconf. Fixed LIBBZ_CFLAGS in .am files that really should be LIBBZ2_CFLAGS. 3.1.0 25aug07 Moved to a global context variable management scheme for future code expansion. Reload waveform function added which uses context management. Update user manual to include references to reload capability. 3.1.1 20sep07 Fixed crash in hierarchy search reload. (Wrong pointer type introduced from code cleanup.) Adding start of tabbed browsing support. Put in window select focus switching between tabs (e.g., on search windows). Added locking in main iteration loop to detect unexpected context switches and fix/report them (wrong operation if it occurs). 3.1.2 24dec07 Compiler warning cleanups from Sun compile logs. Added named parameter support to vermin parser. Added check for gperf back into configure.ac. Added vlist_spill rc variable to control new feature of spilling vlists to a tempfile on disk. Fixed vcd loader status bar on files > 2GB. Removed non-growable vlists and also finalize aliases in order to be compatible with spill. Changed vlist allocation scheme to allocate only half as much per-block, then the rest when the half-way point is reached. This reduces memory wastage to an average of 12.5% rather than 25% on uncompressed blocks. Added code to pre-process data in vlists through an LZ-based compressor. The can cut down on memory usage ever further. This can be enabled with the vlist_prepack rc variable. Added --giga option to turn on vlist_spill and vlist_prepack from the command line. 3.1.3 13jan08 Added dynamic keypress detection in the Pattern Search Requester so users do not need to press enter for search strings. Likewise, added the rc variable sst_dynamic_filter to enable the same type behavior for the signal name filter in the GTK2 signal search tree. Fixed bug where filtered signal names did not reappear on reload. Updated user manual as necessary. Added "edge" left/right buttons for handy single signal edge detection due to user requests. Fixed long-standing backward edge seek bug in pattern search. (It would miss the preceeding edge if the marker isn't already on one.) Added use_standard_clicking rc variable in order to enable "normal GTK" shift/click semantics in the signal window. Collapse/uncollapse is now shift-ctrl when use_standard_clicking is active. Added prelim dnd for use_standard_clicking mode. use_standard_clicking disabled in GTK-1.2 as there are dnd issues. Recalculate signal width on reload as sometimes it was missed. Added input focus capability to signalwindow. Moving menu options to standard GTK accelerator keys. Added Ctrl-A/Shift-Ctrl-A handler to the treeview so it acts like the signal window. Added left/right scrolling hotkeys in signal window. Added use_toolbutton_interface environment variable which enables new user interface at the top of screen. More modifications to handle globals swapping in multi-tab mode. Update configure.ac to handle library order problem with cygwin in rtlbrowse. Added scrollwheel support in signal window when focused and standard clicking is active. Added "Use Color" and "Use Black and White" (for screendumps) View menu options from user requests. Fixed help window so it is not editable. Also do an implicit click-to-front for window managers that automatically move windows to front when their insides (not decorations) are clicked on. 3.1.4 30jan08 Added fix for how dnd gets killed after reload on new versions of GTK (e.g., 2.10.14). Added dirty_kick in MaxSignalLength that forces usize if width is dirty. For interpolated analog traces, fixed interpolation at end of line so it doesn't cause endpoint to go offscreen. Experimenting with track-and-hold fixing. Integrated spice3f5 poly interpolation routines, but are currently unused. Now allow both interpolated+step simultaneously for analog. Integrating signal window popup menu code. Fixed rendering bugs in coalesced vectors displayed as analog. Added resizing options that are windowed to either the screen or across all trace data. Added enter=OK as a default file chooser response. Added DND and standard clicking to GTK1 compiles. 3.1.5 14feb08 Fixed bug in rtlbrowse that causes lxt2 dumps not to be value annotated. (signal match worked for bitblasted nets only) Updated rtlbrowse so that it can update dynamically with the marker position. Added anti-aliased font rendering code. Added use_pango_fonts rc variable. Updated edge buttons so they can handle multiply selected signals. Logfile(s) now update on waveform reload. MinGW compile fixes. MinGW crash on reload fixed. 3.1.6 27feb08 Added additional #ifdefs that disable Pango on GTK versions less than 2.8.0. Added support for optional sideband .aetinfo files when using .aet files. Update interface to rtlbrowse to translate time value back to original aet ones. Improved x vs X (z vs Z, etc) handling at signal boundaries. Changed color scheme where red marks X data similar to how it marks U for VHDL. Fixed longstanding bug in linear lxts that only occurs if integers are present in the lxt dump (length is failed to be promoted to 32 during re-chaining). Fixed shift-clicking when use_standard_clicking is active such that shift-clicks past the last trace when the signalwindow isn't fully populated count as a shift-click on the last trace. 3.1.7 23mar08 Updated file.c to remove potential file chooser crash in the case of a missing save file at the command line followed by "write save file as". Fixed problem in black and white mode where process filter could possible cause colors to be displayed when ?color? value escaping is used. Fixed problem where primary marker was listed as 0 sec on init instead of -- if not set initially from a save file. 3.1.8 06apr08 Added Range Fill option in the data format menu so that vectors like address[31:2] will display as a human expects to read them. Fill in can be zeros or ones. Added trace flags display at right hand side of signal name in mouseover popup window. Added more visual feedback in signal D&D window in order for users to determine more easily where a drop will insert. Reduced visual noise on D&D by not updating screen after a cut if a paste also occurs. Fixed problem where primary marker was filtered through time_trunc() on initialization. Removed other time_trunc() calls causing similar problems as necessary. 3.1.9 20apr08 Added missing init_filetrans_data() to reload function. Updated manfiles to get them in line with Debian lintian. 3.1.10 14may08 Added missing adjustment of t->shift in mouseover.c in order to allow the mouseover on shifted traces to display properly. Fixed problem with edgebutton going back two edges on a combined vector. (Cut and paste typo from strace.c.) Added support for DND from regex search window to the signal/waveareas. 3.1.11 18jun08 Compile fix for tla2vcd in MinGW. Added #ifdef for HAVE_BZERO for MinGW. Compiler warning fixes. Added time = -1 endcaps in LXT2+VZT+AET loaders. 3.1.12 14jul08 Compiler warning fixes. Fixed crash in vcd recoder for b vs 01xz mixups in malformed VCD files. Fixed abort on VCD load for malformed size vs [msi:lsi] syntax. NC does this on arrays of wires. Fix to vlist reader with --giga enabled in order to handle reads which go off the end of the file. (Possible due to how only the amount used in a block is actually written to the file in order to save space, so the vlist blocks can be overlapping yet usable.) 3.1.13 20aug08 Adding compressed hierarchy handling in order to reduce memory usage on large bitblasted models. This is currently only enabled for the VCD recoder, LXT, LXT2, and VZT loaders. Fixed some buffer overflows in vectorization code (and when vectorization is enabled) in vzt_read.c. Modification to autoconf handling for rpc.h. Fix for DnD to directly under an expanded comment trace. Make step_increment equal to 1/10 page_increment for the horizontal scroller in the wavewindow. Added sticky click semantics for clicks in signal window. To do this in the treesearch_gtk2 file will require some additional future work with view_selection_func() and/or signal handling and trapping. 3.2.0 16feb09 Fix for strings ('s' type) in recoder. Added timestart command to savefiles which indicates what the leftmost position should be on reload. Added support for as/zs small timescales as well as 0.1/0.01/0.001 multipliers which simvision can emit. Adding signal name DnD support from external apps. Force open tree nodes on initial .sav file read. Yet more new warning (-Wall) cleanups. Fixed ExtractNodeSingleBit for vectors which do not have a zero in either the msb or lsb (e.g., [1:9]). Added support for dragging files into the viewer (i.e., dumpfile, savefile, stems file) Added DnD of signal names from RTLBrowse source code windows directly into gtkwave. GTK1 compiler compatibility fixes. Improved search performance from rtlbrowse initiated DnD searches. Fixed wave_locale.h for MinGW. Fixed longstanding bug with blackout regions rendering. Integrating embedded Tcl interpreter. Fixed bug with unformat time when base time is in seconds. Added tcl example in examples/ directory. Updated -f argument file handling in vermin. Updated tcl_helper code so that signalwindow drags of bit- blasted vectors are properly re-coalesced for client code for the drag. Updated task definition in vermin so that identifiers with dots in them can be used as task enable names. Fixed problem in vermin preprocessor where defines in 0x0d0a terminated lines would insert the carriage return into the sourcecode. Added synthesis pragmas which mirror synopsys ones to vermin. Used gtk_window_set_default_size instead of gtk_widget_set_usize in rtlbrowse in order to allow window to shrink appropriately. Made size_tag values smaller in logfile.c in gtkwave/rtlbrowse. Allow dragging from rtlbrowse window without needing to high- light signals first. This allows single signal drags. GCC-4.1.3 with -O3 flag fix for x86_64 on xchgb instruction assembler intrinsic. Use gtk_window_set_transient_for() on simplereq windows. Starting to update environment for rtlbrowse into a single integrated window. Adjust xthickness/ythickness in toolbars to make images take up less space. Preliminary support for text searching in rtlbrowse. Added rtlbrowse case (in)sensitive searching both directions. Fix re-entrancy on file names for file.c file requester in gtkwave. Add --with-tcl to configure script via tcl.m4 macro. Cut down on visual noise during reload. Added fix using TCL_INCLUDE_SPEC to get to compile under Ubuntu. Fixed lost num_cpus variable that wasn't passing through reload. Added Cut/Copy/Paste functionality that allows multiple pastes rather than destroying the cut buffer on paste. Cut buffer contents will survive after a reload operation. Removed translate filter process from mingw32 menu as it is disabled in the compile by #ifdef'ing in empty functions. Updated shmidcat so it restarts properly when VCD is being looked at while sim is running and gtkwave gets ahead of the generated VCD. Fix crash on invalid node for force tree open during load. Added Partial VCD Dynamic Zoom and related zoom_dynamic rc variables. Added prelim support for export to TimingAnalyzer file format. Added mouseover support in signal window which shows full facility name. Added dynamic update on strings for marker values which keeps user from having to press enter explicitly for each one. Now allow support for named markers using optional user names rather than just 'A'-'Z' labels. Added countdown timer to remove dnd cursor if it is onscreen longer than 5 seconds. Added support for setting optional user names for named markers via Tcl scripts. Added prelim auto-scrolling code for trace adds/copies. Added support for Tcl repscripts. Removed warnings found when compiling with -Wshadow. Fix for stack crash in treesort() on dumpfiles with an extremely large number of signals (e.g., 5 million). Compile fixes for rtlbrowse in older versions of GTK2. Remove stray tempfiles created by --giga writer under MinGW. Removed stray file descriptor from lxt on reload. Fixed repeat error problem in lxt.c introduced by -Wshadow fix. Added prelim version of scale_to_time_dimension rc variable and appropriate menu options. Beginning to update user manual to reflect new 3.2 features. Added Partial VCD Dynamic Zoom To End and related zoom_dynamic_end rc variables. More mingw compile fixes: the whole tarball compiles now. Use old file chooser (for now) in mingw as the new one seems not to be re-sizeable. Added "copy traces" to toolbar in gtkwave as copy function now exists. Added check for "server" in env var CYGWIN before printing warning about using shared memory. Added vpi client lxt/lxt2/vzt writers in contrib/vpi, but these currently are not built. Compatibility fix for gcc 3.x. Added extload capability which grabs data via popen(). This allows adding loaders for unsupported formats via data mining. Added Tcl command setBaselineMarker. Extload hardening on reload. Added extload filetype to DnD. Fixed window close when tabs active so it would update the titlebar, times, etc., to the current tab. 3.2.1 09apr09 Add more information for users if gtk can't initialize on MacOS. Added possibility for vlist.c to write out the spill file in a machine independent fashion. Added --fastload option to gtkwave. Fixed autoconf so Tcl works in cygwin. Updated cygwin "Bad system call" warning text to include more possible fixes. Fixed warning message in strace.c ("Named Marker xx not in use") which spanned multiple lines because of multiple status_text() calls. Fixed STATUS_ACCESS_VIOLATION in cygwin for both vztminer and lxt2miner and added the --comprehensive option in each. Also added behavior that no search string specified matches all value changes across all nets. Updated documentation description for collapsible groups to indicate that shift-control is required, not control (as previously). Adjusted brightnesses for mdgray and dkgray so collapsed traces are visible on some monitors. Fixed dkgray->mdgray for "Time" background as brightnesses have changes. Made AN_NORMAL/AN_REVERSE const declarations also static in order to avoid unnecessary stack pushing. Fixing reloader crashes in vcd_build_symbols(). Adding experimental support for bringing up gtkwave without a trace like "every other" GUI app. This is currently disabled pending more testing. Sort filename lists from DnD in order to allow both a dumpfile and a savefile to be dragged into the viewer and processed in a logical order (i.e., the dumpfile before the save file.) Added disable_empty_gui rc file variable. Working with ergonomic features of empty gui handling. Fixed & to && in if() comparison in lxt_write.c Added support for PDF output via ps2pdf. Added support in VZT file format for LZMA compression. Fixed calling to install_keypress_handler() as it only needs to be done once. Add menu blackouts on empty gui. 3.2.2 02aug09 Changed some instances of exit() in main.c to vcd_exit() in order to keep failed loads in tabs from killing the whole session. Update VCD ID generation in VCD writers to use XL-style identifier sequencing. Fix MinGW printf format strings for helper apps. Ported shmidcat and partial VCD loader function to MinGW. Added twinwave support in MinGW. This currently has some problems with D&D as well as window decorations being present due to various system incompatibilities. Added rtlbrowse support in MinGW. Fixed rtlbrowse on reload, now allows to respawn. Fixed rtlbrowse in cygwin as kill() does not work the same as posix kill. Added clearing of t->minmax_valid in dataformat() in case sign bit changes for analog vectors when TR_ANALOG_FULLSCALE is in use. This allows dynamically changing from/to "signed decimal" and other modes and removes any y-scale artifacts from having stale minmax data. For rtlbrowse kill, step through all contexts in atexit() handler. More exit fixes for rtlbrowse killing. Warning fixes for printf format strings in lxt2/vzt/ghw. Updated VCD parser to handle names like "a[1] [3:0]". Added VCDNAM_ESCAPE cases in lxt, lxt2, and vzt loaders. Updated VCD writers so they put spaces before bracketed signal ranges. Added extra message for help requester if file type is MISSING_FILE in order to direct users what to do. Fixed segfault caused by improper search/replace and malloc length in renderopt.c for ps2pdf. Beginning to integrate FST file format support. Optimize rtlbrowse somewhat by not redoing fac finding every time the cursor moves. Beginning to integrate FST into rtlbrowse. Added vcd2fst and fst2vcd helper utils. Added option to FST to allow monolithic post-compress for much smaller file sizes. Documentation updates. Added capability in GHW reader for negative indices on bitstrands. Added variable type support to VCD + impulse arrows for depicting events on VCD (other formats will migrate in the future). Added vartype info (if avail in trace, now FST+VCD). Added module type info (if avail, now FST+VCD+GHW only) by decorating the hierarchy tree info appropriately. Changed build_tree_from_name() to perform move to front for hier names in order to work better with decorated trees. Add EVCD support to vcd2fst, fst2vcd, and FST loader. Fix longstanding bug in vcd parsers where evcd did not parse correctly if standard VCD IDs were used. Fixed "f" value in EVCD files so it converts to z, not x. Convert capitalization usage on hex values to match that of verilog. (i.e., x = all bits are x, X means some but not all bits are x.) Change magic number 3 to AN_1 in vtype2(). This was skipped by an earlier sourcecode conversion. Change file requester handling so old names are copied to the new tab and the directory used on an unspecified entry is derived from the loaded file name directory. Added type information to mouseover in signal window. Added --enable-fatlines ./configure flag which enables gtkwave to render lines in "Fisher Price" (aka Simvision) double- width style. Added evcd2vcd to the distribution. 3.2.3 03sep09 Set iconify icon for gtkwave with gtk_window_set_icon(). Ensure -d flag survives across reloads/new tab. Added LIBZ_CFLAGS to helpers/fst AM_CFLAGS for MinGW. Added gtk_window_set_resizable for pWindowMain in file.c as some distros need this. Changed some strace.c globals to "signed char" to remove warnings under AIX compiles. AIX ./configure fixes. Added malform_eof_fix() to recoder and regular VCD loader. Fix to attempt_vecmatch_2 when no suffix encountered. 3.3.0 25dec09 Modified unformat_time() so it can also handle floating- point exponential format. Integration of a large amount of group handling sourcecode from Don Baltus / Bluespec, Inc. Re-integrated original Simpod repscript handling. Reworked force open tree node and moved to tcl_support_commands.c. Renamed liblzma to libgwlzma for now: liblzma is present on some systems and causing conflicts. Fix for tk library issue on Cygwin. (Use TK_BUILD_LIB_SPEC if TK_LIB_SPEC is a null string.) Added --enable-stubify ./configure option to make Tcl/Tk library usage be completely dynamic. Generate anonymous name for groups to prevent crashes when group name is unspecified. Added EnsureGroupsMatch() on various parsewavline() code sections to enforce legitimate group formations. Applied gtk+-1.2 compile fixes as compile was getting out of sync as it hadn't been tested recently. Allow more events in GuiDoEvent() to prevent hangs. Made --wish and --vcd mutually exclusive as they both require input on stdin. Enabled gc caching on linux to help with rendering extremely dense traces. Removed memcpy() ops in baseconvert.c and changed them into pointer copies as the copied string is never modified. Resequenced enum WV_MenuItems in menu.h which lost ordering from Bluespec menu item adds. Added gray code conversion ops. Added FST detection to gtkwave::getDumpType. Added missing context change variables in context_swapper(). Added gtkwave::setTabActive and gtkwave::getNumTabs MinGW tcl compile fixes. Cygwin fix for optimized vcd -o option. Disabled reload on optimized vcd from stdin. Removed --wish when building under MinGW and when specifying --enable-stubify for configure (for now, the fail is with TkMainEx). Removed tempfile generation for Tcl script execution; now use alloca based scheme. Also removed old-style "script" file support as it is obsolete: all scripts are Tcl scripts now. Integrated user-provided rework of rgb.c. Removed local lzma library and now use system xz if available. Old VZT files using -z 2 are no longer readable but can be converted using vzt2vcd from an old version of gtkwave. Various warnings fixes. 3.3.1 03jan10 Fixed Makefile.am files to allow builds into different directories than the current one. GHW crash fixes. In fstapi.c now use tmpfile() to generate tempfiles in order to speed up operation on networked filesystems. Fixed problem in fstapi.c with conflict between off_t and unsigned longs on some 32-bit systems which cause a "tsec uncompress" failure on reads. Fixed missing dependencies in various Makefile.am files. 3.3.2 05jan10 Emergency fix for ghw.c as it was missing a close comment causing problems with iterative generate. 3.3.3 18feb10 Fix for Pattern Search where end marker time was not used for dropping down a marker: for clock counts this would mean that the clock count was off by one. Added locking/unlocking of named markers against the primary marker with 1/2/0 keys. Fixed broken "make distclean". Added patch for move to time against named markers. Added a secondary pattern search function. Added sanity checking on WAVE_NUM_STRACE_WINDOWS. Added fix for broken bsearch_facs() when characters like "$" are in a facname and it matches a hierarchy boundary. Removed tla2vcd from distribution because of incompatibility with some TLA700 traces. Removed obsolete helper executables. Activated preliminary line clipping for analog rendering as line clipping in GTK does not always work for extreme value ranges. Hang in gtkwave on backtracking time fix (usually caused by truncated files). Replaced Tcl_GetStringResult() in tcl_np.c with Tcl_GetVar() on Tk init fail. Added AC_CHECK_LIB([dl], [dlopen]) (Fedora requirement). Added --disable-xz (requested by Gentoo). Added extern "C" { } bookends to headers for C++. 3.3.4 07mar10 Change slope calculation "m" in clipping.c to all doubles in order to avoid integer overflow errors. Change main resync loop name from gtkwave_gtk_main_iteration to gtkwave_main_iteration. (Start of separation of GUI code from functional code.) More fixes to analog clipping: yt0/yt1 were reversed, also added analog_redraw_skip_count env var. Added support for "realtime" VCD variable. GTK1 compile compatibility fixes for pattern trace. Removed "Reduce Single Bit Vectors" menu option. Added defensive re-link of t_prev on prepend and cut ops. Fix for analog stretch traces when analog trace was expanded and then collapsed. Fix to LZMA_write_compress to detect xz compression failures. 3.3.5 19mar10 Fix for usage of deallocated next pointer in the force_open_tree_nodes loop (spotted using an alternate allocator). Added optional preliminary Judy array support. Fixed compiler warnings. Fixed toggle max hier so it toggles back and forth between the most previously set hierarchy depth. Added ".lxt2" to list of suffixes allowed by gtkwave. Remove name field from struct fac. Added missing hierarchy boundary sort for FST in order to allow compatibility with compressed names (-C flag). Removed resolve_lxt_alias_to field from struct fac. Removed lxt-only lastchange field from struct fac. Removed unused h field in struct symbol. Removed nextinaet field if unused, recoded to symchain when used. Fixed && used in logical operation for generating ExtNode. Removed ExtNode, made inline with Node. Deallocate symbol hash table after no longer needed. Only allocate hash when necessary. Added marker vs maxtime marker conflict check in kick_partial_vcd() to ensure signal window values reflect data value rather than x when maxtime scrolls over the marker time and makes the marker visible. More Judy array adds for VCD. Removed sym->selected member and replaced with 1-bit Judy array if enabled. 3.3.6 01may10 Added RealToBits menu options for displaying real numbers as binary values. Added missing break statements to terminate cases in bits2vector(). Fixed cut and paste error on FILE_FILTER_MAX versus PROC_FILTER_MAX. Reduced FILE_FILTER_MAX from 1024 down to 128. Added preliminary transaction filter support. Added transaction parser in examples/ directory. Updated time warp handling. Updated print routine to use populateBuffer(). Added raise to front when filename selected in filter dialogs as this helps with some window managers. Remove color for translated/transaction traces in black and white mode. Copy gc_grid_wavewindow_c_1 from gccache on reload as this was accidentally overwritten with gc_grid2_wavewindow_c_1 without adding back gc_grid_wavewindow_c_1. Added fstWriterSetTimescaleFromString() to fstapi.c which allows usage of strings such as "1ns" for the timescale. Incorporated FST writer optimizations. Incorporated some fixes suggested by cppcheck. 3.3.7 03jun10 Made enable_fast_exit rc variable default to yes. Compiler warning fix in lxt_write.c/fstapi.c for Open Solaris. Added fstWriterGetDumpSizeLimitReached() to fstapi.c. Fixes to Tcl string handling. Applied user-supplied fixes for null pointer crashes in rtlbrowse. Moved gtk_grab_add() after gtk_widget_show() in order to work with newer versions of GTK. Use PRId64/PRId32 in lxt2_read.h and vzt_read.h to remove printf format warnings. Fixed "format not a string literal and no format arguments" warnings. Added missing HAVE_INTTYPES_H in compile note for transaction.c. Disable autocoalesce if Icarus Verilog is detected. Added units forward scan in logfile.c. 3.3.8 25jun10 Added failure check on tempfile create in fstReaderInit(). Added strace_repeat_count and appropriate menu option. Removed the "/File/Quit/Don't Quit" menu item if fast exit is enabled. Added dnd of signals from gtkwave into rtlbrowse: now the appropriate verilog code sections automatically are imported. More warnings cleanups. 3.3.9 06jul10 Changed accelerator for Quit to conform to Gnome standard menus guidelines. Update local libz and libbz2 to current versions. Moved version string out to version.h to keep from having the CVS data updating in currenttime.h. Fix crash that can occur in RemoveTrace. Header file cleanups. Fixed actual result of crash in RemoveTrace: defensive re-linking in PasteBuffer didn't always relink the back pointers properly. 3.3.10 16jul10 Fix in vermin Makefile.am for parallel build failures involving shred.c depending on tokens.h. Added missing dependencies in various Makefile.am files. Fix for free to non-malloc'd address problem in main.c and menu.c due to context changing in Tcl scripts when gtkwave::/File/Open_New_Tab is invoked. Updated vcd2fst so it is compatible with VerilatedVcd writer. Read hierarchy reconstruction hardening for fstapi.c. Check return code for hierarchy generation in fst2vcd.c. Updated example to reflect Quit name change. Updated repscript_timer so it prints stack trace. Use setvbuf (as with MinGW) for fstapi.c to fix for OS X. 3.3.11 17aug10 Added tcl functions gtkwave::installFileFilter, gtkwave::installProcFilter, gtkwave::installTransFilter, gtkwave::setCurrentTranslateFile, gtkwave::setCurrentTranslateProc, gtkwave::setCurrentTranslateTransProc, and gtkwave::setCurrentTranslateEnums to give Tcl access to these features. Add write combining in fstWriterEmitValueChange to speed up execution on Cygwin. Nested `ifdef fix for Vermin. Fix for free to non-malloc'd address problem in repscripts due to context changing in Tcl scripts when reload occurs. Added gtkwavetcl_setvar() for starting to build a framework to support Tcl variable change callbacks. This can be used to closely monitor how a user manipulates the gtkwave GUI. Fix for 0 millisecond Tcl timer causing 100% CPU usage. Added CVS versus ModelSim compatibility fixes for Bluespec savefiles. Fix for atoi_64 when value is zero followed by a legitimate nonzero value after some garbage non-numerics. 3.3.12 29aug10 Compile fix for --disable-tcl or systems which do not have Tcl installed. Added support for process filters in MinGW. Added support for transaction filters in MinGW. Added support for Open New Window to MinGW. 3.3.13 23sep10 Reduce memory footprint of VectorEnt on 32-bit architecture by struct reordering. Added warnings for options that are non-functional for some configurations. (They are not disabled in order to allow compatibility across systems.) Fixed dangling fnam malloc in fst.c. Reduced temporary memory usage during file init for lxt2, vzt, and fst files by using F_NAME_MODULUS wrap on f_name. Sparse vs non-sparse array crash fix for ae2 loader. Suppress decorated treebuild for fst when compressed facs are being used: this was causing duplicate tree entries. Fixed renderhash problems in print.c caused by disparity in eqns used in wavewindow vs print.c (need realx, not just x). Upgrade local libbz2 to 1.0.6 for uncompress security fix. Added experimental dynamic SST building code which speeds up initialization time for trees with extremely large number of scopes. 3.3.14 26oct10 Fixed force_open_tree_node() for dynamic SST trees when unbuilt nodes are encountered during traversal. Allow VCD files where start = end time. Compiler warning fixes. Added preliminary RPC mechanism to gtkwave. Added --disable-inline-asm ./configure flag. Added initial_signal_window_width rc var. 3.3.15 10nov10 Added check in fstapi.c for corner case where fstWriterEmitSectionHeader could make a file unusable if.hier is not present. Added more checks in fstapi reader to prevent crashes on malformed files. Add config.h #include to the fstapi.c code. Add detection in vcd2fst for Verilog XL-style VCD identifiers to speed up reading VCD files from those simulators. Speedup in fst writer by ensuring checkpoint is not written to for every fstWriterEmitValueChange call. The --optimize flag now uses fst instead of lxt2 as its default file format use vcd2lxt2 directly if old behavior (e.g., converting flat signal names to hierarchies) is desired. 3.3.16 24nov10 Remove unused JError variables and replace with PJE0 macro. Added experimental dynamic alias detection in fst writer if Judy arrays are detected. (Judy not required for reading.) Added Jenkins hash routine to enable dynamic alias detection for when Judy not available. 3.3.17 28nov10 Added sanity check in dynamic alias reconstruct routine in FST reader and also fixed bug where alias reconstruction in current blocks doesn't overwrite previous, old block data. 3.3.18 24dec10 Added extra allocation in fstWriterEmitValueChange in case users modify the FST_BREAK_ADD_SIZE to a very small value. Fixed in lxt.c that --disable-inline-asm did not propagate into its compile. Fixed x86_64 assembler =q vs =Q problem in lxt.c. Preliminary support for variable length records in FST files. Added fstUtilityBinToEsc and fstUtilityEscToBin for conversion of binary data to C-style strings. Now allow escaped strings in VCD files to encode a richer set of data for non-standard "s" VCD records. To comply with fst2vcd, vcd readers now handle "string" variable type keyword. Scaled back multipler from 95 to 94 for VCD ID processing as !..~ is a distance of 94. Add detection for Verilog XL-style VCD identifiers in all vcd loaders in gtkwave in order to aid in indexing. Added --enable-struct-pack configure flag. More warnings fixes. Fix mif_draw_string so it does not emit escaped character codes. Added gtkwave_server to distro but it is not currently in automake as it is not ready for use. 3.3.19 03feb11 Added more NULL pointer checking to vcd2fst to prevent crashes on malformed files. Rewrote support for compressed signal handling. Currently this is for FST only. Modified shmidcat to exit on EOF. Added sys_fst.c VPI source for NC Verilog and XL. Added component typename dumping into sys_fst.c so that NC can dump component names. Added component type names in gtk2 tree. Currently the FST loader is the only one that will populate this field. For 64-bit architectures, doubles are stored in HistEnt fields directly to conserve on memory usage. Fixed top/bottom pane resizing bug after reload in SST window. Fixed crashes in hierarchy search widget for GHW where standard, textio, std_logic_1164, etc. were selectable. Fixed reload scroll position for bottom TreeView in SST window. 3.3.20 21feb11 Fixed uninitialized mat variable in compress_facility(). Added --slider-zoom option to gtkwave to enable experimental horizontal slider zoom feature (GTK2). Fix vcd2fst so it can handle 0 length VCD event variables in their declarations (MTI). 3.3.21 28apr11 Fixed crash in LXT2 reader on malformed files. Fixed reload crash when -o flag used on non-VCD files. 3.3.22 03jun11 Optimize tree build so it can handle large amounts of component instantiations (netlists) without undue slowdown. Added gcc -Wformat and -Wformat-security related fixes. Update hier_decompress_flagged so it can also decompress into its own static buffer in order to speed up temporary usage cases. Fix FST reader iterator to work better with --begin flag. Fixed missing facname decompression for FST files on single trace import (backup case that should never happen). Added support for user-specified timescale ruler using the ruler_origin and ruler_step rc variables. Added "/View/Define Time Ruler Marks" menu option. Removed indirect file support as is unneeded for 64-bit. Removed obsolete CVS modification log comments. Handle vcd saver case of dot at end of signal name. 3.3.23 01jul11 Fixed ItemFactory callbacks as their argument lists did not reflect the correct callback argument type/order for callback_type=1. This is a longstanding hidden bug. (Would prevent pattern search from working on 64-bit big-endian architectures.) Fixed broken "replace" signal option. 3.3.24 03aug11 Improve the searching for the TCL libraries (when using stubs). Fixed bug where Tcl_GetString was substituted with brace removal preprocessing when unnecessary (would break addSignalsFromList, etc.) 3.3.25 15sep11 Replaced calloc_2 with histent_calloc in loaders where applicable. Updated tcl.m4 so /usr/lib64 can be automatically used. Fixed TR_ANALOG_STEP line clipping problem. Checked in fix for modelsim signal bit nets that are defined as [0] as some tools emit signals without the [0] and it causes savefile compatibility problems. Add visible filter pattern in fileselbox() as well as selectable "*" pattern overrides. Added custom filters to GtkFileChooser dialogue. Fix in lxt2_read.c/.h for negative msb/lsb indices. Fix in vzt_read.c/.h for negative msb/lsb indices. 3.3.26 25sep11 Mac OSX fixes: removed restrictions for twinwave on OSX, OSX compile fixes for Tcl detection, printf warning fixes (xcode gcc uses stricter warnings). More generic warning fixes from recent feature adds. 3.3.27 20oct11 Fixes of suspicious NULL pointer warnings from scan-build. Fixed inline function linker errors when using Clang. Optimization of more [1] cases found in analyzer.h when -DWAVE_USE_STRUCT_PACKING is active. In process_url_list() use g_malloc/g_free as context can or will change when files are loaded. Added fix for DnD crash when Quartz is the GDK back-end on Mac OSX. Enable fix with --enable-quartz in configure. Fixed fstWriterFlushContext() such that invocations outside the fstapi are synced with time changes. Modify main window size for twinwave on Quartz: GtkPlug window does not fit into GtkSocket as with X11. 3.3.28 11nov11 Use larger more readable Apple fonts for Quartz. Added support for colorful traces using the /Edit/Color Format/... menu options. Fixed rendertimes bug where times did not always display when grid is turned off. Added keep_xz_colors gtkwaverc variable. 3.3.29 31dec11 << short descriptions >> Added OSX integration when compiled against gtk-osx. Added mime types and icons for file types and desktop menus. Changed .sav (deprecated but not removed) to .gtkw, with .gtkw itself being able to bring up the original dumpfile. Numerous bug fixes. Preliminary GConf support supporting session ID-based restore. Preliminary GConf support to emulate OSX "open" functionality such that dumpfiles/savefiles can be targeted to an open gtkwave viewer / session ID. << long descriptions >> Fixed size of declaration of render_mutex_renderopt_c_1 as it was one element too short. Added transition code for shifting away from using GtkItemFactoryEntry (also will help with OSX menubar integration which expects menu shells). Added support for native Quartz menu bars. Removed --enable-quartz as it is auto detected now if PKG_CHECK_MODULES(GTK_MAC, gtk-mac-integration) is true and GDK is compiled against Quartz. Fixed pointer crashes on NULL returned on gtk_entry_get_text() on OSX/Quartz. Recommended usage for Quartz is now jhbuild with gtk-mac-integration, not MacPorts. Added mac bundle info in contrib/bundle_for_osx. Added gtkwave_argv0_cached as Open New Window does not work if "gtkwave" is not in path or is something like gtkwave-bin as in an OSX bundle. Detect context swapping in file chooser from DnD to prevent possible crashes. Block DnD while file chooser is active. Migrate OSX to OSX key accelerators. Fix for tcl code opening the root node. Fix time warp cmd->control mapping for OSX. Fix for time warped traces not rendering properly when x-coordinate overdraw is detected. Added WAVE_ALLOW_QUARTZ_FLUSH_WORKAROUND temporarily which needs to be set at compile time which gates redraw. Add GLOBALS->force_hide_show to force redraws in OSX. Added osx_timer() which controls forced redraw. Abort GHW read when nbr_el<0: indicates malformed file from variable/signal construct of form (7 to 0) rather than downto. Crash fix for non-string len zero facilities in vcd2fst. Fixed overflow in draw_hptr_trace_vector_analog(). Added rtlbrowse and vcd2fst binary path finding code to OSX. Changed ps2pdf to pstopdf on Mac. Fixed broken wave_script_args. Reverted to 3.3.26 code in menu_func() as the renderbox requester did not work from TCL anymore. Catch NSApplicationOpenFile so files can be opened from Finder. Added --chdir command line option to support open for OSX so that gtkwave can be run at the command line directly from its installed gtkwave.app. Fix window resizing / repositioning to work in OSX: block once viewer is on second tab, however. Added sst_width, sst_vpaned_height, sst_expanded, and signals_width tags into save file to allow pane size and expander settings to be saved to the save file. Add ignore_savefile_pane_pos .gtkwaverc variable. Added dumpfile tag to save files. OSX Finder uses these to find the original dumpfile. This can be done from the command line also by specifying --save but not specifying a dump file. Added .gtkw as a new save file extension. When either .sav or .gtkw is encountered, the rest of a tab's session adaptively follows in expecting it as the save file suffix. Added [savefile] tag to save files. The intended use is to allow reconstruction of relative paths between dump and save file. Fixed --autosavename to use .gtkw as a suffix rather than the .sav suffix. Reworked wave_info and wave_alert icons. wave_info now matches gtkwave.icns. Renamed .sav examples to .gtkw. Added relative path comparisons for --save so when dumpfiles and savefiles move in tandem, a successful load can be attempted. Added [dumpfile_mtime] and [dumpfile_size] tags to save file. Can now specify just an augmented save file at the command line and gtkwave will load both the dump file and the save file: this makes launching from desktops easier on Linux. Added mime types, desktops, and icons in share/ for gnome. Added percentage progress during load for most file types in window title bar when splash screen not active. Preliminary add of interfacing with GConf via the /com.geda.gtkwave directory for keys in GConf. Memory overrun fix to symbol.c for Bluespec add from 3.3.11. Added --restore command line option to gtkwave. 3.3.30 17jan12 Updated ./configure to add --disable-mime-update flag. Fix --optimize for --restore. Add [optimize_vcd] savefile tag. Disable analog during mutually incompatible mode selection (binary, filters, etc). Added F/P/T flags to mouseover for the filters. Fix problem where ungrab doesn't occur if button pressed + simultaneous reload accelerator key occurs. Fix combine direction in transaction filter to down. Fix vector analog render/print routine to use skipcnt. Fixed transaction filter to cache hptr node if converted (i.e., do not place bitblasted in save file if avoidable). Fixed min/max of cached autoscaling sizing when number of extension traces changes. 3.3.31 30jan12 Added support for native file requesters in OSX Quartz. Added support for native alert dialogs in OSX Quartz. Clang warning fixes. Added missing config.guess and config.sub. Allow drag of .gtkw (when viewer still does not have a file loaded) to load the corresponding dump file. Fix MinGW compiles broken from recent changes. Documentation updates. Fixed broken ifdef in signalwindow.c that degated savefile loading .gtkw dump+save properly if not gconf2 or Mac. 3.3.32 13feb12 Turn off loader messages when Tcl is executing a command. Added gtk_print_unix_dialog support for printing to real printers by using the "UNIX" type. Automatically kill splash screen on reload/new tab. Added transaction_args savefile tag and support for passing args to transaction filters via the args $comment. Added string value of \000 which renders as high-z. Integrated alt_wheel_mode code provided by Tom Browne. Fixes for some rc file variables to keep them from getting clobbered on 2nd tab opening. Warning fixes when compiled on Ubuntu. 3.3.33 27feb12 Scan-build fix in vcd_recoder.c. Added $timezero tag to VCD files which allows offsetting all the values in a trace to provide ability for negative time values. Currently only VCD, LXT, LXT2, VZT, and FST support this. Fix for timescale 10s and 100s. 3.3.34 12mar12 Fix for marker time deltas when $timezero is used. Reduced size of alert requester icons to 64x64 pixels. 3.3.35 04apr12 Polarity fix for vcd_preserve_glitches in rcfile. Default is no/off. Use yes in the rcfile to enable (e.g., for viewing interpolated analog waveforms). Added vcd_preserve_glitches support to FST as --optimize uses FST. Added vcd_preserve_glitches_real (for VCD/FST) rcfile variable that turns off deglitching only for real signals. This removes the need for #define TRACK_AND_HOLD_FIX and prevents the case where interpolation of an analog waveform is deformed as significant data points were removed by the VCD or FST loader. Fix for do_initial_zoom_fit when file requester used. Changed contact address for bug reports. Enable mouseover for MinGW. Added fstWriterSetParallelMode(). 3.3.36 04may12 Fixed destructive string convert in fstUtilityBinToEsc(). Added support for 01xzhuwl- in fst.c callback interface, vcd2fst.c, and lxt.c. Added adaptive buffer resizing in FST writer for Linux and Mac OSX. Fix for realpath() 2nd argument NULL on Leopard. Fix for doubles stored in HistEnt fields in ghw introduced in 3.3.19. 3.3.37 10jun12 Added patch for savefile.c that corrects an issue in which the parser for process filter lines assumed the associated id number was always a single digit. Added patch to bitvec.c catches one more case when locating bitblasted signals in vcd files created by modelsim. Fix that kills stray pipeio_create() processes on pipeio_destroy(). Additions to extload to handle hier types, component types, and signal types. Added support for extload files as input filetype in vcd2fst. Added -o for extload files to convert to FST. 3.3.38 10jul12 Upgrading vermin parser to handle some > 1995 constructs. Propagate -o option into "Open New Window" menu option. Change invert function so it does not incorrectly expand into the whole nybble when it is < 4 bits. That is, inverting the two bit quantity 10 now displays as 0x1, not 0xD. Added fstminer. MinGW warnings fixes. Fixed relative pathnames for gtkw save files in MinGW. Fix fstapi reader so it does not leave stray hier tmpfiles around in MinGW if reader is never closed. Changed twinwave for MinGW so that it does not target two panes in a single window. Something is apparently now broken in the GtkSocket/GtkPlug implementation for Win32. 3.3.39 08aug12 Fixed relative pathnames when generated in MinGW and used back on Linux. Added --output filename option to fst2vcd, vzt2vcd, and lxt2vcd. Fix crash on OSX if gtk_widget_set_sensitive is called on a separator. Fixed OSX version so it looks for .gtkwaverc in the home directory and if not found, probes the resource bundle for Contents/Resources/examples/gtkwaverc (no dot in the name). Added GTKWave User's Guide option to help menu on OSX. Added + vs ++ separators for twinwave. Dynamic resize fixes. 3.3.40 10sep12 Fixed y-size of splash screen on MinGW with newest version of GTK2 (as it could be verified on that version). Fixed off-by-one buffer string allocation write overflow in calloc_2() call in maketraces(). 3.3.41 30sep12 Fix for gtkwave::addSignalsFromList when encountering signals of form a.b.MyBus[7:0] and a.b.MyBus[15:8] such that brackets aren't stripped. Added experimental highlight_wavewindow rc variable which allows signals also to be highlighted in the wave window using the value for color_grid. Added use_standard_trace_select rc variable and related menu option. 3.3.42 28nov12 Fix to prevent missing group openings from keeping other signals in the viewer that follow from displaying. Adding more support for newer constructs in Vermin. Added scrollwheel support to rtlbrowse code windows. Added fseeko() return checking in fstapi.c to prevent errors with dynamically updated files. 3.3.43 26jan13 Fix for rtlbrowse for gtk_adjustment_get_page_increment and gtk_adjustment_get_step_increment introduced in 2.14. Added VPD support via vpd2vcd. To use, specify -o at the command line. (e.g., gtkwave -o test.vpd) Added autodetect for LXT, LXT2, VZT, FST regardless of the filename suffix. Crash fix for gtkwave::getDisplayedSignals, specifically removing the extra free_2() in WAVE_OE_ME. Added conditional compile for stat() being available. 3.3.44 16feb13 gdk_draw_layout assertion `GDK_IS_DRAWABLE (drawable)' assertion fix. 3.3.45 28feb13 Fix for VCDNAM_ESCAPE character in treesearch window. This sometimes occurs for structure identifiers. 3.3.46 29apr13 Upgraded to autoconf 2.69. Fixed as of yet undetected hdr_incomplete bug when running off end of FST file. (e.g., while file is being written) Fixed problem with is_gtkw_save_file getting wiped out on reload. Updated Mac bundle info to reflect new autoconf filenames. 3.3.47 14may13 Fix for crash in 64-bit mode with array accesses in deprecated loader. Partial VCD loader fix for small files. Added preliminary do-nothing generate support in vermin. Fixed minmax_valid for partial VCD loader: affects scaling on floating-point traces. 3.3.48 04aug13 Fixed infinite loop hang on various helpers executables when extra arguments are specified. Delete changed marker name if it exists when marker is removed. Added "Open Hierarchy" option that will expand the SST and select the hierarchy for a given signal selected in the Signals window. Added preliminary support for FsdbReader. FSDB fix for generate created hierarchies. FSDB fix for new debug info output style to be parsed. Added generate as scope type to VCD/FST/FSDB. Preliminary add for module port direction for FSDB and FST. Display signal direction column in SST if not all signals are declared as FST_VD_IMPLICIT. Fixed GTK warning when hide_sst is enabled and SST is opened then closed. Added extraction of in/out/inout from FSDB into FST with vcd2fst helper executable. (It also converts FSDB to FST.) Added support for SV structures, unions, classes, packages, programs, and interfaces. Updated signal parsing in FST/FSDB to handle NC declarations for arrays in VCD. (i.e., bitranges are missing) Use vcd2fst or the -o option to read NC VCD files with arrays properly. Preliminary support for SV datatypes of bit, logic, int, shortint, longint, byte, enum, and shortreal in VCD and FST. Added sparse array datatype to FST (currently unused by gtkwave). Added support for attribute begin/end in FST. (Currently unused by gtkwave.) This allows embedding of various data inside the structure tree. Added autoraise on entry window on keystrokes or periodically when it exists. Added ability to store $comment in FST files via the attribute mechanism (FST_AT_MISC/FST_MT_COMMENT). 3.3.49 11sep13 Fix crashed caused by X11 protocol limitation for pixmap size. Potential buffer overflow fix in vcd2fst. Added ability to store environment variable information in FST files (FST_MT_ENVVAR). Fixed bad enum for FST_PT_MAX. Added contrib/fst_jni directory to distribution. Fixed broken "make dist" variants. Added buffer and linkage data directions (future expansion for VHDL) in FST and gtkwave. Removed requirement for fsdbdebug in path when FsdbReader is present. Fixed ordering of static FSDB libraries for when dynamic ones are not present. Added direction filters to SST name filter search. That is, adding +I+, +O+, +IO+, +B+, or +L+ before the regular expression adds additional filtering criteria. Direction filters are case-insensitive. Relax FSDB loader to allow VHDL and mixed-language files. Added VHDL hierarchy types to FST, internal VCD loaders and also vcdfst/fst2vcd. Added in VHDL to FST (which will also allow other languages): gtkwave can process these types (e.g., signal + std_ulogic), but there are currently no simulators supporting them. These are written by using fstWriterCreateVar2(). 3.3.50 15oct13 Limit number of rows that can be displayed in mouseover in order to prevent potential X11 crashes on extremely wide signals. Added "/File/Grab To File" PNG image grab menu option. Added missing $dumpvars emission in fst2vcd. Added missing atto and zepto time prefix parsing in vcd2fst. Added VHDL package type to FST. Added red box around 'U' vector values for VHDL similar to 'X' for Verilog. Used FST "attribute name" for variable types if specified. CRLF fix for save file reading on LF-only systems. Fix Valgrind hit in fst.c that was causing crashes on OSX. Added fstWriterSetFiletype() and fstReaderGetFiletype() to provide sim language hint to gtkwave for language- appropriate formatting of various data. Added fstWriterSetSourceStem() so writers can embed source stems in the FST file. Specify before the appropriate hierarchy or variable declaration. Added gtkwave_bin_launcher.sh script to set up environment variables on OSX for running the bin/ directory files from a terminal rather than as an app invocation. 3.3.51 27oct13 MAINTAINERS: Please add gedit to the list of dependencies for gtkwave in order to enable new function that Icarus Verilog dumps into FST files. Fix "/File/Grab To File" on OSX with an OSX patch as the _gdk_quartz_image_copy_to_image() function in the GTK toolkit for Quartz is broken. Updated examples/gtkwaverc accel options to reflect the current state of the gtkwave main window main menu. Added "Open Source Definition" and "Open Source Instantiation" options that invoke .gtkwaverc variable "editor" (or $GTKWAVE_EDITOR or gedit or open -t [OSX]) on sourcecode when source stems are present in the dumpfile (currently FST only). Fixed timezero in vcd2fst as it was only parsing unsigned numbers. Fixed Open Hierarchy crash on blank signals. 3.3.52 11nov13 Added LZ4 as compression type for FST. When enabled with --fourpack in vcd2fst, this compresses both signal data and the hierarchy using LZ4. Added WLF support via wlf2vcd. To use, specify -o at the command line. (e.g., gtkwave -o test.wlf) Changed left/right arrow function in signal/wave windows to find next transition of selected signal(s). Re-enabled DnD scroll beyond top/bottom of Signals pane. Added debounce for baseline (middle) mouse button. Another partial VCD loader fix. Now use libcomdlg32 file requesters on MinGW. Added --extensions flag to fstvcd to enable emission of FST extensions/attributes to VCD files. This is to keep FST attributes from making VCD files unparseable with other tools. Fix in FsdbReader interface for version 1.x files. Many warnings fixes found from gcc -Wextra flag. Fixed thread-unsafe static allocations in fstapi.c. 3.3.53 15dec13 Made LZ4 the default compression routine selected for vcd2fst. Fixes to EVCD parsing in vcd2fst and evcd2vcd. Automatically invoke --optimize if VPD or WLF is detected; invoke on FSDB if FsdbReader is missing. Standardized export feature to write vcd using lower case for non 0/1 values. Added perror() on errno-related exits in vcd loaders. Added experimental wlf2vcd in contrib. It is not currently compiled or used. Corrected non-functional typos in documentation. 3.3.54 02jan14 Added LZ4 double compression on hierarchy tree for FST when hierarchy size exceeds 4MB. Fix to regular expression filtering when +I+ form expressions are encountered in the SST. Previously, the wrong value of regex match was used on 32-bit architectures due to the stack layout. Removed --disable-inline-asm ./configure flag as inline assembly has been removed because it is generating incorrectly in some cases on x86_64. 3.3.55 06feb14 Fixed problem with FST_DYNAMIC_ALIAS_DISABLE enabled when Judy arrays are not present. FST writer performance tweaks for traces with millions of signal declarations. Keep FSDB_VT_STREAM (FSDB transaction type) traces from attempting to be read (for now) as they aren't yet processed. Added more space efficient FST dynamic alias encoding. Tempfile creation fix for Windows. Using tmpnam() is not enough and fails depending on user permissions. Make vcd2fst use FastLZ instead of LZ4 as a default compression type if an EVCD file is being processed as it (re-)compresses much better. Using -4/-F/-Z still gives expected results. Changed double printf formatting for FSDB to "%.16g" to match VCD formatting. Added very fast I/O write capability to fst2vcd. Added support for FSDB_BYTES_PER_BIT_2B (EVCD) in FSDB loader. Added experimental fsdb2vcd in contrib. It is not currently compiled or used. Fix to treesearch to remove duplicate signal names because of faulty dumpers. Repscript fix for if -R starts without a dumpfile name. 3.3.56 12feb14 Added another crash fix patch for GTK-OSX. Fix to regex search to remove duplicate signal names because of faulty dumpers. Fix to configure.ac for MSYS not adding -lcomdlg32 when Tcl is disabled. Valgrind fix on deallocated context: old GLOBALS pointer could be examined in set_GLOBALS_x(). Minor cleanup in treesearch_gtk2.c: removed redundant show widget invocation. Added missing compressBound() for compress2() dest mallocs. 3.3.57 13feb14 Fix for Electric Fence crash in vlist_freeze(). Updated LZ4 for version r113. 3.3.58 16mar14 Added /Data Format/Popcnt function for ones counting. Warnings fixes from new Clang 3.4 scan-build. Updated VCD ID generation in various helpers to use a faster, equivalent algorithm. Change [1] at end of struct to C99 [] notation with appropriate allocation size modification. System_profiler speed fix for OSX. 3.3.59 26apr14 Use Duff's Device for 8 byte -> 1 byte binary value compression algorithm in FST writer. Warnings fixes from cppcheck. Moved MinGW for FST to using different windows tempfile generation instead of tmpfile(). Removed fflush() in FST for MinGW in places that can cause crashes with read only files. Updated man page for gtkwave.1 indicating that XID is in hex. Allow decimal conversions on popcnt filtered vectors that are greater than 64 bits (they will never overflow). 3.3.60 14may14 Fix MinGW tmpfile_open() patch from previous release as it was using the wrong filename. Harden fsdb reader against xtags that move backward in time. 3.3.61 27jun14 Parameterized number of named markers, so that --enable-manymarkers at configure time allows up to 702 named markers instead of 26 (disabled by default). Updated LZ4 for version r118. Fixed broken VCD/TIM export in Windows (broken by new file requester). 3.3.62 29aug14 Added zoom_full, zoom_size, and move_to_time to the dbus interface (dbus enabled by --with-gconf). Updated LZ4 to version r120 (r121 files are the same). Compiler warnings fixes for gtk+-1.2 (-Wall -Wshadow -Wextra). 3.3.63 06nov14 Updated LZ4 for version r123. Added fine horiz scrolling in wavewindow (when using the wheel on a mouse) if shift pressed. Timescale fix for Verilator where it emits 0ps as a timescale. Added sample gtkwave.appdata.xml file in share/appdata. 3.3.64 25nov14 Fix to FileChooser to prevent requester from blocking on asking for a directory if a dumpfile is loaded without some amount of absolute/relative pathname. Updated LZ4 for version r124. Fix for x-windows OSX compiles. 3.3.65 01apr15 Added --, -I-, etc. option to port filtering in SST. Using -- for example filters all non-ports from search results. Updated LZ4 for version r126. Minor warnings fixes. Moved TCL_LDADD/TK_LDADD before FSDB_LDADD to avoid stale Tcl library version conflicts. Removed appending [31:0] to vcd loaded integer names. Reduced recursion depth in GHW signal loader to prevent stack overflow crashes. Added support for synthetic clocks in FST file. Update timetrace marking so it runs quicker for large traces. 3.3.66 05jul15 Faster fsdb initialization. Fix vcd recoder loader crash for malformed vcd if signal is declared as bits and a real valued change is encountered for the value change. Fixed crash in vcd2vzt for vcd files with no value changes (likely a malformed vcd). Added fsdbReaderResetSignalList() to prevent signals from loading over and over when unnecessary. Compile fixes for renamed functions and defines in gtk osx. 3.3.67 24sep15 Updated LZ4 for version r131. Fixed right justify ascii datatype display. 3.3.68 18nov15 Update copyright date. Added named markers capability to From: and To: time value input boxes. Added support for fixed point binary numbers for both signed and unsigned decimal display types. 3.3.69 03feb16 Added missing EXTLOAD_CFLAGS declarations in configure.ac for FSDB detection when only .a files are present (necessary for Ubuntu). Fixed valgrind warning in fst.c for dead memory allocation. Fixed signed fixed point binary number shift for negative numbers. Added ghw patch for missing enum crash in ghw files. 3.3.70 14feb16 Various warnings fixes from new version of scan-build. Crash fix in Windows for transaction traces (broken since VCD/TIM export in 3.3.61). 3.3.71 06apr16 Printf format warnings fixes in lxt2_write.c. Added SVG gtkwave icon in share/icons/hicolor/scalable/apps/gtkwave.svg directory. Make gtkwave interpret values as double precision FP for plotting when BitsToReal is enabled. Also keeps analog mode enabled when selecting numerical formats (which allows enabling/disabling BitsToReal without going out of analog mode). Disabling analog mode can be done using the existing Analog->Off menu option. Fix broken non-canonical bit ordering (IBM) single bit extraction in process_tcl_list(). Fixed gtkwave::gtkwave::addSignalsFromList so it can handle subset and forward/reverse extractions on signals. Remove FST_WRITER_PARALLEL from MinGW CFLAGS as some recent versions of MinGW have issues with struct timespec when pthread.h is included. Added /Edit/Delete to destroy traces without affecting the existing cut buffer. 3.3.72 13apr16 Revert to old gtkwave.appdata.xml as the new one is causing problems with appstream-util validation. 3.3.73 11jun16 Added dragzoom_threshold rc variable to accommodate input devices that have a noisy 3rd mouse button. Fix emission of all filter names so they are emitted in canonical fashion so as to avoid growing strings of ../ in savefiles. 3.3.74 27jul16 Fix for when a signal name is used as a hierarchy name at the same level of scope. (Affects fsdb.) Added --rcvar command line option to insert rc variable changes individually without needing to point to a configuration file. Change to combine traces down/up routines to handle 2D vector name generation. Allow FSDB files to contain ".gz" and ".bz2" suffixes as the libnffr loader can handle those. If a variable is declared in the dumpfile as an integer, then it is imported to the waveform display as an integer instead of a hex value. This works for dump file formats that show the datatype in the SST window. Added code that should prevent the primary marker from disappearing unexpectedly as well as dynamic resizing being stuck in the unset marker width. 3.3.75 02aug16 Fix crash when -S and -W are used in tandem. 3.3.76 13aug16 Fix for --disable-tcl in ./configure caused by 3.3.75 fix. Crash fix in fstapi.c on read value at time accessing of FST files that use new dynamic aliases, FastLZ, or LZ4. This primarily affects rtlbrowse. 3.3.77 03oct16 Updated documentation to include an appendix on FST implementation details. Removed '!A || (A && B)' is equivalent to '!A || B' redundant condition checks where found in source. Added hier_ignore_escapes rc variable. Dynamic resizing tweaks for when it is turned off. Added HUWL-? value types to signal_change_list() to keep GHW files from crashing Tcl scripts. 3.3.78 26oct16 Fixed crash when using multiple pattern searches. 3.3.79 31dec16 Disable accelerator keys in twinwave single window mode to avoid focus conflicts. Fixes for -fstrict-aliasing and other recent warnings. Added fill_waveform rc variable and corresponding menu option (/View/Show Filled High Values) to allow filling in the lower portion of high values for increased visibility. 3.3.80 17mar17 Added "/View/Mouseover Copies To Clipboard" menu option to allow copying values into the clipboard so they can be pasted into text editors, etc. 3.3.81 09jun17 Added max_fsdb_trees environment variable. Fixed -C option so it is persistent across new tabs. Integrated updated GHW reader code. 3.3.82 02jul17 Get sys_fst working with VCS VPI. Added string concatenations for vectors. Added asserts to ghwlib.c to make scan-view clean. 3.3.83 04aug17 Preserve search type for regex search across reloads or close/reopens of regex search widget. Update local libz to current version. 3.3.84 03sep17 Updated FSDB reader with experimental FST tree build routines for faster init. Removed warnings found when compiling with -Wshadow. Automatically enable --comphier for FST/FSDB/AE2 if facility count reaches 500000. This is to reduce memory consumption for traces with very many signals. Added disable_auto_comphier to override this behavior. Fix null pointer sent to gtk_clipboard_set_text() for mouseover to clipboard cut ops. 3.3.85 06sep17 Fix integer type in GHW loader so integer value changes are not stored as a string. This then allows bitwise manipulations of integers. 3.3.86 03oct17 Added recurse import function (found before only in the hier search) into the SST. Removed obsolete bundle functionality from SST as recurse import more accurately imports recursively. Made entrybox taller (using -1) as recent versions of gnome have taller window titlebars and the widget was not tall enough. 3.3.87 28dec17 Added missing prototype for ghw_read_sm_hdr in ghwlib.h. Made intptr_t changes vs long during casting for win64. Warnings fixes. Added use_fat_lines rc variable (which replaces the old --enable-fatlines configure line option for the gtk1/2 version of gtkwave). This allows dynamic line width adjustment at runtime instead of compile time. Re-enable twinwave for Win32/64. Added missing gtkwave_bin_launcher.sh in contrib/bundle_for_osx Makefile.am. 3.3.88 20feb18 Added --sstexclude command line option to prune unwanted clutter from the SST window. Updated "/View/Mouseover Copies To Clipboard" menu option to copying signal names into the clipboard so they can be pasted into text editors, etc. Fixed Write Save File to handle getting confused by initial cancel then retry. Updated v2k input/output declarations to handle unpacked arrays. Fix for pattern marks that could overshoot the left marker. 3.3.89 17mar18 Added support for 32-bit conversions in BitsToReal. Crash fix for pattern search with reals using LXT, LXT2, VZT. 3.3.90 08may18 For Cut Traces, fix up scroll position if there are traces above the current row being cut. Bits to real crash fix for very large floats. Fixed gray code conversions that were incomplete for right justified vectors such that the vector length is not a multiple of the radix size (4 for hex, 3 for oct). Warray-bounds warning fix for 32-bit conversions in BitsToReal. 3.3.91 29may18 Added support for GSettings for when GConf is removed from distributions such as Debian and Ubuntu. Performance fix for large number of groups (remove useless recursion required for transaction traces). 3.3.92 05jul18 Harden FST loader for missing .hier files (if applicable). GTK3 "How does the code know the size to allocate?" warning fix. Fix scrolling on help window by adding scroll to end mark. Fix scrolling on status window when use_toolbutton_interface rc var is set to FALSE by adding scroll to end mark. GTK3: Fix status window so it does not grow in the y direction. Ifdef out code for --slider-zoom as it does not function with GTK toolkit versions > 1.x series. Ifdef out code for force_toolbars as it does not function with GTK toolkit versions > 2.x series. Removed and replaced all GTK3 deprecated API. Installed g_log_set_writer_func handler to suppress numerous GTK3 warnings. Updated BUILT_SOURCES for vermin. extern yy_size_t yyleng fix in rtlbrowse. 3.3.93 03aug18 Add missing XXX_gdk_pointer_ungrab() prototype for GTK3. Fix missing signal/wave window updates in Wayland. Fix mouseover initial position in Wayland. Movement is not yet supported in Wayland for floating mouseover window. Crash fix for twinwave with Wayland (no GtkSocket/Plug). Added sst_dbl_action_type rc variable which controls side- effect of double-clicking in SST signals pane. Added preliminary support for gestures in wave window (currently disabled by default with rc variable use_gestures). Added GtkGestureSwipe for kinetic scrolling in waves window. Added GtkGestureLongPress for baseline marker set/clear. Added GtkGestureDrag to restore normal left cursor drag. Added GtkGestureZoom for zoom/pinch in waves window. Warnings cleanups. Double-click during gestures active deletes primary marker. Use gtk_gesture_single_set_button() to allow re-enabling dragzoom and middle mouse button clicking if use_gestures is enabled. Added xml2stems Verilator XML to rtlbrowse stems converter to distribution. Eventually vermin will be removed. Added missing realpath() in udp emission in vermin. 3.3.94 03sep18 Applied ghwlib.c patch for dealing with null ranges. Fixed typo on gtk_gesture_zoom_new() being disconnected. Slowed down ctrl-scroll for better use on systems where touchpad/screen gestures convert to scroll events. Button press while swipe is slowing down now zeroes out the swipe velocity, causing the scrolling to stop. Added second chance algorithm for find_dumpfile() in case it fails. 3.3.95 07oct18 Fixed GtkGestureZoom to work better on touchscreens. More touchscreen tweaks: provide visual feedback on pinch and zoom. Fix for progress bar on splash screen in Wayland. Add filtering to zoom and drag to prevent floods of events before the next draw. Added fflush on stdout for help text as fix for possible stdout problem with mingw/msys shells. Added warning that "Touch DnD not yet supported on Wayland" when it is attempted on Wayland touchscreens. (X11 is ok.) Added preliminary support for Time datatype. MinGW compile fix on X11 Window usage. Added gesture_filter_cnt to fix spurious mouse events on X11 touch. Warnings fixes for Verilator integration. Fixed install_proc_filter usage for Tcl invocation. Change integer type to "integer" in SST to differentiate it from sv ints. Premiminary support for enum tables embedded in FST files. 3.3.96 16nov18 Changed to standardized zoom in/out/full hotkeys. Changed swipe to use realtime clock for better positioning when frame rate is variable due to differing rendering speed along the trace. Added time backtracking warning (for partial mode) to lxt2vcd. VCD time backtracking fix (not for interactive mode). Added experimental header bar support for GTK3. Added show/hide toolbar buttons to header bar. Added drag_failed handling (can press ESC) to DnD operations. Move reload failure message to header bar for GTK3. Prevent missing file in savefile from causing savefile to be read as VCD by mistake. Changed to Dinotrace-like 0s/1s rendering for bit vectors so values can be discerned without seeing the full value text. Removed unneeded pango_layout_get_extents() inside call for font_engine_draw_string(). Changed bsearch_trunc() to run in constant time when monospace fonts are in use. Added missing GDK_SCROLL_MASK to signal area (need for gtk3). Added default "maybe" option for use_gestures rc variable such that it converts to yes if a touchscreen is detected. Added F11 fullscreen mode toggle. Added F10 to enable main menu. Added F9 toolbar visibility toggle. 3.3.97 23nov18 Added fullscreen button to header bar. Added gtk-application-prefer-dark-theme support. Need to set menu_wlist entry NULL on gtk_widget_destroy(). Fix on vtype()/vtype2() to detect 'x' and make the coloration red on newly-displayed traces. (Bug new from Dinotrace-like rendering in 3.3.96.) 3.3.98 15dec18 Removed pccts and vermin. Use xml2stems instead. Fix gtk_header_bar_set_subtitle() assertion in twinwave. Fix visibility of time_mainbox in twinwave (related to header bar implementation). 3.3.99 09feb19 Added visible single bit glitches as a yellow dot (if enabled with --rcvar 'vcd_preserve_glitches on'). Added filter to prevent redundant redraws during swipes. Disabled rendundant redraw filter during zooms. Fixed print routine broken by bsearch_trunc() optimization in version 3.3.96. 3.3.100 20mar19 GTK3 crash fix for twinwave when change window title is called. FSDB fix for variable declarations of array of reals. Added Real, Time, Enum, and Popcnt flags to Edit/Show-Change. Ensure Show-Change regenerates analog traces. Added braces inside Tcl source command to allow spaces in filenames for Tcl scripts. 3.3.101 08may19 Added gtkwave::getFacDir, gtkwave::getFacVtype, and gtkwave::getFacDtype Tcl accessor functions that function similar to gtkwave::getFacName. Pair $end with $dumpvars in VCD writers. Make %.16g printing in baseconvert.c more resistant to power of 10 roundoff errors. Remove register keyword where applicable as is deprecated. Added --saveonexit gtkwave command line option. 3.3.102 21sep19 Remove redundant TREE_VHDL_ST_PACKAGE from SST exclude. Added addCommentTracesFromList tcl command from user patch. Harden savefile loader for missing group start on vectors. Preliminary VHDL support for wlf2vcd. Add missing return value checks on mmap() in FST writer. 3.3.103 03nov19 Fix MAP_FAILED missing for MinGW. Fix to make the coloration red on 'u' traces. (Bug from Dinotrace-like rendering in 3.3.96.) Typo fix on missing group start on vectors. 3.3.104 24jan20 Added support for loading .vf files (provided FSDB reader libraries are enabled). Added support for dumping variable types in vcd saveer, not just using "wire" for non-reals/strings. Fix for uninitialized values at time 0 for FST, FSDB loaders. 3.3.105 01jul20 Fix bad (void) of is_closing in fstDestroyMmaps when using Cygwin or MinGW. Fix left shift overflow in cvt_fpsdec(). Add in missing file/translate/process filter for reals. Fix for bitvec merging in GHW so integers arrays can be viewed. Added Shift-Up/Down highlight with scroll in order to assist with left/right arrow based transition movement. Fix Show Wave Highlight so it is not dependent on Show Grid. Fix negative MSBs on VCD loaders for vectors. Fix getpwuid() null pointer exception. Add missing recursion case to treenamefix(). Fix lock/unlock misuse of pthread mutexes across threads. Examine env var $HOME for home dir on geteuid failure. Fix blurring on use_fat_lines rc variable usage. 3.3.106 31jul20 Fix Shift-Up/Down highlight to traverse inside groups. Resync ghwlib to handled unbounded arrays. 3.3.107 30sep20 Fix left shift overflow in cvt_fpsudec for fixed point. Added Find First One trace type options. Fixed bug in Show-Change All Highlighted. 3.3.108 30dec20 Fix VZT writer crash when dumpoff is invoked before first timestep. Fix convert_ffo() that scanned in wrong direction. Fix use after free in fstapi.c. 3.3.109 10apr21 gtk_ctree_node_moveto bugfix in SST. MSVC compiler fix for fstapi. Update xml2stems and rtlbrowse to support generate. 3.3.110 22may21 Removed ghwdump and ghwdump.1 from the distribution (now provided with GHDL). Fix for when WAVE_GTK3_GESTURE_ZOOM_USES_GTK_PHASE_CAPTURE is disabled. Integrated blank window fixes from Fedora Core. Minor scan-build fixes. 3.3.111 01sep21 Rendering fix for filled rectangles and line caps in Cairo. Fix in fstapi for read start limit time. Use GtkSearchEntry in SST. Convert entrybox to use dialog box. Entrybox: use default response instead of signal handler. Updated show-change widget. Fix xml2stems when begin blocks are in functions. Skip over decimal point in timescale in viewer. 3.3.112 04oct22 Bugfix-only release. VCD reader fixes for unnamed Icarus begin blocks. String data type crash fix in fst.c. 3.3.113 04oct22 Bugfix-only release. High CPU utilization when nothing is happening. 3.3.114 23nov22 Buffer overflow fixes in FST reader. 3.3.115 28mar23 Fix VZT reader with -fstrict-aliasing. Fix use_multi_state condition in vzt_write.c. Fix for UNDEF vs strings at start of a vzt file. Fix sleep() time scaling redefine for mingw. Use MapViewOfFileEx for mmap on Windows (fstapi). Define FST_DO_MISALIGNED_OPS on AArch64 (fstapi). Fixed attrbegin short length problem. 3.3.116 25jun23 Fix manpage/odt for vcd2fst command switch documentation for zlibpack. Add GDK_WINDOWING_WAYLAND check for gdkwayland.h header usage. Changed sprintf to snprintf in fstapi.c. Fix init crash on show_base_symbols enabled. 3.3.117 08aug23 Fix stems reader processing code broken in 3.3.114. 3.3.118 17dec23 Update xml2stems to handle newer "loc" vs "fl" xml tags. Change preg_regex_c_1 decl to use regex_t* as datatype. Move gtkwave.appdata.xml to io.github.gtkwave.GTKWave.metainfo.xml. Fixed popen security advisories: TALOS-2023-1786 Fixed FST security advisories: TALOS-2023-1777 TALOS-2023-1783 TALOS-2023-1785 TALOS-2023-1789 TALOS-2023-1790 TALOS-2023-1791 TALOS-2023-1792 TALOS-2023-1793 TALOS-2023-1797 TALOS-2023-1798 Fixed evcd2vcd security advisories: TALOS-2023-1803 Fixed VCD security advisories: TALOS-2023-1804 TALOS-2023-1805 TALOS-2023-1806 TALOS-2023-1807 Fixed VZT security advisories: TALOS-2023-1810 TALOS-2023-1811 TALOS-2023-1812 TALOS-2023-1813 TALOS-2023-1814 TALOS-2023-1815 TALOS-2023-1816 TALOS-2023-1817 Fixed LXT2 security advisories: TALOS-2023-1818 TALOS-2023-1819 TALOS-2023-1820 TALOS-2023-1821 TALOS-2023-1822 TALOS-2023-1823 TALOS-2023-1824 TALOS-2023-1826 TALOS-2023-1827 3.3.119 20mar24 Remove FST_DO_MISALIGNED_OPS. Update lz4 to current version from github. Change LZ4_compress to LZ4_compress_default. Update libghw.c/.h to latest upstream version. Fix for -Wsign-compare in fstapi.c. Security fixes for GHW. Fix left shift of a negative number warning in fstapi.c. Fix ctrl-A behavior for SST filter entry. Fix for bad shmat return value in main.c. 3.3.120 14jun24 Add launchable tag in io.github.gtkwave.GTKWave.metainfo.xml. Fix memory leak on name in build_hierarchy_array(). Fix memory leak in ptranslate/ttranslate. Fix case of missing newline at EOF for VCD loaders. Add escape handling state machine for vars in FST loader. Remove escape check on coalesce in FST loader. CreateFileMapping() warning fix for win32 compiles. 3.3.121 26sep24 Integrate gtkwave/pull/376 and gtkwave/pull/377 updates to the FST loader for windows and warnings fixes. Clang warning fixes in fstapi.c on dynamic arrays. Updates for MACOS compiles on gtk3. 3.3.122 19apr25 Buffer warning fix in fstVcdIDForFwrite. Warning fixes in vzt_read.c and fstapi.c. Prototype fixes for port to gcc15. Fixes for tcl9 compatibility. Added fixes for --saveonexit command line option. Fix for convert_real for TR_REAL traces. Fix for popen_san() in vcd2fst using fsdb binaries. Added fstWriterGetFlushContextPending() to fstapi.c/.h. Reenable wayland code for primary and baseline markers in wavewindow.c. Unnamed scope fix for fstReader. Opaque pointer warning fix for fstapi.c. Remove broken pseudo-2D array support in fst.c. Fix in fst.c for signals whose MSB/LSB/len mismatch. Libfst #15: fstReaderOpen should not fail on empty FST file. Fix crash introduced in 3.3.120 with legacy VCD loader caused by "Fix case of missing newline at EOF for VCD loaders." #423: fstminer doesn't handle string transitions correctly. Fix in fst.c for duplicate string values. Remove duplicate string values from adjacent value changes. Libghw add from upstream for ghdl_rtik_type_i64. #428: Inconsistent handling of invalid vector bounds in VCD and FST loaders. 3.3.123 01may25 Fix broken autocoalesce of bitblasted vectors that fix for #428 in 3.3.122 introduced. Fix improper autocoalesce of adjacent duplicate symbols. Preserve dimension on integer array element when expanded. 3.3.124 07may25 Ensure type name in $var for VCD saver is >0 length (GHW). Preserve bitblasted vector ordering with VCD saver. Use full type names in VCD saver instead of abbreviations. Dump all bits for a bitblasted vector in VCD saver in order to ensure stray bit extractions do not cause a failure to reconstruct vectors in proper order in the extracted file. 3.3.125 22jun25 Added json2stems to distribution to support newer versions of Verilator. VCD parser fix for colon in VCD variable name (Jasper). Parameter size 0 fix for Vivado: backs out very old fix (for MTI) that converts 0 size signals to reals. Update vcd2fst so it handles MTI 0 size conversion. gtkwave-gtk3-3.3.125/compile0000775000175000017500000001624515047725113015104 0ustar bybellbybell#! /bin/sh # Wrapper for compilers which do not understand '-c -o'. scriptversion=2012-10-14.11; # UTC # Copyright (C) 1999-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 # . nl=' ' # We need space, tab and new line, in precisely that order. Quoting is # there to prevent tools from complaining about whitespace usage. IFS=" "" $nl" file_conv= # func_file_conv build_file lazy # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. If the determined conversion # type is listed in (the comma separated) LAZY, no conversion will # take place. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv/,$2, in *,$file_conv,*) ;; mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_cl_dashL linkdir # Make cl look for libraries in LINKDIR func_cl_dashL () { func_file_conv "$1" if test -z "$lib_path"; then lib_path=$file else lib_path="$lib_path;$file" fi linker_opts="$linker_opts -LIBPATH:$file" } # func_cl_dashl library # Do a library search-path lookup for cl func_cl_dashl () { lib=$1 found=no save_IFS=$IFS IFS=';' for dir in $lib_path $LIB do IFS=$save_IFS if $shared && test -f "$dir/$lib.dll.lib"; then found=yes lib=$dir/$lib.dll.lib break fi if test -f "$dir/$lib.lib"; then found=yes lib=$dir/$lib.lib break fi if test -f "$dir/lib$lib.a"; then found=yes lib=$dir/lib$lib.a break fi done IFS=$save_IFS if test "$found" != yes; then lib=$lib.lib fi } # func_cl_wrapper cl arg... # Adjust compile command to suit cl func_cl_wrapper () { # Assume a capable shell lib_path= shared=: linker_opts= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. eat=1 case $2 in *.o | *.[oO][bB][jJ]) func_file_conv "$2" set x "$@" -Fo"$file" shift ;; *) func_file_conv "$2" set x "$@" -Fe"$file" shift ;; esac ;; -I) eat=1 func_file_conv "$2" mingw set x "$@" -I"$file" shift ;; -I*) func_file_conv "${1#-I}" mingw set x "$@" -I"$file" shift ;; -l) eat=1 func_cl_dashl "$2" set x "$@" "$lib" shift ;; -l*) func_cl_dashl "${1#-l}" set x "$@" "$lib" shift ;; -L) eat=1 func_cl_dashL "$2" ;; -L*) func_cl_dashL "${1#-L}" ;; -static) shared=false ;; -Wl,*) arg=${1#-Wl,} save_ifs="$IFS"; IFS=',' for flag in $arg; do IFS="$save_ifs" linker_opts="$linker_opts $flag" done IFS="$save_ifs" ;; -Xlinker) eat=1 linker_opts="$linker_opts $2" ;; -*) set x "$@" "$1" shift ;; *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) func_file_conv "$1" set x "$@" -Tp"$file" shift ;; *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) func_file_conv "$1" mingw set x "$@" "$file" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -n "$linker_opts"; then linker_opts="-link$linker_opts" fi exec "$@" $linker_opts exit 1 } eat= case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand '-c -o'. Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file 'INSTALL'. Report bugs to . EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac ofile= cfile= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. # Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook '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-gtk3-3.3.125/config.guess0000775000175000017500000012746315047725113016053 0ustar bybellbybell#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012, 2013 Free Software Foundation, Inc. timestamp='2012-12-29' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD # # Please send patches with a ChangeLog entry to config-patches@gnu.org. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH="x86_64" fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW64*:*) echo ${UNAME_MACHINE}-pc-mingw64 exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-gnu else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-unknown-linux-gnueabi else echo ${UNAME_MACHINE}-unknown-linux-gnueabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; cris:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-gnu exit ;; crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-gnu exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; hexagon:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; i*86:Linux:*:*) LIBC=gnu eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; padre:Linux:*:*) echo sparc-unknown-linux-gnu exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; x86_64:Haiku:*:*) echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in i386) eval $set_cc_for_build if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then UNAME_PROCESSOR="x86_64" fi fi ;; unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; NSE-*:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; esac eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp 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` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: gtkwave-gtk3-3.3.125/README.md0000664000175000017500000001074015047725113014777 0ustar bybellbybell# GTKWave ## Installation 2) If you compile a GIT version: Type `./autogen.sh` 2) Type `./configure --enable-gtk3` (or `./configure` for GTK+ 2) 3) `make` 4) `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 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: ```sh ./configure CFLAGS='-Wall -O3 -mcpu=i686 -mms-bitfields -ffast-math -fstrict-aliasing' ``` After that you may just call make the usual way. ## Misc. Notes 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. 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` ## 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. ```sh sudo apt-get install libgtk2.0-dev ./configure --with-tcl=/usr/lib/tcl8.4 --with-tk=/usr/lib/tk8.4 ``` ## 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: ```sh ./configure --enable-local-libz ``` ## Note (3) For Ubuntu users (version 11.10): ```sh 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: ```sh ./configure --enable-judy --enable-struct-pack --with-gconf ``` ## Notes for Mac OSX users: Install MacPorts then ```sh sudo port -v selfupdate sudo port install Judy tcl tk xz-devel gtk2 ``` If Quartz is used: ```sh 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): ```sh ./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. ## MSYS2 notes for creating a working environment for compiling gtkwave: ```sh pacman -Syuu [repeat "pacman -Syuu" multiple times until environment stabilizes] pacman -S --needed base-devel mingw-w64-i686-toolchain mingw-w64-x86_64-toolchain git subversion mercurial mingw-w64-i686-cmake mingw-w64-x86_64-cmake pacman -S base-devel mingw-w64-toolchain mingw-w64-i686-gtk2 pacman -S mingw-w64-i686-gtk2 pacman -S mingw-w64-x86_64-gtk2 pacman -S mingw-w64-i686-gtk3 pacman -S mingw-w64-x86_64-gtk3 ``` Add `--enable-gtk3` to the `./configure` invocation to build against GTK3. This causes the GTK+ frontend to be built with gtk3 instead of gtk2. gtkwave-gtk3-3.3.125/config.sub0000775000175000017500000010546715047725113015516 0ustar bybellbybell#! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011, 2012, 2013 Free Software Foundation, Inc. timestamp='2012-12-29' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches with a ChangeLog entry to config-patches@gnu.org. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze*) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 ;; -lynx*5) os=-lynxos5 ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ | be32 | be64 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | epiphany \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 \ | ns16k | ns32k \ | open8 \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze*) basic_machine=microblaze-xilinx ;; mingw64) basic_machine=x86_64-pc os=-mingw64 ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i386-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos | rdos64) basic_machine=x86_64-pc os=-rdos ;; rdos32) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tile*) basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -bitrig* | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -kaos*) os=-kaos ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; hexagon-*) os=-elf ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: gtkwave-gtk3-3.3.125/changes_from_gtk2.txt0000664000175000017500000004014215047725113017642 0ustar bybellbybellConversions from gtkwave-3.3.86 (gtk1/2 codebase) 01 changes: ls -1 | awk '{print "cat "$0" | sed s/GtkSignalFunc/GCallback/g >"$0".xxx ; mv "$0".xxx "$0}' | sh ls -1 | awk '{print "cat "$0" | sed s/GTK_SIGNAL_FUNC/G_CALLBACK/g >"$0".xxx ; mv "$0".xxx "$0}' | sh change gtkctree in treesearch_gtk2 widget to treeview 02 changes: tooltip: https://developer.gnome.org/gtk2/stable/GtkTooltip.html 03 changes: remove stray any_tree_node left over from 01 remove gdk font support (use pango only now) 04 changes: enable WAVE_USE_MLIST_T to replace deprecated GtkItemFactory code. change GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_DEFAULT) to gtk_widget_set_can_default(widget, TRUE). 05 changes: change GtkCList usage in translate.c/ptranslate.c/ttranslate.c to use gtk list stores. remove stray unused GtkCList* declaration in treesearch_gtk2.c, remove treesearch_gtk1.c support. change GtkCList usage in search.c to use gtk list stores. change GtkCList usage in hiersearch.c to use gtk list stores. 06 changes: removed GtkFileSelection code paths in file.c (GtkFileChooser is already used anyway) change remaining GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_DEFAULT) to gtk_widget_set_can_default(widget, TRUE), change GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS) to gtk_widget_set_can_focus(widget, TRUE). change from using deprecated portions of GtkToolbar API. change remaining pixmap.c usages of pixmap usages to pixbuf change gtk_entry_new_with_max_length calls with wrapped XXX_gtk_entry_new_with_max_length ones (gtk_entry_new + gtk_entry_set_max_length) removed stray GtkCTree references in tcl_support_commands.h, changed GtkNotebookPage* to gpointer in main.c. 07 changes: ls -1 | awk '{print "cat "$0" | sed s/gtk_signal_connect_object/g_signal_connect_swapped/g >"$0".xxx ; mv "$0".xxx "$0}' | sh ls -1 | awk '{print "cat "$0" | sed s/gtk_signal_connect/g_signal_connect/g >"$0".xxx ; mv "$0".xxx "$0}' | sh replace gtk_signal_disconnect with g_signal_handler_disconnect. ls -1 | awk '{print "cat "$0" | sed s/gtk_container_border_width/gtk_container_set_border_width/g >"$0".xxx ; mv "$0".xxx "$0}' | sh ls -1 | awk '{print "cat "$0" | sed s/gtk_label_set/gtk_label_set_text/g >"$0".xxx ; mv "$0".xxx "$0}' | sh change gtk_menu_append to gtk_menu_shell_append. change gtk_radio_menu_item_group to gtk_radio_menu_item_get_group. change gtk_radio_button_group to gtk_radio_button_get_group. change gtk_toggle_button_set_state to gtk_toggle_button_set_active. change gtk_button_box_set_spacing to gtk_box_set_spacing. change GtkOptionMenu usages to GtkComboBox. change GtkProgress to GtkProgressBar. change GTK_WIDGET_HAS_FOCUS() to gtk_widget_has_focus(). change !GTK_WIDGET_NO_WINDOW() to gtk_widget_get_has_window(). change GTK_WIDGET_STATE() to gtk_widget_get_state(). * now compiles OK with: make CFLAGS+="-DGTK_DISABLE_DEPRECATED" 08 changes: replaced gtk legacy format GDK_A type define usages to GDK_KEY_A. * now compiles OK with: make CFLAGS+="-D__G_IR_SCANNER__" 09 changes: includes fixes * now compiles OK with: make CFLAGS+="-DGTK_DISABLE_SINGLE_INCLUDES" 10 changes: gtk_adjustment_get_value () gtk_adjustment_get_lower () gtk_adjustment_get_upper () gtk_adjustment_set_value () gtk_widget_get_allocation () gtk_widget_get_window () gtk_entry_get_text_length () gtk_text_view_get_buffer () gtk_text_view_get_vadjustment () gtk_widget_get_style () gtk_toggle_button_get_active () gdk_drag_context_get_actions () gtk_selection_data_get_length () gtk_selection_data_get_data () gtk_adjustment_set_lower () gtk_adjustment_set_upper () gtk_adjustment_get_page_size () gtk_adjustment_get_page_increment () gtk_adjustment_get_step_increment () GtkAllocation allocation; gtk_widget_get_allocation(GLOBALS->signalarea, &allocation); * now compiles OK with make CFLAGS+="-DGSEAL_ENABLE" 11 changes: make shadow rgb_gcs for cairo operations that have the proper RGB values. these will replace existing GCs that specify individual colors. remove GLOBALS->signalpixmap usages (e.g., via gdk_draw_pixmap) and replace with corresponding cairo operations fixed improperly converted ->page_size and ->page increment for signal/wavewindow vertical slider that used incorrect value of 1.0. remove GLOBALS->wavepixmap_wavewindow_c_1 usages (e.g., via gdk_draw_pixmap) and replace with corresponding cairo operations remove GLOBALS->wave_splash_pixmap usages (e.g., via gdk_draw_pixmap) and replace with corresponding cairo operations Needed to make GLOBALS->timestart_from_savefile_valid a down counter from 2 rather than a simple 1/0 value as does not now work without that remove GLOBALS->mo_pixmap_mouseover_c_1 (e.g., via gdk_draw_pixmap) and replace with corresponding cairo operations remove usage of fonts_gc for pango fonts as is unnecessary remove any usages/definitions of GdkGC remaining (not used by any code) * now compiles OK with make CFLAGS+="-DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED" 12 changes: added configure.3 for gtk3, still need to convert more gtk2->gtk3 items redefine GTK_OBJECT to GTK_OBJECT(x) x. Change GtkObject to gpointer. Remove stray GdkFont usages. Change GdkNativeWindow to Window. Use gdk_screen_get_default() in fonts.c to prevent from having to use a GdkDrawable for configuring the pango fonts. Remove set_scroll_adjustments() function call hanging off TextViewClass. ls -1 | awk '{print "cat "$0" | sed s/GTK_OBJECT/XXX_GTK_OBJECT/g >"$0".xxx ; mv "$0".xxx "$0}' | sh ls -1 | awk '{print "cat "$0" | sed s/GDK_DRAWABLE/XXX_GDK_DRAWABLE/g >"$0".xxx ; mv "$0".xxx "$0}' | sh ls -1 | awk '{print "cat "$0" | sed s/gtk_signal_emit_by_name/g_signal_emit_by_name/g >"$0".xxx ; mv "$0".xxx "$0}' | sh ls -1 | awk '{print "cat "$0" | sed s/gtk_widget_set_usize/gtk_widget_set_size_request/g >"$0".xxx ; mv "$0".xxx "$0}' | sh ls -1 | awk '{print "cat "$0" | sed s/gtk_widget_set_usize/gtk_widget_set_size_request/g >"$0".xxx ; mv "$0".xxx "$0}' | sh ls -1 | awk '{print "cat "$0" | sed s/gtk_entry_select_region/gtk_editable_select_region/g >"$0".xxx ; mv "$0".xxx "$0}' | sh Replace gtk_window_set_policy with gtk_window_set_resizable. Replace gtk_entry_set_editable with gtk_editable_set_editable. Replace gtk_timeout_add with g_timeout_add. Replace gtk_timeout_remove with g_source_remove. Comment out gtk_object_set_data(XXX_GTK_OBJECT(pFileChoose), "FileChooseWindow", pFileChoose); in file.c Now compiles in gtk3...need to do various adjustments such as handling expose events. 13 changes: Change expose_event to draw. Added XXX_resize_sstpane_y_hack_for_gtk3() hack to get GtkExpander more-or-less sizing its child contents properly. Converted most of rtl browser using above. Still need to convert over GtkCList tree. 14 changes: Compiles in both gtk2 and gtk3. Need to address various gtk2->gtk3 glitches as outlined below. ls -1 *.c *.h | awk '{print "cppp -DWAVE_USE_GTK2 "$0" >"$0".xxx ; mv "$0".xxx "$0}' | sh ls -1 *.c *.h | awk '{print "cppp -UGTK_ENABLE_BROKEN "$0" >"$0".xxx ; mv "$0".xxx "$0}' | sh ls -1 *.c *.h | awk '{print "cppp -DWAVE_USE_MLIST_T "$0" >"$0".xxx ; mv "$0".xxx "$0}' | sh Removed XXX_resize_sstpane_y_hack_for_gtk3(), changed GtkExpander to gtkframe in gtk3 to get child contents resizing properly. Removed obsolete GTK_CHECK_VERSION instantiations for gtk2. Changed rtlbrose expose_event to use draw so text search can work in gtk3. Re-enabled fileselbox_old() code for comdlg requester during MinGW32 builds. 15 changes: fold in mainline 3.3.87 change for missing ghw_read_sm_hdr prototype in ghwlib.h. intptr_t/uintptr_t changes vs long during casting for win64. update GtkStyle.draw_slider usage for gtk3. 16 changes: change package name to gtwave-gtk3. This and the regular gtkwave should *not* be installed at the same time! add back in dashed lines for 2nd pattern marks. added code in to zoombuttons.c to work around GTK3 value clamping (adjustment set functions have side effects and not just changing the value directly) recycled some WAVE_ALLOW_QUARTZ_FLUSH_WORKAROUND as WAVE_ALLOW_GTK3_VSLIDER_WORKAROUND to get wave_vslider to update properly on gtk3 startup. change top level for splash on gtk3 win32/64 to use GTK_WINDOW_TOPLEVEL as apparently GTK_WINDOW_POPUP is not handling the render events for the black status bar. expanded size of window in des.gtkw example file so Marker|Cursor display is visible. converted named markers to using cairo dashed lines (rather than drawing segments manually) 17 changes: removed all GTK_CHECK_VERSION for less than 3.0 and made = defined by using cppp. minor change of placement of zoom full so des.tcl renders properly bump up gtk2 requirement version to 2.24.9. (matches OSX build machine) removed most _MSC_VER from code as MinGW is the preferred Win32/64 build environment, however left in helpers and non-gtkwave/non-rtlbrowse code. remove local libz and libbz2 source code as almost all systems have this installed now. added gtk_widget_set_vexpand_set() to fix SST vertical size in gtk3 (vertical pane wouldn't grow properly to fill full y direction) added GLOBALS->h_debounce gating in in hiersearch.c, xxx_view_selection_func does not seem to function correctly and sometimes goes up multiple levels per .. selection. it seems to be that selection_func is not a good place for tree updates.! normalize all xxx_ function names created from gtk1/2 -> gtk2/3 conversion to XXX_ 18 changes: gtk_tree_view_[g|s]et_[v|h]adjustment -> gtk_scrollable_[g|s]et_[v|h]adjustment for gtk3 gtk_text_view_get_vadjustment -> gtk_scrollable_get_vadjustment 19 changes: fixed overwide x-size misallocation in pattern search window. seems to be a problem with hbox allocations. 20 changes: fixed internal in gtk3 toolkit: (gtkwave:9908): Gtk-WARNING **: Allocating size to GtkFrame 0x1820c00 without calling gtk_widget_get_preferred_width/height(). gtk_container_set_resize_mode() is needed in create_wavewindow() because for some reason the vertical scrollbar attached to the table does not propagate resize allocations up to the frame. ifdef'd out gtk_widget_get_style/gtk_widget_set_style/gtk_rc_style_new/gtk_widget_modify_style as there is no apparent effect on gtk3. twinwave: gtk_[v|h]box_new -> gtk_box_new + gtk_box_set_homogeneous twinwave: gtk_[v|h]paned_new -> gtk_paned_new rtlbrowse: gtk_hpaned_new -> gtk_paned_new ls -1 | awk '{print "cat "$0" | sed s/gtk_hbox_new/XXX_gtk_hbox_new/g >"$0".xxx ; mv "$0".xxx "$0}' | sh ls -1 | awk '{print "cat "$0" | sed s/gtk_vbox_new/XXX_gtk_vbox_new/g >"$0".xxx ; mv "$0".xxx "$0}' | sh gtkwave: gtk_[v|h]paned_new -> XXX_gtk_[v|h]paned_new gtk_hseparator_new() -> gtk_separator_new(GTK_ORIENTATION_HORIZONTAL) gtk_menu_popup -> gtk_menu_popup_at_pointer gtk_button_set_focus_on_click -> gtk_widget_set_focus_on_click gtk_[h|v]scrollbar_new -> gtk_scrollbar_new rtlbrowse: gtk_table_attach -> gtk_grid_attach/gtk_widget_set_hexpand/gtk_widget_set_vexpand ls -1 | awk '{print "cat "$0" | sed s/gtk_table_new/XXX_gtk_table_new/g >"$0".xxx ; mv "$0".xxx "$0}' | sh ls -1 | awk '{print "cat "$0" | sed s/gtk_table_attach/XXX_gtk_table_attach/g >"$0".xxx ; mv "$0".xxx "$0}' | sh ls -1 | awk '{print "cat "$0" | sed s/GTK_TABLE/XXX_GTK_TABLE/g >"$0".xxx ; mv "$0".xxx "$0}' | sh Ifdef removal of gtk_handle_box_new force_toolbars code. rtlbrowse: gtk_image_new_from_stock -> gtk_image_new_from_icon_name rtlbrowse: gtk_tool_button_new_from_stock -> gtk_image_new_from_icon_name + gtk_tool_button_new Convert GtkStock strings to freedesktop ones using table from https://wiki.gnome.org/Attic/GtkNamingSpecInvestigation webpage. gdk_pointer_grab -> gdk_seat_grab gdk_pointer_ungrab -> gdk_seat_ungrab gdk_cursor_new -> gdk_cursor_new_for_display gdk_window_get_pointer->gdk_window_get_device_position gdk_cairo_create->gdk_window_begin_draw_frame and related support functions cairo_destroy->gdk_window_end_draw_frame === to do: remove gtksocket/plug mechanism and simply use separate windows to avoid gtkx/X11 dependencies? for GLOBALS->treeview_main, see what hadj/vadj work is required in globals.c to get this to scroll to the correct position. it's not currently working right/consistently. internal in gtk3 toolkit using + option (++ works): (twinwave:9756): Gtk-CRITICAL **: gtk_widget_destroy: assertion 'GTK_IS_WIDGET (widget)' Look for size allocation issues with the tabbed viewing in gtkwave when resizing, etc. Splash screen does not raise or have centered window position for Wayland. === Future possible use on signalarea in case it moves to gestures. Getting modifiers inside a gesture: GdkDevice *device = gtk_gesture_get_device (GTK_GESTURE(gesture)); if(device) { GdkModifierType mask; gdk_device_get_state (device, gtk_widget_get_window(GLOBALS->wavearea), NULL, &mask); ev.state = mask; } Determine x/y position in DnD: GdkDevice *device = gdk_drag_context_get_device(dc); GdkInputSource is = gdk_device_get_source(device); gint x, y; gdk_device_get_position (device, NULL, &x, &y); printf("x: %d, y: %d\n", x, y); if(is == GDK_SOURCE_TOUCHSCREEN) // gtk 3.0 only { } === Momentum scrolling fundamentals: https://ariya.io/2011/10/flick-list-with-its-momentum-scrolling-and-deceleration === Notes on GMenu usage so they don't get lost if there is a forced migration to them: ############################## #ifdef WAVE_USE_GTK_APPLICATION GtkApplication *app = NULL; int my_argc; char **my_argv; static void activate_main (GApplication *app, gpointer user_data) { printf("XXX activate\n"); main_2(0, my_argc, my_argv); } int main(int argc, char *argv[]) { int status; app = gtk_application_new ("org.gnome.example", G_APPLICATION_FLAGS_NONE); g_signal_connect (app, "activate", G_CALLBACK (activate_main), NULL); my_argc = argc; my_argv = argv; status = g_application_run (G_APPLICATION (app), 1, argv); g_object_unref (app); printf("status = %d\n", status); return status; } #else int main(int argc, char *argv[]) { return(main_2(0, argc, argv)); } #endif ############################## #define WAVE_GTKIFE(a,b,c,d,e) {a,b,c,d,e,NULL,"app." #d} 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; const char *detailed_action_name; }; ############################## static void activate_cb (GSimpleAction *action, GVariant *parameter, gpointer user_data) { printf("XXX %p '%s'\n", user_data, menu_items[(intptr_t)user_data].path); // } static void *alt_menu_walk_2(gtkwave_mlist_t *mi, struct menu_item_t *lst, int depth) { struct menu_item_t *ptr = lst; struct menu_item_t *optr; GMenu *menu = g_menu_new(); GMenu *tmenu = g_menu_new(); while(ptr) { /* mi[ptr->idx] is menu item */ int skip = 0; int tog = ((!strcmp(mi[ptr->idx].item_type, "")) && !ptr->child); if(!strcmp(mi[ptr->idx].item_type, "")) { skip = 1; if(ptr->next) { g_menu_append_section (menu, NULL, G_MENU_MODEL (tmenu)); g_object_unref (tmenu); tmenu = g_menu_new(); } } if(ptr->child) { GMenu *cmenu = alt_menu_walk_2(mi, ptr->child, depth+1); g_menu_append_submenu (tmenu, ptr->name, G_MENU_MODEL (cmenu)); } else { if(!skip) { const char *dit = mi[ptr->idx].detailed_action_name; const GActionEntry app_entries = { dit+4, activate_cb, NULL, tog ? "true" : NULL, NULL }; /* dit string is "app.whatever" */ g_action_map_add_action_entries (G_ACTION_MAP (app), &app_entries, 1, (gpointer)(intptr_t)mi[ptr->idx].callback_action); g_menu_append (tmenu, ptr->name, dit); const gchar *accels[2]; accels[0] = mi[ptr->idx].accelerator; accels[1] = NULL; gtk_application_set_accels_for_action (GTK_APPLICATION (app), dit, accels); } } optr = ptr; ptr = ptr->next; free_2(optr->name); free_2(optr); } g_menu_append_section (menu, NULL, G_MENU_MODEL (tmenu)); g_object_unref (tmenu); if(!depth) { menu = (void *)gtk_menu_bar_new_from_model (G_MENU_MODEL (menu)); gtk_application_add_window (app, GTK_WINDOW(GLOBALS->mainwindow)); } return(menu); } ############################## === gtkwave-gtk3-3.3.125/config.h.in0000664000175000017500000002162315047725113015545 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-gtk3-3.3.125/LICENSE.TXT0000664000175000017500000001224715047725113015207 0ustar bybellbybell########################################################################## GTKWave 3.3.125 Wave Viewer is Copyright (C) 1999-2025 Tony Bybell. Portions of GTKWave are Copyright (C) 1999-2025 Udi Finkelstein. Context support is Copyright (C) 2007-2025 Kermin Elliott Fleming. Trace group support is Copyright (C) 2009-2025 Donald Baltus. GHW and additional GUI support is Copyright (C) 2005-2025 Tristan Gingold. Analog support is Copyright (C) 2005-2025 Thomas Sailer. External DnD support is Copyright (C) 2008-2025 Concept Engineering GmbH. FastLZ is Copyright (C) 2005-2025 Ariya Hidayat. LZ4 is Copyright (C) 2011-2025 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. ########################################################################## 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-gtk3-3.3.125/contrib/0000775000175000017500000000000015047725113015156 5ustar bybellbybellgtkwave-gtk3-3.3.125/contrib/fst_jni/0000775000175000017500000000000015047725113016612 5ustar bybellbybellgtkwave-gtk3-3.3.125/contrib/fst_jni/fstHier.java0000664000175000017500000000362515047725113021067 0ustar bybellbybell/* * Copyright (c) 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. */ public class fstHier { public boolean valid; // all types public int htyp; // FST_HT_SCOPE, FST_HT_UPSCOPE, FST_HT_VAR, FST_HT_ATTRBEGIN, FST_HT_ATTREND public int typ; // appropriate FST_ST_* type for htyp, vartype, etc. public int subtype; // FST_HT_ATTRBEGIN public String name1; // FST_HT_SCOPE, FST_HT_VAR, FST_HT_ATTRBEGIN public String name2; // FST_HT_SCOPE public int direction; // FST_HT_VAR public int handle; // FST_HT_VAR public int length; // FST_HT_VAR public boolean is_alias; // FST_HT_VAR public long arg; // FST_HT_ATTRBEGIN public long arg_from_name; // FST_HT_ATTRBEGIN public fstHier() { valid = false; htyp = 0; typ = 0; subtype = 0; name1 = ""; name2 = ""; direction = 0; handle = 0; length = 0; is_alias = false; arg = 0; arg_from_name = 0; }; }; gtkwave-gtk3-3.3.125/contrib/fst_jni/fstVarDir.java0000664000175000017500000000314015047725113021357 0ustar bybellbybell/* * Copyright (c) 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. */ public class fstVarDir { private fstVarDir() { } public static final String [] FST_VD_NAMESTRINGS = { "implicit", "input", "output", "inout", "buffer", "linkage" }; public static final int FST_VD_MIN = 0; public static final int FST_VD_IMPLICIT = 0; public static final int FST_VD_INPUT = 1; public static final int FST_VD_OUTPUT = 2; public static final int FST_VD_INOUT = 3; public static final int FST_VD_BUFFER = 4; public static final int FST_VD_LINKAGE = 5; public static final int FST_VD_MAX = 5; }; gtkwave-gtk3-3.3.125/contrib/fst_jni/fstHierType.java0000664000175000017500000000263215047725113021726 0ustar bybellbybell/* * Copyright (c) 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. */ public class fstHierType { private fstHierType( ) { } public static final int FST_HT_SCOPE = 0; public static final int FST_HT_UPSCOPE = 1; public static final int FST_HT_VAR = 2; public static final int FST_HT_ATTRBEGIN = 3; public static final int FST_HT_ATTREND = 4; public static final int FST_HT_MAX = 4; }; gtkwave-gtk3-3.3.125/contrib/fst_jni/fstVarType.java0000664000175000017500000000577415047725113021601 0ustar bybellbybell/* * Copyright (c) 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. */ public class fstVarType { private fstVarType() { } public static final String [] FST_VT_NAMESTRINGS = { "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" }; public static final int FST_VT_VCD_MIN = 0; public static final int FST_VT_VCD_EVENT = 0; public static final int FST_VT_VCD_INTEGER = 1; public static final int FST_VT_VCD_PARAMETER = 2; public static final int FST_VT_VCD_REAL = 3; public static final int FST_VT_VCD_REAL_PARAMETER = 4; public static final int FST_VT_VCD_REG = 5; public static final int FST_VT_VCD_SUPPLY0 = 6; public static final int FST_VT_VCD_SUPPLY1 = 7; public static final int FST_VT_VCD_TIME = 8; public static final int FST_VT_VCD_TRI = 9; public static final int FST_VT_VCD_TRIAND = 10; public static final int FST_VT_VCD_TRIOR = 11; public static final int FST_VT_VCD_TRIREG = 12; public static final int FST_VT_VCD_TRI0 = 13; public static final int FST_VT_VCD_TRI1 = 14; public static final int FST_VT_VCD_WAND = 15; public static final int FST_VT_VCD_WIRE = 16; public static final int FST_VT_VCD_WOR = 17; public static final int FST_VT_VCD_PORT = 18; public static final int FST_VT_VCD_SPARRAY = 19; public static final int FST_VT_VCD_REALTIME = 20; public static final int FST_VT_GEN_STRING = 21; public static final int FST_VT_SV_BIT = 22; public static final int FST_VT_SV_LOGIC = 23; public static final int FST_VT_SV_INT = 24; public static final int FST_VT_SV_SHORTINT = 25; public static final int FST_VT_SV_LONGINT = 26; public static final int FST_VT_SV_BYTE = 27; public static final int FST_VT_SV_ENUM = 28; public static final int FST_VT_SV_SHORTREAL = 29; public static final int FST_VT_VCD_MAX = 29; }; gtkwave-gtk3-3.3.125/contrib/fst_jni/fstMiscType.java0000664000175000017500000000303615047725113021731 0ustar bybellbybell/* * Copyright (c) 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. */ public class fstMiscType { fstMiscType( ) { } public static final int FST_MT_MIN = 0; public static final int FST_MT_COMMENT = 0; public static final int FST_MT_ENVVAR = 1; public static final int FST_MT_SUPVAR = 2; public static final int FST_MT_PATHNAME = 3; public static final int FST_MT_SOURCESTEM = 4; public static final int FST_MT_SOURCEISTEM = 5; public static final int FST_MT_UNKNOWN = 6; public static final int FST_MT_MAX = 6; }; gtkwave-gtk3-3.3.125/contrib/fst_jni/fst2Vcd.java0000664000175000017500000001054115047725113020771 0ustar bybellbybell/* * Copyright (c) 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. */ public class fst2Vcd { fstReader fb; byte [] facType; long prevTime; long startTime, endTime; public void fstReaderCallback(long tim, int facidx, String value) { if(tim != prevTime) { System.out.println("#" + tim); prevTime = tim; } switch(facType[facidx]) { case fstVarType.FST_VT_VCD_REAL: case fstVarType.FST_VT_VCD_REAL_PARAMETER: case fstVarType.FST_VT_VCD_REALTIME: case fstVarType.FST_VT_SV_SHORTREAL: System.out.println("r" + value + " " + fb.fstReaderVcdID(facidx)); break; case fstVarType.FST_VT_GEN_STRING: System.out.println("s" + value + " " + fb.fstReaderVcdID(facidx)); break; default:if(value.length() == 1) { System.out.println(value + fb.fstReaderVcdID(facidx)); } else { System.out.println("b" + value + " " + fb.fstReaderVcdID(facidx)); } break; } } fst2Vcd(String fnam) { fb = new fstReader(fnam); startTime = fb.fstReaderGetStartTime(); endTime = fb.fstReaderGetEndTime(); System.out.println("$date\n\t" + fb.fstReaderGetDateString() + "\n$end"); System.out.println("$version\n\t" + fb.fstReaderGetVersionString() + "\n$end"); System.out.println("$timescale\n\t" + fb.fstReaderGetTimescaleString() + "s\n$end"); int maxHandle = fb.fstReaderGetMaxHandle(); facType = new byte[maxHandle+1]; fstHier fh = new fstHier(); for(;;) { fb.fstReaderIterateHier(fh); if(!fh.valid) break; switch(fh.htyp) { case fstHierType.FST_HT_SCOPE: System.out.println("$scope " + fstScopeType.FST_ST_NAMESTRINGS[fh.typ] + " " + fh.name1 + " $end"); break; case fstHierType.FST_HT_UPSCOPE: System.out.println("$upscope $end"); break; case fstHierType.FST_HT_VAR: int modlen; facType[fh.handle] = (byte)fh.typ; switch(fh.typ) { case fstVarType.FST_VT_VCD_REAL: case fstVarType.FST_VT_VCD_REAL_PARAMETER: case fstVarType.FST_VT_VCD_REALTIME: modlen = 64; break; case fstVarType.FST_VT_SV_SHORTREAL: modlen = 32; break; case fstVarType.FST_VT_GEN_STRING: modlen = 0; break; default: modlen = fh.length; break; } System.out.println("$var " + fstVarType.FST_VT_NAMESTRINGS[fh.typ] + " " + modlen + " " + fb.fstReaderVcdID(fh.handle) + " " + fh.name1 + " $end"); break; case fstHierType.FST_HT_ATTRBEGIN: if(fh.typ == fstAttrType.FST_AT_MISC) { switch(fh.subtype) { case fstMiscType.FST_MT_COMMENT: System.out.println("$comment\n\t" + fh.name1 + "\n$end"); break; case fstMiscType.FST_MT_SOURCESTEM: case fstMiscType.FST_MT_SOURCEISTEM: System.out.println("$attrbegin " + fstAttrType.FST_AT_NAMESTRINGS[fh.typ] + " " + Integer.toHexString(fh.subtype) + " " + fh.arg_from_name + " " + fh.arg + " $end"); break; default: System.out.println("$attrbegin " + fstAttrType.FST_AT_NAMESTRINGS[fh.typ] + " " + Integer.toHexString(fh.subtype) + " " + fh.name1 + " " + fh.arg + " $end"); break; } } break; case fstHierType.FST_HT_ATTREND: System.out.println("$attrend $end"); break; } } System.out.println("$enddefinitions $end"); fb.fstReaderSetFacProcessMaskAll(); prevTime = 0; fb.fstReaderIterBlocks(this); if(prevTime != endTime) { System.out.println("#" + endTime); } fb.fstReaderClose(); } } gtkwave-gtk3-3.3.125/contrib/fst_jni/fstReader.java0000664000175000017500000001573115047725113021403 0ustar bybellbybell/* * Copyright (c) 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. */ public class fstReader extends fstAPI { private long ctx; fstReader(String nam) { ctx = fstReaderOpen(nam); } protected void finalize() throws Throwable { try { fstReaderClose(ctx); } finally { super.finalize(); } } public void fstReaderClose() { fstReaderClose(ctx); ctx = 0; } public void fstReaderClrFacProcessMaskAll() { fstReaderClrFacProcessMaskAll(ctx); } public void fstReaderClrFacProcessMask(int facidx) { fstReaderClrFacProcessMask(ctx, facidx); } public long fstReaderGetAliasCount() { return(fstReaderGetAliasCount(ctx)); } public String fstReaderGetCurrentFlatScope() { return(fstReaderGetCurrentFlatScope(ctx)); } public int fstReaderGetCurrentScopeLen() { return(fstReaderGetCurrentScopeLen(ctx)); } public int fstReaderGetFileType() { return(fstReaderGetFileType(ctx)); } public String fstReaderGetCurrentScopeUserInfo() { return(fstReaderGetCurrentScopeUserInfo(ctx)); } public String fstReaderGetDateString() { return(fstReaderGetDateString(ctx)); } public long fstReaderGetDumpActivityChangeTime(int idx) { return(fstReaderGetDumpActivityChangeTime(ctx, idx)); } public boolean fstReaderGetDumpActivityChangeValue(int idx) { return(fstReaderGetDumpActivityChangeValue(ctx, idx)); } public long fstReaderGetEndTime() { return(fstReaderGetEndTime(ctx)); } public boolean fstReaderGetFacProcessMask(int facidx) { return(fstReaderGetFacProcessMask(ctx, facidx)); } public boolean fstReaderGetFseekFailed() { return(fstReaderGetFseekFailed(ctx)); } public int fstReaderGetMaxHandle() { return(fstReaderGetMaxHandle(ctx)); } public long fstReaderGetMemoryUsedByWriter() { return(fstReaderGetMemoryUsedByWriter(ctx)); } public int fstReaderGetNumberDumpActivityChanges() { return(fstReaderGetNumberDumpActivityChanges(ctx)); } public long fstReaderGetScopeCount() { return(fstReaderGetScopeCount(ctx)); } public long fstReaderGetStartTime() { return(fstReaderGetStartTime(ctx)); } public int fstReaderGetTimescale() { return(fstReaderGetTimescale(ctx)); } public long fstReaderGetTimezero() { return(fstReaderGetTimezero(ctx)); } public long fstReaderGetValueChangeSectionCount() { return(fstReaderGetValueChangeSectionCount(ctx)); } public String fstReaderGetValueFromHandleAtTime(long tim, int facidx) { return(fstReaderGetValueFromHandleAtTime(ctx, tim, facidx)); } public long fstReaderGetVarCount() { return(fstReaderGetVarCount(ctx)); } public String fstReaderGetVersionString() { return(fstReaderGetVersionString(ctx)); } public void fstReaderIterateHier(fstHier fh) { fstReaderIterateHier(ctx, fh); } public boolean fstReaderIterateHierRewind() { return(fstReaderIterateHierRewind(ctx)); } public int fstReaderIterBlocks(Object cbobj) { return(fstReaderIterBlocks(ctx, cbobj)); } public String fstReaderPopScope() { return(fstReaderPopScope(ctx)); } public String fstReaderPushScope(String nam, long user_info) { return(fstReaderPushScope(ctx, nam, user_info)); } public void fstReaderResetScope() { fstReaderResetScope(ctx); } public void fstReaderSetFacProcessMaskAll() { fstReaderSetFacProcessMaskAll(ctx); } public void fstReaderSetFacProcessMask(int facidx) { fstReaderSetFacProcessMask(ctx, facidx); } public void fstReaderSetVcdExtensions(boolean enable) { fstReaderSetVcdExtensions(ctx, enable); } public void fstReaderSetLimitTimeRange(long start_time, long end_time) { fstReaderSetLimitTimeRange(ctx, start_time, end_time); } public void fstReaderSetUnlimitedTimeRange() { fstReaderSetUnlimitedTimeRange(ctx); } public String fstReaderVcdID(int value) { char []s = new char[5]; // 94 ** 5 int vmod; int i; // zero is illegal for a value...it is assumed they start at one for(i=0;;i++) { vmod = (value % 94); if(vmod != 0) { s[i] = (char) (vmod+32); } else { s[i] = '~'; value -= 94; } value = value / 94; if(value == 0) { break; } } return(new String(s, 0, i+1)); } public String fstReaderGetTimescaleString() { int ts = fstReaderGetTimescale(); int time_scale = 1; char time_dimension; String s; switch(ts) { case 2: time_scale = 100; time_dimension = ' '; break; case 1: time_scale = 10; case 0: time_dimension = ' '; 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 -16: time_scale = 100; time_dimension = 'a'; break; case -17: time_scale = 10; case -18: time_dimension = 'a'; break; case -19: time_scale = 100; time_dimension = 'z'; break; case -20: time_scale = 10; case -21: time_dimension = 'z'; break; case -7: time_scale = 100; time_dimension = 'n'; break; case -8: time_scale = 10; case -9: default: time_dimension = 'n'; break; } s = "" + time_scale; s = s + time_dimension; return(s); } } gtkwave-gtk3-3.3.125/contrib/fst_jni/fstEnumValueType.java0000664000175000017500000000426215047725113022741 0ustar bybellbybell/* * Copyright (c) 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. */ public class fstEnumValueType { private fstEnumValueType() { } public static final String [] FST_VT_NAMESTRINGS = { "integer", "bit", "logic", "int", "shortint", "longint", "byte", "unsigned_integer", "unsigned_bit", "unsigned_logic", "unsigned_int", "unsigned_shortint", "unsigned_longint", "unsigned_byte" }; public static final int FST_EV_MIN = 0; public static final int FST_EV_SV_INTEGER = 0; public static final int FST_EV_SV_BIT = 1; public static final int FST_EV_SV_LOGIC = 2; public static final int FST_EV_SV_INT = 3; public static final int FST_EV_SV_SHORTINT = 4; public static final int FST_EV_SV_LONGINT = 5; public static final int FST_EV_SV_BYTE = 6; public static final int FST_EV_SV_UNSIGNED_INTEGER = 7; public static final int FST_EV_SV_UNSIGNED_BIT = 8; public static final int FST_EV_SV_UNSIGNED_LOGIC = 9; public static final int FST_EV_SV_UNSIGNED_INT = 10; public static final int FST_EV_SV_UNSIGNED_SHORTINT = 11; public static final int FST_EV_SV_UNSIGNED_LONGINT = 12; public static final int FST_EV_SV_UNSIGNED_BYTE = 13; public static final int FST_EV_MAX = 13; }; gtkwave-gtk3-3.3.125/contrib/fst_jni/fstSupplementalDataType.java0000664000175000017500000000502215047725113024276 0ustar bybellbybell/* * Copyright (c) 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. */ public class fstSupplementalDataType { fstSupplementalDataType( ) { } public static final int FST_SDT_MIN = 0; public static final int FST_SDT_NONE = 0; public static final int FST_SDT_VHDL_BOOLEAN = 1; public static final int FST_SDT_VHDL_BIT = 2; public static final int FST_SDT_VHDL_BIT_VECTOR = 3; public static final int FST_SDT_VHDL_STD_ULOGIC = 4; public static final int FST_SDT_VHDL_STD_ULOGIC_VECTOR = 5; public static final int FST_SDT_VHDL_STD_LOGIC = 6; public static final int FST_SDT_VHDL_STD_LOGIC_VECTOR = 7; public static final int FST_SDT_VHDL_UNSIGNED = 8; public static final int FST_SDT_VHDL_SIGNED = 9; public static final int FST_SDT_VHDL_INTEGER = 10; public static final int FST_SDT_VHDL_REAL = 11; public static final int FST_SDT_VHDL_NATURAL = 12; public static final int FST_SDT_VHDL_POSITIVE = 13; public static final int FST_SDT_VHDL_TIME = 14; public static final int FST_SDT_VHDL_CHARACTER = 15; public static final int FST_SDT_VHDL_STRING = 16; public static final int FST_SDT_MAX = 16; public static final int FST_SDT_SVT_SHIFT_COUNT = 10; /* FST_SVT_* is ORed in to the left after shifting FST_SDT_SVT_SHIFT_COUNT */ public static final int FST_SDT_ABS_MAX = (1<<(FST_SDT_SVT_SHIFT_COUNT)); }; gtkwave-gtk3-3.3.125/contrib/fst_jni/Main.java0000664000175000017500000000246115047725113020344 0ustar bybellbybell/* * Copyright (c) 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. */ public class Main { public static void main(String[] argv) { if(argv.length == 1) { fst2Vcd t = new fst2Vcd(argv[0]); } else { System.out.println("Usage\n-----\njava Main inputfile.fst"); } } } gtkwave-gtk3-3.3.125/contrib/fst_jni/fstAPI.java0000664000175000017500000001466615047725113020620 0ustar bybellbybell/* * Copyright (c) 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. */ public class fstAPI { static { System.loadLibrary("fstAPI"); } private static String bitStringInt(int i, int len) { len = Math.min(32, Math.max(len, 1)); char[] cs = new char[len]; for (int j = len - 1, b = 1; 0 <= j; --j, b <<= 1) { cs[j] = ((i & b) == 0) ? '0' : '1'; } return(new String(cs)); } protected native long fstWriterCreate(String nam, boolean use_compressed_hier); protected native void fstWriterClose(long ctx); protected native boolean fstWriterGetFseekFailed(long ctx); protected native boolean fstWriterGetDumpSizeLimitReached(long ctx); protected native void fstWriterFlushContext(long ctx); protected native void fstWriterSetUpscope(long ctx); protected native void fstWriterSetAttrEnd(long ctx); protected native void fstWriterSetPackType(long ctx, int typ); protected native void fstWriterSetFileType(long ctx, int typ); protected native void fstWriterSetRepackOnClose(long ctx, boolean enable); protected native void fstWriterSetParallelMode(long ctx, boolean enable); protected native void fstWriterSetTimescale(long ctx, int ts); protected native void fstWriterSetTimezero(long ctx, long tim); protected native void fstWriterSetDumpSizeLimit(long ctx, long numbytes); protected native void fstWriterEmitDumpActive(long ctx, boolean enable); protected native void fstWriterEmitTimeChange(long ctx, long tim); protected native void fstWriterSetDate(long ctx, String dat); protected native void fstWriterSetVersion(long ctx, String vers); protected native void fstWriterSetComment(long ctx, String comm); protected native void fstWriterSetEnvVar(long ctx, String envvar); protected native void fstWriterSetTimescaleFromString(long ctx, String s); protected native int fstWriterCreateVar(long ctx, int vt, int vd, int len, String nam, int aliasHandle); protected native int fstWriterCreateVar2(long ctx, int vt, int vd, int len, String nam, int aliasHandle, String type, int svt, int sdt); protected native void fstWriterSetSourceStem(long ctx, String path, int line, boolean use_realpath); protected native void fstWriterSetSourceInstantiationStem(long ctx, String path, int line, boolean use_realpath); protected native void fstWriterSetScope(long ctx, int scopetype, String scopename, String scopecomp); protected native void fstWriterEmitVariableLengthValueChange(long ctx, int handle, String val, int len); protected native void fstWriterSetAttrBegin(long ctx, int attrtype, int subtype, String attrname, long arg); protected native void fstWriterEmitValueChange(long ctx, int handle, String val); protected native void fstWriterEmitValueChange(long ctx, int handle, double val); protected void fstWriterEmitValueChange(long ctx, int handle, int val) { fstWriterEmitValueChange(ctx, handle, bitStringInt(val, 32)); } protected native long fstReaderOpen(String nam); protected native long fstReaderOpenForUtilitiesOnly(); protected native void fstReaderClose(long ctx); protected native boolean fstReaderIterateHierRewind(long ctx); protected native void fstReaderResetScope(long ctx); protected native int fstReaderGetCurrentScopeLen(long ctx); protected native int fstReaderGetFileType(long ctx); protected native long fstReaderGetTimezero(long ctx); protected native long fstReaderGetStartTime(long ctx); protected native long fstReaderGetEndTime(long ctx); protected native long fstReaderGetMemoryUsedByWriter(long ctx); protected native long fstReaderGetScopeCount(long ctx); protected native long fstReaderGetVarCount(long ctx); protected native int fstReaderGetMaxHandle(long ctx); protected native long fstReaderGetAliasCount(long ctx); protected native long fstReaderGetValueChangeSectionCount(long ctx); protected native boolean fstReaderGetFseekFailed(long ctx); protected native void fstReaderSetUnlimitedTimeRange(long ctx); protected native void fstReaderSetLimitTimeRange(long ctx, long start_time, long end_time); protected native void fstReaderSetVcdExtensions(long ctx, boolean enable); protected native int fstReaderGetNumberDumpActivityChanges(long ctx); protected native long fstReaderGetDumpActivityChangeTime(long ctx, int idx); protected native boolean fstReaderGetFacProcessMask(long ctx, int facidx); protected native void fstReaderSetFacProcessMask(long ctx, int facidx); protected native void fstReaderClrFacProcessMask(long ctx, int facidx); protected native void fstReaderSetFacProcessMaskAll(long ctx); protected native void fstReaderClrFacProcessMaskAll(long ctx); protected native String fstReaderGetVersionString(long ctx); protected native String fstReaderGetDateString(long ctx); protected native String fstReaderPopScope(long ctx); protected native String fstReaderGetCurrentFlatScope(long ctx); protected native String fstReaderGetCurrentScopeUserInfo(long ctx); protected native String fstReaderPushScope(long ctx, String nam, long user_info); protected native int fstReaderGetTimescale(long ctx); protected native boolean fstReaderGetDumpActivityChangeValue(long ctx, int idx); protected native String fstReaderGetValueFromHandleAtTime(long ctx, long tim, int facidx); protected native void fstReaderIterateHier(long ctx, fstHier fh); protected native int fstReaderIterBlocks(long ctx, Object cbobj); public native static String fstUtilityBinToEsc(byte []s, int len); public native static byte[] fstUtilityEscToBin(String s); // // example do-nothing callback for fstReaderIterateHier() // public void fstReaderCallback(long tim, int facidx, String value) { } } gtkwave-gtk3-3.3.125/contrib/fst_jni/fstAPI.c0000664000175000017500000005150015047725113020105 0ustar bybellbybell/* * Copyright (c) 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 #include "fstapi.h" /* * fstWriter */ JNIEXPORT jlong JNICALL Java_fstAPI_fstWriterCreate (JNIEnv *env, jobject obj, jstring j_nam, jboolean use_compressed_hier) { void *ctx; const char *nam = (*env)->GetStringUTFChars(env, j_nam, 0); ctx = fstWriterCreate(nam, (int)use_compressed_hier); (*env)->ReleaseStringUTFChars(env, j_nam, nam); return((jlong)(long)ctx); } JNIEXPORT void JNICALL Java_fstAPI_fstWriterClose (JNIEnv *env, jobject obj, jlong ctx) { fstWriterClose((void *)(long)ctx); } JNIEXPORT jboolean JNICALL Java_fstAPI_fstWriterGetFseekFailed (JNIEnv *env, jobject obj, jlong ctx) { int rc = fstWriterGetFseekFailed((void *)(long)ctx); return(rc != 0); } JNIEXPORT jboolean JNICALL Java_fstAPI_fstWriterGetDumpSizeLimitReached (JNIEnv *env, jobject obj, jlong ctx) { int rc = fstWriterGetDumpSizeLimitReached((void *)(long)ctx); return(rc != 0); } JNIEXPORT void JNICALL Java_fstAPI_fstWriterFlushContext (JNIEnv *env, jobject obj, jlong ctx) { fstWriterFlushContext((void *)(long)ctx); } JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetUpscope (JNIEnv *env, jobject obj, jlong ctx) { fstWriterSetUpscope((void *)(long)ctx); } JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetAttrEnd (JNIEnv *env, jobject obj, jlong ctx) { fstWriterSetAttrEnd((void *)(long)ctx); } JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetPackType (JNIEnv *env, jobject obj, jlong ctx, jint typ) { fstWriterSetPackType((void *)(long)ctx, (int)typ); } JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetFileType (JNIEnv *env, jobject obj, jlong ctx, jint typ) { fstWriterSetFileType((void *)(long)ctx, (int)typ); } JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetRepackOnClose (JNIEnv *env, jobject obj, jlong ctx, jboolean enable) { fstWriterSetRepackOnClose((void *)(long)ctx, (int)enable); } JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetParallelMode (JNIEnv *env, jobject obj, jlong ctx, jboolean enable) { fstWriterSetParallelMode((void *)(long)ctx, (int)enable); } JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetTimescale (JNIEnv *env, jobject obj, jlong ctx, jint ts) { fstWriterSetParallelMode((void *)(long)ctx, (int)ts); } JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetTimezero (JNIEnv *env, jobject obj, jlong ctx, jlong tim) { fstWriterSetTimezero((void *)(long)ctx, (int64_t)tim); } JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetDumpSizeLimit (JNIEnv *env, jobject obj, jlong ctx, jlong numbytes) { fstWriterSetDumpSizeLimit((void *)(long)ctx, (uint64_t)numbytes); } JNIEXPORT void JNICALL Java_fstAPI_fstWriterEmitDumpActive (JNIEnv *env, jobject obj, jlong ctx, jboolean enable) { fstWriterEmitDumpActive((void *)(long)ctx, (int)enable); } JNIEXPORT void JNICALL Java_fstAPI_fstWriterEmitTimeChange (JNIEnv *env, jobject obj, jlong ctx, jlong tim) { fstWriterEmitTimeChange((void *)(long)ctx, (uint64_t)tim); } JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetDate (JNIEnv *env, jobject obj, jlong ctx, jstring j_dat) { const char *dat = (*env)->GetStringUTFChars(env, j_dat, 0); fstWriterSetDate((void *)(long)ctx, dat); (*env)->ReleaseStringUTFChars(env, j_dat, dat); } JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetVersion (JNIEnv *env, jobject obj, jlong ctx, jstring j_vers) { const char *vers = (*env)->GetStringUTFChars(env, j_vers, 0); fstWriterSetVersion((void *)(long)ctx, vers); (*env)->ReleaseStringUTFChars(env, j_vers, vers); } JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetComment (JNIEnv *env, jobject obj, jlong ctx, jstring j_comm) { const char *comm = (*env)->GetStringUTFChars(env, j_comm, 0); fstWriterSetComment((void *)(long)ctx, comm); (*env)->ReleaseStringUTFChars(env, j_comm, comm); } JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetEnvVar (JNIEnv *env, jobject obj, jlong ctx, jstring j_envvar) { const char *envvar = (*env)->GetStringUTFChars(env, j_envvar, 0); fstWriterSetEnvVar((void *)(long)ctx, envvar); (*env)->ReleaseStringUTFChars(env, j_envvar, envvar); } JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetTimescaleFromString (JNIEnv *env, jobject obj, jlong ctx, jstring j_s) { const char *s = (*env)->GetStringUTFChars(env, j_s, 0); fstWriterSetTimescaleFromString((void *)(long)ctx, s); (*env)->ReleaseStringUTFChars(env, j_s, s); } JNIEXPORT void JNICALL Java_fstAPI_fstWriterEmitValueChange__JILjava_lang_String_2 (JNIEnv *env, jobject obj, jlong ctx, jint handle, jstring j_val) { const char *val = (*env)->GetStringUTFChars(env, j_val, 0); fstWriterEmitValueChange((void *)(long)ctx, (fstHandle)handle, val); (*env)->ReleaseStringUTFChars(env, j_val, val); } JNIEXPORT void JNICALL Java_fstAPI_fstWriterEmitValueChange__JID (JNIEnv *env, jobject obj, jlong ctx, jint handle, jdouble d) { fstWriterEmitValueChange((void *)(long)ctx, (fstHandle)handle, (void *)&d); } JNIEXPORT jint JNICALL Java_fstAPI_fstWriterCreateVar (JNIEnv *env, jobject obj, jlong ctx, jint vt, jint vd, jint len, jstring j_nam, jint aliasHandle) { fstHandle handle; const char *nam = (*env)->GetStringUTFChars(env, j_nam, 0); handle = fstWriterCreateVar((void *)(long)ctx, (int)vt, (int)vd, (uint32_t)len, nam, (fstHandle)aliasHandle); (*env)->ReleaseStringUTFChars(env, j_nam, nam); return((jint)handle); } JNIEXPORT jint JNICALL Java_fstAPI_fstWriterCreateVar2 (JNIEnv *env, jobject obj, jlong ctx, jint vt, jint vd, jint len, jstring j_nam, jint aliasHandle, jstring j_type, jint svt, jint sdt) { fstHandle handle; const char *nam = (*env)->GetStringUTFChars(env, j_nam, 0); const char *typ = (*env)->GetStringUTFChars(env, j_type, 0); handle = fstWriterCreateVar2((void *)(long)ctx, (int)vt, (int)vd, (uint32_t)len, nam, (fstHandle)aliasHandle, typ, (int)svt, (int)sdt); (*env)->ReleaseStringUTFChars(env, j_type, typ); (*env)->ReleaseStringUTFChars(env, j_nam, nam); return((jint)handle); } JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetSourceStem (JNIEnv *env, jobject obj, jlong ctx, jstring j_path, jint line, jboolean use_realpath) { const char *path = (*env)->GetStringUTFChars(env, j_path, 0); fstWriterSetSourceStem((void *)(long)ctx, path, line, use_realpath); (*env)->ReleaseStringUTFChars(env, j_path, path); } JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetSourceInstantiationStem (JNIEnv *env, jobject obj, jlong ctx, jstring j_path, jint line, jboolean use_realpath) { const char *path = (*env)->GetStringUTFChars(env, j_path, 0); fstWriterSetSourceInstantiationStem((void *)(long)ctx, path, line, use_realpath); (*env)->ReleaseStringUTFChars(env, j_path, path); } JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetScope (JNIEnv *env, jobject obj, jlong ctx, jint scopetype, jstring j_scopename, jstring j_scopecomp) { const char *scopename = (*env)->GetStringUTFChars(env, j_scopename, 0); const char *scopecomp = (*env)->GetStringUTFChars(env, j_scopecomp, 0); fstWriterSetScope((void *)(long)ctx, (int)scopetype, scopename, scopecomp); (*env)->ReleaseStringUTFChars(env, j_scopecomp, scopecomp); (*env)->ReleaseStringUTFChars(env, j_scopename, scopename); } JNIEXPORT void JNICALL Java_fstAPI_fstWriterEmitVariableLengthValueChange (JNIEnv *env, jobject obj, jlong ctx, jint handle, jstring j_val, jint len) { const char *val = (*env)->GetStringUTFChars(env, j_val, 0); fstWriterEmitVariableLengthValueChange((void *)(long)ctx, (fstHandle)handle, val, (uint32_t)len); (*env)->ReleaseStringUTFChars(env, j_val, val); } JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetAttrBegin (JNIEnv *env, jobject obj, jlong ctx, jint attrtype, jint subtype, jstring j_attrname, jlong arg) { const char *attrname = (*env)->GetStringUTFChars(env, j_attrname, 0); fstWriterSetAttrBegin((void *)(long)ctx, (int)attrtype, (int)subtype, attrname, (uint64_t)arg); (*env)->ReleaseStringUTFChars(env, j_attrname, attrname); } /* * fstReader */ JNIEXPORT jlong JNICALL Java_fstAPI_fstReaderOpen (JNIEnv *env, jobject obj, jstring j_nam) { void *ctx; const char *nam = (*env)->GetStringUTFChars(env, j_nam, 0); ctx = fstReaderOpen(nam); (*env)->ReleaseStringUTFChars(env, j_nam, nam); return((jlong)(long)ctx); } JNIEXPORT jlong JNICALL Java_fstAPI_fstReaderOpenForUtilitiesOnly (JNIEnv *env, jobject obj) { void *ctx; ctx = fstReaderOpenForUtilitiesOnly(); return((jlong)(long)ctx); } JNIEXPORT void JNICALL Java_fstAPI_fstReaderClose (JNIEnv *env, jobject obj, jlong ctx) { fstReaderClose((void *)(long)ctx); } JNIEXPORT jboolean JNICALL Java_fstAPI_fstReaderIterateHierRewind (JNIEnv *env, jobject obj, jlong ctx) { return((jboolean)(fstReaderIterateHierRewind((void *)(long)ctx) != 0)); } JNIEXPORT void JNICALL Java_fstAPI_fstReaderResetScope (JNIEnv *env, jobject obj, jlong ctx) { fstReaderResetScope((void *)(long)ctx); } JNIEXPORT jint JNICALL Java_fstAPI_fstReaderGetCurrentScopeLen (JNIEnv *env, jobject obj, jlong ctx) { return((jint)fstReaderGetCurrentScopeLen((void *)(long)ctx)); } JNIEXPORT jint JNICALL Java_fstAPI_fstReaderGetFileType (JNIEnv *env, jobject obj, jlong ctx) { return((jint)fstReaderGetFileType((void *)(long)ctx)); } JNIEXPORT jlong JNICALL Java_fstAPI_fstReaderGetTimezero (JNIEnv *env, jobject obj, jlong ctx) { return((jlong)fstReaderGetTimezero((void *)(long)ctx)); } JNIEXPORT jlong JNICALL Java_fstAPI_fstReaderGetStartTime (JNIEnv *env, jobject obj, jlong ctx) { return((jlong)fstReaderGetStartTime((void *)(long)ctx)); } JNIEXPORT jlong JNICALL Java_fstAPI_fstReaderGetEndTime (JNIEnv *env, jobject obj, jlong ctx) { return((jlong)fstReaderGetEndTime((void *)(long)ctx)); } JNIEXPORT jlong JNICALL Java_fstAPI_fstReaderGetMemoryUsedByWriter (JNIEnv *env, jobject obj, jlong ctx) { return((jlong)fstReaderGetMemoryUsedByWriter((void *)(long)ctx)); } JNIEXPORT jlong JNICALL Java_fstAPI_fstReaderGetScopeCount (JNIEnv *env, jobject obj, jlong ctx) { return((jlong)fstReaderGetScopeCount((void *)(long)ctx)); } JNIEXPORT jlong JNICALL Java_fstAPI_fstReaderGetVarCount (JNIEnv *env, jobject obj, jlong ctx) { return((jlong)fstReaderGetVarCount((void *)(long)ctx)); } JNIEXPORT jint JNICALL Java_fstAPI_fstReaderGetMaxHandle (JNIEnv *env, jobject obj, jlong ctx) { return((jint)fstReaderGetMaxHandle((void *)(long)ctx)); } JNIEXPORT jlong JNICALL Java_fstAPI_fstReaderGetAliasCount (JNIEnv *env, jobject obj, jlong ctx) { return((jlong)fstReaderGetAliasCount((void *)(long)ctx)); } JNIEXPORT jlong JNICALL Java_fstAPI_fstReaderGetValueChangeSectionCount (JNIEnv *env, jobject obj, jlong ctx) { return((jlong)fstReaderGetValueChangeSectionCount((void *)(long)ctx)); } JNIEXPORT jboolean JNICALL Java_fstAPI_fstReaderGetFseekFailed (JNIEnv *env, jobject obj, jlong ctx) { return((jboolean)(fstReaderGetFseekFailed((void *)(long)ctx) != 0)); } JNIEXPORT void JNICALL Java_fstAPI_fstReaderSetUnlimitedTimeRange (JNIEnv *env, jobject obj, jlong ctx) { fstReaderSetUnlimitedTimeRange((void *)(long)ctx); } JNIEXPORT void JNICALL Java_fstAPI_fstReaderSetLimitTimeRange (JNIEnv *env, jobject obj, jlong ctx, jlong start_time, jlong end_time) { fstReaderSetLimitTimeRange((void *)(long)ctx, (uint64_t)start_time, (uint64_t)end_time); } JNIEXPORT void JNICALL Java_fstAPI_fstReaderSetVcdExtensions (JNIEnv *env, jobject obj, jlong ctx, jboolean enable) { fstReaderSetVcdExtensions((void *)(long)ctx, (int)enable); } JNIEXPORT jint JNICALL Java_fstAPI_fstReaderGetNumberDumpActivityChanges (JNIEnv *env, jobject obj, jlong ctx) { return((jint)fstReaderGetNumberDumpActivityChanges((void *)(long)ctx)); } JNIEXPORT jlong JNICALL Java_fstAPI_fstReaderGetDumpActivityChangeTime (JNIEnv *env, jobject obj, jlong ctx, jint idx) { return((jlong)fstReaderGetDumpActivityChangeTime((void *)(long)ctx, (uint32_t)idx)); } JNIEXPORT jboolean JNICALL Java_fstAPI_fstReaderGetFacProcessMask (JNIEnv *env, jobject obj, jlong ctx, jint facidx) { return((jboolean)(fstReaderGetFacProcessMask((void *)(long)ctx, (fstHandle)facidx) != 0)); } JNIEXPORT void JNICALL Java_fstAPI_fstReaderSetFacProcessMask (JNIEnv *env, jobject obj, jlong ctx, jint facidx) { fstReaderSetFacProcessMask((void *)(long)ctx, (fstHandle)facidx); } JNIEXPORT void JNICALL Java_fstAPI_fstReaderClrFacProcessMask (JNIEnv *env, jobject obj, jlong ctx, jint facidx) { fstReaderClrFacProcessMask((void *)(long)ctx, (fstHandle)facidx); } JNIEXPORT void JNICALL Java_fstAPI_fstReaderSetFacProcessMaskAll (JNIEnv *env, jobject obj, jlong ctx) { fstReaderSetFacProcessMaskAll((void *)(long)ctx); } JNIEXPORT void JNICALL Java_fstAPI_fstReaderClrFacProcessMaskAll (JNIEnv *env, jobject obj, jlong ctx) { fstReaderClrFacProcessMaskAll((void *)(long)ctx); } JNIEXPORT jstring JNICALL Java_fstAPI_fstReaderGetVersionString (JNIEnv *env, jobject obj, jlong ctx) { const char *s = fstReaderGetVersionString((void *)(long)ctx); jstring j_s = (*env)->NewStringUTF(env, s); return(j_s); } JNIEXPORT jstring JNICALL Java_fstAPI_fstReaderGetDateString (JNIEnv *env, jobject obj, jlong ctx) { const char *s = fstReaderGetDateString((void *)(long)ctx); jstring j_s = (*env)->NewStringUTF(env, s); return(j_s); } JNIEXPORT jstring JNICALL Java_fstAPI_fstReaderPopScope (JNIEnv *env, jobject obj, jlong ctx) { const char *s = fstReaderPopScope((void *)(long)ctx); jstring j_s = (*env)->NewStringUTF(env, s); return(j_s); } JNIEXPORT jstring JNICALL Java_fstAPI_fstReaderGetCurrentFlatScope (JNIEnv *env, jobject obj, jlong ctx) { const char *s = fstReaderGetCurrentFlatScope((void *)(long)ctx); jstring j_s = (*env)->NewStringUTF(env, s); return(j_s); } JNIEXPORT jstring JNICALL Java_fstAPI_fstReaderGetCurrentScopeUserInfo (JNIEnv *env, jobject obj, jlong ctx) { const char *s = fstReaderGetCurrentScopeUserInfo((void *)(long)ctx); jstring j_s = (*env)->NewStringUTF(env, s); return(j_s); } JNIEXPORT jstring JNICALL Java_fstAPI_fstReaderPushScope (JNIEnv *env, jobject obj, jlong ctx, jstring j_nam, jlong user_info) { const char *nam = (*env)->GetStringUTFChars(env, j_nam, 0); const char *s = fstReaderPushScope((void *)(long)ctx, nam, (void *)(long)user_info); jstring j_s = (*env)->NewStringUTF(env, s); (*env)->ReleaseStringUTFChars(env, j_nam, nam); return(j_s); } JNIEXPORT jint JNICALL Java_fstAPI_fstReaderGetTimescale (JNIEnv *env, jobject obj, jlong ctx) { return((jint)fstReaderGetTimescale((void *)(long)ctx)); } JNIEXPORT jboolean JNICALL Java_fstAPI_fstReaderGetDumpActivityChangeValue (JNIEnv *env, jobject obj, jlong ctx, jint idx) { return((jboolean)(fstReaderGetDumpActivityChangeValue((void *)(long)ctx, (uint32_t)idx) != 0)); } JNIEXPORT jstring JNICALL Java_fstAPI_fstReaderGetValueFromHandleAtTime (JNIEnv *env, jobject obj, jlong ctx, jlong tim, jint facidx) { char buf[65537]; const char *s = fstReaderGetValueFromHandleAtTime((void *)(long)ctx, (uint64_t)tim, (fstHandle)facidx, buf); jstring j_s = (*env)->NewStringUTF(env, s); return(j_s); } JNIEXPORT jstring JNICALL Java_fstAPI_fstUtilityBinToEsc (JNIEnv *env, jclass obj, jbyteArray b_s, jint len) { jbyte* s = (*env)->GetByteArrayElements(env, b_s,NULL); char *d = malloc(len * 4); jstring j_d; int i; int rlen; d[0] = 0; rlen = fstUtilityBinToEsc(d, s, (int)len); d[rlen] = 0; j_d = (*env)->NewStringUTF(env, d); free(d); (*env)->ReleaseByteArrayElements(env, b_s, s, 0); return(j_d); } JNIEXPORT jbyteArray JNICALL Java_fstAPI_fstUtilityEscToBin (JNIEnv *env, jclass obj, jstring j_s) { const char *s = (*env)->GetStringUTFChars(env, j_s, 0); char *d = strdup(s); int len = strlen(s); jbyteArray result; int rlen = fstUtilityEscToBin(d, d, len); (*env)->ReleaseStringUTFChars(env, j_s, s); result=(*env)->NewByteArray(env, rlen); (*env)->SetByteArrayRegion(env, result, 0, rlen, d); free(d); return(result); } JNIEXPORT void JNICALL Java_fstAPI_fstReaderIterateHier (JNIEnv *env, jobject obj, jlong ctx, jobject obj2) { struct fstHier *fh = fstReaderIterateHier((void *)(long)ctx); jclass javaDataClass = (*env)->FindClass(env, "fstHier"); jfieldID validField = (*env)->GetFieldID(env, javaDataClass, "valid", "Z"); jfieldID htypField = (*env)->GetFieldID(env, javaDataClass, "htyp", "I"); jfieldID typField = (*env)->GetFieldID(env, javaDataClass, "typ", "I"); jfieldID subtypeField; jfieldID directionField; jfieldID lengthField; jfieldID handleField; jfieldID name1Field; jfieldID name2Field; jfieldID argField; jfieldID arg_from_nameField; jfieldID isAliasField; jstring j_name1; jstring j_name2; (*env)->SetBooleanField(env, obj2, validField, (fh != NULL)); if(fh) { (*env)->SetIntField(env, obj2, htypField, fh->htyp); switch(fh->htyp) { case FST_HT_SCOPE: (*env)->SetIntField(env, obj2, typField, fh->u.scope.typ); j_name1 = (*env)->NewStringUTF(env, fh->u.scope.name); name1Field = (*env)->GetFieldID(env, javaDataClass, "name1", "Ljava/lang/String;"); (*env)->SetObjectField(env, obj2, name1Field, j_name1); j_name2 = (*env)->NewStringUTF(env, fh->u.scope.component); name2Field = (*env)->GetFieldID(env, javaDataClass, "name2", "Ljava/lang/String;"); (*env)->SetObjectField(env, obj2, name2Field, j_name2); break; case FST_HT_UPSCOPE: (*env)->SetIntField(env, obj2, typField, FST_ST_VCD_UPSCOPE); break; case FST_HT_VAR: (*env)->SetIntField(env, obj2, typField, fh->u.var.typ); directionField = (*env)->GetFieldID(env, javaDataClass, "direction", "I"); (*env)->SetIntField(env, obj2, directionField, (jint)fh->u.var.direction); j_name1 = (*env)->NewStringUTF(env, fh->u.var.name); name1Field = (*env)->GetFieldID(env, javaDataClass, "name1", "Ljava/lang/String;"); (*env)->SetObjectField(env, obj2, name1Field, j_name1); lengthField = (*env)->GetFieldID(env, javaDataClass, "length", "I"); (*env)->SetIntField(env, obj2, lengthField, (jint)fh->u.var.length); handleField = (*env)->GetFieldID(env, javaDataClass, "handle", "I"); (*env)->SetIntField(env, obj2, handleField, (jint)fh->u.var.handle); isAliasField = (*env)->GetFieldID(env, javaDataClass, "is_alias", "Z"); (*env)->SetBooleanField(env, obj2, isAliasField, (jboolean)(fh->u.var.is_alias)); break; case FST_HT_ATTRBEGIN: (*env)->SetIntField(env, obj2, typField, fh->u.attr.typ); subtypeField = (*env)->GetFieldID(env, javaDataClass, "subtype", "I"); (*env)->SetIntField(env, obj2, subtypeField, fh->u.attr.subtype); j_name1 = (*env)->NewStringUTF(env, fh->u.attr.name); name1Field = (*env)->GetFieldID(env, javaDataClass, "name1", "Ljava/lang/String;"); (*env)->SetObjectField(env, obj2, name1Field, j_name1); argField = (*env)->GetFieldID(env, javaDataClass, "arg", "J"); (*env)->SetLongField(env, obj2, argField, fh->u.attr.arg); arg_from_nameField = (*env)->GetFieldID(env, javaDataClass, "arg_from_name", "J"); (*env)->SetLongField(env, obj2, arg_from_nameField, fh->u.attr.arg_from_name); break; case FST_HT_ATTREND: (*env)->SetIntField(env, obj2, typField, FST_ST_GEN_ATTREND); break; default: break; } } } struct jni_fstCB_t { JNIEnv *env; jobject obj; void *ctx; jobject cbobj; jclass cls; jmethodID mid; }; static void value_change_callback2(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value, uint32_t len) { struct jni_fstCB_t *jni = (struct jni_fstCB_t *)user_callback_data_pointer; jstring j_s = (*jni->env)->NewStringUTF(jni->env, value); (*jni->env)->CallVoidMethod(jni->env, jni->cbobj, jni->mid, (jlong)time, (jint)facidx, j_s); } static void value_change_callback(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value) { value_change_callback2(user_callback_data_pointer, time, facidx, value, 0); } JNIEXPORT jint JNICALL Java_fstAPI_fstReaderIterBlocks (JNIEnv *env, jobject obj, jlong ctx, jobject cbobj) { struct jni_fstCB_t cb; jint rc; jclass cls = (*env)->GetObjectClass(env, cbobj); jmethodID mid = (*env)->GetMethodID(env, cls, "fstReaderCallback", "(JILjava/lang/String;)V"); cb.env = env; cb.obj = obj; cb.ctx = (void *)(long)ctx; cb.cbobj = cbobj; cb.cls = cls; cb.mid = mid; rc = fstReaderIterBlocks2((void *)(long)ctx, value_change_callback, value_change_callback2, &cb, NULL); return(rc); } gtkwave-gtk3-3.3.125/contrib/fst_jni/fstScopeType.java0000664000175000017500000000554215047725113022113 0ustar bybellbybell/* * Copyright (c) 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. */ public class fstScopeType { private fstScopeType() { } public static final String [] FST_ST_NAMESTRINGS = { "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" }; public static final int FST_ST_MIN = 0; public static final int FST_ST_VCD_MODULE = 0; public static final int FST_ST_VCD_TASK = 1; public static final int FST_ST_VCD_FUNCTION = 2; public static final int FST_ST_VCD_BEGIN = 3; public static final int FST_ST_VCD_FORK = 4; public static final int FST_ST_VCD_GENERATE = 5; public static final int FST_ST_VCD_STRUCT = 6; public static final int FST_ST_VCD_UNION = 7; public static final int FST_ST_VCD_CLASS = 8; public static final int FST_ST_VCD_INTERFACE = 9; public static final int FST_ST_VCD_PACKAGE = 10; public static final int FST_ST_VCD_PROGRAM = 11; public static final int FST_ST_VHDL_ARCHITECTURE = 12; public static final int FST_ST_VHDL_PROCEDURE = 13; public static final int FST_ST_VHDL_FUNCTION = 14; public static final int FST_ST_VHDL_RECORD = 15; public static final int FST_ST_VHDL_PROCESS = 16; public static final int FST_ST_VHDL_BLOCK = 17; public static final int FST_ST_VHDL_FOR_GENERATE = 18; public static final int FST_ST_VHDL_IF_GENERATE = 19; public static final int FST_ST_VHDL_GENERATE = 20; public static final int FST_ST_VHDL_PACKAGE = 21; public static final int FST_ST_MAX = 21; public static final int FST_ST_GEN_ATTRBEGIN = 252; public static final int FST_ST_GEN_ATTREND = 253; public static final int FST_ST_VCD_SCOPE = 254; public static final int FST_ST_VCD_UPSCOPE = 255; }; gtkwave-gtk3-3.3.125/contrib/fst_jni/zzz_test.csh0000775000175000017500000000126315047725113021212 0ustar bybellbybell#!/bin/csh setenv LD_LIBRARY_PATH `pwd` javac \ fstAPI.java \ fstArrayType.java \ fstAttrType.java \ fstEnumValueType.java \ fstFileType.java \ fstHier.java \ fstHierType.java \ fstMiscType.java \ fstPackType.java \ fstScopeType.java \ fstSupplementalDataType.java \ fstSupplementalVarType.java \ fstVarDir.java \ fstVarType.java \ fstWriter.java \ fstWriterPackType.java \ fstReader.java javac \ fst2Vcd.java \ Main.java javah -jni fstAPI gcc -o libfstAPI.so -fPIC -shared -Wl,-soname,fstAPI.so fstAPI.c ../../src/helpers/fst/fstapi.c ../../src/helpers/fst/fastlz.c \ -I./ -I../../ -I../../src/helpers/fst/ -lz java Main /tmp/des.fst rm *.class rm libfstAPI.so gtkwave-gtk3-3.3.125/contrib/fst_jni/fstAttrType.java0000664000175000017500000000275415047725113021756 0ustar bybellbybell/* * Copyright (c) 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. */ public class fstAttrType { private fstAttrType( ) { } public static final String [] FST_AT_NAMESTRINGS = { "misc", "array", "enum", "class" }; public static final int FST_AT_MIN = 0; public static final int FST_AT_MISC = 0; public static final int FST_AT_ARRAY = 1; public static final int FST_AT_ENUM = 2; public static final int FST_AT_PACK = 3; public static final int FST_AT_MAX = 3; }; gtkwave-gtk3-3.3.125/contrib/fst_jni/Makefile.am0000664000175000017500000000071615047725113020652 0ustar bybellbybell## -*- makefile ## EXTRA_DIST= \ fst2Vcd.java \ fstAPI.c \ fstAPI.h \ fstAPI.java \ fstArrayType.java \ fstAttrType.java \ fstEnumValueType.java \ fstFileType.java \ fstHier.java \ fstHierType.java \ fstMiscType.java \ fstPackType.java \ fstReader.java \ fstScopeType.java \ fstSupplementalDataType.java \ fstSupplementalVarType.java \ fstVarDir.java \ fstVarType.java \ fstWriter.java \ fstWriterPackType.java \ Main.java \ zzz_test.csh gtkwave-gtk3-3.3.125/contrib/fst_jni/fstWriter.java0000664000175000017500000000765715047725113021465 0ustar bybellbybell/* * Copyright (c) 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. */ public class fstWriter extends fstAPI { private long ctx; fstWriter(String nam, boolean use_compressed_hier) { ctx = fstWriterCreate(nam, use_compressed_hier); } protected void finalize() throws Throwable { try { fstWriterClose(ctx); } finally { super.finalize(); } } public void fstWriterClose() { fstWriterClose(ctx); ctx = 0; } public int fstWriterCreateVar(int vt, int vd, int len, String nam, int aliasHandle) { return(fstWriterCreateVar(ctx, vt, vd, len, nam, aliasHandle)); } public void fstWriterEmitDumpActive(boolean enable) { fstWriterEmitDumpActive(ctx, enable); } public void fstWriterEmitTimeChange(long tim) { fstWriterEmitTimeChange(ctx, tim); } public void fstWriterEmitValueChange(int handle, double val) { fstWriterEmitValueChange(ctx, handle, val); } public void fstWriterEmitValueChange(int handle, int val) { fstWriterEmitValueChange(ctx, handle, val); } public void fstWriterEmitValueChange(int handle, String val) { fstWriterEmitValueChange(ctx, handle, val); } public void fstWriterEmitVariableLengthValueChange(int handle, String val, int len) { fstWriterEmitVariableLengthValueChange(ctx, handle, val, len); } public void fstWriterFlushContext() { fstWriterFlushContext(ctx); } public boolean fstWriterGetDumpSizeLimitReached() { return(fstWriterGetDumpSizeLimitReached(ctx)); } public boolean fstWriterGetFseekFailed() { return(fstWriterGetFseekFailed(ctx)); } public void fstWriterSetAttrBegin(int attrtype, int subtype, String attrname, long arg) { fstWriterSetAttrBegin(ctx, attrtype, subtype, attrname, arg); } public void fstWriterSetAttrEnd() { fstWriterSetAttrEnd(ctx); } public void fstWriterSetComment(String comm) { fstWriterSetComment(ctx, comm); } public void fstWriterSetDate(String dat) { fstWriterSetDate(ctx, dat); } public void fstWriterSetDumpSizeLimit(long numbytes) { fstWriterSetDumpSizeLimit(ctx, numbytes); } public void fstWriterSetEnvVar(String envvar) { fstWriterSetEnvVar(ctx, envvar); } public void fstWriterSetFileType(int typ) { fstWriterSetFileType(ctx, typ); } public void fstWriterSetPackType(int typ) { fstWriterSetPackType(ctx, typ); } public void fstWriterSetParallelMode(boolean enable) { fstWriterSetParallelMode(ctx, enable); } public void fstWriterSetRepackOnClose(boolean enable) { fstWriterSetRepackOnClose(ctx, enable); } public void fstWriterSetScope(int scopetype, String scopename, String scopecomp) { fstWriterSetScope(ctx, scopetype, scopename, scopecomp); } public void fstWriterSetTimescaleFromString(String s) { fstWriterSetTimescaleFromString(ctx, s); } public void fstWriterSetTimescale(int ts) { fstWriterSetTimescale(ctx, ts); } public void fstWriterSetTimezero(long tim) { fstWriterSetTimezero(ctx, tim); } public void fstWriterSetUpscope() { fstWriterSetUpscope(ctx); } public void fstWriterSetVersion(String vers) { fstWriterSetVersion(ctx, vers); } } gtkwave-gtk3-3.3.125/contrib/fst_jni/fstWriterPackType.java0000664000175000017500000000245115047725113023111 0ustar bybellbybell/* * Copyright (c) 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. */ public class fstWriterPackType { private fstWriterPackType( ) { } public static final int FST_WR_PT_ZLIB = 0; public static final int FST_WR_PT_FASTLZ = 1; public static final int FST_WR_PT_LZ4 = 2; }; gtkwave-gtk3-3.3.125/contrib/fst_jni/fstAPI.h0000664000175000017500000003252315047725113020116 0ustar bybellbybell/* DO NOT EDIT THIS FILE - it is machine generated */ #include /* Header for class fstAPI */ #ifndef _Included_fstAPI #define _Included_fstAPI #ifdef __cplusplus extern "C" { #endif /* * Class: fstAPI * Method: fstWriterCreate * Signature: (Ljava/lang/String;Z)J */ JNIEXPORT jlong JNICALL Java_fstAPI_fstWriterCreate (JNIEnv *, jobject, jstring, jboolean); /* * Class: fstAPI * Method: fstWriterClose * Signature: (J)V */ JNIEXPORT void JNICALL Java_fstAPI_fstWriterClose (JNIEnv *, jobject, jlong); /* * Class: fstAPI * Method: fstWriterGetFseekFailed * Signature: (J)Z */ JNIEXPORT jboolean JNICALL Java_fstAPI_fstWriterGetFseekFailed (JNIEnv *, jobject, jlong); /* * Class: fstAPI * Method: fstWriterGetDumpSizeLimitReached * Signature: (J)Z */ JNIEXPORT jboolean JNICALL Java_fstAPI_fstWriterGetDumpSizeLimitReached (JNIEnv *, jobject, jlong); /* * Class: fstAPI * Method: fstWriterFlushContext * Signature: (J)V */ JNIEXPORT void JNICALL Java_fstAPI_fstWriterFlushContext (JNIEnv *, jobject, jlong); /* * Class: fstAPI * Method: fstWriterSetUpscope * Signature: (J)V */ JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetUpscope (JNIEnv *, jobject, jlong); /* * Class: fstAPI * Method: fstWriterSetAttrEnd * Signature: (J)V */ JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetAttrEnd (JNIEnv *, jobject, jlong); /* * Class: fstAPI * Method: fstWriterSetPackType * Signature: (JI)V */ JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetPackType (JNIEnv *, jobject, jlong, jint); /* * Class: fstAPI * Method: fstWriterSetFileType * Signature: (JI)V */ JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetFileType (JNIEnv *, jobject, jlong, jint); /* * Class: fstAPI * Method: fstWriterSetRepackOnClose * Signature: (JZ)V */ JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetRepackOnClose (JNIEnv *, jobject, jlong, jboolean); /* * Class: fstAPI * Method: fstWriterSetParallelMode * Signature: (JZ)V */ JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetParallelMode (JNIEnv *, jobject, jlong, jboolean); /* * Class: fstAPI * Method: fstWriterSetTimescale * Signature: (JI)V */ JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetTimescale (JNIEnv *, jobject, jlong, jint); /* * Class: fstAPI * Method: fstWriterSetTimezero * Signature: (JJ)V */ JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetTimezero (JNIEnv *, jobject, jlong, jlong); /* * Class: fstAPI * Method: fstWriterSetDumpSizeLimit * Signature: (JJ)V */ JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetDumpSizeLimit (JNIEnv *, jobject, jlong, jlong); /* * Class: fstAPI * Method: fstWriterEmitDumpActive * Signature: (JZ)V */ JNIEXPORT void JNICALL Java_fstAPI_fstWriterEmitDumpActive (JNIEnv *, jobject, jlong, jboolean); /* * Class: fstAPI * Method: fstWriterEmitTimeChange * Signature: (JJ)V */ JNIEXPORT void JNICALL Java_fstAPI_fstWriterEmitTimeChange (JNIEnv *, jobject, jlong, jlong); /* * Class: fstAPI * Method: fstWriterSetDate * Signature: (JLjava/lang/String;)V */ JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetDate (JNIEnv *, jobject, jlong, jstring); /* * Class: fstAPI * Method: fstWriterSetVersion * Signature: (JLjava/lang/String;)V */ JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetVersion (JNIEnv *, jobject, jlong, jstring); /* * Class: fstAPI * Method: fstWriterSetComment * Signature: (JLjava/lang/String;)V */ JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetComment (JNIEnv *, jobject, jlong, jstring); /* * Class: fstAPI * Method: fstWriterSetEnvVar * Signature: (JLjava/lang/String;)V */ JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetEnvVar (JNIEnv *, jobject, jlong, jstring); /* * Class: fstAPI * Method: fstWriterSetTimescaleFromString * Signature: (JLjava/lang/String;)V */ JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetTimescaleFromString (JNIEnv *, jobject, jlong, jstring); /* * Class: fstAPI * Method: fstWriterCreateVar * Signature: (JIIILjava/lang/String;I)I */ JNIEXPORT jint JNICALL Java_fstAPI_fstWriterCreateVar (JNIEnv *, jobject, jlong, jint, jint, jint, jstring, jint); /* * Class: fstAPI * Method: fstWriterCreateVar2 * Signature: (JIIILjava/lang/String;ILjava/lang/String;II)I */ JNIEXPORT jint JNICALL Java_fstAPI_fstWriterCreateVar2 (JNIEnv *, jobject, jlong, jint, jint, jint, jstring, jint, jstring, jint, jint); /* * Class: fstAPI * Method: fstWriterSetSourceStem * Signature: (JLjava/lang/String;IZ)V */ JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetSourceStem (JNIEnv *, jobject, jlong, jstring, jint, jboolean); /* * Class: fstAPI * Method: fstWriterSetSourceInstantiationStem * Signature: (JLjava/lang/String;IZ)V */ JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetSourceInstantiationStem (JNIEnv *, jobject, jlong, jstring, jint, jboolean); /* * Class: fstAPI * Method: fstWriterSetScope * Signature: (JILjava/lang/String;Ljava/lang/String;)V */ JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetScope (JNIEnv *, jobject, jlong, jint, jstring, jstring); /* * Class: fstAPI * Method: fstWriterEmitVariableLengthValueChange * Signature: (JILjava/lang/String;I)V */ JNIEXPORT void JNICALL Java_fstAPI_fstWriterEmitVariableLengthValueChange (JNIEnv *, jobject, jlong, jint, jstring, jint); /* * Class: fstAPI * Method: fstWriterSetAttrBegin * Signature: (JIILjava/lang/String;J)V */ JNIEXPORT void JNICALL Java_fstAPI_fstWriterSetAttrBegin (JNIEnv *, jobject, jlong, jint, jint, jstring, jlong); /* * Class: fstAPI * Method: fstWriterEmitValueChange * Signature: (JILjava/lang/String;)V */ JNIEXPORT void JNICALL Java_fstAPI_fstWriterEmitValueChange__JILjava_lang_String_2 (JNIEnv *, jobject, jlong, jint, jstring); /* * Class: fstAPI * Method: fstWriterEmitValueChange * Signature: (JID)V */ JNIEXPORT void JNICALL Java_fstAPI_fstWriterEmitValueChange__JID (JNIEnv *, jobject, jlong, jint, jdouble); /* * Class: fstAPI * Method: fstReaderOpen * Signature: (Ljava/lang/String;)J */ JNIEXPORT jlong JNICALL Java_fstAPI_fstReaderOpen (JNIEnv *, jobject, jstring); /* * Class: fstAPI * Method: fstReaderOpenForUtilitiesOnly * Signature: ()J */ JNIEXPORT jlong JNICALL Java_fstAPI_fstReaderOpenForUtilitiesOnly (JNIEnv *, jobject); /* * Class: fstAPI * Method: fstReaderClose * Signature: (J)V */ JNIEXPORT void JNICALL Java_fstAPI_fstReaderClose (JNIEnv *, jobject, jlong); /* * Class: fstAPI * Method: fstReaderIterateHierRewind * Signature: (J)Z */ JNIEXPORT jboolean JNICALL Java_fstAPI_fstReaderIterateHierRewind (JNIEnv *, jobject, jlong); /* * Class: fstAPI * Method: fstReaderResetScope * Signature: (J)V */ JNIEXPORT void JNICALL Java_fstAPI_fstReaderResetScope (JNIEnv *, jobject, jlong); /* * Class: fstAPI * Method: fstReaderGetCurrentScopeLen * Signature: (J)I */ JNIEXPORT jint JNICALL Java_fstAPI_fstReaderGetCurrentScopeLen (JNIEnv *, jobject, jlong); /* * Class: fstAPI * Method: fstReaderGetFileType * Signature: (J)I */ JNIEXPORT jint JNICALL Java_fstAPI_fstReaderGetFileType (JNIEnv *, jobject, jlong); /* * Class: fstAPI * Method: fstReaderGetTimezero * Signature: (J)J */ JNIEXPORT jlong JNICALL Java_fstAPI_fstReaderGetTimezero (JNIEnv *, jobject, jlong); /* * Class: fstAPI * Method: fstReaderGetStartTime * Signature: (J)J */ JNIEXPORT jlong JNICALL Java_fstAPI_fstReaderGetStartTime (JNIEnv *, jobject, jlong); /* * Class: fstAPI * Method: fstReaderGetEndTime * Signature: (J)J */ JNIEXPORT jlong JNICALL Java_fstAPI_fstReaderGetEndTime (JNIEnv *, jobject, jlong); /* * Class: fstAPI * Method: fstReaderGetMemoryUsedByWriter * Signature: (J)J */ JNIEXPORT jlong JNICALL Java_fstAPI_fstReaderGetMemoryUsedByWriter (JNIEnv *, jobject, jlong); /* * Class: fstAPI * Method: fstReaderGetScopeCount * Signature: (J)J */ JNIEXPORT jlong JNICALL Java_fstAPI_fstReaderGetScopeCount (JNIEnv *, jobject, jlong); /* * Class: fstAPI * Method: fstReaderGetVarCount * Signature: (J)J */ JNIEXPORT jlong JNICALL Java_fstAPI_fstReaderGetVarCount (JNIEnv *, jobject, jlong); /* * Class: fstAPI * Method: fstReaderGetMaxHandle * Signature: (J)I */ JNIEXPORT jint JNICALL Java_fstAPI_fstReaderGetMaxHandle (JNIEnv *, jobject, jlong); /* * Class: fstAPI * Method: fstReaderGetAliasCount * Signature: (J)J */ JNIEXPORT jlong JNICALL Java_fstAPI_fstReaderGetAliasCount (JNIEnv *, jobject, jlong); /* * Class: fstAPI * Method: fstReaderGetValueChangeSectionCount * Signature: (J)J */ JNIEXPORT jlong JNICALL Java_fstAPI_fstReaderGetValueChangeSectionCount (JNIEnv *, jobject, jlong); /* * Class: fstAPI * Method: fstReaderGetFseekFailed * Signature: (J)Z */ JNIEXPORT jboolean JNICALL Java_fstAPI_fstReaderGetFseekFailed (JNIEnv *, jobject, jlong); /* * Class: fstAPI * Method: fstReaderSetUnlimitedTimeRange * Signature: (J)V */ JNIEXPORT void JNICALL Java_fstAPI_fstReaderSetUnlimitedTimeRange (JNIEnv *, jobject, jlong); /* * Class: fstAPI * Method: fstReaderSetLimitTimeRange * Signature: (JJJ)V */ JNIEXPORT void JNICALL Java_fstAPI_fstReaderSetLimitTimeRange (JNIEnv *, jobject, jlong, jlong, jlong); /* * Class: fstAPI * Method: fstReaderSetVcdExtensions * Signature: (JZ)V */ JNIEXPORT void JNICALL Java_fstAPI_fstReaderSetVcdExtensions (JNIEnv *, jobject, jlong, jboolean); /* * Class: fstAPI * Method: fstReaderGetNumberDumpActivityChanges * Signature: (J)I */ JNIEXPORT jint JNICALL Java_fstAPI_fstReaderGetNumberDumpActivityChanges (JNIEnv *, jobject, jlong); /* * Class: fstAPI * Method: fstReaderGetDumpActivityChangeTime * Signature: (JI)J */ JNIEXPORT jlong JNICALL Java_fstAPI_fstReaderGetDumpActivityChangeTime (JNIEnv *, jobject, jlong, jint); /* * Class: fstAPI * Method: fstReaderGetFacProcessMask * Signature: (JI)Z */ JNIEXPORT jboolean JNICALL Java_fstAPI_fstReaderGetFacProcessMask (JNIEnv *, jobject, jlong, jint); /* * Class: fstAPI * Method: fstReaderSetFacProcessMask * Signature: (JI)V */ JNIEXPORT void JNICALL Java_fstAPI_fstReaderSetFacProcessMask (JNIEnv *, jobject, jlong, jint); /* * Class: fstAPI * Method: fstReaderClrFacProcessMask * Signature: (JI)V */ JNIEXPORT void JNICALL Java_fstAPI_fstReaderClrFacProcessMask (JNIEnv *, jobject, jlong, jint); /* * Class: fstAPI * Method: fstReaderSetFacProcessMaskAll * Signature: (J)V */ JNIEXPORT void JNICALL Java_fstAPI_fstReaderSetFacProcessMaskAll (JNIEnv *, jobject, jlong); /* * Class: fstAPI * Method: fstReaderClrFacProcessMaskAll * Signature: (J)V */ JNIEXPORT void JNICALL Java_fstAPI_fstReaderClrFacProcessMaskAll (JNIEnv *, jobject, jlong); /* * Class: fstAPI * Method: fstReaderGetVersionString * Signature: (J)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_fstAPI_fstReaderGetVersionString (JNIEnv *, jobject, jlong); /* * Class: fstAPI * Method: fstReaderGetDateString * Signature: (J)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_fstAPI_fstReaderGetDateString (JNIEnv *, jobject, jlong); /* * Class: fstAPI * Method: fstReaderPopScope * Signature: (J)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_fstAPI_fstReaderPopScope (JNIEnv *, jobject, jlong); /* * Class: fstAPI * Method: fstReaderGetCurrentFlatScope * Signature: (J)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_fstAPI_fstReaderGetCurrentFlatScope (JNIEnv *, jobject, jlong); /* * Class: fstAPI * Method: fstReaderGetCurrentScopeUserInfo * Signature: (J)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_fstAPI_fstReaderGetCurrentScopeUserInfo (JNIEnv *, jobject, jlong); /* * Class: fstAPI * Method: fstReaderPushScope * Signature: (JLjava/lang/String;J)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_fstAPI_fstReaderPushScope (JNIEnv *, jobject, jlong, jstring, jlong); /* * Class: fstAPI * Method: fstReaderGetTimescale * Signature: (J)I */ JNIEXPORT jint JNICALL Java_fstAPI_fstReaderGetTimescale (JNIEnv *, jobject, jlong); /* * Class: fstAPI * Method: fstReaderGetDumpActivityChangeValue * Signature: (JI)Z */ JNIEXPORT jboolean JNICALL Java_fstAPI_fstReaderGetDumpActivityChangeValue (JNIEnv *, jobject, jlong, jint); /* * Class: fstAPI * Method: fstReaderGetValueFromHandleAtTime * Signature: (JJI)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_fstAPI_fstReaderGetValueFromHandleAtTime (JNIEnv *, jobject, jlong, jlong, jint); /* * Class: fstAPI * Method: fstReaderIterateHier * Signature: (JLfstHier;)V */ JNIEXPORT void JNICALL Java_fstAPI_fstReaderIterateHier (JNIEnv *, jobject, jlong, jobject); /* * Class: fstAPI * Method: fstReaderIterBlocks * Signature: (JLjava/lang/Object;)I */ JNIEXPORT jint JNICALL Java_fstAPI_fstReaderIterBlocks (JNIEnv *, jobject, jlong, jobject); /* * Class: fstAPI * Method: fstUtilityBinToEsc * Signature: ([BI)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_fstAPI_fstUtilityBinToEsc (JNIEnv *, jclass, jbyteArray, jint); /* * Class: fstAPI * Method: fstUtilityEscToBin * Signature: (Ljava/lang/String;)[B */ JNIEXPORT jbyteArray JNICALL Java_fstAPI_fstUtilityEscToBin (JNIEnv *, jclass, jstring); #ifdef __cplusplus } #endif #endif gtkwave-gtk3-3.3.125/contrib/fst_jni/fstPackType.java0000664000175000017500000000277715047725113021727 0ustar bybellbybell/* * Copyright (c) 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. */ public class fstPackType { private fstPackType( ) { } public static final String [] FST_PT_NAMESTRINGS = { "none", "unpacked", "packed", "sparse" }; public static final int FST_PT_MIN = 0; public static final int FST_PT_NONE = 0; public static final int FST_PT_UNPACKED = 1; public static final int FST_PT_PACKED = 2; public static final int FST_PT_TAGGED_PACKED = 3; public static final int FST_PT_MAX = 3; }; gtkwave-gtk3-3.3.125/contrib/fst_jni/fstArrayType.java0000664000175000017500000000277015047725113022120 0ustar bybellbybell/* * Copyright (c) 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. */ public class fstArrayType { private fstArrayType() { } public static final String [] FST_AR_NAMESTRINGS = { "none", "unpacked", "packed", "sparse" }; public static final int FST_AR_MIN = 0; public static final int FST_AR_NONE = 0; public static final int FST_AR_UNPACKED = 1; public static final int FST_AR_PACKED =2; public static final int FST_AR_SPARSE = 3; public static final int FST_AR_MAX = 3; }; gtkwave-gtk3-3.3.125/contrib/fst_jni/fstFileType.java0000664000175000017500000000256015047725113021716 0ustar bybellbybell/* * Copyright (c) 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. */ public class fstFileType { private fstFileType( ) { } public static final int FST_FT_MIN = 0; public static final int FST_FT_VERILOG = 0; public static final int FST_FT_VHDL = 1; public static final int FST_FT_VERILOG_VHDL = 2; public static final int FST_FT_MAX = 2; }; gtkwave-gtk3-3.3.125/contrib/fst_jni/fstSupplementalVarType.java0000664000175000017500000000303515047725113024157 0ustar bybellbybell/* * Copyright (c) 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. */ public class fstSupplementalVarType { fstSupplementalVarType( ) { } public static final int FST_SVT_MIN = 0; public static final int FST_SVT_NONE = 0; public static final int FST_SVT_VHDL_SIGNAL = 1; public static final int FST_SVT_VHDL_VARIABLE = 2; public static final int FST_SVT_VHDL_CONSTANT = 3; public static final int FST_SVT_VHDL_FILE = 4; public static final int FST_SVT_VHDL_MEMORY = 5; public static final int FST_SVT_MAX = 5; }; gtkwave-gtk3-3.3.125/contrib/fst_jni/Makefile.in0000664000175000017500000003204715047725113020665 0ustar bybellbybell# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = contrib/fst_jni DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am 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__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@ GLIB_COMPILE_SCHEMAS = @GLIB_COMPILE_SCHEMAS@ GPERF = @GPERF@ GREP = @GREP@ GSETTINGS_CFLAGS = @GSETTINGS_CFLAGS@ GSETTINGS_DISABLE_SCHEMAS_COMPILE = @GSETTINGS_DISABLE_SCHEMAS_COMPILE@ GTK_CFLAGS = @GTK_CFLAGS@ 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_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_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@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ RANLIB = @RANLIB@ RPC_CFLAGS = @RPC_CFLAGS@ RPC_LDADD = @RPC_LDADD@ 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@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ 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@ gsettingsschemadir = @gsettingsschemadir@ 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@ EXTRA_DIST = \ fst2Vcd.java \ fstAPI.c \ fstAPI.h \ fstAPI.java \ fstArrayType.java \ fstAttrType.java \ fstEnumValueType.java \ fstFileType.java \ fstHier.java \ fstHierType.java \ fstMiscType.java \ fstPackType.java \ fstReader.java \ fstScopeType.java \ fstSupplementalDataType.java \ fstSupplementalVarType.java \ fstVarDir.java \ fstVarType.java \ fstWriter.java \ fstWriterPackType.java \ Main.java \ zzz_test.csh 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 contrib/fst_jni/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign contrib/fst_jni/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): 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 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 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-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: .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-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 # 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-gtk3-3.3.125/contrib/fsdb2vcd/0000775000175000017500000000000015047725113016653 5ustar bybellbybellgtkwave-gtk3-3.3.125/contrib/fsdb2vcd/fsdb2vcd_fast.cc0000664000175000017500000005323715047725113021706 0ustar bybellbybell/* to compile: g++ -o fsdb2vcd_fast -O2 fsdb2vcd_fast.cc -I /pub/FsdbReader/ /pub/FsdbReader/libnffr.a /pub/FsdbReader/libnsys.a -ldl -lpthread -lz Much faster version of fsdb2vcd as compared to one bundled with Verdi. Requires libs and headers for FsdbReader. */ #ifdef NOVAS_FSDB #undef NOVAS_FSDB #endif #include "ffrAPI.h" #include #include #include #include #include #include #include #include #ifdef __GNUC__ /* non-portable trick that caches the ->second value of a RB tree entry for a given ->first key */ /* provides about 20% overall speedup */ #define BYPASS_RB_TREE_IF_POSSIBLE #endif #define __STDC_FORMAT_MACROS #include #define WRITEX_FILE_BUFFER_SIZE (64 * 1024) #define T2U64(t) (((uint64_t)(t).H << 32) | ((uint64_t)(t).L)) #define XT2U64(xt) (((uint64_t)(xt).t64.H << 32) | ((uint64_t)(xt).t64.L)) #define 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 enum VcdVcTypes { VCD_VC_TYPE_BIT, VCD_VC_TYPE_BITVEC, VCD_VC_TYPE_REAL, VCD_VC_TYPE_PORT, VCD_VC_TYPE_IGNORE }; struct fsdbReaderBlackoutChain { uint64_t tim; unsigned active : 1; }; static void writex(int fd, char *s, int len) { const int mx = WRITEX_FILE_BUFFER_SIZE; static char buf[mx]; static int pos = 0; if(len) { if(len < mx) { if(pos + len >= mx) { writex(fd, NULL, 0); } memcpy(buf + pos, s, len); pos += len; } else { writex(fd, NULL, 0); write(fd, s, len); } } else { if(pos) { write(fd, buf, pos); pos = 0; } } } static char *makeVcdID(unsigned int value, int *idlen) { static char buf[16]; 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; *idlen = pnt - buf; return(buf); } static bool_T __TreeCB(fsdbTreeCBType cb_type, void *client_data, void *tree_cb_data) { return(TRUE); } static bool_T __MyTreeCB(fsdbTreeCBType cb_type, void *client_data, void *tree_cb_data); static 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); } static void fsdbReaderReadScopeVarTree(void *ctx, FILE *cb) { ffrObject *fsdb_obj = (ffrObject *)ctx; fsdb_obj->ffrSetTreeCBFunc(__MyTreeCB, (void *) cb); fsdb_obj->ffrReadScopeVarTree(); } static int fsdbReaderGetMaxVarIdcode(void *ctx) { ffrObject *fsdb_obj = (ffrObject *)ctx; fsdbVarIdcode max_var_idcode = fsdb_obj->ffrGetMaxVarIdcode(); return(max_var_idcode); } static void fsdbReaderAddToSignalList(void *ctx, int i) { ffrObject *fsdb_obj = (ffrObject *)ctx; fsdb_obj->ffrAddToSignalList(i); } static void fsdbReaderLoadSignals(void *ctx) { ffrObject *fsdb_obj = (ffrObject *)ctx; fsdb_obj->ffrLoadSignals(); } static void *fsdbReaderCreateVCTraverseHandle(void *ctx, int i) { ffrObject *fsdb_obj = (ffrObject *)ctx; ffrVCTrvsHdl hdl = fsdb_obj->ffrCreateVCTraverseHandle(i); return((void *)hdl); } static int fsdbReaderHasIncoreVC(void *ctx, void *hdl) { ffrObject *fsdb_obj = (ffrObject *)ctx; ffrVCTrvsHdl fsdb_hdl = (ffrVCTrvsHdl)hdl; return(fsdb_hdl->ffrHasIncoreVC() == TRUE); } static void fsdbReaderFree(void *ctx, void *hdl) { ffrObject *fsdb_obj = (ffrObject *)ctx; ffrVCTrvsHdl fsdb_hdl = (ffrVCTrvsHdl)hdl; fsdb_hdl->ffrFree(); } static 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 = T2U64(timetag); return(rv); } static 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 = T2U64(timetag); return(rv); } static void 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); fsdb_hdl->ffrGotoXTag((void*)&timetag); } static uint64_t fsdbReaderGetXTag(void *ctx, void *hdl) { ffrObject *fsdb_obj = (ffrObject *)ctx; ffrVCTrvsHdl fsdb_hdl = (ffrVCTrvsHdl)hdl; fsdbTag64 timetag; fsdb_hdl->ffrGetXTag((void*)&timetag); uint64_t rv = T2U64(timetag); return(rv); } static 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); } static int fsdbReaderGotoNextVC(void *ctx, void *hdl) { ffrObject *fsdb_obj = (ffrObject *)ctx; ffrVCTrvsHdl fsdb_hdl = (ffrVCTrvsHdl)hdl; return(fsdb_hdl->ffrGotoNextVC() == FSDB_RC_SUCCESS); } static void fsdbReaderUnloadSignals(void *ctx) { ffrObject *fsdb_obj = (ffrObject *)ctx; fsdb_obj->ffrUnloadSignals(); } static void fsdbReaderClose(void *ctx) { ffrObject *fsdb_obj = (ffrObject *)ctx; fsdb_obj->ffrClose(); } static int fsdbReaderGetBytesPerBit(void *hdl) { ffrVCTrvsHdl fsdb_hdl = (ffrVCTrvsHdl)hdl; return(fsdb_hdl->ffrGetBytesPerBit()); } static int fsdbReaderGetBitSize(void *hdl) { ffrVCTrvsHdl fsdb_hdl = (ffrVCTrvsHdl)hdl; return(fsdb_hdl->ffrGetBitSize()); } static int fsdbReaderGetVarType(void *hdl) { ffrVCTrvsHdl fsdb_hdl = (ffrVCTrvsHdl)hdl; return(fsdb_hdl->ffrGetVarType()); } static char *fsdbReaderTranslateVC(void *hdl, void *val_ptr, int *vtype, int *vlen) { ffrVCTrvsHdl vc_trvs_hdl = (ffrVCTrvsHdl)hdl; byte_T *vc_ptr = (byte_T *)val_ptr; byte_T *bufferp; uint_T i; fsdbVarType var_type; int bs; static byte_T buffer[FSDB_MAX_BIT_SIZE+1+32]; bufferp = buffer + 1; switch (vc_trvs_hdl->ffrGetBytesPerBit()) { case FSDB_BYTES_PER_BIT_1B: *vlen = bs = vc_trvs_hdl->ffrGetBitSize(); for (i = 0; i < bs; i++) { switch(vc_ptr[i]) { case FSDB_BT_VCD_0: bufferp[i] = '0'; break; case FSDB_BT_VCD_1: bufferp[i] = '1'; break; case FSDB_BT_VCD_X: bufferp[i] = 'x'; break; case FSDB_BT_VCD_Z: bufferp[i] = 'z'; break; default: bufferp[i] = 'x'; break; } } *vtype = (i>1) ? VCD_VC_TYPE_BITVEC : VCD_VC_TYPE_BIT; break; case FSDB_BYTES_PER_BIT_2B: { bs = vc_trvs_hdl->ffrGetBitSize(); fsdbBitType *bt = (fsdbBitType *)bufferp; byte_T *buffers0 = bufferp + bs*1+1; byte_T *buffers1 = bufferp + bs*2+2; fsdbStrengthType *s0 = (fsdbStrengthType *)buffers0; fsdbStrengthType *s1 = (fsdbStrengthType *)buffers1; ffrObject::ffrGetEvcdPortStrength((byte_T *)val_ptr, bt, s0, s1); for (i = 0; i < bs; i++) { /* normally use ffrObject::ffrGetEvcdPortStrength() */ bufferp[i] = ((byte_T *)val_ptr)[i*2]; buffers0[i] = ((byte_T *)val_ptr)[i*2+1] & 15; buffers1[i] = (((byte_T *)val_ptr)[i*2+1] >> 4) & 15; if((bufferp[i] >= FSDB_BT_EVCD_L) && (bufferp[i] <= FSDB_BT_EVCD_f)) { bufferp[i] = "LlHhXxTDdUuNnZ?01AaBbCcFf"[bufferp[i]]; } else { bufferp[i] = '?'; } if((buffers0[i] >= FSDB_ST_HIGHZ) && (buffers0[i] <= FSDB_ST_SUPPLY)) { buffers0[i] += '0'; } else { buffers0[i] = FSDB_ST_HIGHZ + '0'; } if((buffers1[i] >= FSDB_ST_HIGHZ) && (buffers1[i] <= FSDB_ST_SUPPLY)) { buffers1[i] += '0'; } else { buffers1[i] = FSDB_ST_HIGHZ + '0'; } } bufferp[bs] = ' '; bufferp[bs*2+1] = ' '; bufferp[*vlen = bs*3+2] = 0; *vtype = VCD_VC_TYPE_PORT; } 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: break; default: vc_trvs_hdl->ffrGetVC(&vc_ptr); *vlen = sprintf((char *)bufferp, "%f", *((float*)vc_ptr)); break; } *vtype = VCD_VC_TYPE_IGNORE; break; case FSDB_BYTES_PER_BIT_8B: var_type = vc_trvs_hdl->ffrGetVarType(); switch(var_type) { case FSDB_VT_VCD_REAL: *vlen = sprintf((char *)bufferp, "%.16g", *((double*)vc_ptr)); *vtype = VCD_VC_TYPE_REAL; break; case FSDB_VT_STREAM: default: *vlen = 0; *vtype = VCD_VC_TYPE_IGNORE; break; } break; default: *vlen = 0; *vtype = VCD_VC_TYPE_IGNORE; break; } return((char *)bufferp); } static 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); } static 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 = T2U64(tag64); } return(rc == FSDB_RC_SUCCESS); } static 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 = T2U64(tag64); } return(rc == FSDB_RC_SUCCESS); } static unsigned int fsdbReaderGetDumpOffRange(void *ctx, struct fsdbReaderBlackoutChain **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 *)calloc(count * 2, sizeof(struct fsdbReaderBlackoutChain)); for(i=0;iname); /* sprintf(bf, "Scope: %s %s %s", type, scope->name, scope->module ? scope->module : "NULL"); */ } static void __DumpScope(fsdbTreeCBDataScope* scope, FILE *cb) { str_T type; switch (scope->type) { case FSDB_ST_SV_INTERFACE: case FSDB_ST_VCD_MODULE: type = (str_T) "module"; break; case FSDB_ST_VCD_TASK: type = (str_T) "task"; break; case FSDB_ST_VCD_FUNCTION: type = (str_T) "function"; break; case FSDB_ST_VCD_BEGIN: type = (str_T) "begin"; break; case FSDB_ST_VCD_FORK: type = (str_T) "fork"; break; case FSDB_ST_VCD_GENERATE: case FSDB_ST_VHDL_ARCHITECTURE: case FSDB_ST_VHDL_PROCEDURE: case FSDB_ST_VHDL_FUNCTION: case FSDB_ST_VHDL_RECORD: case FSDB_ST_VHDL_PROCESS: case FSDB_ST_VHDL_BLOCK: case FSDB_ST_VHDL_FOR_GENERATE: case FSDB_ST_VHDL_IF_GENERATE: case FSDB_ST_VHDL_GENERATE: default: type = (str_T) "begin"; break; } fprintf(cb, "$scope %s %s $end\n", type, scope->name); /* sprintf(bf, "Scope: %s %s %s", type, scope->name, scope->module ? scope->module : "NULL"); */ } static void __DumpVar(fsdbTreeCBDataVar *var, FILE *cb) { str_T type; int vcdid_len; int siz = 0; switch (var->type) { case FSDB_VT_VCD_EVENT: type = (str_T) "event"; break; case FSDB_VT_VCD_INTEGER: type = (str_T) "integer"; break; case FSDB_VT_VCD_PARAMETER: type = (str_T) "parameter"; break; case FSDB_VT_VCD_REAL: type = (str_T) "real"; siz = 64; break; case FSDB_VT_VCD_REG: type = (str_T) "reg"; break; case FSDB_VT_VCD_SUPPLY0: type = (str_T) "supply0"; break; case FSDB_VT_VCD_SUPPLY1: type = (str_T) "supply1"; break; case FSDB_VT_VCD_TIME: type = (str_T) "time"; break; case FSDB_VT_VCD_TRI: type = (str_T) "tri"; break; case FSDB_VT_VCD_TRIAND: type = (str_T) "triand"; break; case FSDB_VT_VCD_TRIOR: type = (str_T) "trior"; break; case FSDB_VT_VCD_TRIREG: type = (str_T) "trireg"; break; case FSDB_VT_VCD_TRI0: type = (str_T) "tri0"; break; case FSDB_VT_VCD_TRI1: type = (str_T) "tri1"; break; case FSDB_VT_VCD_WAND: type = (str_T) "wand"; break; case FSDB_VT_VCD_WIRE: type = (str_T) "wire"; break; case FSDB_VT_VCD_WOR: type = (str_T) "wor"; 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) "real"; 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) "wire"; } else { type = (str_T) "reg"; } break; } break; case FSDB_VT_VCD_PORT: type = (str_T) "port"; break; case FSDB_VT_STREAM: /* these hold transactions: not yet supported so do not emit */ return; /* type = (str_T) "stream"; */ break; default: type = (str_T) "wire"; break; } if(!siz) { if(var->lbitnum >= var->rbitnum) { siz = var->lbitnum - var->rbitnum + 1; } else { siz = var->rbitnum - var->lbitnum + 1; } } char *lb = strchr(var->name, '['); if(!lb || strchr(var->name, ' ')) { fprintf(cb, "$var %s %d %s %s $end\n", type, siz, makeVcdID(var->u.idcode, &vcdid_len), var->name); } else { fprintf(cb, "$var %s %d %s ", type, siz, makeVcdID(var->u.idcode, &vcdid_len)); /* add space, VCS-style */ fwrite(var->name, lb - var->name, 1, cb); fprintf(cb, " %s $end\n", lb); } } static bool_T __MyTreeCB(fsdbTreeCBType cb_type, void *client_data, void *tree_cb_data) { FILE *cb = (FILE *)client_data; 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_STRUCT_BEGIN: __DumpStruct((fsdbTreeCBDataStructBegin *)tree_cb_data, cb); break; case FSDB_TREE_CBT_VAR: __DumpVar((fsdbTreeCBDataVar*)tree_cb_data, cb); break; case FSDB_TREE_CBT_UPSCOPE: case FSDB_TREE_CBT_STRUCT_END: fprintf(cb, "$upscope $end\n"); break; case FSDB_TREE_CBT_END_TREE: /* fprintf(stderr, "End Tree:\n"); */ break; case FSDB_TREE_CBT_ARRAY_BEGIN: 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); } int main(int argc, char **argv) { void *ctx; FILE *fh; int i; ffrVCTrvsHdl *hdl; int mx_id; uint64_t key = 0; uint64_t max_tim; ffrFSDBInfo fsdb_info; int mult; char scale[3]; std::map time_map; fsdbVarIdcode *time_autosort; char timestring[32]; FILE *stdout_cache = stdout; unsigned int dumpoff_count = 0; unsigned int dumpoff_idx = 0; struct fsdbReaderBlackoutChain *dumpoff_ranges = NULL; uint64_t prev_dumponoff_tim = 0; int dumptime_emitted = 0; uint64_t time_serial_number = 0; stdout_cache = stdout; stdout = tmpfile(); /* redirects useless log file messages that would mess up VCD output for piped execution */ if((argc != 2) && (argc != 3)) { fprintf(stderr, "Usage:\n------\n%s filename.fsdb [filename.vcd]\n\n", argv[0]); exit(0); } ctx = fsdbReaderOpenFile(argv[1]); if(!ctx) { fprintf(stderr, "Could not open '%s', exiting.\n", argv[1]); exit(255); } if(argc == 3) { fh = fopen(argv[2], "wb"); if(!fh) { fprintf(stderr, "Could not open '%s', exiting.\n", argv[2]); perror("Why"); exit(255); } } else { fh = stdout_cache; if(!fh) { fprintf(stderr, "stdin is NULL, exiting.\n"); exit(255); } } dumpoff_count = fsdbReaderGetDumpOffRange(ctx, &dumpoff_ranges); if(FSDB_RC_SUCCESS == ((ffrObject *)ctx)->ffrGetFSDBInfo(argv[1], fsdb_info)) { fprintf(fh, "$date\n\t%s\n$end\n", fsdb_info.simulation_date); fprintf(fh, "$version\n\t%s\n$end\n", fsdb_info.simulator_version); } if(fsdbReaderExtractScaleUnit(ctx, &mult, &scale[0])) { scale[0] = tolower(scale[0]); switch(scale[0]) { case 'm': case 'u': case 'n': case 'p': case 'f': case 'a': case 'z': scale[1] = 's'; scale[2] = 0; break; default : scale[0] = 's'; scale[1] = 0; break; } fprintf(fh, "$timescale\n\t%d%s\n$end\n", mult, scale); } fsdbReaderReadScopeVarTree(ctx, fh); fprintf(fh, "$enddefinitions $end\n$dumpvars\n"); mx_id = fsdbReaderGetMaxVarIdcode(ctx); for(i=1;i<=mx_id;i++) { fsdbReaderAddToSignalList(ctx, i); } fsdbReaderLoadSignals(ctx); hdl = (ffrVCTrvsHdl *)calloc(i+1, sizeof(ffrVCTrvsHdl)); for(i=1;i<=mx_id;i++) { hdl[i] = (ffrVCTrvsHdl)fsdbReaderCreateVCTraverseHandle(ctx, i); } time_autosort = (fsdbVarIdcode *)calloc(mx_id + 1, sizeof(fsdbVarIdcode)); for(i=mx_id;i>0;i--) { ffrXTag xt; fsdbRC gf = hdl[i]->ffrGotoTheFirstVC(); if(gf == FSDB_RC_SUCCESS) { fsdbRC gx = hdl[i]->ffrGetXTag(&xt); if(gx == FSDB_RC_SUCCESS) { uint64_t x64 = XT2U64(xt); fsdbVarIdcode t_prev = time_map[x64]; time_autosort[i] = t_prev; time_map[x64] = i; } } } fflush(fh); setvbuf(fh, (char *) NULL, _IONBF, 0); /* even buffered IO is slow so disable it and use our own routines that don't need seeking */ int fd = fileno(fh); while(!time_map.empty()) { key = time_map.begin()->first; while(dumpoff_idx < dumpoff_count) { uint64_t top_tim = dumpoff_ranges[dumpoff_idx].tim; if(key >= top_tim) { uint64_t active = dumpoff_ranges[dumpoff_idx].active; if(top_tim >= prev_dumponoff_tim) { if((top_tim != prev_dumponoff_tim) || (!dumptime_emitted)) { if(time_serial_number++ == 1) { writex(fd, (char *)"$end\n", 5); } if(top_tim) { writex(fd, timestring, sprintf(timestring, "#%"PRIu64"\n", top_tim)); } prev_dumponoff_tim = top_tim; dumptime_emitted = 1; } if(active) { writex(fd, timestring, sprintf(timestring, "$dumpon\n")); } else { writex(fd, timestring, sprintf(timestring, "$dumpoff\n")); } } dumpoff_idx++; } else { break; } } if((!dumptime_emitted) || (key != prev_dumponoff_tim)) { if(time_serial_number++ == 1) { writex(fd, (char *)"$end\n", 5); } if(key) { writex(fd, timestring, sprintf(timestring, "#%"PRIu64"\n", key)); } } fsdbVarIdcode idx = time_map.begin()->second; #ifdef BYPASS_RB_TREE_IF_POSSIBLE fsdbVarIdcode *tms = NULL; uint64_t prev_x64 = key - 1; #endif while(idx) { fsdbVarIdcode idxn = time_autosort[idx]; byte_T *ret_vc; fsdbRC gvc = hdl[idx]->ffrGetVC(&ret_vc); if(gvc == FSDB_RC_SUCCESS) { int vtype, vlen; char *vcdid; int vcdid_len; char *vdata = fsdbReaderTranslateVC(hdl[idx], ret_vc, &vtype, &vlen); vcdid = makeVcdID(idx, &vcdid_len); switch(vtype) { case VCD_VC_TYPE_BIT: { writex(fd, vdata, 1); vcdid[vcdid_len++] = '\n'; writex(fd, vcdid, vcdid_len); } break; case VCD_VC_TYPE_BITVEC: case VCD_VC_TYPE_REAL: case VCD_VC_TYPE_PORT: { vdata--; /* buffer was specially allocated in fsdbReaderTranslateVC() so we can do this */ vdata[0] = (vtype == VCD_VC_TYPE_BITVEC) ? 'b' : ((vtype == VCD_VC_TYPE_REAL) ? 'r' : 'p'); vlen++; vdata[vlen] = ' '; vlen++; writex(fd, vdata, vlen); vcdid[vcdid_len++] = '\n'; writex(fd, vcdid, vcdid_len); } break; case VCD_VC_TYPE_IGNORE: default: 1; } if(FSDB_RC_SUCCESS == hdl[idx]->ffrGotoNextVC()) { ffrXTag xt; fsdbRC gx = hdl[idx]->ffrGetXTag(&xt); if(gx == FSDB_RC_SUCCESS) { uint64_t x64 = XT2U64(xt); #ifdef BYPASS_RB_TREE_IF_POSSIBLE if(x64 == prev_x64) { } else { tms = & time_map[prev_x64 = x64]; } fsdbVarIdcode t_prev = *tms; time_autosort[idx] = t_prev; *tms = idx; #else fsdbVarIdcode t_prev = time_map[x64]; time_autosort[idx] = t_prev; time_map[x64] = idx; #endif } } } idx = idxn; } time_map.erase(key); } if(fsdbReaderGetMaxFsdbTag64(ctx, &max_tim)) { if(key != max_tim) { if(time_serial_number++ == 1) { writex(fd, (char *)"$end\n", 5); } if(max_tim) { writex(fd, timestring, sprintf(timestring, "#%"PRIu64"\n", max_tim)); } } } writex(fd, NULL, 0); free(dumpoff_ranges); free(time_autosort); free(hdl); if(fh != stdout_cache) fclose(fh); fsdbReaderClose(ctx); fclose(stdout); return(0); } gtkwave-gtk3-3.3.125/contrib/fsdb2vcd/Makefile.in0000664000175000017500000003122115047725113020717 0ustar bybellbybell# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = contrib/fsdb2vcd DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am 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__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@ GLIB_COMPILE_SCHEMAS = @GLIB_COMPILE_SCHEMAS@ GPERF = @GPERF@ GREP = @GREP@ GSETTINGS_CFLAGS = @GSETTINGS_CFLAGS@ GSETTINGS_DISABLE_SCHEMAS_COMPILE = @GSETTINGS_DISABLE_SCHEMAS_COMPILE@ GTK_CFLAGS = @GTK_CFLAGS@ 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_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_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@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ RANLIB = @RANLIB@ RPC_CFLAGS = @RPC_CFLAGS@ RPC_LDADD = @RPC_LDADD@ 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@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ 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@ gsettingsschemadir = @gsettingsschemadir@ 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@ EXTRA_DIST = \ fsdb2vcd_fast.cc 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 contrib/fsdb2vcd/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign contrib/fsdb2vcd/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): 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 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 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-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: .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-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 # 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-gtk3-3.3.125/contrib/fsdb2vcd/Makefile.am0000664000175000017500000000006415047725113020707 0ustar bybellbybell## -*- makefile ## EXTRA_DIST= \ fsdb2vcd_fast.cc gtkwave-gtk3-3.3.125/contrib/vpi/0000775000175000017500000000000015047725113015754 5ustar bybellbybellgtkwave-gtk3-3.3.125/contrib/vpi/sys_fst.c0000664000175000017500000004050415047725113017615 0ustar bybellbybell/* FST dumper for NC Verilog / Verilog-XL to compile/run under AIX: ar -xv /lib/libz.a # to get libz.so.1 xlc -O3 -c sys_fst.c fstapi.c fastlz.c ld -G -o sys_fst.so sys_fst.o fstapi.o fastlz.o libz.so.1 -bnoentry -bexpall -lld -lc [nc]verilog r.v +loadvpi=sys_fst.so:sys_fst_register +access+r FST dumper for VCS to compile/run under LINUX: gcc -O2 -c -fPIC *.c ld -G -o sys_fst.so ../../src/libz/*.o *.o vcs +v2k -R +vpi +acc+2 +memchbk -full64 t.v -P sys_fst.tab sys_fst.so sys_fst.tab: $fstdumpfile check=sys_dumpfile_compiletf call=sys_dumpfile_calltf acc+=r:* $fstdumpvars check=sys_dumpvars_compiletf call=sys_dumpvars_calltf acc+=r:* $fstdumpoff check=sys_dumpoff_compiletf call=sys_dumpoff_calltf acc+=r:* */ #include #include #include #include #include #include #include #include #include "fstapi.h" struct fst_info { struct fst_info *dump_chain; vpiHandle item; s_vpi_value value; fstHandle fstSym; unsigned is_real:1; unsigned is_changed:1; }; /*************************************************/ static struct fstContext *ctx = NULL; static uint64_t prev64 = 0; static char *dump_path = NULL; static int dump_is_off = 0; static struct fst_info *fst_dump_list = 0; static int dumpvars_status = 0; /* 0:fresh 1:cb installed, * 2:callback done */ static uint64_t dumpvars_time; static uint64_t timerec_to_time64(s_vpi_time * vt) { uint64_t hi = vt->high; uint64_t lo = vt->low; return ((hi << 32) | lo); } static int dump_header_pending(void) { return (dumpvars_status != 2); } int variable_cb_rosync(p_cb_data cause); int variable_cb_rosync(p_cb_data cause) { p_vpi_time tim = cause->time; uint64_t now64 = timerec_to_time64(tim); struct fst_info *a_info = fst_dump_list; s_vpi_value value; if((now64 > prev64) || (!now64)) { fstWriterEmitTimeChange(ctx, now64); prev64 = now64; } while (a_info) { if (!a_info->is_real) { value.value.str = NULL; value.format = vpiBinStrVal; vpi_get_value(a_info->item, &value); fstWriterEmitValueChange(ctx, a_info->fstSym, value.value.str); } else { double d; value.format = vpiRealVal; vpi_get_value(a_info->item, &value); d = value.value.real; fstWriterEmitValueChange(ctx, a_info->fstSym, &d); } a_info->is_changed = 0; struct fst_info *a_info_next = a_info->dump_chain; a_info->dump_chain = NULL; a_info = a_info_next; } fst_dump_list = NULL; return (0); } static void install_rosync_cb(void) { struct t_cb_data cb; struct t_vpi_time time; memset(&cb, 0, sizeof(cb)); memset(&time, 0, sizeof(time)); time.type = vpiSimTime; cb.time = &time; cb.reason = cbReadOnlySynch; cb.cb_rtn = variable_cb_rosync; cb.user_data = NULL; cb.obj = NULL; vpi_free_object(vpi_register_cb(&cb)); } int variable_cb(p_cb_data cause) { struct fst_info *info = (struct fst_info *) cause->user_data; if (dump_is_off) return (0); if (dump_header_pending()) return (0); if (info->is_changed) return (0); if (!fst_dump_list) { install_rosync_cb(); } info->is_changed = 1; info->dump_chain = fst_dump_list; fst_dump_list = info; return (0); } static int dumpvars_cb(p_cb_data cause) { if (dumpvars_status != 1) return (0); dumpvars_status = 2; dumpvars_time = timerec_to_time64(cause->time); return (0); } static int install_dumpvars_callback(void) { struct t_cb_data cb; struct t_vpi_time time; if (dumpvars_status == 1) return (0); if (dumpvars_status == 2) { vpi_mcd_printf(1, "Error:" " $fstdumpvars ignored," " previously called at simtime %"PRIu64 "\n", dumpvars_time); return (1); } memset(&cb, 0, sizeof(cb)); memset(&time, 0, sizeof(time)); time.type = vpiSimTime; cb.time = &time; cb.reason = cbReadOnlySynch; cb.cb_rtn = dumpvars_cb; cb.user_data = NULL; cb.obj = NULL; vpi_free_object(vpi_register_cb(&cb)); dumpvars_status = 1; return (0); } static int end_of_sim_cb(p_cb_data cause) { if (ctx) { fstWriterClose(ctx); ctx = NULL; prev64 = 0; } return (0); } static int next_time_cb(p_cb_data cause) { struct t_cb_data cb; struct t_vpi_time vtime; p_vpi_time tim = cause->time; uint64_t now64 = timerec_to_time64(tim); if(now64 > prev64) { fstWriterEmitTimeChange(ctx, now64); prev64 = now64; } memset(&cb, 0, sizeof(cb)); memset(&vtime, 0, sizeof(vtime)); vtime.type = vpiSimTime; cb.time = &vtime; cb.reason = cbNextSimTime; cb.cb_rtn = next_time_cb; cb.user_data = NULL; cb.obj = NULL; vpi_free_object(vpi_register_cb(&cb)); return (0); } static void open_dumpfile(void) { struct t_cb_data cb; struct t_vpi_time vtime; if (dump_path == NULL) { dump_path = strdup("dump.fst"); } { time_t walltime; /* * primary */ ctx = fstWriterCreate(dump_path, 1); prev64 = 0; fstWriterSetPackType(ctx, FST_WR_PT_LZ4); /* fstWriterSetParallelMode(ctx, 1); */ time(&walltime); fstWriterSetDate(ctx, asctime(localtime(&walltime))); fstWriterSetVersion(ctx, acc_product_version()); free(dump_path); dump_path = NULL; memset(&cb, 0, sizeof(cb)); memset(&vtime, 0, sizeof(vtime)); vtime.type = vpiSimTime; cb.time = &vtime; cb.reason = cbEndOfSimulation; cb.cb_rtn = end_of_sim_cb; cb.user_data = NULL; cb.obj = NULL; vpi_free_object(vpi_register_cb(&cb)); memset(&cb, 0, sizeof(cb)); memset(&vtime, 0, sizeof(vtime)); vtime.type = vpiSimTime; cb.time = &vtime; cb.reason = cbNextSimTime; cb.cb_rtn = next_time_cb; cb.user_data = NULL; cb.obj = NULL; vpi_free_object(vpi_register_cb(&cb)); } } int sys_dumpfile_compiletf(char *name) { vpiHandle sys = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, sys); vpiHandle item; char *path; if (argv && (item = vpi_scan(argv))) { s_vpi_value value; if (vpi_get(vpiType, item) != vpiConstant || vpi_get(vpiConstType, item) != vpiStringConst) { vpi_mcd_printf(1, "FST Error:" " %s parameter must be a string constant\n", name); return (0); } value.format = vpiStringVal; vpi_get_value(item, &value); path = strdup(value.value.str); vpi_free_object(argv); } else { path = strdup("dump.fst"); } if (dump_path) { vpi_mcd_printf(1, "FST Warning:" " Overriding dumpfile path %s with %s\n", dump_path, path); free(dump_path); } dump_path = path; return (0); } int sys_dumpfile_calltf(char *name) { return (0); } static int draw_module_type(vpiHandle item, int typ) { vpiHandle iter = vpi_iterate(typ, item); vpiHandle net; const char *name; struct t_cb_data cb; struct fst_info *info; struct t_vpi_time time; int vtyp; int ilrange, irrange; if (!iter) return (0); while ((net = vpi_scan(iter))) { int siz; info = calloc(1, sizeof(*info)); if (typ == vpiVariables) { siz = vpi_get(vpiSize, net); ilrange = siz - 1; irrange = 0; } else if (vpi_get(vpiVector, net)) { s_vpi_value lvalue, rvalue; vpiHandle lrange = vpi_handle(vpiLeftRange, net); vpiHandle rrange = vpi_handle(vpiRightRange, net); lvalue.value.integer = 0; lvalue.format = vpiIntVal; vpi_get_value(lrange, &lvalue); rvalue.value.integer = 0; rvalue.format = vpiIntVal; vpi_get_value(rrange, &rvalue); siz = vpi_get(vpiSize, net); ilrange = lvalue.value.integer; irrange = rvalue.value.integer; } else { siz = 1; ilrange = irrange = -1; } name = vpi_get_str(vpiName, net); switch (typ) { case vpiNet: { int vartype = vpi_get(vpiNetType, net); switch (vartype) { case vpiWand: vtyp = FST_VT_VCD_WAND; break; case vpiWor: vtyp = FST_VT_VCD_WOR; break; case vpiTri: vtyp = FST_VT_VCD_TRI; break; case vpiTri0: vtyp = FST_VT_VCD_TRI0; break; case vpiTri1: vtyp = FST_VT_VCD_TRI1; break; case vpiTriReg: vtyp = FST_VT_VCD_TRIREG; break; case vpiTriAnd: vtyp = FST_VT_VCD_TRIAND; break; case vpiTriOr: vtyp = FST_VT_VCD_TRIOR; break; case vpiSupply0: vtyp = FST_VT_VCD_SUPPLY0; break; case vpiSupply1: vtyp = FST_VT_VCD_SUPPLY1; break; case vpiWire: default: vtyp = FST_VT_VCD_WIRE; break; } break; } case vpiReg: vtyp = FST_VT_VCD_REG; break; case vpiVariables: { int vartype = vpi_get(vpiType, net); switch (vartype) { case vpiTimeVar: vtyp = FST_VT_VCD_TIME; break; case vpiRealVar: vtyp = FST_VT_VCD_REAL; info->is_real = 1; break; case vpiIntegerVar: default: vtyp = FST_VT_VCD_INTEGER; break; } } break; default: vtyp = FST_VT_VCD_WIRE; break; } if (((ilrange == -1) && (irrange == -1)) || (typ == vpiVariables)) { info->fstSym = fstWriterCreateVar(ctx, vtyp, FST_VD_IMPLICIT, siz, name, 0); } else { char *n2 = malloc(strlen(name) + 64); int len = ilrange - irrange; if(len < 0) len = - len; len++; if (ilrange == irrange) { if(siz == len) { sprintf(n2, "%s [%d]", name, irrange); } else { sprintf(n2, "%s [%d][%d:0]", name, irrange, siz/len-1); } } else { if(siz == len) { sprintf(n2, "%s [%d:%d]", name, ilrange, irrange); } else { sprintf(n2, "%s [%d:%d][%d:0]", name, ilrange, irrange, siz/len-1); } } info->fstSym = fstWriterCreateVar(ctx, vtyp, FST_VD_IMPLICIT, siz, n2, 0); free(n2); } info->item = net; info->is_changed = 1; info->dump_chain = fst_dump_list; fst_dump_list = info; memset(&cb, 0, sizeof(cb)); memset(&time, 0, sizeof(time)); time.type = vpiSimTime; cb.time = &time; cb.user_data = (char *) info; cb.value = &info->value; /* NC seems to be ok with NULL, but VCS needs &info->value */ info->value.format = vpiObjTypeVal; cb.obj = net; cb.reason = cbValueChange; cb.cb_rtn = variable_cb; vpi_free_object(vpi_register_cb(&cb)); } return (0); } static int draw_module(vpiHandle item, int typ) { if (typ == vpiModule) { draw_module_type(item, vpiNet); } draw_module_type(item, vpiReg); draw_module_type(item, vpiVariables); return (0); } static int draw_scope_fst(vpiHandle item, int depth, int depth_max) { const char *fstscopnam; char *defname = NULL; vpiHandle orig = item; if ((depth_max) && (depth >= depth_max)) return (0); if (depth == 0) { int vpitype = vpi_get(vpiType, item); int fsttype; int lineno = vpi_get(vpiLineNo, item); const char *fname = vpi_get_str(vpiFile, item); fstWriterSetSourceInstantiationStem(ctx, fname, lineno, 1); lineno = vpi_get(vpiDefLineNo, item); fname = vpi_get_str(vpiDefFile, item); fstWriterSetSourceStem(ctx, fname, lineno, 1); switch (vpitype) { case vpiTaskFunc: case vpiTask: fsttype = FST_ST_VCD_TASK; break; case vpiFunction: fsttype = FST_ST_VCD_FUNCTION; break; case vpiNamedBegin: fsttype = FST_ST_VCD_BEGIN; break; case vpiNamedFork: fsttype = FST_ST_VCD_FORK; break; case vpiModule: default: fsttype = FST_ST_VCD_MODULE; defname = strdup(vpi_get_str(vpiDefName, item)); break; } fstscopnam = vpi_get_str(vpiName, item); if(defname && !strcmp(defname, fstscopnam)) { free(defname); defname = NULL; } /* no sense in storing a duplicate name */ fstWriterSetScope(ctx, fsttype, fstscopnam, defname); if(defname) free(defname); draw_module(item, vpitype); if (vpitype == vpiModule) { draw_scope_fst(item, depth + 1, depth_max); } fstWriterSetUpscope(ctx); } else { vpiHandle iter = vpi_iterate(vpiInternalScope, orig); if (iter) while ((item = vpi_scan(iter))) { int vpitype = vpi_get(vpiType, item); int fsttype; int lineno = vpi_get(vpiLineNo, item); const char *fname = vpi_get_str(vpiFile, item); fstWriterSetSourceInstantiationStem(ctx, fname, lineno, 1); lineno = vpi_get(vpiDefLineNo, item); fname = vpi_get_str(vpiDefFile, item); fstWriterSetSourceStem(ctx, fname, lineno, 1); switch (vpitype) { case vpiTaskFunc: case vpiTask: fsttype = FST_ST_VCD_TASK; break; case vpiFunction: fsttype = FST_ST_VCD_FUNCTION; break; case vpiNamedBegin: fsttype = FST_ST_VCD_BEGIN; break; case vpiNamedFork: fsttype = FST_ST_VCD_FORK; break; case vpiModule: default: fsttype = FST_ST_VCD_MODULE; defname = strdup(vpi_get_str(vpiDefName, item)); break; } fstscopnam = vpi_get_str(vpiName, item); if(defname && !strcmp(defname, fstscopnam)) { free(defname); defname = NULL; } /* no sense in storing a duplicate name */ fstWriterSetScope(ctx, fsttype, fstscopnam, defname); if(defname) free(defname); draw_module(item, vpitype); if (vpitype == vpiModule) { draw_scope_fst(item, depth + 1, depth_max); } fstWriterSetUpscope(ctx); } } return (0); } /* * This function is also used in sys_fst to check the arguments of the fst * variant of $dumpvars. */ int sys_dumpvars_compiletf(char *name) { vpiHandle sys = vpi_handle(vpiSysTfCall, 0); vpiHandle argv = vpi_iterate(vpiArgument, sys); vpiHandle tmp; if (argv == 0) return (0); tmp = vpi_scan(argv); assert(tmp); switch (vpi_get(vpiType, tmp)) { case vpiConstant: if (vpi_get(vpiConstType, tmp) == vpiStringConst) { vpi_printf("ERROR: %s argument must be " "a number constant.\n", name); vpi_control(vpiFinish, 1); } break; case vpiNet: case vpiReg: case vpiIntegerVar: case vpiMemoryWord: break; default: vpi_printf("ERROR: %s argument must be " "a number constant.\n", name); vpi_control(vpiFinish, 1); break; } vpi_free_object(argv); return (0); } int sys_dumpvars_calltf(char *name) { unsigned depth; s_vpi_value value; vpiHandle item = 0; vpiHandle sys = vpi_handle(vpiSysTfCall, 0); vpiHandle argv; if (ctx == 0) { open_dumpfile(); if (ctx == 0) return (0); } if (install_dumpvars_callback()) { return (0); } argv = vpi_iterate(vpiArgument, sys); depth = 0; if (argv && (item = vpi_scan(argv))) switch (vpi_get(vpiType, item)) { case vpiConstant: case vpiNet: case vpiReg: case vpiIntegerVar: case vpiMemoryWord: value.format = vpiIntVal; vpi_get_value(item, &value); depth = value.value.integer; break; } if (!argv) { vpiHandle parent = vpi_handle(vpiScope, sys); while (parent) { item = parent; parent = vpi_handle(vpiScope, item); } } else if (!item || !(item = vpi_scan(argv))) { item = vpi_handle(vpiScope, sys); argv = 0x0; } for (; item; item = argv ? vpi_scan(argv) : 0x0) { draw_scope_fst(item, 0, depth); } { struct fst_info *a_info; int prec = vpi_get(vpiTimePrecision, 0); fstWriterSetTimescale(ctx, prec); fstWriterEmitTimeChange(ctx, 0); install_rosync_cb(); } return (0); } int sys_dumpoff_compiletf(char *name) { return (0); } int sys_dumpoff_calltf(char *name) { dump_is_off = 1; return (0); } void sys_fst_register() { s_vpi_systf_data tf_data; tf_data.type = vpiSysTask; tf_data.tfname = "$fstdumpfile"; tf_data.calltf = sys_dumpfile_calltf; tf_data.compiletf = sys_dumpfile_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$fstdumpfile"; vpi_register_systf(&tf_data); tf_data.type = vpiSysTask; tf_data.tfname = "$fstdumpvars"; tf_data.calltf = sys_dumpvars_calltf; tf_data.compiletf = sys_dumpvars_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$fstdumpvars"; vpi_register_systf(&tf_data); tf_data.type = vpiSysTask; tf_data.tfname = "$fstdumpoff"; tf_data.calltf = sys_dumpoff_calltf; tf_data.compiletf = sys_dumpoff_compiletf; tf_data.sizetf = 0; tf_data.user_data = "$fstdumpoff"; vpi_register_systf(&tf_data); } gtkwave-gtk3-3.3.125/contrib/vpi/vpi_user.h0000664000175000017500000011366615047725113017776 0ustar bybellbybell/*************************************************************************** * vpi_user.h * * IEEE 1364-2000 Verilog HDL Programming Language Interface (PLI). * * This file contains the constant definitions, structure definitions, and * routine declarations used by the Verilog PLI procedural interface VPI * access routines. * **************************************************************************/ /*************************************************************************** * NOTE: the constant values 1 through 299 are reserved for use in this * vpi_user.h file. **************************************************************************/ #ifndef VPI_USER_H #define VPI_USER_H #include #ifdef __cplusplus extern "C" { #endif /*------------------------------------------------------------------------*/ /*-------------------------- Portability Help ----------------------------*/ /*------------------------------------------------------------------------*/ /* Sized variables */ #ifndef PLI_TYPES #define PLI_TYPES typedef int PLI_INT32; typedef unsigned int PLI_UINT32; typedef short PLI_INT16; typedef unsigned short PLI_UINT16; typedef char PLI_BYTE8; typedef unsigned char PLI_UBYTE8; #endif /* Use to export a symbol */ #if WIN32 #ifndef PLI_DLLISPEC #define PLI_DLLISPEC __declspec(dllimport) #define VPI_USER_DEFINED_DLLISPEC 1 #endif #else #ifndef PLI_DLLISPEC #define PLI_DLLISPEC #endif #endif /* Use to import a symbol */ #if WIN32 #ifndef PLI_DLLESPEC #define PLI_DLLESPEC __declspec(dllexport) #define VPI_USER_DEFINED_DLLESPEC 1 #endif #else #ifndef PLI_DLLESPEC #define PLI_DLLESPEC #endif #endif /* Use to mark a function as external */ #ifndef PLI_EXTERN #define PLI_EXTERN #endif /* Use to mark a variable as external */ #ifndef PLI_VEXTERN #define PLI_VEXTERN extern #endif #ifndef PLI_PROTOTYPES #define PLI_PROTOTYPES #define PROTO_PARAMS(params) params /* object is defined imported by the application */ #define XXTERN PLI_EXTERN PLI_DLLISPEC /* object is exported by the application */ #define EETERN PLI_EXTERN PLI_DLLESPEC #endif /******************************** TYPEDEFS ********************************/ typedef PLI_UINT32 *vpiHandle; /****************************** OBJECT TYPES ******************************/ #define vpiAlways 1 /* always block */ #define vpiAssignStmt 2 /* quasi-continuous assignment */ #define vpiAssignment 3 /* procedural assignment */ #define vpiBegin 4 /* block statement */ #define vpiCase 5 /* case statement */ #define vpiCaseItem 6 /* case statement item */ #define vpiConstant 7 /* numerical constant or literal string */ #define vpiContAssign 8 /* continuous assignment */ #define vpiDeassign 9 /* deassignment statement */ #define vpiDefParam 10 /* defparam */ #define vpiDelayControl 11 /* delay statement (e.g. #10) */ #define vpiDisable 12 /* named block disable statement */ #define vpiEventControl 13 /* wait on event, e.g. @e */ #define vpiEventStmt 14 /* event trigger, e.g. ->e */ #define vpiFor 15 /* for statement */ #define vpiForce 16 /* force statement */ #define vpiForever 17 /* forever statement */ #define vpiFork 18 /* fork-join block */ #define vpiFuncCall 19 /* HDL function call */ #define vpiFunction 20 /* HDL function */ #define vpiGate 21 /* primitive gate */ #define vpiIf 22 /* if statement */ #define vpiIfElse 23 /* if-else statement */ #define vpiInitial 24 /* initial block */ #define vpiIntegerVar 25 /* integer variable */ #define vpiInterModPath 26 /* intermodule wire delay */ #define vpiIterator 27 /* iterator */ #define vpiIODecl 28 /* input/output declaration */ #define vpiMemory 29 /* behavioral memory */ #define vpiMemoryWord 30 /* single word of memory */ #define vpiModPath 31 /* module path for path delays */ #define vpiModule 32 /* module instance */ #define vpiNamedBegin 33 /* named block statement */ #define vpiNamedEvent 34 /* event variable */ #define vpiNamedFork 35 /* named fork-join block */ #define vpiNet 36 /* scalar or vector net */ #define vpiNetBit 37 /* bit of vector net */ #define vpiNullStmt 38 /* a semicolon, Ie. #10 ; */ #define vpiOperation 39 /* behavioral operation */ #define vpiParamAssign 40 /* module parameter assignment */ #define vpiParameter 41 /* module parameter */ #define vpiPartSelect 42 /* part select */ #define vpiPathTerm 43 /* terminal of module path */ #define vpiPort 44 /* module port */ #define vpiPortBit 45 /* bit of vector module port */ #define vpiPrimTerm 46 /* primitive terminal */ #define vpiRealVar 47 /* real variable */ #define vpiReg 48 /* scalar or vector reg */ #define vpiRegBit 49 /* bit of vector reg */ #define vpiRelease 50 /* release statement */ #define vpiRepeat 51 /* repeat statement */ #define vpiRepeatControl 52 /* repeat control in an assign stmt */ #define vpiSchedEvent 53 /* vpi_put_value() event */ #define vpiSpecParam 54 /* specparam */ #define vpiSwitch 55 /* transistor switch */ #define vpiSysFuncCall 56 /* system function call */ #define vpiSysTaskCall 57 /* system task call */ #define vpiTableEntry 58 /* UDP state table entry */ #define vpiTask 59 /* HDL task */ #define vpiTaskCall 60 /* HDL task call */ #define vpiTchk 61 /* timing check */ #define vpiTchkTerm 62 /* terminal of timing check */ #define vpiTimeVar 63 /* time variable */ #define vpiTimeQueue 64 /* simulation event queue */ #define vpiUdp 65 /* user-defined primitive */ #define vpiUdpDefn 66 /* UDP definition */ #define vpiUserSystf 67 /* user defined system task or function */ #define vpiVarSelect 68 /* variable array selection */ #define vpiWait 69 /* wait statement */ #define vpiWhile 70 /* while statement */ /****************** object types added with 1364-2000 *********************/ #define vpiAttribute 105 /* attribute of an object */ #define vpiBitSelect 106 /* Bit select of parameter, var select */ #define vpiCallback 107 /* callback object */ #define vpiDelayTerm 108 /* Delay term which is a load or driver */ #define vpiDelayDevice 109 /* Delay object within a net */ #define vpiFrame 110 /* reentrant task/func frame */ #define vpiGateArray 111 /* gate instance array */ #define vpiModuleArray 112 /* module instance array */ #define vpiPrimitiveArray 113 /* vpiprimitiveArray type */ #define vpiNetArray 114 /* multidimensional net */ #define vpiRange 115 /* range declaration */ #define vpiRegArray 116 /* multidimensional reg */ #define vpiSwitchArray 117 /* switch instance array */ #define vpiUdpArray 118 /* UDP instance array */ #define vpiContAssignBit 128 /* Bit of a vector continuous assignment */ #define vpiNamedEventArray 129 /* multidimensional named event */ /******************************** METHODS *********************************/ /************* methods used to traverse 1 to 1 relationships **************/ #define vpiCondition 71 /* condition expression */ #define vpiDelay 72 /* net or gate delay */ #define vpiElseStmt 73 /* else statement */ #define vpiForIncStmt 74 /* increment statement in for loop */ #define vpiForInitStmt 75 /* initialization statement in for loop */ #define vpiHighConn 76 /* higher connection to port */ #define vpiLhs 77 /* left-hand side of assignment */ #define vpiIndex 78 /* index of var select, bit select, etc. */ #define vpiLeftRange 79 /* left range of vector or part select */ #define vpiLowConn 80 /* lower connection to port */ #define vpiParent 81 /* parent object */ #define vpiRhs 82 /* right-hand side of assignment */ #define vpiRightRange 83 /* right range of vector or part select */ #define vpiScope 84 /* containing scope object */ #define vpiSysTfCall 85 /* task function call */ #define vpiTchkDataTerm 86 /* timing check data term */ #define vpiTchkNotifier 87 /* timing check notifier */ #define vpiTchkRefTerm 88 /* timing check reference term */ /************ methods used to traverse 1 to many relationships ************/ #define vpiArgument 89 /* argument to (system) task/function */ #define vpiBit 90 /* bit of vector net or port */ #define vpiDriver 91 /* driver for a net */ #define vpiInternalScope 92 /* internal scope in module */ #define vpiLoad 93 /* load on net or reg */ #define vpiModDataPathIn 94 /* data terminal of a module path */ #define vpiModPathIn 95 /* Input terminal of a module path */ #define vpiModPathOut 96 /* output terminal of a module path */ #define vpiOperand 97 /* operand of expression */ #define vpiPortInst 98 /* connected port instance */ #define vpiProcess 99 /* process in module */ #define vpiVariables 100 /* variables in module */ #define vpiUse 101 /* usage */ /***** methods which can traverse 1 to 1, or 1 to many relationships ******/ #define vpiExpr 102 /* connected expression */ #define vpiPrimitive 103 /* primitive (gate, switch, UDP) */ #define vpiStmt 104 /* statement in process or task */ /********************* methods added with 1364-2000 ***********************/ #define vpiActiveTimeFormat 119 /* active $timeformat() system task */ #define vpiInTerm 120 /* To get to a delay device's drivers. */ #define vpiInstanceArray 121 /* vpiInstance arrays */ #define vpiLocalDriver 122 /* local drivers (within a module */ #define vpiLocalLoad 123 /* local loads (within a module */ #define vpiOutTerm 124 /* To get to a delay device's loads. */ #define vpiPorts 125 /* Module port */ #define vpiSimNet 126 /* simulated net after collapsing */ #define vpiTaskFunc 127 /* HDL task or function */ /******************************* PROPERTIES *******************************/ /************************ generic object properties ***********************/ #define vpiUndefined -1 /* undefined property */ #define vpiType 1 /* type of object */ #define vpiName 2 /* local name of object */ #define vpiFullName 3 /* full hierarchical name */ #define vpiSize 4 /* size of gate, net, port, etc. */ #define vpiFile 5 /* File name in which the object is used */ #define vpiLineNo 6 /* line number where the object is used */ /*************************** module properties ****************************/ #define vpiTopModule 7 /* top-level module (boolean) */ #define vpiCellInstance 8 /* cell (boolean) */ #define vpiDefName 9 /* module definition name */ #define vpiProtected 10 /* source protected module (boolean) */ #define vpiTimeUnit 11 /* module time unit */ #define vpiTimePrecision 12 /* module time precision */ #define vpiDefNetType 13 /* default net type */ #define vpiUnconnDrive 14 /* unconnected port drive strength */ #define vpiHighZ 1 /* No default drive given */ #define vpiPull1 2 /* default pull1 drive */ #define vpiPull0 3 /* default pull0 drive */ #define vpiDefFile 15 /* File name where the module is defined */ #define vpiDefLineNo 16 /* line number for module definition */ #define vpiDefDelayMode 47 /* Default delay mode for a module */ #define vpiDelayModeNone 1 /* no delay mode specified */ #define vpiDelayModePath 2 /* path delay mode */ #define vpiDelayModeDistrib 3 /* distributed delay mode */ #define vpiDelayModeUnit 4 /* unit delay mode */ #define vpiDelayModeZero 5 /* zero delay mode */ #define vpiDelayModeMTM 6 /* min:typ:max delay mode */ #define vpiDefDecayTime 48 /* Default decay time for a module */ /************************ port and net properties *************************/ #define vpiScalar 17 /* scalar (boolean) */ #define vpiVector 18 /* vector (boolean) */ #define vpiExplicitName 19 /* port is explicitly named */ #define vpiDirection 20 /* direction of port: */ #define vpiInput 1 /* input */ #define vpiOutput 2 /* output */ #define vpiInout 3 /* inout */ #define vpiMixedIO 4 /* mixed input-output */ #define vpiNoDirection 5 /* no direction */ #define vpiConnByName 21 /* connected by name (boolean) */ #define vpiNetType 22 /* net subtypes: */ #define vpiWire 1 /* wire net */ #define vpiWand 2 /* wire-and net */ #define vpiWor 3 /* wire-or net */ #define vpiTri 4 /* three-state net */ #define vpiTri0 5 /* pull-down net */ #define vpiTri1 6 /* pull-up net */ #define vpiTriReg 7 /* tri state reg net */ #define vpiTriAnd 8 /* three-state wire-and net */ #define vpiTriOr 9 /* three-state wire-or net */ #define vpiSupply1 10 /* supply 1 net */ #define vpiSupply0 11 /* supply zero net */ #define vpiNone 12 /* no default net type (1364-2000) */ #define vpiExplicitScalared 23 /* explicitly scalared (boolean) */ #define vpiExplicitVectored 24 /* explicitly vectored (boolean) */ #define vpiExpanded 25 /* expanded vector net (boolean) */ #define vpiImplicitDecl 26 /* implicitly declared net (boolean) */ #define vpiChargeStrength 27 /* charge decay strength of net */ /* Defined as part of strengths section. #define vpiLargeCharge 0x10 #define vpiMediumCharge 0x04 #define vpiSmallCharge 0x02 */ #define vpiArray 28 /* variable array (boolean) */ #define vpiPortIndex 29 /* Port index */ /********************** gate and terminal properties **********************/ #define vpiTermIndex 30 /* Index of a primitive terminal */ #define vpiStrength0 31 /* 0-strength of net or gate */ #define vpiStrength1 32 /* 1-strength of net or gate */ #define vpiPrimType 33 /* prmitive subtypes: */ #define vpiAndPrim 1 /* and gate */ #define vpiNandPrim 2 /* nand gate */ #define vpiNorPrim 3 /* nor gate */ #define vpiOrPrim 4 /* or gate */ #define vpiXorPrim 5 /* xor gate */ #define vpiXnorPrim 6 /* xnor gate */ #define vpiBufPrim 7 /* buffer */ #define vpiNotPrim 8 /* not gate */ #define vpiBufif0Prim 9 /* zero-enabled buffer */ #define vpiBufif1Prim 10 /* one-enabled buffer */ #define vpiNotif0Prim 11 /* zero-enabled not gate */ #define vpiNotif1Prim 12 /* one-enabled not gate */ #define vpiNmosPrim 13 /* nmos switch */ #define vpiPmosPrim 14 /* pmos switch */ #define vpiCmosPrim 15 /* cmos switch */ #define vpiRnmosPrim 16 /* resistive nmos switch */ #define vpiRpmosPrim 17 /* resistive pmos switch */ #define vpiRcmosPrim 18 /* resistive cmos switch */ #define vpiRtranPrim 19 /* resistive bidirectional */ #define vpiRtranif0Prim 20 /* zero-enable resistive bidirectional */ #define vpiRtranif1Prim 21 /* one-enable resistive bidirectional */ #define vpiTranPrim 22 /* bidirectional */ #define vpiTranif0Prim 23 /* zero-enabled bidirectional */ #define vpiTranif1Prim 24 /* one-enabled bidirectional */ #define vpiPullupPrim 25 /* pullup */ #define vpiPulldownPrim 26 /* pulldown */ #define vpiSeqPrim 27 /* sequential UDP */ #define vpiCombPrim 28 /* combinational UDP */ /************** path, path terminal, timing check properties **************/ #define vpiPolarity 34 /* polarity of module path... */ #define vpiDataPolarity 35 /* ...or data path: */ #define vpiPositive 1 /* positive */ #define vpiNegative 2 /* negative */ #define vpiUnknown 3 /* unknown (unspecified) */ #define vpiEdge 36 /* edge type of module path: */ #define vpiNoEdge 0x00000000 /* no edge */ #define vpiEdge01 0x00000001 /* 0 -> 1 */ #define vpiEdge10 0x00000002 /* 1 -> 0 */ #define vpiEdge0x 0x00000004 /* 0 -> x */ #define vpiEdgex1 0x00000008 /* x -> 1 */ #define vpiEdge1x 0x00000010 /* 1 -> x */ #define vpiEdgex0 0x00000020 /* x -> 0 */ #define vpiPosEdge (vpiEdgex1 | vpiEdge01 | vpiEdge0x) #define vpiNegEdge (vpiEdgex0 | vpiEdge10 | vpiEdge1x) #define vpiAnyEdge (vpiPosEdge | vpiNegEdge) #define vpiPathType 37 /* path delay connection subtypes: */ #define vpiPathFull 1 /* ( a *> b ) */ #define vpiPathParallel 2 /* ( a => b ) */ #define vpiTchkType 38 /* timing check subtypes: */ #define vpiSetup 1 /* $setup */ #define vpiHold 2 /* $hold */ #define vpiPeriod 3 /* $period */ #define vpiWidth 4 /* $width */ #define vpiSkew 5 /* $skew */ #define vpiRecovery 6 /* $recovery */ #define vpiNoChange 7 /* $nochange */ #define vpiSetupHold 8 /* $setuphold */ #define vpiFullskew 9 /* $fullskew -- added for 1364-2000 */ #define vpiRecrem 10 /* $recrem -- added for 1364-2000 */ #define vpiRemoval 11 /* $removal -- added for 1364-2000 */ #define vpiTimeskew 12 /* $timeskew -- added for 1364-2000 */ /************************* expression properties **************************/ #define vpiOpType 39 /* operation subtypes: */ #define vpiMinusOp 1 /* unary minus */ #define vpiPlusOp 2 /* unary plus */ #define vpiNotOp 3 /* unary not */ #define vpiBitNegOp 4 /* bitwise negation */ #define vpiUnaryAndOp 5 /* bitwise reduction and */ #define vpiUnaryNandOp 6 /* bitwise reduction nand */ #define vpiUnaryOrOp 7 /* bitwise reduction or */ #define vpiUnaryNorOp 8 /* bitwise reduction nor */ #define vpiUnaryXorOp 9 /* bitwise reduction xor */ #define vpiUnaryXNorOp 10 /* bitwise reduction xnor */ #define vpiSubOp 11 /* binary subtraction */ #define vpiDivOp 12 /* binary division */ #define vpiModOp 13 /* binary modulus */ #define vpiEqOp 14 /* binary equality */ #define vpiNeqOp 15 /* binary inequality */ #define vpiCaseEqOp 16 /* case (x and z) equality */ #define vpiCaseNeqOp 17 /* case inequality */ #define vpiGtOp 18 /* binary greater than */ #define vpiGeOp 19 /* binary greater than or equal */ #define vpiLtOp 20 /* binary less than */ #define vpiLeOp 21 /* binary less than or equal */ #define vpiLShiftOp 22 /* binary left shift */ #define vpiRShiftOp 23 /* binary right shift */ #define vpiAddOp 24 /* binary addition */ #define vpiMultOp 25 /* binary multiplication */ #define vpiLogAndOp 26 /* binary logical and */ #define vpiLogOrOp 27 /* binary logical or */ #define vpiBitAndOp 28 /* binary bitwise and */ #define vpiBitOrOp 29 /* binary bitwise or */ #define vpiBitXorOp 30 /* binary bitwise xor */ #define vpiBitXNorOp 31 /* binary bitwise xnor */ #define vpiBitXnorOp vpiBitXNorOp /* added with 1364-2000 */ #define vpiConditionOp 32 /* ternary conditional */ #define vpiConcatOp 33 /* n-ary concatenation */ #define vpiMultiConcatOp 34 /* repeated concatenation */ #define vpiEventOrOp 35 /* event or */ #define vpiNullOp 36 /* null operation */ #define vpiListOp 37 /* list of expressions */ #define vpiMinTypMaxOp 38 /* min:typ:max: delay expression */ #define vpiPosedgeOp 39 /* posedge */ #define vpiNegedgeOp 40 /* negedge */ #define vpiArithLShiftOp 41 /* arithmetic left shift (1364-2000) */ #define vpiArithRShiftOp 42 /* arithmetic right shift (1364-2000) */ #define vpiPowerOp 43 /* arithmetic power op (1364-2000) */ #define vpiConstType 40 /* constant subtypes: */ #define vpiDecConst 1 /* decimal integer */ #define vpiRealConst 2 /* real */ #define vpiBinaryConst 3 /* binary integer */ #define vpiOctConst 4 /* octal integer */ #define vpiHexConst 5 /* hexadecimal integer */ #define vpiStringConst 6 /* string literal */ #define vpiIntConst 7 /* HDL integer constant (1364-2000) */ #define vpiBlocking 41 /* blocking assignment (boolean) */ #define vpiCaseType 42 /* case statement subtypes: */ #define vpiCaseExact 1 /* exact match */ #define vpiCaseX 2 /* ignore X's */ #define vpiCaseZ 3 /* ignore Z's */ #define vpiNetDeclAssign 43 /* assign part of decl (boolean) */ /************** task/function properties **************/ #define vpiFuncType 44 /* HDL function and system function type */ #define vpiIntFunc 1 /* returns integer */ #define vpiRealFunc 2 /* returns real */ #define vpiTimeFunc 3 /* returns time */ #define vpiSizedFunc 4 /* returns an arbitrary size */ #define vpiSizedSignedFunc 5 /* returns sized signed value */ /* alias 1364-1995 system function subtypes to 1364-2000 function subtypes */ #define vpiSysFuncType vpiFuncType #define vpiSysFuncInt vpiIntFunc #define vpiSysFuncReal vpiRealFunc #define vpiSysFuncTime vpiTimeFunc #define vpiSysFuncSized vpiSizedFunc #define vpiUserDefn 45 /* user defined system task/func (boolean) */ #define vpiScheduled 46 /* object still scheduled (boolean) */ /*********************** properties added with 1364-2000 *******************/ #define vpiActive 49 /* reentrant task/func frame is active */ #define vpiAutomatic 50 /* task/func obj is automatic */ #define vpiCell 51 /* configuration cell */ #define vpiConfig 52 /* configuration config file */ #define vpiConstantSelect 53 /* (boolean) bit or part select indices are constant expressions */ #define vpiDecompile 54 /* decompile the object */ #define vpiDefAttribute 55 /* Attribute defined for the obj */ #define vpiDelayType 56 /* delay subtype */ #define vpiModPathDelay 1 /* module path delay */ #define vpiInterModPathDelay 2 /* intermodule path delay */ #define vpiMIPDelay 3 /* module input port delay */ #define vpiIteratorType 57 /* object type of an iterator */ #define vpiLibrary 58 /* configuration library */ #define vpiMultiArray 59 /* Object is a multidimensional array */ #define vpiOffset 60 /* offset from LSB */ #define vpiResolvedNetType 61 /* net subtype after resolution, returns same subtypes as vpiNetType */ #define vpiSaveRestartID 62 /* unique ID for save/restart data */ #define vpiSaveRestartLocation 63 /* name of save/restart data file */ #define vpiValid 64 /* reentrant task/func frame is valid */ #define vpiSigned 65 /* TRUE for vpiIODecl and any object in the expression class if the object has the signed attribute */ #define vpiLocalParam 70 /* TRUE when a param is declared as a localparam */ #define vpiModPathHasIfNone 71 /* Mod path has an ifnone statement */ /************* vpi_control() constants (added with 1364-2000) *************/ #define vpiStop 66 /* execute simulator's $stop */ #define vpiFinish 67 /* execute simulator's $finish */ #define vpiReset 68 /* execute simulator's $reset */ #define vpiSetInteractiveScope 69 /* set simulator's interactive scope */ /************************** I/O related defines ***************************/ #define VPI_MCD_STDOUT 0x00000001 /************************** STRUCTURE DEFINITIONS *************************/ /***************************** time structure *****************************/ typedef struct t_vpi_time { PLI_INT32 type; /* [vpiScaledRealTime, vpiSimTime, vpiSuppressTime] */ PLI_UINT32 high, low; /* for vpiSimTime */ double real; /* for vpiScaledRealTime */ } s_vpi_time, *p_vpi_time; /* time types */ #define vpiScaledRealTime 1 #define vpiSimTime 2 #define vpiSuppressTime 3 /**************************** delay structures ****************************/ typedef struct t_vpi_delay { struct t_vpi_time *da; /* pointer to user allocated array of delay values */ PLI_INT32 no_of_delays; /* number of delays */ PLI_INT32 time_type; /* [vpiScaledRealTime, vpiSimTime, vpiSuppressTime] */ PLI_INT32 mtm_flag; /* true for mtm values */ PLI_INT32 append_flag; /* true for append */ PLI_INT32 pulsere_flag; /* true for pulsere values */ } s_vpi_delay, *p_vpi_delay; /**************************** value structures ****************************/ /* vector value */ typedef struct t_vpi_vecval { /* following fields are repeated enough times to contain vector */ PLI_INT32 aval, bval; /* bit encoding: ab: 00=0, 10=1, 11=X, 01=Z */ } s_vpi_vecval, *p_vpi_vecval; /* strength (scalar) value */ typedef struct t_vpi_strengthval { PLI_INT32 logic; /* vpi[0,1,X,Z] */ PLI_INT32 s0, s1; /* refer to strength coding below */ } s_vpi_strengthval, *p_vpi_strengthval; /* strength values */ #define vpiSupplyDrive 0x80 #define vpiStrongDrive 0x40 #define vpiPullDrive 0x20 #define vpiWeakDrive 0x08 #define vpiLargeCharge 0x10 #define vpiMediumCharge 0x04 #define vpiSmallCharge 0x02 #define vpiHiZ 0x01 /* generic value */ typedef struct t_vpi_value { PLI_INT32 format; /* vpi[[Bin,Oct,Dec,Hex]Str,Scalar,Int,Real,String, Vector,Strength,Suppress,Time,ObjType]Val */ union { PLI_BYTE8 *str; /* string value */ PLI_INT32 scalar; /* vpi[0,1,X,Z] */ PLI_INT32 integer; /* integer value */ double real; /* real value */ struct t_vpi_time *time; /* time value */ struct t_vpi_vecval *vector; /* vector value */ struct t_vpi_strengthval *strength; /* strength value */ PLI_BYTE8 *misc; /* ...other */ } value; } s_vpi_value, *p_vpi_value; /* value formats */ #define vpiBinStrVal 1 #define vpiOctStrVal 2 #define vpiDecStrVal 3 #define vpiHexStrVal 4 #define vpiScalarVal 5 #define vpiIntVal 6 #define vpiRealVal 7 #define vpiStringVal 8 #define vpiVectorVal 9 #define vpiStrengthVal 10 #define vpiTimeVal 11 #define vpiObjTypeVal 12 #define vpiSuppressVal 13 /* delay modes */ #define vpiNoDelay 1 #define vpiInertialDelay 2 #define vpiTransportDelay 3 #define vpiPureTransportDelay 4 /* force and release flags */ #define vpiForceFlag 5 #define vpiReleaseFlag 6 /* scheduled event cancel flag */ #define vpiCancelEvent 7 /* bit mask for the flags argument to vpi_put_value() */ #define vpiReturnEvent 0x1000 /* scalar values */ #define vpi0 0 #define vpi1 1 #define vpiZ 2 #define vpiX 3 #define vpiH 4 #define vpiL 5 #define vpiDontCare 6 /* #define vpiNoChange 7 Defined under vpiTchkType, but can be used here. */ /********************* system task/function structure *********************/ typedef struct t_vpi_systf_data { PLI_INT32 type; /* vpiSysTask, vpiSysFunc */ PLI_INT32 sysfunctype; /* vpiSysTask, vpi[Int,Real,Time,Sized, SizedSigned] Func */ PLI_BYTE8 *tfname; /* first character must be `$' */ PLI_INT32 (*calltf)(); PLI_INT32 (*compiletf)(); PLI_INT32 (*sizetf)(); /* for sized function callbacks only */ PLI_BYTE8 *user_data; } s_vpi_systf_data, *p_vpi_systf_data; #define vpiSysTask 1 #define vpiSysFunc 2 /* the subtypes are defined under the vpiFuncType property */ /***************** Verilog execution information structure ****************/ typedef struct t_vpi_vlog_info { PLI_INT32 argc; PLI_BYTE8 **argv; PLI_BYTE8 *product; PLI_BYTE8 *version; } s_vpi_vlog_info, *p_vpi_vlog_info; /******************** PLI error information structure *********************/ typedef struct t_vpi_error_info { PLI_INT32 state; /* vpi[Compile,PLI,Run] */ PLI_INT32 level; /* vpi[Notice,Warning,Error,System,Internal] */ PLI_BYTE8 *message; PLI_BYTE8 *product; PLI_BYTE8 *code; PLI_BYTE8 *file; PLI_INT32 line; } s_vpi_error_info, *p_vpi_error_info; /* error types */ #define vpiCompile 1 #define vpiPLI 2 #define vpiRun 3 #define vpiNotice 1 #define vpiWarning 2 #define vpiError 3 #define vpiSystem 4 #define vpiInternal 5 /************************** callback structures ***************************/ /* normal callback structure */ typedef struct t_cb_data { PLI_INT32 reason; /* callback reason */ PLI_INT32 (*cb_rtn)(struct t_cb_data *); /* call routine */ vpiHandle obj; /* trigger object */ p_vpi_time time; /* callback time */ p_vpi_value value; /* trigger object value */ PLI_INT32 index; /* index of the memory word or var select that changed */ PLI_BYTE8 *user_data; } s_cb_data, *p_cb_data; /**************************** CALLBACK REASONS ****************************/ /*************************** Simulation related ***************************/ #define cbValueChange 1 #define cbStmt 2 #define cbForce 3 #define cbRelease 4 /****************************** Time related ******************************/ #define cbAtStartOfSimTime 5 #define cbReadWriteSynch 6 #define cbReadOnlySynch 7 #define cbNextSimTime 8 #define cbAfterDelay 9 /***************************** Action related *****************************/ #define cbEndOfCompile 10 #define cbStartOfSimulation 11 #define cbEndOfSimulation 12 #define cbError 13 #define cbTchkViolation 14 #define cbStartOfSave 15 #define cbEndOfSave 16 #define cbStartOfRestart 17 #define cbEndOfRestart 18 #define cbStartOfReset 19 #define cbEndOfReset 20 #define cbEnterInteractive 21 #define cbExitInteractive 22 #define cbInteractiveScopeChange 23 #define cbUnresolvedSystf 24 /************************** Added with 1364-2000 **************************/ #define cbAssign 25 #define cbDeassign 26 #define cbDisable 27 #define cbPLIError 28 #define cbSignal 29 /************************* FUNCTION DECLARATIONS **************************/ /* callback related */ XXTERN vpiHandle vpi_register_cb PROTO_PARAMS((p_cb_data cb_data_p)); XXTERN PLI_INT32 vpi_remove_cb PROTO_PARAMS((vpiHandle cb_obj)); XXTERN void vpi_get_cb_info PROTO_PARAMS((vpiHandle object, p_cb_data cb_data_p)); XXTERN vpiHandle vpi_register_systf PROTO_PARAMS((p_vpi_systf_data systf_data_p)); XXTERN void vpi_get_systf_info PROTO_PARAMS((vpiHandle object, p_vpi_systf_data systf_data_p)); /* for obtaining handles */ XXTERN vpiHandle vpi_handle_by_name PROTO_PARAMS((PLI_BYTE8 *name, vpiHandle scope)); XXTERN vpiHandle vpi_handle_by_index PROTO_PARAMS((vpiHandle object, PLI_INT32 indx)); /* for traversing relationships */ XXTERN vpiHandle vpi_handle PROTO_PARAMS((PLI_INT32 type, vpiHandle refHandle)); XXTERN vpiHandle vpi_handle_multi PROTO_PARAMS((PLI_INT32 type, vpiHandle refHandle1, vpiHandle refHandle2, ... )); XXTERN vpiHandle vpi_iterate PROTO_PARAMS((PLI_INT32 type, vpiHandle refHandle)); XXTERN vpiHandle vpi_scan PROTO_PARAMS((vpiHandle iterator)); /* for processing properties */ XXTERN PLI_INT32 vpi_get PROTO_PARAMS((PLI_INT32 property, vpiHandle object)); XXTERN PLI_BYTE8 *vpi_get_str PROTO_PARAMS((PLI_INT32 property, vpiHandle object)); /* delay processing */ XXTERN void vpi_get_delays PROTO_PARAMS((vpiHandle object, p_vpi_delay delay_p)); XXTERN void vpi_put_delays PROTO_PARAMS((vpiHandle object, p_vpi_delay delay_p)); /* value processing */ XXTERN void vpi_get_value PROTO_PARAMS((vpiHandle expr, p_vpi_value value_p)); XXTERN vpiHandle vpi_put_value PROTO_PARAMS((vpiHandle object, p_vpi_value value_p, p_vpi_time time_p, PLI_INT32 flags)); /* time processing */ XXTERN void vpi_get_time PROTO_PARAMS((vpiHandle object, p_vpi_time time_p)); /* I/O routines */ XXTERN PLI_UINT32 vpi_mcd_open PROTO_PARAMS((PLI_BYTE8 *fileName)); XXTERN PLI_UINT32 vpi_mcd_close PROTO_PARAMS((PLI_UINT32 mcd)); XXTERN PLI_BYTE8 *vpi_mcd_name PROTO_PARAMS((PLI_UINT32 cd)); XXTERN PLI_INT32 vpi_mcd_printf PROTO_PARAMS((PLI_UINT32 mcd, PLI_BYTE8 *format, ...)); XXTERN PLI_INT32 vpi_printf PROTO_PARAMS((PLI_BYTE8 *format, ...)); /* utility routines */ XXTERN PLI_INT32 vpi_compare_objects PROTO_PARAMS((vpiHandle object1, vpiHandle object2)); XXTERN PLI_INT32 vpi_chk_error PROTO_PARAMS((p_vpi_error_info error_info_p)); XXTERN PLI_INT32 vpi_free_object PROTO_PARAMS((vpiHandle object)); XXTERN PLI_INT32 vpi_get_vlog_info PROTO_PARAMS((p_vpi_vlog_info vlog_info_p)); /* routines added with 1364-2000 */ XXTERN PLI_INT32 vpi_get_data PROTO_PARAMS((PLI_INT32 id, PLI_BYTE8 *dataLoc, PLI_INT32 numOfBytes)); XXTERN PLI_INT32 vpi_put_data PROTO_PARAMS((PLI_INT32 id, PLI_BYTE8 *dataLoc, PLI_INT32 numOfBytes)); XXTERN void *vpi_get_userdata PROTO_PARAMS((vpiHandle obj)); XXTERN PLI_INT32 vpi_put_userdata PROTO_PARAMS((vpiHandle obj, void *userdata)); XXTERN PLI_INT32 vpi_vprintf PROTO_PARAMS((PLI_BYTE8 *format, va_list ap)); XXTERN PLI_INT32 vpi_mcd_vprintf PROTO_PARAMS((PLI_UINT32 mcd, PLI_BYTE8 *format, va_list ap)); XXTERN PLI_INT32 vpi_flush PROTO_PARAMS((void)); XXTERN PLI_INT32 vpi_mcd_flush PROTO_PARAMS((PLI_UINT32 mcd)); XXTERN PLI_INT32 vpi_control PROTO_PARAMS((PLI_INT32 operation, ...)); XXTERN vpiHandle vpi_handle_by_multi_index PROTO_PARAMS((vpiHandle obj, PLI_INT32 num_index, PLI_INT32 *index_array)); /**************************** GLOBAL VARIABLES ****************************/ PLI_VEXTERN PLI_DLLESPEC void (*vlog_startup_routines[])(); /* array of function pointers, last pointer should be null */ #undef PLI_EXTERN #undef PLI_VEXTERN #ifdef VPI_USER_DEFINED_DLLISPEC #undef VPI_USER_DEFINED_DLLISPEC #undef PLI_DLLISPEC #endif #ifdef VPI_USER_DEFINED_DLLESPEC #undef VPI_USER_DEFINED_DLLESPEC IEEE HARDWARE DESCRIPTION LANGUAGE Std 1364-2001 #undef PLI_DLLESPEC #endif #ifdef PLI_PROTOTYPES #undef PLI_PROTOTYPES #undef PROTO_PARAMS #undef XXTERN #undef EETERN #endif #ifdef __cplusplus } #endif #endif /* VPI_USER_H */ gtkwave-gtk3-3.3.125/contrib/vpi/Makefile.am0000664000175000017500000000243115047725113020010 0ustar bybellbybell## -*- makefile -*- ## ## To compile this, add AC_PROG_LIBTOOL to configure.ac ## also add contrib/vpi/Makefile to AC_CONFIG_FILES ## also run libtoolize to generate ltmain.sh. ## ## This is not built by default. In the future this will be a normal part of ## the build process. ## ## Note that this explicitly uses the libz library found in this ## distro as this might be necessary if your simulator is not already linked ## against it. ## ## 20jan09ajb ## lib_LTLIBRARIES= libsysfst.la libsysvzt_la_SOURCES= ../../src/libz/adler32.c ../../src/libz/compress.c ../../src/libz/crc32.c ../../src/libz/crc32.h \ ../../src/libz/deflate.c ../../src/libz/deflate.h ../../src/libz/gzio.c ../../src/libz/infback.c ../../src/libz/inffast.c \ ../../src/libz/inffast.h ../../src/libz/inffixed.h ../../src/libz/inflate.c ../../src/libz/inflate.h \ ../../src/libz/inftrees.c ../../src/libz/inftrees.h ../../src/libz/trees.c ../../src/libz/trees.h ../../src/libz/uncompr.c \ ../../src/libz/zconf.h ../../src/libz/zlib.h ../../src/libz/zutil.c ../../src/libz/zutil.h \ ../../src/helpers/fst/fstapi.c ../../src/helpers/fst/fstapi.h ../../src/helpers/fst/fastlz.c ../../src/helpers/fst/fastlz.h \ sys_fst.c libsysfst_la_LDFLAGS = -version-info 1:0:0 AM_CFLAGS= -I../../src/libz/ -I../../src/helpers/fst/ -I. gtkwave-gtk3-3.3.125/contrib/vpi/acc_user.h0000664000175000017500000005566515047725113017732 0ustar bybellbybell/***************************************************************************** * acc_user.h * * IEEE 1364-2000 Verilog HDL Programming Language Interface (PLI). * * This file contains the constant definitions, structure definitions, and * routine declarations for the Verilog Programming Language Interface ACC * access routines. * ****************************************************************************/ #ifndef ACC_USER_H #define ACC_USER_H #ifdef __cplusplus extern "C" { #endif /*---------------------------------------------------------------------------*/ /*--------------------------- Portability Help ------------------------------*/ /*---------------------------------------------------------------------------*/ /* Sized variables */ #ifndef PLI_TYPES #define PLI_TYPES typedef int PLI_INT32; typedef unsigned int PLI_UINT32; typedef short PLI_INT16; typedef unsigned short PLI_UINT16; typedef char PLI_BYTE8; typedef unsigned char PLI_UBYTE8; #endif /* export a symbol */ #if WIN32 #ifndef PLI_DLLISPEC #define PLI_DLLISPEC __declspec(dllimport) #define ACC_USER_DEFINED_DLLISPEC 1 #endif #else #ifndef PLI_DLLISPEC #define PLI_DLLISPEC #endif #endif /* import a symbol */ #if WIN32 #ifndef PLI_DLLESPEC #define PLI_DLLESPEC __declspec(dllexport) #define ACC_USER_DEFINED_DLLESPEC 1 #endif #else #ifndef PLI_DLLESPEC #define PLI_DLLESPEC #endif #endif /* mark a function as external */ #ifndef PLI_EXTERN #define PLI_EXTERN #endif /* mark a variable as external */ #ifndef PLI_VEXTERN #define PLI_VEXTERN extern #endif #ifndef PLI_PROTOTYPES #define PLI_PROTOTYPES #define PROTO_PARAMS(params) params /* object is imported by the application */ #define XXTERN PLI_EXTERN PLI_DLLISPEC /* object is exported by the application */ #define EETERN PLI_EXTERN PLI_DLLESPEC #endif /* * The following group of defines exists purely for backwards compatibility */ #ifndef PLI_EXTRAS #define PLI_EXTRAS #define bool int #define true 1 #define TRUE 1 #define false 0 #define FALSE 0 #define null 0L #endif /*---------------------------------------------------------------------------*/ /*------------------------------- definitions -------------------------------*/ /*---------------------------------------------------------------------------*/ /*----------------------------- general defines -----------------------------*/ typedef PLI_INT32 *HANDLE; #ifndef VPI_USER_CDS_H typedef PLI_INT32 *handle; #endif /*------------------------------- object types ------------------------------*/ #define accModule 20 #define accScope 21 #define accNet 25 #define accReg 30 #define accRegister accReg #define accPort 35 #define accTerminal 45 #define accInputTerminal 46 #define accOutputTerminal 47 #define accInoutTerminal 48 #define accCombPrim 140 #define accSeqPrim 142 #define accAndGate 144 #define accNandGate 146 #define accNorGate 148 #define accOrGate 150 #define accXorGate 152 #define accXnorGate 154 #define accBufGate 156 #define accNotGate 158 #define accBufif0Gate 160 #define accBufif1Gate 162 #define accNotif0Gate 164 #define accNotif1Gate 166 #define accNmosGate 168 #define accPmosGate 170 #define accCmosGate 172 #define accRnmosGate 174 #define accRpmosGate 176 #define accRcmosGate 178 #define accRtranGate 180 #define accRtranif0Gate 182 #define accRtranif1Gate 184 #define accTranGate 186 #define accTranif0Gate 188 #define accTranif1Gate 190 #define accPullupGate 192 #define accPulldownGate 194 #define accIntegerParam 200 #define accIntParam accIntegerParam #define accRealParam 202 #define accStringParam 204 #define accPath 206 #define accTchk 208 #define accPrimitive 210 #define accBit 212 #define accPortBit 214 #define accNetBit 216 #define accRegBit 218 #define accParameter 220 #define accSpecparam 222 #define accTopModule 224 #define accModuleInstance 226 #define accCellInstance 228 #define accModPath 230 #define accWirePath 234 #define accInterModPath 236 #define accScalarPort 250 #define accBitSelectPort 252 #define accPartSelectPort 254 #define accVectorPort 256 #define accConcatPort 258 #define accWire 260 #define accWand 261 #define accWor 262 #define accTri 263 #define accTriand 264 #define accTrior 265 #define accTri0 266 #define accTri1 267 #define accTrireg 268 #define accSupply0 269 #define accSupply1 270 #define accNamedEvent 280 #define accEventVar accNamedEvent #define accIntegerVar 281 #define accIntVar 281 #define accRealVar 282 #define accTimeVar 283 #define accScalar 300 #define accVector 302 #define accCollapsedNet 304 #define accExpandedVector 306 #define accUnExpandedVector 307 #define accProtected 308 #define accSetup 366 #define accHold 367 #define accWidth 368 #define accPeriod 369 #define accRecovery 370 #define accSkew 371 #define accNochange 376 #define accNoChange accNochange #define accSetuphold 377 #define accInput 402 #define accOutput 404 #define accInout 406 #define accMixedIo 407 #define accPositive 408 #define accNegative 410 #define accUnknown 412 #define accPathTerminal 420 #define accPathInput 422 #define accPathOutput 424 #define accDataPath 426 #define accTchkTerminal 428 #define accBitSelect 500 #define accPartSelect 502 #define accTask 504 #define accFunction 506 #define accStatement 508 #define accTaskCall 510 #define accFunctionCall 512 #define accSystemTask 514 #define accSystemFunction 516 #define accSystemRealFunction 518 #define accUserTask 520 #define accUserFunction 522 #define accUserRealFunction 524 #define accNamedBeginStat 560 #define accNamedForkStat 564 #define accConstant 600 #define accConcat 610 #define accOperator 620 #define accMinTypMax 696 #define accModPathHasIfnone 715 /*------------------ parameter values for acc_configure() -------------------*/ #define accPathDelayCount 1 #define accPathDelimStr 2 #define accDisplayErrors 3 #define accDefaultAttr0 4 #define accToHiZDelay 5 #define accEnableArgs 6 #define accDisplayWarnings 8 #define accDevelopmentVersion 11 #define accMapToMipd 17 #define accMinTypMaxDelays 19 /*------------ edge information used by acc_handle_tchk(), etc. ------------*/ #define accNoedge 0 #define accNoEdge 0 #define accEdge01 1 #define accEdge10 2 #define accEdge0x 4 #define accEdgex1 8 #define accEdge1x 16 #define accEdgex0 32 #define accPosedge 13 #define accPosEdge accPosedge #define accNegedge 50 #define accNegEdge accNegedge /*------------------------------- delay modes -------------------------------*/ #define accDelayModeNone 0 #define accDelayModePath 1 #define accDelayModeDistrib 2 #define accDelayModeUnit 3 #define accDelayModeZero 4 #define accDelayModeMTM 5 /*------------ values for type field in t_setval_delay structure ------------*/ #define accNoDelay 0 #define accInertialDelay 1 #define accTransportDelay 2 #define accPureTransportDelay 3 #define accForceFlag 4 #define accReleaseFlag 5 #define accAssignFlag 6 #define accDeassignFlag 7 /*------------ values for type field in t_setval_value structure ------------*/ #define accBinStrVal 1 #define accOctStrVal 2 #define accDecStrVal 3 #define accHexStrVal 4 #define accScalarVal 5 #define accIntVal 6 #define accRealVal 7 #define accStringVal 8 #define accVectorVal 10 /*------------------------------ scalar values ------------------------------*/ #define acc0 0 #define acc1 1 #define accX 2 #define accZ 3 /*---------------------------- VCL scalar values ----------------------------*/ #define vcl0 acc0 #define vcl1 acc1 #define vclX accX #define vclx vclX #define vclZ accZ #define vclz vclZ /*----------- values for vc_reason field in t_vc_record structure -----------*/ #define logic_value_change 1 #define strength_value_change 2 #define real_value_change 3 #define vector_value_change 4 #define event_value_change 5 #define integer_value_change 6 #define time_value_change 7 #define sregister_value_change 8 #define vregister_value_change 9 #define realtime_value_change 10 /*--------------------------- VCL strength values ---------------------------*/ #define vclSupply 7 #define vclStrong 6 #define vclPull 5 #define vclLarge 4 #define vclWeak 3 #define vclMedium 2 #define vclSmall 1 #define vclHighZ 0 /*----------------------- flags used with acc_vcl_add -----------------------*/ #define vcl_verilog_logic 2 #define VCL_VERILOG_LOGIC vcl_verilog_logic #define vcl_verilog_strength 3 #define VCL_VERILOG_STRENGTH vcl_verilog_strength /*---------------------- flags used with acc_vcl_delete ---------------------*/ #define vcl_verilog vcl_verilog_logic #define VCL_VERILOG vcl_verilog /*---------- values for the type field in the t_acc_time structure --------- */ #define accTime 1 #define accSimTime 2 #define accRealTime 3 /*------------------------------ product types ------------------------------*/ #define accSimulator 1 #define accTimingAnalyzer 2 #define accFaultSimulator 3 #define accOther 4 /*---------------------------------------------------------------------------*/ /*-------------------------- structure definitions --------------------------*/ /*---------------------------------------------------------------------------*/ typedef PLI_INT32 (*consumer_function)(); /*----------------- data structure used with acc_set_value() ----------------*/ typedef struct t_acc_time { PLI_INT32 type; PLI_INT32 low, high; double real; } s_acc_time, *p_acc_time; /*----------------- data structure used with acc_set_value() ----------------*/ typedef struct t_setval_delay { s_acc_time time; PLI_INT32 model; } s_setval_delay, *p_setval_delay; /*--------------------- data structure of vector values ---------------------*/ typedef struct t_acc_vecval { PLI_INT32 aval; PLI_INT32 bval; } s_acc_vecval, *p_acc_vecval; /*------ data structure used with acc_set_value() and acc_fetch_value() -----*/ typedef struct t_setval_value { PLI_INT32 format; union { PLI_BYTE8 *str; PLI_INT32 scalar; PLI_INT32 integer; double real; p_acc_vecval vector; } value; } s_setval_value, *p_setval_value, s_acc_value, *p_acc_value; /*----------------------- structure for VCL strengths -----------------------*/ typedef struct t_strengths { PLI_UBYTE8 logic_value; PLI_UBYTE8 strength1; PLI_UBYTE8 strength2; } s_strengths, *p_strengths; /*--------------- structure passed to callback routine for VCL --------------*/ typedef struct t_vc_record { PLI_INT32 vc_reason; PLI_INT32 vc_hightime; PLI_INT32 vc_lowtime; PLI_BYTE8 *user_data; union { PLI_UBYTE8 logic_value; double real_value; handle vector_handle; s_strengths strengths_s; } out_value; } s_vc_record, *p_vc_record; /*------------- structure used with acc_fetch_location() routine ------------*/ typedef struct t_location { PLI_INT32 line_no; PLI_BYTE8 *filename; } s_location, *p_location; /*---------- structure used with acc_fetch_timescale_info() routine ---------*/ typedef struct t_timescale_info { PLI_INT16 unit; PLI_INT16 precision; } s_timescale_info, *p_timescale_info; /*---------------------------------------------------------------------------*/ /*-------------------------- routine declarations ---------------------------*/ /*---------------------------------------------------------------------------*/ XXTERN PLI_INT32 acc_append_delays PROTO_PARAMS((handle object, ...)); XXTERN PLI_INT32 acc_append_pulsere PROTO_PARAMS((handle object, double val1r, double val1x, ...)); XXTERN void acc_close PROTO_PARAMS((void)); XXTERN handle *acc_collect PROTO_PARAMS((handle (*p_next_routine)(), handle scope_object, PLI_INT32 *aof_count)); XXTERN PLI_INT32 acc_compare_handles PROTO_PARAMS((handle h1, handle h2)); XXTERN PLI_INT32 acc_configure PROTO_PARAMS((PLI_INT32 item, PLI_BYTE8 *value)); XXTERN PLI_INT32 acc_count PROTO_PARAMS((handle (*next_func)(), handle object_handle)); XXTERN PLI_INT32 acc_fetch_argc PROTO_PARAMS((void)); XXTERN PLI_BYTE8 **acc_fetch_argv PROTO_PARAMS((void)); XXTERN double acc_fetch_attribute PROTO_PARAMS((handle object, ...)); XXTERN PLI_INT32 acc_fetch_attribute_int PROTO_PARAMS((handle object, ...)); XXTERN PLI_BYTE8 *acc_fetch_attribute_str PROTO_PARAMS((handle object, ...)); XXTERN PLI_BYTE8 *acc_fetch_defname PROTO_PARAMS((handle object_handle)); XXTERN PLI_INT32 acc_fetch_delay_mode PROTO_PARAMS((handle object_p)); XXTERN PLI_INT32 acc_fetch_delays PROTO_PARAMS((handle object, ...)); XXTERN PLI_INT32 acc_fetch_direction PROTO_PARAMS((handle object_handle)); XXTERN PLI_INT32 acc_fetch_edge PROTO_PARAMS((handle acc_obj)); XXTERN PLI_BYTE8 *acc_fetch_fullname PROTO_PARAMS((handle object_handle)); XXTERN PLI_INT32 acc_fetch_fulltype PROTO_PARAMS((handle object_h)); XXTERN PLI_INT32 acc_fetch_index PROTO_PARAMS((handle object_handle)); XXTERN double acc_fetch_itfarg PROTO_PARAMS((PLI_INT32 n, handle tfinst)); XXTERN PLI_INT32 acc_fetch_itfarg_int PROTO_PARAMS((PLI_INT32 n, handle tfinst)); XXTERN PLI_BYTE8 *acc_fetch_itfarg_str PROTO_PARAMS((PLI_INT32 n, handle tfinst)); XXTERN PLI_INT32 acc_fetch_location PROTO_PARAMS((p_location location_p, handle object)); XXTERN PLI_BYTE8 *acc_fetch_name PROTO_PARAMS((handle object_handle)); XXTERN PLI_INT32 acc_fetch_paramtype PROTO_PARAMS((handle param_p)); XXTERN double acc_fetch_paramval PROTO_PARAMS((handle param)); XXTERN PLI_INT32 acc_fetch_polarity PROTO_PARAMS((handle path)); XXTERN PLI_INT32 acc_fetch_precision PROTO_PARAMS((void)); XXTERN PLI_INT32 acc_fetch_pulsere PROTO_PARAMS((handle path_p, double *val1r, double *val1e, ...)); XXTERN PLI_INT32 acc_fetch_range PROTO_PARAMS((handle node, PLI_INT32 *msb, PLI_INT32 *lsb)); XXTERN PLI_INT32 acc_fetch_size PROTO_PARAMS((handle obj_h)); XXTERN double acc_fetch_tfarg PROTO_PARAMS((PLI_INT32 n)); XXTERN PLI_INT32 acc_fetch_tfarg_int PROTO_PARAMS((PLI_INT32 n)); XXTERN PLI_BYTE8 *acc_fetch_tfarg_str PROTO_PARAMS((PLI_INT32 n)); XXTERN void acc_fetch_timescale_info PROTO_PARAMS((handle obj, p_timescale_info aof_timescale_info)); XXTERN PLI_INT32 acc_fetch_type PROTO_PARAMS((handle object_handle)); XXTERN PLI_BYTE8 *acc_fetch_type_str PROTO_PARAMS((PLI_INT32 type)); XXTERN PLI_BYTE8 *acc_fetch_value PROTO_PARAMS((handle object_handle, PLI_BYTE8 *format_str, p_acc_value acc_value_p)); XXTERN void acc_free PROTO_PARAMS((handle *array_ptr)); XXTERN handle acc_handle_by_name PROTO_PARAMS((PLI_BYTE8 *inst_name, handle scope_p)); XXTERN handle acc_handle_condition PROTO_PARAMS((handle obj)); XXTERN handle acc_handle_conn PROTO_PARAMS((handle term_p)); XXTERN handle acc_handle_datapath PROTO_PARAMS((handle path)); XXTERN handle acc_handle_hiconn PROTO_PARAMS((handle port_ref)); XXTERN handle acc_handle_interactive_scope PROTO_PARAMS((void)); XXTERN handle acc_handle_itfarg PROTO_PARAMS((PLI_INT32 n, handle tfinst)); XXTERN handle acc_handle_loconn PROTO_PARAMS((handle port_ref)); XXTERN handle acc_handle_modpath PROTO_PARAMS((handle mod_p, PLI_BYTE8 *pathin_name, PLI_BYTE8 *pathout_name, ...)); XXTERN handle acc_handle_notifier PROTO_PARAMS((handle tchk)); XXTERN handle acc_handle_object PROTO_PARAMS((PLI_BYTE8 *inst_name, ...)); XXTERN handle acc_handle_parent PROTO_PARAMS((handle object_p)); XXTERN handle acc_handle_path PROTO_PARAMS((handle source, handle destination)); XXTERN handle acc_handle_pathin PROTO_PARAMS((handle path_p)); XXTERN handle acc_handle_pathout PROTO_PARAMS((handle path_p)); XXTERN handle acc_handle_port PROTO_PARAMS((handle mod_handle, PLI_INT32 port_num, ...)); XXTERN handle acc_handle_scope PROTO_PARAMS((handle object)); XXTERN handle acc_handle_simulated_net PROTO_PARAMS((handle net_h)); XXTERN handle acc_handle_tchk PROTO_PARAMS((handle mod_p, PLI_INT32 tchk_type, PLI_BYTE8 *arg1_conn_name, PLI_INT32 arg1_edgetype, ...)); XXTERN handle acc_handle_tchkarg1 PROTO_PARAMS((handle tchk)); XXTERN handle acc_handle_tchkarg2 PROTO_PARAMS((handle tchk)); XXTERN handle acc_handle_terminal PROTO_PARAMS((handle gate_handle, PLI_INT32 terminal_index)); XXTERN handle acc_handle_tfarg PROTO_PARAMS((PLI_INT32 n)); XXTERN handle acc_handle_tfinst PROTO_PARAMS((void)); XXTERN PLI_INT32 acc_initialize PROTO_PARAMS((void)); XXTERN handle acc_next PROTO_PARAMS((PLI_INT32 *type_list, handle h_scope, handle h_object)); XXTERN handle acc_next_bit PROTO_PARAMS ((handle vector, handle bit)); XXTERN handle acc_next_cell PROTO_PARAMS((handle scope, handle cell)); XXTERN handle acc_next_cell_load PROTO_PARAMS((handle net_handle, handle load)); XXTERN handle acc_next_child PROTO_PARAMS((handle mod_handle, handle child)); XXTERN handle acc_next_driver PROTO_PARAMS((handle net, handle driver)); XXTERN handle acc_next_hiconn PROTO_PARAMS((handle port, handle hiconn)); XXTERN handle acc_next_input PROTO_PARAMS((handle path, handle pathin)); XXTERN handle acc_next_load PROTO_PARAMS((handle net, handle load)); XXTERN handle acc_next_loconn PROTO_PARAMS((handle port, handle loconn)); XXTERN handle acc_next_modpath PROTO_PARAMS((handle mod_p, handle path)); XXTERN handle acc_next_net PROTO_PARAMS((handle mod_handle, handle net)); XXTERN handle acc_next_output PROTO_PARAMS((handle path, handle pathout)); XXTERN handle acc_next_parameter PROTO_PARAMS((handle module_p, handle param)); XXTERN handle acc_next_port PROTO_PARAMS((handle ref_obj_p, handle port)); XXTERN handle acc_next_portout PROTO_PARAMS((handle mod_p, handle port)); XXTERN handle acc_next_primitive PROTO_PARAMS((handle mod_handle, handle prim)); XXTERN handle acc_next_scope PROTO_PARAMS((handle ref_scope_p, handle scope)); XXTERN handle acc_next_specparam PROTO_PARAMS((handle module_p, handle sparam)); XXTERN handle acc_next_tchk PROTO_PARAMS((handle mod_p, handle tchk)); XXTERN handle acc_next_terminal PROTO_PARAMS((handle gate_handle, handle term)); XXTERN handle acc_next_topmod PROTO_PARAMS((handle topmod)); XXTERN PLI_INT32 acc_object_in_typelist PROTO_PARAMS((handle object, PLI_INT32 *type_list)); XXTERN PLI_INT32 acc_object_of_type PROTO_PARAMS((handle object, PLI_INT32 type)); XXTERN PLI_INT32 acc_product_type PROTO_PARAMS((void)); XXTERN PLI_BYTE8 *acc_product_version PROTO_PARAMS((void)); XXTERN PLI_INT32 acc_release_object PROTO_PARAMS((handle obj)); XXTERN PLI_INT32 acc_replace_delays PROTO_PARAMS((handle object, ...)); XXTERN PLI_INT32 acc_replace_pulsere PROTO_PARAMS((handle object, double val1r, double val1x, ...)); XXTERN void acc_reset_buffer PROTO_PARAMS((void)); XXTERN PLI_INT32 acc_set_interactive_scope PROTO_PARAMS((handle scope, PLI_INT32 callback_flag)); XXTERN PLI_INT32 acc_set_pulsere PROTO_PARAMS((handle path_p, double val1r, double val1e)); XXTERN PLI_BYTE8 *acc_set_scope PROTO_PARAMS((handle object, ...)); XXTERN PLI_INT32 acc_set_value PROTO_PARAMS((handle obj, p_setval_value setval_p, p_setval_delay delay_p)); XXTERN void acc_vcl_add PROTO_PARAMS((handle object_p, PLI_INT32 (*consumer)(p_vc_record), PLI_BYTE8 *user_data, PLI_INT32 vcl_flags)); XXTERN void acc_vcl_delete PROTO_PARAMS((handle object_p, PLI_INT32 (*consumer)(p_vc_record), PLI_BYTE8 *user_data, PLI_INT32 vcl_flags)); XXTERN PLI_BYTE8 *acc_version PROTO_PARAMS((void)); /*---------------------------------------------------------------------------*/ /*----------------------- global variable definitions -----------------------*/ /*---------------------------------------------------------------------------*/ PLI_VEXTERN PLI_DLLISPEC PLI_INT32 acc_error_flag; /*---------------------------------------------------------------------------*/ /*---------------------------- macro definitions ----------------------------*/ /*---------------------------------------------------------------------------*/ #define acc_handle_calling_mod_m acc_handle_parent((handle)tf_getinstance()) #undef PLI_EXTERN #undef PLI_VEXTERN #ifdef ACC_USER_DEFINED_DLLISPEC #undef ACC_USER_DEFINED_DLLISPEC #undef PLI_DLLISPEC #endif #ifdef ACC_USER_DEFINED_DLLESPEC #undef ACC_USER_DEFINED_DLLESPEC #undef PLI_DLLESPEC #endif #ifdef PLI_PROTOTYPES #undef PLI_PROTOTYPES #undef PROTO_PARAMS #undef XXTERN #undef EETERN #endif #ifdef __cplusplus } #endif #endif /* ACC_USER_H */ gtkwave-gtk3-3.3.125/contrib/xml2stems/0000775000175000017500000000000015047725113017114 5ustar bybellbybellgtkwave-gtk3-3.3.125/contrib/xml2stems/Makefile.in0000664000175000017500000004534715047725113021176 0ustar bybellbybell# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : bin_PROGRAMS = xml2stems$(EXEEXT) subdir = contrib/xml2stems 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_xml2stems_OBJECTS = xml2stems.$(OBJEXT) xml2stems_OBJECTS = $(am_xml2stems_OBJECTS) xml2stems_LDADD = $(LDADD) 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 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 = $(xml2stems_SOURCES) DIST_SOURCES = $(xml2stems_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@ GLIB_COMPILE_SCHEMAS = @GLIB_COMPILE_SCHEMAS@ GPERF = @GPERF@ GREP = @GREP@ GSETTINGS_CFLAGS = @GSETTINGS_CFLAGS@ GSETTINGS_DISABLE_SCHEMAS_COMPILE = @GSETTINGS_DISABLE_SCHEMAS_COMPILE@ GTK_CFLAGS = @GTK_CFLAGS@ 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_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_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@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ RANLIB = @RANLIB@ RPC_CFLAGS = @RPC_CFLAGS@ RPC_LDADD = @RPC_LDADD@ 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@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ 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@ gsettingsschemadir = @gsettingsschemadir@ 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 = AM_LIBS = xml2stems_SOURCES = \ xml2stems.cc all: all-am .SUFFIXES: .SUFFIXES: .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 contrib/xml2stems/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign contrib/xml2stems/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) xml2stems$(EXEEXT): $(xml2stems_OBJECTS) $(xml2stems_DEPENDENCIES) $(EXTRA_xml2stems_DEPENDENCIES) @rm -f xml2stems$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(xml2stems_OBJECTS) $(xml2stems_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml2stems.Po@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` 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-gtk3-3.3.125/contrib/xml2stems/xml2stems.cc0000664000175000017500000002347115047725113021370 0ustar bybellbybell/* * Copyright (c) 2018 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 #include #include #include #include using namespace std; #define BUF_SIZ 65536 std::map * parse_xml_tags(char *s, int *oneline) { char sprev; std::map *fId = new std::map ; if(oneline) *oneline = 0; while(*s) { if(!isspace(*s)) { char *tag_s = s; char *tag_e = NULL; char *val_s = NULL; char *val_e = NULL; sprev = 0; while(*s) { if(!s) goto bot; if(*s == '>') { if(sprev == '/') { if(oneline) *oneline = 1; } goto bot; } sprev = *s; if(*s == '=') { tag_e = s; break; } s++; } while(*s) { if(!s) goto bot; if(*s == '"') { val_s = ++s; break; } s++; } while(*s) { if(!s) goto bot; if(*s == '"') { val_e = s; break; } s++; } if(tag_e && val_e) { *tag_e = 0; *val_e = 0; fId->insert(pair (tag_s, val_s)); } } s++; } bot: return(fId); } void xml2stems(FILE *fi, FILE *fo, int is_verilator_sim) { std::map fId; std::stack mId; queue bQueue; int in_files = 0; int geninst = 0; int func_nesting_cnt = 0; while(!feof(fi)) { char buf[BUF_SIZ + 1]; int endtag; char *ln = fgets(buf, BUF_SIZ, fi); char *pnt = ln; if(!pnt) goto bot; while(*pnt) { if(*pnt == ' ') { pnt++; continue; } else { break; } } if(*pnt != '<') goto bot; pnt++; endtag = (*pnt == '/'); pnt += endtag; switch(*pnt) { case 'b': if(!strncmp(pnt, "begin", 5) && !func_nesting_cnt) { if(!endtag) { char *s = pnt + 5; int oneline = 0; std::map *xmt = parse_xml_tags(s, &oneline); if(xmt) { const char *nam = (*xmt)[string("name")].c_str(); const char *fl = (*xmt)[string("fl")].c_str(); const char *loc = (*xmt)[string("loc")].c_str(); int loc_offset = 0; if(!fl || !strlen(fl)) { fl = loc; loc_offset = 1; } if(!oneline) { bQueue.push((*xmt)[string("name")]); if(fl && nam && nam[0]) { char fl_dup[strlen(fl)+1]; const char *s = fl; char *d = fl_dup; while(isalpha(*s)) { *(d++) = *(s++); } *d = 0; s+=loc_offset; unsigned int lineno = atoi(s); const char *mnam = fId[fl_dup].c_str(); fprintf(fo, "++ begin %s file %s line %d\n", nam, mnam, lineno); char *genname = (char *)malloc(strlen(nam) + 32); sprintf(genname, "%s:G%d", nam, geninst++); fprintf(fo, "++ comp %s type %s parent %s\n", genname, genname, mId.top().c_str()); fprintf(fo, "++ module %s file %s lines %d - %d\n", genname, mnam, lineno, lineno); /* don't need line number it truly ends at */ mId.push(genname); free(genname); } } delete xmt; } } else { string bs = bQueue.front(); bQueue.pop(); const char *nam = bs.c_str(); if(nam && nam[0]) { mId.pop(); fprintf(fo, "++ endbegin %s\n", nam); } } } break; case 'm': if(!strncmp(pnt, "module", 6) && strncmp(pnt, "module_files", 12)) { if(!endtag) { char *s = pnt + 6; std::map *xmt = parse_xml_tags(s, NULL); if(xmt) { const char *fl = (*xmt)[string("fl")].c_str(); const char *nam = (*xmt)[string("name")].c_str(); const char *tms = (*xmt)[string("topModule")].c_str(); const char *loc = (*xmt)[string("loc")].c_str(); int loc_offset = 0; if(!fl || !strlen(fl)) { fl = loc; loc_offset = 1; } if(fl && nam && tms) { int tm = (tms[0] == '1') ? is_verilator_sim : 0; mId.push(nam); char fl_dup[strlen(fl)+1]; const char *s = fl; char *d = fl_dup; while(isalpha(*s)) { *(d++) = *(s++); } *d = 0; s += loc_offset; unsigned int lineno = atoi(s); const char *mnam = fId[fl_dup].c_str(); fprintf(fo, "++ module %s file %s lines %d - %d\n", nam, mnam, lineno, lineno); /* don't need line number it truly ends at */ if(tm) { fprintf(fo, "++ module TOP file %s lines %d - %d\n", "(VerilatorTop)", 1, 1); fprintf(fo, "++ comp %s type %s parent TOP\n", nam, nam); } } delete xmt; } } else { if(!mId.empty()) { mId.pop(); } } } case 'f': if(!strncmp(pnt, "func", 4)) { func_nesting_cnt = (!endtag) ? (func_nesting_cnt+1) : (func_nesting_cnt-1); } else if((!strncmp(pnt, "files", 5)) || (!strncmp(pnt, "module_files", 12))) { in_files = (!endtag); } else { if((!endtag) && (in_files) && (!strncmp(pnt, "file", 4))) { char *s = pnt + 4; std::map *xmt = parse_xml_tags(s, NULL); if(xmt) { const char *cod = (*xmt)[string("id")].c_str(); const char *fil = (*xmt)[string("filename")].c_str(); if(cod && fil) { fId.insert(pair (cod, fil)); } delete xmt; } } } break; case 'i': if((!endtag) && (!strncmp(pnt, "instance", 8))) { char *s = pnt + 8; std::map *xmt = parse_xml_tags(s, NULL); if(xmt) { const char *nam = (*xmt)[string("name")].c_str(); const char *defnam = (*xmt)[string("defName")].c_str(); if(!mId.empty() && nam && defnam) { fprintf(fo, "++ comp %s type %s parent %s\n", nam, defnam, mId.top().c_str()); } delete xmt; } } break; case 'p': if(!strncmp(pnt, "primitive", 9)) { if(!endtag) { char *s = pnt + 9; std::map *xmt = parse_xml_tags(s, NULL); if(xmt) { const char *fl = (*xmt)[string("fl")].c_str(); const char *nam = (*xmt)[string("name")].c_str(); const char *loc = (*xmt)[string("loc")].c_str(); int loc_offset = 0; if(!fl || !strlen(fl)) { fl = loc; loc_offset = 1; } if(fl && nam) { mId.push(nam); char fl_dup[strlen(fl)+1]; const char *s = fl; char *d = fl_dup; while(isalpha(*s)) { *(d++) = *(s++); } *d = 0; s += loc_offset; unsigned int lineno = atoi(s); const char *mnam = fId[fl_dup].c_str(); fprintf(fo, "++ udp %s file %s lines %d - %d\n", nam, mnam, lineno, lineno); /* don't need line number it truly ends at */ } delete xmt; } } else { if(!mId.empty()) { mId.pop(); } } } break; default: break; } bot: 1; } } int main(int argc, char **argv) { FILE *fi, *fo; int rc = 0; int is_verilator_sim = 0; while(argc > 1) { if(*argv[1] != '-') { break; } else if(!strcmp(argv[1], "--")) { argc--; argv++; break; } else if(!strcmp(argv[1], "-V") || !strcmp(argv[1], "--vl_sim")) { is_verilator_sim = 1; argc--; argv++; } else if(!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) { argc = 1; break; } else { fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], argv[1]); argc = 1; break; } } switch(argc) { case 2: fi = (!strcmp("-", argv[1])) ? stdin : fopen(argv[1], "rb"); if(fi) { fo = stdout; xml2stems(fi, fo, is_verilator_sim); if(fi != stdin) fclose(fi); } else { fprintf(stderr, "Could not open '%s', exiting.\n", argv[1]); perror("Why"); rc = 255; } break; case 3: fi = (!strcmp("-", argv[1])) ? stdin : fopen(argv[1], "rb"); if(fi) { fo = fopen(argv[2], "wb"); if(fo) { xml2stems(fi, fo, is_verilator_sim); if(fi != stdin) fclose(fi); fclose(fo); } else { if(fi != stdin) fclose(fi); fprintf(stderr, "Could not open '%s', exiting.\n", argv[2]); perror("Why"); rc = 255; } } else { fprintf(stderr, "Could not open '%s', exiting.\n", argv[1]); perror("Why"); rc = 255; } break; default: printf("Usage: %s [OPTION] infile.xml [outfile.stems]\n\n" " -V, --vl_sim add TOP hierarchy for Verilator sim\n" " -h, --help display this help then exit\n\n" "Converts Verilator XML file to rtlbrowse stems format. For example:\n\n" "verilator -Wno-fatal des.v -xml-only --bbox-sys\n" "xml2stems obj_dir/Vdes.xml des.stems\n" "gtkwave -t des.stems des.fst\n\n" "Use - as input filename for stdin.\n" "Omitting optional stems outfile name emits to stdout.\n", argv[0]); break; } bot: return(rc); } gtkwave-gtk3-3.3.125/contrib/xml2stems/Makefile.am0000664000175000017500000000015315047725113021147 0ustar bybellbybell## -*- makefile -*- ## bin_PROGRAMS= xml2stems AM_CFLAGS = AM_LIBS = xml2stems_SOURCES= \ xml2stems.cc gtkwave-gtk3-3.3.125/contrib/Makefile.in0000664000175000017500000004562215047725113017234 0ustar bybellbybell# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = contrib DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am 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 = 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 DIST_SUBDIRS = $(SUBDIRS) 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@ GLIB_COMPILE_SCHEMAS = @GLIB_COMPILE_SCHEMAS@ GPERF = @GPERF@ GREP = @GREP@ GSETTINGS_CFLAGS = @GSETTINGS_CFLAGS@ GSETTINGS_DISABLE_SCHEMAS_COMPILE = @GSETTINGS_DISABLE_SCHEMAS_COMPILE@ GTK_CFLAGS = @GTK_CFLAGS@ 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_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_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@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ RANLIB = @RANLIB@ RPC_CFLAGS = @RPC_CFLAGS@ RPC_LDADD = @RPC_LDADD@ 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@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ 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@ gsettingsschemadir = @gsettingsschemadir@ 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 = rtlbrowse xml2stems json2stems bundle_for_osx fst_jni wlf2vcd fsdb2vcd all: all-recursive .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 contrib/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign contrib/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): # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic cscopelist-am ctags ctags-am \ distclean 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 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-gtk3-3.3.125/contrib/rtlbrowse/0000775000175000017500000000000015047725113017201 5ustar bybellbybellgtkwave-gtk3-3.3.125/contrib/rtlbrowse/wavelink.h0000664000175000017500000000164615047725113021201 0ustar bybellbybell#ifndef BROWSE_WAVELINK_H #define BROWSE_WAVELINK_H /* kill the GLOBALS_H header inclusion as it's not needed here */ #define GLOBALS_H #include "../../src/ae2.h" #include "../../src/debug.h" #include "../../src/helpers/vzt_read.h" #include "../../src/helpers/lxt2_read.h" #include extern struct vzt_rd_trace *vzt; extern struct lxt2_rd_trace *lx2; extern void *fst; extern int64_t timezero; #ifdef AET2_IS_PRESENT extern AE2_HANDLE ae2; #endif enum treeview2_columns { XXX2_NAME_COLUMN, XXX2_TREE_COLUMN, XXX2_NUM_COLUMNS }; #define XXX_GTK_OBJECT(x) x #define XXX_GTK_OBJECT_GET_CLASS GTK_OBJECT_GET_CLASS /* gtk3->4 deprecated */ #if GTK_CHECK_VERSION(3,0,0) #define YYY_GTK_TEXT_VIEW GTK_SCROLLABLE #define YYY_gtk_text_view_get_vadjustment gtk_scrollable_get_vadjustment #else #define YYY_GTK_TEXT_VIEW GTK_TEXT_VIEW #define YYY_gtk_text_view_get_vadjustment gtk_text_view_get_vadjustment #endif #endif gtkwave-gtk3-3.3.125/contrib/rtlbrowse/vlex.l0000664000175000017500000001462415047725113020343 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2006-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. */ %option nounput %{ /* * vlex.l * 06apr06ajb */ #define YY_INPUT(buf, result, max_size) \ result = v_preproc(buf, max_size); #include "vlex.h" int my_yylineno = 0; static int yywrap(void) { return(1); } static int v_preproc_initialized = 0; char *v_preproc_name = NULL; static int v_preproc(char *buf, int max_size) { (void)max_size; int ch; if(!v_preproc_initialized) { yyin = fopen(v_preproc_name, "rb"); if(!yyin) return(0); v_preproc_initialized = 1; my_yylineno = 1; } ch = fgetc(yyin); if(ch!=EOF) { buf[0] = ch; buf[1] = 0; return(1); } else { fclose(yyin); yyin = NULL; v_preproc_initialized = 0; return (0); } } %} %x CMNT %x PREPROC %% "/*" { BEGIN CMNT; return V_CMT; } "/*" { return V_CMT; } "*/" { BEGIN INITIAL; return V_CMT; } [^\*\\/\n]+ { return V_CMT; } . { return V_CMT; } \n { my_yylineno++; return V_CMT; } always { return V_KW; } and { return V_KW; } assign { return V_KW; } begin { return V_KW; } buf { return V_KW; } bufif0 { return V_KW; } bufif1 { return V_KW; } case { return V_KW; } casex { return V_KW; } casez { return V_KW; } cmos { return V_KW; } deassign { return V_KW; } default { return V_KW; } defparam { return V_KW; } disable { return V_KW; } edge { return V_KW; } else { return V_KW; } end { return V_KW; } endcase { return V_KW; } event { return V_KW; } for { return V_KW; } force { return V_KW; } forever { return V_KW; } fork { return V_KW; } highz0 { return V_KW; } highz1 { return V_KW; } if { return V_KW; } initial { return V_KW; } inout { return V_KW; } input { return V_KW; } integer { return V_KW; } join { return V_KW; } large { return V_KW; } medium { return V_KW; } nand { return V_KW; } negedge { return V_KW; } nmos { return V_KW; } nor { return V_KW; } not { return V_KW; } notif0 { return V_KW; } notif1 { return V_KW; } or { return V_KW; } output { return V_KW; } parameter { return V_KW; } pmos { return V_KW; } posedge { return V_KW; } pull0 { return V_KW; } pull1 { return V_KW; } pulldown { return V_KW; } pullup { return V_KW; } rcmos { return V_KW; } real { return V_KW; } realtime { return V_KW; } reg { return V_KW; } release { return V_KW; } repeat { return V_KW; } rnmos { return V_KW; } rpmos { return V_KW; } rtran { return V_KW; } rtranif0 { return V_KW; } rtranif1 { return V_KW; } scalared { return V_KW; } small { return V_KW; } specparam { return V_KW; } strong0 { return V_KW; } strong1 { return V_KW; } supply0 { return V_KW; } supply1 { return V_KW; } time { return V_KW; } tran { return V_KW; } tranif0 { return V_KW; } tranif1 { return V_KW; } tri { return V_KW; } tri0 { return V_KW; } tri1 { return V_KW; } triand { return V_KW; } trior { return V_KW; } trireg { return V_KW; } vectored { return V_KW; } wait { return V_KW; } wand { return V_KW; } weak0 { return V_KW; } weak1 { return V_KW; } while { return V_KW; } wire { return V_KW; } wor { return V_KW; } xnor { return V_KW; } xor { return V_KW; } task { return V_KW; } endtask { return V_KW; } function { return V_KW; } endfunction { return V_KW; } table { return V_KW; } endtable { return V_KW; } specify { return V_KW; } endspecify { return V_KW; } automatic { return V_KW_2005; } cell { return V_KW_2005; } config { return V_KW_2005; } design { return V_KW_2005; } endconfig { return V_KW_2005; } endgenerate { return V_KW_2005; } ifnone { return V_KW_2005; } incdir { return V_KW_2005; } include { return V_KW_2005; } instance { return V_KW_2005; } generate { return V_KW_2005; } genvar { return V_KW_2005; } liblist { return V_KW_2005; } library { return V_KW_2005; } localparam { return V_KW_2005; } noshowcancelled { return V_KW_2005; } pulsestyle_onevent { return V_KW_2005; } pulsestyle_ondetect { return V_KW_2005; } unsigned { return V_KW_2005; } showcancelled { return V_KW_2005; } signed { return V_KW_2005; } use { return V_KW_2005; } uwire { return V_KW_2005; } bit { return V_KW_2005; } logic { return V_KW_2005; } int { return V_KW_2005; } shortint { return V_KW_2005; } longint { return V_KW_2005; } byte { return V_KW_2005; } enum { return V_KW_2005; } macromodule { return V_MODULE; } module { return V_MODULE; } primitive { return V_MODULE; } endmodule { return V_ENDMODULE; } endprimitive { return V_ENDMODULE; } [^\n]+ { return V_PREPROC_WS; } \n { my_yylineno++; BEGIN INITIAL; return V_WS; } `[_a-zA-Z][_a-zA-Z\$0-9]* { if(is_builtin_define (yytext+1, yyleng-1)) { BEGIN PREPROC; return(V_PREPROC); } return(V_MACRO); } \\[^ \t\r\n]+ { return V_ID; } \$[_a-zA-Z][_a-zA-Z\$0-9]* { return V_FUNC; } [_a-zA-Z][_a-zA-Z\$0-9]* { return V_ID; } [_a-zA-Z][_a-zA-Z\$0-9]*(\.[_a-zA-Z][_a-zA-Z\$0-9]*)+ { return V_ID; } \.[_a-zA-Z][_a-zA-Z\$0-9]* { return V_PORT; } [0-9]+ { return V_NUMBER; } \'[dD][ \t]*[0-9][0-9_]* { return V_NUMBER; } \'[bB][ \t]*[xXzZ?01][xXzZ?01_]* { return V_NUMBER; } \'[oO][ \t]*[xXzZ0-7][xXzZ0-7_]* { return V_NUMBER; } \'[hH][ \t]*[xXzZ0-9A-Fa-f][xXzZ0-9A-Fa-f_]* { return V_NUMBER; } "*/" { return V_IGNORE; } [ \t\r]+ { return V_WS; } \n { my_yylineno++; return V_WS; } \/\/[^\n]* { return V_CMT; } \"[^\"\r\n]*\" { return V_STRING; } . { return V_IGNORE; } %% gtkwave-gtk3-3.3.125/contrib/rtlbrowse/Makefile.am0000664000175000017500000000311115047725113021231 0ustar bybellbybell## -*- makefile -*- ## # FIXME -- how to figure out automatically when we need these? # SUBDIRS= AET2LIB = AIXFLAGS = -bmaxdata:0xd0000000/dsa -D_WAVE_BE32 BIGFILES = -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 LIBFST_CFLAGS = -I$(srcdir)/../../src/helpers/fst LIBLZMA_CFLAGS = -I$(srcdir)/../../src/liblzma $(LIBXZ_CFLAGS) LIBLZMA_LDADD = $(LIBXZ_LDADD) bin_PROGRAMS= rtlbrowse rtlbrowse_SOURCES = definehash.c fgetdynamic.c fgetdynamic.h \ logfile.c splay.c tcl_helper.c tree_widget.c \ $(srcdir)/../../src/helpers/fst/lz4.c \ $(srcdir)/../../src/helpers/fst/lz4.h \ $(srcdir)/../../src/helpers/fst/fastlz.c \ $(srcdir)/../../src/helpers/fst/fastlz.h \ $(srcdir)/../../src/helpers/fst/fstapi.c \ $(srcdir)/../../src/helpers/fst/fstapi.h \ stem_recurse.c jrb.c jrb.h $(srcdir)/../../src/helpers/vzt_read.c $(srcdir)/../../src/helpers/vzt_read.h \ $(srcdir)/../../src/helpers/lxt2_read.c $(srcdir)/../../src/helpers/lxt2_read.h splay.h \ vlex.l vlex.h wavelink.h $(srcdir)/../../src/liblzma/LzmaLib.c $(srcdir)/../../src/liblzma/LzmaLib.h LDADD= $(GTK_LIBS) $(LIBZ_LDADD) $(LIBBZ2_LDADD) $(LIBLZMA_LDADD) $(AET2_LDADD) \ $(LIBJUDY_LDADD) $(GTK_MAC_LIBS) $(GCONF_LIBS) AM_CFLAGS= -I$(top_srcdir) -I$(top_srcdir)/src -I$(top_srcdir)/src/helpers \ $(GTK_CFLAGS) $(LIBZ_CFLAGS) $(LIBBZ2_CFLAGS) $(LIBLZMA_CFLAGS) \ $(LIBFST_CFLAGS) $(AET2_CFLAGS) $(LIBJUDY_CFLAGS) \ $(GTK_MAC_CFLAGS) $(GCONF_CFLAGS) -DYY_NO_INPUT definehash.c: vpp_keyword.gperf $(GPERF) -C -I -N is_builtin_define $(srcdir)/vpp_keyword.gperf >definehash.c BUILT_SOURCES= definehash.c EXTRA_DIST= vpp_keyword.gperf gtkwave-gtk3-3.3.125/contrib/rtlbrowse/splay.c0000664000175000017500000001102715047725113020476 0ustar bybellbybell/* An implementation of top-down splaying D. Sleator March 1992 "Splay trees", or "self-adjusting search trees" are a simple and efficient data structure for storing an ordered set. The data structure consists of a binary tree, without parent pointers, and no additional fields. It allows searching, insertion, deletion, deletemin, deletemax, splitting, joining, and many other operations, all with amortized logarithmic performance. Since the trees adapt to the sequence of requests, their performance on real access patterns is typically even better. Splay trees are described in a number of texts and papers [1,2,3,4,5]. The code here is adapted from simple top-down splay, at the bottom of page 669 of [3]. It can be obtained via anonymous ftp from spade.pc.cs.cmu.edu in directory /usr/sleator/public. The chief modification here is that the splay operation works even if the item being splayed is not in the tree, and even if the tree root of the tree is NULL. So the line: t = splay(i, t); causes it to search for item with key i in the tree rooted at t. If it's there, it is splayed to the root. If it isn't there, then the node put at the root is the last one before NULL that would have been reached in a normal binary search for i. (It's a neighbor of i in the tree.) This allows many other operations to be easily implemented, as shown below. [1] "Fundamentals of data structures in C", Horowitz, Sahni, and Anderson-Freed, Computer Science Press, pp 542-547. [2] "Data Structures and Their Algorithms", Lewis and Denenberg, Harper Collins, 1991, pp 243-251. [3] "Self-adjusting Binary Search Trees" Sleator and Tarjan, JACM Volume 32, No 3, July 1985, pp 652-686. [4] "Data Structure and Algorithm Analysis", Mark Weiss, Benjamin Cummins, 1992, pp 119-130. [5] "Data Structures, Algorithms, and Performance", Derick Wood, Addison-Wesley, 1993, pp 367-375. note: modified for void pointer passing 120302ajb */ #include "splay.h" ds_Tree * ds_splay (char *i, ds_Tree * t) { /* Simple top down splay, not requiring i to be in the tree t. */ /* What it does is described above. */ ds_Tree N, *l, *r, *y; if (t == NULL) return t; N.left = N.right = NULL; l = r = &N; for (;;) { if (strcmp(i, t->item) <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 (strcmp(i, t->item) > 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 { break; } } l->right = t->left; /* assemble */ r->left = t->right; t->left = N.right; t->right = N.left; return t; } ds_Tree * ds_insert(char *i, ds_Tree * t) { /* Insert i into the tree t, unless it's already there. */ /* Return a pointer to the resulting tree. */ ds_Tree * n; n = (ds_Tree *) calloc (1, sizeof (ds_Tree)); if (n == NULL) { fprintf(stderr, "ds_insert: ran out of memory, exiting.\n"); exit(255); } n->item = i; if (t == NULL) { n->left = n->right = NULL; return n; } t = ds_splay(i,t); if (strcmp(i, t->item) < 0) { n->left = t->left; n->right = t; t->left = NULL; return n; } else if (strcmp(i, t->item) > 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; } } ds_Tree * ds_delete(char *i, ds_Tree * t) { /* Deletes i from the tree if it's there. */ /* Return a pointer to the resulting tree. */ ds_Tree * x; if (t==NULL) return NULL; t = ds_splay(i,t); if (strcmp(i, t->item) == 0) { /* found it */ if (t->left == NULL) { x = t->right; } else { x = ds_splay(i, t->left); x->right = t->right; } free(t); return x; } return t; /* It wasn't there */ } gtkwave-gtk3-3.3.125/contrib/rtlbrowse/vpp_keyword.gperf0000664000175000017500000000044715047725113022604 0ustar bybellbybellcelldefine default_nettype define delay_mode_distributed delay_mode_path delay_mode_unit disable_portfaults else enable_portfaults endcelldefine endif endprotect ifdef ifndef include nosuppress_faults nounconnected_drive protect resetall suppress_faults timescale unconnected_drive undef uselib gtkwave-gtk3-3.3.125/contrib/rtlbrowse/fgetdynamic.c0000664000175000017500000000257215047725113021645 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. */ #ifdef _AIX #pragma alloca #endif #include #include "fgetdynamic.h" #include #if HAVE_ALLOCA_H #include #elif defined(__GNUC__) #ifndef alloca #define alloca __builtin_alloca #endif #endif int fgetmalloc_len; char *fgetmalloc(FILE *handle) { char *pnt, *pnt2; struct alloc_bytechain *bytechain_root=NULL, *bytechain_current=NULL; int ch; fgetmalloc_len=0; for(;;) { ch=fgetc(handle); if((ch==EOF)||(ch==0x00)||(ch=='\n')||(ch=='\r')) break; fgetmalloc_len++; if(bytechain_current) { bytechain_current->next=alloca(sizeof(struct alloc_bytechain)); bytechain_current=bytechain_current->next; bytechain_current->val=(char)ch; bytechain_current->next=NULL; } else { bytechain_root=bytechain_current=alloca(sizeof(struct alloc_bytechain)); bytechain_current->val=(char)ch; bytechain_current->next=NULL; } } if(!fgetmalloc_len) { return(NULL); } else { pnt=pnt2=(char *)malloc(fgetmalloc_len+1); while(bytechain_root) { *(pnt2++)=bytechain_root->val; bytechain_root=bytechain_root->next; } *(pnt2)=0; return(pnt); } } gtkwave-gtk3-3.3.125/contrib/rtlbrowse/splay.h0000664000175000017500000000116615047725113020506 0ustar bybellbybell#ifndef DS_SPLAY_FUNCTIONS_H #define DS_SPLAY_FUNCTIONS_H #include #include #include typedef struct ds_tree_node ds_Tree; struct ds_tree_node { ds_Tree * left, * right; ds_Tree * next_flat; char *item; char *filename; int s_line, e_line; char *fullname; int refcnt; struct ds_component *comp; unsigned resolved : 1; unsigned dnd_to_import : 1; }; struct ds_component { struct ds_component *next; char *compname; ds_Tree *module; }; ds_Tree * ds_splay (char *i, ds_Tree * t); ds_Tree * ds_insert(char *i, ds_Tree * t); ds_Tree * ds_delete(char *i, ds_Tree * t); #endif gtkwave-gtk3-3.3.125/contrib/rtlbrowse/definehash.c0000664000175000017500000001216015047725113021443 0ustar bybellbybell/* C code produced by gperf version 3.0.4 */ /* Command-line: /usr/bin/gperf -C -I -N is_builtin_define ./vpp_keyword.gperf */ /* Computed positions: -k'1,12' */ #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 #include #define TOTAL_KEYWORDS 24 #define MIN_WORD_LENGTH 4 #define MAX_WORD_LENGTH 22 #define MIN_HASH_VALUE 6 #define MAX_HASH_VALUE 45 /* maximum key range = 40, duplicates = 0 */ #ifdef __GNUC__ __inline #else #ifdef __cplusplus inline #endif #endif static unsigned int hash (str, len) register const char *str; register unsigned int len; { static const unsigned char asso_values[] = { 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 15, 46, 46, 46, 3, 0, 25, 0, 46, 46, 20, 46, 46, 46, 46, 0, 46, 25, 46, 0, 25, 0, 5, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46 }; register int hval = len; switch (hval) { default: hval += asso_values[(unsigned char)str[11]]; /*FALLTHROUGH*/ case 11: case 10: case 9: case 8: case 7: case 6: case 5: case 4: case 3: case 2: case 1: hval += asso_values[(unsigned char)str[0]]; break; } return hval; } #ifdef __GNUC__ __inline #if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__ __attribute__ ((__gnu_inline__)) #endif #endif const char * is_builtin_define (str, len) register const char *str; register unsigned int len; { static const char * const wordlist[] = { "", "", "", "", "", "", "define", "", "resetall", "timescale", "undef", "uselib", "", "celldefine", "", "default_nettype", "", "nosuppress_faults", "disable_portfaults", "", "delay_mode_unit", "", "delay_mode_distributed", "", "", "ifdef", "ifndef", "include", "", "else", "endif", "", "protect", "", "", "endprotect", "", "unconnected_drive", "endcelldefine", "", "delay_mode_path", "", "enable_portfaults", "", "nounconnected_drive", "suppress_faults" }; if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) { register int key = hash (str, len); if (key <= MAX_HASH_VALUE && key >= 0) { register const char *s = wordlist[key]; if (*str == *s && !strcmp (str + 1, s + 1)) return s; } } return 0; } gtkwave-gtk3-3.3.125/contrib/rtlbrowse/fgetdynamic.h0000664000175000017500000000101215047725113021636 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 FGET_DYNAMIC_H #define FGET_DYNAMIC_H #include #include struct alloc_bytechain { char val; struct alloc_bytechain *next; }; char *fgetmalloc(FILE *handle); extern int fgetmalloc_len; #endif gtkwave-gtk3-3.3.125/contrib/rtlbrowse/stem_recurse.c0000664000175000017500000003271115047725113022051 0ustar bybellbybell/* * Copyright (c) Tony Bybell 2006-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 #include #include #include #include #include "fgetdynamic.h" #include "splay.h" #include "wavelink.h" #include "wave_locale.h" /* #define WAVE_CRASH_ON_GTK_WARNING */ GtkTreeStore *treestore_main = NULL; GtkWidget *treeview_main = NULL; #if defined __MINGW32__ #define shmat(a,b,c) NULL #define shmdt(a) #endif void treebox(char *title, GCallback func, GtkWidget *old_window); gboolean update_ctx_when_idle(gpointer dummy); int verilog_2005 = 0; /* currently 1364-2005 keywords are disabled */ int mod_cnt; ds_Tree **mod_list; ds_Tree *flattened_mod_list_root = NULL; struct gtkwave_annotate_ipc_t *anno_ctx = NULL; struct vzt_rd_trace *vzt=NULL; struct lxt2_rd_trace *lx2=NULL; void *fst=NULL; int64_t timezero = 0; /* only currently used for FST */ #ifdef AET2_IS_PRESENT FILE *aetf; AE2_HANDLE ae2 = NULL; #endif static int bwsigcmp(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); } } } static int compar_comp_array_bsearch(const void *s1, const void *s2) { char *key, *obj; key=(*((struct ds_component **)s1))->compname; obj=(*((struct ds_component **)s2))->compname; return(bwsigcmp(key, obj)); } void recurse_into_modules(char *compname_build, char *compname, ds_Tree *t, int depth, GtkTreeIter *ti_subtree) { struct ds_component *comp; struct ds_component **comp_array; int i; char *compname_full; char *txt, *txt2 = NULL; ds_Tree *tdup = malloc(sizeof(ds_Tree)); int numcomps; char *colon; char *compname2 = compname ? strdup(compname) : NULL; char *compname_colon = NULL; if(compname2) { compname_colon = strchr(compname2, ':'); if(compname_colon) { *compname_colon = 0; } } memcpy(tdup, t, sizeof(ds_Tree)); t = tdup; colon = strchr(t->item, ':'); if(colon) { *colon = 0; /* remove generate hack */ } t->next_flat = flattened_mod_list_root; flattened_mod_list_root = t; if(compname_build) { int cnl = strlen(compname_build); compname_full = malloc(cnl + 1 + strlen(compname2) + 1); strcpy(compname_full, compname_build); compname_full[cnl] = '.'; strcpy(compname_full + cnl + 1, compname2); } else { compname_full = strdup(t->item); } t->fullname = compname_full; txt = compname_build ? compname2 : t->item; if(!t->filename) { txt2 = malloc(strlen(txt) + strlen(" [MISSING]") + 1); strcpy(txt2, txt); strcat(txt2, " [MISSING]"); /* txt = txt2; */ /* scan-build */ } gtk_tree_store_set (treestore_main, ti_subtree, XXX_NAME_COLUMN, compname2 ? compname2 : t->item, /* t->comp->compname? */ XXX_TREE_COLUMN, t, -1); if(colon) { *colon = ':'; } free(compname2); compname2 = NULL; comp = t->comp; if(comp) { numcomps = 0; while(comp) { numcomps++; comp = comp->next; } comp_array = calloc(numcomps, sizeof(struct ds_component *)); comp = t->comp; for(i=0;inext; } qsort(comp_array, numcomps, sizeof(struct ds_component *), compar_comp_array_bsearch); for(i=0;icompname, XXX_TREE_COLUMN, comp->module, -1); recurse_into_modules(compname_full, comp->compname, comp->module, depth+1, &iter); } free(comp_array); } if(txt2) { free(txt2); } } void rec_tree(ds_Tree *t, int *cnt) { if(!t) return; if(t->left) { rec_tree(t->left, cnt); } (*cnt)++; if(t->right) { rec_tree(t->right, cnt); } } void rec_tree_populate(ds_Tree *t, int *cnt, ds_Tree **list_root) { if(!t) return; if(t->left) { rec_tree_populate(t->left, cnt, list_root); } list_root[*cnt] = t; (*cnt)++; if(t->right) { rec_tree_populate(t->right, cnt, list_root); } } int main_2r(int argc, char **argv) { FILE *f; ds_Tree *modules = NULL; char *id; int i; int len; if(argc != 2) { printf("Usage:\n------\n%s stems_filename\n\n", argv[0]); exit(0); } id = argv[1]; len = strlen(id); for(i=0;imatchword, WAVE_MATCHWORD, 4))&&(anno_ctx->aet_type > WAVE_ANNO_NONE)&&(anno_ctx->aet_type < WAVE_ANNO_MAX)) { id = anno_ctx->stems_name; } else { shmdt((void *)anno_ctx); fprintf(stderr, "Not a valid shared memory ID from gtkwave, exiting.\n"); exit(255); } } else { id = argv[1]; } } else { id = argv[1]; } f = fopen(id, "rb"); if(!f) { fprintf(stderr, "*** Could not open '%s'\n", argv[1]); perror("Why"); exit(255); } /* read_filename: */ while(!feof(f)) { char *ln = fgetmalloc(f); if(fgetmalloc_len > 4) { if((ln[0] == '+')&&(ln[1] == '+')&&(ln[2]==' ')) { if(ln[3]=='c') { char cname[1024], mname[1024], pname[1024], scratch[128]; ds_Tree *which_module; struct ds_component *dc; sscanf(ln+8, "%s %s %s %s %s", cname, scratch, mname, scratch, pname); /* printf("comp: %s module: %s, parent: %s\n", cname, mname, pname); */ modules = ds_splay(mname, modules); if((!modules)||(strcmp(modules->item, mname))) { modules = ds_insert(strdup(mname), modules); } which_module = modules; which_module->refcnt++; modules = ds_splay(pname, modules); if(strcmp(modules->item, pname)) { modules = ds_insert(strdup(pname), modules); } dc = calloc(1, sizeof(struct ds_component)); dc->compname = strdup(cname); dc->module = which_module; dc->next = modules->comp; modules->comp = dc; } else if((ln[3]=='m')||(ln[3]=='u')) { char scratch[128], mname[1024], fname[1024]; int s_line, e_line; sscanf(ln+3, "%s %s %s %s %s %d %s %d", scratch, mname, scratch, fname, scratch, &s_line, scratch, &e_line); /* printf("mod: %s from %s %d-%d\n", mname, fname, s_line, e_line); */ modules = ds_insert(strdup(mname), modules); modules->filename = strdup(fname); modules->s_line = s_line; modules->e_line = e_line; modules->resolved = 1; } else if(ln[3]=='v') { } } } free(ln); } fclose(f); mod_cnt = 0; rec_tree(modules, &mod_cnt); /* printf("number of modules: %d\n", mod_cnt); */ mod_list = calloc(mod_cnt /* scan-build */ ? mod_cnt : 1, sizeof(ds_Tree *)); mod_cnt = 0; rec_tree_populate(modules, &mod_cnt, mod_list); return(0); } /**********************************************************/ /**********************************************************/ /**********************************************************/ void bwmaketree(void) { int i; treestore_main = gtk_tree_store_new (XXX2_NUM_COLUMNS, /* Total number of columns */ G_TYPE_STRING, /* name */ G_TYPE_POINTER); /* tree */ for(i=0;irefcnt) { /* printf("TOP: %s\n", t->item); */ GtkTreeIter iter; gtk_tree_store_append (treestore_main, &iter, NULL); recurse_into_modules(NULL, NULL, t, 0, &iter /* ti_subtree */); } else if(!t->resolved) { /* printf("MISSING: %s\n", t->item); */ } } GtkCellRenderer *renderer_t; GtkTreeViewColumn *column; treeview_main = gtk_tree_view_new_with_model (GTK_TREE_MODEL (treestore_main)); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(treeview_main), FALSE); gtk_tree_view_set_enable_tree_lines (GTK_TREE_VIEW(treeview_main), TRUE); column = gtk_tree_view_column_new(); renderer_t = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_start (column, renderer_t, FALSE); gtk_tree_view_column_add_attribute (column, renderer_t, "text", XXX2_NAME_COLUMN); gtk_tree_view_append_column (GTK_TREE_VIEW (treeview_main), column); gtk_widget_show(treeview_main); } /**********************************************************/ /**********************************************************/ #ifdef AET2_IS_PRESENT static void *alloc_fn(size_t size) { void *pnt = calloc(1, size); return(pnt); } static void free_fn(void* ptr, size_t size) { (void)size; free(ptr); } static void error_fn(const char *format, ...) { va_list ap; va_start(ap, format); vfprintf(stderr, format, ap); fprintf(stderr, "\n"); va_end(ap); exit(255); } static void msg_fn(int sev, const char *format, ...) { va_list ap; va_start(ap, format); fprintf(stderr, "AE2 %03d | ", sev); vfprintf(stderr, format, ap); fprintf(stderr, "\n"); va_end(ap); } #endif /**********************************************************/ /**********************************************************/ #if GTK_CHECK_VERSION(3,0,0) static GLogWriterOutput gtkwave_glib_log_handler (GLogLevelFlags log_level, const GLogField *fields, gsize n_fields, gpointer user_data) { (void) user_data; #ifndef WAVE_CRASH_ON_GTK_WARNING if(log_level & (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG)) { /* filter out low-level warnings as GTK3 is too chatty */ } else #endif { gsize i; for(i=0;iaet_type) { case WAVE_ANNO_FST: fst=fstReaderOpen(anno_ctx->aet_name); if(!fst) { fprintf(stderr, "Could not initialize '%s', exiting.\n", anno_ctx->aet_name); exit(255); } else { timezero = fstReaderGetTimezero(fst); } break; case WAVE_ANNO_VZT: vzt=vzt_rd_init(anno_ctx->aet_name); if(!vzt) { fprintf(stderr, "Could not initialize '%s', exiting.\n", anno_ctx->aet_name); exit(255); } break; case WAVE_ANNO_LXT2: lx2=lxt2_rd_init(anno_ctx->aet_name); if(!lx2) { fprintf(stderr, "Could not initialize '%s', exiting.\n", anno_ctx->aet_name); exit(255); } break; case WAVE_ANNO_AE2: #ifdef AET2_IS_PRESENT ae2_initialize(error_fn, msg_fn, alloc_fn, free_fn); if ( (!(aetf=fopen(anno_ctx->aet_name, "rb"))) || (!(ae2 = ae2_read_initialize(aetf))) ) { fprintf(stderr, "Could not initialize '%s', exiting.\n", anno_ctx->aet_name); exit(255); } break; #endif default: fprintf(stderr, "Unsupported wave file type %d encountered, exiting.\n", anno_ctx->aet_type); exit(255); break; } } treebox("RTL Design Hierarchy", NULL, NULL); g_timeout_add(100, update_ctx_when_idle, NULL); gtk_main(); return(0); } gtkwave-gtk3-3.3.125/contrib/rtlbrowse/Makefile.in0000664000175000017500000011465015047725113021255 0ustar bybellbybell# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : bin_PROGRAMS = rtlbrowse$(EXEEXT) subdir = contrib/rtlbrowse DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am vlex.c \ $(top_srcdir)/depcomp $(top_srcdir)/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) 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_rtlbrowse_OBJECTS = definehash.$(OBJEXT) fgetdynamic.$(OBJEXT) \ logfile.$(OBJEXT) splay.$(OBJEXT) tcl_helper.$(OBJEXT) \ tree_widget.$(OBJEXT) lz4.$(OBJEXT) fastlz.$(OBJEXT) \ fstapi.$(OBJEXT) stem_recurse.$(OBJEXT) jrb.$(OBJEXT) \ vzt_read.$(OBJEXT) lxt2_read.$(OBJEXT) vlex.$(OBJEXT) \ LzmaLib.$(OBJEXT) rtlbrowse_OBJECTS = $(am_rtlbrowse_OBJECTS) rtlbrowse_LDADD = $(LDADD) am__DEPENDENCIES_1 = am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) rtlbrowse_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \ $(am__DEPENDENCIES_1) $(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 = @MAINTAINER_MODE_FALSE@am__skiplex = test -f $@ || LEXCOMPILE = $(LEX) $(AM_LFLAGS) $(LFLAGS) AM_V_LEX = $(am__v_LEX_@AM_V@) am__v_LEX_ = $(am__v_LEX_@AM_DEFAULT_V@) am__v_LEX_0 = @echo " LEX " $@; am__v_LEX_1 = YLWRAP = $(top_srcdir)/ylwrap SOURCES = $(rtlbrowse_SOURCES) DIST_SOURCES = $(rtlbrowse_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 DIST_SUBDIRS = $(SUBDIRS) 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@ GLIB_COMPILE_SCHEMAS = @GLIB_COMPILE_SCHEMAS@ GPERF = @GPERF@ GREP = @GREP@ GSETTINGS_CFLAGS = @GSETTINGS_CFLAGS@ GSETTINGS_DISABLE_SCHEMAS_COMPILE = @GSETTINGS_DISABLE_SCHEMAS_COMPILE@ GTK_CFLAGS = @GTK_CFLAGS@ 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_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_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@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ RANLIB = @RANLIB@ RPC_CFLAGS = @RPC_CFLAGS@ RPC_LDADD = @RPC_LDADD@ 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@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ 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@ gsettingsschemadir = @gsettingsschemadir@ 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@ # FIXME -- how to figure out automatically when we need these? # SUBDIRS = AET2LIB = AIXFLAGS = -bmaxdata:0xd0000000/dsa -D_WAVE_BE32 BIGFILES = -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 LIBFST_CFLAGS = -I$(srcdir)/../../src/helpers/fst LIBLZMA_CFLAGS = -I$(srcdir)/../../src/liblzma $(LIBXZ_CFLAGS) LIBLZMA_LDADD = $(LIBXZ_LDADD) rtlbrowse_SOURCES = definehash.c fgetdynamic.c fgetdynamic.h \ logfile.c splay.c tcl_helper.c tree_widget.c \ $(srcdir)/../../src/helpers/fst/lz4.c \ $(srcdir)/../../src/helpers/fst/lz4.h \ $(srcdir)/../../src/helpers/fst/fastlz.c \ $(srcdir)/../../src/helpers/fst/fastlz.h \ $(srcdir)/../../src/helpers/fst/fstapi.c \ $(srcdir)/../../src/helpers/fst/fstapi.h \ stem_recurse.c jrb.c jrb.h $(srcdir)/../../src/helpers/vzt_read.c $(srcdir)/../../src/helpers/vzt_read.h \ $(srcdir)/../../src/helpers/lxt2_read.c $(srcdir)/../../src/helpers/lxt2_read.h splay.h \ vlex.l vlex.h wavelink.h $(srcdir)/../../src/liblzma/LzmaLib.c $(srcdir)/../../src/liblzma/LzmaLib.h LDADD = $(GTK_LIBS) $(LIBZ_LDADD) $(LIBBZ2_LDADD) $(LIBLZMA_LDADD) $(AET2_LDADD) \ $(LIBJUDY_LDADD) $(GTK_MAC_LIBS) $(GCONF_LIBS) AM_CFLAGS = -I$(top_srcdir) -I$(top_srcdir)/src -I$(top_srcdir)/src/helpers \ $(GTK_CFLAGS) $(LIBZ_CFLAGS) $(LIBBZ2_CFLAGS) $(LIBLZMA_CFLAGS) \ $(LIBFST_CFLAGS) $(AET2_CFLAGS) $(LIBJUDY_CFLAGS) \ $(GTK_MAC_CFLAGS) $(GCONF_CFLAGS) -DYY_NO_INPUT BUILT_SOURCES = definehash.c EXTRA_DIST = vpp_keyword.gperf all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: .SUFFIXES: .c .l .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 contrib/rtlbrowse/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign contrib/rtlbrowse/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) rtlbrowse$(EXEEXT): $(rtlbrowse_OBJECTS) $(rtlbrowse_DEPENDENCIES) $(EXTRA_rtlbrowse_DEPENDENCIES) @rm -f rtlbrowse$(EXEEXT) $(AM_V_CCLD)$(LINK) $(rtlbrowse_OBJECTS) $(rtlbrowse_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)/definehash.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fastlz.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fgetdynamic.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstapi.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)/lxt2_read.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lz4.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/splay.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stem_recurse.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcl_helper.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tree_widget.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vlex.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vzt_read.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) '$<'` lz4.o: $(srcdir)/../../src/helpers/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)/../../src/helpers/fst/lz4.c' || echo '$(srcdir)/'`$(srcdir)/../../src/helpers/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)/../../src/helpers/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)/../../src/helpers/fst/lz4.c' || echo '$(srcdir)/'`$(srcdir)/../../src/helpers/fst/lz4.c lz4.obj: $(srcdir)/../../src/helpers/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)/../../src/helpers/fst/lz4.c'; then $(CYGPATH_W) '$(srcdir)/../../src/helpers/fst/lz4.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/../../src/helpers/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)/../../src/helpers/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)/../../src/helpers/fst/lz4.c'; then $(CYGPATH_W) '$(srcdir)/../../src/helpers/fst/lz4.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/../../src/helpers/fst/lz4.c'; fi` fastlz.o: $(srcdir)/../../src/helpers/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)/../../src/helpers/fst/fastlz.c' || echo '$(srcdir)/'`$(srcdir)/../../src/helpers/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)/../../src/helpers/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)/../../src/helpers/fst/fastlz.c' || echo '$(srcdir)/'`$(srcdir)/../../src/helpers/fst/fastlz.c fastlz.obj: $(srcdir)/../../src/helpers/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)/../../src/helpers/fst/fastlz.c'; then $(CYGPATH_W) '$(srcdir)/../../src/helpers/fst/fastlz.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/../../src/helpers/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)/../../src/helpers/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)/../../src/helpers/fst/fastlz.c'; then $(CYGPATH_W) '$(srcdir)/../../src/helpers/fst/fastlz.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/../../src/helpers/fst/fastlz.c'; fi` fstapi.o: $(srcdir)/../../src/helpers/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)/../../src/helpers/fst/fstapi.c' || echo '$(srcdir)/'`$(srcdir)/../../src/helpers/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)/../../src/helpers/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)/../../src/helpers/fst/fstapi.c' || echo '$(srcdir)/'`$(srcdir)/../../src/helpers/fst/fstapi.c fstapi.obj: $(srcdir)/../../src/helpers/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)/../../src/helpers/fst/fstapi.c'; then $(CYGPATH_W) '$(srcdir)/../../src/helpers/fst/fstapi.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/../../src/helpers/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)/../../src/helpers/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)/../../src/helpers/fst/fstapi.c'; then $(CYGPATH_W) '$(srcdir)/../../src/helpers/fst/fstapi.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/../../src/helpers/fst/fstapi.c'; fi` vzt_read.o: $(srcdir)/../../src/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 '$(srcdir)/../../src/helpers/vzt_read.c' || echo '$(srcdir)/'`$(srcdir)/../../src/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='$(srcdir)/../../src/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 '$(srcdir)/../../src/helpers/vzt_read.c' || echo '$(srcdir)/'`$(srcdir)/../../src/helpers/vzt_read.c vzt_read.obj: $(srcdir)/../../src/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 '$(srcdir)/../../src/helpers/vzt_read.c'; then $(CYGPATH_W) '$(srcdir)/../../src/helpers/vzt_read.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/../../src/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='$(srcdir)/../../src/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 '$(srcdir)/../../src/helpers/vzt_read.c'; then $(CYGPATH_W) '$(srcdir)/../../src/helpers/vzt_read.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/../../src/helpers/vzt_read.c'; fi` lxt2_read.o: $(srcdir)/../../src/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 '$(srcdir)/../../src/helpers/lxt2_read.c' || echo '$(srcdir)/'`$(srcdir)/../../src/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='$(srcdir)/../../src/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 '$(srcdir)/../../src/helpers/lxt2_read.c' || echo '$(srcdir)/'`$(srcdir)/../../src/helpers/lxt2_read.c lxt2_read.obj: $(srcdir)/../../src/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 '$(srcdir)/../../src/helpers/lxt2_read.c'; then $(CYGPATH_W) '$(srcdir)/../../src/helpers/lxt2_read.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/../../src/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='$(srcdir)/../../src/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 '$(srcdir)/../../src/helpers/lxt2_read.c'; then $(CYGPATH_W) '$(srcdir)/../../src/helpers/lxt2_read.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/../../src/helpers/lxt2_read.c'; fi` LzmaLib.o: $(srcdir)/../../src/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)/../../src/liblzma/LzmaLib.c' || echo '$(srcdir)/'`$(srcdir)/../../src/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)/../../src/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)/../../src/liblzma/LzmaLib.c' || echo '$(srcdir)/'`$(srcdir)/../../src/liblzma/LzmaLib.c LzmaLib.obj: $(srcdir)/../../src/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)/../../src/liblzma/LzmaLib.c'; then $(CYGPATH_W) '$(srcdir)/../../src/liblzma/LzmaLib.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/../../src/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)/../../src/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)/../../src/liblzma/LzmaLib.c'; then $(CYGPATH_W) '$(srcdir)/../../src/liblzma/LzmaLib.c'; else $(CYGPATH_W) '$(srcdir)/$(srcdir)/../../src/liblzma/LzmaLib.c'; fi` .l.c: $(AM_V_LEX)$(am__skiplex) $(SHELL) $(YLWRAP) $< $(LEX_OUTPUT_ROOT).c $@ -- $(LEXCOMPILE) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(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." -rm -f vlex.c -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 definehash.c: vpp_keyword.gperf $(GPERF) -C -I -N is_builtin_define $(srcdir)/vpp_keyword.gperf >definehash.c # 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-gtk3-3.3.125/contrib/rtlbrowse/tree_widget.c0000664000175000017500000001272115047725113021652 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 #include #include "splay.h" #include "wavelink.h" #define set_winsize(w,x,y) gtk_window_set_default_size(GTK_WINDOW(w),(x),(y)) void create_toolbar(GtkWidget *table); GtkWidget *notebook = NULL; extern GtkTreeStore *treestore_main; extern GtkWidget *treeview_main; void bwmaketree(void); void bwlogbox(char *title, int width, ds_Tree *t, int display_mode); void setup_dnd(GtkWidget *wid); static ds_Tree *selectedtree=NULL; static int is_active=0; int treebox_is_active(void) { return(is_active); } static void XXX_select_row_callback( GtkTreeModel *model, GtkTreePath *path) { GtkTreeIter iter; ds_Tree *t = NULL; if (!gtk_tree_model_get_iter(model, &iter, path)) { return; /* path describes a non-existing row - should not happen */ } gtk_tree_model_get_iter(model, &iter, path); gtk_tree_model_get(model, &iter, XXX2_TREE_COLUMN, &t, -1); if(t && (selectedtree!=t)) { if(t->filename) { /* printf("%s\n", t->fullname); printf("%s -> '%s' %d-%d\n\n", t->item, t->filename, t->s_line, t->e_line); */ bwlogbox(t->fullname ? t->fullname : "*", 640 + 8*8, t, 0); } else { /* printf("%s\n", t->fullname); printf("%s -> *MISSING*\n\n", t->item); */ } } selectedtree=t; } static void XXX_unselect_row_callback( GtkTreeModel *model, GtkTreePath *path) { GtkTreeIter iter; ds_Tree *t = NULL; if (!gtk_tree_model_get_iter(model, &iter, path)) { return; /* path describes a non-existing row - should not happen */ } gtk_tree_model_get_iter(model, &iter, path); gtk_tree_model_get(model, &iter, XXX2_TREE_COLUMN, &t, -1); /* selectedtree=NULL; */ } static gboolean XXX_view_selection_func (GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean path_currently_selected, gpointer userdata) { (void) selection; (void) userdata; if(!path_currently_selected) { XXX_select_row_callback(model, path); } else { XXX_unselect_row_callback(model, path); } return(TRUE); } /***************************************************************************/ static GtkWidget *window; static GCallback cleanup; static void destroy_callback(GtkWidget *widget, GtkWidget *nothing) { (void)widget; (void)nothing; is_active=0; gtk_widget_destroy(window); gtk_main_quit(); } /* * mainline.. */ void treebox(char *title, GCallback func, GtkWidget *old_window) { (void)old_window; GtkWidget *scrolled_win; GtkWidget *frame2; GtkWidget *table; if(is_active) { gdk_window_raise(gtk_widget_get_window(window)); return; } is_active=1; cleanup=func; /* create a new modal window */ window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW (window), title); g_signal_connect(XXX_GTK_OBJECT (window), "delete_event", (GCallback) destroy_callback, NULL); set_winsize(window, 640, 600); #if GTK_CHECK_VERSION(3,0,0) table = gtk_grid_new (); #else table = gtk_table_new (256, 1, FALSE); #endif gtk_widget_show (table); #if GTK_CHECK_VERSION(3,0,0) frame2 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL); #else frame2 = gtk_hpaned_new(); #endif gtk_widget_show(frame2); notebook = gtk_notebook_new(); gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP); gtk_notebook_set_show_tabs(GTK_NOTEBOOK(notebook), ~0); gtk_notebook_set_show_border(GTK_NOTEBOOK(notebook), ~0); gtk_notebook_set_scrollable(GTK_NOTEBOOK(notebook), ~0); gtk_notebook_popup_enable(GTK_NOTEBOOK(notebook)); gtk_widget_show(notebook); gtk_paned_pack2(GTK_PANED(frame2), notebook, TRUE, TRUE); #if GTK_CHECK_VERSION(3,0,0) gtk_grid_attach (GTK_GRID (table), frame2, 0, 0, 1, 255); gtk_widget_set_hexpand (GTK_WIDGET (frame2), TRUE); gtk_widget_set_vexpand (GTK_WIDGET (frame2), TRUE); #else gtk_table_attach (GTK_TABLE (table), frame2, 0, 1, 0, 255, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); #endif bwmaketree(); selectedtree=NULL; scrolled_win = gtk_scrolled_window_new (NULL, NULL); gtk_widget_set_size_request( GTK_WIDGET (scrolled_win), 150, 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 (treeview_main)); gtk_tree_selection_set_select_function (gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview_main)), XXX_view_selection_func, NULL, NULL); gtk_tree_selection_set_mode (gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview_main)), GTK_SELECTION_SINGLE); gtk_paned_pack1(GTK_PANED(frame2), scrolled_win, TRUE, TRUE); create_toolbar(table); gtk_container_add (GTK_CONTAINER (window), table); gtk_widget_show(window); setup_dnd(window); } gtkwave-gtk3-3.3.125/contrib/rtlbrowse/jrb.c0000664000175000017500000003025115047725113020123 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, 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, 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-gtk3-3.3.125/contrib/rtlbrowse/vlex.c0000664000175000017500000024725015047725113020335 0ustar bybellbybell #line 3 "vlex.c" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_SUBMINOR_VERSION 37 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! C99 */ #endif /* ! FLEXINT_H */ #ifdef __cplusplus /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST #else /* ! __cplusplus */ /* C99 requires __STDC__ to be defined as 1. */ #if defined (__STDC__) #define YY_USE_CONST #endif /* defined (__STDC__) */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart(yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #define YY_BUF_SIZE 16384 #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif extern yy_size_t yyleng; extern FILE *yyin, *yyout; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, (yytext_ptr) ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ yy_size_t yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* Stack of input buffers. */ static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] /* yy_hold_char holds the character lost when yytext is formed. */ static char yy_hold_char; static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ yy_size_t yyleng; /* Points to current character in buffer. */ static char *yy_c_buf_p = (char *) 0; static int yy_init = 0; /* whether we need to initialize */ static int yy_start = 0; /* start state number */ /* Flag which is used to allow yywrap()'s to do buffer switches * instead of setting up a fresh yyin. A bit of a hack ... */ static int yy_did_buffer_switch_on_eof; void yyrestart (FILE *input_file ); void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); void yy_delete_buffer (YY_BUFFER_STATE b ); void yy_flush_buffer (YY_BUFFER_STATE b ); void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); void yypop_buffer_state (void ); static void yyensure_buffer_stack (void ); static void yy_load_buffer_state (void ); static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); #define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ); void *yyalloc (yy_size_t ); void *yyrealloc (void *,yy_size_t ); void yyfree (void * ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer(yyin,YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer(yyin,YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ typedef unsigned char YY_CHAR; FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; typedef int yy_state_type; extern int yylineno; int yylineno = 1; extern char *yytext; #define yytext_ptr yytext static yy_state_type yy_get_previous_state (void ); static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); static int yy_get_next_buffer (void ); static void yy_fatal_error (yyconst char msg[] ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ yyleng = (size_t) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 157 #define YY_END_OF_BUFFER 158 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_accept[619] = { 0, 0, 0, 0, 0, 0, 0, 158, 156, 152, 153, 156, 156, 156, 156, 156, 156, 146, 143, 156, 156, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 4, 6, 5, 5, 5, 138, 139, 152, 0, 155, 142, 0, 0, 0, 0, 151, 145, 1, 154, 146, 143, 0, 141, 140, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 33, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 48, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 4, 3, 2, 138, 142, 0, 148, 0, 147, 0, 150, 0, 149, 145, 154, 144, 140, 143, 8, 143, 143, 143, 126, 11, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 24, 143, 143, 27, 143, 143, 143, 143, 143, 143, 143, 143, 143, 128, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 44, 143, 45, 143, 143, 143, 143, 143, 143, 143, 143, 60, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 79, 143, 124, 143, 143, 143, 143, 143, 143, 143, 92, 143, 94, 148, 147, 150, 149, 144, 143, 143, 143, 143, 143, 131, 14, 104, 17, 143, 143, 143, 143, 143, 143, 22, 23, 143, 143, 143, 143, 143, 143, 143, 132, 143, 143, 143, 30, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 38, 143, 143, 143, 143, 143, 143, 143, 143, 143, 41, 143, 43, 143, 143, 143, 143, 51, 143, 143, 143, 143, 143, 58, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 95, 75, 76, 80, 81, 143, 143, 143, 143, 143, 143, 86, 87, 143, 143, 91, 93, 143, 143, 143, 10, 143, 15, 16, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 26, 28, 143, 143, 143, 143, 143, 143, 143, 143, 143, 35, 36, 143, 143, 39, 143, 143, 143, 127, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 53, 54, 143, 143, 143, 57, 143, 143, 143, 63, 64, 65, 143, 143, 143, 143, 69, 143, 143, 143, 143, 99, 143, 143, 83, 143, 143, 125, 143, 88, 89, 90, 7, 9, 143, 12, 13, 105, 143, 143, 143, 106, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 114, 31, 32, 109, 110, 143, 143, 143, 143, 143, 143, 143, 143, 143, 40, 134, 143, 143, 46, 47, 49, 143, 143, 143, 143, 56, 143, 143, 143, 62, 143, 143, 143, 143, 123, 143, 143, 143, 143, 143, 82, 84, 143, 143, 143, 143, 19, 143, 21, 25, 143, 143, 143, 143, 143, 143, 143, 96, 29, 143, 143, 111, 34, 143, 37, 115, 116, 143, 130, 143, 42, 143, 143, 52, 143, 143, 143, 143, 61, 143, 143, 143, 143, 101, 143, 71, 72, 73, 74, 77, 78, 143, 143, 143, 18, 20, 143, 143, 143, 143, 143, 143, 100, 97, 113, 112, 143, 143, 143, 143, 143, 55, 143, 59, 66, 67, 68, 129, 143, 143, 121, 85, 103, 107, 143, 143, 136, 143, 143, 143, 143, 143, 50, 135, 143, 143, 70, 143, 143, 143, 102, 117, 143, 143, 143, 143, 98, 108, 143, 133, 143, 143, 143, 137, 143, 143, 143, 143, 143, 122, 143, 143, 143, 118, 143, 143, 143, 143, 143, 143, 143, 119, 120, 0 } ; static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 5, 1, 6, 1, 1, 7, 1, 1, 8, 1, 1, 1, 9, 10, 11, 12, 13, 13, 13, 13, 13, 13, 14, 14, 1, 1, 1, 1, 1, 15, 1, 16, 17, 16, 18, 16, 16, 19, 20, 19, 19, 19, 19, 19, 19, 21, 19, 19, 19, 19, 19, 19, 19, 19, 22, 19, 22, 1, 23, 1, 1, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 19, 42, 43, 44, 45, 46, 47, 48, 49, 50, 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, 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, 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, 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, 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, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int32_t yy_meta[51] = { 0, 1, 2, 3, 4, 1, 5, 1, 6, 7, 6, 8, 8, 8, 8, 1, 9, 9, 9, 10, 10, 10, 9, 6, 11, 1, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 10, 9 } ; static yyconst flex_int16_t yy_base[637] = { 0, 0, 0, 48, 49, 1360, 1359, 1361, 1364, 51, 1364, 1355, 0, 56, 1349, 0, 52, 52, 1349, 0, 0, 45, 61, 71, 69, 78, 60, 72, 52, 83, 58, 95, 104, 107, 109, 110, 129, 165, 130, 84, 111, 149, 103, 0, 1364, 1347, 1348, 1364, 0, 1364, 124, 1350, 1364, 0, 165, 183, 1352, 179, 1364, 0, 1364, 0, 149, 1344, 0, 0, 0, 85, 137, 162, 140, 156, 160, 169, 177, 193, 116, 198, 202, 199, 203, 205, 207, 210, 213, 66, 208, 209, 217, 214, 223, 211, 219, 225, 226, 231, 215, 247, 251, 253, 259, 260, 1343, 261, 264, 268, 266, 262, 263, 269, 284, 273, 274, 271, 265, 275, 285, 272, 288, 277, 279, 305, 286, 313, 280, 319, 292, 318, 320, 324, 321, 322, 325, 326, 327, 0, 1364, 1364, 0, 0, 341, 346, 360, 364, 1349, 0, 388, 371, 0, 0, 1341, 0, 371, 1340, 331, 372, 351, 1339, 370, 377, 378, 383, 389, 393, 394, 400, 396, 397, 404, 405, 433, 402, 406, 416, 419, 409, 418, 408, 420, 422, 413, 424, 434, 445, 441, 447, 444, 458, 451, 450, 453, 454, 459, 461, 463, 464, 1338, 478, 474, 480, 483, 482, 485, 488, 487, 489, 490, 1337, 492, 493, 491, 494, 507, 501, 497, 496, 503, 504, 505, 508, 509, 511, 527, 519, 539, 528, 1336, 510, 532, 533, 534, 544, 545, 555, 1335, 546, 1334, 572, 578, 0, 586, 1333, 551, 561, 557, 547, 592, 1332, 559, 1331, 1330, 569, 562, 566, 595, 597, 603, 1329, 1328, 605, 604, 607, 606, 608, 610, 609, 1327, 615, 617, 616, 1326, 619, 618, 629, 623, 630, 624, 631, 632, 633, 634, 635, 639, 1325, 644, 645, 655, 643, 647, 648, 656, 658, 661, 1324, 659, 1323, 674, 663, 675, 677, 1322, 676, 678, 680, 681, 684, 686, 690, 691, 688, 692, 693, 695, 697, 698, 699, 701, 709, 710, 714, 704, 1321, 1320, 713, 1319, 1318, 715, 719, 727, 724, 728, 730, 1317, 1316, 333, 733, 1315, 1314, 731, 736, 739, 1313, 755, 1312, 1311, 737, 743, 735, 744, 746, 750, 751, 753, 759, 762, 764, 769, 767, 772, 1310, 1309, 770, 771, 780, 774, 779, 787, 786, 773, 795, 1308, 1307, 775, 799, 1306, 798, 800, 802, 1305, 801, 809, 810, 803, 804, 811, 813, 817, 814, 818, 821, 1304, 1303, 822, 823, 825, 1302, 826, 828, 829, 1301, 1300, 836, 830, 840, 837, 846, 1299, 845, 843, 847, 842, 1298, 850, 848, 1297, 857, 844, 1296, 858, 1295, 1294, 1293, 1292, 1291, 869, 1290, 1289, 1288, 871, 873, 875, 1287, 876, 877, 878, 883, 884, 879, 881, 887, 885, 889, 886, 890, 888, 1286, 1285, 1284, 1283, 1277, 893, 896, 899, 895, 901, 903, 909, 907, 917, 1274, 1267, 911, 912, 1266, 1253, 1246, 920, 925, 922, 927, 1245, 929, 930, 933, 1241, 934, 937, 938, 939, 1240, 935, 940, 949, 960, 974, 1239, 1238, 945, 950, 953, 957, 1237, 941, 1231, 1230, 961, 944, 967, 980, 972, 981, 982, 1220, 1212, 983, 984, 1209, 1196, 988, 1195, 1194, 1187, 985, 1172, 990, 1171, 994, 991, 1145, 989, 992, 993, 995, 1144, 996, 1001, 1002, 1004, 1143, 1007, 1142, 1140, 1139, 1138, 1137, 1134, 1014, 1015, 1017, 1133, 1131, 1019, 1020, 1027, 1025, 1028, 1029, 1130, 1129, 1128, 1126, 1030, 1031, 1032, 1038, 1039, 1123, 1040, 1122, 1120, 1118, 1117, 1113, 1043, 1041, 564, 563, 560, 558, 1048, 1049, 552, 1050, 1052, 1053, 1055, 1054, 407, 342, 1056, 1057, 332, 1058, 1059, 1061, 329, 328, 1065, 1066, 550, 1069, 283, 278, 1072, 270, 1074, 1076, 1078, 224, 1081, 1089, 1090, 1091, 1094, 222, 1096, 1100, 1095, 131, 1101, 1103, 1104, 1105, 1108, 1106, 1111, 70, 59, 1364, 1155, 1166, 1177, 1180, 1183, 1190, 1201, 1204, 1215, 1226, 1233, 1243, 1248, 1259, 1262, 1269, 1273, 1280 } ; static yyconst flex_int16_t yy_def[637] = { 0, 618, 1, 619, 619, 620, 620, 618, 618, 618, 618, 621, 622, 618, 618, 623, 618, 618, 624, 625, 626, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 627, 618, 618, 618, 618, 628, 618, 618, 621, 618, 629, 618, 618, 630, 618, 618, 631, 618, 632, 618, 624, 633, 625, 634, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 627, 618, 618, 628, 629, 618, 618, 618, 618, 630, 635, 618, 618, 631, 632, 636, 634, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 618, 618, 635, 618, 636, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 0, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618 } ; static yyconst flex_int16_t yy_nxt[1415] = { 0, 8, 9, 10, 9, 11, 12, 13, 14, 15, 16, 17, 17, 17, 17, 8, 18, 18, 18, 18, 18, 18, 18, 19, 18, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 18, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 18, 18, 44, 44, 50, 64, 50, 45, 45, 46, 46, 60, 64, 61, 62, 62, 62, 62, 64, 64, 64, 64, 47, 47, 54, 55, 64, 56, 57, 64, 64, 64, 64, 67, 54, 68, 55, 88, 64, 69, 56, 70, 71, 64, 64, 64, 72, 57, 75, 91, 79, 85, 76, 87, 80, 64, 86, 73, 81, 173, 77, 74, 78, 64, 64, 89, 82, 64, 83, 64, 64, 64, 92, 90, 124, 84, 64, 50, 125, 50, 93, 95, 126, 152, 98, 96, 94, 104, 99, 64, 64, 64, 127, 133, 134, 97, 100, 64, 101, 105, 64, 106, 102, 107, 161, 103, 108, 121, 109, 64, 110, 62, 62, 62, 62, 122, 64, 153, 140, 111, 64, 112, 64, 123, 113, 64, 128, 141, 141, 64, 129, 141, 146, 130, 131, 155, 142, 64, 141, 156, 132, 147, 147, 147, 114, 143, 143, 143, 143, 115, 116, 158, 147, 64, 117, 157, 154, 118, 64, 64, 119, 120, 64, 64, 141, 64, 141, 64, 64, 64, 64, 64, 159, 64, 64, 64, 164, 64, 147, 64, 147, 165, 64, 64, 64, 64, 64, 160, 168, 162, 170, 64, 163, 166, 172, 191, 184, 167, 174, 175, 176, 169, 178, 186, 177, 187, 171, 64, 179, 188, 190, 64, 185, 64, 180, 181, 189, 182, 183, 64, 64, 64, 64, 64, 64, 64, 64, 192, 64, 64, 64, 64, 64, 64, 64, 64, 194, 64, 64, 64, 64, 193, 213, 64, 64, 64, 64, 203, 64, 216, 195, 204, 64, 196, 197, 198, 199, 200, 205, 201, 202, 206, 210, 211, 212, 64, 214, 207, 215, 217, 218, 219, 208, 64, 225, 222, 209, 227, 64, 64, 64, 64, 64, 220, 64, 64, 64, 64, 64, 64, 223, 64, 64, 64, 140, 419, 420, 228, 224, 221, 226, 231, 64, 141, 141, 229, 232, 141, 237, 237, 230, 64, 237, 142, 141, 233, 243, 235, 234, 237, 236, 237, 143, 143, 143, 143, 238, 238, 238, 238, 64, 64, 64, 240, 240, 240, 245, 64, 64, 238, 141, 146, 141, 64, 240, 237, 240, 237, 242, 64, 147, 147, 147, 64, 64, 246, 64, 64, 247, 248, 64, 147, 64, 244, 64, 64, 64, 64, 64, 64, 240, 249, 240, 64, 256, 251, 64, 253, 64, 64, 64, 255, 64, 250, 64, 257, 258, 147, 252, 147, 272, 266, 254, 64, 64, 268, 267, 269, 271, 275, 276, 64, 274, 270, 64, 64, 273, 64, 277, 279, 64, 64, 259, 64, 64, 260, 261, 278, 64, 64, 280, 64, 262, 64, 64, 263, 282, 264, 265, 281, 284, 283, 285, 289, 64, 287, 288, 286, 64, 291, 64, 293, 64, 64, 294, 64, 290, 64, 64, 64, 64, 64, 64, 64, 64, 292, 64, 64, 295, 297, 299, 64, 296, 64, 64, 64, 301, 64, 64, 64, 64, 64, 298, 307, 308, 303, 300, 302, 306, 64, 305, 304, 309, 317, 311, 310, 315, 64, 64, 312, 313, 316, 64, 64, 64, 314, 318, 320, 321, 64, 319, 324, 325, 330, 64, 64, 64, 64, 322, 323, 64, 64, 64, 329, 333, 64, 326, 64, 64, 64, 64, 64, 64, 64, 64, 596, 64, 331, 332, 64, 327, 334, 328, 335, 237, 237, 336, 341, 237, 337, 238, 238, 238, 238, 339, 237, 340, 237, 240, 240, 240, 338, 64, 238, 345, 64, 346, 64, 343, 240, 344, 240, 347, 64, 64, 64, 64, 64, 64, 64, 64, 237, 348, 237, 342, 64, 64, 64, 64, 64, 349, 350, 351, 64, 64, 240, 358, 240, 354, 64, 64, 64, 64, 64, 64, 64, 352, 355, 360, 64, 353, 356, 357, 64, 64, 64, 364, 64, 64, 367, 359, 363, 372, 361, 362, 64, 64, 369, 64, 64, 366, 64, 373, 64, 365, 374, 378, 368, 370, 371, 375, 377, 376, 379, 64, 64, 64, 64, 64, 383, 64, 64, 390, 391, 64, 385, 64, 380, 64, 382, 64, 64, 64, 64, 381, 64, 388, 64, 64, 64, 392, 64, 394, 389, 64, 384, 387, 397, 398, 64, 64, 386, 402, 64, 64, 64, 393, 404, 395, 64, 405, 396, 399, 401, 64, 411, 400, 64, 64, 406, 64, 64, 403, 64, 407, 64, 64, 64, 412, 64, 409, 408, 410, 64, 64, 413, 64, 416, 415, 417, 64, 64, 414, 64, 421, 64, 424, 425, 426, 64, 427, 418, 64, 429, 64, 422, 423, 64, 428, 64, 64, 64, 64, 64, 64, 64, 431, 430, 432, 64, 64, 446, 447, 434, 437, 433, 64, 64, 439, 435, 440, 442, 436, 450, 438, 64, 443, 444, 64, 64, 64, 64, 64, 64, 64, 452, 441, 445, 448, 64, 64, 64, 451, 64, 64, 463, 464, 64, 64, 449, 453, 64, 64, 64, 460, 64, 64, 461, 64, 64, 64, 457, 454, 455, 456, 466, 64, 64, 458, 459, 64, 467, 64, 64, 64, 64, 64, 64, 64, 462, 64, 472, 465, 469, 478, 470, 468, 64, 64, 471, 481, 475, 473, 476, 474, 477, 479, 480, 485, 64, 482, 64, 484, 64, 487, 64, 64, 64, 64, 64, 486, 64, 483, 64, 64, 64, 64, 64, 64, 64, 64, 488, 492, 64, 490, 64, 64, 493, 494, 64, 495, 64, 496, 64, 489, 497, 500, 64, 491, 64, 499, 64, 64, 501, 506, 498, 502, 64, 508, 503, 64, 504, 64, 505, 507, 64, 512, 64, 509, 64, 64, 516, 515, 64, 64, 64, 510, 64, 64, 64, 64, 64, 513, 511, 64, 64, 518, 519, 514, 64, 64, 530, 531, 64, 523, 517, 524, 64, 525, 522, 64, 64, 532, 533, 521, 520, 536, 64, 526, 527, 540, 537, 64, 529, 64, 528, 534, 535, 538, 542, 64, 64, 64, 64, 64, 64, 541, 539, 64, 64, 64, 64, 64, 64, 64, 64, 64, 545, 559, 560, 543, 64, 64, 547, 64, 549, 546, 64, 544, 550, 552, 553, 554, 548, 64, 64, 558, 64, 551, 64, 64, 561, 556, 563, 564, 64, 555, 64, 64, 64, 64, 64, 64, 557, 565, 566, 567, 562, 64, 64, 64, 64, 568, 64, 570, 569, 571, 574, 64, 64, 64, 573, 64, 64, 64, 64, 64, 64, 64, 64, 578, 64, 576, 572, 580, 64, 64, 575, 579, 64, 581, 577, 64, 588, 64, 584, 64, 589, 64, 582, 592, 64, 586, 587, 583, 590, 594, 595, 591, 64, 64, 64, 585, 598, 64, 64, 64, 597, 593, 601, 64, 64, 599, 64, 64, 64, 64, 600, 64, 602, 604, 64, 605, 64, 606, 607, 608, 64, 64, 603, 64, 609, 64, 64, 612, 613, 64, 615, 64, 64, 64, 64, 610, 64, 64, 614, 611, 64, 64, 64, 64, 616, 64, 64, 64, 64, 617, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 51, 51, 64, 64, 51, 51, 51, 51, 51, 51, 51, 53, 53, 53, 59, 59, 59, 63, 64, 63, 63, 63, 63, 63, 65, 64, 64, 64, 65, 65, 65, 65, 65, 65, 65, 66, 66, 66, 135, 135, 64, 135, 135, 64, 135, 135, 135, 135, 135, 138, 138, 64, 138, 138, 138, 138, 138, 138, 138, 138, 139, 64, 64, 139, 139, 139, 139, 145, 64, 64, 64, 64, 64, 145, 145, 148, 64, 64, 148, 148, 148, 148, 149, 149, 64, 149, 149, 149, 149, 149, 149, 149, 149, 150, 150, 150, 151, 64, 64, 151, 151, 151, 151, 239, 239, 64, 239, 241, 64, 241, 241, 241, 241, 241, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 144, 64, 64, 144, 52, 137, 136, 64, 58, 52, 618, 49, 49, 7, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618 } ; static yyconst flex_int16_t yy_chk[1415] = { 0, 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, 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, 3, 4, 9, 21, 9, 3, 4, 3, 4, 16, 28, 16, 17, 17, 17, 17, 30, 617, 26, 22, 3, 4, 13, 13, 85, 13, 13, 24, 616, 23, 27, 21, 13, 21, 13, 28, 25, 21, 13, 21, 22, 29, 39, 67, 22, 13, 23, 30, 24, 26, 23, 27, 24, 31, 26, 22, 25, 85, 23, 22, 23, 42, 32, 29, 25, 33, 25, 34, 35, 40, 31, 29, 39, 25, 76, 50, 39, 50, 31, 32, 39, 67, 33, 32, 31, 35, 33, 36, 38, 608, 40, 42, 42, 32, 33, 68, 33, 35, 70, 35, 34, 35, 76, 34, 35, 38, 36, 41, 36, 62, 62, 62, 62, 38, 71, 68, 54, 36, 72, 36, 69, 38, 36, 37, 41, 54, 54, 73, 41, 54, 57, 41, 41, 70, 55, 74, 54, 71, 41, 57, 57, 57, 37, 55, 55, 55, 55, 37, 37, 73, 57, 75, 37, 72, 69, 37, 77, 79, 37, 37, 78, 80, 54, 81, 54, 82, 86, 87, 83, 91, 74, 84, 89, 96, 79, 88, 57, 92, 57, 79, 604, 90, 598, 93, 94, 75, 81, 77, 83, 95, 78, 79, 84, 96, 91, 80, 86, 87, 88, 82, 90, 93, 89, 94, 83, 97, 90, 94, 95, 98, 92, 99, 90, 90, 94, 90, 90, 100, 101, 103, 107, 108, 104, 114, 106, 97, 105, 109, 594, 113, 117, 111, 112, 115, 99, 119, 592, 120, 124, 98, 114, 591, 110, 116, 122, 107, 118, 117, 100, 108, 126, 101, 101, 101, 103, 104, 109, 105, 106, 110, 111, 112, 113, 121, 115, 110, 116, 118, 119, 120, 110, 123, 124, 122, 110, 126, 127, 125, 128, 130, 131, 121, 129, 132, 133, 134, 586, 585, 123, 154, 581, 334, 140, 334, 334, 127, 123, 121, 125, 129, 578, 140, 140, 128, 130, 140, 141, 141, 128, 156, 141, 142, 140, 131, 154, 133, 132, 141, 134, 141, 142, 142, 142, 142, 143, 143, 143, 143, 158, 152, 155, 147, 147, 147, 156, 159, 160, 143, 140, 146, 140, 161, 147, 141, 147, 141, 152, 162, 146, 146, 146, 163, 164, 158, 166, 167, 159, 160, 165, 146, 171, 155, 168, 169, 172, 577, 177, 175, 147, 161, 147, 180, 167, 163, 173, 165, 176, 174, 178, 166, 179, 162, 181, 168, 169, 146, 164, 146, 175, 171, 165, 170, 182, 173, 172, 173, 174, 177, 178, 184, 176, 173, 186, 183, 175, 185, 178, 180, 189, 188, 170, 190, 191, 170, 170, 179, 187, 192, 181, 193, 170, 194, 195, 170, 183, 170, 170, 182, 185, 184, 186, 189, 198, 187, 188, 186, 197, 191, 199, 193, 201, 200, 194, 202, 190, 204, 203, 205, 206, 210, 208, 209, 211, 192, 215, 214, 195, 198, 200, 213, 197, 216, 217, 218, 202, 212, 219, 220, 227, 221, 199, 208, 209, 204, 201, 203, 206, 223, 205, 204, 210, 217, 212, 211, 215, 222, 225, 213, 214, 216, 228, 229, 230, 214, 218, 220, 221, 224, 219, 224, 224, 227, 231, 232, 235, 245, 222, 223, 589, 242, 571, 225, 230, 233, 224, 244, 568, 248, 567, 243, 252, 566, 565, 589, 253, 228, 229, 251, 224, 231, 224, 232, 237, 237, 233, 245, 237, 235, 238, 238, 238, 238, 243, 237, 244, 237, 240, 240, 240, 242, 246, 238, 251, 254, 252, 255, 248, 240, 248, 240, 253, 256, 260, 259, 262, 261, 263, 265, 264, 237, 254, 237, 246, 267, 269, 268, 272, 271, 255, 256, 259, 274, 276, 240, 265, 240, 261, 273, 275, 277, 278, 279, 280, 281, 259, 262, 268, 282, 260, 263, 264, 287, 284, 285, 273, 288, 289, 276, 267, 272, 281, 269, 271, 286, 290, 278, 291, 294, 275, 292, 282, 297, 274, 284, 288, 277, 279, 280, 285, 287, 286, 289, 296, 298, 301, 299, 302, 294, 303, 304, 303, 303, 305, 297, 306, 290, 309, 292, 307, 308, 310, 311, 291, 312, 301, 313, 314, 315, 303, 316, 304, 302, 320, 296, 299, 307, 308, 317, 318, 298, 312, 323, 319, 326, 303, 314, 305, 327, 315, 306, 309, 311, 329, 320, 310, 328, 330, 316, 331, 338, 313, 335, 317, 347, 339, 345, 323, 340, 318, 317, 319, 346, 348, 326, 349, 329, 328, 330, 350, 351, 327, 352, 335, 342, 340, 342, 342, 353, 345, 331, 354, 347, 355, 338, 339, 357, 346, 356, 361, 362, 358, 368, 364, 372, 349, 348, 350, 365, 363, 365, 365, 352, 355, 351, 367, 366, 357, 353, 358, 361, 354, 368, 356, 369, 362, 363, 375, 373, 376, 379, 377, 382, 383, 372, 358, 364, 366, 380, 381, 384, 369, 385, 387, 385, 385, 386, 388, 367, 373, 389, 392, 393, 382, 394, 396, 383, 397, 398, 402, 379, 375, 376, 377, 387, 401, 404, 380, 381, 403, 388, 410, 408, 416, 407, 405, 409, 413, 384, 412, 396, 386, 392, 404, 393, 389, 415, 418, 394, 408, 401, 397, 402, 398, 403, 405, 407, 413, 424, 409, 428, 412, 429, 416, 430, 432, 433, 434, 437, 415, 438, 410, 435, 436, 440, 442, 439, 444, 441, 443, 418, 430, 450, 428, 453, 451, 432, 433, 452, 434, 454, 435, 455, 424, 436, 439, 457, 429, 456, 438, 461, 462, 440, 450, 437, 441, 458, 452, 442, 466, 443, 468, 444, 451, 467, 456, 469, 453, 471, 472, 462, 461, 473, 475, 480, 454, 476, 477, 478, 481, 492, 457, 455, 496, 487, 467, 468, 458, 482, 488, 482, 482, 489, 473, 466, 475, 490, 476, 472, 483, 495, 483, 483, 471, 469, 487, 497, 477, 478, 492, 488, 499, 481, 484, 480, 484, 484, 489, 496, 498, 500, 501, 504, 505, 512, 495, 490, 508, 519, 514, 517, 520, 521, 516, 522, 524, 499, 524, 524, 497, 525, 526, 501, 527, 505, 500, 529, 498, 508, 514, 516, 517, 504, 536, 537, 522, 538, 512, 541, 542, 525, 520, 527, 529, 544, 519, 543, 545, 546, 551, 552, 553, 521, 536, 537, 538, 526, 554, 555, 557, 564, 541, 563, 543, 542, 544, 551, 569, 570, 572, 546, 573, 574, 576, 575, 579, 580, 582, 583, 555, 584, 553, 545, 563, 587, 588, 552, 557, 590, 564, 554, 593, 576, 595, 572, 596, 579, 597, 569, 583, 599, 574, 575, 570, 580, 587, 588, 582, 600, 601, 602, 573, 593, 603, 607, 605, 590, 584, 597, 606, 609, 595, 610, 611, 612, 614, 596, 613, 599, 601, 615, 602, 562, 603, 603, 605, 561, 560, 600, 559, 606, 558, 556, 610, 611, 550, 613, 549, 548, 547, 540, 607, 539, 535, 612, 609, 534, 533, 532, 531, 614, 530, 528, 523, 518, 615, 619, 619, 619, 619, 619, 619, 619, 619, 619, 619, 619, 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, 621, 621, 515, 513, 621, 621, 621, 621, 621, 621, 621, 622, 622, 622, 623, 623, 623, 624, 511, 624, 624, 624, 624, 624, 625, 510, 509, 507, 625, 625, 625, 625, 625, 625, 625, 626, 626, 626, 627, 627, 506, 627, 627, 503, 627, 627, 627, 627, 627, 628, 628, 502, 628, 628, 628, 628, 628, 628, 628, 628, 629, 494, 493, 629, 629, 629, 629, 630, 491, 486, 485, 479, 474, 630, 630, 631, 470, 465, 631, 631, 631, 631, 632, 632, 464, 632, 632, 632, 632, 632, 632, 632, 632, 633, 633, 633, 634, 463, 460, 634, 634, 634, 634, 635, 635, 459, 635, 636, 449, 636, 636, 636, 636, 636, 448, 447, 446, 445, 431, 427, 426, 425, 423, 422, 421, 420, 419, 417, 414, 411, 406, 400, 399, 395, 391, 390, 378, 374, 371, 370, 360, 359, 344, 343, 341, 337, 336, 333, 332, 325, 324, 322, 321, 300, 295, 293, 283, 270, 266, 258, 257, 250, 249, 247, 241, 236, 234, 226, 207, 196, 157, 153, 150, 144, 102, 63, 56, 51, 46, 45, 18, 14, 11, 7, 6, 5, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, 618 } ; static yy_state_type yy_last_accepting_state; static char *yy_last_accepting_cpos; extern int yy_flex_debug; int yy_flex_debug = 0; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET char *yytext; #line 1 "vlex.l" /* * Copyright (c) Tony Bybell 2006-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. */ #line 13 "vlex.l" /* * vlex.l * 06apr06ajb */ #define YY_INPUT(buf, result, max_size) \ result = v_preproc(buf, max_size); #include "vlex.h" int my_yylineno = 0; static int yywrap(void) { return(1); } static int v_preproc_initialized = 0; char *v_preproc_name = NULL; static int v_preproc(char *buf, int max_size) { (void)max_size; int ch; if(!v_preproc_initialized) { yyin = fopen(v_preproc_name, "rb"); if(!yyin) return(0); v_preproc_initialized = 1; my_yylineno = 1; } ch = fgetc(yyin); if(ch!=EOF) { buf[0] = ch; buf[1] = 0; return(1); } else { fclose(yyin); yyin = NULL; v_preproc_initialized = 0; return (0); } } #line 1031 "vlex.c" #define INITIAL 0 #define CMNT 1 #define PREPROC 2 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif static int yy_init_globals (void ); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int yylex_destroy (void ); int yyget_debug (void ); void yyset_debug (int debug_flag ); YY_EXTRA_TYPE yyget_extra (void ); void yyset_extra (YY_EXTRA_TYPE user_defined ); FILE *yyget_in (void ); void yyset_in (FILE * in_str ); FILE *yyget_out (void ); void yyset_out (FILE * out_str ); yy_size_t yyget_leng (void ); char *yyget_text (void ); int yyget_lineno (void ); void yyset_lineno (int line_number ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yywrap (void ); #else extern int yywrap (void ); #endif #endif #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void ); #else static int input (void ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #define YY_READ_BUF_SIZE 8192 #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ size_t n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ buf[n++] = (char) c; \ if ( c == EOF && ferror( yyin ) ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ else \ { \ errno=0; \ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(yyin); \ } \ }\ \ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int yylex (void); #define YY_DECL int yylex (void) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK break; #endif #define YY_RULE_SETUP \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; #line 69 "vlex.l" #line 1215 "vlex.c" if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = stdin; if ( ! yyout ) yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin,YY_BUF_SIZE ); } yy_load_buffer_state( ); } while ( 1 ) /* loops until end-of-file is reached */ { yy_cp = (yy_c_buf_p); /* Support of yytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 619 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } while ( yy_base[yy_current_state] != 1364 ); yy_find_action: yy_act = yy_accept[yy_current_state]; if ( yy_act == 0 ) { /* have to back up */ yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); yy_act = yy_accept[yy_current_state]; } YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = (yy_hold_char); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; case 1: YY_RULE_SETUP #line 70 "vlex.l" { BEGIN CMNT; return V_CMT; } YY_BREAK case 2: YY_RULE_SETUP #line 71 "vlex.l" { return V_CMT; } YY_BREAK case 3: YY_RULE_SETUP #line 72 "vlex.l" { BEGIN INITIAL; return V_CMT; } YY_BREAK case 4: YY_RULE_SETUP #line 73 "vlex.l" { return V_CMT; } YY_BREAK case 5: YY_RULE_SETUP #line 74 "vlex.l" { return V_CMT; } YY_BREAK case 6: /* rule 6 can match eol */ YY_RULE_SETUP #line 75 "vlex.l" { my_yylineno++; return V_CMT; } YY_BREAK case 7: YY_RULE_SETUP #line 77 "vlex.l" { return V_KW; } YY_BREAK case 8: YY_RULE_SETUP #line 78 "vlex.l" { return V_KW; } YY_BREAK case 9: YY_RULE_SETUP #line 79 "vlex.l" { return V_KW; } YY_BREAK case 10: YY_RULE_SETUP #line 80 "vlex.l" { return V_KW; } YY_BREAK case 11: YY_RULE_SETUP #line 81 "vlex.l" { return V_KW; } YY_BREAK case 12: YY_RULE_SETUP #line 82 "vlex.l" { return V_KW; } YY_BREAK case 13: YY_RULE_SETUP #line 83 "vlex.l" { return V_KW; } YY_BREAK case 14: YY_RULE_SETUP #line 84 "vlex.l" { return V_KW; } YY_BREAK case 15: YY_RULE_SETUP #line 85 "vlex.l" { return V_KW; } YY_BREAK case 16: YY_RULE_SETUP #line 86 "vlex.l" { return V_KW; } YY_BREAK case 17: YY_RULE_SETUP #line 87 "vlex.l" { return V_KW; } YY_BREAK case 18: YY_RULE_SETUP #line 88 "vlex.l" { return V_KW; } YY_BREAK case 19: YY_RULE_SETUP #line 89 "vlex.l" { return V_KW; } YY_BREAK case 20: YY_RULE_SETUP #line 90 "vlex.l" { return V_KW; } YY_BREAK case 21: YY_RULE_SETUP #line 91 "vlex.l" { return V_KW; } YY_BREAK case 22: YY_RULE_SETUP #line 92 "vlex.l" { return V_KW; } YY_BREAK case 23: YY_RULE_SETUP #line 93 "vlex.l" { return V_KW; } YY_BREAK case 24: YY_RULE_SETUP #line 94 "vlex.l" { return V_KW; } YY_BREAK case 25: YY_RULE_SETUP #line 95 "vlex.l" { return V_KW; } YY_BREAK case 26: YY_RULE_SETUP #line 96 "vlex.l" { return V_KW; } YY_BREAK case 27: YY_RULE_SETUP #line 97 "vlex.l" { return V_KW; } YY_BREAK case 28: YY_RULE_SETUP #line 98 "vlex.l" { return V_KW; } YY_BREAK case 29: YY_RULE_SETUP #line 99 "vlex.l" { return V_KW; } YY_BREAK case 30: YY_RULE_SETUP #line 100 "vlex.l" { return V_KW; } YY_BREAK case 31: YY_RULE_SETUP #line 101 "vlex.l" { return V_KW; } YY_BREAK case 32: YY_RULE_SETUP #line 102 "vlex.l" { return V_KW; } YY_BREAK case 33: YY_RULE_SETUP #line 103 "vlex.l" { return V_KW; } YY_BREAK case 34: YY_RULE_SETUP #line 104 "vlex.l" { return V_KW; } YY_BREAK case 35: YY_RULE_SETUP #line 105 "vlex.l" { return V_KW; } YY_BREAK case 36: YY_RULE_SETUP #line 106 "vlex.l" { return V_KW; } YY_BREAK case 37: YY_RULE_SETUP #line 107 "vlex.l" { return V_KW; } YY_BREAK case 38: YY_RULE_SETUP #line 108 "vlex.l" { return V_KW; } YY_BREAK case 39: YY_RULE_SETUP #line 109 "vlex.l" { return V_KW; } YY_BREAK case 40: YY_RULE_SETUP #line 110 "vlex.l" { return V_KW; } YY_BREAK case 41: YY_RULE_SETUP #line 111 "vlex.l" { return V_KW; } YY_BREAK case 42: YY_RULE_SETUP #line 112 "vlex.l" { return V_KW; } YY_BREAK case 43: YY_RULE_SETUP #line 113 "vlex.l" { return V_KW; } YY_BREAK case 44: YY_RULE_SETUP #line 114 "vlex.l" { return V_KW; } YY_BREAK case 45: YY_RULE_SETUP #line 115 "vlex.l" { return V_KW; } YY_BREAK case 46: YY_RULE_SETUP #line 116 "vlex.l" { return V_KW; } YY_BREAK case 47: YY_RULE_SETUP #line 117 "vlex.l" { return V_KW; } YY_BREAK case 48: YY_RULE_SETUP #line 118 "vlex.l" { return V_KW; } YY_BREAK case 49: YY_RULE_SETUP #line 119 "vlex.l" { return V_KW; } YY_BREAK case 50: YY_RULE_SETUP #line 120 "vlex.l" { return V_KW; } YY_BREAK case 51: YY_RULE_SETUP #line 121 "vlex.l" { return V_KW; } YY_BREAK case 52: YY_RULE_SETUP #line 122 "vlex.l" { return V_KW; } YY_BREAK case 53: YY_RULE_SETUP #line 123 "vlex.l" { return V_KW; } YY_BREAK case 54: YY_RULE_SETUP #line 124 "vlex.l" { return V_KW; } YY_BREAK case 55: YY_RULE_SETUP #line 125 "vlex.l" { return V_KW; } YY_BREAK case 56: YY_RULE_SETUP #line 126 "vlex.l" { return V_KW; } YY_BREAK case 57: YY_RULE_SETUP #line 127 "vlex.l" { return V_KW; } YY_BREAK case 58: YY_RULE_SETUP #line 128 "vlex.l" { return V_KW; } YY_BREAK case 59: YY_RULE_SETUP #line 129 "vlex.l" { return V_KW; } YY_BREAK case 60: YY_RULE_SETUP #line 130 "vlex.l" { return V_KW; } YY_BREAK case 61: YY_RULE_SETUP #line 131 "vlex.l" { return V_KW; } YY_BREAK case 62: YY_RULE_SETUP #line 132 "vlex.l" { return V_KW; } YY_BREAK case 63: YY_RULE_SETUP #line 133 "vlex.l" { return V_KW; } YY_BREAK case 64: YY_RULE_SETUP #line 134 "vlex.l" { return V_KW; } YY_BREAK case 65: YY_RULE_SETUP #line 135 "vlex.l" { return V_KW; } YY_BREAK case 66: YY_RULE_SETUP #line 136 "vlex.l" { return V_KW; } YY_BREAK case 67: YY_RULE_SETUP #line 137 "vlex.l" { return V_KW; } YY_BREAK case 68: YY_RULE_SETUP #line 138 "vlex.l" { return V_KW; } YY_BREAK case 69: YY_RULE_SETUP #line 139 "vlex.l" { return V_KW; } YY_BREAK case 70: YY_RULE_SETUP #line 140 "vlex.l" { return V_KW; } YY_BREAK case 71: YY_RULE_SETUP #line 141 "vlex.l" { return V_KW; } YY_BREAK case 72: YY_RULE_SETUP #line 142 "vlex.l" { return V_KW; } YY_BREAK case 73: YY_RULE_SETUP #line 143 "vlex.l" { return V_KW; } YY_BREAK case 74: YY_RULE_SETUP #line 144 "vlex.l" { return V_KW; } YY_BREAK case 75: YY_RULE_SETUP #line 145 "vlex.l" { return V_KW; } YY_BREAK case 76: YY_RULE_SETUP #line 146 "vlex.l" { return V_KW; } YY_BREAK case 77: YY_RULE_SETUP #line 147 "vlex.l" { return V_KW; } YY_BREAK case 78: YY_RULE_SETUP #line 148 "vlex.l" { return V_KW; } YY_BREAK case 79: YY_RULE_SETUP #line 149 "vlex.l" { return V_KW; } YY_BREAK case 80: YY_RULE_SETUP #line 150 "vlex.l" { return V_KW; } YY_BREAK case 81: YY_RULE_SETUP #line 151 "vlex.l" { return V_KW; } YY_BREAK case 82: YY_RULE_SETUP #line 152 "vlex.l" { return V_KW; } YY_BREAK case 83: YY_RULE_SETUP #line 153 "vlex.l" { return V_KW; } YY_BREAK case 84: YY_RULE_SETUP #line 154 "vlex.l" { return V_KW; } YY_BREAK case 85: YY_RULE_SETUP #line 155 "vlex.l" { return V_KW; } YY_BREAK case 86: YY_RULE_SETUP #line 156 "vlex.l" { return V_KW; } YY_BREAK case 87: YY_RULE_SETUP #line 157 "vlex.l" { return V_KW; } YY_BREAK case 88: YY_RULE_SETUP #line 158 "vlex.l" { return V_KW; } YY_BREAK case 89: YY_RULE_SETUP #line 159 "vlex.l" { return V_KW; } YY_BREAK case 90: YY_RULE_SETUP #line 160 "vlex.l" { return V_KW; } YY_BREAK case 91: YY_RULE_SETUP #line 161 "vlex.l" { return V_KW; } YY_BREAK case 92: YY_RULE_SETUP #line 162 "vlex.l" { return V_KW; } YY_BREAK case 93: YY_RULE_SETUP #line 163 "vlex.l" { return V_KW; } YY_BREAK case 94: YY_RULE_SETUP #line 164 "vlex.l" { return V_KW; } YY_BREAK case 95: YY_RULE_SETUP #line 166 "vlex.l" { return V_KW; } YY_BREAK case 96: YY_RULE_SETUP #line 167 "vlex.l" { return V_KW; } YY_BREAK case 97: YY_RULE_SETUP #line 168 "vlex.l" { return V_KW; } YY_BREAK case 98: YY_RULE_SETUP #line 169 "vlex.l" { return V_KW; } YY_BREAK case 99: YY_RULE_SETUP #line 170 "vlex.l" { return V_KW; } YY_BREAK case 100: YY_RULE_SETUP #line 171 "vlex.l" { return V_KW; } YY_BREAK case 101: YY_RULE_SETUP #line 172 "vlex.l" { return V_KW; } YY_BREAK case 102: YY_RULE_SETUP #line 173 "vlex.l" { return V_KW; } YY_BREAK case 103: YY_RULE_SETUP #line 175 "vlex.l" { return V_KW_2005; } YY_BREAK case 104: YY_RULE_SETUP #line 176 "vlex.l" { return V_KW_2005; } YY_BREAK case 105: YY_RULE_SETUP #line 177 "vlex.l" { return V_KW_2005; } YY_BREAK case 106: YY_RULE_SETUP #line 178 "vlex.l" { return V_KW_2005; } YY_BREAK case 107: YY_RULE_SETUP #line 179 "vlex.l" { return V_KW_2005; } YY_BREAK case 108: YY_RULE_SETUP #line 180 "vlex.l" { return V_KW_2005; } YY_BREAK case 109: YY_RULE_SETUP #line 181 "vlex.l" { return V_KW_2005; } YY_BREAK case 110: YY_RULE_SETUP #line 182 "vlex.l" { return V_KW_2005; } YY_BREAK case 111: YY_RULE_SETUP #line 183 "vlex.l" { return V_KW_2005; } YY_BREAK case 112: YY_RULE_SETUP #line 184 "vlex.l" { return V_KW_2005; } YY_BREAK case 113: YY_RULE_SETUP #line 185 "vlex.l" { return V_KW_2005; } YY_BREAK case 114: YY_RULE_SETUP #line 186 "vlex.l" { return V_KW_2005; } YY_BREAK case 115: YY_RULE_SETUP #line 187 "vlex.l" { return V_KW_2005; } YY_BREAK case 116: YY_RULE_SETUP #line 188 "vlex.l" { return V_KW_2005; } YY_BREAK case 117: YY_RULE_SETUP #line 189 "vlex.l" { return V_KW_2005; } YY_BREAK case 118: YY_RULE_SETUP #line 190 "vlex.l" { return V_KW_2005; } YY_BREAK case 119: YY_RULE_SETUP #line 191 "vlex.l" { return V_KW_2005; } YY_BREAK case 120: YY_RULE_SETUP #line 192 "vlex.l" { return V_KW_2005; } YY_BREAK case 121: YY_RULE_SETUP #line 193 "vlex.l" { return V_KW_2005; } YY_BREAK case 122: YY_RULE_SETUP #line 194 "vlex.l" { return V_KW_2005; } YY_BREAK case 123: YY_RULE_SETUP #line 195 "vlex.l" { return V_KW_2005; } YY_BREAK case 124: YY_RULE_SETUP #line 196 "vlex.l" { return V_KW_2005; } YY_BREAK case 125: YY_RULE_SETUP #line 197 "vlex.l" { return V_KW_2005; } YY_BREAK case 126: YY_RULE_SETUP #line 199 "vlex.l" { return V_KW_2005; } YY_BREAK case 127: YY_RULE_SETUP #line 200 "vlex.l" { return V_KW_2005; } YY_BREAK case 128: YY_RULE_SETUP #line 201 "vlex.l" { return V_KW_2005; } YY_BREAK case 129: YY_RULE_SETUP #line 202 "vlex.l" { return V_KW_2005; } YY_BREAK case 130: YY_RULE_SETUP #line 203 "vlex.l" { return V_KW_2005; } YY_BREAK case 131: YY_RULE_SETUP #line 204 "vlex.l" { return V_KW_2005; } YY_BREAK case 132: YY_RULE_SETUP #line 205 "vlex.l" { return V_KW_2005; } YY_BREAK case 133: YY_RULE_SETUP #line 207 "vlex.l" { return V_MODULE; } YY_BREAK case 134: YY_RULE_SETUP #line 208 "vlex.l" { return V_MODULE; } YY_BREAK case 135: YY_RULE_SETUP #line 209 "vlex.l" { return V_MODULE; } YY_BREAK case 136: YY_RULE_SETUP #line 211 "vlex.l" { return V_ENDMODULE; } YY_BREAK case 137: YY_RULE_SETUP #line 212 "vlex.l" { return V_ENDMODULE; } YY_BREAK case 138: YY_RULE_SETUP #line 214 "vlex.l" { return V_PREPROC_WS; } YY_BREAK case 139: /* rule 139 can match eol */ YY_RULE_SETUP #line 215 "vlex.l" { my_yylineno++; BEGIN INITIAL; return V_WS; } YY_BREAK case 140: YY_RULE_SETUP #line 217 "vlex.l" { if(is_builtin_define (yytext+1, yyleng-1)) { BEGIN PREPROC; return(V_PREPROC); } return(V_MACRO); } YY_BREAK case 141: YY_RULE_SETUP #line 228 "vlex.l" { return V_ID; } YY_BREAK case 142: YY_RULE_SETUP #line 229 "vlex.l" { return V_FUNC; } YY_BREAK case 143: YY_RULE_SETUP #line 230 "vlex.l" { return V_ID; } YY_BREAK case 144: YY_RULE_SETUP #line 231 "vlex.l" { return V_ID; } YY_BREAK case 145: YY_RULE_SETUP #line 232 "vlex.l" { return V_PORT; } YY_BREAK case 146: YY_RULE_SETUP #line 233 "vlex.l" { return V_NUMBER; } YY_BREAK case 147: YY_RULE_SETUP #line 234 "vlex.l" { return V_NUMBER; } YY_BREAK case 148: YY_RULE_SETUP #line 235 "vlex.l" { return V_NUMBER; } YY_BREAK case 149: YY_RULE_SETUP #line 236 "vlex.l" { return V_NUMBER; } YY_BREAK case 150: YY_RULE_SETUP #line 237 "vlex.l" { return V_NUMBER; } YY_BREAK case 151: YY_RULE_SETUP #line 238 "vlex.l" { return V_IGNORE; } YY_BREAK case 152: YY_RULE_SETUP #line 239 "vlex.l" { return V_WS; } YY_BREAK case 153: /* rule 153 can match eol */ YY_RULE_SETUP #line 240 "vlex.l" { my_yylineno++; return V_WS; } YY_BREAK case 154: YY_RULE_SETUP #line 241 "vlex.l" { return V_CMT; } YY_BREAK case 155: YY_RULE_SETUP #line 242 "vlex.l" { return V_STRING; } YY_BREAK case 156: YY_RULE_SETUP #line 243 "vlex.l" { return V_IGNORE; } YY_BREAK case 157: YY_RULE_SETUP #line 245 "vlex.l" ECHO; YY_BREAK #line 2094 "vlex.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(CMNT): case YY_STATE_EOF(PREPROC): yyterminate(); case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_c_buf_p); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer (void) { register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; register char *source = (yytext_ptr); register int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { yy_size_t num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { yy_size_t new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = 0; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart(yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state (void) { register yy_state_type yy_current_state; register char *yy_cp; yy_current_state = (yy_start); for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 619 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) { register int yy_is_jam; register char *yy_cp = (yy_c_buf_p); register YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 619 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 618); return yy_is_jam ? 0 : yy_current_state; } #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void) #else static int input (void) #endif { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart(yyin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) return EOF; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); return c; } #endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void yyrestart (FILE * input_file ) { if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin,YY_BUF_SIZE ); } yy_init_buffer(YY_CURRENT_BUFFER,input_file ); yy_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } static void yy_load_buffer_state (void) { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer(b,file ); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * */ void yy_delete_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) yyfree((void *) b->yy_ch_buf ); yyfree((void *) b ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) { int oerrno = errno; yy_flush_buffer(b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void yy_flush_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) { if (new_buffer == NULL) return; yyensure_buffer_stack(); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void yypop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void yyensure_buffer_stack (void) { yy_size_t num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return 0; b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = 0; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; yy_switch_to_buffer(b ); return b; } /** Setup the input buffer state to scan a string. The next call to yylex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan * * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * yy_scan_bytes() instead. */ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) { return yy_scan_bytes(yystr,strlen(yystr) ); } /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. * @param yybytes the byte buffer to scan * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) { YY_BUFFER_STATE b; char *buf; yy_size_t n; yy_size_t i; /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; buf = (char *) yyalloc(n ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); for ( i = 0; i < _yybytes_len; ++i ) buf[i] = yybytes[i]; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = yy_scan_buffer(buf,n ); if ( ! b ) YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif static void yy_fatal_error (yyconst char* msg ) { (void) fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = (yy_hold_char); \ (yy_c_buf_p) = yytext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the current line number. * */ int yyget_lineno (void) { return yylineno; } /** Get the input stream. * */ FILE *yyget_in (void) { return yyin; } /** Get the output stream. * */ FILE *yyget_out (void) { return yyout; } /** Get the length of the current token. * */ yy_size_t yyget_leng (void) { return yyleng; } /** Get the current token. * */ char *yyget_text (void) { return yytext; } /** Set the current line number. * @param line_number * */ void yyset_lineno (int line_number ) { yylineno = line_number; } /** Set the input stream. This does not discard the current * input buffer. * @param in_str A readable stream. * * @see yy_switch_to_buffer */ void yyset_in (FILE * in_str ) { yyin = in_str ; } void yyset_out (FILE * out_str ) { yyout = out_str ; } int yyget_debug (void) { return yy_flex_debug; } void yyset_debug (int bdebug ) { yy_flex_debug = bdebug ; } static int yy_init_globals (void) { /* Initialization is the same as for the non-reentrant scanner. * This function is called from yylex_destroy(), so don't allocate here. */ (yy_buffer_stack) = 0; (yy_buffer_stack_top) = 0; (yy_buffer_stack_max) = 0; (yy_c_buf_p) = (char *) 0; (yy_init) = 0; (yy_start) = 0; /* Defined in main.c */ #ifdef YY_STDINIT yyin = stdin; yyout = stdout; #else yyin = (FILE *) 0; yyout = (FILE *) 0; #endif /* For future reference: Set errno on error, since we are called by * yylex_init() */ return 0; } /* yylex_destroy is for both reentrant and non-reentrant scanners. */ int yylex_destroy (void) { /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; yypop_buffer_state(); } /* Destroy the stack itself. */ yyfree((yy_buffer_stack) ); (yy_buffer_stack) = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * yylex() is called, initialization will occur. */ yy_init_globals( ); return 0; } /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s ) { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *yyalloc (yy_size_t size ) { return (void *) malloc( size ); } void *yyrealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } void yyfree (void * ptr ) { free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 245 "vlex.l" gtkwave-gtk3-3.3.125/contrib/rtlbrowse/logfile.c0000664000175000017500000017702715047725113021004 0ustar bybellbybell/* * Copyright (c) Tony Bybell 1999-2018. * * 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 "splay.h" #include "vlex.h" #include "jrb.h" #include "wavelink.h" #if GTK_CHECK_VERSION(3,0,0) #define XXX_GTK_STOCK_GO_BACK "go-previous" #define XXX_GTK_STOCK_GO_FORWARD "go-next" #define XXX_GTK_STOCK_CLOSE "window-close" #else #define XXX_GTK_STOCK_GO_BACK GTK_STOCK_GO_BACK #define XXX_GTK_STOCK_GO_FORWARD GTK_STOCK_GO_FORWARD #define XXX_GTK_STOCK_CLOSE GTK_STOCK_CLOSE #endif extern ds_Tree *flattened_mod_list_root; extern struct gtkwave_annotate_ipc_t *anno_ctx; extern GtkWidget *notebook; extern int verilog_2005; TimeType old_marker = 0; unsigned old_marker_set = 0; #define set_winsize(w,x,y) gtk_window_set_default_size(GTK_WINDOW(w),(x),(y)) /* only for use locally */ struct wave_logfile_lines_t { struct wave_logfile_lines_t *next; int line_no, tok; char *text; }; struct logfile_context_t { ds_Tree *which; char *title; int display_mode; int width; JRB varnames; int resolved; }; struct text_find_t { struct text_find_t *next; GtkWidget *text, *window, *button; struct logfile_context_t *ctx; gint line, offs; /* of insert marker */ gint srch_line, srch_offs; /* for search, to avoid duplication */ GtkTextTag *bold_tag; GtkTextTag *dgray_tag, *lgray_tag; GtkTextTag *blue_tag, *fwht_tag; GtkTextTag *mono_tag; GtkTextTag *size_tag; }; void bwlogbox(char *title, int width, ds_Tree *t, int display_mode); void bwlogbox_2(struct logfile_context_t *ctx, GtkWidget *window, GtkWidget *button, GtkWidget *text); gboolean update_ctx_when_idle(gpointer textview_or_dummy); static struct text_find_t *text_root = NULL; static struct text_find_t *selected_text_via_tab = NULL; static GtkWidget *matchcase_checkbutton = NULL; static gboolean matchcase_active = FALSE; static char *fontname_logfile = NULL; /* 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 */ static gpointer fontx = NULL; static GtkTextIter iterx; static GtkTextTag *bold_tag = NULL; static GtkTextTag *dgray_tag = NULL, *lgray_tag = NULL; static GtkTextTag *blue_tag = NULL, *fwht_tag = NULL; static GtkTextTag *mono_tag = NULL; static GtkTextTag *size_tag = NULL; static void *pressWindow = NULL; static gint pressX = 0; static gint pressY = 0; static gint button_press_event(GtkWidget *widget, GdkEventButton *event) { pressWindow = (void *)gtk_widget_get_window(widget); pressX = event->x; pressY = event->y; return(FALSE); } static gint expose_event_local(GtkWidget *widget, GdkEventExpose *event) { (void)event; struct text_find_t *tr = text_root; while(tr) { if(tr->window == widget) { if(selected_text_via_tab != tr) { selected_text_via_tab = tr; /* printf("Expose: %08x '%s'\n", widget, tr->ctx->title); */ } return(FALSE); } tr = tr->next; } selected_text_via_tab = NULL; return(FALSE); } #if GTK_CHECK_VERSION(3,0,0) static gint draw_event(GtkWidget *widget, cairo_t *cr, gpointer user_data) { (void) cr; (void) user_data; return(expose_event_local(widget, NULL)); } #endif GtkWidget * XXX_gtk_toolbar_insert_stock (GtkToolbar *toolbar, const gchar *stock_id, const char *tooltip_text, const char *tooltip_private_text, GCallback callback, gpointer user_data, gint position) { (void) tooltip_private_text; GtkToolItem *button; #if GTK_CHECK_VERSION(3,0,0) GtkWidget *icon_widget = gtk_image_new_from_icon_name(stock_id, GTK_ICON_SIZE_BUTTON); gtk_widget_show(icon_widget); button = gtk_tool_button_new(icon_widget, NULL); #else button = gtk_tool_button_new_from_stock (stock_id); #endif gtk_tool_item_set_tooltip_text (button, tooltip_text); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), button, position); g_signal_connect(XXX_GTK_OBJECT(button), "clicked", G_CALLBACK(callback), user_data); return(GTK_WIDGET(button)); } void read_insert_position(struct text_find_t *tr) { GtkTextBuffer *tb = gtk_text_view_get_buffer(GTK_TEXT_VIEW(tr->text)); GtkTextMark *tm = gtk_text_buffer_get_insert(tb); GtkTextIter iter; gtk_text_buffer_get_iter_at_mark(tb, &iter, tm); tr->line = gtk_text_iter_get_line(&iter); tr->offs = gtk_text_iter_get_line_offset(&iter); } void set_insert_position(struct text_find_t *tr) { GtkTextBuffer *tb = gtk_text_view_get_buffer(GTK_TEXT_VIEW(tr->text)); GtkTextMark *tm = gtk_text_buffer_get_insert(tb); GtkTextIter iter; gint llen; gtk_text_buffer_get_iter_at_mark(tb, &iter, tm); gtk_text_iter_set_line(&iter, tr->line); llen = gtk_text_iter_get_chars_in_line (&iter); tr->offs = (tr->offs > llen) ? llen : tr->offs; gtk_text_iter_set_line_offset(&iter, tr->offs); gtk_text_buffer_place_cursor(tb, &iter); } static void forward_chars_with_skipping (GtkTextIter *iter, gint count) { gint i; g_return_if_fail (count >= 0); i = count; while (i > 0) { gboolean ignored = FALSE; if (gtk_text_iter_get_char (iter) == 0xFFFC) ignored = TRUE; gtk_text_iter_forward_char (iter); if (!ignored) --i; } } static gboolean iter_forward_search_caseins( const GtkTextIter *iter, gchar *str, GtkTextIter *match_start, GtkTextIter *match_end) { GtkTextIter start = *iter; GtkTextIter next; gchar *line_text, *found, *pnt; gint offset; gchar *strcaseins; if(!str) return(FALSE); pnt = strcaseins = strdup(str); while(*pnt) { *pnt = toupper((int)(unsigned char)*pnt); pnt++; } for(;;) { next = start; gtk_text_iter_forward_line (&next); /* No more text in buffer */ if (gtk_text_iter_equal (&start, &next)) { free(strcaseins); return(FALSE); } pnt = line_text = gtk_text_iter_get_visible_text (&start, &next); while(*pnt) { *pnt = toupper((int)(unsigned char)*pnt); pnt++; } found = strstr(line_text, strcaseins); if(found) { gchar cached = *found; *found = 0; offset = g_utf8_strlen (line_text, -1); *found = cached; break; } g_free (line_text); start = next; } *match_start = start; forward_chars_with_skipping (match_start, offset); offset = g_utf8_strlen (str, -1); *match_end = *match_start; forward_chars_with_skipping (match_end, offset); free(strcaseins); return(TRUE); } void tr_search_forward(char *str, gboolean noskip) { struct text_find_t *tr = selected_text_via_tab; if((tr) && (tr->text)) { GtkTextBuffer *tb = gtk_text_view_get_buffer(GTK_TEXT_VIEW(tr->text)); GtkTextMark *tm = gtk_text_buffer_get_insert(tb); GtkTextIter iter; gboolean found = FALSE; GtkTextIter match_start; GtkTextIter match_end; gtk_text_buffer_get_iter_at_mark(tb, &iter, tm); tr->line = gtk_text_iter_get_line(&iter); tr->offs = gtk_text_iter_get_line_offset(&iter); if(!noskip) if((tr->line == tr->srch_line) && (tr->offs == tr->srch_offs)) { gtk_text_iter_forward_char(&iter); } if(str) { if(!matchcase_active) { found = iter_forward_search_caseins(&iter, str, &match_start, &match_end); } else { found = gtk_text_iter_forward_search(&iter, str, GTK_TEXT_SEARCH_TEXT_ONLY, &match_start, &match_end, NULL); } if(!found) { gtk_text_buffer_get_start_iter(tb, &iter); if(!matchcase_active) { found = iter_forward_search_caseins(&iter, str, &match_start, &match_end); } else { found = gtk_text_iter_forward_search(&iter, str, GTK_TEXT_SEARCH_TEXT_ONLY, &match_start, &match_end, NULL); } } } if(found) { gtk_text_buffer_select_range(tb, &match_start, &match_end); read_insert_position(tr); tr->srch_line = tr->line; tr->srch_offs = tr->offs; /* tm = gtk_text_buffer_get_insert(tb); */ /* scan-build : never read */ gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(tr->text), &match_start, 0.0, TRUE, 0.0, 0.5); } else { gtk_text_buffer_get_iter_at_mark(tb, &iter, tm); gtk_text_buffer_select_range(tb, &iter, &iter); } } } static gboolean iter_backward_search_caseins( const GtkTextIter *iter, gchar *str, GtkTextIter *match_start, GtkTextIter *match_end) { GtkTextIter start = *iter; GtkTextIter next; gchar *line_text; int offset; int cmpval; if(!str) return(FALSE); offset = g_utf8_strlen (str, -1); for(;;) { if(gtk_text_iter_is_start(&start)) { break; } next = start; forward_chars_with_skipping (&next, offset); line_text = gtk_text_iter_get_visible_text (&start, &next); cmpval = strcasecmp(str, line_text); g_free(line_text); if(!cmpval) { *match_start = start; *match_end = next; return(TRUE); } gtk_text_iter_backward_char(&start); } return(FALSE); } void tr_search_backward(char *str) { struct text_find_t *tr = selected_text_via_tab; if((tr) && (tr->text)) { GtkTextBuffer *tb = gtk_text_view_get_buffer(GTK_TEXT_VIEW(tr->text)); GtkTextMark *tm = gtk_text_buffer_get_insert(tb); GtkTextIter iter; gboolean found = FALSE; GtkTextIter match_start; GtkTextIter match_end; gtk_text_buffer_get_iter_at_mark(tb, &iter, tm); tr->line = gtk_text_iter_get_line(&iter); tr->offs = gtk_text_iter_get_line_offset(&iter); if((tr->line == tr->srch_line) && (tr->offs == tr->srch_offs)) { gtk_text_iter_backward_char(&iter); } if(str) { if(!matchcase_active) { found = iter_backward_search_caseins(&iter, str, &match_start, &match_end); } else { found = gtk_text_iter_backward_search(&iter, str, GTK_TEXT_SEARCH_TEXT_ONLY, &match_start, &match_end, NULL); } if(!found) { gtk_text_buffer_get_end_iter(tb, &iter); if(!matchcase_active) { found = iter_backward_search_caseins(&iter, str, &match_start, &match_end); } else { found = gtk_text_iter_backward_search(&iter, str, GTK_TEXT_SEARCH_TEXT_ONLY, &match_start, &match_end, NULL); } } } if(found) { gtk_text_buffer_select_range(tb, &match_start, &match_end); read_insert_position(tr); tr->srch_line = tr->line; tr->srch_offs = tr->offs; /* tm = gtk_text_buffer_get_insert(tb); */ /* scan-build : never read */ gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(tr->text), &match_start, 0.0, TRUE, 0.0, 0.5); } else { gtk_text_buffer_get_iter_at_mark(tb, &iter, tm); gtk_text_buffer_select_range(tb, &iter, &iter); } } } static char *search_string = NULL; static void search_backward(GtkWidget *widget, gpointer data) { (void)widget; (void)data; tr_search_backward(search_string); } static gboolean forward_noskip = FALSE; static void search_forward(GtkWidget *widget, gpointer data) { (void)widget; (void)data; tr_search_forward(search_string, forward_noskip); } /* Signal callback for the filter widget. This catch the return key to update the signal area. */ static gboolean find_edit_cb (GtkWidget *widget, GdkEventKey *ev, gpointer *data) { (void)data; /* Maybe this test is too strong ? */ if (ev->keyval == GDK_KEY_Return) { const char *t = gtk_entry_get_text (GTK_ENTRY (widget)); if(search_string) { free(search_string); search_string = NULL; } if (t == NULL || *t == 0) { } else { search_string = strdup(t); } search_forward(NULL, NULL); } return FALSE; } static void toggle_callback(GtkWidget *widget, GtkWidget *nothing) { (void)nothing; matchcase_active = (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) != 0); tr_search_forward(search_string, TRUE); } static void press_callback (GtkWidget *widget, gpointer *data) { GdkEventKey ev; ev.keyval = GDK_KEY_Return; forward_noskip = TRUE; find_edit_cb (widget, &ev, data); forward_noskip = FALSE; } void create_toolbar(GtkWidget *table) { GtkWidget *find_label; GtkWidget *find_entry; GtkWidget *tb; GtkWidget *stock; #if !GTK_CHECK_VERSION(3,0,0) GtkStyle *style; #endif GtkWidget *hbox; int tb_pos = 0; #if GTK_CHECK_VERSION(3,0,0) hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 1); gtk_box_set_homogeneous (GTK_BOX(hbox), FALSE); #else hbox = gtk_hbox_new (FALSE, 1); #endif gtk_widget_show (hbox); #if GTK_CHECK_VERSION(3,0,0) gtk_grid_attach (GTK_GRID (table), hbox, 0, 255, 255, 1); gtk_widget_set_hexpand (GTK_WIDGET (hbox), TRUE); gtk_widget_set_vexpand (GTK_WIDGET (hbox), FALSE); /* otherwise the bottom part stretches */ #else gtk_table_attach (GTK_TABLE (table), hbox, 0, 1, 255, 256, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1); #endif find_label = gtk_label_new ("Find:"); gtk_widget_show (find_label); gtk_box_pack_start (GTK_BOX (hbox), find_label, FALSE, FALSE, 0); find_entry = gtk_entry_new (); gtk_widget_show (find_entry); g_signal_connect(XXX_GTK_OBJECT(find_entry), "changed", G_CALLBACK(press_callback), NULL); g_signal_connect(XXX_GTK_OBJECT (find_entry), "key_press_event", (GCallback) find_edit_cb, NULL); gtk_box_pack_start (GTK_BOX (hbox), find_entry, FALSE, FALSE, 0); tb = gtk_toolbar_new(); #if !GTK_CHECK_VERSION(3,0,0) style = gtk_widget_get_style(tb); style->xthickness = style->ythickness = 0; gtk_widget_set_style (tb, style); #endif gtk_widget_show (tb); gtk_toolbar_set_style(GTK_TOOLBAR(tb), GTK_TOOLBAR_ICONS); stock = XXX_gtk_toolbar_insert_stock(GTK_TOOLBAR(tb), XXX_GTK_STOCK_GO_BACK, "Search Back", NULL, G_CALLBACK(search_backward), NULL, tb_pos++); #if !GTK_CHECK_VERSION(3,0,0) style = gtk_widget_get_style(stock); style->xthickness = style->ythickness = 0; gtk_widget_set_style (stock, style); #endif gtk_widget_show(stock); stock = XXX_gtk_toolbar_insert_stock(GTK_TOOLBAR(tb), XXX_GTK_STOCK_GO_FORWARD, "Search Forward", NULL, G_CALLBACK(search_forward), NULL, tb_pos); /* scan-build: removed ++ on tb_pos as never read */ #if !GTK_CHECK_VERSION(3,0,0) style = gtk_widget_get_style(stock); style->xthickness = style->ythickness = 0; gtk_widget_set_style (stock, style); #endif gtk_widget_show(stock); gtk_box_pack_start (GTK_BOX (hbox), tb, FALSE, FALSE, 0); matchcase_checkbutton = gtk_check_button_new_with_label("Match case"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(matchcase_checkbutton), matchcase_active); g_signal_connect (XXX_GTK_OBJECT (matchcase_checkbutton), "toggled", G_CALLBACK(toggle_callback), NULL); gtk_widget_show(matchcase_checkbutton); gtk_box_pack_start (GTK_BOX (hbox), matchcase_checkbutton, FALSE, FALSE, 0); } static char *tmpnam_rtlbrowse(char *s, int *fd) { #if defined __MINGW32__ *fd = -1; return(tmpnam(s)); #else (void)s; char *backpath = "gtkwaveXXXXXX"; char *tmpspace; int len = strlen(P_tmpdir); int i; unsigned char slash = '/'; for(i=0;i='a')&&(ch<='z')) || ((ch>='A')&&(ch<='Z')) || ((ch>='0')&&(ch<='9')) || (ch == '_') || (ch == '$'); return(rc); } static char *hexify(char *s) { int len = strlen(s); if(len < 4) { char *s2 = malloc(len+1+1); int idx; s2[0]='b'; for(idx = 0; idx < len; idx++) { s2[idx+1] = toupper((int)(unsigned char)s[idx]); } s2[idx+1] = 0; free(s); return(s2); } else { int skip = len & 3; int siz = ((len + 3) / 4) + 1; char *sorig = s; char *s2 = calloc(1, siz); int idx; char *pnt = s2; char arr[5] = { 0, 0, 0, 0, 0 }; /* scan-build : but arr[4] should work ok */ while(*s) { char isx, isz; int val; if(!skip) { arr[0] = toupper((int)(unsigned char)*(s++)); arr[1] = toupper((int)(unsigned char)*(s++)); arr[2] = toupper((int)(unsigned char)*(s++)); arr[3] = toupper((int)(unsigned char)*(s++)); } else { int j = 3; for(idx = skip-1; idx>=0; idx--) { arr[j] = toupper((int)(unsigned char)s[idx]); j--; } for(idx = j; idx >= 0; idx--) { arr[idx] = ((arr[j+1] == 'X') || (arr[j+1] == 'Z')) ? arr[j+1] : '0'; } s+=skip; skip = 0; } isx = isz = 0; val = 0; for(idx=0; idx<4; idx++) { val <<= 1; if(arr[idx] == '0') continue; if(arr[idx] == '1') { val |= 1; continue; } if(arr[idx] == 'Z') { isz++; continue; } isx++; } if(isx) { *(pnt++) = (isx==4) ? 'x' : 'X'; } else if(isz) { *(pnt++) = (isz==4) ? 'z' : 'Z'; } else { *(pnt++) = "0123456789ABCDEF"[val]; } } free(sorig); return(s2); } } int fst_alpha_strcmpeq(const char *s1, const char *s2) { for(;;) { char c1 = *s1; char c2 = *s2; switch(c1) { case ' ': case '\t': case '[': c1 = 0; default: break; } switch(c2) { case ' ': case '\t': case '[': c2 = 0; default: break; } if(c1 != c2) { return(1); } if(!c1) break; s1++; s2++; } return(0); } /* 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 static void DNDBeginCB( GtkWidget *widget, GdkDragContext *dc, gpointer data ) { (void)widget; (void)dc; (void)data; /* nothing */ } static void DNDEndCB( GtkWidget *widget, GdkDragContext *dc, gpointer data ) { (void)widget; (void)dc; (void)data; /* nothing */ } static void DNDDataDeleteCB( GtkWidget *widget, GdkDragContext *dc, gpointer data ) { (void)widget; (void)dc; (void)data; /* nothing */ } static void DNDDataRequestCB( GtkWidget *widget, GdkDragContext *dc, GtkSelectionData *selection_data, guint info, guint t, gpointer data ) { (void)dc; (void)t; (void)info; struct logfile_context_t *ctx = (struct logfile_context_t *)data; GtkWidget *text = (GtkWidget *)widget; gchar *sel = NULL; gchar *sel2 = NULL; GtkTextIter start; GtkTextIter end; int ok = 0; char ch; if((!text)||(!ctx)) return; if (gtk_text_buffer_get_selection_bounds (gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), &start, &end)) { ok = 1; } else if(((void *)gtk_widget_get_window(widget)) == pressWindow) { GtkTextView *text_view = GTK_TEXT_VIEW(text); gint buffer_x, buffer_y; gint s_trailing, e_trailing; gtk_text_view_window_to_buffer_coords(text_view, GTK_TEXT_WINDOW_WIDGET, pressX, pressY, &buffer_x, &buffer_y); gtk_text_view_get_iter_at_position (text_view, &start, &s_trailing, buffer_x, buffer_y); gtk_text_view_get_iter_at_position (text_view, &end, &e_trailing, buffer_x, buffer_y); gtk_text_iter_forward_char(&end); ok = 1; } pressWindow = NULL; if(ok) { if(gtk_text_iter_compare (&start, &end) < 0) { sel = gtk_text_buffer_get_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), &start, &end, FALSE); if(sel && strlen(sel)) { while(gtk_text_iter_backward_char(&start)) { sel2 = gtk_text_buffer_get_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), &start, &end, FALSE); if(!sel2) break; ch = *sel2; g_free(sel2); if(!is_identifier(ch)) { gtk_text_iter_forward_char(&start); break; } } gtk_text_iter_backward_char(&end); for(;;) { gtk_text_iter_forward_char(&end); sel2 = gtk_text_buffer_get_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), &start, &end, FALSE); if(!sel2) break; ch = *(sel2 + strlen(sel2) - 1); g_free(sel2); if(!is_identifier(ch)) { gtk_text_iter_backward_char(&end); break; } } sel2 = gtk_text_buffer_get_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), &start, &end, FALSE); g_free(sel); sel = sel2; sel2 = NULL; } /* gtk_text_buffer_delete_selection (gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), 0, 0); ...no need to delete because of update_ctx_when_idle() */ } } if(sel) { JRB strs, node; int fd; char *fname = tmpnam_rtlbrowse("rtlbrowse", &fd); FILE *handle = fopen(fname, "wb"); int lx; int degate = 0; int cnt = 0; if(!handle) { fprintf(stderr, "Could not open cutpaste file '%s'\n", fname); return; } fprintf(handle, "%s", sel); fclose(handle); if(fd>=0) close(fd); v_preproc_name = fname; strs = make_jrb(); while((lx = yylex())) { char *pnt = yytext; if(!verilog_2005) { if(lx == V_KW_2005) lx = V_ID; } if(lx==V_ID) { if(!degate) { JRB str = jrb_find_str(strs, pnt); Jval jv; jv.v = NULL; if(!str) { jrb_insert_str(strs, strdup(pnt), jv); cnt++; } } } else if(lx==V_IGNORE) { if(*pnt == '[') degate = 1; else if(*pnt == ']') degate = 0; } } unlink(fname); free(fname); if(cnt) { int title_len = 5 + strlen(ctx->title) + 1; char *tpnt = calloc(1, title_len + 1); char *op = ctx->title; char *np = tpnt; char *mlist = NULL; int mlen = 0; strcpy(np, "{net "); np+=5; while(*op) { if(*op == '.') *np = ' '; else *np = *op; op++; np++; } *np = ' '; jrb_traverse(node, strs) { int slen = strlen(node->key.s); int singlen = title_len + slen + 2; char *singlist = calloc(1, singlen + 1); memcpy(singlist, tpnt, title_len); strcpy(singlist + title_len, node->key.s); strcpy(singlist + title_len + slen, "} "); if(mlist) { mlist = realloc(mlist, mlen + singlen + 1); strcpy(mlist + mlen, singlist); mlen += singlen; } else { mlist = strdup(singlist); mlen = singlen; } free(singlist); free(node->key.s); } gtk_selection_data_set(selection_data,GDK_SELECTION_TYPE_STRING, 8, (guchar*)mlist, mlen); free(mlist); update_ctx_when_idle(text); free(tpnt); } else { update_ctx_when_idle(text); } jrb_free_tree(strs); g_free(sel); } } void log_text(GtkWidget *text, gpointer font, char *str) { (void)font; gtk_text_buffer_insert_with_tags (gtk_text_view_get_buffer(GTK_TEXT_VIEW (text)), &iterx, str, -1, mono_tag, size_tag, NULL); } void log_text_bold(GtkWidget *text, gpointer font, char *str) { (void)font; gtk_text_buffer_insert_with_tags (gtk_text_view_get_buffer(GTK_TEXT_VIEW (text)), &iterx, str, -1, bold_tag, mono_tag, size_tag, fwht_tag, blue_tag, NULL); } void log_text_active(GtkWidget *text, gpointer font, char *str) { (void)font; gtk_text_buffer_insert_with_tags (gtk_text_view_get_buffer(GTK_TEXT_VIEW (text)), &iterx, str, -1, dgray_tag, mono_tag, size_tag, NULL); } void log_text_prelight(GtkWidget *text, gpointer font, char *str) { (void)font; gtk_text_buffer_insert_with_tags (gtk_text_view_get_buffer(GTK_TEXT_VIEW (text)), &iterx, str, -1, lgray_tag, mono_tag, size_tag, NULL); } static void log_realize_text (GtkWidget *text, gpointer data) { (void)text; (void)data; /* nothing for now */ } /* lxt2 iteration handling... (lxt2 doesn't have a direct "value at" function) */ static JRB lx2vals = NULL; static void lx2_iter_fn(struct lxt2_rd_trace **lt, lxtint64_t *pnt_time, lxtint32_t *pnt_facidx, char **pnt_value) { (void)lt; if(*pnt_time <= (lxtint64_t)anno_ctx->marker) { JRB node = jrb_find_int(lx2vals, *pnt_facidx); Jval jv; if(node) { free(node->val.s); node->val.s = strdup(*pnt_value); } else { jv.s = strdup(*pnt_value); jrb_insert_int(lx2vals, *pnt_facidx, jv); } } } static void import_doubleclick(GtkWidget *text, char *s) { struct text_find_t *t = text_root; char *s2; ds_Tree *ft = flattened_mod_list_root; while(t) { if(text == t->text) { break; } t = t->next; } if(!t) return; s2 = malloc(strlen(t->ctx->which->fullname) + 1 + strlen(s) + 1); sprintf(s2, "%s.%s", t->ctx->which->fullname, s); while(ft) { if(!strcmp(s2, ft->fullname)) { bwlogbox(ft->fullname, 640 + 8*8, ft, 0); break; } ft = ft->next_flat; } free(s2); } static gboolean button_release_event (GtkWidget *text, GdkEventButton *event) { (void)event; gchar *sel; GtkTextIter start; GtkTextIter end; if (gtk_text_buffer_get_selection_bounds (gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), &start, &end)) { if(gtk_text_iter_compare (&start, &end) < 0) { sel = gtk_text_buffer_get_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), &start, &end, FALSE); if(sel) { if(strlen(sel)) { int i, len = strlen(sel); char *sel2; char ch; for(i=0;iset_selection(oe, lft, rgh); */ import_doubleclick(text, sel2); g_free(sel2); } bail: g_free(sel); } } } return(FALSE); /* call remaining handlers... */ } static gint scroll_event( GtkWidget * widget, GdkEventScroll * event, gpointer text) { (void)widget; GtkTextView *text_view = GTK_TEXT_VIEW(text); /* GtkAdjustment *hadj = text_view->hadjustment; */ GtkAdjustment *vadj = YYY_gtk_text_view_get_vadjustment(YYY_GTK_TEXT_VIEW(text_view)); gdouble s_val = gtk_adjustment_get_step_increment(vadj); gdouble p_val = gtk_adjustment_get_page_increment(vadj); switch ( event->direction ) { case GDK_SCROLL_UP: gtk_adjustment_set_value(vadj, gtk_adjustment_get_value(vadj) - s_val); if(gtk_adjustment_get_value(vadj) < gtk_adjustment_get_lower(vadj)) gtk_adjustment_set_value(vadj, gtk_adjustment_get_lower(vadj)); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(vadj)), "changed"); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(vadj)), "value_changed"); break; case GDK_SCROLL_DOWN: gtk_adjustment_set_value(vadj, gtk_adjustment_get_value(vadj) + s_val); if(gtk_adjustment_get_value(vadj) > gtk_adjustment_get_upper(vadj) - p_val) gtk_adjustment_set_value(vadj, gtk_adjustment_get_upper(vadj) - p_val); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(vadj)), "changed"); g_signal_emit_by_name (XXX_GTK_OBJECT (GTK_ADJUSTMENT(vadj)), "value_changed"); default: break; } return(TRUE); } /* Create a scrolled text area that displays a "message" */ static GtkWidget *create_log_text (GtkWidget **textpnt) { GtkWidget *text; GtkWidget *scrolled_window; text = gtk_text_view_new (); gtk_text_buffer_get_start_iter (gtk_text_view_get_buffer(GTK_TEXT_VIEW (text)), &iterx); bold_tag = gtk_text_buffer_create_tag (gtk_text_view_get_buffer(GTK_TEXT_VIEW (text)), "bold", "weight", PANGO_WEIGHT_BOLD, NULL); dgray_tag = gtk_text_buffer_create_tag (gtk_text_view_get_buffer(GTK_TEXT_VIEW (text)), "dk_gray_background", "background", "dark gray", NULL); lgray_tag = gtk_text_buffer_create_tag (gtk_text_view_get_buffer(GTK_TEXT_VIEW (text)), "lt_gray_background", "background", "light gray", NULL); fwht_tag = gtk_text_buffer_create_tag (gtk_text_view_get_buffer(GTK_TEXT_VIEW (text)), "white_foreground", "foreground", "white", NULL); blue_tag = gtk_text_buffer_create_tag (gtk_text_view_get_buffer(GTK_TEXT_VIEW (text)), "blue_background", "background", "blue", NULL); #ifdef MAC_INTEGRATION mono_tag = gtk_text_buffer_create_tag (gtk_text_view_get_buffer(GTK_TEXT_VIEW (text)), "monospace", "family", "monospace", NULL); size_tag = gtk_text_buffer_create_tag (gtk_text_view_get_buffer(GTK_TEXT_VIEW (text)), "fsiz", "size", 10 * PANGO_SCALE, NULL); #else mono_tag = gtk_text_buffer_create_tag (gtk_text_view_get_buffer(GTK_TEXT_VIEW (text)), "monospace", "family", "monospace", NULL); size_tag = gtk_text_buffer_create_tag (gtk_text_view_get_buffer(GTK_TEXT_VIEW (text)), "fsiz", "size", 8 * PANGO_SCALE, NULL); #endif *textpnt = text; gtk_widget_set_size_request(GTK_WIDGET(text), 100, 100); gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE); gtk_widget_show (text); scrolled_window = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_container_add (GTK_CONTAINER (scrolled_window), text); gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 5); gtk_widget_show(scrolled_window); /* Add a handler to put a message in the text widget when it is realized */ g_signal_connect (XXX_GTK_OBJECT (text), "realize", G_CALLBACK (log_realize_text), NULL); g_signal_connect(XXX_GTK_OBJECT(text), "button_release_event", G_CALLBACK(button_release_event), NULL); g_signal_connect (XXX_GTK_OBJECT (text), "scroll_event",G_CALLBACK(scroll_event), text); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text), GTK_WRAP_CHAR); return(scrolled_window); } /***********************************************************************************/ static void ok_callback(GtkWidget *widget, struct logfile_context_t *ctx) { (void)widget; bwlogbox(ctx->which->fullname, ctx->width, ctx->which, (ctx->display_mode == 0)); } gboolean update_ctx_when_idle(gpointer textview_or_dummy) { struct text_find_t *t; if((anno_ctx) && (anno_ctx->cygwin_remote_kill)) { anno_ctx->cygwin_remote_kill = 0; exit(0); /* remote kill command from gtkwave */ } if(textview_or_dummy == NULL) { if(anno_ctx) { if((anno_ctx->marker_set != old_marker_set) || (old_marker != anno_ctx->marker)) { old_marker_set = anno_ctx->marker_set; old_marker = anno_ctx->marker; } else { return(TRUE); } } else { return(TRUE); } } t = text_root; while(t) { if(textview_or_dummy) { if(textview_or_dummy != (gpointer)(t->text)) { t = t->next; continue; } } if(t->window) { if((!t->ctx->display_mode) || (textview_or_dummy)) { GtkTextIter st_iter, en_iter; GtkAdjustment *vadj = YYY_gtk_text_view_get_vadjustment(YYY_GTK_TEXT_VIEW (t->text)); gdouble vvalue = gtk_adjustment_get_value(vadj); read_insert_position(t); gtk_text_buffer_get_start_iter(gtk_text_view_get_buffer(GTK_TEXT_VIEW (t->text)), &st_iter); gtk_text_buffer_get_end_iter(gtk_text_view_get_buffer(GTK_TEXT_VIEW (t->text)), &en_iter); gtk_text_buffer_delete(gtk_text_view_get_buffer(GTK_TEXT_VIEW (t->text)), &st_iter, &en_iter); gtk_text_buffer_get_start_iter (gtk_text_view_get_buffer(GTK_TEXT_VIEW (t->text)), &iterx); bold_tag = t->bold_tag; dgray_tag = t->dgray_tag; lgray_tag = t->lgray_tag; blue_tag = t->blue_tag; fwht_tag = t->fwht_tag; mono_tag = t->mono_tag; size_tag = t->size_tag; bwlogbox_2(t->ctx, NULL, t->button, t->text); set_insert_position(t); gtk_adjustment_set_value(vadj, vvalue); g_signal_emit_by_name (XXX_GTK_OBJECT (vadj), "changed"); g_signal_emit_by_name (XXX_GTK_OBJECT (vadj), "value_changed"); } } t = t->next; } return(TRUE); } static void destroy_callback(GtkWidget *widget, gpointer dummy) { (void)dummy; struct text_find_t *t = text_root, *tprev = NULL; struct logfile_context_t *ctx = NULL; int which = (notebook != NULL); GtkWidget *matched = NULL; while(t) { if((which ? t->button : t->window)==widget) { matched = t->window; if(t==selected_text_via_tab) selected_text_via_tab = NULL; if(tprev) /* prune out struct text_find_t */ { tprev->next = t->next; ctx = t->ctx; free(t); break; } else { text_root = t->next; ctx = t->ctx; free(t); break; } } tprev = t; t = t->next; } if(matched) gtk_widget_destroy(matched); if(ctx) { JRB node; JRB varnames = ctx->varnames; if(ctx->title) free(ctx->title); /* Avoid dereferencing null pointers. */ if (varnames == NULL) return; /* free up variables list */ jrb_traverse(node, varnames) { if(node->val2.v) free(node->val2.v); free(node->key.s); } jrb_traverse(node, varnames) { struct jrb_chain *jvc = node->jval_chain; while(jvc) { struct jrb_chain *jvcn = jvc->next; free(jvc); jvc = jvcn; } } jrb_free_tree(varnames); free(ctx); } } static gint destroy_via_closebutton_release(GtkWidget *widget, GdkEventButton *event) { GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); if((event->x<0)||(event->x>=allocation.width)||(event->y<0)||(event->y>=allocation.height)) { /* let gtk take focus from us with focus out event */ } else { destroy_callback(widget, NULL); } return(TRUE); } void bwlogbox(char *title, int width, ds_Tree *t, int display_mode) { GtkWidget *window; GtkWidget *vbox; GtkWidget *hbox, *button1; GtkWidget *label, *separator; GtkWidget *ctext; GtkWidget *text; GtkWidget *close_button = NULL; gint pagenum = 0; FILE *handle; struct logfile_context_t *ctx; char *default_text = t->filename; handle = fopen(default_text, "rb"); if(!handle) { if(strcmp(default_text, "(VerilatorTop)")) { fprintf(stderr, "Could not open sourcefile '%s'\n", default_text); } return; } fclose(handle); /* nothing */ /* create a new nonmodal window */ if(!notebook) { window = gtk_window_new(GTK_WINDOW_TOPLEVEL); if(fontname_logfile) { set_winsize(window, width*1.8, 640); } else { set_winsize(window, width, 640); } gtk_window_set_title(GTK_WINDOW (window), title); } else { GtkWidget *tbox; GtkWidget *l1; GtkWidget *image; #if !GTK_CHECK_VERSION(3,0,0) GtkRcStyle *rcstyle; #endif #if GTK_CHECK_VERSION(3,0,0) window = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL); tbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_set_homogeneous (GTK_BOX(tbox), FALSE); #else window = gtk_hpaned_new(); tbox = gtk_hbox_new(FALSE, 0); #endif l1 = gtk_label_new(title); /* code from gedit... */ /* setup close button */ close_button = gtk_button_new (); gtk_button_set_relief (GTK_BUTTON (close_button), GTK_RELIEF_NONE); /* don't allow focus on the close button */ #if GTK_CHECK_VERSION(3,0,0) gtk_widget_set_focus_on_click (GTK_WIDGET (close_button), FALSE); #else gtk_button_set_focus_on_click (GTK_BUTTON (close_button), FALSE); #endif /* make it as small as possible */ #if !GTK_CHECK_VERSION(3,0,0) rcstyle = gtk_rc_style_new (); rcstyle->xthickness = rcstyle->ythickness = 0; gtk_widget_modify_style (close_button, rcstyle); g_object_unref(rcstyle); /* was gtk_rc_style_unref (rcstyle) */ #endif #if GTK_CHECK_VERSION(3,0,0) image = gtk_image_new_from_icon_name (XXX_GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU); #else image = gtk_image_new_from_stock (XXX_GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU); #endif gtk_container_add (GTK_CONTAINER (close_button), image); /* ...code from gedit */ gtk_widget_show(image); gtk_widget_show(close_button); gtk_box_pack_start(GTK_BOX (tbox), l1, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX (tbox), close_button, FALSE, FALSE, 0); gtk_widget_show(l1); gtk_widget_show(tbox); pagenum = gtk_notebook_append_page_menu (GTK_NOTEBOOK(notebook), window, tbox, gtk_label_new(title)); g_signal_connect (XXX_GTK_OBJECT (close_button), "button_release_event", G_CALLBACK (destroy_via_closebutton_release), NULL); /* this will destroy the tab by destroying the parent container */ } #if GTK_CHECK_VERSION(3,0,0) vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 1); gtk_box_set_homogeneous (GTK_BOX(vbox), FALSE); #else vbox = gtk_vbox_new (FALSE, 1); #endif 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); #if GTK_CHECK_VERSION(3,0,0) separator = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL); #else separator = gtk_hseparator_new (); #endif 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); g_signal_connect(XXX_GTK_OBJECT(text), "button_press_event",G_CALLBACK(button_press_event), NULL); #if GTK_CHECK_VERSION(3,0,0) separator = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL); #else separator = gtk_hseparator_new (); #endif gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, TRUE, 0); gtk_widget_show (separator); #if GTK_CHECK_VERSION(3,0,0) hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 1); gtk_box_set_homogeneous (GTK_BOX(hbox), FALSE); #else hbox = gtk_hbox_new (FALSE, 1); #endif gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_widget_show (hbox); ctx = (struct logfile_context_t *)calloc(1, sizeof(struct logfile_context_t)); ctx->which = t; ctx->display_mode = display_mode; ctx->width = width; ctx->title = strdup(title); #if GTK_CHECK_VERSION(3,0,0) g_signal_connect(XXX_GTK_OBJECT(window), "draw", G_CALLBACK(draw_event), NULL); #else g_signal_connect(XXX_GTK_OBJECT(window), "expose_event",G_CALLBACK(expose_event_local), NULL); #endif button1 = gtk_button_new_with_label (display_mode ? "View Design Unit Only": "View Full File"); gtk_widget_set_size_request(button1, 100, -1); g_signal_connect(XXX_GTK_OBJECT (button1), "clicked", G_CALLBACK(ok_callback), ctx); gtk_widget_show (button1); #if GTK_CHECK_VERSION(3,0,0) gtk_box_pack_start(GTK_BOX(hbox), button1, TRUE, TRUE, 0); #else gtk_container_add (GTK_CONTAINER (hbox), button1); #endif gtk_widget_set_can_default (button1, TRUE); g_signal_connect_swapped (XXX_GTK_OBJECT (button1), "realize", (GCallback) gtk_widget_grab_default, XXX_GTK_OBJECT (button1)); gtk_widget_show(window); bwlogbox_2(ctx, window, close_button, text); if(text) { GtkWidget *src = text; GtkTargetEntry target_entry[3]; /* 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; gtk_drag_source_set( src, GDK_BUTTON2_MASK, target_entry, sizeof(target_entry) / sizeof(GtkTargetEntry), GDK_ACTION_COPY | GDK_ACTION_MOVE ); g_signal_connect(XXX_GTK_OBJECT(src), "drag_begin", G_CALLBACK(DNDBeginCB), ctx); g_signal_connect(XXX_GTK_OBJECT(src), "drag_end", G_CALLBACK(DNDEndCB), ctx); g_signal_connect(XXX_GTK_OBJECT(src), "drag_data_get", G_CALLBACK(DNDDataRequestCB), ctx); g_signal_connect(XXX_GTK_OBJECT(src), "drag_data_delete", G_CALLBACK(DNDDataDeleteCB), ctx); } if(notebook) { gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), pagenum); } } void bwlogbox_2(struct logfile_context_t *ctx, GtkWidget *window, GtkWidget *button, GtkWidget *text) { ds_Tree *t = ctx->which; int display_mode = ctx->display_mode; char *title = ctx->title; FILE *handle; int lx; int lx_module_line = 0; int lx_module_line_locked = 0; int lx_endmodule_line_locked = 0; struct wave_logfile_lines_t *wlog_head=NULL, *wlog_curr=NULL; int wlog_size = 0; int line_no; int s_line_find = -1, e_line_find = -1; struct text_find_t *text_curr; char *default_text = t->filename; char *design_unit = t->item; int s_line = t->s_line; int e_line = t->e_line; handle = fopen(default_text, "rb"); if(!handle) { if(strcmp(default_text, "(VerilatorTop)")) { fprintf(stderr, "Could not open sourcefile '%s'\n", default_text); } return; } fclose(handle); v_preproc_name = default_text; while((lx = yylex())) { char *pnt = yytext; struct wave_logfile_lines_t *w; line_no = my_yylineno; if(!verilog_2005) { if(lx == V_KW_2005) lx = V_ID; } if(!lx_module_line_locked) { if(lx==V_MODULE) { lx_module_line = line_no; } else if((lx==V_ID)&&(lx_module_line)) { if(!strcmp(pnt, design_unit)) { lx_module_line_locked = 1; s_line_find = lx_module_line; } } else if((lx != V_WS)&&(lx_module_line)) { lx_module_line = 0; } } else { if((lx==V_ENDMODULE)&&(!lx_endmodule_line_locked)) { e_line_find = line_no; lx_endmodule_line_locked = 1; } } w = calloc(1, sizeof(struct wave_logfile_lines_t)); w->line_no = line_no; w->tok = lx; wlog_size += yyleng; w->text = malloc(yyleng + 1); strcpy(w->text, pnt); if(!wlog_curr) { wlog_head = wlog_curr = w; } else { wlog_curr->next = w; wlog_curr = w; } } log_text(text, NULL, "Design unit "); log_text_bold(text, NULL, design_unit); { char buf[8192]; s_line = s_line_find > 0 ? s_line_find : s_line; e_line = e_line_find > 0 ? e_line_find : e_line; sprintf(buf, " occupies lines %d - %d.\n", s_line, e_line); log_text(text, NULL, buf); if(anno_ctx) { sprintf(buf, "Marker time for '%s' is %s.\n", anno_ctx->aet_name, anno_ctx->marker_set ? anno_ctx->time_string: "not set"); log_text(text, NULL, buf); } log_text(text, NULL, "\n"); } if(wlog_curr) { struct wave_logfile_lines_t *w = wlog_head; struct wave_logfile_lines_t *wt; char *pnt = malloc(wlog_size + 1); char *pnt2 = pnt; JRB varnames = NULL; JRB node; int numvars = 0; /* build up list of potential variables in this module */ if(!display_mode && !ctx->varnames) { varnames = make_jrb(); while(w) { if(w->tok == V_ID) { if((w->line_no >= s_line) && (w->line_no <= e_line)) { if(strcmp(w->text, design_unit)) /* filter out design unit name */ { node = jrb_find_str(varnames, w->text); if(!node) { Jval dummy; dummy.v = NULL; jrb_insert_str(varnames, strdup(w->text), dummy); numvars++; } } } } w = w->next; } } if((anno_ctx)&&(anno_ctx->marker_set)&&(!display_mode)) /* !display_mode somehow was removed earlier causing full view crashes */ { int resolved = 0; /*************************/ if(fst) { int numfacs=fstReaderGetVarCount(fst); int i; const char *scp_nam = NULL; fstHandle fh = 0; int new_scope_encountered = 1; int good_scope = 0; if(ctx->varnames) goto skip_resolved_fst; jrb_traverse(node, varnames) { node->val.i = -1; } fstReaderIterateHierRewind(fst); fstReaderResetScope(fst); for(i=0;ihtyp) { case FST_HT_SCOPE: scp_nam = fstReaderPushScope(fst, h->u.scope.name, NULL); new_scope_encountered = 1; break; case FST_HT_UPSCOPE: scp_nam = fstReaderPopScope(fst); new_scope_encountered = 1; break; case FST_HT_VAR: scp_nam = fstReaderGetCurrentFlatScope(fst); if(!h->u.var.is_alias) fh++; do_brk = 1; break; default: break; } if(do_brk) break; } if(!h) break; if(!new_scope_encountered) { if(!good_scope) { continue; } } else { good_scope = !strcmp(scp_nam, title); } if(!good_scope) { if(resolved == numvars) { break; } } else { jrb_traverse(node, varnames) { if(node->val.i < 0) { if(!fst_alpha_strcmpeq(h->u.var.name, node->key.s)) { resolved++; if(h->u.var.is_alias) { node->val.i = h->u.var.handle; } else { node->val.i = fh; } } } else /* bitblasted */ { if(!fst_alpha_strcmpeq(h->u.var.name, node->key.s)) { struct jrb_chain *jvc = node->jval_chain; if(jvc) { while(jvc->next) jvc = jvc->next; jvc->next = calloc(1, sizeof(struct jrb_chain)); jvc = jvc->next; } else { jvc = calloc(1, sizeof(struct jrb_chain)); node->jval_chain = jvc; } if(h->u.var.is_alias) { jvc->val.i = h->u.var.is_alias; } else { jvc->val.i = fh; } } } } } } /* resolved_fst: */ ctx->varnames = varnames; ctx->resolved = resolved; skip_resolved_fst: varnames = ctx->varnames; resolved = ctx->resolved; jrb_traverse(node, varnames) { if(node->val.i >= 0) { char rcb[65537]; char *rc; struct jrb_chain *jvc = node->jval_chain; char first_char; rc = fstReaderGetValueFromHandleAtTime(fst, anno_ctx->marker, node->val.i, rcb); first_char = rc ? rc[0] : '?'; if(!jvc) { if(rc) { node->val2.v = hexify(strdup(rc)); } else { node->val2.v = NULL; } } else { char *rc2; int len = rc ? strlen(rc) : 0; int iter = 1; while(jvc) { fstReaderGetValueFromHandleAtTime(fst, anno_ctx->marker, jvc->val.i, rc); len+= (rc ? strlen(rc) : 0); /* scan-build : possible null pointer */ iter++; jvc = jvc->next; } if(iter==len) { int pos = 1; jvc = node->jval_chain; rc2 = calloc(1, len+1); rc2[0] = first_char; while(jvc) { char rcv[65537]; fstReaderGetValueFromHandleAtTime(fst, anno_ctx->marker, jvc->val.i, rcv); rc2[pos++] = *rcv; jvc = jvc->next; } node->val2.v = hexify(strdup(rc2)); free(rc2); } else { node->val2.v = NULL; } } } else { node->val2.v = NULL; } } } /*************************/ else if(vzt) { int numfacs=vzt_rd_get_num_facs(vzt); int i; int tlen; char *pfx = NULL; if(ctx->varnames) goto skip_resolved_vzt; pfx = malloc((tlen=strlen(title))+1+1); strcpy(pfx, title); strcat(pfx+tlen, "."); tlen++; jrb_traverse(node, varnames) { node->val.i = -1; } for(i=0;ival.i < 0) { if(!strcmp(fnam+tlen, node->key.s)) { mat = 1; if(vzt->flags[i] & VZT_RD_SYM_F_ALIAS) { node->val.i = vzt_rd_get_alias_root(vzt, i); } else { node->val.i = i; } } } else /* bitblasted */ { if(!strcmp(fnam+tlen, node->key.s)) { struct jrb_chain *jvc = node->jval_chain; mat = 1; if(jvc) { while(jvc->next) jvc = jvc->next; jvc->next = calloc(1, sizeof(struct jrb_chain)); jvc = jvc->next; } else { jvc = calloc(1, sizeof(struct jrb_chain)); node->jval_chain = jvc; } if(vzt->flags[i] & VZT_RD_SYM_F_ALIAS) { jvc->val.i = vzt_rd_get_alias_root(vzt, i); } else { jvc->val.i = i; } } } if(mat) { if(i==(numfacs-1)) { resolved++; } else { char *fnam2 = vzt_rd_get_facname(vzt, i+1); if(strcmp(fnam, fnam2)) { resolved++; if(resolved == numvars) goto resolved_vzt; } } } } } } } resolved_vzt: free(pfx); ctx->varnames = varnames; ctx->resolved = resolved; skip_resolved_vzt: varnames = ctx->varnames; resolved = ctx->resolved; jrb_traverse(node, varnames) { if(node->val.i >= 0) { char *rc = vzt_rd_value(vzt, anno_ctx->marker, node->val.i); struct jrb_chain *jvc = node->jval_chain; char first_char = rc ? rc[0] : '?'; if(!jvc) { if(rc) { node->val2.v = hexify(strdup(rc)); } else { node->val2.v = NULL; } } else { char *rc2; int len = rc ? strlen(rc) : 0; int iter = 1; while(jvc) { rc = vzt_rd_value(vzt, anno_ctx->marker, jvc->val.i); len+=(rc ? strlen(rc) : 0); iter++; jvc = jvc->next; } if(iter==len) { int pos = 1; jvc = node->jval_chain; rc2 = calloc(1, len+1); rc2[0] = first_char; while(jvc) { char *rcv = vzt_rd_value(vzt, anno_ctx->marker, jvc->val.i); rc2[pos++] = *rcv; jvc = jvc->next; } node->val2.v = hexify(strdup(rc2)); free(rc2); } else { node->val2.v = NULL; } } } else { node->val2.v = NULL; } } } /******/ else if(lx2) { int numfacs=lxt2_rd_get_num_facs(lx2); int i; int tlen; char *pfx = NULL; if(ctx->varnames) goto skip_resolved_lxt2; pfx = malloc((tlen=strlen(title))+1+1); strcpy(pfx, title); strcat(pfx+tlen, "."); tlen++; lxt2_rd_clr_fac_process_mask_all(lx2); jrb_traverse(node, varnames) { node->val.i = -1; } for(i=0;ival.i < 0) { if(!strcmp(fnam+tlen, node->key.s)) { mat = 1; if(lx2->flags[i] & LXT2_RD_SYM_F_ALIAS) { node->val.i = lxt2_rd_get_alias_root(lx2, i); } else { node->val.i = i; } lxt2_rd_set_fac_process_mask(lx2, node->val.i); } } else /* bitblasted */ { if(!strcmp(fnam+tlen, node->key.s)) { struct jrb_chain *jvc = node->jval_chain; mat = 1; if(jvc) { while(jvc->next) jvc = jvc->next; jvc->next = calloc(1, sizeof(struct jrb_chain)); jvc = jvc->next; } else { jvc = calloc(1, sizeof(struct jrb_chain)); node->jval_chain = jvc; } if(lx2->flags[i] & LXT2_RD_SYM_F_ALIAS) { jvc->val.i = lxt2_rd_get_alias_root(lx2, i); } else { jvc->val.i = i; } lxt2_rd_set_fac_process_mask(lx2, jvc->val.i); } } if(mat) { if(i==(numfacs-1)) { resolved++; } else { char *fnam2 = lxt2_rd_get_facname(lx2, i+1); if(strcmp(fnam, fnam2)) { resolved++; if(resolved == numvars) goto resolved_lxt2; } } } } } } } resolved_lxt2: free(pfx); ctx->varnames = varnames; ctx->resolved = resolved; skip_resolved_lxt2: varnames = ctx->varnames; resolved = ctx->resolved; lx2vals = make_jrb(); lxt2_rd_unlimit_time_range(lx2); lxt2_rd_limit_time_range(lx2, anno_ctx->marker, anno_ctx->marker); lxt2_rd_iter_blocks(lx2, lx2_iter_fn, NULL); jrb_traverse(node, varnames) { struct jrb_chain *jvc = node->jval_chain; if(node->val.i >= 0) { JRB srch = jrb_find_int(lx2vals, node->val.i); char *rc = srch ? srch->val.s : NULL; char first_char = rc ? rc[0] : '?'; if(!jvc) { if(rc) { node->val2.v = hexify(strdup(rc)); } else { node->val2.v = NULL; } } else { char *rc2; int len = rc ? strlen(rc) : 0; int iter = 1; while(jvc) { srch = jrb_find_int(lx2vals, jvc->val.i); rc = srch ? srch->val.s : NULL; len+=(rc ? strlen(rc) : 0); iter++; jvc = jvc->next; } if(iter==len) { int pos = 1; jvc = node->jval_chain; rc2 = calloc(1, len+1); rc2[0] = first_char; while(jvc) { srch = jrb_find_int(lx2vals, jvc->val.i); rc = srch->val.s; rc2[pos++] = *rc; jvc = jvc->next; } node->val2.v = hexify(strdup(rc2)); free(rc2); } else { node->val2.v = NULL; } } } else { node->val2.v = NULL; } } jrb_traverse(node, lx2vals) { if(node->val.s) free(node->val.s); } jrb_free_tree(lx2vals); lx2vals = NULL; } /******/ #ifdef AET2_IS_PRESENT else if(ae2) { int numfacs=ae2_read_num_symbols(ae2); int i; int tlen; char *pfx = NULL; char *tstr; int attempt = 0; if(ctx->varnames) goto skip_resolved_ae2; pfx = malloc((tlen=strlen(title))+1+1); strcpy(pfx, title); strcat(pfx+tlen, "."); tlen++; jrb_traverse(node, varnames) { node->val.i = -1; } retry_ae2: for(i=0;ival.i < 0) { /* note, ae2 is never bitblasted */ if(!strcmp(fnam+tlen, node->key.s)) { node->val.i = i; resolved++; if(resolved == numvars) goto resolved_ae2; } } } } } } free(pfx); /* prune off one level of hierarchy... */ tstr = strchr(title, '.'); if(tstr) { if((!attempt)&&(!resolved)) { pfx = malloc((tlen=strlen(tstr+1))+1+1); strcpy(pfx, tstr+1); strcat(pfx+tlen, "."); tlen++; attempt++; goto retry_ae2; } else { pfx = malloc(1); /* dummy */ } } else /* try name as top level sig */ { pfx = malloc(1); /* dummy */ if(!resolved) for(i=0;ival.i < 0) { if(!strcmp(fnam, node->key.s)) { node->val.i = i; resolved++; if(resolved == numvars) goto resolved_ae2; } } } } } resolved_ae2: free(pfx); ctx->varnames = varnames; ctx->resolved = resolved; skip_resolved_ae2: varnames = ctx->varnames; resolved = ctx->resolved; jrb_traverse(node, varnames) { if(node->val.i >= 0) { char rc[AE2_MAXFACLEN+1]; AE2_FACREF fr; fr.s = node->val.i; fr.row = 0; fr.row_high = 0; fr.offset = 0; fr.length = ae2_read_symbol_length(ae2, fr.s); ae2_read_value(ae2, &fr, anno_ctx->marker, rc); node->val2.v = rc[0] ? hexify(strdup(rc)) : NULL; } else { node->val2.v = NULL; } } } #endif /******/ if(resolved > 0) { w = wlog_head; while(w) { if((w->line_no >= s_line) && (w->line_no <= e_line)) { if(w->tok == V_ID) { if(strcmp(w->text, design_unit)) /* filter out design unit name */ { node = jrb_find_str(varnames, w->text); if((node)&&(node->val2.v)) { log_text(text, fontx, w->text); log_text_bold(text, fontx, "["); log_text_bold(text, fontx, node->val2.v); log_text_bold(text, fontx, "]"); goto iter_free; } } } switch(w->tok) { case V_CMT: log_text_active(text, fontx, w->text); break; case V_STRING: case V_PREPROC: case V_PREPROC_WS: case V_MACRO: log_text_prelight(text, fontx, w->text); break; default: log_text(text, fontx, w->text); break; } } iter_free: free(w->text); wt = w; w = w->next; free(wt); } free(pnt); /* wlog_head = */ wlog_curr = NULL; goto free_vars; } } w = wlog_head; while(w) { if((display_mode)||((w->line_no >= s_line) && (w->line_no <= e_line))) { int len = strlen(w->text); memcpy(pnt2, w->text, len); pnt2 += len; } free(w->text); wt = w; w = w->next; free(wt); } /* wlog_head = */ wlog_curr = NULL; *pnt2 = 0; log_text(text, fontx, pnt); free(pnt); free_vars: #if 0 /* free up variables list */ if(!display_mode) { jrb_traverse(node, varnames) { if(node->val2.v) free(node->val2.v); free(node->key.s); } } jrb_traverse(node, varnames) { struct jrb_chain *jvc = node->jval_chain; while(jvc) { struct jrb_chain *jvcn = jvc->next; free(jvc); jvc = jvcn; } } jrb_free_tree(varnames); varnames = NULL; #endif /* insert context for destroy */ if(window) { text_curr = (struct text_find_t *)calloc(1, sizeof(struct text_find_t)); text_curr->window = window; text_curr->button = button; text_curr->text = text; text_curr->ctx = ctx; text_curr->next = text_root; text_root = text_curr; text_curr->bold_tag = bold_tag; text_curr->dgray_tag = dgray_tag; text_curr->lgray_tag = lgray_tag; text_curr->blue_tag = blue_tag; text_curr->fwht_tag = fwht_tag; text_curr->mono_tag = mono_tag; text_curr->size_tag = size_tag; } } } gtkwave-gtk3-3.3.125/contrib/rtlbrowse/tcl_helper.c0000664000175000017500000005576215047725113021505 0ustar bybellbybell/* * Copyright (c) Tony Bybell and Concept Engineering GmbH 2008-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 #include #include #include #include #include "splay.h" #include "wavelink.h" #if !defined __MINGW32__ #include #include #endif extern ds_Tree *flattened_mod_list_root; void bwlogbox(char *title, int width, ds_Tree *t, int display_mode); /*---------------------------------------------------------------------- * 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(). * * *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(i); for (i = 0, p = (char*) (argv+size); *list != 0; i++) { ok = tclFindElement(list, &element, &list, &elSize, &brace); if (!ok) { free(argv); return NULL; } if (*element == 0) break; if (i >= size) { free(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(argc*sizeof(int)); numChars = 1; for (i=0; itargets; * * 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)) { int impcnt = 0; ds_Tree *ft = NULL; int argc = 0; char**zs = zSplitTclList((const char *)gtk_selection_data_get_data(selection_data), &argc); if(zs) { int i; for(i=0;ifullname)) { if(!ft->dnd_to_import) { ft->dnd_to_import = 1; impcnt++; } break; } ft = ft->next_flat; } free(stemp); } } free(zs); } if(impcnt) { ds_Tree **fta = calloc(impcnt, sizeof(ds_Tree *)); int i = 0; while(ft) { if(ft->dnd_to_import) { ft->dnd_to_import = 0; fta[i++] = ft; if(i == impcnt) break; } ft = ft->next_flat; } for(i=impcnt-1;i>=0;i--) /* reverse list so it is forwards in rtlbrowse */ { if(fta[i]) /* scan-build */ { bwlogbox(fta[i]->fullname, 640 + 8*8, fta[i], 0); } } free(fta); } } } void setup_dnd(GtkWidget *wid) { 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(wid), GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP, target_entry, sizeof(target_entry) / sizeof(GtkTargetEntry), GDK_ACTION_COPY ); g_signal_connect(XXX_GTK_OBJECT(wid), "drag_data_received", G_CALLBACK(DNDDataReceivedCB), GTK_WIDGET(wid)); g_signal_connect(XXX_GTK_OBJECT(wid), "drag_motion", G_CALLBACK(DNDDragMotionCB), GTK_WIDGET(wid)); g_signal_connect(XXX_GTK_OBJECT(wid), "drag_begin", G_CALLBACK(DNDBeginCB), GTK_WIDGET(wid)); g_signal_connect(XXX_GTK_OBJECT(wid), "drag_end", G_CALLBACK(DNDEndCB), GTK_WIDGET(wid)); } gtkwave-gtk3-3.3.125/contrib/rtlbrowse/jrb.h0000664000175000017500000000647215047725113020140 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; struct jrb_chain *jval_chain; /* added for rtlbrowse */ Jval key; Jval val; Jval val2; /* added for rtlbrowse */ } *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, 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, 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-gtk3-3.3.125/contrib/rtlbrowse/vlex.h0000664000175000017500000000117115047725113020330 0ustar bybellbybell#ifndef VLEX_DEFINES_H #define VLEX_DEFINES_H #include #define V_IGNORE (1) #define V_ID (2) #define V_PORT (3) #define V_MODULE (4) #define V_ENDMODULE (5) #define V_STRING (6) #define V_WS (7) #define V_MACRO (8) #define V_CMT (9) #define V_NUMBER (10) #define V_FUNC (11) #define V_PREPROC (12) #define V_PREPROC_WS (13) #define V_KW (14) #define V_KW_2005 (15) extern int my_yylineno; extern char *v_preproc_name; int yylex(void); extern char *yytext; typedef size_t gtkwave_yy_size_t; extern gtkwave_yy_size_t yyleng; const char *is_builtin_define (register const char *str, register unsigned int len); #endif gtkwave-gtk3-3.3.125/contrib/wlf2vcd/0000775000175000017500000000000015047725113016525 5ustar bybellbybellgtkwave-gtk3-3.3.125/contrib/wlf2vcd/Makefile.in0000664000175000017500000003120715047725113020575 0ustar bybellbybell# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = contrib/wlf2vcd DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am 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__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@ GLIB_COMPILE_SCHEMAS = @GLIB_COMPILE_SCHEMAS@ GPERF = @GPERF@ GREP = @GREP@ GSETTINGS_CFLAGS = @GSETTINGS_CFLAGS@ GSETTINGS_DISABLE_SCHEMAS_COMPILE = @GSETTINGS_DISABLE_SCHEMAS_COMPILE@ GTK_CFLAGS = @GTK_CFLAGS@ 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_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_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@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POW_LIB = @POW_LIB@ RANLIB = @RANLIB@ RPC_CFLAGS = @RPC_CFLAGS@ RPC_LDADD = @RPC_LDADD@ 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@ TIRPC_CFLAGS = @TIRPC_CFLAGS@ TIRPC_LIBS = @TIRPC_LIBS@ 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@ gsettingsschemadir = @gsettingsschemadir@ 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@ EXTRA_DIST = \ wlf2vcd.c 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 contrib/wlf2vcd/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign contrib/wlf2vcd/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): 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 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 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-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: .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-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 # 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-gtk3-3.3.125/contrib/wlf2vcd/wlf2vcd.c0000664000175000017500000005704615047725113020254 0ustar bybellbybell/* to compile: gcc -O2 -o wlf2vcd wlf2vcd.c -L ./lib -I ./include/ ./lib/libwlf.a ./lib/libtcl8.5.a -lm -lsqlite3 -lz ./lib/libucdb.a Much faster version of wlf2vcd as compared to one bundled with Questa, etc. Requires libs and headers from ModelSim. Some libwlf.a versions don't need libucdb.a. */ #include #include #include #include #include #include /* skips using wlfValueToString() and determines string directly from value representation */ #define BYPASS_USING_VALUE_TO_STRING /* definition of WlfVreg from wlf_api.h */ #define WLF2VCD_MVL4 "01zx" #define WLF2VCD_MVL9 "ux01zwlh-" static const char *wlf_mvl9[9] = {"'U'", "'X'", "'0'", "'1'", "'Z'", "'W'", "'L'", "'H'", "'-'"}; typedef struct WlfGlobalContext { WlfPackId pack; WlfTime64 old_time; char *prev_hier; int prev_hier_len; unsigned int vcdid_added; unsigned int num_scopes; unsigned int num_symbols; unsigned int max_bits; unsigned int num_aliases; unsigned is_vhdl : 1; unsigned char *value_string; int *archive_number; WlfSymbolId *archive_sym; } WlfGlobalContext; WlfGlobalContext wgc; static void AddSymbolToCB( WlfSymbolId sym, unsigned int vcdid, int num_bits, unsigned int is_real, unsigned int is_vbit, unsigned int is_vhbit, unsigned int is_vreg ); /* structure to hold callback data */ typedef struct cbData { #ifdef BYPASS_USING_VALUE_TO_STRING void *pv; #endif WlfValueId val; unsigned int vcdid; unsigned int num_bits; unsigned is_real : 1; unsigned is_vbit : 1; unsigned is_vhbit : 1; unsigned is_vreg : 1; } cbData; char *genVcdID(char *buf, unsigned int value) { char *pnt = buf; unsigned int vmod; /* zero is illegal for a value...it is assumed they start at one */ for(;;) { if((vmod = (value % 94))) { *(pnt++) = (char)(vmod + 32); } else { *(pnt++) = '~'; value -= 94; } value = value / 94; if(!value) { break; } } *pnt = 0; return(buf); } /****************************************************************************** // errorExit // Prints error message to stderr and exits. ******************************************************************************/ static void errorExit(char *funcName) { int errorNum = wlfErrorNum(); fprintf(stderr, "Error: %s - %d - %s\n", funcName, wlfErrorNum(), wlfErrorMsg()); exit(errorNum); } /****************************************************************************** // countSubElements // Recursively enumerates the context tree information ******************************************************************************/ static void countSubElements(WlfSymbolId top) { WlfIterId iter; WlfSymbolId sym; int cnt; WlfDataType vtyp; /* create an iterator to retrieve children of top */ iter = wlfSymChildren64(top, wlfSelAll); if(iter == NULL) return; /* iterate through the children */ while ((sym = wlfIterate(iter)) != NULL) { cnt = wlfSymPropInt(sym, WLF_PROP_SUBELEMENT_COUNT); WlfSymbolSel64 typ = wlfSymPropSymbolSel64(sym, WLF_PROP_SYMBOL_TYPE); if(typ & wlfSelVhdlScopes) { wgc.is_vhdl = 1; } if(typ & (wlfSelVhdlScopes | wlfSelVlogScopes)) { wgc.num_scopes++; } else { WlfTypeId wid = wlfSymPropTypeId(sym, WLF_PROP_TYPE_ID); vtyp = wlfTypePropDataType(wid, WLF_TYPE_TYPE); if(vtyp == wlfTypeRecord) { // fprintf(stderr, "wlfTypeRecord %d\n", cnt); wgc.num_scopes++; } else if(vtyp != wlfTypeArray) /* still possibly have to recurse */ { int rgh = wlfTypePropInt(wid, WLF_TYPE_ARRAY_RIGHT); int lft = wlfTypePropInt(wid, WLF_TYPE_ARRAY_LEFT); int len = wlfTypePropInt(wid, WLF_TYPE_ARRAY_LENGTH); if(vtyp == wlfTypeScalar) { lft = 31; rgh = 0; len = 32; } wgc.num_symbols++; if(len > wgc.max_bits) wgc.max_bits = len; } } /* recurse through the children, but block out bitblasted children (except vhdl) */ if((cnt<=0) || (wgc.is_vhdl)) { countSubElements(sym); } } wlfIteratorDestroy(iter); } /****************************************************************************** // printSubElements // Recursively prints the context tree information starting at the top and // adds elements to the symbol callback iterator. ******************************************************************************/ static void printSubElements(WlfSymbolId top) { WlfIterId iter; WlfSymbolId sym; int cnt; char *name; char vcdid_str[10]; /* create an iterator to retrieve children of top */ iter = wlfSymChildren64(top, wlfSelAll); if(iter == NULL) return; /* iterate through the children */ while ((sym = wlfIterate(iter)) != NULL) { // printf("\n"); // char *lib = wlfSymPropString(sym, WLF_PROP_LIBRARY_NAME); // printf("lib: '%s'\n", lib); // char *sor= wlfSymPropString(sym, WLF_PROP_SOURCE_NAME); // printf("sor: '%s'\n", sor); // char *pri = wlfSymPropString(sym, WLF_PROP_PRIMARY_NAME); // component type // printf("pri: '%s'\n", pri); // char *sec = wlfSymPropString(sym, WLF_PROP_SECONDARY_NAME); // secondary component type? (VHDL?) // printf("sec: '%s'\n", sec); // char *exp= wlfSymPropString(sym, WLF_PROP_EXPRESSION); // printf("exp: '%s'\n", exp); // int ssor = wlfSymPropInt(sym, WLF_PROP_SYMBOL_SOURCE); // printf("sym source: '%d'\n", ssor); // char *apath = wlfSymPropString(sym, WLF_PROP_SYMBOL_ABSOLUTE_PATH); // printf("abs path: '%s'\n", apath); // char *dname = wlfSymPropString(sym, WLF_PROP_SYMBOL_DATASET_NAME); // printf("dataset name: '%s'\n", dname); // char *pat = wlfSymPropString(sym, WLF_PROP_SYMBOL_PATH); // printf("path: '%s'\n", pat); cnt = wlfSymPropInt(sym, WLF_PROP_SUBELEMENT_COUNT); WlfSymbolSel64 typ = wlfSymPropSymbolSel64(sym, WLF_PROP_SYMBOL_TYPE); int this_arch; int arch = this_arch = wlfSymPropInt(sym, WLF_PROP_ARCHIVE_NUMBER); int alias_ok = 0; if(arch < 0) { if(cnt > 0) { WlfIterId iter2 = wlfSymChildren64(sym, wlfSelAll); if(iter2) { WlfSymbolId sym2 = wlfIterate(iter2); if(sym2) { arch = wlfSymPropInt(sym2, WLF_PROP_ARCHIVE_NUMBER); /* NOTE: alias comparisons should really look across ALL bits, not just the first */ } wlfIteratorDestroy(iter2); } } } if(arch >= 0) { WlfSymbolId archive_sym = wgc.archive_sym[arch]; if(archive_sym) { int archive_arch = wlfSymPropInt(archive_sym, WLF_PROP_ARCHIVE_NUMBER); if((this_arch >= 0) && (archive_arch >= 0)) { alias_ok = (this_arch == archive_arch); } else { WlfIterId this_iter = wlfSymChildren64(sym, wlfSelAll); WlfIterId archive_iter = wlfSymChildren64(archive_sym, wlfSelAll); WlfSymbolId this_child; WlfSymbolId archive_child; alias_ok = 1; for(;;) { this_child = wlfIterate(this_iter); archive_child = wlfIterate(archive_iter); if(this_child && archive_child) { int this_child_arch = wlfSymPropInt(this_child, WLF_PROP_ARCHIVE_NUMBER); int archive_child_arch = wlfSymPropInt(archive_child, WLF_PROP_ARCHIVE_NUMBER); if(this_child_arch != archive_child_arch) { alias_ok = 0; break; } } else if(!this_child && !archive_child) { break; } else { alias_ok = 0; break; } } wlfIteratorDestroy(archive_iter); wlfIteratorDestroy(this_iter); } } } unsigned int is_real = 0; unsigned int is_vbit = 0; unsigned int is_vhbit = 0; unsigned int num_bits = 0; unsigned int is_vreg = 0; char *vartype = NULL; char *scopetype = "module"; switch(typ) { /* wlfSelVhdlScopes */ case wlfSelArchitecture: scopetype = "architecture"; break; case wlfSelBlock: scopetype = "block"; break; case wlfSelGenerate: scopetype = "generate"; break; case wlfSelPackage: scopetype = "package"; break; case wlfSelSubprogram: scopetype = "subprogram"; break; case wlfSelForeign: scopetype = "foreign"; break; /* wlfSelVlogScopes */ case wlfSelModule: scopetype = "module"; break; case wlfSelTask: scopetype = "task"; break; /* case wlfSelBlock: (same as VHDL's) */ case wlfSelFunction: scopetype = "function"; break; case wlfSelStatement: scopetype = "statement"; break; case wlfSelSVCovergroup: scopetype = "covergroup"; break; case wlfSelSVCoverpoint: scopetype = "coverpoint"; break; case wlfSelSVCross: scopetype = "cross"; break; case wlfSelSVClass: scopetype = "class"; break; case wlfSelSVParamClass: scopetype = "paramclass"; break; case wlfSelSVInterface: scopetype = "interface"; break; case wlfSelVlPackage: scopetype = "package"; break; case wlfSelVlGenerateBlock: scopetype = "generate"; break; case wlfSelAssertionScope: scopetype = "assertionscope"; break; case wlfSelClockingBlock: scopetype = "clockingblock"; break; case wlfSelVlTypedef: scopetype = "typedef"; break; /* wlfSelVlogVars */ case wlfSelParameter: vartype = "parameter"; is_vbit = 1; break; case wlfSelReg: vartype = "reg"; is_vreg = 1; break; case wlfSelInteger: vartype = "integer"; is_vbit = 1; break; case wlfSelTime: vartype = "time"; is_vbit = 1; break; case wlfSelReal: vartype = "real"; is_real = 1; break; case wlfSelSpecparam: case wlfSelMemory: break; case wlfSelNamedEvent: vartype = "event"; break; /* wlfSelHdlSignals */ case wlfSelSignal: vartype = "wire"; break; break; case wlfSelNet: vartype = "wire"; break; /* wlfSelHdlVars */ case wlfSelVariable: case wlfSelConstant: case wlfSelGeneric: case wlfSelAlias: default: fprintf(stderr, "Type: %d\n", typ); exit(255); break; } WlfModeSel ptyp = wlfSymPropModeSel(sym, WLF_PROP_PORT_TYPE); name = wlfSymPropString(sym, WLF_PROP_SYMBOL_PATH); while(wgc.prev_hier_len && strncmp(name, wgc.prev_hier, wgc.prev_hier_len)) { wgc.prev_hier[wgc.prev_hier_len - 1] = 0; char *pmod = strrchr(wgc.prev_hier, '/'); char *dmod = strrchr(wgc.prev_hier, '.'); if(dmod && (dmod - pmod > 0)) pmod = dmod; *(pmod + 1) = 0; wgc.prev_hier_len = pmod - wgc.prev_hier + 1; printf("$upscope $end\n"); } WlfTypeId wid = wlfSymPropTypeId(sym, WLF_PROP_TYPE_ID); WlfDataType vtyp = wlfTypePropDataType(wid, WLF_TYPE_TYPE); if((typ & (wlfSelVhdlScopes | wlfSelVlogScopes)) || (vtyp == wlfTypeRecord)) { char *ls = strrchr(name, '/'); char *ds = strrchr(name, '.'); if(ds && (ds - ls > 0)) ls = ds; char *sname = ls ? (ls+1) : name; printf("$scope %s %s $end\n", scopetype, sname); if(wgc.prev_hier) { free(wgc.prev_hier); } int hlen = strlen(name); wgc.prev_hier = malloc(hlen + 1 + 1); memcpy(wgc.prev_hier, name, hlen); wgc.prev_hier[hlen] = (vtyp == wlfTypeRecord) ? '.' : '/'; wgc.prev_hier[(wgc.prev_hier_len = hlen + 1)] = 0; } else { if(vtyp != wlfTypeArray) /* still possibly have to recurse, depends on value of cnt below */ { int rgh = wlfTypePropInt(wid, WLF_TYPE_ARRAY_RIGHT); int lft = wlfTypePropInt(wid, WLF_TYPE_ARRAY_LEFT); int len = wlfTypePropInt(wid, WLF_TYPE_ARRAY_LENGTH); if(vtyp == wlfTypeScalar) { lft = 31; rgh = 0; len = 32; is_vbit = 1; is_vhbit = 0; is_real = 0; is_vreg = 0; } if(vtyp == wlfTypeEnum) { char **enumLiterals; int i, count; wlfEnumLiterals(wid, &enumLiterals, &count); if(count == 9) { for(i=0;i<9;i++) { if(strcmp(enumLiterals[i], wlf_mvl9[i])) { break; } } if(i == 9) { is_vhbit = 1; is_vbit = 0; lft = rgh = 0; len = 1; } } } if((is_real) || (vtyp == wlfTypeReal) || (vtyp == wlfTypeVlogReal)) { is_real = 1; len = lft = rgh = 0; vartype = "real"; if(64 > wgc.max_bits) wgc.max_bits = 64; } name = wlfSymPropString(sym, WLF_PROP_SYMBOL_PATH); /* add the symbol to the callback iterator if not an alias */ unsigned int vcdid = 0; if((arch >= 0) && (alias_ok)) { vcdid = wgc.archive_number[arch]; } if(!vcdid) { AddSymbolToCB(sym, ++wgc.vcdid_added, num_bits = len, is_real, is_vbit, is_vhbit, is_vreg); vcdid = wgc.vcdid_added; if(arch >= 0) { wgc.archive_number[arch] = vcdid; wgc.archive_sym[arch] = sym; } } else { if(arch >= 0) { wgc.archive_number[arch] = vcdid; wgc.archive_sym[arch] = sym; } wgc.num_aliases++; } char *rsl = strrchr(name, '.'); if(!rsl) rsl = strrchr(name, '/'); char *lp = strrchr(rsl, '('); char *rp = strrchr(rsl, ')'); char *lp2 = NULL, *rp2 = NULL; if(lp && rp) { *lp = '['; *rp = ']'; lp2 = strrchr(rsl, '('); rp2 = strrchr(rsl, ')'); if(lp2 && rp2) { *lp2 = '['; *rp2 = ']'; } else { lp2 = rp2 = NULL; } } if((lft != rgh) && (!is_vbit) && (!is_real)) { printf("$var %s %d %s %s [%d:%d] $end\n", vartype, len, genVcdID(vcdid_str, vcdid), rsl+1, lft, rgh); } else { if(cnt && (!is_vbit) && (!is_real)) { printf("$var %s %d %s %s [%d] $end\n", vartype, len, genVcdID(vcdid_str, vcdid), rsl+1, lft); } else { printf("$var %s %d %s %s $end\n", vartype, len, genVcdID(vcdid_str, vcdid), rsl+1); } } if(lp && rp) { *lp = '('; *rp = ')'; } if(lp2 && rp2) { *lp2 = '('; *rp2 = ')'; } } } /* recurse through the children, but block out bitblasted children (except vhdl) */ if((cnt<=0) || (wgc.is_vhdl)) { printSubElements(sym); } } /* status = */ wlfIteratorDestroy(iter); } /****************************************************************************** // timeCb // This function is called by the WLF reader when time advances. // Unused in the program. ******************************************************************************/ static WlfCallbackResponse timeCb( void *cbData, WlfTime64 oldTime, int oldDelta) { return(WLF_CONTINUE_SCAN); } /****************************************************************************** // sigCb // This function prints the time, the name of the signal, and its value. // This function is called by the WLF reader as events occur on // registered signals. This function was registered with each signal // in AddSymbolToCB(). ******************************************************************************/ #ifdef BYPASS_USING_VALUE_TO_STRING /* faster version not using wlfValueToString() */ static WlfCallbackResponse sigCb( void *data, WlfCallbackReason reason) { WlfValueId v = ((cbData*) data)->val; WlfTime64 time; int i; char vbuf[16]; if(reason == WLF_ENDLOG) { wlfValueDestroy(v); free(data); /* no longer need cbData struct as we're iterating through the end log */ return(WLF_CONTINUE_SCAN); } wlfPackTime(wgc.pack, &time); if(time != wgc.old_time) { printf("#"LLDSTR"\n", time); wgc.old_time = time; } if(!((cbData*) data)->is_real) { unsigned int nbits = ((cbData*) data)->num_bits; unsigned char *pv = ((cbData*) data)->pv; char *value = wgc.value_string; if(((cbData*) data)->is_vhbit) { for(i=0;iis_vbit) { WlfVbit *ip = (WlfVbit *)pv; int bitrvs = (nbits - 1); for(i=0;i> bit) & 1; // 01 plane value[bitrvs--] = '0' | vl; } value[i] = 0; } else if(((cbData*) data)->is_vreg) { WlfVreg *ip = (WlfVreg *)pv; int bitrvs = (nbits - 1); for(i=0;i> bit) & 1; // 01 plane int vh = (ip[word_l].unk >> bit) & 1; // zx plane value[bitrvs--] = WLF2VCD_MVL4[(vh << 1) | vl]; } value[i] = 0; } else { if(pv) { for(i=0;ivcdid)); } else { putc('b', stdout); fputs(value, stdout); putc(' ', stdout); puts(genVcdID(vbuf, ((cbData*) data)->vcdid)); } } else { double *d = ((cbData*) data)->pv; double dv; if(d) { dv = *d; } else { dv = 0.0; /* probably should be NaN */ } putc('r', stdout); fprintf(stdout, "%lg", dv); putc(' ', stdout); puts(genVcdID(vbuf, ((cbData*) data)->vcdid)); } return(WLF_CONTINUE_SCAN); } #else /* slower version using wlfValueToString() */ static WlfCallbackResponse sigCb( void *data, WlfCallbackReason reason) { WlfValueId v = ((cbData*) data)->val; WlfTime64 time; char *value; char vbuf[16]; if(reason == WLF_ENDLOG) { free(data); /* no longer need cbData struct as we're iterating through the end log */ return(WLF_CONTINUE_SCAN); } wlfPackTime(wgc.pack, &time); if(time != wgc.old_time) { printf("#"LLDSTR"\n", time); wgc.old_time = time; } if(!((cbData*) data)->is_real) { if((value=wlfValueToString(v, WLF_RADIX_BINARY, 0))==NULL) // wgc.max_bits instead of 0 to specify explicitly { /* for events */ value = "1"; } if(((cbData*) data)->num_bits == 1) { putc(tolower(value[0]), stdout); puts(genVcdID(vbuf, ((cbData*) data)->vcdid)); } else { putc('b', stdout); fputs(value, stdout); putc(' ', stdout); puts(genVcdID(vbuf, ((cbData*) data)->vcdid)); } } else { if((value=wlfValueToString(v, WLF_RADIX_SYMBOLIC, 0))==NULL) { value = "0"; } putc('r', stdout); fputs(value, stdout); putc(' ', stdout); puts(genVcdID(vbuf, ((cbData*) data)->vcdid)); } return(WLF_CONTINUE_SCAN); } #endif /****************************************************************************** // AddSymbolToCB // Adds a symbol to the callback iterator ******************************************************************************/ static void AddSymbolToCB( WlfSymbolId sym, unsigned int vcdid, int num_bits, unsigned int is_real, unsigned int is_vbit, unsigned int is_vhbit, unsigned int is_vreg ) { int status; cbData *pdata; if(wlfSymIsSymbolSelect64(sym, wlfSelAllSignals)) { WlfValueId val = wlfValueCreate(sym); pdata = (cbData *) malloc(sizeof(cbData)); pdata->val = val; #ifdef BYPASS_USING_VALUE_TO_STRING pdata->pv = wlfValueGetValue(val); #endif pdata->vcdid = vcdid; pdata->num_bits = (num_bits < 0) ? 0 : num_bits; // ?? how to fix properly pdata->is_real = is_real; pdata->is_vbit = is_vbit; pdata->is_vhbit = is_vhbit; pdata->is_vreg = is_vreg; status = wlfAddSignalEventCB(wgc.pack, sym, val, WLF_REQUEST_POSTPONED, sigCb, pdata); if(status != WLF_OK) { errorExit("AddSymbolToCB"); } } } /****************************************************************************** // main ******************************************************************************/ int main(int argc, char **argv) { int status; int resolution; WlfFileId wlfFile; WlfSymbolId top; WlfValueId val = NULL; WlfFileInfo fileInfo; wgc.old_time = -1ULL; wgc.prev_hier = NULL; wgc.prev_hier_len = 0; wgc.vcdid_added = 0; wgc.is_vhdl = 0; if(argc < 2) { fprintf(stderr,"Usage: %s \n", argv[0]); exit(1); } /* Initialize the WLF api */ status = wlfInit(); if(status != WLF_OK) { errorExit("wlfInit"); } /* Open the WLF File */ wlfFile = wlfFileOpen(argv[1], "vsim_wlf"); if(wlfFile == NULL) { errorExit("wlfFileOpen"); } /* Check the API version */ status = wlfFileInfo(wlfFile, &fileInfo); if(status != WLF_OK) { errorExit("wlfFileInfo"); } fprintf(stderr, "max archive num: %d\n", fileInfo.signalCount); wgc.archive_number = calloc(fileInfo.signalCount + 1, sizeof(int)); wgc.archive_sym = calloc(fileInfo.signalCount + 1, sizeof(WlfSymbolId)); time_t walltime = fileInfo.creationTime; printf("$date\n\t%s\n$end\n", asctime(localtime(&walltime))); printf("$version\n\t%s\n$end\n", fileInfo.productName); /* Get the simulator resolution */ status = wlfFileResolution(wlfFile, &resolution); if(status != WLF_OK) { errorExit("wlfFileResolution"); } /* Retrieve and print out the top level context for this wlf file */ top = wlfFileGetTopContext(wlfFile); if(top == NULL) { errorExit("wlfFileGetTopContext"); } char *tscale = NULL; switch(resolution) { case WLF_TIME_RES_1FS: tscale = "1fs"; break; case WLF_TIME_RES_10FS: tscale = "10fs"; break; case WLF_TIME_RES_100FS:tscale = "100fs"; break; case WLF_TIME_RES_1PS: tscale = "1ps"; break; case WLF_TIME_RES_10PS: tscale = "10ps"; break; case WLF_TIME_RES_100PS:tscale = "100ps"; break; case WLF_TIME_RES_1NS: tscale = "1ns"; break; case WLF_TIME_RES_10NS: tscale = "10ns"; break; case WLF_TIME_RES_100NS:tscale = "100ns"; break; case WLF_TIME_RES_1US: tscale = "1us"; break; case WLF_TIME_RES_10US: tscale = "10us"; break; case WLF_TIME_RES_100US:tscale = "100us"; break; case WLF_TIME_RES_1MS: tscale = "1ms"; break; case WLF_TIME_RES_10MS: tscale = "10ms"; break; case WLF_TIME_RES_100MS:tscale = "100ms"; break; case WLF_TIME_RES_1SEC: tscale = "1s"; break; case WLF_TIME_RES_10SEC:tscale = "10s"; break; case WLF_TIME_RES_100SEC:tscale ="100s"; break; default: tscale = "1ns"; break; } printf("$timescale\n\t%s\n$end\n", tscale); /* Create a callback context */ wgc.pack = wlfPackCreate(); if(wgc.pack == NULL) { errorExit("wlfPackCreate"); } /* gather symbol information */ countSubElements(top); /* print out symbol information */ printSubElements(top); fprintf(stderr, "num_scopes: %d\n", wgc.num_scopes); fprintf(stderr, "num_symbols: %d\n", wgc.num_symbols); fprintf(stderr, "max_bits: %d\n", wgc.max_bits); wgc.value_string = malloc(wgc.max_bits+1); fprintf(stderr, "num_signals %d\n", wgc.num_symbols - wgc.num_aliases); fprintf(stderr, "num_aliases %d\n", wgc.num_aliases); while(wgc.prev_hier_len && strncmp("/", wgc.prev_hier, wgc.prev_hier_len)) { wgc.prev_hier[wgc.prev_hier_len - 1] = 0; char *pmod = strrchr(wgc.prev_hier, '/'); *(pmod + 1) = 0; wgc.prev_hier_len = pmod - wgc.prev_hier + 1; printf("$upscope $end\n"); } printf("$enddefinitions $end\n"); printf("$dumpvars\n"); free(wgc.archive_sym); wgc.archive_sym = NULL; free(wgc.archive_number); wgc.archive_number = NULL; /* Scan the data starting at time 0 through the end of file */ status = wlfReadDataOverRange(wgc.pack, fileInfo.startTime, fileInfo.startDelta, fileInfo.lastTime, fileInfo.lastDelta, NULL, NULL, NULL); if(status != WLF_OK) { errorExit("wlfReadDataOverRange"); } /* free resources */ wlfPackDestroy(wgc.pack); free(wgc.value_string); wgc.value_string = NULL; /* close the file and release resources */ status = wlfFileClose(wlfFile); if(status != WLF_OK) { errorExit("wlfFileClose"); } status = wlfCleanup(); if(status != WLF_OK) { errorExit("wlfCleanup"); } return(status); } gtkwave-gtk3-3.3.125/contrib/wlf2vcd/Makefile.am0000664000175000017500000000005515047725113020561 0ustar bybellbybell## -*- makefile ## EXTRA_DIST= \ wlf2vcd.c gtkwave-gtk3-3.3.125/contrib/json2stems/0000775000175000017500000000000015047725113017265 5ustar bybellbybellgtkwave-gtk3-3.3.125/contrib/json2stems/Makefile.am0000664000175000017500000000020415047725113021315 0ustar bybellbybell## -*- makefile -*- ## bin_PROGRAMS= json2stems AM_CXXFLAGS = -std=c++11 AM_LIBS = json2stems_SOURCES= \ json2stems.cc json.hpp gtkwave-gtk3-3.3.125/contrib/json2stems/json2stems.cc0000664000175000017500000001404715047725113021711 0ustar bybellbybell/* * Copyright (c) 2025 Leon Wandruschka. * * 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 #include #include #include "json.hpp" using json = nlohmann::json; std::map parse_filemap(const json& meta_json); std::string get_file_id(const std::string& loc); std::pair get_line_range(const std::string& loc); void json2stems(std::istream& netlist_in, std::istream& meta_in, std::ostream& out); int main(int argc, char* argv[]) { if (argc < 4) { std::cerr << "Usage: json2stems \n"; return 1; } json j1, j2; try { std::ifstream f1(argv[1]); std::ifstream f2(argv[2]); if (!f1.is_open() || !f2.is_open()) throw std::runtime_error("Failed to open input files"); f1 >> j1; f2 >> j2; } catch (const std::exception& e) { std::cerr << "JSON parse or file error: " << e.what() << std::endl; return 1; } // Determine which file is meta and which is netlist std::stringstream meta_buf, netlist_buf; if (j1.contains("files") && !j2.contains("files")) { meta_buf << j1.dump(); netlist_buf << j2.dump(); } else if (!j1.contains("files") && j2.contains("files")) { meta_buf << j2.dump(); netlist_buf << j1.dump(); } else { std::cout << "Unable to distinguish meta and netlist JSON." << std::endl; return 1; } std::ofstream out_file(argv[3]); if (!out_file.is_open()) { std::cout << "Failed to open output file." << std::endl; return 1; } json2stems(netlist_buf, meta_buf, out_file); return 0; } // Parse file ID to real path mapping from the meta JSON std::map parse_filemap(const json& meta_json) { std::map filemap; if (meta_json.contains("files")) { // bybell: won't compile on older c++ compilers // for (const auto& [id, info] : meta_json["files"].items()) // { for (auto it = meta_json["files"].items().begin(); it != meta_json["files"].items().end(); ++it) { const auto& pair = *it; const auto& id = pair.key(); const auto& info = pair.value(); if (info.contains("filename")) { filemap[id] = info["realpath"]; } } } return filemap; } // Extract file ID (e.g., "a") from location string like "a,12:0,12:23" std::string get_file_id(const std::string& loc) { size_t comma = loc.find(','); return (comma != std::string::npos) ? loc.substr(0, comma) : ""; } // Extract start and end line numbers from location string std::pair get_line_range(const std::string& loc) { // bybell: crashes with regex error on older compilers, replace with faster c code // std::regex line_re("[a-z]+,(\\d+):\\d+,(\\d+):\\d+"); // std::smatch match; // if (std::regex_search(loc, match, line_re) && match.size() >= 3) // { // return {std::stoi(match[1]), std::stoi(match[2])}; // } // return {0, 0}; const char *s = loc.c_str(); const char *comma = strchr(s, ','); int l1, c1, l2, c2; int rc = sscanf(comma+1, "%d:%d,%d:%d", &l1, &c1, &l2, &c2); if(rc == 4) return {l1, l2}; else return {0, 0}; } // Main converter function void json2stems(std::istream& netlist_stream, std::istream& meta_stream, std::ostream& out) { json meta_json, netlist_json; meta_stream >> meta_json; netlist_stream >> netlist_json; auto filemap = parse_filemap(meta_json); std::map pointer_to_module_name; if (netlist_json.contains("modulesp")) { for (const auto& mod : netlist_json["modulesp"]) { if (mod.contains("addr") && mod.contains("name")) { pointer_to_module_name[mod["addr"]] = mod["name"]; } } } for (const auto& mod : netlist_json["modulesp"]) { if (!mod.contains("name") || !mod.contains("loc")) continue; std::string loc = mod["loc"]; std::string mod_name = mod["name"]; std::string file_id = get_file_id(loc); // bybell: won't compile on older c++ compilers // auto [start_line, end_line] = get_line_range(loc); std::pair lr = get_line_range(loc); auto start_line = lr.first; auto end_line = lr.second; auto it = filemap.find(file_id); if (it != filemap.end()) { out << "++ module " << mod_name << " file " << it->second << " lines " << start_line << " - " << end_line << "\n"; } if (mod.contains("stmtsp")) { for (const auto& stmt : mod["stmtsp"]) { if (stmt.contains("type") && stmt["type"] == "CELL" && stmt.contains("name")) { std::string inst_name = stmt["name"]; std::string target_mod_name = "UNKNOWN"; if (stmt.contains("modp")) { std::string modp = stmt["modp"]; auto it2 = pointer_to_module_name.find(modp); if (it2 != pointer_to_module_name.end()) { target_mod_name = it2->second; } } out << "++ comp " << inst_name << " type " << target_mod_name << " parent " << mod_name << "\n"; } } } } } gtkwave-gtk3-3.3.125/contrib/json2stems/json.hpp0000664000175000017500000352140615047725113020762 0ustar bybellbybell// __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT /****************************************************************************\ * Note on documentation: The source files contain links to the online * * documentation of the public API at https://json.nlohmann.me. This URL * * contains the most recent documentation and should also be applicable to * * previous versions; documentation for deprecated functions is not * * removed, but marked deprecated. See "Generate documentation" section in * * file docs/README.md. * \****************************************************************************/ #ifndef INCLUDE_NLOHMANN_JSON_HPP_ #define INCLUDE_NLOHMANN_JSON_HPP_ #include // all_of, find, for_each #include // nullptr_t, ptrdiff_t, size_t #include // hash, less #include // initializer_list #ifndef JSON_NO_IO #include // istream, ostream #endif // JSON_NO_IO #include // random_access_iterator_tag #include // unique_ptr #include // string, stoi, to_string #include // declval, forward, move, pair, swap #include // vector // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT #include // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT // This file contains all macro definitions affecting or depending on the ABI #ifndef JSON_SKIP_LIBRARY_VERSION_CHECK #if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH) #if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 12 || NLOHMANN_JSON_VERSION_PATCH != 0 #warning "Already included a different version of the library!" #endif #endif #endif #define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum) #define NLOHMANN_JSON_VERSION_MINOR 12 // NOLINT(modernize-macro-to-enum) #define NLOHMANN_JSON_VERSION_PATCH 0 // NOLINT(modernize-macro-to-enum) #ifndef JSON_DIAGNOSTICS #define JSON_DIAGNOSTICS 0 #endif #ifndef JSON_DIAGNOSTIC_POSITIONS #define JSON_DIAGNOSTIC_POSITIONS 0 #endif #ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0 #endif #if JSON_DIAGNOSTICS #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag #else #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS #endif #if JSON_DIAGNOSTIC_POSITIONS #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS _dp #else #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS #endif #if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON _ldvcmp #else #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON #endif #ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION #define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0 #endif // Construct the namespace ABI tags component #define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c) json_abi ## a ## b ## c #define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b, c) \ NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c) #define NLOHMANN_JSON_ABI_TAGS \ NLOHMANN_JSON_ABI_TAGS_CONCAT( \ NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \ NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON, \ NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS) // Construct the namespace version component #define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \ _v ## major ## _ ## minor ## _ ## patch #define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \ NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) #if NLOHMANN_JSON_NAMESPACE_NO_VERSION #define NLOHMANN_JSON_NAMESPACE_VERSION #else #define NLOHMANN_JSON_NAMESPACE_VERSION \ NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \ NLOHMANN_JSON_VERSION_MINOR, \ NLOHMANN_JSON_VERSION_PATCH) #endif // Combine namespace components #define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b #define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \ NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) #ifndef NLOHMANN_JSON_NAMESPACE #define NLOHMANN_JSON_NAMESPACE \ nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \ NLOHMANN_JSON_ABI_TAGS, \ NLOHMANN_JSON_NAMESPACE_VERSION) #endif #ifndef NLOHMANN_JSON_NAMESPACE_BEGIN #define NLOHMANN_JSON_NAMESPACE_BEGIN \ namespace nlohmann \ { \ inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \ NLOHMANN_JSON_ABI_TAGS, \ NLOHMANN_JSON_NAMESPACE_VERSION) \ { #endif #ifndef NLOHMANN_JSON_NAMESPACE_END #define NLOHMANN_JSON_NAMESPACE_END \ } /* namespace (inline namespace) NOLINT(readability/namespace) */ \ } // namespace nlohmann #endif // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT #include // transform #include // array #include // forward_list #include // inserter, front_inserter, end #include // map #include // string #include // tuple, make_tuple #include // is_arithmetic, is_same, is_enum, underlying_type, is_convertible #include // unordered_map #include // pair, declval #include // valarray // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT #include // nullptr_t #include // exception #if JSON_DIAGNOSTICS #include // accumulate #endif #include // runtime_error #include // to_string #include // vector // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT #include // array #include // size_t #include // uint8_t #include // string // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT #include // declval, pair // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT #include // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT // #include NLOHMANN_JSON_NAMESPACE_BEGIN namespace detail { template struct make_void { using type = void; }; template using void_t = typename make_void::type; } // namespace detail NLOHMANN_JSON_NAMESPACE_END NLOHMANN_JSON_NAMESPACE_BEGIN namespace detail { // https://en.cppreference.com/w/cpp/experimental/is_detected struct nonesuch { nonesuch() = delete; ~nonesuch() = delete; nonesuch(nonesuch const&) = delete; nonesuch(nonesuch const&&) = delete; void operator=(nonesuch const&) = delete; void operator=(nonesuch&&) = delete; }; template class Op, class... Args> struct detector { using value_t = std::false_type; using type = Default; }; template class Op, class... Args> struct detector>, Op, Args...> { using value_t = std::true_type; using type = Op; }; template class Op, class... Args> using is_detected = typename detector::value_t; template class Op, class... Args> struct is_detected_lazy : is_detected { }; template class Op, class... Args> using detected_t = typename detector::type; template class Op, class... Args> using detected_or = detector; template class Op, class... Args> using detected_or_t = typename detected_or::type; template class Op, class... Args> using is_detected_exact = std::is_same>; template class Op, class... Args> using is_detected_convertible = std::is_convertible, To>; } // namespace detail NLOHMANN_JSON_NAMESPACE_END // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-FileCopyrightText: 2016 - 2021 Evan Nemerson // SPDX-License-Identifier: MIT /* Hedley - https://nemequ.github.io/hedley * Created by Evan Nemerson */ #if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15) #if defined(JSON_HEDLEY_VERSION) #undef JSON_HEDLEY_VERSION #endif #define JSON_HEDLEY_VERSION 15 #if defined(JSON_HEDLEY_STRINGIFY_EX) #undef JSON_HEDLEY_STRINGIFY_EX #endif #define JSON_HEDLEY_STRINGIFY_EX(x) #x #if defined(JSON_HEDLEY_STRINGIFY) #undef JSON_HEDLEY_STRINGIFY #endif #define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x) #if defined(JSON_HEDLEY_CONCAT_EX) #undef JSON_HEDLEY_CONCAT_EX #endif #define JSON_HEDLEY_CONCAT_EX(a,b) a##b #if defined(JSON_HEDLEY_CONCAT) #undef JSON_HEDLEY_CONCAT #endif #define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b) #if defined(JSON_HEDLEY_CONCAT3_EX) #undef JSON_HEDLEY_CONCAT3_EX #endif #define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c #if defined(JSON_HEDLEY_CONCAT3) #undef JSON_HEDLEY_CONCAT3 #endif #define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c) #if defined(JSON_HEDLEY_VERSION_ENCODE) #undef JSON_HEDLEY_VERSION_ENCODE #endif #define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision)) #if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR) #undef JSON_HEDLEY_VERSION_DECODE_MAJOR #endif #define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000) #if defined(JSON_HEDLEY_VERSION_DECODE_MINOR) #undef JSON_HEDLEY_VERSION_DECODE_MINOR #endif #define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000) #if defined(JSON_HEDLEY_VERSION_DECODE_REVISION) #undef JSON_HEDLEY_VERSION_DECODE_REVISION #endif #define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000) #if defined(JSON_HEDLEY_GNUC_VERSION) #undef JSON_HEDLEY_GNUC_VERSION #endif #if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__) #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) #elif defined(__GNUC__) #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0) #endif #if defined(JSON_HEDLEY_GNUC_VERSION_CHECK) #undef JSON_HEDLEY_GNUC_VERSION_CHECK #endif #if defined(JSON_HEDLEY_GNUC_VERSION) #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) #else #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0) #endif #if defined(JSON_HEDLEY_MSVC_VERSION) #undef JSON_HEDLEY_MSVC_VERSION #endif #if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL) #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100) #elif defined(_MSC_FULL_VER) && !defined(__ICL) #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10) #elif defined(_MSC_VER) && !defined(__ICL) #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0) #endif #if defined(JSON_HEDLEY_MSVC_VERSION_CHECK) #undef JSON_HEDLEY_MSVC_VERSION_CHECK #endif #if !defined(JSON_HEDLEY_MSVC_VERSION) #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0) #elif defined(_MSC_VER) && (_MSC_VER >= 1400) #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch))) #elif defined(_MSC_VER) && (_MSC_VER >= 1200) #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch))) #else #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor))) #endif #if defined(JSON_HEDLEY_INTEL_VERSION) #undef JSON_HEDLEY_INTEL_VERSION #endif #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL) #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE) #elif defined(__INTEL_COMPILER) && !defined(__ICL) #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0) #endif #if defined(JSON_HEDLEY_INTEL_VERSION_CHECK) #undef JSON_HEDLEY_INTEL_VERSION_CHECK #endif #if defined(JSON_HEDLEY_INTEL_VERSION) #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) #else #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0) #endif #if defined(JSON_HEDLEY_INTEL_CL_VERSION) #undef JSON_HEDLEY_INTEL_CL_VERSION #endif #if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL) #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0) #endif #if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK) #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK #endif #if defined(JSON_HEDLEY_INTEL_CL_VERSION) #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) #else #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0) #endif #if defined(JSON_HEDLEY_PGI_VERSION) #undef JSON_HEDLEY_PGI_VERSION #endif #if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__) #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__) #endif #if defined(JSON_HEDLEY_PGI_VERSION_CHECK) #undef JSON_HEDLEY_PGI_VERSION_CHECK #endif #if defined(JSON_HEDLEY_PGI_VERSION) #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) #else #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0) #endif #if defined(JSON_HEDLEY_SUNPRO_VERSION) #undef JSON_HEDLEY_SUNPRO_VERSION #endif #if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000) #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10) #elif defined(__SUNPRO_C) #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf) #elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000) #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10) #elif defined(__SUNPRO_CC) #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf) #endif #if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK) #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK #endif #if defined(JSON_HEDLEY_SUNPRO_VERSION) #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) #else #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0) #endif #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION) #undef JSON_HEDLEY_EMSCRIPTEN_VERSION #endif #if defined(__EMSCRIPTEN__) #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__) #endif #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK) #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK #endif #if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION) #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) #else #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0) #endif #if defined(JSON_HEDLEY_ARM_VERSION) #undef JSON_HEDLEY_ARM_VERSION #endif #if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION) #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100) #elif defined(__CC_ARM) && defined(__ARMCC_VERSION) #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100) #endif #if defined(JSON_HEDLEY_ARM_VERSION_CHECK) #undef JSON_HEDLEY_ARM_VERSION_CHECK #endif #if defined(JSON_HEDLEY_ARM_VERSION) #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) #else #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0) #endif #if defined(JSON_HEDLEY_IBM_VERSION) #undef JSON_HEDLEY_IBM_VERSION #endif #if defined(__ibmxl__) #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__) #elif defined(__xlC__) && defined(__xlC_ver__) #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff) #elif defined(__xlC__) #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0) #endif #if defined(JSON_HEDLEY_IBM_VERSION_CHECK) #undef JSON_HEDLEY_IBM_VERSION_CHECK #endif #if defined(JSON_HEDLEY_IBM_VERSION) #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) #else #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0) #endif #if defined(JSON_HEDLEY_TI_VERSION) #undef JSON_HEDLEY_TI_VERSION #endif #if \ defined(__TI_COMPILER_VERSION__) && \ ( \ defined(__TMS470__) || defined(__TI_ARM__) || \ defined(__MSP430__) || \ defined(__TMS320C2000__) \ ) #if (__TI_COMPILER_VERSION__ >= 16000000) #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) #endif #endif #if defined(JSON_HEDLEY_TI_VERSION_CHECK) #undef JSON_HEDLEY_TI_VERSION_CHECK #endif #if defined(JSON_HEDLEY_TI_VERSION) #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) #else #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0) #endif #if defined(JSON_HEDLEY_TI_CL2000_VERSION) #undef JSON_HEDLEY_TI_CL2000_VERSION #endif #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__) #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) #endif #if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK) #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK #endif #if defined(JSON_HEDLEY_TI_CL2000_VERSION) #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) #else #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0) #endif #if defined(JSON_HEDLEY_TI_CL430_VERSION) #undef JSON_HEDLEY_TI_CL430_VERSION #endif #if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__) #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) #endif #if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK) #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK #endif #if defined(JSON_HEDLEY_TI_CL430_VERSION) #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) #else #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0) #endif #if defined(JSON_HEDLEY_TI_ARMCL_VERSION) #undef JSON_HEDLEY_TI_ARMCL_VERSION #endif #if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__)) #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) #endif #if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK) #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK #endif #if defined(JSON_HEDLEY_TI_ARMCL_VERSION) #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) #else #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0) #endif #if defined(JSON_HEDLEY_TI_CL6X_VERSION) #undef JSON_HEDLEY_TI_CL6X_VERSION #endif #if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__) #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) #endif #if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK) #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK #endif #if defined(JSON_HEDLEY_TI_CL6X_VERSION) #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) #else #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0) #endif #if defined(JSON_HEDLEY_TI_CL7X_VERSION) #undef JSON_HEDLEY_TI_CL7X_VERSION #endif #if defined(__TI_COMPILER_VERSION__) && defined(__C7000__) #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) #endif #if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK) #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK #endif #if defined(JSON_HEDLEY_TI_CL7X_VERSION) #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) #else #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0) #endif #if defined(JSON_HEDLEY_TI_CLPRU_VERSION) #undef JSON_HEDLEY_TI_CLPRU_VERSION #endif #if defined(__TI_COMPILER_VERSION__) && defined(__PRU__) #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) #endif #if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK) #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK #endif #if defined(JSON_HEDLEY_TI_CLPRU_VERSION) #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) #else #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0) #endif #if defined(JSON_HEDLEY_CRAY_VERSION) #undef JSON_HEDLEY_CRAY_VERSION #endif #if defined(_CRAYC) #if defined(_RELEASE_PATCHLEVEL) #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL) #else #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0) #endif #endif #if defined(JSON_HEDLEY_CRAY_VERSION_CHECK) #undef JSON_HEDLEY_CRAY_VERSION_CHECK #endif #if defined(JSON_HEDLEY_CRAY_VERSION) #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) #else #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0) #endif #if defined(JSON_HEDLEY_IAR_VERSION) #undef JSON_HEDLEY_IAR_VERSION #endif #if defined(__IAR_SYSTEMS_ICC__) #if __VER__ > 1000 #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000)) #else #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0) #endif #endif #if defined(JSON_HEDLEY_IAR_VERSION_CHECK) #undef JSON_HEDLEY_IAR_VERSION_CHECK #endif #if defined(JSON_HEDLEY_IAR_VERSION) #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) #else #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0) #endif #if defined(JSON_HEDLEY_TINYC_VERSION) #undef JSON_HEDLEY_TINYC_VERSION #endif #if defined(__TINYC__) #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100) #endif #if defined(JSON_HEDLEY_TINYC_VERSION_CHECK) #undef JSON_HEDLEY_TINYC_VERSION_CHECK #endif #if defined(JSON_HEDLEY_TINYC_VERSION) #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) #else #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0) #endif #if defined(JSON_HEDLEY_DMC_VERSION) #undef JSON_HEDLEY_DMC_VERSION #endif #if defined(__DMC__) #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf) #endif #if defined(JSON_HEDLEY_DMC_VERSION_CHECK) #undef JSON_HEDLEY_DMC_VERSION_CHECK #endif #if defined(JSON_HEDLEY_DMC_VERSION) #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) #else #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0) #endif #if defined(JSON_HEDLEY_COMPCERT_VERSION) #undef JSON_HEDLEY_COMPCERT_VERSION #endif #if defined(__COMPCERT_VERSION__) #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100) #endif #if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK) #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK #endif #if defined(JSON_HEDLEY_COMPCERT_VERSION) #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) #else #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0) #endif #if defined(JSON_HEDLEY_PELLES_VERSION) #undef JSON_HEDLEY_PELLES_VERSION #endif #if defined(__POCC__) #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0) #endif #if defined(JSON_HEDLEY_PELLES_VERSION_CHECK) #undef JSON_HEDLEY_PELLES_VERSION_CHECK #endif #if defined(JSON_HEDLEY_PELLES_VERSION) #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) #else #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0) #endif #if defined(JSON_HEDLEY_MCST_LCC_VERSION) #undef JSON_HEDLEY_MCST_LCC_VERSION #endif #if defined(__LCC__) && defined(__LCC_MINOR__) #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__) #endif #if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK) #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK #endif #if defined(JSON_HEDLEY_MCST_LCC_VERSION) #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) #else #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0) #endif #if defined(JSON_HEDLEY_GCC_VERSION) #undef JSON_HEDLEY_GCC_VERSION #endif #if \ defined(JSON_HEDLEY_GNUC_VERSION) && \ !defined(__clang__) && \ !defined(JSON_HEDLEY_INTEL_VERSION) && \ !defined(JSON_HEDLEY_PGI_VERSION) && \ !defined(JSON_HEDLEY_ARM_VERSION) && \ !defined(JSON_HEDLEY_CRAY_VERSION) && \ !defined(JSON_HEDLEY_TI_VERSION) && \ !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \ !defined(JSON_HEDLEY_TI_CL430_VERSION) && \ !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \ !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \ !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \ !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \ !defined(__COMPCERT__) && \ !defined(JSON_HEDLEY_MCST_LCC_VERSION) #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION #endif #if defined(JSON_HEDLEY_GCC_VERSION_CHECK) #undef JSON_HEDLEY_GCC_VERSION_CHECK #endif #if defined(JSON_HEDLEY_GCC_VERSION) #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) #else #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0) #endif #if defined(JSON_HEDLEY_HAS_ATTRIBUTE) #undef JSON_HEDLEY_HAS_ATTRIBUTE #endif #if \ defined(__has_attribute) && \ ( \ (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \ ) # define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute) #else # define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0) #endif #if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE) #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE #endif #if defined(__has_attribute) #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) #else #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) #endif #if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE) #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE #endif #if defined(__has_attribute) #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) #else #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) #endif #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE) #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE #endif #if \ defined(__has_cpp_attribute) && \ defined(__cplusplus) && \ (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute) #else #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0) #endif #if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS) #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS #endif #if !defined(__cplusplus) || !defined(__has_cpp_attribute) #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0) #elif \ !defined(JSON_HEDLEY_PGI_VERSION) && \ !defined(JSON_HEDLEY_IAR_VERSION) && \ (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \ (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0)) #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute) #else #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0) #endif #if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE) #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE #endif #if defined(__has_cpp_attribute) && defined(__cplusplus) #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute) #else #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) #endif #if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE) #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE #endif #if defined(__has_cpp_attribute) && defined(__cplusplus) #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute) #else #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) #endif #if defined(JSON_HEDLEY_HAS_BUILTIN) #undef JSON_HEDLEY_HAS_BUILTIN #endif #if defined(__has_builtin) #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin) #else #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0) #endif #if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN) #undef JSON_HEDLEY_GNUC_HAS_BUILTIN #endif #if defined(__has_builtin) #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin) #else #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) #endif #if defined(JSON_HEDLEY_GCC_HAS_BUILTIN) #undef JSON_HEDLEY_GCC_HAS_BUILTIN #endif #if defined(__has_builtin) #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin) #else #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) #endif #if defined(JSON_HEDLEY_HAS_FEATURE) #undef JSON_HEDLEY_HAS_FEATURE #endif #if defined(__has_feature) #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature) #else #define JSON_HEDLEY_HAS_FEATURE(feature) (0) #endif #if defined(JSON_HEDLEY_GNUC_HAS_FEATURE) #undef JSON_HEDLEY_GNUC_HAS_FEATURE #endif #if defined(__has_feature) #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature) #else #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) #endif #if defined(JSON_HEDLEY_GCC_HAS_FEATURE) #undef JSON_HEDLEY_GCC_HAS_FEATURE #endif #if defined(__has_feature) #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature) #else #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) #endif #if defined(JSON_HEDLEY_HAS_EXTENSION) #undef JSON_HEDLEY_HAS_EXTENSION #endif #if defined(__has_extension) #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension) #else #define JSON_HEDLEY_HAS_EXTENSION(extension) (0) #endif #if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION) #undef JSON_HEDLEY_GNUC_HAS_EXTENSION #endif #if defined(__has_extension) #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension) #else #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) #endif #if defined(JSON_HEDLEY_GCC_HAS_EXTENSION) #undef JSON_HEDLEY_GCC_HAS_EXTENSION #endif #if defined(__has_extension) #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension) #else #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) #endif #if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE) #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE #endif #if defined(__has_declspec_attribute) #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute) #else #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0) #endif #if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE) #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE #endif #if defined(__has_declspec_attribute) #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute) #else #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) #endif #if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE) #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE #endif #if defined(__has_declspec_attribute) #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute) #else #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) #endif #if defined(JSON_HEDLEY_HAS_WARNING) #undef JSON_HEDLEY_HAS_WARNING #endif #if defined(__has_warning) #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning) #else #define JSON_HEDLEY_HAS_WARNING(warning) (0) #endif #if defined(JSON_HEDLEY_GNUC_HAS_WARNING) #undef JSON_HEDLEY_GNUC_HAS_WARNING #endif #if defined(__has_warning) #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning) #else #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) #endif #if defined(JSON_HEDLEY_GCC_HAS_WARNING) #undef JSON_HEDLEY_GCC_HAS_WARNING #endif #if defined(__has_warning) #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning) #else #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) #endif #if \ (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ defined(__clang__) || \ JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \ JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \ JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \ JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \ JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \ JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \ JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \ JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \ (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR)) #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value) #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) #define JSON_HEDLEY_PRAGMA(value) __pragma(value) #else #define JSON_HEDLEY_PRAGMA(value) #endif #if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH) #undef JSON_HEDLEY_DIAGNOSTIC_PUSH #endif #if defined(JSON_HEDLEY_DIAGNOSTIC_POP) #undef JSON_HEDLEY_DIAGNOSTIC_POP #endif #if defined(__clang__) #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push") #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop") #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)") #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)") #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push") #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop") #elif \ JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \ JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push)) #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop)) #elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push") #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop") #elif \ JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \ JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \ JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push") #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop") #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0) #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)") #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)") #else #define JSON_HEDLEY_DIAGNOSTIC_PUSH #define JSON_HEDLEY_DIAGNOSTIC_POP #endif /* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for HEDLEY INTERNAL USE ONLY. API subject to change without notice. */ #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_) #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ #endif #if defined(__cplusplus) # if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat") # if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions") # if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions") # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ JSON_HEDLEY_DIAGNOSTIC_PUSH \ _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \ _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \ xpr \ JSON_HEDLEY_DIAGNOSTIC_POP # else # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ JSON_HEDLEY_DIAGNOSTIC_PUSH \ _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \ xpr \ JSON_HEDLEY_DIAGNOSTIC_POP # endif # else # define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ JSON_HEDLEY_DIAGNOSTIC_PUSH \ _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ xpr \ JSON_HEDLEY_DIAGNOSTIC_POP # endif # endif #endif #if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x #endif #if defined(JSON_HEDLEY_CONST_CAST) #undef JSON_HEDLEY_CONST_CAST #endif #if defined(__cplusplus) # define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast(expr)) #elif \ JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \ JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) # define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \ JSON_HEDLEY_DIAGNOSTIC_PUSH \ JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \ ((T) (expr)); \ JSON_HEDLEY_DIAGNOSTIC_POP \ })) #else # define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr)) #endif #if defined(JSON_HEDLEY_REINTERPRET_CAST) #undef JSON_HEDLEY_REINTERPRET_CAST #endif #if defined(__cplusplus) #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast(expr)) #else #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr)) #endif #if defined(JSON_HEDLEY_STATIC_CAST) #undef JSON_HEDLEY_STATIC_CAST #endif #if defined(__cplusplus) #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast(expr)) #else #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr)) #endif #if defined(JSON_HEDLEY_CPP_CAST) #undef JSON_HEDLEY_CPP_CAST #endif #if defined(__cplusplus) # if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast") # define JSON_HEDLEY_CPP_CAST(T, expr) \ JSON_HEDLEY_DIAGNOSTIC_PUSH \ _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \ ((T) (expr)) \ JSON_HEDLEY_DIAGNOSTIC_POP # elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0) # define JSON_HEDLEY_CPP_CAST(T, expr) \ JSON_HEDLEY_DIAGNOSTIC_PUSH \ _Pragma("diag_suppress=Pe137") \ JSON_HEDLEY_DIAGNOSTIC_POP # else # define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr)) # endif #else # define JSON_HEDLEY_CPP_CAST(T, expr) (expr) #endif #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED) #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED #endif #if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations") #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)") #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786)) #elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445") #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444") #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996)) #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444") #elif \ JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718") #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)") #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)") #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215") #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)") #else #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED #endif #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS) #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS #endif #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"") #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)") #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161)) #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675") #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"") #elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068)) #elif \ JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \ JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \ JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163") #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163") #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161") #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161") #else #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS #endif #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES) #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES #endif #if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes") #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"") #elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") #elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)") #elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292)) #elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030)) #elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098") #elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097") #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)") #elif \ JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \ JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \ JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173") #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097") #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097") #else #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES #endif #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL) #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL #endif #if JSON_HEDLEY_HAS_WARNING("-Wcast-qual") #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"") #elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)") #elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"") #else #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL #endif #if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION) #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION #endif #if JSON_HEDLEY_HAS_WARNING("-Wunused-function") #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"") #elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"") #elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505)) #elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142") #else #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION #endif #if defined(JSON_HEDLEY_DEPRECATED) #undef JSON_HEDLEY_DEPRECATED #endif #if defined(JSON_HEDLEY_DEPRECATED_FOR) #undef JSON_HEDLEY_DEPRECATED_FOR #endif #if \ JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since)) #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement)) #elif \ (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \ JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \ JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \ JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \ JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \ JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \ JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since))) #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement))) #elif defined(__cplusplus) && (__cplusplus >= 201402L) #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]]) #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]]) #elif \ JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \ JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__)) #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__)) #elif \ JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \ JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated) #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated) #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated") #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated") #else #define JSON_HEDLEY_DEPRECATED(since) #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) #endif #if defined(JSON_HEDLEY_UNAVAILABLE) #undef JSON_HEDLEY_UNAVAILABLE #endif #if \ JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \ JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since))) #else #define JSON_HEDLEY_UNAVAILABLE(available_since) #endif #if defined(JSON_HEDLEY_WARN_UNUSED_RESULT) #undef JSON_HEDLEY_WARN_UNUSED_RESULT #endif #if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG) #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG #endif #if \ JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \ JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__)) #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__)) #elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L) #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]]) #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) #elif defined(_Check_return_) /* SAL */ #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_ #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_ #else #define JSON_HEDLEY_WARN_UNUSED_RESULT #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) #endif #if defined(JSON_HEDLEY_SENTINEL) #undef JSON_HEDLEY_SENTINEL #endif #if \ JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \ JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \ JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position))) #else #define JSON_HEDLEY_SENTINEL(position) #endif #if defined(JSON_HEDLEY_NO_RETURN) #undef JSON_HEDLEY_NO_RETURN #endif #if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) #define JSON_HEDLEY_NO_RETURN __noreturn #elif \ JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__)) #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L #define JSON_HEDLEY_NO_RETURN _Noreturn #elif defined(__cplusplus) && (__cplusplus >= 201103L) #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]]) #elif \ JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \ JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \ JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__)) #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return") #elif \ JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) #define JSON_HEDLEY_NO_RETURN __declspec(noreturn) #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus) #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;") #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0) #define JSON_HEDLEY_NO_RETURN __attribute((noreturn)) #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0) #define JSON_HEDLEY_NO_RETURN __declspec(noreturn) #else #define JSON_HEDLEY_NO_RETURN #endif #if defined(JSON_HEDLEY_NO_ESCAPE) #undef JSON_HEDLEY_NO_ESCAPE #endif #if JSON_HEDLEY_HAS_ATTRIBUTE(noescape) #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__)) #else #define JSON_HEDLEY_NO_ESCAPE #endif #if defined(JSON_HEDLEY_UNREACHABLE) #undef JSON_HEDLEY_UNREACHABLE #endif #if defined(JSON_HEDLEY_UNREACHABLE_RETURN) #undef JSON_HEDLEY_UNREACHABLE_RETURN #endif #if defined(JSON_HEDLEY_ASSUME) #undef JSON_HEDLEY_ASSUME #endif #if \ JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) #define JSON_HEDLEY_ASSUME(expr) __assume(expr) #elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume) #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr) #elif \ JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) #if defined(__cplusplus) #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr) #else #define JSON_HEDLEY_ASSUME(expr) _nassert(expr) #endif #endif #if \ (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \ JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \ JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \ JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable() #elif defined(JSON_HEDLEY_ASSUME) #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0) #endif #if !defined(JSON_HEDLEY_ASSUME) #if defined(JSON_HEDLEY_UNREACHABLE) #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1))) #else #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr) #endif #endif #if defined(JSON_HEDLEY_UNREACHABLE) #if \ JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value)) #else #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE() #endif #else #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value) #endif #if !defined(JSON_HEDLEY_UNREACHABLE) #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0) #endif JSON_HEDLEY_DIAGNOSTIC_PUSH #if JSON_HEDLEY_HAS_WARNING("-Wpedantic") #pragma clang diagnostic ignored "-Wpedantic" #endif #if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus) #pragma clang diagnostic ignored "-Wc++98-compat-pedantic" #endif #if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0) #if defined(__clang__) #pragma clang diagnostic ignored "-Wvariadic-macros" #elif defined(JSON_HEDLEY_GCC_VERSION) #pragma GCC diagnostic ignored "-Wvariadic-macros" #endif #endif #if defined(JSON_HEDLEY_NON_NULL) #undef JSON_HEDLEY_NON_NULL #endif #if \ JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \ JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__))) #else #define JSON_HEDLEY_NON_NULL(...) #endif JSON_HEDLEY_DIAGNOSTIC_POP #if defined(JSON_HEDLEY_PRINTF_FORMAT) #undef JSON_HEDLEY_PRINTF_FORMAT #endif #if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO) #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check))) #elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO) #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check))) #elif \ JSON_HEDLEY_HAS_ATTRIBUTE(format) || \ JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check))) #elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0) #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check)) #else #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) #endif #if defined(JSON_HEDLEY_CONSTEXPR) #undef JSON_HEDLEY_CONSTEXPR #endif #if defined(__cplusplus) #if __cplusplus >= 201103L #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr) #endif #endif #if !defined(JSON_HEDLEY_CONSTEXPR) #define JSON_HEDLEY_CONSTEXPR #endif #if defined(JSON_HEDLEY_PREDICT) #undef JSON_HEDLEY_PREDICT #endif #if defined(JSON_HEDLEY_LIKELY) #undef JSON_HEDLEY_LIKELY #endif #if defined(JSON_HEDLEY_UNLIKELY) #undef JSON_HEDLEY_UNLIKELY #endif #if defined(JSON_HEDLEY_UNPREDICTABLE) #undef JSON_HEDLEY_UNPREDICTABLE #endif #if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable) #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr)) #endif #if \ (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \ JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \ JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) # define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability)) # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability)) # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability)) # define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 ) # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 ) #elif \ (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \ JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \ JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \ JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \ JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \ JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) # define JSON_HEDLEY_PREDICT(expr, expected, probability) \ (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))) # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \ (__extension__ ({ \ double hedley_probability_ = (probability); \ ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \ })) # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \ (__extension__ ({ \ double hedley_probability_ = (probability); \ ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \ })) # define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1) # define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0) #else # define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)) # define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr)) # define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr)) # define JSON_HEDLEY_LIKELY(expr) (!!(expr)) # define JSON_HEDLEY_UNLIKELY(expr) (!!(expr)) #endif #if !defined(JSON_HEDLEY_UNPREDICTABLE) #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5) #endif #if defined(JSON_HEDLEY_MALLOC) #undef JSON_HEDLEY_MALLOC #endif #if \ JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \ JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) #define JSON_HEDLEY_MALLOC __attribute__((__malloc__)) #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory") #elif \ JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) #define JSON_HEDLEY_MALLOC __declspec(restrict) #else #define JSON_HEDLEY_MALLOC #endif #if defined(JSON_HEDLEY_PURE) #undef JSON_HEDLEY_PURE #endif #if \ JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \ JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) # define JSON_HEDLEY_PURE __attribute__((__pure__)) #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) # define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data") #elif defined(__cplusplus) && \ ( \ JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \ JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \ JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \ ) # define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;") #else # define JSON_HEDLEY_PURE #endif #if defined(JSON_HEDLEY_CONST) #undef JSON_HEDLEY_CONST #endif #if \ JSON_HEDLEY_HAS_ATTRIBUTE(const) || \ JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) #define JSON_HEDLEY_CONST __attribute__((__const__)) #elif \ JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) #define JSON_HEDLEY_CONST _Pragma("no_side_effect") #else #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE #endif #if defined(JSON_HEDLEY_RESTRICT) #undef JSON_HEDLEY_RESTRICT #endif #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus) #define JSON_HEDLEY_RESTRICT restrict #elif \ JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \ JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \ JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \ JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ defined(__clang__) || \ JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) #define JSON_HEDLEY_RESTRICT __restrict #elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus) #define JSON_HEDLEY_RESTRICT _Restrict #else #define JSON_HEDLEY_RESTRICT #endif #if defined(JSON_HEDLEY_INLINE) #undef JSON_HEDLEY_INLINE #endif #if \ (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ (defined(__cplusplus) && (__cplusplus >= 199711L)) #define JSON_HEDLEY_INLINE inline #elif \ defined(JSON_HEDLEY_GCC_VERSION) || \ JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0) #define JSON_HEDLEY_INLINE __inline__ #elif \ JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \ JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \ JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \ JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \ JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) #define JSON_HEDLEY_INLINE __inline #else #define JSON_HEDLEY_INLINE #endif #if defined(JSON_HEDLEY_ALWAYS_INLINE) #undef JSON_HEDLEY_ALWAYS_INLINE #endif #if \ JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \ JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) # define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE #elif \ JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \ JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) # define JSON_HEDLEY_ALWAYS_INLINE __forceinline #elif defined(__cplusplus) && \ ( \ JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \ ) # define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;") #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) # define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced") #else # define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE #endif #if defined(JSON_HEDLEY_NEVER_INLINE) #undef JSON_HEDLEY_NEVER_INLINE #endif #if \ JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \ JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__)) #elif \ JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline) #elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0) #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline") #elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus) #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;") #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never") #elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0) #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline)) #elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0) #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline) #else #define JSON_HEDLEY_NEVER_INLINE #endif #if defined(JSON_HEDLEY_PRIVATE) #undef JSON_HEDLEY_PRIVATE #endif #if defined(JSON_HEDLEY_PUBLIC) #undef JSON_HEDLEY_PUBLIC #endif #if defined(JSON_HEDLEY_IMPORT) #undef JSON_HEDLEY_IMPORT #endif #if defined(_WIN32) || defined(__CYGWIN__) # define JSON_HEDLEY_PRIVATE # define JSON_HEDLEY_PUBLIC __declspec(dllexport) # define JSON_HEDLEY_IMPORT __declspec(dllimport) #else # if \ JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \ JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ ( \ defined(__TI_EABI__) && \ ( \ (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \ ) \ ) || \ JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) # define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden"))) # define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default"))) # else # define JSON_HEDLEY_PRIVATE # define JSON_HEDLEY_PUBLIC # endif # define JSON_HEDLEY_IMPORT extern #endif #if defined(JSON_HEDLEY_NO_THROW) #undef JSON_HEDLEY_NO_THROW #endif #if \ JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \ JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__)) #elif \ JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \ JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) #define JSON_HEDLEY_NO_THROW __declspec(nothrow) #else #define JSON_HEDLEY_NO_THROW #endif #if defined(JSON_HEDLEY_FALL_THROUGH) #undef JSON_HEDLEY_FALL_THROUGH #endif #if \ JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \ JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \ JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__)) #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough) #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]]) #elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough) #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]]) #elif defined(__fallthrough) /* SAL */ #define JSON_HEDLEY_FALL_THROUGH __fallthrough #else #define JSON_HEDLEY_FALL_THROUGH #endif #if defined(JSON_HEDLEY_RETURNS_NON_NULL) #undef JSON_HEDLEY_RETURNS_NON_NULL #endif #if \ JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \ JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \ JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__)) #elif defined(_Ret_notnull_) /* SAL */ #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_ #else #define JSON_HEDLEY_RETURNS_NON_NULL #endif #if defined(JSON_HEDLEY_ARRAY_PARAM) #undef JSON_HEDLEY_ARRAY_PARAM #endif #if \ defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ !defined(__STDC_NO_VLA__) && \ !defined(__cplusplus) && \ !defined(JSON_HEDLEY_PGI_VERSION) && \ !defined(JSON_HEDLEY_TINYC_VERSION) #define JSON_HEDLEY_ARRAY_PARAM(name) (name) #else #define JSON_HEDLEY_ARRAY_PARAM(name) #endif #if defined(JSON_HEDLEY_IS_CONSTANT) #undef JSON_HEDLEY_IS_CONSTANT #endif #if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR) #undef JSON_HEDLEY_REQUIRE_CONSTEXPR #endif /* JSON_HEDLEY_IS_CONSTEXPR_ is for HEDLEY INTERNAL USE ONLY. API subject to change without notice. */ #if defined(JSON_HEDLEY_IS_CONSTEXPR_) #undef JSON_HEDLEY_IS_CONSTEXPR_ #endif #if \ JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \ JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \ JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \ JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr) #endif #if !defined(__cplusplus) # if \ JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \ JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \ JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24) #if defined(__INTPTR_TYPE__) #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*) #else #include #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*) #endif # elif \ ( \ defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \ !defined(JSON_HEDLEY_SUNPRO_VERSION) && \ !defined(JSON_HEDLEY_PGI_VERSION) && \ !defined(JSON_HEDLEY_IAR_VERSION)) || \ (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \ JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \ JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0) #if defined(__INTPTR_TYPE__) #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0) #else #include #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0) #endif # elif \ defined(JSON_HEDLEY_GCC_VERSION) || \ defined(JSON_HEDLEY_INTEL_VERSION) || \ defined(JSON_HEDLEY_TINYC_VERSION) || \ defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \ JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \ defined(JSON_HEDLEY_TI_CL2000_VERSION) || \ defined(JSON_HEDLEY_TI_CL6X_VERSION) || \ defined(JSON_HEDLEY_TI_CL7X_VERSION) || \ defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \ defined(__clang__) # define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \ sizeof(void) != \ sizeof(*( \ 1 ? \ ((void*) ((expr) * 0L) ) : \ ((struct { char v[sizeof(void) * 2]; } *) 1) \ ) \ ) \ ) # endif #endif #if defined(JSON_HEDLEY_IS_CONSTEXPR_) #if !defined(JSON_HEDLEY_IS_CONSTANT) #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr) #endif #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1)) #else #if !defined(JSON_HEDLEY_IS_CONSTANT) #define JSON_HEDLEY_IS_CONSTANT(expr) (0) #endif #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr) #endif #if defined(JSON_HEDLEY_BEGIN_C_DECLS) #undef JSON_HEDLEY_BEGIN_C_DECLS #endif #if defined(JSON_HEDLEY_END_C_DECLS) #undef JSON_HEDLEY_END_C_DECLS #endif #if defined(JSON_HEDLEY_C_DECL) #undef JSON_HEDLEY_C_DECL #endif #if defined(__cplusplus) #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" { #define JSON_HEDLEY_END_C_DECLS } #define JSON_HEDLEY_C_DECL extern "C" #else #define JSON_HEDLEY_BEGIN_C_DECLS #define JSON_HEDLEY_END_C_DECLS #define JSON_HEDLEY_C_DECL #endif #if defined(JSON_HEDLEY_STATIC_ASSERT) #undef JSON_HEDLEY_STATIC_ASSERT #endif #if \ !defined(__cplusplus) && ( \ (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \ (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \ JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ defined(_Static_assert) \ ) # define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message) #elif \ (defined(__cplusplus) && (__cplusplus >= 201103L)) || \ JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \ JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) # define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message)) #else # define JSON_HEDLEY_STATIC_ASSERT(expr, message) #endif #if defined(JSON_HEDLEY_NULL) #undef JSON_HEDLEY_NULL #endif #if defined(__cplusplus) #if __cplusplus >= 201103L #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr) #elif defined(NULL) #define JSON_HEDLEY_NULL NULL #else #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0) #endif #elif defined(NULL) #define JSON_HEDLEY_NULL NULL #else #define JSON_HEDLEY_NULL ((void*) 0) #endif #if defined(JSON_HEDLEY_MESSAGE) #undef JSON_HEDLEY_MESSAGE #endif #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") # define JSON_HEDLEY_MESSAGE(msg) \ JSON_HEDLEY_DIAGNOSTIC_PUSH \ JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \ JSON_HEDLEY_PRAGMA(message msg) \ JSON_HEDLEY_DIAGNOSTIC_POP #elif \ JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg) #elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg) #elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg)) #elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0) # define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg)) #else # define JSON_HEDLEY_MESSAGE(msg) #endif #if defined(JSON_HEDLEY_WARNING) #undef JSON_HEDLEY_WARNING #endif #if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") # define JSON_HEDLEY_WARNING(msg) \ JSON_HEDLEY_DIAGNOSTIC_PUSH \ JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \ JSON_HEDLEY_PRAGMA(clang warning msg) \ JSON_HEDLEY_DIAGNOSTIC_POP #elif \ JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \ JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \ JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg) #elif \ JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \ JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg)) #else # define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg) #endif #if defined(JSON_HEDLEY_REQUIRE) #undef JSON_HEDLEY_REQUIRE #endif #if defined(JSON_HEDLEY_REQUIRE_MSG) #undef JSON_HEDLEY_REQUIRE_MSG #endif #if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if) # if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat") # define JSON_HEDLEY_REQUIRE(expr) \ JSON_HEDLEY_DIAGNOSTIC_PUSH \ _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ __attribute__((diagnose_if(!(expr), #expr, "error"))) \ JSON_HEDLEY_DIAGNOSTIC_POP # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \ JSON_HEDLEY_DIAGNOSTIC_PUSH \ _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ __attribute__((diagnose_if(!(expr), msg, "error"))) \ JSON_HEDLEY_DIAGNOSTIC_POP # else # define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error"))) # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error"))) # endif #else # define JSON_HEDLEY_REQUIRE(expr) # define JSON_HEDLEY_REQUIRE_MSG(expr,msg) #endif #if defined(JSON_HEDLEY_FLAGS) #undef JSON_HEDLEY_FLAGS #endif #if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion")) #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__)) #else #define JSON_HEDLEY_FLAGS #endif #if defined(JSON_HEDLEY_FLAGS_CAST) #undef JSON_HEDLEY_FLAGS_CAST #endif #if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0) # define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \ JSON_HEDLEY_DIAGNOSTIC_PUSH \ _Pragma("warning(disable:188)") \ ((T) (expr)); \ JSON_HEDLEY_DIAGNOSTIC_POP \ })) #else # define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr) #endif #if defined(JSON_HEDLEY_EMPTY_BASES) #undef JSON_HEDLEY_EMPTY_BASES #endif #if \ (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \ JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases) #else #define JSON_HEDLEY_EMPTY_BASES #endif /* Remaining macros are deprecated. */ #if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK) #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK #endif #if defined(__clang__) #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0) #else #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) #endif #if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE) #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE #endif #define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) #if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE) #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE #endif #define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) #if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN) #undef JSON_HEDLEY_CLANG_HAS_BUILTIN #endif #define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin) #if defined(JSON_HEDLEY_CLANG_HAS_FEATURE) #undef JSON_HEDLEY_CLANG_HAS_FEATURE #endif #define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature) #if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION) #undef JSON_HEDLEY_CLANG_HAS_EXTENSION #endif #define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension) #if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE) #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE #endif #define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) #if defined(JSON_HEDLEY_CLANG_HAS_WARNING) #undef JSON_HEDLEY_CLANG_HAS_WARNING #endif #define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning) #endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */ // This file contains all internal macro definitions (except those affecting ABI) // You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them // #include // exclude unsupported compilers #if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK) #if defined(__clang__) #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400 #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers" #endif #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER)) #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800 #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers" #endif #endif #endif // C++ language standard detection // if the user manually specified the used C++ version, this is skipped #if !defined(JSON_HAS_CPP_26) && !defined(JSON_HAS_CPP_23) && !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11) #if (defined(__cplusplus) && __cplusplus > 202302L) || (defined(_MSVC_LANG) && _MSVC_LANG > 202302L) #define JSON_HAS_CPP_26 #define JSON_HAS_CPP_23 #define JSON_HAS_CPP_20 #define JSON_HAS_CPP_17 #define JSON_HAS_CPP_14 #elif (defined(__cplusplus) && __cplusplus > 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG > 202002L) #define JSON_HAS_CPP_23 #define JSON_HAS_CPP_20 #define JSON_HAS_CPP_17 #define JSON_HAS_CPP_14 #elif (defined(__cplusplus) && __cplusplus > 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG > 201703L) #define JSON_HAS_CPP_20 #define JSON_HAS_CPP_17 #define JSON_HAS_CPP_14 #elif (defined(__cplusplus) && __cplusplus > 201402L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 #define JSON_HAS_CPP_17 #define JSON_HAS_CPP_14 #elif (defined(__cplusplus) && __cplusplus > 201103L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) #define JSON_HAS_CPP_14 #endif // the cpp 11 flag is always specified because it is the minimal required version #define JSON_HAS_CPP_11 #endif #ifdef __has_include #if __has_include() #include #endif #endif #if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM) #ifdef JSON_HAS_CPP_17 #if defined(__cpp_lib_filesystem) #define JSON_HAS_FILESYSTEM 1 #elif defined(__cpp_lib_experimental_filesystem) #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 #elif !defined(__has_include) #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 #elif __has_include() #define JSON_HAS_FILESYSTEM 1 #elif __has_include() #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 #endif // std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/ #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8 #undef JSON_HAS_FILESYSTEM #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM #endif // no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8 #undef JSON_HAS_FILESYSTEM #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM #endif // no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support #if defined(__clang_major__) && __clang_major__ < 7 #undef JSON_HAS_FILESYSTEM #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM #endif // no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support #if defined(_MSC_VER) && _MSC_VER < 1914 #undef JSON_HAS_FILESYSTEM #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM #endif // no filesystem support before iOS 13 #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 #undef JSON_HAS_FILESYSTEM #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM #endif // no filesystem support before macOS Catalina #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 #undef JSON_HAS_FILESYSTEM #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM #endif #endif #endif #ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0 #endif #ifndef JSON_HAS_FILESYSTEM #define JSON_HAS_FILESYSTEM 0 #endif #ifndef JSON_HAS_THREE_WAY_COMPARISON #if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L \ && defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L #define JSON_HAS_THREE_WAY_COMPARISON 1 #else #define JSON_HAS_THREE_WAY_COMPARISON 0 #endif #endif #ifndef JSON_HAS_RANGES // ranges header shipping in GCC 11.1.0 (released 2021-04-27) has a syntax error #if defined(__GLIBCXX__) && __GLIBCXX__ == 20210427 #define JSON_HAS_RANGES 0 #elif defined(__cpp_lib_ranges) #define JSON_HAS_RANGES 1 #else #define JSON_HAS_RANGES 0 #endif #endif #ifndef JSON_HAS_STATIC_RTTI #if !defined(_HAS_STATIC_RTTI) || _HAS_STATIC_RTTI != 0 #define JSON_HAS_STATIC_RTTI 1 #else #define JSON_HAS_STATIC_RTTI 0 #endif #endif #ifdef JSON_HAS_CPP_17 #define JSON_INLINE_VARIABLE inline #else #define JSON_INLINE_VARIABLE #endif #if JSON_HEDLEY_HAS_ATTRIBUTE(no_unique_address) #define JSON_NO_UNIQUE_ADDRESS [[no_unique_address]] #else #define JSON_NO_UNIQUE_ADDRESS #endif // disable documentation warnings on clang #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdocumentation" #pragma clang diagnostic ignored "-Wdocumentation-unknown-command" #endif // allow disabling exceptions #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION) #define JSON_THROW(exception) throw exception #define JSON_TRY try #define JSON_CATCH(exception) catch(exception) #define JSON_INTERNAL_CATCH(exception) catch(exception) #else #include #define JSON_THROW(exception) std::abort() #define JSON_TRY if(true) #define JSON_CATCH(exception) if(false) #define JSON_INTERNAL_CATCH(exception) if(false) #endif // override exception macros #if defined(JSON_THROW_USER) #undef JSON_THROW #define JSON_THROW JSON_THROW_USER #endif #if defined(JSON_TRY_USER) #undef JSON_TRY #define JSON_TRY JSON_TRY_USER #endif #if defined(JSON_CATCH_USER) #undef JSON_CATCH #define JSON_CATCH JSON_CATCH_USER #undef JSON_INTERNAL_CATCH #define JSON_INTERNAL_CATCH JSON_CATCH_USER #endif #if defined(JSON_INTERNAL_CATCH_USER) #undef JSON_INTERNAL_CATCH #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER #endif // allow overriding assert #if !defined(JSON_ASSERT) #include // assert #define JSON_ASSERT(x) assert(x) #endif // allow accessing some private functions (needed by the test suite) #if defined(JSON_TESTS_PRIVATE) #define JSON_PRIVATE_UNLESS_TESTED public #else #define JSON_PRIVATE_UNLESS_TESTED private #endif /*! @brief macro to briefly define a mapping between an enum and JSON @def NLOHMANN_JSON_SERIALIZE_ENUM @since version 3.4.0 */ #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \ template \ inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \ { \ /* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \ static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ /* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on */ \ static const std::pair m[] = __VA_ARGS__; \ auto it = std::find_if(std::begin(m), std::end(m), \ [e](const std::pair& ej_pair) -> bool \ { \ return ej_pair.first == e; \ }); \ j = ((it != std::end(m)) ? it : std::begin(m))->second; \ } \ template \ inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \ { \ /* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \ static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ /* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on */ \ static const std::pair m[] = __VA_ARGS__; \ auto it = std::find_if(std::begin(m), std::end(m), \ [&j](const std::pair& ej_pair) -> bool \ { \ return ej_pair.second == j; \ }); \ e = ((it != std::end(m)) ? it : std::begin(m))->first; \ } // Ugly macros to avoid uglier copy-paste when specializing basic_json. They // may be removed in the future once the class is split. #define NLOHMANN_BASIC_JSON_TPL_DECLARATION \ template class ObjectType, \ template class ArrayType, \ class StringType, class BooleanType, class NumberIntegerType, \ class NumberUnsignedType, class NumberFloatType, \ template class AllocatorType, \ template class JSONSerializer, \ class BinaryType, \ class CustomBaseClass> #define NLOHMANN_BASIC_JSON_TPL \ basic_json // Macros to simplify conversion from/to types #define NLOHMANN_JSON_EXPAND( x ) x #define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME #define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \ NLOHMANN_JSON_PASTE64, \ NLOHMANN_JSON_PASTE63, \ NLOHMANN_JSON_PASTE62, \ NLOHMANN_JSON_PASTE61, \ NLOHMANN_JSON_PASTE60, \ NLOHMANN_JSON_PASTE59, \ NLOHMANN_JSON_PASTE58, \ NLOHMANN_JSON_PASTE57, \ NLOHMANN_JSON_PASTE56, \ NLOHMANN_JSON_PASTE55, \ NLOHMANN_JSON_PASTE54, \ NLOHMANN_JSON_PASTE53, \ NLOHMANN_JSON_PASTE52, \ NLOHMANN_JSON_PASTE51, \ NLOHMANN_JSON_PASTE50, \ NLOHMANN_JSON_PASTE49, \ NLOHMANN_JSON_PASTE48, \ NLOHMANN_JSON_PASTE47, \ NLOHMANN_JSON_PASTE46, \ NLOHMANN_JSON_PASTE45, \ NLOHMANN_JSON_PASTE44, \ NLOHMANN_JSON_PASTE43, \ NLOHMANN_JSON_PASTE42, \ NLOHMANN_JSON_PASTE41, \ NLOHMANN_JSON_PASTE40, \ NLOHMANN_JSON_PASTE39, \ NLOHMANN_JSON_PASTE38, \ NLOHMANN_JSON_PASTE37, \ NLOHMANN_JSON_PASTE36, \ NLOHMANN_JSON_PASTE35, \ NLOHMANN_JSON_PASTE34, \ NLOHMANN_JSON_PASTE33, \ NLOHMANN_JSON_PASTE32, \ NLOHMANN_JSON_PASTE31, \ NLOHMANN_JSON_PASTE30, \ NLOHMANN_JSON_PASTE29, \ NLOHMANN_JSON_PASTE28, \ NLOHMANN_JSON_PASTE27, \ NLOHMANN_JSON_PASTE26, \ NLOHMANN_JSON_PASTE25, \ NLOHMANN_JSON_PASTE24, \ NLOHMANN_JSON_PASTE23, \ NLOHMANN_JSON_PASTE22, \ NLOHMANN_JSON_PASTE21, \ NLOHMANN_JSON_PASTE20, \ NLOHMANN_JSON_PASTE19, \ NLOHMANN_JSON_PASTE18, \ NLOHMANN_JSON_PASTE17, \ NLOHMANN_JSON_PASTE16, \ NLOHMANN_JSON_PASTE15, \ NLOHMANN_JSON_PASTE14, \ NLOHMANN_JSON_PASTE13, \ NLOHMANN_JSON_PASTE12, \ NLOHMANN_JSON_PASTE11, \ NLOHMANN_JSON_PASTE10, \ NLOHMANN_JSON_PASTE9, \ NLOHMANN_JSON_PASTE8, \ NLOHMANN_JSON_PASTE7, \ NLOHMANN_JSON_PASTE6, \ NLOHMANN_JSON_PASTE5, \ NLOHMANN_JSON_PASTE4, \ NLOHMANN_JSON_PASTE3, \ NLOHMANN_JSON_PASTE2, \ NLOHMANN_JSON_PASTE1)(__VA_ARGS__)) #define NLOHMANN_JSON_PASTE2(func, v1) func(v1) #define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2) #define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3) #define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4) #define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5) #define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6) #define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7) #define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8) #define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9) #define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10) #define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) #define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) #define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) #define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) #define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) #define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) #define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) #define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) #define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) #define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) #define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) #define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) #define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) #define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) #define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) #define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) #define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) #define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) #define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) #define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) #define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) #define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) #define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) #define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) #define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) #define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) #define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) #define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) #define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) #define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) #define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) #define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) #define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) #define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) #define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) #define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) #define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) #define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) #define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) #define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) #define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) #define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) #define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) #define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) #define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) #define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) #define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) #define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) #define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) #define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) #define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) #define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) #define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) #define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1; #define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1); #define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = !nlohmann_json_j.is_null() ? nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1) : nlohmann_json_default_obj.v1; /*! @brief macro @def NLOHMANN_DEFINE_TYPE_INTRUSIVE @since version 3.9.0 @sa https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/ */ #define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \ template::value, int> = 0> \ friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ template::value, int> = 0> \ friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } /*! @brief macro @def NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT @since version 3.11.0 @sa https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/ */ #define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \ template::value, int> = 0> \ friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ template::value, int> = 0> \ friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } /*! @brief macro @def NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE @since version 3.11.3 @sa https://json.nlohmann.me/api/macros/nlohmann_define_type_intrusive/ */ #define NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \ template::value, int> = 0> \ friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } /*! @brief macro @def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE @since version 3.9.0 @sa https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/ */ #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \ template::value, int> = 0> \ void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ template::value, int> = 0> \ void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } /*! @brief macro @def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT @since version 3.11.0 @sa https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/ */ #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \ template::value, int> = 0> \ void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ template::value, int> = 0> \ void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } /*! @brief macro @def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE @since version 3.11.3 @sa https://json.nlohmann.me/api/macros/nlohmann_define_type_non_intrusive/ */ #define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \ template::value, int> = 0> \ void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } /*! @brief macro @def NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE @since version 3.12.0 @sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ */ #define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE(Type, BaseType, ...) \ template::value, int> = 0> \ friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ template::value, int> = 0> \ friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } /*! @brief macro @def NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT @since version 3.12.0 @sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ */ #define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_WITH_DEFAULT(Type, BaseType, ...) \ template::value, int> = 0> \ friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ template::value, int> = 0> \ friend void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } /*! @brief macro @def NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE @since version 3.12.0 @sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ */ #define NLOHMANN_DEFINE_DERIVED_TYPE_INTRUSIVE_ONLY_SERIALIZE(Type, BaseType, ...) \ template::value, int> = 0> \ friend void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } /*! @brief macro @def NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE @since version 3.12.0 @sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ */ #define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE(Type, BaseType, ...) \ template::value, int> = 0> \ void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ template::value, int> = 0> \ void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } /*! @brief macro @def NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT @since version 3.12.0 @sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ */ #define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, BaseType, ...) \ template::value, int> = 0> \ void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ template::value, int> = 0> \ void from_json(const BasicJsonType& nlohmann_json_j, Type& nlohmann_json_t) { nlohmann::from_json(nlohmann_json_j, static_cast(nlohmann_json_t)); const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } /*! @brief macro @def NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE @since version 3.12.0 @sa https://json.nlohmann.me/api/macros/nlohmann_define_derived_type/ */ #define NLOHMANN_DEFINE_DERIVED_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(Type, BaseType, ...) \ template::value, int> = 0> \ void to_json(BasicJsonType& nlohmann_json_j, const Type& nlohmann_json_t) { nlohmann::to_json(nlohmann_json_j, static_cast(nlohmann_json_t)); NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } // inspired from https://stackoverflow.com/a/26745591 // allows calling any std function as if (e.g., with begin): // using std::begin; begin(x); // // it allows using the detected idiom to retrieve the return type // of such an expression #define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \ namespace detail { \ using std::std_name; \ \ template \ using result_of_##std_name = decltype(std_name(std::declval()...)); \ } \ \ namespace detail2 { \ struct std_name##_tag \ { \ }; \ \ template \ std_name##_tag std_name(T&&...); \ \ template \ using result_of_##std_name = decltype(std_name(std::declval()...)); \ \ template \ struct would_call_std_##std_name \ { \ static constexpr auto const value = ::nlohmann::detail:: \ is_detected_exact::value; \ }; \ } /* namespace detail2 */ \ \ template \ struct would_call_std_##std_name : detail2::would_call_std_##std_name \ { \ } #ifndef JSON_USE_IMPLICIT_CONVERSIONS #define JSON_USE_IMPLICIT_CONVERSIONS 1 #endif #if JSON_USE_IMPLICIT_CONVERSIONS #define JSON_EXPLICIT #else #define JSON_EXPLICIT explicit #endif #ifndef JSON_DISABLE_ENUM_SERIALIZATION #define JSON_DISABLE_ENUM_SERIALIZATION 0 #endif #ifndef JSON_USE_GLOBAL_UDLS #define JSON_USE_GLOBAL_UDLS 1 #endif #if JSON_HAS_THREE_WAY_COMPARISON #include // partial_ordering #endif NLOHMANN_JSON_NAMESPACE_BEGIN namespace detail { /////////////////////////// // JSON type enumeration // /////////////////////////// /*! @brief the JSON type enumeration This enumeration collects the different JSON types. It is internally used to distinguish the stored values, and the functions @ref basic_json::is_null(), @ref basic_json::is_object(), @ref basic_json::is_array(), @ref basic_json::is_string(), @ref basic_json::is_boolean(), @ref basic_json::is_number() (with @ref basic_json::is_number_integer(), @ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()), @ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and @ref basic_json::is_structured() rely on it. @note There are three enumeration entries (number_integer, number_unsigned, and number_float), because the library distinguishes these three types for numbers: @ref basic_json::number_unsigned_t is used for unsigned integers, @ref basic_json::number_integer_t is used for signed integers, and @ref basic_json::number_float_t is used for floating-point numbers or to approximate integers which do not fit in the limits of their respective type. @sa see @ref basic_json::basic_json(const value_t value_type) -- create a JSON value with the default value for a given type @since version 1.0.0 */ enum class value_t : std::uint8_t { null, ///< null value object, ///< object (unordered set of name/value pairs) array, ///< array (ordered collection of values) string, ///< string value boolean, ///< boolean value number_integer, ///< number value (signed integer) number_unsigned, ///< number value (unsigned integer) number_float, ///< number value (floating-point) binary, ///< binary array (ordered collection of bytes) discarded ///< discarded by the parser callback function }; /*! @brief comparison operator for JSON types Returns an ordering that is similar to Python: - order: null < boolean < number < object < array < string < binary - furthermore, each type is not smaller than itself - discarded values are not comparable - binary is represented as a b"" string in python and directly comparable to a string; however, making a binary array directly comparable with a string would be surprising behavior in a JSON file. @since version 1.0.0 */ #if JSON_HAS_THREE_WAY_COMPARISON inline std::partial_ordering operator<=>(const value_t lhs, const value_t rhs) noexcept // *NOPAD* #else inline bool operator<(const value_t lhs, const value_t rhs) noexcept #endif { static constexpr std::array order = {{ 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */, 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */, 6 /* binary */ } }; const auto l_index = static_cast(lhs); const auto r_index = static_cast(rhs); #if JSON_HAS_THREE_WAY_COMPARISON if (l_index < order.size() && r_index < order.size()) { return order[l_index] <=> order[r_index]; // *NOPAD* } return std::partial_ordering::unordered; #else return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index]; #endif } // GCC selects the built-in operator< over an operator rewritten from // a user-defined spaceship operator // Clang, MSVC, and ICC select the rewritten candidate // (see GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105200) #if JSON_HAS_THREE_WAY_COMPARISON && defined(__GNUC__) inline bool operator<(const value_t lhs, const value_t rhs) noexcept { return std::is_lt(lhs <=> rhs); // *NOPAD* } #endif } // namespace detail NLOHMANN_JSON_NAMESPACE_END // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT // #include NLOHMANN_JSON_NAMESPACE_BEGIN namespace detail { /*! @brief replace all occurrences of a substring by another string @param[in,out] s the string to manipulate; changed so that all occurrences of @a f are replaced with @a t @param[in] f the substring to replace with @a t @param[in] t the string to replace @a f @pre The search string @a f must not be empty. **This precondition is enforced with an assertion.** @since version 2.0.0 */ template inline void replace_substring(StringType& s, const StringType& f, const StringType& t) { JSON_ASSERT(!f.empty()); for (auto pos = s.find(f); // find the first occurrence of f pos != StringType::npos; // make sure f was found s.replace(pos, f.size(), t), // replace with t, and pos = s.find(f, pos + t.size())) // find the next occurrence of f {} } /*! * @brief string escaping as described in RFC 6901 (Sect. 4) * @param[in] s string to escape * @return escaped string * * Note the order of escaping "~" to "~0" and "/" to "~1" is important. */ template inline StringType escape(StringType s) { replace_substring(s, StringType{"~"}, StringType{"~0"}); replace_substring(s, StringType{"/"}, StringType{"~1"}); return s; } /*! * @brief string unescaping as described in RFC 6901 (Sect. 4) * @param[in] s string to unescape * @return unescaped string * * Note the order of escaping "~1" to "/" and "~0" to "~" is important. */ template inline void unescape(StringType& s) { replace_substring(s, StringType{"~1"}, StringType{"/"}); replace_substring(s, StringType{"~0"}, StringType{"~"}); } } // namespace detail NLOHMANN_JSON_NAMESPACE_END // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT #include // size_t // #include NLOHMANN_JSON_NAMESPACE_BEGIN namespace detail { /// struct to capture the start position of the current token struct position_t { /// the total number of characters read std::size_t chars_read_total = 0; /// the number of characters read in the current line std::size_t chars_read_current_line = 0; /// the number of lines read std::size_t lines_read = 0; /// conversion to size_t to preserve SAX interface constexpr operator size_t() const { return chars_read_total; } }; } // namespace detail NLOHMANN_JSON_NAMESPACE_END // #include // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-FileCopyrightText: 2018 The Abseil Authors // SPDX-License-Identifier: MIT #include // array #include // size_t #include // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type #include // index_sequence, make_index_sequence, index_sequence_for // #include NLOHMANN_JSON_NAMESPACE_BEGIN namespace detail { template using uncvref_t = typename std::remove_cv::type>::type; #ifdef JSON_HAS_CPP_14 // the following utilities are natively available in C++14 using std::enable_if_t; using std::index_sequence; using std::make_index_sequence; using std::index_sequence_for; #else // alias templates to reduce boilerplate template using enable_if_t = typename std::enable_if::type; // The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h // which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0. //// START OF CODE FROM GOOGLE ABSEIL // integer_sequence // // Class template representing a compile-time integer sequence. An instantiation // of `integer_sequence` has a sequence of integers encoded in its // type through its template arguments (which is a common need when // working with C++11 variadic templates). `absl::integer_sequence` is designed // to be a drop-in replacement for C++14's `std::integer_sequence`. // // Example: // // template< class T, T... Ints > // void user_function(integer_sequence); // // int main() // { // // user_function's `T` will be deduced to `int` and `Ints...` // // will be deduced to `0, 1, 2, 3, 4`. // user_function(make_integer_sequence()); // } template struct integer_sequence { using value_type = T; static constexpr std::size_t size() noexcept { return sizeof...(Ints); } }; // index_sequence // // A helper template for an `integer_sequence` of `size_t`, // `absl::index_sequence` is designed to be a drop-in replacement for C++14's // `std::index_sequence`. template using index_sequence = integer_sequence; namespace utility_internal { template struct Extend; // Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency. template struct Extend, SeqSize, 0> { using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >; }; template struct Extend, SeqSize, 1> { using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >; }; // Recursion helper for 'make_integer_sequence'. // 'Gen::type' is an alias for 'integer_sequence'. template struct Gen { using type = typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type; }; template struct Gen { using type = integer_sequence; }; } // namespace utility_internal // Compile-time sequences of integers // make_integer_sequence // // This template alias is equivalent to // `integer_sequence`, and is designed to be a drop-in // replacement for C++14's `std::make_integer_sequence`. template using make_integer_sequence = typename utility_internal::Gen::type; // make_index_sequence // // This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`, // and is designed to be a drop-in replacement for C++14's // `std::make_index_sequence`. template using make_index_sequence = make_integer_sequence; // index_sequence_for // // Converts a typename pack into an index sequence of the same length, and // is designed to be a drop-in replacement for C++14's // `std::index_sequence_for()` template using index_sequence_for = make_index_sequence; //// END OF CODE FROM GOOGLE ABSEIL #endif // dispatch utility (taken from ranges-v3) template struct priority_tag : priority_tag < N - 1 > {}; template<> struct priority_tag<0> {}; // taken from ranges-v3 template struct static_const { static JSON_INLINE_VARIABLE constexpr T value{}; }; #ifndef JSON_HAS_CPP_17 template constexpr T static_const::value; #endif template constexpr std::array make_array(Args&& ... args) { return std::array {{static_cast(std::forward(args))...}}; } } // namespace detail NLOHMANN_JSON_NAMESPACE_END // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT #include // numeric_limits #include // char_traits #include // tuple #include // false_type, is_constructible, is_integral, is_same, true_type #include // declval #if defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603L #include // byte #endif // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT #include // random_access_iterator_tag // #include // #include // #include NLOHMANN_JSON_NAMESPACE_BEGIN namespace detail { template struct iterator_types {}; template struct iterator_types < It, void_t> { using difference_type = typename It::difference_type; using value_type = typename It::value_type; using pointer = typename It::pointer; using reference = typename It::reference; using iterator_category = typename It::iterator_category; }; // This is required as some compilers implement std::iterator_traits in a way that // doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341. template struct iterator_traits { }; template struct iterator_traits < T, enable_if_t < !std::is_pointer::value >> : iterator_types { }; template struct iterator_traits::value>> { using iterator_category = std::random_access_iterator_tag; using value_type = T; using difference_type = ptrdiff_t; using pointer = T*; using reference = T&; }; } // namespace detail NLOHMANN_JSON_NAMESPACE_END // #include // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT // #include NLOHMANN_JSON_NAMESPACE_BEGIN NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin); NLOHMANN_JSON_NAMESPACE_END // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT // #include NLOHMANN_JSON_NAMESPACE_BEGIN NLOHMANN_CAN_CALL_STD_FUNC_IMPL(end); NLOHMANN_JSON_NAMESPACE_END // #include // #include // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 // |_____|_____|_____|_|___| https://github.com/nlohmann/json // // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT #ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_ #define INCLUDE_NLOHMANN_JSON_FWD_HPP_ #include // int64_t, uint64_t #include // map #include // allocator #include // string #include // vector // #include /*! @brief namespace for Niels Lohmann @see https://github.com/nlohmann @since version 1.0.0 */ NLOHMANN_JSON_NAMESPACE_BEGIN /*! @brief default JSONSerializer template argument This serializer ignores the template arguments and uses ADL ([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl)) for serialization. */ template struct adl_serializer; /// a class to store JSON values /// @sa https://json.nlohmann.me/api/basic_json/ template class ObjectType = std::map, template class ArrayType = std::vector, class StringType = std::string, class BooleanType = bool, class NumberIntegerType = std::int64_t, class NumberUnsignedType = std::uint64_t, class NumberFloatType = double, template class AllocatorType = std::allocator, template class JSONSerializer = adl_serializer, class BinaryType = std::vector, // cppcheck-suppress syntaxError class CustomBaseClass = void> class basic_json; /// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document /// @sa https://json.nlohmann.me/api/json_pointer/ template class json_pointer; /*! @brief default specialization @sa https://json.nlohmann.me/api/json/ */ using json = basic_json<>; /// @brief a minimal map-like container that preserves insertion order /// @sa https://json.nlohmann.me/api/ordered_map/ template struct ordered_map; /// @brief specialization that maintains the insertion order of object keys /// @sa https://json.nlohmann.me/api/ordered_json/ using ordered_json = basic_json; NLOHMANN_JSON_NAMESPACE_END #endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_ NLOHMANN_JSON_NAMESPACE_BEGIN /*! @brief detail namespace with internal helper functions This namespace collects functions that should not be exposed, implementations of some @ref basic_json methods, and meta-programming helpers. @since version 2.1.0 */ namespace detail { ///////////// // helpers // ///////////// // Note to maintainers: // // Every trait in this file expects a non-CV-qualified type. // The only exceptions are in the 'aliases for detected' section // (i.e., those of the form: decltype(T::member_function(std::declval()))) // // In this case, T has to be properly CV-qualified to constraint the function arguments // (e.g., to_json(BasicJsonType&, const T&)) template struct is_basic_json : std::false_type {}; NLOHMANN_BASIC_JSON_TPL_DECLARATION struct is_basic_json : std::true_type {}; // used by exceptions create() member functions // true_type for the pointer to possibly cv-qualified basic_json or std::nullptr_t // false_type otherwise template struct is_basic_json_context : std::integral_constant < bool, is_basic_json::type>::type>::value || std::is_same::value > {}; ////////////////////// // json_ref helpers // ////////////////////// template class json_ref; template struct is_json_ref : std::false_type {}; template struct is_json_ref> : std::true_type {}; ////////////////////////// // aliases for detected // ////////////////////////// template using mapped_type_t = typename T::mapped_type; template using key_type_t = typename T::key_type; template using value_type_t = typename T::value_type; template using difference_type_t = typename T::difference_type; template using pointer_t = typename T::pointer; template using reference_t = typename T::reference; template using iterator_category_t = typename T::iterator_category; template using to_json_function = decltype(T::to_json(std::declval()...)); template using from_json_function = decltype(T::from_json(std::declval()...)); template using get_template_function = decltype(std::declval().template get()); // trait checking if JSONSerializer::from_json(json const&, udt&) exists template struct has_from_json : std::false_type {}; // trait checking if j.get is valid // use this trait instead of std::is_constructible or std::is_convertible, // both rely on, or make use of implicit conversions, and thus fail when T // has several constructors/operator= (see https://github.com/nlohmann/json/issues/958) template struct is_getable { static constexpr bool value = is_detected::value; }; template struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> { using serializer = typename BasicJsonType::template json_serializer; static constexpr bool value = is_detected_exact::value; }; // This trait checks if JSONSerializer::from_json(json const&) exists // this overload is used for non-default-constructible user-defined-types template struct has_non_default_from_json : std::false_type {}; template struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> { using serializer = typename BasicJsonType::template json_serializer; static constexpr bool value = is_detected_exact::value; }; // This trait checks if BasicJsonType::json_serializer::to_json exists // Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion. template struct has_to_json : std::false_type {}; template struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> { using serializer = typename BasicJsonType::template json_serializer; static constexpr bool value = is_detected_exact::value; }; template using detect_key_compare = typename T::key_compare; template struct has_key_compare : std::integral_constant::value> {}; // obtains the actual object key comparator template struct actual_object_comparator { using object_t = typename BasicJsonType::object_t; using object_comparator_t = typename BasicJsonType::default_object_comparator_t; using type = typename std::conditional < has_key_compare::value, typename object_t::key_compare, object_comparator_t>::type; }; template using actual_object_comparator_t = typename actual_object_comparator::type; ///////////////// // char_traits // ///////////////// // Primary template of char_traits calls std char_traits template struct char_traits : std::char_traits {}; // Explicitly define char traits for unsigned char since it is not standard template<> struct char_traits : std::char_traits { using char_type = unsigned char; using int_type = uint64_t; // Redefine to_int_type function static int_type to_int_type(char_type c) noexcept { return static_cast(c); } static char_type to_char_type(int_type i) noexcept { return static_cast(i); } static constexpr int_type eof() noexcept { return static_cast(std::char_traits::eof()); } }; // Explicitly define char traits for signed char since it is not standard template<> struct char_traits : std::char_traits { using char_type = signed char; using int_type = uint64_t; // Redefine to_int_type function static int_type to_int_type(char_type c) noexcept { return static_cast(c); } static char_type to_char_type(int_type i) noexcept { return static_cast(i); } static constexpr int_type eof() noexcept { return static_cast(std::char_traits::eof()); } }; #if defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603L template<> struct char_traits : std::char_traits { using char_type = std::byte; using int_type = uint64_t; static int_type to_int_type(char_type c) noexcept { return static_cast(std::to_integer(c)); } static char_type to_char_type(int_type i) noexcept { return std::byte(static_cast(i)); } static constexpr int_type eof() noexcept { return static_cast(std::char_traits::eof()); } }; #endif /////////////////// // is_ functions // /////////////////// // https://en.cppreference.com/w/cpp/types/conjunction template struct conjunction : std::true_type { }; template struct conjunction : B { }; template struct conjunction : std::conditional(B::value), conjunction, B>::type {}; // https://en.cppreference.com/w/cpp/types/negation template struct negation : std::integral_constant < bool, !B::value > { }; // Reimplementation of is_constructible and is_default_constructible, due to them being broken for // std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367). // This causes compile errors in e.g., Clang 3.5 or GCC 4.9. template struct is_default_constructible : std::is_default_constructible {}; template struct is_default_constructible> : conjunction, is_default_constructible> {}; template struct is_default_constructible> : conjunction, is_default_constructible> {}; template struct is_default_constructible> : conjunction...> {}; template struct is_default_constructible> : conjunction...> {}; template struct is_constructible : std::is_constructible {}; template struct is_constructible> : is_default_constructible> {}; template struct is_constructible> : is_default_constructible> {}; template struct is_constructible> : is_default_constructible> {}; template struct is_constructible> : is_default_constructible> {}; template struct is_iterator_traits : std::false_type {}; template struct is_iterator_traits> { private: using traits = iterator_traits; public: static constexpr auto value = is_detected::value && is_detected::value && is_detected::value && is_detected::value && is_detected::value; }; template struct is_range { private: using t_ref = typename std::add_lvalue_reference::type; using iterator = detected_t; using sentinel = detected_t; // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator // and https://en.cppreference.com/w/cpp/iterator/sentinel_for // but reimplementing these would be too much work, as a lot of other concepts are used underneath static constexpr auto is_iterator_begin = is_iterator_traits>::value; public: static constexpr bool value = !std::is_same::value && !std::is_same::value && is_iterator_begin; }; template using iterator_t = enable_if_t::value, result_of_begin())>>; template using range_value_t = value_type_t>>; // The following implementation of is_complete_type is taken from // https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/ // and is written by Xiang Fan who agreed to use it in this library. template struct is_complete_type : std::false_type {}; template struct is_complete_type : std::true_type {}; template struct is_compatible_object_type_impl : std::false_type {}; template struct is_compatible_object_type_impl < BasicJsonType, CompatibleObjectType, enable_if_t < is_detected::value&& is_detected::value >> { using object_t = typename BasicJsonType::object_t; // macOS's is_constructible does not play well with nonesuch... static constexpr bool value = is_constructible::value && is_constructible::value; }; template struct is_compatible_object_type : is_compatible_object_type_impl {}; template struct is_constructible_object_type_impl : std::false_type {}; template struct is_constructible_object_type_impl < BasicJsonType, ConstructibleObjectType, enable_if_t < is_detected::value&& is_detected::value >> { using object_t = typename BasicJsonType::object_t; static constexpr bool value = (is_default_constructible::value && (std::is_move_assignable::value || std::is_copy_assignable::value) && (is_constructible::value && std::is_same < typename object_t::mapped_type, typename ConstructibleObjectType::mapped_type >::value)) || (has_from_json::value || has_non_default_from_json < BasicJsonType, typename ConstructibleObjectType::mapped_type >::value); }; template struct is_constructible_object_type : is_constructible_object_type_impl {}; template struct is_compatible_string_type { static constexpr auto value = is_constructible::value; }; template struct is_constructible_string_type { // launder type through decltype() to fix compilation failure on ICPC #ifdef __INTEL_COMPILER using laundered_type = decltype(std::declval()); #else using laundered_type = ConstructibleStringType; #endif static constexpr auto value = conjunction < is_constructible, is_detected_exact>::value; }; template struct is_compatible_array_type_impl : std::false_type {}; template struct is_compatible_array_type_impl < BasicJsonType, CompatibleArrayType, enable_if_t < is_detected::value&& is_iterator_traits>>::value&& // special case for types like std::filesystem::path whose iterator's value_type are themselves // c.f. https://github.com/nlohmann/json/pull/3073 !std::is_same>::value >> { static constexpr bool value = is_constructible>::value; }; template struct is_compatible_array_type : is_compatible_array_type_impl {}; template struct is_constructible_array_type_impl : std::false_type {}; template struct is_constructible_array_type_impl < BasicJsonType, ConstructibleArrayType, enable_if_t::value >> : std::true_type {}; template struct is_constructible_array_type_impl < BasicJsonType, ConstructibleArrayType, enable_if_t < !std::is_same::value&& !is_compatible_string_type::value&& is_default_constructible::value&& (std::is_move_assignable::value || std::is_copy_assignable::value)&& is_detected::value&& is_iterator_traits>>::value&& is_detected::value&& // special case for types like std::filesystem::path whose iterator's value_type are themselves // c.f. https://github.com/nlohmann/json/pull/3073 !std::is_same>::value&& is_complete_type < detected_t>::value >> { using value_type = range_value_t; static constexpr bool value = std::is_same::value || has_from_json::value || has_non_default_from_json < BasicJsonType, value_type >::value; }; template struct is_constructible_array_type : is_constructible_array_type_impl {}; template struct is_compatible_integer_type_impl : std::false_type {}; template struct is_compatible_integer_type_impl < RealIntegerType, CompatibleNumberIntegerType, enable_if_t < std::is_integral::value&& std::is_integral::value&& !std::is_same::value >> { // is there an assert somewhere on overflows? using RealLimits = std::numeric_limits; using CompatibleLimits = std::numeric_limits; static constexpr auto value = is_constructible::value && CompatibleLimits::is_integer && RealLimits::is_signed == CompatibleLimits::is_signed; }; template struct is_compatible_integer_type : is_compatible_integer_type_impl {}; template struct is_compatible_type_impl: std::false_type {}; template struct is_compatible_type_impl < BasicJsonType, CompatibleType, enable_if_t::value >> { static constexpr bool value = has_to_json::value; }; template struct is_compatible_type : is_compatible_type_impl {}; template struct is_constructible_tuple : std::false_type {}; template struct is_constructible_tuple> : conjunction...> {}; template struct is_json_iterator_of : std::false_type {}; template struct is_json_iterator_of : std::true_type {}; template struct is_json_iterator_of : std::true_type {}; // checks if a given type T is a template specialization of Primary template