Imported Upstream version 1.7.7 upstream/1.7.7
authorDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 18 Jan 2022 02:15:06 +0000 (11:15 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 18 Jan 2022 02:15:06 +0000 (11:15 +0900)
67 files changed:
NEWS
configure
configure.ac
ltmain.sh
m4/libtool.m4
src/bin/Makefile.am
src/bin/fstequivalent-main.cc
src/bin/fstequivalent.cc
src/bin/fstrandgen-main.cc
src/bin/fstrandgen.cc
src/extensions/compact/Makefile.am
src/extensions/compact/Makefile.in
src/extensions/compress/Makefile.am
src/extensions/compress/Makefile.in
src/extensions/const/Makefile.am
src/extensions/const/Makefile.in
src/extensions/far/Makefile.am
src/extensions/far/Makefile.in
src/extensions/linear/Makefile.am
src/extensions/linear/Makefile.in
src/extensions/lookahead/Makefile.am
src/extensions/lookahead/Makefile.in
src/extensions/mpdt/Makefile.am
src/extensions/mpdt/Makefile.in
src/extensions/ngram/Makefile.am
src/extensions/ngram/Makefile.in
src/extensions/ngram/nthbit.cc
src/extensions/pdt/Makefile.am
src/extensions/pdt/Makefile.in
src/extensions/python/Makefile.am
src/extensions/python/Makefile.in
src/extensions/python/cintegral_types.pxd [moved from src/extensions/python/basictypes.pxd with 100% similarity]
src/extensions/python/cios.pxd [moved from src/extensions/python/ios.pxd with 77% similarity]
src/extensions/python/cpywrapfst.pxd
src/extensions/python/cutility.pxd [moved from src/extensions/python/utility.pxd with 100% similarity]
src/extensions/python/pywrapfst.pxd
src/extensions/python/pywrapfst.pyx
src/extensions/special/Makefile.am
src/extensions/special/Makefile.in
src/include/fst/arc-map.h
src/include/fst/config.h
src/include/fst/config.h.in
src/include/fst/const-fst.h
src/include/fst/edit-fst.h
src/include/fst/equal.h
src/include/fst/extensions/compress/compress.h
src/include/fst/extensions/far/far-class.h
src/include/fst/extensions/ngram/nthbit.h
src/include/fst/flags.h
src/include/fst/fst.h
src/include/fst/properties.h
src/include/fst/randequivalent.h
src/include/fst/randgen.h
src/include/fst/script/randequivalent.h
src/include/fst/script/randgen.h
src/include/fst/string.h
src/include/fst/test-properties.h
src/include/fst/test/algo_test.h
src/include/fst/vector-fst.h
src/include/fst/verify.h
src/lib/Makefile.am
src/lib/Makefile.in
src/lib/flags.cc
src/script/Makefile.am
src/script/Makefile.in
src/script/randequivalent.cc
src/script/randgen.cc

diff --git a/NEWS b/NEWS
index fe0577b..305aa35 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,6 @@
 OpenFst: Release 1.7
+   * Property testing is now thread-safe (1.7.7)
+   * Modernizes random generation (1.7.7)
    * Adds MakeArcMapFst (1.7.6)
    * Adds RealWeight and Real64Weight (1.7.6)
    * Adds a new, idiomatic SymbolTable iterator interface (1.7.6)
index 58f0e43..5df6f05 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for OpenFst 1.7.6.
+# Generated by GNU Autoconf 2.69 for OpenFst 1.7.7.
 #
 # Report bugs to <help@www.openfst.org>.
 #
@@ -590,8 +590,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='OpenFst'
 PACKAGE_TARNAME='openfst'
-PACKAGE_VERSION='1.7.6'
-PACKAGE_STRING='OpenFst 1.7.6'
+PACKAGE_VERSION='1.7.7'
+PACKAGE_STRING='OpenFst 1.7.7'
 PACKAGE_BUGREPORT='help@www.openfst.org'
 PACKAGE_URL=''
 
@@ -1398,7 +1398,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures OpenFst 1.7.6 to adapt to many kinds of systems.
+\`configure' configures OpenFst 1.7.7 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1469,7 +1469,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of OpenFst 1.7.6:";;
+     short | recursive ) echo "Configuration of OpenFst 1.7.7:";;
    esac
   cat <<\_ACEOF
 
@@ -1602,7 +1602,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-OpenFst configure 1.7.6
+OpenFst configure 1.7.7
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2043,7 +2043,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by OpenFst $as_me 1.7.6, which was
+It was created by OpenFst $as_me 1.7.7, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2906,7 +2906,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='openfst'
- VERSION='1.7.6'
+ VERSION='1.7.7'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -4598,7 +4598,7 @@ fi
 
 # This library does not throw exceptions, so we do not generate exception
 # handling code. However, users are free to re-enable exception handling.
-CXX="$CXX -std=c++17 -fno-exceptions"
+CXX="$CXX -std=c++11 -fno-exceptions"
 
 # Check whether --enable-static was given.
 if test "${enable_static+set}" = set; then :
@@ -5940,7 +5940,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
-netbsd* | netbsdelf*-gnu)
+netbsd*)
   if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
     lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
   else
@@ -6803,8 +6803,11 @@ _LT_EOF
   test $ac_status = 0; }; then
     # Now try to grab the symbols.
     nlist=conftest.nm
-    $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&5
-    if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&5 && test -s "$nlist"; then
+    if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
+  (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s "$nlist"; then
       # Try sorting and uniquifying the output.
       if sort "$nlist" | uniq > "$nlist"T; then
        mv -f "$nlist"T "$nlist"
@@ -9134,12 +9137,6 @@ lt_prog_compiler_static=
        lt_prog_compiler_pic='-KPIC'
        lt_prog_compiler_static='-static'
         ;;
-      # flang / f18. f95 an alias for gfortran or flang on Debian
-      flang* | f18* | f95*)
-       lt_prog_compiler_wl='-Wl,'
-       lt_prog_compiler_pic='-fPIC'
-       lt_prog_compiler_static='-static'
-        ;;
       # icc used to be incompatible with GCC.
       # ICC 10 doesn't accept -KPIC any more.
       icc* | ifort*)
@@ -9616,9 +9613,6 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
   openbsd* | bitrig*)
     with_gnu_ld=no
     ;;
-  linux* | k*bsd*-gnu | gnu*)
-    link_all_deplibs=no
-    ;;
   esac
 
   ld_shlibs=yes
@@ -9873,7 +9867,7 @@ _LT_EOF
       fi
       ;;
 
-    netbsd* | netbsdelf*-gnu)
+    netbsd*)
       if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
        archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
        wlarc=
@@ -10543,7 +10537,6 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
        if test yes = "$lt_cv_irix_exported_symbol"; then
           archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
        fi
-       link_all_deplibs=no
       else
        archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
        archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
@@ -10565,7 +10558,7 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
       esac
       ;;
 
-    netbsd* | netbsdelf*-gnu)
+    netbsd*)
       if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
        archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
       else
   dynamic_linker='GNU/Linux ld.so'
   ;;
 
-netbsdelf*-gnu)
-  version_type=linux
-  need_lib_prefix=no
-  need_version=no
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
-  soname_spec='${libname}${release}${shared_ext}$major'
-  shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=no
-  hardcode_into_libs=yes
-  dynamic_linker='NetBSD ld.elf_so'
-  ;;
-
 netbsd*)
   version_type=sunos
   need_lib_prefix=no
@@ -13082,7 +13063,7 @@ with_gnu_ld=$lt_cv_prog_gnu_ld
       # Commands to make compiler produce verbose output that lists
       # what "hidden" libraries, object files and flags are used when
       # linking a shared library.
-      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
 
     else
       GXX=no
@@ -13574,7 +13555,7 @@ fi
             # explicitly linking system object files so we need to strip them
             # from the output so that they don't get included in the library
             # dependencies.
-            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
             ;;
           *)
             if test yes = "$GXX"; then
@@ -13639,7 +13620,7 @@ fi
            # explicitly linking system object files so we need to strip them
            # from the output so that they don't get included in the library
            # dependencies.
-           output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+           output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
            ;;
           *)
            if test yes = "$GXX"; then
@@ -13978,7 +13959,7 @@ fi
              # Commands to make compiler produce verbose output that lists
              # what "hidden" libraries, object files and flags are used when
              # linking a shared library.
-             output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
+             output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
 
            else
              # FIXME: insert proper C++ library support
@@ -14062,7 +14043,7 @@ fi
                # Commands to make compiler produce verbose output that lists
                # what "hidden" libraries, object files and flags are used when
                # linking a shared library.
-               output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
+               output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
              else
                # g++ 2.7 appears to require '-G' NOT '-shared' on this
                # platform.
@@ -14073,7 +14054,7 @@ fi
                # Commands to make compiler produce verbose output that lists
                # what "hidden" libraries, object files and flags are used when
                # linking a shared library.
-               output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
+               output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
              fi
 
              hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir'
@@ -14586,7 +14567,7 @@ lt_prog_compiler_static_CXX=
            ;;
        esac
        ;;
-      netbsd* | netbsdelf*-gnu)
+      netbsd*)
        ;;
       *qnx* | *nto*)
         # QNX uses GNU C++, but need to define -shared option too, otherwise
@@ -14961,9 +14942,6 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
       ;;
     esac
     ;;
-  linux* | k*bsd*-gnu | gnu*)
-    link_all_deplibs_CXX=no
-    ;;
   *)
     export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
     ;;
   dynamic_linker='GNU/Linux ld.so'
   ;;
 
-netbsdelf*-gnu)
-  version_type=linux
-  need_lib_prefix=no
-  need_version=no
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
-  soname_spec='${libname}${release}${shared_ext}$major'
-  shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=no
-  hardcode_into_libs=yes
-  dynamic_linker='NetBSD ld.elf_so'
-  ;;
-
 netbsd*)
   version_type=sunos
   need_lib_prefix=no
@@ -17584,7 +17550,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by OpenFst $as_me 1.7.6, which was
+This file was extended by OpenFst $as_me 1.7.7, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -17650,7 +17616,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-OpenFst config.status 1.7.6
+OpenFst config.status 1.7.7
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
@@ -18887,6 +18853,7 @@ See \`config.log' for more details" "$LINENO" 5; }
     cat <<_LT_EOF >> "$cfgfile"
 #! $SHELL
 # Generated automatically by $as_me ($PACKAGE) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
 # NOTE: Changes made to this file will be lost: look at ltmain.sh.
 
 # Provide generalized library-building support services.
index 718dd0f..d52ed02 100644 (file)
@@ -1,11 +1,11 @@
-AC_INIT([OpenFst], [1.7.6], [help@www.openfst.org])
+AC_INIT([OpenFst], [1.7.7], [help@www.openfst.org])
 AM_INIT_AUTOMAKE([foreign nostdinc -Wall -Werror subdir-objects])
 AM_PROG_AR
 
 AC_PROG_CXX
 # This library does not throw exceptions, so we do not generate exception
 # handling code. However, users are free to re-enable exception handling.
-CXX="$CXX -std=c++17 -fno-exceptions"
+CXX="$CXX -std=c++11 -fno-exceptions"
 
 AC_DISABLE_STATIC
 AC_PROG_LIBTOOL
index d11f1e0..b6f1800 100644 (file)
--- a/ltmain.sh
+++ b/ltmain.sh
@@ -31,7 +31,7 @@
 
 PROGRAM=libtool
 PACKAGE=libtool
-VERSION="2.4.6 Debian-2.4.6-11"
+VERSION=2.4.6
 package_revision=2.4.6
 
 
@@ -1370,7 +1370,7 @@ func_lt_ver ()
 #! /bin/sh
 
 # Set a version string for this script.
-scriptversion=2015-10-07.11; # UTC
+scriptversion=2014-01-07.03; # UTC
 
 # A portable, pluggable option parser for Bourne shell.
 # Written by Gary V. Vaughan, 2010
@@ -1530,8 +1530,6 @@ func_run_hooks ()
 {
     $debug_cmd
 
-    _G_rc_run_hooks=false
-
     case " $hookable_fns " in
       *" $1 "*) ;;
       *) func_fatal_error "'$1' does not support hook funcions.n" ;;
@@ -1540,16 +1538,16 @@ func_run_hooks ()
     eval _G_hook_fns=\$$1_hooks; shift
 
     for _G_hook in $_G_hook_fns; do
-      if eval $_G_hook '"$@"'; then
-        # store returned options list back into positional
-        # parameters for next 'cmd' execution.
-        eval _G_hook_result=\$${_G_hook}_result
-        eval set dummy "$_G_hook_result"; shift
-        _G_rc_run_hooks=:
-      fi
+      eval $_G_hook '"$@"'
+
+      # store returned options list back into positional
+      # parameters for next 'cmd' execution.
+      eval _G_hook_result=\$${_G_hook}_result
+      eval set dummy "$_G_hook_result"; shift
     done
 
-    $_G_rc_run_hooks && func_run_hooks_result=$_G_hook_result
+    func_quote_for_eval ${1+"$@"}
+    func_run_hooks_result=$func_quote_for_eval_result
 }
 
 
@@ -1559,16 +1557,10 @@ func_run_hooks ()
 ## --------------- ##
 
 # In order to add your own option parsing hooks, you must accept the
-# full positional parameter list in your hook function, you may remove/edit
-# any options that you action, and then pass back the remaining unprocessed
+# full positional parameter list in your hook function, remove any
+# options that you action, and then pass back the remaining unprocessed
 # options in '<hooked_function_name>_result', escaped suitably for
-# 'eval'.  In this case you also must return $EXIT_SUCCESS to let the
-# hook's caller know that it should pay attention to
-# '<hooked_function_name>_result'.  Returning $EXIT_FAILURE signalizes that
-# arguments are left untouched by the hook and therefore caller will ignore the
-# result variable.
-#
-# Like this:
+# 'eval'.  Like this:
 #
 #    my_options_prep ()
 #    {
@@ -1578,11 +1570,9 @@ func_run_hooks ()
 #        usage_message=$usage_message'
 #      -s, --silent       don'\''t print informational messages
 #    '
-#        # No change in '$@' (ignored completely by this hook).  There is
-#        # no need to do the equivalent (but slower) action:
-#        # func_quote_for_eval ${1+"$@"}
-#        # my_options_prep_result=$func_quote_for_eval_result
-#        false
+#
+#        func_quote_for_eval ${1+"$@"}
+#        my_options_prep_result=$func_quote_for_eval_result
 #    }
 #    func_add_hook func_options_prep my_options_prep
 #
@@ -1591,37 +1581,25 @@ func_run_hooks ()
 #    {
 #        $debug_cmd
 #
-#        args_changed=false
-#
 #        # Note that for efficiency, we parse as many options as we can
 #        # recognise in a loop before passing the remainder back to the
 #        # caller on the first unrecognised argument we encounter.
 #        while test $# -gt 0; do
 #          opt=$1; shift
 #          case $opt in
-#            --silent|-s) opt_silent=:
-#                         args_changed=:
-#                         ;;
+#            --silent|-s) opt_silent=: ;;
 #            # Separate non-argument short options:
 #            -s*)         func_split_short_opt "$_G_opt"
 #                         set dummy "$func_split_short_opt_name" \
 #                             "-$func_split_short_opt_arg" ${1+"$@"}
 #                         shift
-#                         args_changed=:
 #                         ;;
-#            *)           # Make sure the first unrecognised option "$_G_opt"
-#                         # is added back to "$@", we could need that later
-#                         # if $args_changed is true.
-#                         set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
+#            *)            set dummy "$_G_opt" "$*"; shift; break ;;
 #          esac
 #        done
 #
-#        if $args_changed; then
-#          func_quote_for_eval ${1+"$@"}
-#          my_silent_option_result=$func_quote_for_eval_result
-#        fi
-#
-#        $args_changed
+#        func_quote_for_eval ${1+"$@"}
+#        my_silent_option_result=$func_quote_for_eval_result
 #    }
 #    func_add_hook func_parse_options my_silent_option
 #
@@ -1633,32 +1611,16 @@ func_run_hooks ()
 #        $opt_silent && $opt_verbose && func_fatal_help "\
 #    '--silent' and '--verbose' options are mutually exclusive."
 #
-#        false
+#        func_quote_for_eval ${1+"$@"}
+#        my_option_validation_result=$func_quote_for_eval_result
 #    }
 #    func_add_hook func_validate_options my_option_validation
 #
-# You'll also need to manually amend $usage_message to reflect the extra
+# You'll alse need to manually amend $usage_message to reflect the extra
 # options you parse.  It's preferable to append if you can, so that
 # multiple option parsing hooks can be added safely.
 
 
-# func_options_finish [ARG]...
-# ----------------------------
-# Finishing the option parse loop (call 'func_options' hooks ATM).
-func_options_finish ()
-{
-    $debug_cmd
-
-    _G_func_options_finish_exit=false
-    if func_run_hooks func_options ${1+"$@"}; then
-      func_options_finish_result=$func_run_hooks_result
-      _G_func_options_finish_exit=:
-    fi
-
-    $_G_func_options_finish_exit
-}
-
-
 # func_options [ARG]...
 # ---------------------
 # All the functions called inside func_options are hookable. See the
@@ -1668,28 +1630,17 @@ func_options ()
 {
     $debug_cmd
 
-    _G_rc_options=false
+    func_options_prep ${1+"$@"}
+    eval func_parse_options \
+        ${func_options_prep_result+"$func_options_prep_result"}
+    eval func_validate_options \
+        ${func_parse_options_result+"$func_parse_options_result"}
 
-    for my_func in options_prep parse_options validate_options options_finish
-    do
-      if eval func_$my_func '${1+"$@"}'; then
-        eval _G_res_var='$'"func_${my_func}_result"
-        eval set dummy "$_G_res_var" ; shift
-        _G_rc_options=:
-      fi
-    done
-
-    # Save modified positional parameters for caller.  As a top-level
-    # options-parser function we always need to set the 'func_options_result'
-    # variable (regardless the $_G_rc_options value).
-    if $_G_rc_options; then
-      func_options_result=$_G_res_var
-    else
-      func_quote_for_eval ${1+"$@"}
-      func_options_result=$func_quote_for_eval_result
-    fi
+    eval func_run_hooks func_options \
+        ${func_validate_options_result+"$func_validate_options_result"}
 
-    $_G_rc_options
+    # save modified positional parameters for caller
+    func_options_result=$func_run_hooks_result
 }
 
 
@@ -1698,9 +1649,9 @@ func_options ()
 # All initialisations required before starting the option parse loop.
 # Note that when calling hook functions, we pass through the list of
 # positional parameters.  If a hook function modifies that list, and
-# needs to propagate that back to rest of this script, then the complete
+# needs to propogate that back to rest of this script, then the complete
 # modified list must be put in 'func_run_hooks_result' before
-# returning $EXIT_SUCCESS (otherwise $EXIT_FAILURE is returned).
+# returning.
 func_hookable func_options_prep
 func_options_prep ()
 {
@@ -1710,14 +1661,10 @@ func_options_prep ()
     opt_verbose=false
     opt_warning_types=
 
-    _G_rc_options_prep=false
-    if func_run_hooks func_options_prep ${1+"$@"}; then
-      _G_rc_options_prep=:
-      # save modified positional parameters for caller
-      func_options_prep_result=$func_run_hooks_result
-    fi
+    func_run_hooks func_options_prep ${1+"$@"}
 
-    $_G_rc_options_prep
+    # save modified positional parameters for caller
+    func_options_prep_result=$func_run_hooks_result
 }
 
 
@@ -1731,20 +1678,18 @@ func_parse_options ()
 
     func_parse_options_result=
 
-    _G_rc_parse_options=false
     # this just eases exit handling
     while test $# -gt 0; do
       # Defer to hook functions for initial option parsing, so they
       # get priority in the event of reusing an option name.
-      if func_run_hooks func_parse_options ${1+"$@"}; then
-        eval set dummy "$func_run_hooks_result"; shift
-        _G_rc_parse_options=:
-      fi
+      func_run_hooks func_parse_options ${1+"$@"}
+
+      # Adjust func_parse_options positional parameters to match
+      eval set dummy "$func_run_hooks_result"; shift
 
       # Break out of the loop if we already parsed every option.
       test $# -gt 0 || break
 
-      _G_match_parse_options=:
       _G_opt=$1
       shift
       case $_G_opt in
@@ -1759,10 +1704,7 @@ func_parse_options ()
                      ;;
 
         --warnings|--warning|-W)
-                      if test $# = 0 && func_missing_arg $_G_opt; then
-                        _G_rc_parse_options=:
-                        break
-                      fi
+                      test $# = 0 && func_missing_arg $_G_opt && break
                       case " $warning_categories $1" in
                         *" $1 "*)
                           # trailing space prevents matching last $1 above
@@ -1815,25 +1757,15 @@ func_parse_options ()
                       shift
                       ;;
 
-        --)           _G_rc_parse_options=: ; break ;;
+        --)           break ;;
         -*)           func_fatal_help "unrecognised option: '$_G_opt'" ;;
-        *)            set dummy "$_G_opt" ${1+"$@"}; shift
-                      _G_match_parse_options=false
-                      break
-                      ;;
+        *)            set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
       esac
-
-      $_G_match_parse_options && _G_rc_parse_options=:
     done
 
-
-    if $_G_rc_parse_options; then
-      # save modified positional parameters for caller
-      func_quote_for_eval ${1+"$@"}
-      func_parse_options_result=$func_quote_for_eval_result
-    fi
-
-    $_G_rc_parse_options
+    # save modified positional parameters for caller
+    func_quote_for_eval ${1+"$@"}
+    func_parse_options_result=$func_quote_for_eval_result
 }
 
 
@@ -1846,21 +1778,16 @@ func_validate_options ()
 {
     $debug_cmd
 
-    _G_rc_validate_options=false
-
     # Display all warnings if -W was not given.
     test -n "$opt_warning_types" || opt_warning_types=" $warning_categories"
 
-    if func_run_hooks func_validate_options ${1+"$@"}; then
-      # save modified positional parameters for caller
-      func_validate_options_result=$func_run_hooks_result
-      _G_rc_validate_options=:
-    fi
+    func_run_hooks func_validate_options ${1+"$@"}
 
     # Bail if the options were screwed!
     $exit_cmd $EXIT_FAILURE
 
-    $_G_rc_validate_options
+    # save modified positional parameters for caller
+    func_validate_options_result=$func_run_hooks_result
 }
 
 
@@ -2141,12 +2068,12 @@ include the following information:
        compiler:       $LTCC
        compiler flags: $LTCFLAGS
        linker:         $LD (gnu? $with_gnu_ld)
-       version:        $progname $scriptversion Debian-2.4.6-11
+       version:        $progname (GNU libtool) 2.4.6
        automake:       `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
        autoconf:       `($AUTOCONF --version) 2>/dev/null |$SED 1q`
 
 Report bugs to <bug-libtool@gnu.org>.
-GNU libtool home page: <http://www.gnu.org/s/libtool/>.
+GNU libtool home page: <http://www.gnu.org/software/libtool/>.
 General help using GNU software: <http://www.gnu.org/gethelp/>."
     exit 0
 }
