Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package black-hole-solver for
openSUSE:Factory checked in at 2025-09-12 21:10:25
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/black-hole-solver (Old)
and /work/SRC/openSUSE:Factory/.black-hole-solver.new.1977 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "black-hole-solver"
Fri Sep 12 21:10:25 2025 rev:4 rq:1304218 version:1.14.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/black-hole-solver/black-hole-solver.changes
2022-12-13 18:55:48.927314744 +0100
+++
/work/SRC/openSUSE:Factory/.black-hole-solver.new.1977/black-hole-solver.changes
2025-09-12 21:11:24.879995219 +0200
@@ -1,0 +2,11 @@
+Fri Sep 12 07:04:29 UTC 2025 - Dirk Müller <[email protected]>
+
+- update to 1.4.0:
+ * Fixed running black_hole_solver_run with the same
+ (or a smaller) iterations limit. It ran indefinetely
+ then (Possible Denial-of-service?)
+ * Fix some hypothetical rresource leaks (e.g.: with "fopen()").
+ * Cleanups: add "const"s , convert "int" to "bool", etc.
+ * Add tests.
+
+-------------------------------------------------------------------
Old:
----
black-hole-solver-1.12.0.tar.xz
New:
----
black-hole-solver-1.14.0.tar.xz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ black-hole-solver.spec ++++++
--- /var/tmp/diff_new_pack.QcXA8L/_old 2025-09-12 21:11:25.476020350 +0200
+++ /var/tmp/diff_new_pack.QcXA8L/_new 2025-09-12 21:11:25.476020350 +0200
@@ -1,7 +1,7 @@
#
# spec file for package black-hole-solver
#
-# Copyright (c) 2022 SUSE LLC
+# Copyright (c) 2025 SUSE LLC and contributors
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -20,7 +20,7 @@
# Missing perl(Env::Path), should also skip some tests like build-process
%global run_tests 0
Name: black-hole-solver
-Version: 1.12.0
+Version: 1.14.0
Release: 0
Summary: The Black Hole Solver Executable
License: MIT
++++++ black-hole-solver-1.12.0.tar.xz -> black-hole-solver-1.14.0.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/black-hole-solver-1.12.0/CMakeLists.txt
new/black-hole-solver-1.14.0/CMakeLists.txt
--- old/black-hole-solver-1.12.0/CMakeLists.txt 2021-12-11 06:47:47.000000000
+0100
+++ new/black-hole-solver-1.14.0/CMakeLists.txt 2025-03-03 08:21:09.000000000
+0100
@@ -1,4 +1,4 @@
-CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
+CMAKE_MINIMUM_REQUIRED(VERSION 3.15)
PROJECT(black-hole-solver)
INCLUDE ("${CMAKE_SOURCE_DIR}/cmake/shlomif_common_bootstrap.cmake")
@@ -13,6 +13,8 @@
option (LINK_TO_STATIC "Link the executables to the static library")
option (DISABLE_APPLYING_RPATH "Disable applying rpath")
option (ENABLE_DISPLAYING_MAX_NUM_PLAYED_CARDS "Allow recording and displaying
the maximal number of played/\"moved\" cards. Enabling it may make the
non-related run time somewhat slower.")
+option (USE_SIGNED_CHARS "-fsigned-char")
+option (USE_UNSIGNED_CHARS "-funsigned-char")
INCLUDE(FindPkgConfig)
@@ -33,7 +35,7 @@
SET (BHS_STATE_STORAGE "BHS_STATE_STORAGE_INTERNAL_HASH" CACHE STRING "The
State Storage Type")
SET (FCS_IA_PACK_SIZE 64 CACHE STRING "Size of a single pack in kilo-bytes.")
-SET (IA_STATE_PACKS_GROW_BY 32 CACHE STRING "Amount to Grow State Packs By")
+SET (IA_STATE_PACKS_GROW_BY 32 CACHE STRING "Amount to Grow State Packs By (
UNUSED! Kept for backward compatibility. )")
SET (base_with_ver "black_hole_solver-[0-9]+\\\\.[0-9]+\\\\.[0-9]+")
SET(CPACK_SOURCE_GENERATOR "TXZ")
SET(CPACK_SOURCE_IGNORE_FILES
@@ -133,6 +135,7 @@
IF ("$ENV{FCS_CLANG}")
ADD_DEFINITIONS("-Weverything -Wno-language-extension-token
-Wno-gnu-statement-expression -Wno-used-but-marked-unused -Wno-padded
-Wno-cast-align -Wno-extra-semi-stmt")
+ ADD_DEFINITIONS("-Wno-declaration-after-statement")
ENDIF ()
IF ("$ENV{FCS_GCC}")
@@ -146,6 +149,15 @@
ENDIF ()
ADD_DEFINITIONS("-Wno-unknown-pragmas")
+IF (USE_UNSIGNED_CHARS)
+ ADD_DEFINITIONS("-funsigned-char")
+ IF (USE_SIGNED_CHARS)
+ MESSAGE(FATAL_ERROR "Cannot have both USE_SIGNED_CHARS and
USE_UNSIGNED_CHARS !")
+ ENDIF ()
+ELSEIF (USE_SIGNED_CHARS)
+ ADD_DEFINITIONS("-fsigned-char")
+ENDIF ()
+
# So it can find config.h
INCLUDE_DIRECTORIES(BEFORE "${CMAKE_CURRENT_SOURCE_DIR}")
INCLUDE_DIRECTORIES(BEFORE "${CMAKE_CURRENT_BINARY_DIR}")
@@ -207,7 +219,7 @@
)
SET_TARGET_PROPERTIES(
- "${LIB_BASE}" PROPERTIES VERSION 1.0.1 SOVERSION 1
+ "${LIB_BASE}" PROPERTIES VERSION 1.0.2 SOVERSION 1
)
SET (LIBS "${LIB_BASE}")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/black-hole-solver-1.12.0/NEWS.asciidoc
new/black-hole-solver-1.14.0/NEWS.asciidoc
--- old/black-hole-solver-1.12.0/NEWS.asciidoc 2022-03-28 12:28:47.000000000
+0200
+++ new/black-hole-solver-1.14.0/NEWS.asciidoc 2025-03-03 07:56:03.000000000
+0100
@@ -1,9 +1,21 @@
Black Hole Solver's News File
=============================
Shlomi Fish <[email protected]>
-:Date: 2020-06-28
+:Date: 2025-03-03
:Revision: $Id$
+1.14.0 ( 03 March 2025 ):
+-------------------------------
+
+* Fixed running black_hole_solver_run with the same (or a smaller) iterations
+limit. It ran indefinetely then (Possible Denial-of-service?)
+
+* Fix some hypothetical rresource leaks (e.g.: with "fopen()").
+
+* Cleanups: add "const"s , convert "int" to "bool", etc.
+
+* Add tests.
+
1.12.0 ( 28 March 2022 ):
-------------------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/black-hole-solver-1.12.0/black-hole-solver.spec
new/black-hole-solver-1.14.0/black-hole-solver.spec
--- old/black-hole-solver-1.12.0/black-hole-solver.spec 2022-03-28
12:29:16.000000000 +0200
+++ new/black-hole-solver-1.14.0/black-hole-solver.spec 2025-03-03
07:57:04.000000000 +0100
@@ -1,5 +1,5 @@
Name: black-hole-solver
-Version: 1.12.0
+Version: 1.14.0
Release: 1
License: MIT
Group: Amusement/Games
@@ -41,22 +41,20 @@
Group: Amusement/Games
%description -n libblack_hole_solver1
-Contains the Blach Hole Solitaire libraries.
+Contains the Black Hole Solitaire libraries.
This package is mandatory for the Black Hole Solitaire executable too.
%package -n libblack_hole_solver1-devel
-Summary: The Freecell Solver development tools for solving Freecell games
+Summary: The Black Hole Solitaire development tools
Group: Amusement/Games
Requires: libblack_hole_solver1 = %{version}
%description -n libblack_hole_solver1-devel
-Freecell Solver is a library for automatically solving boards of Freecell and
-similar variants of card Solitaire. This package contains the header files and
-static libraries necessary for developing programs using Freecell Solver.
+Contains the Black Hole Solitaire development libraries.
You should install it if you are a game developer who would like to use
-Freecell Solver from within your programs.
+Black Hole Solitaire Solver from within your programs.
%prep
%setup
@@ -92,81 +90,5 @@
rm -rf $RPM_BUILD_ROOT
%changelog
-* Tue Mar 31 2009 Shlomi Fish <[email protected]> 2.21.2-1
-- Adapted to the CMake build system.
-- Changed the license from "Public Domain" to "MIT".
-
-* Mon Oct 24 2005 Shlomi Fish <[email protected]> 2.8.11-1
-- Changed "Copyright" to "License"
-
-* Fri Jul 30 2004 Shlomi Fish <[email protected]> 2.8.7-1
-- Added some unpackaged files
-- deleted make-microsoft-freecell-board so it won't be reported as
- unpacked
-- removed some old cd's that are now useless
-- removed the serial tags - they are just trouble.
-
-* Mon Sep 02 2002 Shlomi Fish <[email protected]> 2.7.15-1
-- Used strip on the range solver
-- Added the presets' related files
-
-* Sat Feb 16 2002 Shlomi Fish <[email protected]> 2.1.10-1
-- updated to version 2.1.10
-- removed the man pages symlinks (they were superceded by the ".so" links).
-
-* Fri Jan 04 2002 Shlomi Fish <[email protected]> 2.0.1-1
-- updated to version 2.0.1
-- added freecell-solver-range-parallel-solve to the /usr/bin programs
-
-* Tue Dec 18 2001 Shlomi Fish <[email protected]> 2.0.0-1
-- updated to version 2.0.0
-
-* Fri Nov 23 2001 Shlomi Fish <[email protected]> 1.10.3-1
-- updated to version 1.10.3
-
-* Thu Nov 22 2001 Shlomi Fish <[email protected]> 1.10.2-1
-- updated to version 1.10.2
-
-* Tue Oct 02 2001 Shlomi Fish <[email protected]> 1.10.0-1
-- updated to version 1.10.0
-
-* Sat Sep 22 2001 Shlomi Fish <[email protected]> 1.8.2-1
-- updated to version 1.8.2
-
-* Sat Sep 01 2001 Shlomi Fish <[email protected]> 1.8.0-1
-- Changed the version to 1.8.0
-- Removed the -autconf suffix from the archive.
-
-* Sat Jul 07 2001 Shlomi Fish <[email protected]> 1.6.7-2
-- Fixed the man pages.
-- Included a paragraph about the board_gen programs in the description of
- the executable package.
-
-* Sat Jun 09 2001 Shlomi Fish <[email protected]> 1.6.7-1
-- Changed the version to 1.6.7.
-- Added support for the man pages.
-- Added the symlinked man pages.
-- Added the board_gen sub-dir in the documentation directory. (using a rather
-crude hack)
-- Known Bugs:
- 1 - The man pages need a little rework, there are some typos and they
- don't look very standard.
-
-
-* Thu May 24 2001 Shlomi Fish <[email protected]> 1.6.4-3
-- Added the board generation programs into the RPM.
-- Changed the package to my name and E-mail. Done through the home-dir conf
-file, not by editting the SPEC, but what the heck.
-
-* Sat May 19 2001 Shlomi Fish <[email protected]> 1.6.4-2
-- Changed the descriptions and summaries to something more meaningful
-- Removed the dependency on "Serial" in "Requires".
-
-* Fri May 18 2001 Shlomi Fish <[email protected]> 1.6.4-1
-- First working version with libs and executable support.
-- Known Bugs:
- 1 - No "devel" package.
- 2 - No options passed to "configure".
-- Added calls to strip.
-- "configure" is now OK with all the options set.
-- Added Headers and a working freecell-solver-devel
+* Mon Feb 10 2025 Shlomi Fish <[email protected]> 1.12.0-1
+- Trim the old, freecell-solver, changelog.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/black-hole-solver-1.12.0/black-hole-solver.spec.in
new/black-hole-solver-1.14.0/black-hole-solver.spec.in
--- old/black-hole-solver-1.12.0/black-hole-solver.spec.in 2020-11-27
09:09:50.000000000 +0100
+++ new/black-hole-solver-1.14.0/black-hole-solver.spec.in 2025-02-10
11:00:17.000000000 +0100
@@ -41,22 +41,20 @@
Group: Amusement/Games
%description -n libblack_hole_solver1
-Contains the Blach Hole Solitaire libraries.
+Contains the Black Hole Solitaire libraries.
This package is mandatory for the Black Hole Solitaire executable too.
%package -n libblack_hole_solver1-devel
-Summary: The Freecell Solver development tools for solving Freecell games
+Summary: The Black Hole Solitaire development tools
Group: Amusement/Games
Requires: libblack_hole_solver1 = %{version}
%description -n libblack_hole_solver1-devel
-Freecell Solver is a library for automatically solving boards of Freecell and
-similar variants of card Solitaire. This package contains the header files and
-static libraries necessary for developing programs using Freecell Solver.
+Contains the Black Hole Solitaire development libraries.
You should install it if you are a game developer who would like to use
-Freecell Solver from within your programs.
+Black Hole Solitaire Solver from within your programs.
%prep
%setup
@@ -92,81 +90,5 @@
rm -rf $RPM_BUILD_ROOT
%changelog
-* Tue Mar 31 2009 Shlomi Fish <[email protected]> 2.21.2-1
-- Adapted to the CMake build system.
-- Changed the license from "Public Domain" to "MIT".
-
-* Mon Oct 24 2005 Shlomi Fish <[email protected]> 2.8.11-1
-- Changed "Copyright" to "License"
-
-* Fri Jul 30 2004 Shlomi Fish <[email protected]> 2.8.7-1
-- Added some unpackaged files
-- deleted make-microsoft-freecell-board so it won't be reported as
- unpacked
-- removed some old cd's that are now useless
-- removed the serial tags - they are just trouble.
-
-* Mon Sep 02 2002 Shlomi Fish <[email protected]> 2.7.15-1
-- Used strip on the range solver
-- Added the presets' related files
-
-* Sat Feb 16 2002 Shlomi Fish <[email protected]> 2.1.10-1
-- updated to version 2.1.10
-- removed the man pages symlinks (they were superceded by the ".so" links).
-
-* Fri Jan 04 2002 Shlomi Fish <[email protected]> 2.0.1-1
-- updated to version 2.0.1
-- added freecell-solver-range-parallel-solve to the /usr/bin programs
-
-* Tue Dec 18 2001 Shlomi Fish <[email protected]> 2.0.0-1
-- updated to version 2.0.0
-
-* Fri Nov 23 2001 Shlomi Fish <[email protected]> 1.10.3-1
-- updated to version 1.10.3
-
-* Thu Nov 22 2001 Shlomi Fish <[email protected]> 1.10.2-1
-- updated to version 1.10.2
-
-* Tue Oct 02 2001 Shlomi Fish <[email protected]> 1.10.0-1
-- updated to version 1.10.0
-
-* Sat Sep 22 2001 Shlomi Fish <[email protected]> 1.8.2-1
-- updated to version 1.8.2
-
-* Sat Sep 01 2001 Shlomi Fish <[email protected]> 1.8.0-1
-- Changed the version to 1.8.0
-- Removed the -autconf suffix from the archive.
-
-* Sat Jul 07 2001 Shlomi Fish <[email protected]> 1.6.7-2
-- Fixed the man pages.
-- Included a paragraph about the board_gen programs in the description of
- the executable package.
-
-* Sat Jun 09 2001 Shlomi Fish <[email protected]> 1.6.7-1
-- Changed the version to 1.6.7.
-- Added support for the man pages.
-- Added the symlinked man pages.
-- Added the board_gen sub-dir in the documentation directory. (using a rather
-crude hack)
-- Known Bugs:
- 1 - The man pages need a little rework, there are some typos and they
- don't look very standard.
-
-
-* Thu May 24 2001 Shlomi Fish <[email protected]> 1.6.4-3
-- Added the board generation programs into the RPM.
-- Changed the package to my name and E-mail. Done through the home-dir conf
-file, not by editting the SPEC, but what the heck.
-
-* Sat May 19 2001 Shlomi Fish <[email protected]> 1.6.4-2
-- Changed the descriptions and summaries to something more meaningful
-- Removed the dependency on "Serial" in "Requires".
-
-* Fri May 18 2001 Shlomi Fish <[email protected]> 1.6.4-1
-- First working version with libs and executable support.
-- Known Bugs:
- 1 - No "devel" package.
- 2 - No options passed to "configure".
-- Added calls to strip.
-- "configure" is now OK with all the options set.
-- Added Headers and a working freecell-solver-devel
+* Mon Feb 10 2025 Shlomi Fish <[email protected]> 1.12.0-1
+- Trim the old, freecell-solver, changelog.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/black-hole-solver-1.12.0/cmake/Shlomif_Common.cmake
new/black-hole-solver-1.14.0/cmake/Shlomif_Common.cmake
--- old/black-hole-solver-1.12.0/cmake/Shlomif_Common.cmake 2021-09-23
10:42:02.000000000 +0200
+++ new/black-hole-solver-1.14.0/cmake/Shlomif_Common.cmake 2025-02-23
18:26:45.000000000 +0100
@@ -224,11 +224,14 @@
FILE (WRITE "${TO}" "${contents}")
ENDMACRO()
+# See: https://github.com/shlomif/shlomif-cmake-modules/issues/1
+SET (SHLOMIF_SYSTEM_INSTALL_DIR "/usr/share/cmake/Modules" CACHE STRING "cmake
sys installation dir")
+
MACRO(SHLOMIF_COMMON_SETUP private_mod_path)
SET (private_mod "Shlomif_Common.cmake")
SET (_dest "${private_mod_path}/${private_mod}")
IF (NOT EXISTS "${_dest}")
- SHLOMIF_PHYS_COPY_FILE( "/usr/share/cmake/Modules/${private_mod}"
"${_dest}")
+ SHLOMIF_PHYS_COPY_FILE( "${SHLOMIF_SYSTEM_INSTALL_DIR}/${private_mod}"
"${_dest}")
ENDIF ()
ENDMACRO()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/black-hole-solver-1.12.0/cmake/pod2man-wrapper.pl
new/black-hole-solver-1.14.0/cmake/pod2man-wrapper.pl
--- old/black-hole-solver-1.12.0/cmake/pod2man-wrapper.pl 2019-01-14
01:59:57.000000000 +0100
+++ new/black-hole-solver-1.14.0/cmake/pod2man-wrapper.pl 2025-02-10
11:02:19.000000000 +0100
@@ -4,8 +4,8 @@
use warnings;
use Getopt::Long;
-use File::Temp qw/tempdir/;
-use File::Copy;
+use File::Temp qw/ tempdir /;
+use File::Copy qw/ copy /;
my ( $src, $dest, $sect, $center, $release );
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/black-hole-solver-1.12.0/config.h.in
new/black-hole-solver-1.14.0/config.h.in
--- old/black-hole-solver-1.12.0/config.h.in 2020-10-25 10:56:51.000000000
+0100
+++ new/black-hole-solver-1.14.0/config.h.in 2025-02-10 11:05:23.000000000
+0100
@@ -14,8 +14,8 @@
* ${AUTOGENERATED_CONFIG_H}
*/
-#ifndef FC_SOLVE__CONFIG_H
-#define FC_SOLVE__CONFIG_H
+#ifndef BLACK_HOLE_SOLVE__CONFIG_H
+#define BLACK_HOLE_SOLVE__CONFIG_H
#ifdef __cplusplus
extern "C" {
@@ -23,17 +23,6 @@
#cmakedefine CARD_DEBUG_PRES
-/*
- The sort margin size for the previous states array.
-*/
-#define PREV_STATES_SORT_MARGIN 32
-
-/*
- The amount the pack pointers array grows by. Shouldn't be too high
- because it doesn't happen too often.
-*/
-#cmakedefine IA_STATE_PACKS_GROW_BY 32
-
/* The size of a single pack in alloc.c/alloc.h measured in 1024 chars. */
#cmakedefine FCS_IA_PACK_SIZE ${FCS_IA_PACK_SIZE}
@@ -53,5 +42,4 @@
}
#endif
-#endif /* #ifndef FC_SOLVE__CONFIG_H */
-
+#endif /* #ifndef BLACK_HOLE_SOLVE__CONFIG_H */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/black-hole-solver-1.12.0/fcs_hash.c
new/black-hole-solver-1.14.0/fcs_hash.c
--- old/black-hole-solver-1.12.0/fcs_hash.c 2019-12-28 20:43:33.000000000
+0100
+++ new/black-hole-solver-1.14.0/fcs_hash.c 2025-02-10 12:32:15.000000000
+0100
@@ -27,21 +27,20 @@
// hash table, allowing for smaller chains, and faster lookup.
static inline bool bh_solve_hash_rehash(bh_solve_hash_t *hash)
{
- bh_solve_hash_symlink_t *new_entries;
-
const_AUTO(old_size, hash->size);
const_AUTO(new_size, old_size << 1);
const_AUTO(new_size_bitmask, new_size - 1);
- if (unlikely(!(new_entries = calloc(
- (size_t)new_size, sizeof(bh_solve_hash_symlink_t)))))
+ bh_solve_hash_symlink_t *new_entries;
+ if (unlikely(
+ !(new_entries = calloc((size_t)new_size, sizeof(new_entries[0])))))
{
return true;
}
/* Copy the items to the new hash while not allocating them again */
- for (bh_solve_hash_value_t i = 0; i < old_size; i++)
+ for (bh_solve_hash_value_t i = 0; i < old_size; ++i)
{
var_AUTO(item, hash->entries[i].first_item);
/* traverse the chain item by item */
@@ -76,7 +75,7 @@
return false;
}
-int bh_solve_hash_init(bh_solve_hash_t *hash, meta_allocator *const meta_alloc)
+bool bh_solve_hash_init(bh_solve_hash_t *hash, meta_allocator *const
meta_alloc)
{
const bh_solve_hash_value_t size = 256;
@@ -90,7 +89,7 @@
if (!(hash->entries =
calloc((size_t)size, sizeof(bh_solve_hash_symlink_t))))
{
- return 1;
+ return true;
}
#ifdef BHS_WITH_HASH_VACANT_ITEMS
hash->list_of_vacant_items = NULL;
@@ -101,10 +100,10 @@
{
free(hash->entries);
hash->entries = NULL;
- return 1;
+ return true;
}
- return 0;
+ return false;
}
int bh_solve_hash_insert(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/black-hole-solver-1.12.0/fcs_hash.h
new/black-hole-solver-1.14.0/fcs_hash.h
--- old/black-hole-solver-1.12.0/fcs_hash.h 2019-06-30 19:39:36.000000000
+0200
+++ new/black-hole-solver-1.14.0/fcs_hash.h 2025-02-10 12:32:52.000000000
+0100
@@ -90,7 +90,7 @@
} bh_solve_hash_t;
-extern int bh_solve_hash_init(bh_solve_hash_t *hash, meta_allocator *);
+extern bool bh_solve_hash_init(bh_solve_hash_t *hash, meta_allocator *);
// Returns false if the key is new and the key/val pair was inserted.
// Returns true if the key is not new and *existing_key / *existing_val
@@ -111,6 +111,7 @@
memset(hash->entries, '\0', sizeof(hash->entries[0]) * hash->size);
hash->num_elems = 0;
}
+
static inline void bh_solve_hash_get(
bh_solve_hash_t *hash, bhs_state_key_t *key_ptr, bhs_state_value_t *result)
{
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/black-hole-solver-1.12.0/include/black-hole-solver/fcs_dllexport.h
new/black-hole-solver-1.14.0/include/black-hole-solver/fcs_dllexport.h
--- old/black-hole-solver-1.12.0/include/black-hole-solver/fcs_dllexport.h
2019-04-16 21:17:00.000000000 +0200
+++ new/black-hole-solver-1.14.0/include/black-hole-solver/fcs_dllexport.h
2024-04-04 09:36:25.000000000 +0200
@@ -1,5 +1,4 @@
-#ifndef FC_SOLVE__FCS_DLLEXPORT_H
-#define FC_SOLVE__FCS_DLLEXPORT_H
+#pragma once
#ifdef _MSC_VER
#ifdef BUILDING_DLL
@@ -15,5 +14,3 @@
#define DLLEXPORT
#define DLLLOCAL
#endif
-
-#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/black-hole-solver-1.12.0/lib.c
new/black-hole-solver-1.14.0/lib.c
--- old/black-hole-solver-1.12.0/lib.c 2020-11-27 09:09:50.000000000 +0100
+++ new/black-hole-solver-1.14.0/lib.c 2025-02-20 16:54:58.000000000 +0100
@@ -49,7 +49,7 @@
INVALID_SUIT = -1
};
-static int suit_char_to_index(char suit)
+static int suit_char_to_index(const char suit)
{
switch (suit)
{
@@ -173,7 +173,7 @@
fc_solve_meta_compact_allocator_init(&(ret->meta_alloc));
if (unlikely(bh_solve_hash_init(&(ret->positions), &(ret->meta_alloc))))
{
- fc_solve_meta_compact_allocator_finish(&(ret->meta_alloc));
+ bh_solve_meta_compact_allocator_finish(&(ret->meta_alloc));
free(ret);
*ret_instance = NULL;
return BLACK_HOLE_SOLVER__OUT_OF_MEMORY;
@@ -549,7 +549,7 @@
next_queue_item.s.packed.value.prev_foundation = prev_foundation;
next_queue_item.rank_counts = queue_item_copy_ptr->rank_counts;
- next_queue_item.rank_counts.c[(ssize_t)card]--;
+ --next_queue_item.rank_counts.c[(ssize_t)card];
const int ret =
bh_solve_hash_insert(&(solver->positions),
&(next_queue_item.s.packed));
@@ -629,7 +629,7 @@
}
extern int DLLEXPORT black_hole_solver_config_setup(
- black_hole_solver_instance_t *instance_proto)
+ black_hole_solver_instance_t *const instance_proto)
{
bhs_solver_t *const solver = (bhs_solver_t *)instance_proto;
setup_config(solver);
@@ -637,14 +637,14 @@
}
extern int DLLEXPORT black_hole_solver_setup(
- black_hole_solver_instance_t *instance_proto)
+ black_hole_solver_instance_t *const instance_proto)
{
bhs_solver_t *const solver = (bhs_solver_t *)instance_proto;
return setup_init_state(solver);
}
extern int DLLEXPORT black_hole_solver_run(
- black_hole_solver_instance_t *instance_proto)
+ black_hole_solver_instance_t *const instance_proto)
{
bhs_solver_t *const solver = (bhs_solver_t *)instance_proto;
@@ -661,6 +661,11 @@
max_reached_depths_stack_len, solver->max_reached_depths_stack_len);
var_AUTO(current_depths_stack_len, solver->current_depths_stack_len);
+ if (iterations_num >= max_iters_limit)
+ {
+ return BLACK_HOLE_SOLVER__OUT_OF_ITERS;
+ }
+
while (solver->queue_len > 0)
{
const_AUTO(prev_len, solver->queue_len);
@@ -754,8 +759,9 @@
return BLACK_HOLE_SOLVER__SUCCESS;
}
- else if (iterations_num == max_iters_limit)
+ else if (iterations_num >= max_iters_limit)
{
+ assert(iterations_num == max_iters_limit);
solver->max_reached_depths_stack_len =
max_reached_depths_stack_len;
solver->iterations_num = iterations_num;
solver->current_depths_stack_len = current_depths_stack_len;
@@ -772,7 +778,7 @@
}
extern int DLLEXPORT black_hole_solver_recycle(
- black_hole_solver_instance_t *instance_proto)
+ black_hole_solver_instance_t *const instance_proto)
{
bhs_solver_t *const solver = (bhs_solver_t *)instance_proto;
@@ -788,7 +794,7 @@
}
DLLEXPORT void black_hole_solver_init_solution_moves(
- black_hole_solver_instance_t *instance_proto)
+ black_hole_solver_instance_t *const instance_proto)
{
bhs_solver_t *const solver = (bhs_solver_t *)instance_proto;
const_SLOT(num_columns, solver);
@@ -824,7 +830,7 @@
states[num_states + 1].packed.value.prev_foundation;
unsigned char *data = states[num_states + 1].packed.key.data;
for (size_t i = 0; i < TALON_PTR_BITS;
- ++i, new_moved_card_height >>= 1)
+ ++i, new_moved_card_height >>= 1)
{
data[0] &= (~(1 << (i)));
data[0] |= ((new_moved_card_height & 0x1) << (i));
@@ -841,7 +847,7 @@
var_AUTO(offset, TALON_PTR_BITS + bits_per_column * col_idx);
unsigned char *data = states[num_states + 1].packed.key.data;
for (size_t i = 0; i < bits_per_column;
- ++i, ++offset, new_moved_card_height >>= 1)
+ ++i, ++offset, new_moved_card_height >>= 1)
{
data[offset >> 3] &= (~(1 << (offset & 0x7)));
data[offset >> 3] |=
@@ -905,14 +911,14 @@
DLLEXPORT extern unsigned long __attribute__((pure))
black_hole_solver_get_iterations_num(
- black_hole_solver_instance_t *instance_proto)
+ black_hole_solver_instance_t *const instance_proto)
{
return ((bhs_solver_t *)instance_proto)->iterations_num;
}
DLLEXPORT extern unsigned long __attribute__((pure))
black_hole_solver_get_max_num_played_cards(
- black_hole_solver_instance_t *instance_proto)
+ black_hole_solver_instance_t *const instance_proto)
{
const_AUTO(
ret, ((bhs_solver_t *)instance_proto)->max_reached_depths_stack_len);
@@ -920,7 +926,7 @@
}
DLLEXPORT extern int black_hole_solver_get_current_solution_board(
- black_hole_solver_instance_t *instance_proto, char *const output)
+ black_hole_solver_instance_t *const instance_proto, char *const output)
{
bhs_solver_t *const solver = (bhs_solver_t *)instance_proto;
@@ -982,12 +988,12 @@
}
extern int DLLEXPORT black_hole_solver_free(
- black_hole_solver_instance_t *instance_proto)
+ black_hole_solver_instance_t *const instance_proto)
{
bhs_solver_t *const solver = (bhs_solver_t *)instance_proto;
bh_solve_hash_free(&(solver->positions));
- fc_solve_meta_compact_allocator_finish(&(solver->meta_alloc));
+ bh_solve_meta_compact_allocator_finish(&(solver->meta_alloc));
free(solver);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/black-hole-solver-1.12.0/meta_alloc.c
new/black-hole-solver-1.14.0/meta_alloc.c
--- old/black-hole-solver-1.12.0/meta_alloc.c 2019-08-16 10:35:02.000000000
+0200
+++ new/black-hole-solver-1.14.0/meta_alloc.c 2025-02-10 12:04:05.000000000
+0100
@@ -30,12 +30,12 @@
}
}
-int fc_solve_compact_allocator_extend(compact_allocator *const allocator)
+bool bh_solve_compact_allocator_extend(compact_allocator *const allocator)
{
char *const new_data = meta_request_new_buffer(allocator->meta);
if (unlikely(!new_data))
{
- return 1;
+ return true;
}
FCS__COMPACT_ALLOC__OLD_LIST_NEXT(new_data) = allocator->old_list;
@@ -43,15 +43,15 @@
allocator->ptr = allocator->rollback_ptr = OLD_LIST_DATA(new_data);
allocator->max_ptr = new_data + ALLOCED_SIZE;
- return 0;
+ return false;
}
-void fc_solve_meta_compact_allocator_finish(meta_allocator *const meta_alloc)
+void bh_solve_meta_compact_allocator_finish(meta_allocator *const meta_alloc)
{
char *iter = meta_alloc->recycle_bin;
char *iter_next = iter ? FCS__COMPACT_ALLOC__OLD_LIST_NEXT(iter) : NULL;
for (; iter_next;
- iter = iter_next, iter_next = FCS__COMPACT_ALLOC__OLD_LIST_NEXT(iter))
+ iter = iter_next, iter_next = FCS__COMPACT_ALLOC__OLD_LIST_NEXT(iter))
{
free(iter);
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/black-hole-solver-1.12.0/meta_alloc.h
new/black-hole-solver-1.14.0/meta_alloc.h
--- old/black-hole-solver-1.12.0/meta_alloc.h 2019-08-16 10:35:02.000000000
+0200
+++ new/black-hole-solver-1.14.0/meta_alloc.h 2025-02-10 12:09:37.000000000
+0100
@@ -16,6 +16,7 @@
extern "C" {
#endif
+#include <stdbool.h>
#include <stddef.h>
#include "rinutils/likely.h"
#include "rinutils/typeof_wrap.h"
@@ -39,14 +40,14 @@
meta_allocator *meta;
} compact_allocator;
-extern int fc_solve_compact_allocator_extend(compact_allocator *);
+extern bool bh_solve_compact_allocator_extend(compact_allocator *);
/* To be called after the meta_alloc was set. */
-static inline int fc_solve_compact_allocator_init_helper(
+static inline bool fc_solve_compact_allocator_init_helper(
compact_allocator *const allocator)
{
allocator->old_list = NULL;
- return fc_solve_compact_allocator_extend(allocator);
+ return bh_solve_compact_allocator_extend(allocator);
}
static inline void fc_solve_meta_compact_allocator_init(
@@ -55,7 +56,7 @@
meta->recycle_bin = NULL;
}
-extern void fc_solve_meta_compact_allocator_finish(meta_allocator *);
+extern void bh_solve_meta_compact_allocator_finish(meta_allocator *);
static inline void *fcs_compact_alloc_ptr(
compact_allocator *const allocator, const size_t how_much_proto)
@@ -68,7 +69,7 @@
if ((size_t)(allocator->max_ptr - allocator->ptr) < how_much)
{
- if (unlikely(fc_solve_compact_allocator_extend(allocator)))
+ if (unlikely(bh_solve_compact_allocator_extend(allocator)))
{
return NULL;
}
@@ -97,8 +98,8 @@
// Enqueue all the allocated buffers in the meta allocator for re-use.
for (iter = allocator->old_list,
iter_next = FCS__COMPACT_ALLOC__OLD_LIST_NEXT(iter);
- iter_next;
- iter = iter_next, iter_next = FCS__COMPACT_ALLOC__OLD_LIST_NEXT(iter))
+ iter_next;
+ iter = iter_next, iter_next = FCS__COMPACT_ALLOC__OLD_LIST_NEXT(iter))
{
FCS__COMPACT_ALLOC__OLD_LIST_NEXT(iter) = bin;
bin = iter;
@@ -115,7 +116,7 @@
fc_solve_compact_allocator_init_helper(allocator);
}
-static inline int fc_solve_compact_allocator_init(
+static inline bool fc_solve_compact_allocator_init(
compact_allocator *const allocator, meta_allocator *const meta_alloc)
{
allocator->meta = meta_alloc;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/black-hole-solver-1.12.0/multi_solver.c
new/black-hole-solver-1.14.0/multi_solver.c
--- old/black-hole-solver-1.12.0/multi_solver.c 2020-11-27 09:09:50.000000000
+0100
+++ new/black-hole-solver-1.14.0/multi_solver.c 2025-02-10 12:39:44.000000000
+0100
@@ -12,7 +12,14 @@
{
char *const filename = argv[arg_idx];
fprintf(settings.out_fh, "[= Starting file %s =]\n", filename);
- solve_filename(filename, &settings);
+ bool should_abort;
+ const int ret = solve_filename(filename, &settings, &should_abort);
+ if (ret && should_abort)
+ {
+ fflush(settings.out_fh);
+ solve_free(&settings);
+ return ret;
+ }
fprintf(settings.out_fh, "[= END of file %s =]\n", filename);
}
fflush(settings.out_fh);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/black-hole-solver-1.12.0/multi_solver_stats.c
new/black-hole-solver-1.14.0/multi_solver_stats.c
--- old/black-hole-solver-1.12.0/multi_solver_stats.c 2021-11-24
07:59:54.000000000 +0100
+++ new/black-hole-solver-1.14.0/multi_solver_stats.c 2025-03-02
12:28:49.000000000 +0100
@@ -3,7 +3,7 @@
// Distributed under terms of the Expat license.
#include <solver_common.h>
-static inline void output_stats__solve_file(
+static inline int output_stats__solve_file(
const char *const filename, bhs_settings *const settings_ptr)
{
#define settings (*settings_ptr)
@@ -14,7 +14,7 @@
if (!fh)
{
fprintf(stderr, "Cannot open '%s' for reading!\n", filename);
- return;
+ return -1;
}
}
char board[MAX_LEN_BOARD_STRING];
@@ -59,6 +59,7 @@
if (!solver_ret_code)
{
+ fputs("Solved!\n", out_fh);
}
else if (solver_ret_code == BLACK_HOLE_SOLVER__OUT_OF_MEMORY)
{
@@ -72,12 +73,19 @@
else
{
fputs("Unsolved!\n", out_fh);
- fprintf(out_fh, "At most %lu cards could be played.\n",
- black_hole_solver_get_max_num_played_cards(solver));
}
+ fprintf(out_fh, "At most %lu cards could be played.\n",
+ black_hole_solver_get_max_num_played_cards(solver));
+ fprintf(out_fh,
+ "Total number of states checked is %lu.\n"
+ "This scan generated %lu states.\n",
+ black_hole_solver_get_iterations_num(solver),
+ black_hole_solver_get_num_states_in_collection(solver));
+
black_hole_solver_recycle(solver);
#undef settings
+ return 0;
}
int main(int argc, char *argv[])
@@ -89,7 +97,12 @@
{
char *const filename = argv[arg_idx];
fprintf(settings.out_fh, "[= Starting file %s =]\n", filename);
- output_stats__solve_file(filename, &settings);
+ const int ret = output_stats__solve_file(filename, &settings);
+ if (unlikely(ret))
+ {
+ solve_free(&settings);
+ return -1;
+ }
fprintf(settings.out_fh, "[= END of file %s =]\n", filename);
}
fflush(settings.out_fh);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/black-hole-solver-1.12.0/rank_reach_prune.h
new/black-hole-solver-1.14.0/rank_reach_prune.h
--- old/black-hole-solver-1.12.0/rank_reach_prune.h 2019-04-16
21:17:00.000000000 +0200
+++ new/black-hole-solver-1.14.0/rank_reach_prune.h 2024-09-29
16:29:30.000000000 +0200
@@ -74,7 +74,7 @@
static const int LINKS[2] = {-1, 1};
for (size_t link_idx = 0; link_idx < (sizeof(LINKS) /
sizeof(LINKS[0]));
- link_idx++)
+ ++link_idx)
{
signed char offset_rank = (signed char)(rank + LINKS[link_idx]);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/black-hole-solver-1.12.0/run-tests.pl
new/black-hole-solver-1.14.0/run-tests.pl
--- old/black-hole-solver-1.12.0/run-tests.pl 2021-04-25 07:09:31.000000000
+0200
+++ new/black-hole-solver-1.14.0/run-tests.pl 2024-04-04 09:36:25.000000000
+0200
@@ -6,8 +6,8 @@
use autodie;
use Getopt::Long qw/ GetOptions /;
-use Env::Path ();
-use Path::Tiny qw/ path /;
+use Env::Path ();
+use Path::Tiny qw/ path /;
my $src_dir = path(__FILE__)->parent->absolute;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/black-hole-solver-1.12.0/scripts/gen-c-lookup-files.pl
new/black-hole-solver-1.14.0/scripts/gen-c-lookup-files.pl
--- old/black-hole-solver-1.12.0/scripts/gen-c-lookup-files.pl 2019-06-30
20:26:54.000000000 +0200
+++ new/black-hole-solver-1.14.0/scripts/gen-c-lookup-files.pl 2025-02-10
12:48:08.000000000 +0100
@@ -6,37 +6,32 @@
use autodie;
use Path::Tiny qw/ path /;
-my $FALSE = 0;
-my $TRUE = 1;
+sub emit
+{
+ my ( $DECL, $bn, $header_headers, $contents, $types ) = @_;
+ $types //= '';
-my $MAX_RANK = $ENV{FCS_MAX_RANK} || 13;
-my $NUM_SUITS = 4;
-my @SUITS = ( 0 .. $NUM_SUITS - 1 );
-my @RANKS = ( 1 .. $MAX_RANK );
-my @PARENT_RANKS = ( 2 .. $MAX_RANK );
-my $MAX_NUM_DECKS = 1;
-my $FCS_POS_BY_RANK_WIDTH = ( $MAX_NUM_DECKS << 3 );
+ my $header_fn = "$bn.h";
-sub make_card
-{
- my ( $rank, $suit ) = @_;
- return ( ( $rank << 2 ) | $suit );
-}
+ path($header_fn)
+ ->spew_utf8( "#pragma once\n"
+ . join( '', map { qq{#include $_\n} } @$header_headers )
+ . $types
+ . "extern $DECL;\n" );
+ path("$bn.c")
+ ->spew_utf8( qq/#include "$header_fn"\n\n$DECL = {/
+ . join( ',', @$contents )
+ . "};\n" );
-sub key
-{
- my ( $parent, $child ) = @_;
- return "${parent}\t${child}";
+ return;
}
-my $NUM_CHILD_CARDS = 64;
-my $NUM_PARENT_CARDS = make_card( $MAX_RANK, $SUITS[-1] ) + 1;
-my @is_king = ( ($FALSE) x $NUM_PARENT_CARDS );
-my %lookup;
-my @state_pos = ( map { [ (0) x $NUM_SUITS ] } 0 .. $MAX_RANK );
-my @card_pos;
-my @positions_by_rank__lookup;
-my @pos_by_rank;
+my $FALSE = 0;
+my $TRUE = 1;
+
+my $MAX_RANK = $ENV{FCS_MAX_RANK} || 13;
+my @RANKS = ( 1 .. $MAX_RANK );
+
my @can_move;
foreach my $wrap_ranks ( 0, 1 )
@@ -58,41 +53,6 @@
}
}
-path('board_gen_lookup1.h')->spew_utf8(
- "#pragma once\n",
- 'static const size_t offset_by_i[52] = {',
- join(
- ',',
- map {
- my $i = $_;
- my $col = ( $i & ( 8 - 1 ) );
- 3 *
- ( $col * 7 - ( ( $col > 4 ) ? ( $col - 4 ) : 0 ) + ( $i >> 3 )
)
- } 0 .. ( 52 - 1 )
- ),
- "};\n"
-);
-
-sub emit
-{
- my ( $DECL, $bn, $header_headers, $contents, $types ) = @_;
- $types //= '';
-
- my $header_fn = "$bn.h";
-
- path($header_fn)
- ->spew_utf8( "#pragma once\n"
- . join( '', map { qq{#include $_\n} } @$header_headers )
- . $types
- . "extern $DECL;\n" );
- path("$bn.c")
- ->spew_utf8( qq/#include "$header_fn"\n\n$DECL = {/
- . join( ',', @$contents )
- . "};\n" );
-
- return;
-}
-
emit(
qq#const bool
black_hole_solver__can_move[2][@{[$MAX_RANK+1]}][@{[$MAX_RANK]}]#,
'can_move',
@@ -104,8 +64,7 @@
',',
map {
my $row = $_;
- '{'
- . join( ',', map { $_ ? 'true' : 'false' } @$row ) .
'}'
+ '{' . join( ',', map { $_ ? 'true' : 'false' } @$row ) .
'}'
} @{$table}
)
. '}'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/black-hole-solver-1.12.0/single_board_main.c
new/black-hole-solver-1.14.0/single_board_main.c
--- old/black-hole-solver-1.12.0/single_board_main.c 2020-11-27
09:09:50.000000000 +0100
+++ new/black-hole-solver-1.14.0/single_board_main.c 2025-02-10
13:15:49.000000000 +0100
@@ -12,13 +12,41 @@
char *filename = NULL;
if (argc > arg_idx)
{
- if (strcmp(argv[arg_idx], "-"))
+ bool dashdash = false;
+ if (argv[arg_idx][0] == '-')
{
+ if (strcmp(argv[arg_idx], "--"))
+ {
+ dashdash = true;
+ ++arg_idx;
+ }
+ }
+ if (arg_idx < argc - 1)
+ {
+ fprintf(stderr,
+ "Too many filenames given; only one is accepted.\nStarting "
+ "from %s .\n",
+ argv[arg_idx]);
+ solve_free(&settings);
+ return -1;
+ }
+ if (dashdash || strcmp(argv[arg_idx], "-"))
+ {
+ if (argv[arg_idx][0] == '-')
+ {
+ if (!dashdash)
+ {
+ fprintf(stderr, "Unknown flag '%s' .\n", argv[arg_idx]);
+ solve_free(&settings);
+ return -1;
+ }
+ }
filename = argv[arg_idx];
}
}
- const int ret = solve_filename(filename, &settings);
+ bool should_abort;
+ const int ret = solve_filename(filename, &settings, &should_abort);
solve_free(&settings);
return ret;
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/black-hole-solver-1.12.0/solver_common.h
new/black-hole-solver-1.14.0/solver_common.h
--- old/black-hole-solver-1.12.0/solver_common.h 2020-11-27
09:09:50.000000000 +0100
+++ new/black-hole-solver-1.14.0/solver_common.h 2025-02-27
15:56:27.000000000 +0100
@@ -27,7 +27,7 @@
GAME__GOLF
};
-static inline void out_board(FILE *out_fh,
+static inline void out_board(FILE *const out_fh,
black_hole_solver_instance_t *const solver, const bool display_boards)
{
if (!display_boards)
@@ -74,11 +74,12 @@
bool quiet_output;
bool wrap_ranks;
bool show_max_num_played_cards;
+ bool was_output_filepath_set;
} bhs_settings;
#pragma clang diagnostic pop
static inline bhs_settings parse_cmd_line(
- int argc, char *argv[], int *out_arg_idx)
+ const int argc, char *argv[], int *const out_arg_idx)
{
bhs_settings settings;
settings.out_fh = stdout;
@@ -91,6 +92,7 @@
settings.wrap_ranks = true;
settings.max_iters_limit = ULONG_MAX;
settings.show_max_num_played_cards = false;
+ settings.was_output_filepath_set = false;
int arg_idx = 1;
while (argc > arg_idx)
@@ -113,7 +115,15 @@
fputs("Error! --output requires an argument.\n", stderr);
exit(-1);
}
+ if (settings.was_output_filepath_set)
+ {
+ fputs("Error! --output can only be used once in order to avoid
"
+ "filehandles leaks.\n",
+ stderr);
+ exit(-1);
+ }
settings.out_fh = fopen(argv[arg_idx++], "wt");
+ settings.was_output_filepath_set = true;
}
else if (!strcmp(argv[arg_idx], "--max-iters"))
{
@@ -234,11 +244,12 @@
return settings;
}
-static inline int solve_filename(
- const char *const filename, bhs_settings *const settings_ptr)
+static inline int solve_filename(const char *const filename,
+ bhs_settings *const settings_ptr, bool *const should_abort)
{
#define settings (*settings_ptr)
int ret = 0;
+ *should_abort = false;
FILE *fh = stdin;
if (filename)
@@ -247,6 +258,7 @@
if (!fh)
{
fprintf(stderr, "Cannot open '%s' for reading!\n", filename);
+ *should_abort = true;
return -1;
}
}
@@ -329,6 +341,7 @@
fprintf(stderr, "%s - %d\n",
"Get next move routine returned the wrong error code.",
next_move_ret_code);
+ *should_abort = true;
ret = -1;
}
}
@@ -336,6 +349,7 @@
else if (solver_ret_code == BLACK_HOLE_SOLVER__OUT_OF_MEMORY)
{
fputs("Out of memory!\n", stderr);
+ *should_abort = true;
exit(-1);
}
else if (solver_ret_code == BLACK_HOLE_SOLVER__OUT_OF_ITERS)
@@ -367,7 +381,7 @@
static inline void solve_free(bhs_settings *const settings_ptr)
{
- if (settings_ptr->out_fh != stdout)
+ if (settings_ptr->was_output_filepath_set)
{
fclose(settings_ptr->out_fh);
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/black-hole-solver-1.12.0/solver_run.h
new/black-hole-solver-1.14.0/solver_run.h
--- old/black-hole-solver-1.12.0/solver_run.h 2019-04-16 21:17:00.000000000
+0200
+++ new/black-hole-solver-1.14.0/solver_run.h 2025-02-20 16:58:51.000000000
+0100
@@ -3,10 +3,17 @@
//
// Distributed under terms of the Expat license.
#pragma once
+#include <assert.h>
static inline int solver_run(black_hole_solver_instance_t *const solver,
const unsigned long max_iters_limit, const unsigned long
iters_display_step)
{
+ if (iters_display_step == 0)
+ {
+ // fprintf(stderr, "iters_display_step is 0.\n");
+ black_hole_solver_set_max_iters_limit(solver, max_iters_limit);
+ return black_hole_solver_run(solver);
+ }
unsigned long iters_limit = min(iters_display_step, max_iters_limit);
black_hole_solver_set_max_iters_limit(solver, iters_limit);
unsigned long iters_num;
@@ -16,15 +23,15 @@
{
solver_ret_code = black_hole_solver_run(solver);
iters_num = black_hole_solver_get_iterations_num(solver);
- if (iters_limit == iters_num)
+ if (iters_limit <= iters_num)
{
- printf("Iteration: %lu\n", iters_limit);
+ printf("Iteration: %lu\n", iters_num);
fflush(stdout);
}
iters_limit += iters_display_step;
iters_limit = min(iters_limit, max_iters_limit);
black_hole_solver_set_max_iters_limit(solver, iters_limit);
} while ((solver_ret_code == BLACK_HOLE_SOLVER__OUT_OF_ITERS) &&
- (iters_num < max_iters_limit));
+ (iters_num <= max_iters_limit));
return solver_ret_code;
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/black-hole-solver-1.12.0/t/all-in-a-row-output.t
new/black-hole-solver-1.14.0/t/all-in-a-row-output.t
--- old/black-hole-solver-1.12.0/t/all-in-a-row-output.t 2020-10-26
08:47:35.000000000 +0100
+++ new/black-hole-solver-1.14.0/t/all-in-a-row-output.t 2024-04-04
09:36:25.000000000 +0200
@@ -19,7 +19,7 @@
return $exit_code = system(@_);
}
-use Dir::Manifest ();
+use Dir::Manifest ();
use Dir::Manifest::Slurp qw/ as_lf /;
my $mani = Dir::Manifest->new(
{
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/black-hole-solver-1.12.0/t/black-hole-output.t
new/black-hole-solver-1.14.0/t/black-hole-output.t
--- old/black-hole-solver-1.12.0/t/black-hole-output.t 2020-11-27
09:09:50.000000000 +0100
+++ new/black-hole-solver-1.14.0/t/black-hole-output.t 2025-03-02
13:24:18.000000000 +0100
@@ -3,7 +3,7 @@
use strict;
use warnings;
-use Test::More tests => 24;
+use Test::More tests => 25;
use Test::Differences qw/ eq_or_diff /;
use Test::Some;
@@ -11,7 +11,9 @@
trap $trap :flow:stderr(systemsafe):stdout(systemsafe):warn
);
-use Path::Tiny qw/ path /;
+use Path::Tiny qw/ path tempdir /;
+
+use Games::Solitaire::BlackHole::Test qw/ _test_multiple_verdict_lines /;
my $bin_dir = path(__FILE__)->parent->absolute;
my $data_dir = $bin_dir->child('data');
@@ -33,7 +35,7 @@
# TEST
ok( !($exit_code), "Running the program successfully." );
-use Dir::Manifest ();
+use Dir::Manifest ();
use Dir::Manifest::Slurp qw/ as_lf /;
my $mani = Dir::Manifest->new(
{
@@ -255,35 +257,71 @@
);
}
+my $master_tmp = tempdir();
{
- my $out_fn = "golf1to20out.txt";
- trap
+ my $count = 0;
{
- mysys(
- './multi-bhs-solver',
- '--output',
- $out_fn,
- '--game',
- 'golf',
- '--display-boards',
- '--wrap-ranks',
- ( map { $mani->fh("golf$_.board") } 1 .. 20 )
- );
- };
+ my $tmp = $master_tmp->child( "multibhs-" . ++$count );
+ $tmp->mkdir();
- # TEST
- ok( !($exit_code), "Exit code for --display-boards for golf board #906." );
-
- my $stdout = as_lf( path($out_fn)->slurp_raw );
- $stdout =~
- s#^(\[= (?:Starting|END of) file )(\S+)#$1 . path($2)->basename#egms;
+ my $out_fn = $tmp->child("golf1to20out.txt");
+ trap
+ {
+ mysys(
+ './multi-bhs-solver',
+ '--output',
+ $out_fn,
+ '--game',
+ 'golf',
+ '--display-boards',
+ '--wrap-ranks',
+ ( map { $mani->fh("golf$_.board") } 1 .. 20 )
+ );
+ };
+
+ # TEST
+ ok( !($exit_code),
+ "Exit code for --display-boards for golf board #906." );
+
+ my $stdout = as_lf( path($out_fn)->slurp_raw );
+ $stdout =~
+s#^(\[= (?:Starting|END of) file )(\S+)#$1 . path($2)->basename#egms;
+
+ # TEST
+ is(
+ $stdout,
+ $mani->text( "golf-1to20.sol.txt", { lf => 1 } ),
+ "recycling works",
+ );
+ }
- # TEST
- is(
- $stdout,
- $mani->text( "golf-1to20.sol.txt", { lf => 1 } ),
- "recycling works",
- );
+ {
+ my $tmp = $master_tmp->child( "multibhs-" . ++$count );
+ $tmp->mkdir();
+ my $out_fn = $tmp->child("golf1to20out.txt");
+ trap
+ {
+ mysys(
+ './multi-bhs-solver',
+ '--output',
+ $out_fn,
+ '--game',
+ 'golf',
+ '--display-boards',
+ '--wrap-ranks',
+ ( map { $mani->fh("golf$_.board") } 1 .. 2 ),
+ $tmp->child("not--------exist.c"),
+ ( map { $mani->fh("golf$_.board") } 3 .. 4 ),
+ );
+ };
+
+ # TEST
+ ok( $exit_code, "Exit code for --display-boards for golf board #906."
);
+
+ my $stdout = as_lf( path($out_fn)->slurp_raw );
+ $stdout =~
+s#^(\[= (?:Starting|END of) file )(\S+)#$1 . path($2)->basename#egms;
+ }
}
my $MAX_NUM_PLAYED_CARDS_RE =
@@ -327,7 +365,7 @@
# TEST
subtest 'max_num_played' => sub {
- plan tests => 10;
+ plan tests => 12;
trap
{
mysys( './black-hole-solve', '--game', 'black_hole',
@@ -422,5 +460,53 @@
input_text => scalar( $trap->stdout() ),
},
);
+
+ {
+ my $count = 0;
+ my $tmp = $master_tmp->child( "statsmultibhs-" . ++$count );
+ $tmp->mkdir();
+
+ my @deals_indexes = ( 1 .. 20 );
+ my $out_fn = $tmp->child("golf1to20out.txt");
+ trap
+ {
+ mysys(
+ './stats-multi-bhs-solver',
+ '--output',
+ $out_fn,
+ '--game',
+ 'golf',
+ '--display-boards',
+ '--wrap-ranks',
+ ( map { $mani->fh("golf$_.board") } 1 .. 20 )
+ );
+ };
+
+ ok( !($exit_code),
+ "Exit code for --display-boards for golf board #906." );
+
+ _test_multiple_verdict_lines(
+ {
+ name => "test multiple verdict lines",
+ expected_results => [
+ "Solved!", "Solved!", "Solved!", "Solved!",
+ "Solved!", "Solved!", "Solved!", "Solved!",
+ "Solved!", "Solved!", "Unsolved!", "Solved!",
+ "Solved!", "Solved!", "Solved!", "Solved!",
+ "Solved!", "Solved!", "Solved!", "Solved!",
+ ],
+ expected_files_checks => sub {
+ my $i = shift;
+ my $dealidx = $deals_indexes[$i];
+ my $fn = path(shift);
+ my $bn = $fn->basename();
+
+ return ( $bn =~ m#golf\Q$dealidx\E\.board#ms );
+ },
+ input_lines => [ path($out_fn)->lines_utf8() ],
+ }
+ );
+
+ }
},
'!no_max_num_played';
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/black-hole-solver-1.12.0/t/lib/Games/Solitaire/BlackHole/RankReachPrune/PP.pm
new/black-hole-solver-1.14.0/t/lib/Games/Solitaire/BlackHole/RankReachPrune/PP.pm
---
old/black-hole-solver-1.12.0/t/lib/Games/Solitaire/BlackHole/RankReachPrune/PP.pm
2019-01-14 01:59:57.000000000 +0100
+++
new/black-hole-solver-1.14.0/t/lib/Games/Solitaire/BlackHole/RankReachPrune/PP.pm
2024-09-29 16:34:40.000000000 +0200
@@ -27,7 +27,7 @@
# Count the foundation - the starting point - in.
if ( $rank_counts->[$foundation] == 0 )
{
- $full_max++;
+ ++$full_max;
}
my $full_count = 0;
@@ -45,7 +45,7 @@
}
$reached[$rank] = $TRUE;
- $full_count++;
+ ++$full_count;
for my $link ( -1, 1 )
{
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/black-hole-solver-1.12.0/t/lib/Games/Solitaire/BlackHole/RankReachPrune/XS.pm
new/black-hole-solver-1.14.0/t/lib/Games/Solitaire/BlackHole/RankReachPrune/XS.pm
---
old/black-hole-solver-1.12.0/t/lib/Games/Solitaire/BlackHole/RankReachPrune/XS.pm
2020-10-07 12:53:32.000000000 +0200
+++
new/black-hole-solver-1.14.0/t/lib/Games/Solitaire/BlackHole/RankReachPrune/XS.pm
2024-09-29 16:34:35.000000000 +0200
@@ -12,7 +12,7 @@
int call_prune(int foundation, AV * rank_counts_av)
{
bhs_rank_counts rank_counts;
- for (int i = 0; i < NUM_RANKS; i++)
+ for (int i = 0; i < NUM_RANKS; ++i)
{
SV * * item = av_fetch(rank_counts_av, i, false);
assert(item);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/black-hole-solver-1.12.0/t/lib/Games/Solitaire/BlackHole/Test.pm
new/black-hole-solver-1.14.0/t/lib/Games/Solitaire/BlackHole/Test.pm
--- old/black-hole-solver-1.12.0/t/lib/Games/Solitaire/BlackHole/Test.pm
1970-01-01 01:00:00.000000000 +0100
+++ new/black-hole-solver-1.14.0/t/lib/Games/Solitaire/BlackHole/Test.pm
2025-03-02 13:17:56.000000000 +0100
@@ -0,0 +1,115 @@
+package Games::Solitaire::BlackHole::Test;
+
+use strict;
+use warnings;
+
+use Test::More;
+
+use Dir::Manifest::Slurp qw/ as_lf /;
+use Test::Differences qw/ eq_or_diff /;
+
+our @ISA = qw(Exporter);
+our %EXPORT_TAGS = ( 'all' => [qw( _test_multiple_verdict_lines )] );
+our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
+require Exporter;
+
+# We intend this test subroutine to be used by more than one
+# subproject.
+sub _test_multiple_verdict_lines
+{
+ my %is_verdict_line = map { $_ => 1, }
+ ( "Solved!", "Unsolved!", "Exceeded max_iters_limit !" );
+ my ($args) = @_;
+ my ( $name, $expected_files_checks, $want, $input_lines ) =
+ @{$args}{qw/ name expected_files_checks expected_results input_lines/};
+ local $Test::Builder::Level = $Test::Builder::Level + 1;
+ return subtest $name => sub {
+ plan tests => 2;
+ $input_lines =
+ [ map { my $l = as_lf($_); chomp $l; $l } @$input_lines ];
+ my @matches;
+ my $deal_idx = 0;
+ while (@$input_lines)
+ {
+ my $dealstart = shift @$input_lines;
+ my ($fn) = $dealstart =~ /^\[\= Starting file (\S+) \=\]$/ms
+ or die "cannot match";
+ if ( not $expected_files_checks->( $deal_idx, $fn ) )
+ {
+ die "filename check";
+ }
+ my $dealverdict = shift @$input_lines;
+ if ( $is_verdict_line{$dealverdict} )
+ {
+ push @matches, $dealverdict;
+ }
+ else
+ {
+ die "mismatch";
+ }
+ my $at_most_num_cards__line = 0;
+ if ( @$input_lines
+ and $input_lines->[0] =~
+ /^At most (?:(?:0)|(?:[1-9][0-9]*)) cards could be
played\.\z/ms
+ )
+ {
+ $at_most_num_cards__line = 1;
+ shift @$input_lines;
+ }
+ my $traversed_states_count__line = 0;
+ if ( @$input_lines
+ and $input_lines->[0] =~
+/^Total number of states checked is (?:(?:0)|(?:[1-9][0-9]*))\.\z/ms,
+ )
+ {
+ $traversed_states_count__line = 1;
+ shift @$input_lines;
+ }
+ my $generated_states_count__line = 0;
+ if ( @$input_lines
+ and $input_lines->[0] =~
+ /^This scan generated (?:(?:0)|(?:[1-9][0-9]*)) states\.\z/ms )
+ {
+ $generated_states_count__line = 1;
+ shift @$input_lines;
+ }
+ if (0)
+ {
+ while ( @$input_lines and $input_lines->[0] !~ /^\[\= /ms )
+ {
+ diag( "unrecognised: '" . $input_lines->[0] . "'" );
+ shift @$input_lines;
+ }
+ }
+ my $dealend = shift @$input_lines;
+ if ( $dealend ne "[= END of file $fn =]" )
+ {
+ die "dealend mismatch";
+ }
+ if ( not $at_most_num_cards__line )
+ {
+ die "At most cards played line is absent";
+ }
+ if ( not $traversed_states_count__line )
+ {
+ die "'checked states' line is absent";
+ }
+ if ( not $generated_states_count__line )
+ {
+ die "'This scan generated' line is absent";
+ }
+ }
+ continue
+ {
+ ++$deal_idx;
+ }
+
+ is( scalar(@matches), scalar(@$want), "lines count." );
+
+ eq_or_diff( [@matches], [@$want], "expected results.", );
+ };
+}
+
+1;
+
+__END__
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/black-hole-solver-1.12.0/t/perltidy.t
new/black-hole-solver-1.14.0/t/perltidy.t
--- old/black-hole-solver-1.12.0/t/perltidy.t 2019-01-14 01:59:57.000000000
+0100
+++ new/black-hole-solver-1.14.0/t/perltidy.t 2024-04-04 09:36:25.000000000
+0200
@@ -9,6 +9,17 @@
Test::More::plan( 'skip_all' =>
"Skipping perltidy test because FCS_TEST_SKIP_PERLTIDY was set" );
}
+
+{
+ my $key = "AUTHOR_TESTING";
+ if ( not $ENV{$key} )
+ {
+ require Test::More;
+ Test::More::plan(
+ 'skip_all' => "Skipping perltidy test because $key was not set" );
+ }
+}
+
require Test::Code::TidyAll;
Test::Code::TidyAll::tidyall_ok( conf_file => "$ENV{FCS_SRC_PATH}/.tidyallrc",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/black-hole-solver-1.12.0/t/valgrind.t
new/black-hole-solver-1.14.0/t/valgrind.t
--- old/black-hole-solver-1.12.0/t/valgrind.t 2020-07-04 17:23:27.000000000
+0200
+++ new/black-hole-solver-1.14.0/t/valgrind.t 2024-04-04 09:36:25.000000000
+0200
@@ -5,7 +5,7 @@
use Test::More;
use Test::RunValgrind ();
-use Path::Tiny qw/ path /;
+use Path::Tiny qw/ path /;
my $bin_dir = path($0)->parent->absolute;
my $data_dir = $bin_dir->child('data');
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/black-hole-solver-1.12.0/ver.txt
new/black-hole-solver-1.14.0/ver.txt
--- old/black-hole-solver-1.12.0/ver.txt 2022-03-28 12:22:05.000000000
+0200
+++ new/black-hole-solver-1.14.0/ver.txt 2025-03-03 07:56:29.000000000
+0100
@@ -1 +1 @@
-1.12.0
+1.14.0