@@ -2343,8 +2270,6 @@ libtool_options_prep ()
     nonopt=
     preserve_args=
 
-    _G_rc_lt_options_prep=:
-
     # Shorthand for --mode=foo, only valid as the first argument
     case $1 in
     clean|clea|cle|cl)
@@ -2368,18 +2293,11 @@ libtool_options_prep ()
     uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
       shift; set dummy --mode uninstall ${1+"$@"}; shift
       ;;
-    *)
-      _G_rc_lt_options_prep=false
-      ;;
     esac
 
-    if $_G_rc_lt_options_prep; then
-      # Pass back the list of options.
-      func_quote_for_eval ${1+"$@"}
-      libtool_options_prep_result=$func_quote_for_eval_result
-    fi
-
-    $_G_rc_lt_options_prep
+    # Pass back the list of options.
+    func_quote_for_eval ${1+"$@"}
+    libtool_options_prep_result=$func_quote_for_eval_result
 }
 func_add_hook func_options_prep libtool_options_prep
 
@@ -2391,12 +2309,9 @@ libtool_parse_options ()
 {
     $debug_cmd
 
-    _G_rc_lt_parse_options=false
-
     # Perform our own loop to consume as many options as possible in
     # each iteration.
     while test $# -gt 0; do
-      _G_match_lt_parse_options=:
       _G_opt=$1
       shift
       case $_G_opt in
@@ -2471,22 +2386,15 @@ libtool_parse_options ()
                         func_append preserve_args " $_G_opt"
                         ;;
 
-        # An option not handled by this hook function:
-        *)              set dummy "$_G_opt" ${1+"$@"} ; shift
-                        _G_match_lt_parse_options=false
-                        break
-                        ;;
+       # An option not handled by this hook function:
+        *)             set dummy "$_G_opt" ${1+"$@"};  shift; break  ;;
       esac
-      $_G_match_lt_parse_options && _G_rc_lt_parse_options=:
     done
 
-    if $_G_rc_lt_parse_options; then
-      # save modified positional parameters for caller
-      func_quote_for_eval ${1+"$@"}
-      libtool_parse_options_result=$func_quote_for_eval_result
-    fi
 
-    $_G_rc_lt_parse_options
+    # save modified positional parameters for caller
+    func_quote_for_eval ${1+"$@"}
+    libtool_parse_options_result=$func_quote_for_eval_result
 }
 func_add_hook func_parse_options libtool_parse_options
 
@@ -7312,6 +7220,11 @@ func_mode_link ()
        arg=$func_stripname_result
        ;;
 
+      -Wl,--as-needed)
+       deplibs="$deplibs $arg"
+       continue
+       ;;
+
       -Wl,*)
        func_stripname '-Wl,' '' "$arg"
        args=$func_stripname_result
@@ -7364,14 +7277,10 @@ func_mode_link ()
       # -tp=*                Portland pgcc target processor selection
       # --sysroot=*          for sysroot support
       # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
-      # -specs=*             GCC specs files
       # -stdlib=*            select c++ std lib with clang
-      # -fsanitize=*         Clang/GCC memory and address sanitizer
-      # -fuse-ld=*           Linker select flags for GCC
       -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
       -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
-      -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \
-      -specs=*|-fsanitize=*|-fuse-ld=*)
+      -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*)
         func_quote_for_eval "$arg"
        arg=$func_quote_for_eval_result
         func_append compile_command " $arg"
@@ -7620,6 +7529,7 @@ func_mode_link ()
 
     case $linkmode in
     lib)
+       as_needed_flag=
        passes="conv dlpreopen link"
        for file in $dlfiles $dlprefiles; do
          case $file in
@@ -7631,6 +7541,7 @@ func_mode_link ()
        done
        ;;
     prog)
+       as_needed_flag=
        compile_deplibs=
        finalize_deplibs=
        alldeplibs=false
@@ -7664,10 +7575,7 @@ func_mode_link ()
        case $pass in
        dlopen) libs=$dlfiles ;;
        dlpreopen) libs=$dlprefiles ;;
-       link)
-         libs="$deplibs %DEPLIBS%"
-         test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
-         ;;
+       link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
        esac
       fi
       if test lib,dlpreopen = "$linkmode,$pass"; then
@@ -7703,6 +7611,15 @@ func_mode_link ()
        lib=
        found=false
        case $deplib in
+       -Wl,--as-needed)
+         if test prog,link = "$linkmode,$pass" ||
+            test lib,link = "$linkmode,$pass"; then
+           as_needed_flag="$deplib "
+         else
+           deplibs="$deplib $deplibs"
+         fi
+         continue
+         ;;
        -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
         |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
          if test prog,link = "$linkmode,$pass"; then
@@ -7986,19 +7903,19 @@ func_mode_link ()
            # It is a libtool convenience library, so add in its objects.
            func_append convenience " $ladir/$objdir/$old_library"
            func_append old_convenience " $ladir/$objdir/$old_library"
-           tmp_libs=
-           for deplib in $dependency_libs; do
-             deplibs="$deplib $deplibs"
-             if $opt_preserve_dup_deps; then
-               case "$tmp_libs " in
-               *" $deplib "*) func_append specialdeplibs " $deplib" ;;
-               esac
-             fi
-             func_append tmp_libs " $deplib"
-           done
          elif test prog != "$linkmode" && test lib != "$linkmode"; then
            func_fatal_error "'$lib' is not a convenience library"
          fi
+         tmp_libs=
+         for deplib in $dependency_libs; do
+           deplibs="$deplib $deplibs"
+           if $opt_preserve_dup_deps; then
+             case "$tmp_libs " in
+             *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+             esac
+           fi
+           func_append tmp_libs " $deplib"
+         done
          continue
        fi # $pass = conv
 
@@ -8922,9 +8839,6 @@ func_mode_link ()
            revision=$number_minor
            lt_irix_increment=no
            ;;
-         *)
-           func_fatal_configuration "$modename: unknown library version type '$version_type'"
-           ;;
          esac
          ;;
        no)
@@ -10123,6 +10037,13 @@ EOF
          test "X$libobjs" = "X " && libobjs=
        fi
 
+       # A bit hacky. I had wanted to add \$as_needed_flag to archive_cmds instead, but that
+       # comes from libtool.m4 which is part of the project being built. This should put it
+       # in the right place though.
+       if test lib,link = "$linkmode,$pass" && test -n "$as_needed_flag"; then
+         libobjs=$as_needed_flag$libobjs
+       fi
+
        save_ifs=$IFS; IFS='~'
        for cmd in $cmds; do
          IFS=$sp$nl
@@ -10355,8 +10276,8 @@ EOF
       compile_deplibs=$new_libs
 
 
-      func_append compile_command " $compile_deplibs"
-      func_append finalize_command " $finalize_deplibs"
+      func_append compile_command " $as_needed_flag $compile_deplibs"
+      func_append finalize_command " $as_needed_flag $finalize_deplibs"
 
       if test -n "$rpath$xrpath"; then
        # If the user specified any rpath flags, then add them.
index 9d6dd9f..a3bc337 100644 (file)
@@ -728,6 +728,7 @@ _LT_CONFIG_SAVE_COMMANDS([
     cat <<_LT_EOF >> "$cfgfile"
 #! $SHELL
 # Generated automatically by $as_me ($PACKAGE) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
 # NOTE: Changes made to this file will be lost: look at ltmain.sh.
 
 # Provide generalized library-building support services.
@@ -2886,18 +2887,6 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   dynamic_linker='GNU/Linux ld.so'
   ;;
 
-netbsdelf*-gnu)
-  version_type=linux
-  need_lib_prefix=no
-  need_version=no
-  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
-  soname_spec='${libname}${release}${shared_ext}$major'
-  shlibpath_var=LD_LIBRARY_PATH
-  shlibpath_overrides_runpath=no
-  hardcode_into_libs=yes
-  dynamic_linker='NetBSD ld.elf_so'
-  ;;
-
 netbsd*)
   version_type=sunos
   need_lib_prefix=no
@@ -3557,7 +3546,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
-netbsd* | netbsdelf*-gnu)
+netbsd*)
   if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
     lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
   else
@@ -4063,8 +4052,7 @@ _LT_EOF
   if AC_TRY_EVAL(ac_compile); then
     # Now try to grab the symbols.
     nlist=conftest.nm
-    $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&AS_MESSAGE_LOG_FD
-    if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&AS_MESSAGE_LOG_FD && test -s "$nlist"; then
+    if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then
       # Try sorting and uniquifying the output.
       if sort "$nlist" | uniq > "$nlist"T; then
        mv -f "$nlist"T "$nlist"
@@ -4436,7 +4424,7 @@ m4_if([$1], [CXX], [
            ;;
        esac
        ;;
-      netbsd* | netbsdelf*-gnu)
+      netbsd*)
        ;;
       *qnx* | *nto*)
         # QNX uses GNU C++, but need to define -shared option too, otherwise
@@ -4704,12 +4692,6 @@ m4_if([$1], [CXX], [
        _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
        _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
         ;;
-      # flang / f18. f95 an alias for gfortran or flang on Debian
-      flang* | f18* | f95*)
-       _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
-       _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
-       _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
-        ;;
       # icc used to be incompatible with GCC.
       # ICC 10 doesn't accept -KPIC any more.
       icc* | ifort*)
@@ -4954,9 +4936,6 @@ m4_if([$1], [CXX], [
       ;;
     esac
     ;;
-  linux* | k*bsd*-gnu | gnu*)
-    _LT_TAGVAR(link_all_deplibs, $1)=no
-    ;;
   *)
     _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
     ;;
@@ -5019,9 +4998,6 @@ dnl Note also adjust exclude_expsyms for C++ above.
   openbsd* | bitrig*)
     with_gnu_ld=no
     ;;
-  linux* | k*bsd*-gnu | gnu*)
-    _LT_TAGVAR(link_all_deplibs, $1)=no
-    ;;
   esac
 
   _LT_TAGVAR(ld_shlibs, $1)=yes
@@ -5276,7 +5252,7 @@ _LT_EOF
       fi
       ;;
 
-    netbsd* | netbsdelf*-gnu)
+    netbsd*)
       if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
        _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
        wlarc=
@@ -5797,7 +5773,6 @@ _LT_EOF
        if test yes = "$lt_cv_irix_exported_symbol"; then
           _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
        fi
-       _LT_TAGVAR(link_all_deplibs, $1)=no
       else
        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
@@ -5819,7 +5794,7 @@ _LT_EOF
       esac
       ;;
 
-    netbsd* | netbsdelf*-gnu)
+    netbsd*)
       if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
        _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
       else
@@ -6445,7 +6420,7 @@ if test yes != "$_lt_caught_CXX_error"; then
       # Commands to make compiler produce verbose output that lists
       # what "hidden" libraries, object files and flags are used when
       # linking a shared library.
-      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
 
     else
       GXX=no
@@ -6820,7 +6795,7 @@ if test yes != "$_lt_caught_CXX_error"; then
             # explicitly linking system object files so we need to strip them
             # from the output so that they don't get included in the library
             # dependencies.
-            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
             ;;
           *)
             if test yes = "$GXX"; then
@@ -6885,7 +6860,7 @@ if test yes != "$_lt_caught_CXX_error"; then
            # explicitly linking system object files so we need to strip them
            # from the output so that they don't get included in the library
            # dependencies.
-           output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+           output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
            ;;
           *)
            if test yes = "$GXX"; then
@@ -7224,7 +7199,7 @@ if test yes != "$_lt_caught_CXX_error"; then
              # Commands to make compiler produce verbose output that lists
              # what "hidden" libraries, object files and flags are used when
              # linking a shared library.
-             output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
+             output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
 
            else
              # FIXME: insert proper C++ library support
@@ -7308,7 +7283,7 @@ if test yes != "$_lt_caught_CXX_error"; then
                # Commands to make compiler produce verbose output that lists
                # what "hidden" libraries, object files and flags are used when
                # linking a shared library.
-               output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
+               output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
              else
                # g++ 2.7 appears to require '-G' NOT '-shared' on this
                # platform.
@@ -7319,7 +7294,7 @@ if test yes != "$_lt_caught_CXX_error"; then
                # Commands to make compiler produce verbose output that lists
                # what "hidden" libraries, object files and flags are used when
                # linking a shared library.
-               output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
+               output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
              fi
 
              _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'
index b4069c4..8a81a34 100644 (file)
@@ -79,7 +79,7 @@ fstshortestpath_SOURCES = fstshortestpath.cc fstshortestpath-main.cc
 fstsymbols_SOURCES = fstsymbols.cc fstsymbols-main.cc
 
 fstsynchronize_SOURCES = fstsynchronize.cc fstsynchronize-main.cc
+
 fsttopsort_SOURCES = fsttopsort.cc fsttopsort-main.cc
 
 fstunion_SOURCES = fstunion.cc fstunion-main.cc
index 4be09e6..cb66f64 100644 (file)
@@ -17,7 +17,7 @@ DECLARE_double(delta);
 DECLARE_bool(random);
 DECLARE_int32(max_length);
 DECLARE_int32(npath);
-DECLARE_int32(seed);
+DECLARE_uint64(seed);
 DECLARE_string(select);
 
 int fstequivalent_main(int argc, char **argv) {
@@ -64,8 +64,8 @@ int fstequivalent_main(int argc, char **argv) {
       return 1;
     }
     const RandGenOptions<s::RandArcSelection> opts(ras, FLAGS_max_length);
-    bool result = s::RandEquivalent(*ifst1, *ifst2, FLAGS_npath, FLAGS_delta,
-                                    FLAGS_seed, opts);
+    bool result = s::RandEquivalent(*ifst1, *ifst2, FLAGS_npath, opts,
+                                    FLAGS_delta, FLAGS_seed);
     if (!result) VLOG(1) << "FSTs are not equivalent";
     return result ? 0 : 2;
   }
index cfc5b77..996ce7d 100644 (file)
@@ -1,7 +1,5 @@
-#include <unistd.h>
-
-#include <climits>
-#include <ctime>
+#include <limits>
+#include <random>
 
 #include <fst/flags.h>
 #include <fst/weight.h>
@@ -9,9 +7,10 @@
 DEFINE_double(delta, fst::kDelta, "Comparison/quantization delta");
 DEFINE_bool(random, false,
             "Test equivalence by randomly selecting paths in the input FSTs");
-DEFINE_int32(max_length, INT32_MAX, "Maximum path length");
+DEFINE_int32(max_length, std::numeric_limits<int32>::max(),
+             "Maximum path length");
 DEFINE_int32(npath, 1, "Number of paths to generate");
-DEFINE_int32(seed, time(nullptr) + getpid(), "Random seed");
+DEFINE_uint64(seed, std::random_device()(), "Random seed");
 DEFINE_string(select, "uniform",
               "Selection type: one of: "
               " \"uniform\", \"log_prob\" (when appropriate),"
index d11665d..ab08551 100644 (file)
@@ -14,7 +14,7 @@
 
 DECLARE_int32(max_length);
 DECLARE_int32(npath);
-DECLARE_int32(seed);
+DECLARE_uint64(seed);
 DECLARE_string(select);
 DECLARE_bool(weighted);
 DECLARE_bool(remove_total_weight);
@@ -54,10 +54,11 @@ int fstrandgen_main(int argc, char **argv) {
     return 1;
   }
 
-  s::RandGen(*ifst, &ofst, FLAGS_seed,
+  s::RandGen(*ifst, &ofst,
              fst::RandGenOptions<s::RandArcSelection>(
                  ras, FLAGS_max_length, FLAGS_npath, FLAGS_weighted,
-                 FLAGS_remove_total_weight));
+                 FLAGS_remove_total_weight),
+             FLAGS_seed);
 
   return !ofst.Write(out_name);
 }
index 5af9231..fb54267 100644 (file)
@@ -1,13 +1,12 @@
-#include <unistd.h>
-
-#include <climits>
-#include <ctime>
+#include <limits>
+#include <random>
 
 #include <fst/flags.h>
 
-DEFINE_int32(max_length, INT32_MAX, "Maximum path length");
+DEFINE_int32(max_length, std::numeric_limits<int32>::max(),
+             "Maximum path length");
 DEFINE_int32(npath, 1, "Number of paths to generate");
-DEFINE_int32(seed, time(nullptr) + getpid(), "Random seed");
+DEFINE_uint64(seed, std::random_device()(), "Random seed");
 DEFINE_string(select, "uniform",
               "Selection type: one of: "
               " \"uniform\", \"log_prob\" (when appropriate),"
index 765e310..37098cb 100644 (file)
@@ -7,7 +7,7 @@ libfst_LTLIBRARIES = compact8_acceptor-fst.la compact8_string-fst.la compact8_un
 lib_LTLIBRARIES = libfstcompact.la
 
 libfstcompact_la_SOURCES = compact8_acceptor-fst.cc compact8_string-fst.cc compact8_unweighted-fst.cc compact8_unweighted_acceptor-fst.cc compact8_weighted_string-fst.cc compact16_acceptor-fst.cc compact16_string-fst.cc compact16_unweighted-fst.cc compact16_unweighted_acceptor-fst.cc compact16_weighted_string-fst.cc compact64_acceptor-fst.cc compact64_string-fst.cc compact64_unweighted-fst.cc compact64_unweighted_acceptor-fst.cc compact64_weighted_string-fst.cc
-libfstcompact_la_LDFLAGS = -version-info 19:0:0
+libfstcompact_la_LDFLAGS = -version-info 20:0:0
 
 compact8_acceptor_fst_la_SOURCES = compact8_acceptor-fst.cc
 compact8_acceptor_fst_la_LDFLAGS = -avoid-version -module
index 064b9bb..09fd333 100644 (file)
@@ -527,7 +527,7 @@ AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 libfst_LTLIBRARIES = compact8_acceptor-fst.la compact8_string-fst.la compact8_unweighted-fst.la compact8_unweighted_acceptor-fst.la compact8_weighted_string-fst.la compact16_acceptor-fst.la compact16_string-fst.la compact16_unweighted-fst.la compact16_unweighted_acceptor-fst.la compact16_weighted_string-fst.la compact64_acceptor-fst.la compact64_string-fst.la compact64_unweighted-fst.la compact64_unweighted_acceptor-fst.la compact64_weighted_string-fst.la
 lib_LTLIBRARIES = libfstcompact.la
 libfstcompact_la_SOURCES = compact8_acceptor-fst.cc compact8_string-fst.cc compact8_unweighted-fst.cc compact8_unweighted_acceptor-fst.cc compact8_weighted_string-fst.cc compact16_acceptor-fst.cc compact16_string-fst.cc compact16_unweighted-fst.cc compact16_unweighted_acceptor-fst.cc compact16_weighted_string-fst.cc compact64_acceptor-fst.cc compact64_string-fst.cc compact64_unweighted-fst.cc compact64_unweighted_acceptor-fst.cc compact64_weighted_string-fst.cc
-libfstcompact_la_LDFLAGS = -version-info 19:0:0
+libfstcompact_la_LDFLAGS = -version-info 20:0:0
 compact8_acceptor_fst_la_SOURCES = compact8_acceptor-fst.cc
 compact8_acceptor_fst_la_LDFLAGS = -avoid-version -module
 compact8_string_fst_la_SOURCES = compact8_string-fst.cc
index 735f092..9123656 100644 (file)
@@ -13,7 +13,7 @@ endif
 
 if HAVE_SCRIPT
 libfstcompressscript_la_SOURCES = compressscript.cc
-libfstcompressscript_la_LDFLAGS = -version-info 19:0:0
+libfstcompressscript_la_LDFLAGS = -version-info 20:0:0
 libfstcompressscript_la_LIBADD = ../../script/libfstscript.la \
                                  ../../lib/libfst.la \
                                  -lm $(DL_LIBS)
index 4266133..5d7d93c 100644 (file)
@@ -370,7 +370,7 @@ AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 
 @HAVE_BIN_TRUE@fstcompress_SOURCES = fstcompress.cc fstcompress-main.cc
 @HAVE_SCRIPT_TRUE@libfstcompressscript_la_SOURCES = compressscript.cc
-@HAVE_SCRIPT_TRUE@libfstcompressscript_la_LDFLAGS = -version-info 19:0:0
+@HAVE_SCRIPT_TRUE@libfstcompressscript_la_LDFLAGS = -version-info 20:0:0
 @HAVE_SCRIPT_TRUE@libfstcompressscript_la_LIBADD = ../../script/libfstscript.la \
 @HAVE_SCRIPT_TRUE@                                 ../../lib/libfst.la \
 @HAVE_SCRIPT_TRUE@                                 -lm $(DL_LIBS)
index 1b5dc95..08d401b 100644 (file)
@@ -7,7 +7,7 @@ libfst_LTLIBRARIES = const8-fst.la const16-fst.la const64-fst.la
 lib_LTLIBRARIES = libfstconst.la
 
 libfstconst_la_SOURCES = const8-fst.cc const16-fst.cc const64-fst.cc
-libfstconst_la_LDFLAGS = -version-info 19:0:0
+libfstconst_la_LDFLAGS = -version-info 20:0:0
 
 const8_fst_la_SOURCES = const8-fst.cc
 const8_fst_la_LDFLAGS = -avoid-version -module
index aeafd1f..0d70559 100644 (file)
@@ -371,7 +371,7 @@ AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 libfst_LTLIBRARIES = const8-fst.la const16-fst.la const64-fst.la
 lib_LTLIBRARIES = libfstconst.la
 libfstconst_la_SOURCES = const8-fst.cc const16-fst.cc const64-fst.cc
-libfstconst_la_LDFLAGS = -version-info 19:0:0
+libfstconst_la_LDFLAGS = -version-info 20:0:0
 const8_fst_la_SOURCES = const8-fst.cc
 const8_fst_la_LDFLAGS = -avoid-version -module
 const16_fst_la_SOURCES = const16-fst.cc
index 4717ade..0088c56 100644 (file)
@@ -7,13 +7,13 @@ lib_LTLIBRARIES = libfstfar.la
 endif
 
 libfstfar_la_SOURCES = sttable.cc stlist.cc
-libfstfar_la_LDFLAGS = -version-info 19:0:0
+libfstfar_la_LDFLAGS = -version-info 20:0:0
 libfstfar_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
 
 if HAVE_SCRIPT
 libfstfarscript_la_SOURCES = far-class.cc farscript.cc getters.cc script-impl.cc \
                              strings.cc sttable.cc stlist.cc
-libfstfarscript_la_LDFLAGS = -version-info 19:0:0
+libfstfarscript_la_LDFLAGS = -version-info 20:0:0
 libfstfarscript_la_LIBADD = \
     libfstfar.la ../../script/libfstscript.la \
         ../../lib/libfst.la -lm $(DL_LIBS)
index 794de41..5a486ca 100644 (file)
@@ -449,12 +449,12 @@ AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 @HAVE_SCRIPT_FALSE@lib_LTLIBRARIES = libfstfar.la
 @HAVE_SCRIPT_TRUE@lib_LTLIBRARIES = libfstfar.la libfstfarscript.la
 libfstfar_la_SOURCES = sttable.cc stlist.cc
-libfstfar_la_LDFLAGS = -version-info 19:0:0
+libfstfar_la_LDFLAGS = -version-info 20:0:0
 libfstfar_la_LIBADD = ../../lib/libfst.la -lm $(DL_LIBS)
 @HAVE_SCRIPT_TRUE@libfstfarscript_la_SOURCES = far-class.cc farscript.cc getters.cc script-impl.cc \
 @HAVE_SCRIPT_TRUE@                             strings.cc sttable.cc stlist.cc
 
-@HAVE_SCRIPT_TRUE@libfstfarscript_la_LDFLAGS = -version-info 19:0:0
+@HAVE_SCRIPT_TRUE@libfstfarscript_la_LDFLAGS = -version-info 20:0:0
 @HAVE_SCRIPT_TRUE@libfstfarscript_la_LIBADD = \
 @HAVE_SCRIPT_TRUE@    libfstfar.la ../../script/libfstscript.la \
 @HAVE_SCRIPT_TRUE@        ../../lib/libfst.la -lm $(DL_LIBS)
index b28b583..4eebe06 100644 (file)
@@ -15,7 +15,7 @@ if HAVE_SCRIPT
 lib_LTLIBRARIES = libfstlinearscript.la
 
 libfstlinearscript_la_SOURCES = linearscript.cc
-libfstlinearscript_la_LDFLAGS = -version-info 19:0:0
+libfstlinearscript_la_LDFLAGS = -version-info 20:0:0
 libfstlinearscript_la_LIBADD = ../../script/libfstscript.la
 endif
 
index c2aa44c..6ae1d35 100644 (file)
@@ -396,7 +396,7 @@ AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 @HAVE_BIN_TRUE@fstloglinearapply_LDADD = libfstlinearscript.la ../../script/libfstscript.la
 @HAVE_SCRIPT_TRUE@lib_LTLIBRARIES = libfstlinearscript.la
 @HAVE_SCRIPT_TRUE@libfstlinearscript_la_SOURCES = linearscript.cc
-@HAVE_SCRIPT_TRUE@libfstlinearscript_la_LDFLAGS = -version-info 19:0:0
+@HAVE_SCRIPT_TRUE@libfstlinearscript_la_LDFLAGS = -version-info 20:0:0
 @HAVE_SCRIPT_TRUE@libfstlinearscript_la_LIBADD = ../../script/libfstscript.la
 libfst_LTLIBRARIES = linear_tagger-fst.la linear_classifier-fst.la
 linear_tagger_fst_la_SOURCES = linear-tagger-fst.cc
index 3796c63..1a4da1e 100644 (file)
@@ -9,7 +9,7 @@ lib_LTLIBRARIES = libfstlookahead.la
 
 libfstlookahead_la_SOURCES = arc_lookahead-fst.cc ilabel_lookahead-fst.cc \
                              olabel_lookahead-fst.cc
-libfstlookahead_la_LDFLAGS = -version-info 19:0:0
+libfstlookahead_la_LDFLAGS = -version-info 20:0:0
 
 arc_lookahead_fst_la_SOURCES = arc_lookahead-fst.cc
 arc_lookahead_fst_la_LDFLAGS = -avoid-version -module
index c675874..d278949 100644 (file)
@@ -382,7 +382,7 @@ lib_LTLIBRARIES = libfstlookahead.la
 libfstlookahead_la_SOURCES = arc_lookahead-fst.cc ilabel_lookahead-fst.cc \
                              olabel_lookahead-fst.cc
 
-libfstlookahead_la_LDFLAGS = -version-info 19:0:0
+libfstlookahead_la_LDFLAGS = -version-info 20:0:0
 arc_lookahead_fst_la_SOURCES = arc_lookahead-fst.cc
 arc_lookahead_fst_la_LDFLAGS = -avoid-version -module
 ilabel_lookahead_fst_la_SOURCES = ilabel_lookahead-fst.cc
index 510441e..1aaeefe 100644 (file)
@@ -20,7 +20,7 @@ endif
 if HAVE_SCRIPT
 lib_LTLIBRARIES = libfstmpdtscript.la
 libfstmpdtscript_la_SOURCES = mpdtscript.cc
-libfstmpdtscript_la_LDFLAGS = -version-info 19:0:0
+libfstmpdtscript_la_LDFLAGS = -version-info 20:0:0
 libfstmpdtscript_la_LIBADD = ../../script/libfstscript.la \
                              ../../lib/libfst.la -lm $(DL_LIBS)
 endif
index 8629b5f..113c736 100644 (file)
@@ -407,7 +407,7 @@ AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 @HAVE_BIN_TRUE@mpdtreverse_SOURCES = mpdtreverse.cc mpdtreverse-main.cc
 @HAVE_SCRIPT_TRUE@lib_LTLIBRARIES = libfstmpdtscript.la
 @HAVE_SCRIPT_TRUE@libfstmpdtscript_la_SOURCES = mpdtscript.cc
-@HAVE_SCRIPT_TRUE@libfstmpdtscript_la_LDFLAGS = -version-info 19:0:0
+@HAVE_SCRIPT_TRUE@libfstmpdtscript_la_LDFLAGS = -version-info 20:0:0
 @HAVE_SCRIPT_TRUE@libfstmpdtscript_la_LIBADD = ../../script/libfstscript.la \
 @HAVE_SCRIPT_TRUE@                             ../../lib/libfst.la -lm $(DL_LIBS)
 
index fc27371..ebabe88 100644 (file)
@@ -10,4 +10,4 @@ ngram_fst_la_SOURCES = bitmap-index.cc ngram-fst.cc nthbit.cc
 ngram_fst_la_LDFLAGS = -avoid-version -module
 
 libfstngram_la_SOURCES = bitmap-index.cc ngram-fst.cc nthbit.cc
-libfstngram_la_LDFLAGS = -version-info 19:0:0
+libfstngram_la_LDFLAGS = -version-info 20:0:0
index 092ec1f..104093b 100644 (file)
@@ -355,7 +355,7 @@ lib_LTLIBRARIES = libfstngram.la
 ngram_fst_la_SOURCES = bitmap-index.cc ngram-fst.cc nthbit.cc
 ngram_fst_la_LDFLAGS = -avoid-version -module
 libfstngram_la_SOURCES = bitmap-index.cc ngram-fst.cc nthbit.cc
-libfstngram_la_LDFLAGS = -version-info 19:0:0
+libfstngram_la_LDFLAGS = -version-info 20:0:0
 all: all-am
 
 .SUFFIXES:
index 7317379..aec0749 100644 (file)
@@ -5,6 +5,8 @@
 
 #include <fst/types.h>
 
+namespace fst {
+
 #if !defined(__BMI2__)  // BMI2 has everything in the header
 #if SIZE_MAX == UINT32_MAX
 
@@ -487,3 +489,5 @@ const uint8 kSelectInByte[8 * 256] = {
 }  // namespace internal
 #endif  // 64-bit, non-BMI2
 #endif  // !defined(__BMI2__)
+
+}  // namespace fst
index 9998f0a..a152890 100644 (file)
@@ -24,7 +24,7 @@ endif
 if HAVE_SCRIPT
 lib_LTLIBRARIES = libfstpdtscript.la
 libfstpdtscript_la_SOURCES = getters.cc pdtscript.cc
-libfstpdtscript_la_LDFLAGS = -version-info 19:0:0
+libfstpdtscript_la_LDFLAGS = -version-info 20:0:0
 libfstpdtscript_la_LIBADD = ../../script/libfstscript.la \
                             ../../lib/libfst.la -lm $(DL_LIBS)
 endif
index c87af19..01a3b0f 100644 (file)
@@ -428,7 +428,7 @@ AM_CPPFLAGS = -I$(srcdir)/../../include $(ICU_CPPFLAGS)
 @HAVE_BIN_TRUE@pdtshortestpath_SOURCES = pdtshortestpath.cc pdtshortestpath-main.cc
 @HAVE_SCRIPT_TRUE@lib_LTLIBRARIES = libfstpdtscript.la
 @HAVE_SCRIPT_TRUE@libfstpdtscript_la_SOURCES = getters.cc pdtscript.cc
-@HAVE_SCRIPT_TRUE@libfstpdtscript_la_LDFLAGS = -version-info 19:0:0
+@HAVE_SCRIPT_TRUE@libfstpdtscript_la_LDFLAGS = -version-info 20:0:0
 @HAVE_SCRIPT_TRUE@libfstpdtscript_la_LIBADD = ../../script/libfstscript.la \
 @HAVE_SCRIPT_TRUE@                            ../../lib/libfst.la -lm $(DL_LIBS)
 
index 974b770..d8fa6a1 100644 (file)
@@ -15,5 +15,5 @@ pywrapfst_la_LIBADD = ../far/libfstfarscript.la ../far/libfstfar.la \
                       -lm $(DL_LIBS) $(PYTHON_LIBS)
 
 # Exports the *.pxd/*.pxd source files.
-EXTRA_DIST = basictypes.pxd cpywrapfst.pxd ios.pxd \
-             pywrapfst.pxd pywrapfst.pyx utility.pxd
+EXTRA_DIST = cintegral_types.pxd cios.pxd cpywrapfst.pxd \
+             cutility.pxd pywrapfst.pxd pywrapfst.pyx
index 765333e..c4e9b6d 100644 (file)
@@ -361,8 +361,8 @@ pywrapfst_la_LIBADD = ../far/libfstfarscript.la ../far/libfstfar.la \
 
 
 # Exports the *.pxd/*.pxd source files.
-EXTRA_DIST = basictypes.pxd cpywrapfst.pxd ios.pxd \
-             pywrapfst.pxd pywrapfst.pyx utility.pxd
+EXTRA_DIST = cintegral_types.pxd cios.pxd cpywrapfst.pxd \
+             cutility.pxd pywrapfst.pxd pywrapfst.pyx
 
 all: all-am
 
similarity index 77%
rename from src/extensions/python/ios.pxd
rename to src/extensions/python/cios.pxd
index 173e3c9..e1b16b0 100644 (file)
@@ -3,14 +3,14 @@
 
 
 from libcpp.string cimport string
-from basictypes cimport int8
-from basictypes cimport int16
-from basictypes cimport int32
-from basictypes cimport int64
-from basictypes cimport uint8
-from basictypes cimport uint16
-from basictypes cimport uint32
-from basictypes cimport uint64
+from cintegral_types cimport int8
+from cintegral_types cimport int16
+from cintegral_types cimport int32
+from cintegral_types cimport int64
+from cintegral_types cimport uint8
+from cintegral_types cimport uint16
+from cintegral_types cimport uint32
+from cintegral_types cimport uint64
 
 
 cdef extern from "<iostream>" namespace "std" nogil:
@@ -54,7 +54,7 @@ cdef extern from "<sstream>" namespace "std" nogil:
 
     stringstream &operator<<(bool)
 
-    # We define these in terms of the Google basictypes.
+    # We define these in terms of the Google cintegral_types.
 
     stringstream &operator<<(int8)
 
index 69f88d0..bb5b90c 100644 (file)
@@ -1,17 +1,13 @@
 # See www.openfst.org for extensive documentation on this weighted
 # finite-state transducer library.
 
-
-from libc.time cimport time_t
-from libc.time cimport time
-
 from libcpp cimport bool
 from libcpp.string cimport string
 from libcpp.vector cimport vector
 from libcpp.utility cimport pair
 
-from basictypes cimport *
-from ios cimport *
+from cios cimport *
+from cintegral_types cimport *
 
 
 cdef extern from "<fst/util.h>" nogil:
@@ -653,14 +649,14 @@ cdef extern from "<fst/script/fstscript.h>" namespace "fst::script" nogil:
   cdef bool RandEquivalent(const FstClass &,
                            const FstClass &,
                            int32,
+                           const RandGenOptions[RandArcSelection] &,
                            float,
-                           time_t,
-                           const RandGenOptions[RandArcSelection] &)
+                           uint64)
 
   cdef void RandGen(const FstClass &,
                     MutableFstClass *,
-                    time_t,
-                    const RandGenOptions[RandArcSelection] &)
+                    const RandGenOptions[RandArcSelection] &,
+                    uint64)
 
   cdef void Relabel(MutableFstClass *,
                     const SymbolTable *,
index d06775f..a7e94f1 100644 (file)
@@ -13,13 +13,13 @@ from libcpp.string cimport string
 from libcpp.utility cimport pair
 from libcpp.vector cimport vector
 
-from basictypes cimport *
+from cintegral_types cimport *
 
 cimport cpywrapfst as fst
 
-from ios cimport ostream
-from ios cimport ofstream
-from ios cimport stringstream
+from cios cimport ostream
+from cios cimport ofstream
+from cios cimport stringstream
 
 
 # Exportable helper functions.
@@ -551,17 +551,17 @@ cpdef bool randequivalent(Fst ifst1,
                           Fst ifst2,
                           int32 npath=?,
                           float delta=?,
-                          time_t seed=?,
                           select=?,
-                          int32 max_length=?) except *
+                          int32 max_length=?,
+                          uint64 seed=?) except *
 
 cpdef MutableFst randgen(Fst ifst,
                          int32 npath=?,
-                         time_t seed=?,
                          select=?,
                          int32 max_length=?,
                          bool remove_total_weight=?,
-                         bool weighted=?)
+                         bool weighted=?,
+                         uint64 seed=?)
 
 cpdef MutableFst replace(pairs,
                          call_arc_labeling=?,
index 66bc34c..cfa5113 100644 (file)
@@ -61,6 +61,11 @@ normal `k` prefix.
 
 ## Imports.
 
+# Cython operator workarounds.
+from cython.operator cimport address as addr       # &foo
+from cython.operator cimport dereference as deref  # *foo
+from cython.operator cimport preincrement as inc   # ++foo
+
 # C imports.
 from libc.stdint cimport INT32_MAX
 from libc.stdint cimport SIZE_MAX
@@ -72,14 +77,9 @@ from libcpp.cast cimport static_cast
 from libcpp.memory cimport static_pointer_cast
 
 # Missing C++ imports.
-from ios cimport ofstream
-from memory cimport WrapUnique
-from utility cimport move
-
-# Cython operator workarounds.
-from cython.operator cimport address as addr       # &foo
-from cython.operator cimport dereference as deref  # *foo
-from cython.operator cimport preincrement as inc   # ++foo
+from cios cimport ofstream
+from cmemory cimport WrapUnique
+from cutility cimport move
 
 # Python imports.
 import logging
@@ -3903,12 +3903,13 @@ cpdef bool randequivalent(Fst ifst1,
                           Fst ifst2,
                           int32 npath=1,
                           float delta=fst.kDelta,
-                          time_t seed=0,
+
                           select=b"uniform",
-                          int32 max_length=INT32_MAX) except *:
+                          int32 max_length=INT32_MAX,
+                          uint64 seed=0) except *:
   """
-  randequivalent(ifst1, ifst2, npath=1, delta=0.0009765625, seed=0,
-                 select="uniform", max_length=2147483647)
+  randequivalent(ifst1, ifst2, npath=1, delta=0.0009765625, select="uniform",
+                 max_length=2147483647, seed=0)
 
   Are two acceptors stochastically equivalent?
 
@@ -3945,18 +3946,18 @@ cpdef bool randequivalent(Fst ifst1,
   return fst.RandEquivalent(deref(ifst1._fst),
                             deref(ifst2._fst),
                             npath,
+                            deref(opts),
                             delta,
-                            seed,
-                            deref(opts))
+                            seed)
 
 
 cpdef MutableFst randgen(Fst ifst,
                          int32 npath=1,
-                         time_t seed=0,
                          select=b"uniform",
                          int32 max_length=INT32_MAX,
                          bool weighted=False,
-                         bool remove_total_weight=False):
+                         bool remove_total_weight=False,
+                         uint64 seed=0):
   """
   randgen(ifst, npath=1, seed=0, select="uniform", max_length=2147483647,
           weighted=False, remove_total_weight=False)
@@ -3997,7 +3998,7 @@ cpdef MutableFst randgen(Fst ifst,
   tfst.reset(new fst.VectorFstClass(ifst.arc_type()))
   if seed == 0:
     seed = time(NULL) + getpid()
-  fst.RandGen(deref(ifst._fst), tfst.get(), seed, deref(opts))
+  fst.RandGen(deref(ifst._fst), tfst.get(), deref(opts), seed)
   return _init_MutableFst(tfst.release())
 
 
index 9538318..25656d1 100644 (file)
@@ -15,7 +15,7 @@ libfst_LTLIBRARIES = phi-fst.la rho-fst.la sigma-fst.la
 lib_LTLIBRARIES = libfstspecial.la
 
 libfstspecial_la_SOURCES = phi-fst.cc rho-fst.cc sigma-fst.cc
-libfstspecial_la_LDFLAGS = -version-info 19:0:0
+libfstspecial_la_LDFLAGS = -version-info 20:0:0
 
 phi_fst_la_SOURCES = phi-fst.cc
 phi_fst_la_LDFLAGS = -avoid-version -module
index 97e9d10..dc951e7 100644 (file)
@@ -388,7 +388,7 @@ AM_CPPFLAGS = -I$(srcdir)/../../include -I$(srcdir)/../../bin $(ICU_CPPFLAGS)
 libfst_LTLIBRARIES = phi-fst.la rho-fst.la sigma-fst.la
 lib_LTLIBRARIES = libfstspecial.la
 libfstspecial_la_SOURCES = phi-fst.cc rho-fst.cc sigma-fst.cc
-libfstspecial_la_LDFLAGS = -version-info 19:0:0
+libfstspecial_la_LDFLAGS = -version-info 20:0:0
 phi_fst_la_SOURCES = phi-fst.cc
 phi_fst_la_LDFLAGS = -avoid-version -module
 rho_fst_la_SOURCES = rho-fst.cc
index 4fb0d4f..47cd41b 100644 (file)
@@ -898,7 +898,7 @@ class FromGallicMapper {
       return A(arc.ilabel, 0, AW::Zero(), kNoStateId);
     }
     Label l = kNoLabel;
-    AW weight;
+    AW weight = AW::Zero();
     if (!Extract(arc.weight, &weight, &l) || arc.ilabel != arc.olabel) {
       FSTERROR() << "FromGallicMapper: Unrepresentable weight: " << arc.weight
                  << " for arc with ilabel = " << arc.ilabel
index 046b49c..3823268 100644 (file)
@@ -1,5 +1,5 @@
 /* src/include/fst/config.h.  Generated from config.h.in by configure.  */
-// OpenFst config file 
+// OpenFst config file
 
 /* Define to 1 if you have the ICU library. */
 /* #undef HAVE_ICU */
index 7815dfc..50d111d 100644 (file)
@@ -1,4 +1,4 @@
-// OpenFst config file 
+// OpenFst config file
 
 /* Define to 1 if you have the ICU library. */
 #undef HAVE_ICU
index 2ed05ed..920c119 100644 (file)
@@ -11,8 +11,6 @@
 #include <string>
 #include <vector>
 
-// Google-only...
-// ...Google-only
 #include <fst/types.h>
 #include <fst/log.h>
 
@@ -22,7 +20,6 @@
 #include <fst/test-properties.h>
 #include <fst/util.h>
 
-
 namespace fst {
 
 template <class A, class Unsigned>
@@ -48,12 +45,7 @@ class ConstFstImpl : public FstImpl<A> {
   using FstImpl<A>::SetProperties;
   using FstImpl<A>::Properties;
 
-  ConstFstImpl()
-      : states_(nullptr),
-        arcs_(nullptr),
-        narcs_(0),
-        nstates_(0),
-        start_(kNoStateId) {
+  ConstFstImpl() {
     std::string type = "const";
     if (sizeof(Unsigned) != sizeof(uint32)) {
       type += std::to_string(CHAR_BIT * sizeof(Unsigned));
@@ -121,11 +113,11 @@ class ConstFstImpl : public FstImpl<A> {
 
   std::unique_ptr<MappedFile> states_region_;  // Mapped file for states.
   std::unique_ptr<MappedFile> arcs_region_;    // Mapped file for arcs.
-  ConstState *states_;                         // States representation.
-  Arc *arcs_;                                  // Arcs representation.
-  size_t narcs_;                               // Number of arcs.
-  StateId nstates_;                            // Number of states.
-  StateId start_;                              // Initial state.
+  ConstState *states_ = nullptr;               // States representation.
+  Arc *arcs_ = nullptr;                        // Arcs representation.
+  size_t narcs_ = 0;                           // Number of arcs.
+  StateId nstates_ = 0;                        // Number of states.
+  StateId start_ = kNoStateId;                 // Initial state.
 
   ConstFstImpl(const ConstFstImpl &) = delete;
   ConstFstImpl &operator=(const ConstFstImpl &) = delete;
@@ -144,8 +136,7 @@ template <class Arc, class Unsigned>
 constexpr int ConstFstImpl<Arc, Unsigned>::kMinFileVersion;
 
 template <class Arc, class Unsigned>
-ConstFstImpl<Arc, Unsigned>::ConstFstImpl(const Fst<Arc> &fst)
-    : narcs_(0), nstates_(0) {
+ConstFstImpl<Arc, Unsigned>::ConstFstImpl(const Fst<Arc> &fst) {
   std::string type = "const";
   if (sizeof(Unsigned) != sizeof(uint32)) {
     type += std::to_string(CHAR_BIT * sizeof(Unsigned));
@@ -235,6 +226,8 @@ ConstFstImpl<Arc, Unsigned> *ConstFstImpl<Arc, Unsigned>::Read(
 // implementation and handles reference counting, delegating most methods to
 // ImplToExpandedFst. The unsigned type U is used to represent indices into the
 // arc array (default declared in fst-decl.h).
+//
+// ConstFst is thread-safe.
 template <class A, class Unsigned>
 class ConstFst : public ImplToExpandedFst<internal::ConstFstImpl<A, Unsigned>> {
  public:
@@ -255,8 +248,8 @@ class ConstFst : public ImplToExpandedFst<internal::ConstFstImpl<A, Unsigned>> {
   explicit ConstFst(const Fst<Arc> &fst)
       : ImplToExpandedFst<Impl>(std::make_shared<Impl>(fst)) {}
 
-  ConstFst(const ConstFst &fst, bool safe = false)
-      : ImplToExpandedFst<Impl>(fst) {}
+  ConstFst(const ConstFst &fst, bool unused_safe = false)
+      : ImplToExpandedFst<Impl>(fst.GetSharedImpl()) {}
 
   // Gets a copy of this ConstFst. See Fst<>::Copy() for further doc.
   ConstFst *Copy(bool safe = false) const override {
@@ -383,14 +376,6 @@ bool ConstFst<Arc, Unsigned>::WriteFst(const FST &fst, std::ostream &strm,
     for (ArcIterator<FST> aiter(fst, siter.Value()); !aiter.Done();
          aiter.Next()) {
       const auto &arc = aiter.Value();
-// Google-only...
-#ifdef MEMORY_SANITIZER
-      // arc may contain padding which has unspecified contents. Tell MSAN to
-      // not complain about it when writing it to a file.
-      ANNOTATE_MEMORY_IS_INITIALIZED(reinterpret_cast<const char *>(&arc),
-                                     sizeof(arc));
-#endif
-      // ...Google-only
       strm.write(reinterpret_cast<const char *>(&arc), sizeof(arc));
     }
   }
index e833968..6d94e87 100644 (file)
@@ -617,6 +617,8 @@ EditFstImpl<Arc, WrappedFstT, MutableFstT>::Read(std::istream &strm,
 }  // namespace internal
 
 // Concrete, editable FST. This class attaches interface to implementation.
+//
+// EditFst is thread-compatible.
 template <typename A, typename WrappedFstT = ExpandedFst<A>,
           typename MutableFstT = VectorFst<A>>
 class EditFst : public ImplToMutableFst<
index abdfcd5..708cfb4 100644 (file)
@@ -50,8 +50,8 @@ bool Equal(const Fst<Arc> &fst1, const Fst<Arc> &fst2, WeightEqual weight_equal,
     return false;
   }
   if ((etype & kEqualCompatProperties) &&
-      !CompatProperties(fst1.Properties(kCopyProperties, false),
-                        fst2.Properties(kCopyProperties, false))) {
+      !internal::CompatProperties(fst1.Properties(kCopyProperties, false),
+                                  fst2.Properties(kCopyProperties, false))) {
     VLOG(1) << "Equal: Properties not compatible";
     return false;
   }
index 349300a..bf692ec 100644 (file)
@@ -705,7 +705,7 @@ void Compressor<Arc>::WriteWeight(const std::vector<Weight> &input,
 
 template <class Arc>
 void Compressor<Arc>::WriteToStream(std::ostream &strm) {
-  while (buffer_code_.size() % 8 != 0) buffer_code_.push_back(1);
+  while (buffer_code_.size() % 8 != 0) buffer_code_.push_back(true);
   int64 data_size = buffer_code_.size() / 8;
   WriteType(strm, data_size);
   int64 i = 0;
index ee34f4e..269563a 100644 (file)
@@ -55,7 +55,7 @@ class FarReaderClassImpl : public FarReaderImplBase {
   bool Find(const std::string &key) final { return impl_->Find(key); }
 
   const FstClass *GetFstClass() const final {
-    fstc_.reset(new FstClass(*impl_->GetFst()));
+    fstc_ = fst::make_unique<FstClass>(*impl_->GetFst());
     return fstc_.get();
   }
 
index 7a1697a..e46610b 100644 (file)
 
 #include <immintrin.h>
 
+namespace fst {
 // Returns the position (0-63) of the r-th 1 bit in v.
 // 1 <= r <= CountOnes(v) <= 64.  Therefore, v must not be 0.
 inline uint32 nth_bit(uint64 v, uint32 r) {
   // PDEP example from https://stackoverflow.com/a/27453505
   return __builtin_ctzll(_pdep_u64(uint64{1} << (r - 1), v));
 }
+}  // namespace fst
 
 #elif SIZE_MAX == UINT32_MAX
 // Detect 32-bit architectures via size_t.
 
+namespace fst {
 // Returns the position (0-63) of the r-th 1 bit in v.
 // 1 <= r <= CountOnes(v) <= 64.  Therefore, v must not be 0.
 uint32 nth_bit(uint64 v, uint32 r);
+}  // namespace fst
 
 #elif SIZE_MAX == UINT64_MAX
 // Default 64-bit version, used by ARM64 and Intel < Haswell.
 
+namespace fst {
 namespace internal {
 extern const uint64 kPrefixSumOverflow[65];
 extern const uint8 kSelectInByte[2048];
@@ -75,6 +80,7 @@ inline uint32 nth_bit(const uint64 v, const uint32 r) {
   return shift +
          internal::kSelectInByte[(rank_in_byte << 8) + ((v >> shift) & 0xFF)];
 }
+}  // namespace fst
 
 #else
 
index 07866d6..12a6bcc 100644 (file)
@@ -12,7 +12,7 @@
 //
 // See www.openfst.org for extensive documentation on this weighted
 // finite-state transducer library.
-// 
+//
 // Google-style flag handling declarations and inline definitions.
 
 #ifndef FST_LIB_FLAGS_H_
@@ -50,6 +50,7 @@
 #define DECLARE_string(name) extern std::string FLAGS_##name
 #define DECLARE_int32(name) extern int32 FLAGS_ ## name
 #define DECLARE_int64(name) extern int64 FLAGS_ ## name
+#define DECLARE_uint64(name) extern uint64 FLAGS_##name
 #define DECLARE_double(name) extern double FLAGS_ ## name
 
 template <typename T>
@@ -107,29 +108,34 @@ class FlagRegister {
   }
 
   bool SetFlag(const std::string &val, int32 *address) const {
-    char *p = 0;
+    char *p = nullptr;
     *address = strtol(val.c_str(), &p, 0);
     return !val.empty() && *p == '\0';
   }
 
   bool SetFlag(const std::string &val, int64 *address) const {
-    char *p = 0;
+    char *p = nullptr;
     *address = strtoll(val.c_str(), &p, 0);
     return !val.empty() && *p == '\0';
   }
 
-  bool SetFlag(const std::string &val, double *address) const {
+  bool SetFlag(const std::string &val, uint64 *address) const {
     char *p = 0;
+    *address = strtoull(val.c_str(), &p, 0);
+    return !val.empty() && *p == '\0';
+  }
+
+  bool SetFlag(const std::string &val, double *address) const {
+    char *p = nullptr;
     *address = strtod(val.c_str(), &p);
     return !val.empty() && *p == '\0';
   }
 
   bool SetFlag(const std::string &arg, const std::string &val) const {
     for (const auto &kv : flag_table_) {
-      const std::string &name = kv.first;
+      const auto &name = kv.first;
       const FlagDescription<T> &desc = kv.second;
-      if (arg == name)
-        return SetFlag(val, desc.address);
+      if (arg == name) return SetFlag(val, desc.address);
     }
     return false;
   }
@@ -137,7 +143,7 @@ class FlagRegister {
   void GetUsage(
       std::set<std::pair<std::string, std::string>> *usage_set) const {
     for (auto it = flag_table_.begin(); it != flag_table_.end(); ++it) {
-      const std::string &name = it->first;
+      const auto &name = it->first;
       const FlagDescription<T> &desc = it->second;
       std::string usage = "  --" + name;
       usage += ": type = ";
@@ -197,6 +203,7 @@ class FlagRegisterer {
   DEFINE_VAR(std::string, name, value, doc)
 #define DEFINE_int32(name, value, doc) DEFINE_VAR(int32, name, value, doc)
 #define DEFINE_int64(name, value, doc) DEFINE_VAR(int64, name, value, doc)
+#define DEFINE_uint64(name, value, doc) DEFINE_VAR(uint64, name, value, doc)
 #define DEFINE_double(name, value, doc) DEFINE_VAR(double, name, value, doc)
 
 
index d59aad6..8a41795 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <sys/types.h>
 
+#include <atomic>
 #include <cmath>
 #include <cstddef>
 #include <iostream>
@@ -181,7 +182,8 @@ constexpr int kNoStateId = -1;  // Not a valid state ID.
 
 // A generic FST, templated on the arc definition, with common-demoninator
 // methods (use StateIterator and ArcIterator to iterate over its states and
-// arcs).
+// arcs).  Derived classes should be assumed to be thread-unsafe unless
+// otherwise specified.
 template <class A>
 class Fst {
  public:
@@ -376,6 +378,9 @@ struct StateIteratorData {
 //     ...
 //   }
 // There is no copying of the FST.
+//
+// Specializations may exist for some FST types.
+// StateIterators are thread-unsafe unless otherwise specified.
 template <class FST>
 class StateIterator {
  public:
@@ -483,6 +488,9 @@ struct ArcIteratorData {
 //     ...
 //   }
 // There is no copying of the FST.
+//
+// Specializations may exist for some FST types.
+// ArcIterators are thread-unsafe unless otherwise specified.
 template <class FST>
 class ArcIterator {
  public:
@@ -636,6 +644,11 @@ inline size_t NumOutputEpsilons(const Fst<Arc> &fst, typename Arc::StateId s) {
 //
 // Users are discouraged, but not prohibited, from subclassing this outside the
 // FST library.
+//
+// This class is thread-compatible except for the const SetProperties
+// overload.  Derived classes should be assumed to be thread-unsafe unless
+// otherwise specified.  Derived-class copy constructors must produce a
+// thread-safe copy.
 template <class Arc>
 class FstImpl {
  public:
@@ -645,7 +658,7 @@ class FstImpl {
   FstImpl() : properties_(0), type_("null") {}
 
   FstImpl(const FstImpl<Arc> &impl)
-      : properties_(impl.properties_),
+      : properties_(impl.properties_.load(std::memory_order_relaxed)),
         type_(impl.type_),
         isymbols_(impl.isymbols_ ? impl.isymbols_->Copy() : nullptr),
         osymbols_(impl.osymbols_ ? impl.osymbols_->Copy() : nullptr) {}
@@ -655,7 +668,8 @@ class FstImpl {
   virtual ~FstImpl() {}
 
   FstImpl &operator=(const FstImpl &impl) {
-    properties_ = impl.properties_;
+    properties_.store(impl.properties_.load(std::memory_order_relaxed),
+                      std::memory_order_relaxed);
     type_ = impl.type_;
     isymbols_ = impl.isymbols_ ? impl.isymbols_->Copy() : nullptr;
     osymbols_ = impl.osymbols_ ? impl.osymbols_->Copy() : nullptr;
@@ -668,18 +682,29 @@ class FstImpl {
 
   void SetType(const std::string &type) { type_ = type; }
 
-  virtual uint64 Properties() const { return properties_; }
+  virtual uint64 Properties() const {
+    return properties_.load(std::memory_order_relaxed);
+  }
 
-  virtual uint64 Properties(uint64 mask) const { return properties_ & mask; }
+  virtual uint64 Properties(uint64 mask) const {
+    return properties_.load(std::memory_order_relaxed) & mask;
+  }
 
   void SetProperties(uint64 props) {
-    properties_ &= kError;  // kError can't be cleared.
-    properties_ |= props;
+    uint64 properties = properties_.load(std::memory_order_relaxed);
+    properties &= kError;  // kError can't be cleared.
+    properties |= props;
+    properties_.store(properties, std::memory_order_relaxed);
   }
 
   void SetProperties(uint64 props, uint64 mask) {
-    properties_ &= ~mask | kError;  // kError can't be cleared.
-    properties_ |= props & mask;
+    // Unlike UpdateProperties, does not require compatibility between props
+    // and properties_, since it may be used to update properties after
+    // a mutation.
+    uint64 properties = properties_.load(std::memory_order_relaxed);
+    properties &= ~mask | kError;  // kError can't be cleared.
+    properties |= props & mask;
+    properties_.store(properties, std::memory_order_relaxed);
   }
 
   // Allows (only) setting error bit on const FST implementations.
@@ -687,7 +712,32 @@ class FstImpl {
     if (mask != kError) {
       FSTERROR() << "FstImpl::SetProperties() const: Can only set kError";
     }
-    properties_ |= kError;
+    properties_.fetch_or(kError, std::memory_order_relaxed);
+  }
+
+  // Sets the subset of the properties that have changed, in a thread-safe
+  // manner via atomic bitwise-or..
+  void UpdateProperties(uint64 props, uint64 mask) {
+    // If properties_ and props are compatible (for example kAcceptor and
+    // kNoAcceptor cannot both be set), the props can be or-ed in.
+    // Compatibility is ensured if props comes from ComputeProperties
+    // and properties_ is set correctly initially.  However
+    // relying on properties to be set correctly is too large an
+    // assumption, as many places set them incorrectly.
+    // Therefore, we or in only the newly discovered properties.
+    // These cannot become inconsistent, but this means that
+    // incorrectly set properties will remain incorrect.
+    const uint64 properties = properties_.load(std::memory_order_relaxed);
+    DCHECK(internal::CompatProperties(properties, props));
+    const uint64 old_props = properties & mask;
+    const uint64 old_mask = internal::KnownProperties(old_props);
+    const uint64 discovered_mask = mask & ~old_mask;
+    const uint64 discovered_props = props & discovered_mask;
+    // It is always correct to or these bits in, but do this only when
+    // necessary to avoid extra stores and possible cache flushes.
+    if (discovered_props != 0) {
+      properties_.fetch_or(discovered_props, std::memory_order_relaxed);
+    }
   }
 
   const SymbolTable *InputSymbols() const { return isymbols_.get(); }
@@ -722,7 +772,7 @@ class FstImpl {
       hdr->SetFstType(type_);
       hdr->SetArcType(Arc::Type());
       hdr->SetVersion(version);
-      hdr->SetProperties(properties_);
+      hdr->SetProperties(properties_.load(std::memory_order_relaxed));
       int32 file_flags = 0;
       if (isymbols_ && opts.write_isymbols) {
         file_flags |= FstHeader::HAS_ISYMBOLS;
@@ -798,7 +848,10 @@ class FstImpl {
   }
 
  protected:
-  mutable uint64 properties_;  // Property bits.
+  // Use atomic so that UpdateProperties() can be thread-safe.
+  // This is always used with memory_order_relaxed because it's only used
+  // as a cache and not used to synchronize other operations.
+  mutable std::atomic<uint64> properties_;  // Property bits.
 
  private:
   std::string type_;  // Unique name of FST class.
@@ -845,7 +898,7 @@ bool FstImpl<Arc>::ReadHeader(std::istream &strm, const FstReadOptions &opts,
                << ": " << opts.source;
     return false;
   }
-  properties_ = hdr->Properties();
+  properties_.store(hdr->Properties(), std::memory_order_relaxed);
   if (hdr->GetFlags() & FstHeader::HAS_ISYMBOLS) {
     isymbols_.reset(SymbolTable::Read(strm, opts.source));
   }
@@ -865,13 +918,15 @@ bool FstImpl<Arc>::ReadHeader(std::istream &strm, const FstReadOptions &opts,
   return true;
 }
 
-}  // namespace internal
-
 template <class Arc>
 uint64 TestProperties(const Fst<Arc> &fst, uint64 mask, uint64 *known);
 
+}  // namespace internal
+
 // This is a helper class template useful for attaching an FST interface to
 // its implementation, handling reference counting.
+// Thread-unsafe due to Properties (a const function) calling
+// Impl::SetProperties.  TODO(jrosenstock): Make thread-compatible.
 // Impl's copy constructor must produce a thread-safe copy.
 template <class Impl, class FST = Fst<typename Impl::Arc>>
 class ImplToFst : public FST {
@@ -894,10 +949,15 @@ class ImplToFst : public FST {
     return impl_->NumOutputEpsilons(s);
   }
 
+  // Note that this is a const function, but can set the Impl's properties
+  // when test is true.
   uint64 Properties(uint64 mask, bool test) const override {
     if (test) {
-      uint64 knownprops, testprops = TestProperties(*this, mask, &knownprops);
-      impl_->SetProperties(testprops, knownprops);
+      uint64 knownprops,
+          testprops = internal::TestProperties(*this, mask, &knownprops);
+      // Properties is a const member function, but can set the cached
+      // properties.  UpdateProperties does this thread-safely via atomics.
+      impl_->UpdateProperties(testprops, knownprops);
       return testprops & mask;
     } else {
       return impl_->Properties(mask);
@@ -917,6 +977,8 @@ class ImplToFst : public FST {
  protected:
   explicit ImplToFst(std::shared_ptr<Impl> impl) : impl_(std::move(impl)) {}
 
+  // The object is thread-compatible if constructed with safe=true,
+  // otherwise thread-unsafe.
   // This constructor presumes there is a copy constructor for the
   // implementation that produces a thread-safe copy.
   ImplToFst(const ImplToFst &fst, bool safe) {
index e76d61d..a44b149 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <fst/compat.h>
 #include <fst/types.h>
+#include <fst/log.h>
 
 namespace fst {
 
@@ -471,6 +472,39 @@ uint64 AddArcProperties(uint64 inprops, typename Arc::StateId s,
 
 extern const char *PropertyNames[];
 
+namespace internal {
+
+// For a binary property, the bit is always returned set. For a trinary (i.e.,
+// two-bit) property, both bits are returned set iff either corresponding input
+// bit is set.
+inline uint64 KnownProperties(uint64 props) {
+  return kBinaryProperties | (props & kTrinaryProperties) |
+         ((props & kPosTrinaryProperties) << 1) |
+         ((props & kNegTrinaryProperties) >> 1);
+}
+
+// Tests compatibility between two sets of properties.
+inline bool CompatProperties(uint64 props1, uint64 props2) {
+  const auto known_props1 = KnownProperties(props1);
+  const auto known_props2 = KnownProperties(props2);
+  const auto known_props = known_props1 & known_props2;
+  const auto incompat_props = (props1 & known_props) ^ (props2 & known_props);
+  if (incompat_props) {
+    uint64 prop = 1;
+    for (int i = 0; i < 64; ++i, prop <<= 1) {
+      if (prop & incompat_props) {
+        LOG(ERROR) << "CompatProperties: Mismatch: " << PropertyNames[i]
+                   << ": props1 = " << (props1 & prop ? "true" : "false")
+                   << ", props2 = " << (props2 & prop ? "true" : "false");
+      }
+    }
+    return false;
+  } else {
+    return true;
+  }
+}
+
+}  // namespace internal
 }  // namespace fst
 
 #endif  // FST_PROPERTIES_H_
index 73108b4..8fd41e9 100644 (file)
@@ -7,6 +7,9 @@
 #ifndef FST_RANDEQUIVALENT_H_
 #define FST_RANDEQUIVALENT_H_
 
+#include <random>
+
+#include <fst/types.h>
 #include <fst/log.h>
 
 #include <fst/arcsort.h>
@@ -28,9 +31,9 @@ namespace fst {
 // generated path and checks that these two values are within a user-specified
 // delta. Returns optional error value (when FLAGS_error_fatal = false).
 template <class Arc, class ArcSelector>
-bool RandEquivalent(const Fst<Arc> &fst1, const Fst<Arc> &fst2,
-                    int32 num_paths, float delta,
+bool RandEquivalent(const Fst<Arc> &fst1, const Fst<Arc> &fst2, int32 npath,
                     const RandGenOptions<ArcSelector> &opts,
+                    float delta = kDelta, uint64 seed = std::random_device()(),
                     bool *error = nullptr) {
   using Weight = typename Arc::Weight;
   if (error) *error = false;
@@ -52,9 +55,11 @@ bool RandEquivalent(const Fst<Arc> &fst1, const Fst<Arc> &fst2,
   ArcSort(&sfst1, icomp);
   ArcSort(&sfst2, icomp);
   bool result = true;
-  for (int32 n = 0; n < num_paths; ++n) {
+  std::mt19937 rand(seed);
+  std::bernoulli_distribution coin(.5);
+  for (int32 n = 0; n < npath; ++n) {
     VectorFst<Arc> path;
-    const auto &fst = rand() % 2 ? sfst1 : sfst2;  // NOLINT
+    const auto &fst = coin(rand) ? sfst1 : sfst2;
     RandGen(fst, &path, opts);
     VectorFst<Arc> ipath(path);
     VectorFst<Arc> opath(path);
@@ -95,18 +100,18 @@ bool RandEquivalent(const Fst<Arc> &fst1, const Fst<Arc> &fst2,
   return result;
 }
 
-// Tests if two FSTs are equivalent by randomly generating a nnum_paths paths
+// Tests if two FSTs are equivalent by randomly generating a nnpath paths
 // (no longer than the path_length) using a user-specified seed, optionally
 // indicating an error setting an optional error argument to true.
 template <class Arc>
-bool RandEquivalent(const Fst<Arc> &fst1, const Fst<Arc> &fst2, int32 num_paths,
-                    float delta = kDelta, time_t seed = time(nullptr),
+bool RandEquivalent(const Fst<Arc> &fst1, const Fst<Arc> &fst2, int32 npath,
+                    float delta = kDelta, uint64 seed = std::random_device()(),
                     int32 max_length = std::numeric_limits<int32>::max(),
                     bool *error = nullptr) {
   const UniformArcSelector<Arc> uniform_selector(seed);
   const RandGenOptions<UniformArcSelector<Arc>> opts(uniform_selector,
                                                      max_length);
-  return RandEquivalent(fst1, fst2, num_paths, delta, opts, error);
+  return RandEquivalent(fst1, fst2, npath, opts, delta, seed, error);
 }
 
 }  // namespace fst
index c9497bf..cdad394 100644 (file)
@@ -55,10 +55,8 @@ class UniformArcSelector {
   using StateId = typename Arc::StateId;
   using Weight = typename Arc::Weight;
 
-  // Constructs a selector with a non-deterministic seed.
-  UniformArcSelector() : rand_(std::random_device()()) {}
-  // Constructs a selector with a given seed.
-  explicit UniformArcSelector(uint64 seed) : rand_(seed) {}
+  explicit UniformArcSelector(uint64 seed = std::random_device()())
+      : rand_(seed) {}
 
   size_t operator()(const Fst<Arc> &fst, StateId s) const {
     const auto n = fst.NumArcs(s) + (fst.Final(s) != Weight::Zero());
@@ -83,6 +81,7 @@ class LogProbArcSelector {
 
   // Constructs a selector with a non-deterministic seed.
   LogProbArcSelector() : seed_(std::random_device()()), rand_(seed_) {}
+
   // Constructs a selector with a given seed.
   explicit LogProbArcSelector(uint64 seed) : seed_(seed), rand_(seed) {}
 
@@ -750,8 +749,9 @@ void RandGen(const Fst<FromArc> &ifst, MutableFst<ToArc> *ofst,
 // Randomly generate a path through an FST with the uniform distribution
 // over the transitions.
 template <class FromArc, class ToArc>
-void RandGen(const Fst<FromArc> &ifst, MutableFst<ToArc> *ofst) {
-  const UniformArcSelector<FromArc> uniform_selector;
+void RandGen(const Fst<FromArc> &ifst, MutableFst<ToArc> *ofst,
+             uint64 seed = std::random_device()()) {
+  const UniformArcSelector<FromArc> uniform_selector(seed);
   RandGenOptions<UniformArcSelector<ToArc>> opts(uniform_selector);
   RandGen(ifst, ofst, opts);
 }
index 3a1f4bf..d11b121 100644 (file)
@@ -4,8 +4,6 @@
 #ifndef FST_SCRIPT_RANDEQUIVALENT_H_
 #define FST_SCRIPT_RANDEQUIVALENT_H_
 
-#include <climits>
-#include <ctime>
 #include <tuple>
 
 #include <fst/types.h>
@@ -17,8 +15,9 @@
 namespace fst {
 namespace script {
 
-using RandEquivalentInnerArgs = std::tuple<const FstClass &, const FstClass &,
-    int32, float, time_t, const RandGenOptions<RandArcSelection> &>;
+using RandEquivalentInnerArgs =
+    std::tuple<const FstClass &, const FstClass &, int32,
+               const RandGenOptions<RandArcSelection> &, float, uint64>;
 
 using RandEquivalentArgs = WithReturnValue<bool, RandEquivalentInnerArgs>;
 
@@ -26,40 +25,39 @@ template <class Arc>
 void RandEquivalent(RandEquivalentArgs *args) {
   const Fst<Arc> &fst1 = *std::get<0>(args->args).GetFst<Arc>();
   const Fst<Arc> &fst2 = *std::get<1>(args->args).GetFst<Arc>();
-  const auto seed = std::get<4>(args->args);
-  const auto &opts = std::get<5>(args->args);
+  const int32 npath = std::get<2>(args->args);
+  const auto &opts = std::get<3>(args->args);
+  const float delta = std::get<4>(args->args);
+  const uint64 seed = std::get<5>(args->args);
   switch (opts.selector) {
     case UNIFORM_ARC_SELECTOR: {
       const UniformArcSelector<Arc> selector(seed);
       const RandGenOptions<UniformArcSelector<Arc>> ropts(selector,
                                                           opts.max_length);
-      args->retval = RandEquivalent(fst1, fst2, std::get<2>(args->args),
-                                    std::get<3>(args->args), ropts);
+      args->retval = RandEquivalent(fst1, fst2, npath, ropts, delta, seed);
       return;
     }
     case FAST_LOG_PROB_ARC_SELECTOR: {
       const FastLogProbArcSelector<Arc> selector(seed);
       const RandGenOptions<FastLogProbArcSelector<Arc>> ropts(selector,
                                                               opts.max_length);
-      args->retval = RandEquivalent(fst1, fst2, std::get<2>(args->args),
-                                    std::get<3>(args->args), ropts);
+      args->retval = RandEquivalent(fst1, fst2, npath, ropts, delta, seed);
       return;
     }
     case LOG_PROB_ARC_SELECTOR: {
       const LogProbArcSelector<Arc> selector(seed);
       const RandGenOptions<LogProbArcSelector<Arc>> ropts(selector,
                                                           opts.max_length);
-      args->retval = RandEquivalent(fst1, fst2, std::get<2>(args->args),
-                                    std::get<3>(args->args), ropts);
+      args->retval = RandEquivalent(fst1, fst2, npath, ropts, delta, seed);
       return;
     }
   }
 }
 
 bool RandEquivalent(const FstClass &fst1, const FstClass &fst2, int32 npath = 1,
-    float delta = kDelta, time_t seed = time(nullptr),
-    const RandGenOptions<RandArcSelection> &opts =
-        RandGenOptions<RandArcSelection>(UNIFORM_ARC_SELECTOR));
+                    const RandGenOptions<RandArcSelection> &opts =
+                        RandGenOptions<RandArcSelection>(UNIFORM_ARC_SELECTOR),
+                    float delta = kDelta, uint64 seed = std::random_device()());
 
 }  // namespace script
 }  // namespace fst
index 5f7a4a8..3eb9734 100644 (file)
@@ -4,9 +4,10 @@
 #ifndef FST_SCRIPT_RANDGEN_H_
 #define FST_SCRIPT_RANDGEN_H_
 
-#include <ctime>
+#include <random>
 #include <tuple>
 
+#include <fst/types.h>
 #include <fst/randgen.h>
 #include <fst/script/fst-class.h>
 #include <fst/script/script-impl.h>
 namespace fst {
 namespace script {
 
-using RandGenArgs = std::tuple<const FstClass &, MutableFstClass *, time_t,
-                               const RandGenOptions<RandArcSelection> &>;
+using RandGenArgs =
+    std::tuple<const FstClass &, MutableFstClass *,
+               const RandGenOptions<RandArcSelection> &, uint64>;
 
 template <class Arc>
 void RandGen(RandGenArgs *args) {
   const Fst<Arc> &ifst = *std::get<0>(*args).GetFst<Arc>();
   MutableFst<Arc> *ofst = std::get<1>(*args)->GetMutableFst<Arc>();
-  const time_t seed = std::get<2>(*args);
-  const auto &opts = std::get<3>(*args);
+  const auto &opts = std::get<2>(*args);
+  const uint64 seed = std::get<3>(*args);
   switch (opts.selector) {
     case UNIFORM_ARC_SELECTOR: {
       const UniformArcSelector<Arc> selector(seed);
@@ -52,9 +54,9 @@ void RandGen(RandGenArgs *args) {
 }
 
 void RandGen(const FstClass &ifst, MutableFstClass *ofst,
-             time_t seed = time(nullptr),
              const RandGenOptions<RandArcSelection> &opts =
-                 RandGenOptions<RandArcSelection>(UNIFORM_ARC_SELECTOR));
+                 RandGenOptions<RandArcSelection>(UNIFORM_ARC_SELECTOR),
+             uint64 seed = std::random_device()());
 
 }  // namespace script
 }  // namespace fst
index 25facc9..0680fe1 100644 (file)
@@ -270,12 +270,14 @@ bool StringFstToOutputLabels(const Fst<Arc> &fst,
     s = arc.nextstate;
     aiter.Next();
     if (!aiter.Done()) {
-      LOG(ERROR) << "StringFstToOutputLabels: State has multiple outgoing arcs";
+      LOG(ERROR) << "StringFstToOutputLabels: State " << s
+                 << " has multiple outgoing arcs";
       return false;
     }
   }
   if (fst.NumArcs(s) != 0) {
-    LOG(ERROR) << "StringFstToOutputLabels: Final state has outgoing arc(s)";
+    LOG(ERROR) << "StringFstToOutputLabels: Final state " << s
+               << " has outgoing arc(s)";
     return false;
   }
   return true;
index 8d9c678..b0ea483 100644 (file)
@@ -10,7 +10,6 @@
 
 #include <fst/flags.h>
 #include <fst/types.h>
-#include <fst/log.h>
 
 #include <fst/connect.h>
 #include <fst/dfs-visit.h>
 DECLARE_bool(fst_verify_properties);
 
 namespace fst {
-// namespace internal {
-
-// For a binary property, the bit is always returned set. For a trinary (i.e.,
-// two-bit) property, both bits are returned set iff either corresponding input
-// bit is set.
-inline uint64 KnownProperties(uint64 props) {
-  return kBinaryProperties | (props & kTrinaryProperties) |
-         ((props & kPosTrinaryProperties) << 1) |
-         ((props & kNegTrinaryProperties) >> 1);
-}
-
-// Tests compatibility between two sets of properties.
-inline bool CompatProperties(uint64 props1, uint64 props2) {
-  const auto known_props1 = KnownProperties(props1);
-  const auto known_props2 = KnownProperties(props2);
-  const auto known_props = known_props1 & known_props2;
-  const auto incompat_props = (props1 & known_props) ^ (props2 & known_props);
-  if (incompat_props) {
-    uint64 prop = 1;
-    for (int i = 0; i < 64; ++i, prop <<= 1) {
-      if (prop & incompat_props) {
-        LOG(ERROR) << "CompatProperties: Mismatch: " << PropertyNames[i]
-                   << ": props1 = " << (props1 & prop ? "true" : "false")
-                   << ", props2 = " << (props2 & prop ? "true" : "false");
-      }
-    }
-    return false;
-  } else {
-    return true;
-  }
-}
+namespace internal {
 
 // Computes FST property values defined in properties.h. The value of each
 // property indicated in the mask will be determined and returned (these will
@@ -57,42 +26,31 @@ inline bool CompatProperties(uint64 props1, uint64 props2) {
 // determined (those with little additional expense) and their values will be
 // returned as well. The complete set of known properties (whether true or
 // false) determined by this operation will be assigned to the the value pointed
-// to by KNOWN. If 'use_stored' is true, pre-computed FST properties may be used
-// when possible. 'mask & required_mask' is used to determine whether the stored
-// propertoes can be used. This routine is seldom called directly; instead it is
-// used to implement fst.Properties(mask, true).
+// to by KNOWN. 'mask & required_mask' is used to determine whether the stored
+// properties can be used. This routine is seldom called directly; instead it is
+// used to implement fst.Properties(mask, /*test=*/true).
 template <class Arc>
-uint64 ComputeProperties(const Fst<Arc> &fst, uint64 mask, uint64 *known,
-                         bool use_stored) {
+uint64 ComputeProperties(const Fst<Arc> &fst, uint64 mask, uint64 *known) {
   using Label = typename Arc::Label;
   using StateId = typename Arc::StateId;
   using Weight = typename Arc::Weight;
   const auto fst_props = fst.Properties(kFstProperties, false);  // FST-stored.
-  // Check stored FST properties first if allowed.
-  if (use_stored) {
-    const auto known_props = KnownProperties(fst_props);
-    // If FST contains required info, return it.
-    if ((known_props & mask) == mask) {
-      if (known) *known = known_props;
-      return fst_props;
-    }
-  }
   // Computes (trinary) properties explicitly.
   // Initialize with binary properties (already known).
   uint64 comp_props = fst_props & kBinaryProperties;
   // Computes these trinary properties with a DFS. We compute only those that
   // need a DFS here, since we otherwise would like to avoid a DFS since its
   // stack could grow large.
-  uint64 dfs_props = kCyclic | kAcyclic | kInitialCyclic | kInitialAcyclic |
-                     kAccessible | kNotAccessible | kCoAccessible |
-                     kNotCoAccessible;
+  constexpr uint64 kDfsProps = kCyclic | kAcyclic | kInitialCyclic |
+                               kInitialAcyclic | kAccessible | kNotAccessible |
+                               kCoAccessible | kNotCoAccessible;
   std::vector<StateId> scc;
-  if (mask & (dfs_props | kWeightedCycles | kUnweightedCycles)) {
+  if (mask & (kDfsProps | kWeightedCycles | kUnweightedCycles)) {
     SccVisitor<Arc> scc_visitor(&scc, nullptr, nullptr, &comp_props);
     DfsVisit(fst, &scc_visitor);
   }
   // Computes any remaining trinary properties via a state and arcs iterations
-  if (mask & ~(kBinaryProperties | dfs_props)) {
+  if (mask & ~(kBinaryProperties | kDfsProps)) {
     comp_props |= kAcceptor | kNoEpsilons | kNoIEpsilons | kNoOEpsilons |
                   kILabelSorted | kOLabelSorted | kUnweighted | kTopSorted |
                   kString;
@@ -102,7 +60,7 @@ uint64 ComputeProperties(const Fst<Arc> &fst, uint64 mask, uint64 *known,
     if (mask & (kODeterministic | kNonODeterministic)) {
       comp_props |= kODeterministic;
     }
-    if (mask & (dfs_props | kWeightedCycles | kUnweightedCycles)) {
+    if (mask & (kDfsProps | kWeightedCycles | kUnweightedCycles)) {
       comp_props |= kUnweightedCycles;
     }
     std::unique_ptr<std::unordered_set<Label>> ilabels;
@@ -205,22 +163,39 @@ uint64 ComputeProperties(const Fst<Arc> &fst, uint64 mask, uint64 *known,
   return comp_props;
 }
 
+// Similar to ComputeProperties, but uses the properties already stored
+// in the FST when possible.
+template <class Arc>
+uint64 ComputeOrUseStoredProperties(const Fst<Arc> &fst, uint64 mask,
+                                    uint64 *known) {
+  // Check stored FST properties first.
+  const auto fst_props = fst.Properties(kFstProperties, /*test=*/false);
+  const auto known_props = KnownProperties(fst_props);
+  // If FST contains required info, return it.
+  if ((known_props & mask) == mask) {
+    if (known) *known = known_props;
+    return fst_props;
+  }
+
+  return ComputeProperties(fst, mask, known);
+}
+
 // This is a wrapper around ComputeProperties that will cause a fatal error if
 // the stored properties and the computed properties are incompatible when
 // FLAGS_fst_verify_properties is true. This routine is seldom called directly;
-// instead it is used to implement fst.Properties(mask, true).
+// instead it is used to implement fst.Properties(mask, /*test=*/true).
 template <class Arc>
 uint64 TestProperties(const Fst<Arc> &fst, uint64 mask, uint64 *known) {
   if (FLAGS_fst_verify_properties) {
     const auto stored_props = fst.Properties(kFstProperties, false);
-    const auto computed_props = ComputeProperties(fst, mask, known, false);
+    const auto computed_props = ComputeProperties(fst, mask, known);
     if (!CompatProperties(stored_props, computed_props)) {
       FSTERROR() << "TestProperties: stored FST properties incorrect"
                  << " (stored: props1, computed: props2)";
     }
     return computed_props;
   } else {
-    return ComputeProperties(fst, mask, known, true);
+    return ComputeOrUseStoredProperties(fst, mask, known);
   }
 }
 
@@ -233,14 +208,14 @@ uint64 CheckProperties(const Fst<Arc> &fst, uint64 check_mask,
                        uint64 test_mask) {
   auto props = fst.Properties(kFstProperties, false);
   if (FLAGS_fst_verify_properties) {
-    props = TestProperties(fst, check_mask | test_mask, nullptr);
+    props = TestProperties(fst, check_mask | test_mask, /*known=*/nullptr);
   } else if ((KnownProperties(props) & check_mask) != check_mask) {
-    props = ComputeProperties(fst, check_mask | test_mask, nullptr, false);
+    props = ComputeProperties(fst, check_mask | test_mask, /*known=*/nullptr);
   }
   return props & (check_mask | test_mask);
 }
 
-//}  // namespace internal
+}  // namespace internal
 }  // namespace fst
 
 #endif  // FST_TEST_PROPERTIES_H_
index e585551..9b8049b 100644 (file)
@@ -896,10 +896,10 @@ class WeightedTester {
     CHECK(Verify(fst2));
 
     // Ensures seed used once per instantiation.
-    static UniformArcSelector<A> uniform_selector(seed_);
+    static const UniformArcSelector<A> uniform_selector(seed_);
     RandGenOptions<UniformArcSelector<A>> opts(uniform_selector,
                                                kRandomPathLength);
-    return RandEquivalent(fst1, fst2, kNumRandomPaths, kTestDelta, opts);
+    return RandEquivalent(fst1, fst2, kNumRandomPaths, opts, kTestDelta, seed_);
   }
 
   // Tests FSA is unambiguous
@@ -928,7 +928,7 @@ class WeightedTester {
     }
 
     // Ensures seed used once per instantiation.
-    static UniformArcSelector<A> uniform_selector(seed_);
+    static const UniformArcSelector<A> uniform_selector(seed_);
     RandGenOptions<UniformArcSelector<A>> opts(uniform_selector,
                                                kRandomPathLength);
 
index b3e3f8f..75774af 100644 (file)
@@ -7,6 +7,7 @@
 #define FST_VECTOR_FST_H_
 
 #include <algorithm>
+#include <atomic>
 #include <string>
 #include <utility>
 #include <vector>
@@ -506,6 +507,8 @@ VectorFstImpl<S> *VectorFstImpl<S>::Read(std::istream &strm,
 // and handles reference counting, delegating most methods to ImplToMutableFst.
 // Also supports ReserveStates and ReserveArcs methods (cf. STL vector methods).
 // The second optional template argument gives the State definition.
+//
+// VectorFst is thread-compatible.
 template <class A, class S /* = VectorState<A> */>
 class VectorFst : public ImplToMutableFst<internal::VectorFstImpl<S>> {
  public:
@@ -527,8 +530,8 @@ class VectorFst : public ImplToMutableFst<internal::VectorFstImpl<S>> {
   explicit VectorFst(const Fst<Arc> &fst)
       : ImplToMutableFst<Impl>(std::make_shared<Impl>(fst)) {}
 
-  VectorFst(const VectorFst &fst, bool safe = false)
-      : ImplToMutableFst<Impl>(fst) {}
+  VectorFst(const VectorFst &fst, bool unused_safe = false)
+      : ImplToMutableFst<Impl>(fst.GetSharedImpl()) {}
 
   VectorFst(VectorFst &&) noexcept;
 
@@ -749,39 +752,41 @@ class MutableArcIterator<VectorFst<Arc, State>>
 
   void SetValue(const Arc &arc) final {
     const auto &oarc = state_->GetArc(i_);
-    if (oarc.ilabel != oarc.olabel) *properties_ &= ~kNotAcceptor;
+    uint64 properties = properties_->load(std::memory_order_relaxed);
+    if (oarc.ilabel != oarc.olabel) properties &= ~kNotAcceptor;
     if (oarc.ilabel == 0) {
-      *properties_ &= ~kIEpsilons;
-      if (oarc.olabel == 0) *properties_ &= ~kEpsilons;
+      properties &= ~kIEpsilons;
+      if (oarc.olabel == 0) properties &= ~kEpsilons;
     }
-    if (oarc.olabel == 0) *properties_ &= ~kOEpsilons;
+    if (oarc.olabel == 0) properties &= ~kOEpsilons;
     if (oarc.weight != Weight::Zero() && oarc.weight != Weight::One()) {
-      *properties_ &= ~kWeighted;
+      properties &= ~kWeighted;
     }
     state_->SetArc(arc, i_);
     if (arc.ilabel != arc.olabel) {
-      *properties_ |= kNotAcceptor;
-      *properties_ &= ~kAcceptor;
+      properties |= kNotAcceptor;
+      properties &= ~kAcceptor;
     }
     if (arc.ilabel == 0) {
-      *properties_ |= kIEpsilons;
-      *properties_ &= ~kNoIEpsilons;
+      properties |= kIEpsilons;
+      properties &= ~kNoIEpsilons;
       if (arc.olabel == 0) {
-        *properties_ |= kEpsilons;
-        *properties_ &= ~kNoEpsilons;
+        properties |= kEpsilons;
+        properties &= ~kNoEpsilons;
       }
     }
     if (arc.olabel == 0) {
-      *properties_ |= kOEpsilons;
-      *properties_ &= ~kNoOEpsilons;
+      properties |= kOEpsilons;
+      properties &= ~kNoOEpsilons;
     }
     if (arc.weight != Weight::Zero() && arc.weight != Weight::One()) {
-      *properties_ |= kWeighted;
-      *properties_ &= ~kUnweighted;
+      properties |= kWeighted;
+      properties &= ~kUnweighted;
     }
-    *properties_ &= kSetArcProperties | kAcceptor | kNotAcceptor | kEpsilons |
-                    kNoEpsilons | kIEpsilons | kNoIEpsilons | kOEpsilons |
-                    kNoOEpsilons | kWeighted | kUnweighted;
+    properties &= kSetArcProperties | kAcceptor | kNotAcceptor | kEpsilons |
+                  kNoEpsilons | kIEpsilons | kNoIEpsilons | kOEpsilons |
+                  kNoOEpsilons | kWeighted | kUnweighted;
+    properties_->store(properties, std::memory_order_relaxed);
   }
 
   uint8 Flags() const final { return kArcValueFlags; }
@@ -790,7 +795,7 @@ class MutableArcIterator<VectorFst<Arc, State>>
 
  private:
   State *state_;
-  uint64 *properties_;
+  std::atomic<uint64> *properties_;
   size_t i_;
 };
 
index b6074ae..fd00677 100644 (file)
@@ -76,15 +76,15 @@ bool Verify(const Fst<Arc> &fst, bool allow_negative_labels = false) {
       return false;
     }
   }
-  const auto fst_props = fst.Properties(kFstProperties, false);
+  const auto fst_props = fst.Properties(kFstProperties, /*test=*/false);
   if (fst_props & kError) {
     LOG(ERROR) << "Verify: FST error property is set";
     return false;
   }
   uint64 known_props;
   uint64 test_props =
-      ComputeProperties(fst, kFstProperties, &known_props, false);
-  if (!CompatProperties(fst_props, test_props)) {
+      internal::ComputeProperties(fst, kFstProperties, &known_props);
+  if (!internal::CompatProperties(fst_props, test_props)) {
     LOG(ERROR) << "Verify: Stored FST properties incorrect "
                << "(props1 = stored props, props2 = tested)";
     return false;
index 9e3c541..ec40722 100644 (file)
@@ -4,5 +4,5 @@ lib_LTLIBRARIES = libfst.la
 libfst_la_SOURCES = compat.cc encode.cc flags.cc fst.cc fst-types.cc \
                     mapped-file.cc properties.cc symbol-table.cc \
                     symbol-table-ops.cc weight.cc util.cc
-libfst_la_LDFLAGS = -version-info 19:0:0
+libfst_la_LDFLAGS = -version-info 20:0:0
 libfst_la_LIBADD = $(DL_LIBS)
index ae10d1a..b3d51f7 100644 (file)
@@ -355,7 +355,7 @@ libfst_la_SOURCES = compat.cc encode.cc flags.cc fst.cc fst-types.cc \
                     mapped-file.cc properties.cc symbol-table.cc \
                     symbol-table-ops.cc weight.cc util.cc
 
-libfst_la_LDFLAGS = -version-info 19:0:0
+libfst_la_LDFLAGS = -version-info 20:0:0
 libfst_la_LIBADD = $(DL_LIBS)
 all: all-am
 
index 15bb5dd..73f02b4 100644 (file)
@@ -69,6 +69,8 @@ void SetFlags(const char *usage, int *argc, char ***argv,
     if (int32_register->SetFlag(arg, val)) continue;
     auto int64_register = FlagRegister<int64>::GetRegister();
     if (int64_register->SetFlag(arg, val)) continue;
+    auto uint64_register = FlagRegister<uint64>::GetRegister();
+    if (uint64_register->SetFlag(arg, val)) continue;
     auto double_register = FlagRegister<double>::GetRegister();
     if (double_register->SetFlag(arg, val)) continue;
     LOG(FATAL) << "SetFlags: Bad option: " << (*argv)[index];
@@ -130,6 +132,8 @@ void ShowUsage(bool long_usage) {
   int32_register->GetUsage(&usage_set);
   auto int64_register = FlagRegister<int64>::GetRegister();
   int64_register->GetUsage(&usage_set);
+  auto uint64_register = FlagRegister<uint64>::GetRegister();
+  uint64_register->GetUsage(&usage_set);
   auto double_register = FlagRegister<double>::GetRegister();
   double_register->GetUsage(&usage_set);
   if (!prog_src.empty()) {
index f1118ef..ea53976 100644 (file)
@@ -13,5 +13,5 @@ shortest-distance.cc shortest-path.cc stateiterator-class.cc synchronize.cc \
 text-io.cc topsort.cc union.cc weight-class.cc verify.cc
 
 libfstscript_la_LIBADD = ../lib/libfst.la -lm $(DL_LIBS)
-libfstscript_la_LDFLAGS = -version-info 19:0:0
+libfstscript_la_LDFLAGS = -version-info 20:0:0
 endif
index a5f5716..e2c3102 100644 (file)
@@ -407,7 +407,7 @@ AM_CPPFLAGS = -I$(srcdir)/../include $(ICU_CPPFLAGS)
 @HAVE_SCRIPT_TRUE@text-io.cc topsort.cc union.cc weight-class.cc verify.cc
 
 @HAVE_SCRIPT_TRUE@libfstscript_la_LIBADD = ../lib/libfst.la -lm $(DL_LIBS)
-@HAVE_SCRIPT_TRUE@libfstscript_la_LDFLAGS = -version-info 19:0:0
+@HAVE_SCRIPT_TRUE@libfstscript_la_LDFLAGS = -version-info 20:0:0
 all: all-am
 
 .SUFFIXES:
index b858ef6..40dcf5e 100644 (file)
@@ -9,10 +9,10 @@ namespace fst {
 namespace script {
 
 bool RandEquivalent(const FstClass &fst1, const FstClass &fst2, int32 npath,
-                    float delta, time_t seed,
-                    const RandGenOptions<RandArcSelection> &opts) {
+                    const RandGenOptions<RandArcSelection> &opts, float delta,
+                    uint64 seed) {
   if (!internal::ArcTypesMatch(fst1, fst2, "RandEquivalent")) return false;
-  RandEquivalentInnerArgs iargs(fst1, fst2, npath, delta, seed, opts);
+  RandEquivalentInnerArgs iargs(fst1, fst2, npath, opts, delta, seed);
   RandEquivalentArgs args(iargs);
   Apply<Operation<RandEquivalentArgs>>("RandEquivalent", fst1.ArcType(), &args);
   return args.retval;
index 92242ea..f0b10f7 100644 (file)
@@ -8,13 +8,13 @@
 namespace fst {
 namespace script {
 
-void RandGen(const FstClass &ifst, MutableFstClass *ofst, time_t seed,
-             const RandGenOptions<RandArcSelection> &opts) {
+void RandGen(const FstClass &ifst, MutableFstClass *ofst,
+             const RandGenOptions<RandArcSelection> &opts, uint64 seed) {
   if (!internal::ArcTypesMatch(ifst, *ofst, "RandGen")) {
     ofst->SetProperties(kError, kError);
     return;
   }
-  RandGenArgs args(ifst, ofst, seed, opts);
+  RandGenArgs args(ifst, ofst, opts, seed);
   Apply<Operation<RandGenArgs>>("RandGen", ifst.ArcType(), &args);
 }