Beginning of implementation of a ctypes-based interface to libboard, which is a much cleaner set of Go routines than I hacked together originally. Including a copy of gnugo 3.8 so we can build a dynamic version of libboard.

This commit is contained in:
2012-04-12 13:46:27 -04:00
parent 55dbed09f5
commit 8b772255a1
2259 changed files with 388094 additions and 291 deletions

View File

@ -0,0 +1,9 @@
SET(utils_STAT_SRCS
getopt.c
getopt1.c
random.c
gg_utils.c
winsocket.c
)
ADD_LIBRARY(utils STATIC ${utils_STAT_SRCS})

10
gnugo/utils/Makefile.am Normal file
View File

@ -0,0 +1,10 @@
noinst_LIBRARIES = libutils.a
EXTRA_DIST = utils.dsp CMakeLists.txt
libutils_a_SOURCES = getopt.c getopt1.c random.c gg_utils.c winsocket.c
noinst_HEADERS = gg-getopt.h random.h gg_utils.h winsocket.h
# Remove these files here... they are created locally
DISTCLEANFILES = *~

400
gnugo/utils/Makefile.in Normal file
View File

@ -0,0 +1,400 @@
# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
subdir = utils
DIST_COMMON = README $(noinst_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
LIBRARIES = $(noinst_LIBRARIES)
AR = ar
ARFLAGS = cru
libutils_a_AR = $(AR) $(ARFLAGS)
libutils_a_LIBADD =
am_libutils_a_OBJECTS = getopt.$(OBJEXT) getopt1.$(OBJEXT) \
random.$(OBJEXT) gg_utils.$(OBJEXT) winsocket.$(OBJEXT)
libutils_a_OBJECTS = $(am_libutils_a_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(libutils_a_SOURCES)
DIST_SOURCES = $(libutils_a_SOURCES)
HEADERS = $(noinst_HEADERS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DFA_ENABLED_FALSE = @DFA_ENABLED_FALSE@
DFA_ENABLED_TRUE = @DFA_ENABLED_TRUE@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GCC_MAJOR_VERSION = @GCC_MAJOR_VERSION@
GCC_MINOR_VERSION = @GCC_MINOR_VERSION@
GCC_ONLY_FALSE = @GCC_ONLY_FALSE@
GCC_ONLY_TRUE = @GCC_ONLY_TRUE@
GNU_GO_WARNINGS = @GNU_GO_WARNINGS@
GREP = @GREP@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
MAKEINFO = @MAKEINFO@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
ac_ct_CC = @ac_ct_CC@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build_alias = @build_alias@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
glibconfig = @glibconfig@
host_alias = @host_alias@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
noinst_LIBRARIES = libutils.a
EXTRA_DIST = utils.dsp CMakeLists.txt
libutils_a_SOURCES = getopt.c getopt1.c random.c gg_utils.c winsocket.c
noinst_HEADERS = gg-getopt.h random.h gg_utils.h winsocket.h
# Remove these files here... they are created locally
DISTCLEANFILES = *~
all: all-am
.SUFFIXES:
.SUFFIXES: .c .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu utils/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu utils/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
clean-noinstLIBRARIES:
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
libutils.a: $(libutils_a_OBJECTS) $(libutils_a_DEPENDENCIES)
-rm -f libutils.a
$(libutils_a_AR) libutils.a $(libutils_a_OBJECTS) $(libutils_a_LIBADD)
$(RANLIB) libutils.a
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gg_utils.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/winsocket.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
uninstall-info-am:
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LIBRARIES) $(HEADERS)
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am:
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-noinstLIBRARIES ctags distclean distclean-compile \
distclean-generic distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-exec install-exec-am install-info \
install-info-am install-man install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
uninstall-am uninstall-info-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

11
gnugo/utils/README Normal file
View File

@ -0,0 +1,11 @@
The files getopt.h, getopt.c, getopt1.c are from glibc-2.1.2,
The getopt functions are included because a lot of platforms do not have
getopt functions for processing long options. Some platforms (VC,MINGW32)
don't have the getopt function that processes single letter options.
getopt.h was renamed to gg-getopt.h to avoid conflicts with system provided
getopt.h files.
Function getopt was renamed gg_getopt to avoid conflicts with the system
provided getopt function.

1042
gnugo/utils/getopt.c Normal file

File diff suppressed because it is too large Load Diff

186
gnugo/utils/getopt1.c Normal file
View File

@ -0,0 +1,186 @@
/* getopt_long and getopt_long_only entry points for GNU getopt.
Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98
Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 3 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
#include "gg-getopt.h"
#if !defined __STDC__ || !__STDC__
/* This is a separate conditional since some stdc systems
reject `defined (const)'. */
#ifndef const
#define const
#endif
#endif
#include <stdio.h>
/* Comment out all this code if we are using the GNU C Library, and are not
actually compiling the library itself. This code is part of the GNU C
Library, but also included in many other GNU distributions. Compiling
and linking in this code is a waste when using the GNU C library
(especially if it is a shared library). Rather than having every GNU
program understand `configure --with-gnu-libc' and omit the object files,
it is simpler to just do this in the source for each such file. */
#define GETOPT_INTERFACE_VERSION 2
#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
#include <gnu-versions.h>
#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
/*#define ELIDE_CODE*/
#endif
#endif
#ifndef ELIDE_CODE
/* This needs to come after some library #include
to get __GNU_LIBRARY__ defined. */
#ifdef __GNU_LIBRARY__
#include <stdlib.h>
#endif
#ifndef NULL
#define NULL 0
#endif
int
gg_getopt_long (argc, argv, options, long_options, opt_index)
int argc;
char *const *argv;
const char *options;
const struct gg_option *long_options;
int *opt_index;
{
return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
}
/* Like getopt_long, but '-' as well as '--' can indicate a long option.
If an option that starts with '-' (not '--') doesn't match a long option,
but does match a short option, it is parsed as a short option
instead. */
int
getopt_long_only (argc, argv, options, long_options, opt_index)
int argc;
char *const *argv;
const char *options;
const struct gg_option *long_options;
int *opt_index;
{
return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
}
#endif /* Not ELIDE_CODE. */
#ifdef TEST
#include <stdio.h>
int
main (argc, argv)
int argc;
char **argv;
{
int c;
int digit_optind = 0;
while (1)
{
int this_option_optind = gg_optind ? gg_optind : 1;
int option_index = 0;
static struct gg_option long_options[] =
{
{"add", 1, 0, 0},
{"append", 0, 0, 0},
{"delete", 1, 0, 0},
{"verbose", 0, 0, 0},
{"create", 0, 0, 0},
{"file", 1, 0, 0},
{0, 0, 0, 0}
};
c = gg_getopt_long (argc, argv, "abc:d:0123456789",
long_options, &option_index);
if (c == -1)
break;
switch (c)
{
case 0:
printf ("option %s", long_options[option_index].name);
if (gg_optarg)
printf (" with arg %s", gg_optarg);
printf ("\n");
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (digit_optind != 0 && digit_optind != this_option_optind)
printf ("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf ("option %c\n", c);
break;
case 'a':
printf ("option a\n");
break;
case 'b':
printf ("option b\n");
break;
case 'c':
printf ("option c with value `%s'\n", gg_optarg);
break;
case 'd':
printf ("option d with value `%s'\n", gg_optarg);
break;
case '?':
break;
default:
printf ("?? getopt returned character code 0%o ??\n", c);
}
}
if (gg_optind < argc)
{
printf ("non-option ARGV-elements: ");
while (gg_optind < argc)
printf ("%s ", argv[gg_optind++]);
printf ("\n");
}
exit (0);
}
#endif /* TEST */

170
gnugo/utils/gg-getopt.h Normal file
View File

@ -0,0 +1,170 @@
/* Declarations for getopt.
Copyright (C) 1989,90,91,92,93,94,96,97,98 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 3 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
#ifndef GG_GETOPT_H
#ifndef __need_getopt
# define GG_GETOPT_H 1
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* For communication from `getopt' to the caller.
When `getopt' finds an option that takes an argument,
the argument value is returned here.
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
extern char *gg_optarg;
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
and for communication between successive calls to `getopt'.
On entry to `getopt', zero means this is the first call; initialize.
When `getopt' returns -1, this is the index of the first of the
non-option elements that the caller should itself scan.
Otherwise, `optind' communicates from one call to the next
how much of ARGV has been scanned so far. */
extern int gg_optind;
/* Callers store zero here to inhibit the error message `getopt' prints
for unrecognized options. */
extern int gg_opterr;
/* Set to an option character which was unrecognized. */
extern int gg_optopt;
#ifndef __need_getopt
/* Describe the long-named options requested by the application.
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
of `struct option' terminated by an element containing a name which is
zero.
The field `has_arg' is:
no_argument (or 0) if the option does not take an argument,
required_argument (or 1) if the option requires an argument,
optional_argument (or 2) if the option takes an optional argument.
If the field `flag' is not NULL, it points to a variable that is set
to the value given in the field `val' when the option is found, but
left unchanged if the option is not found.
To have a long-named option do something other than set an `int' to
a compiled-in constant, such as set a value from `optarg', set the
option's `flag' field to zero and its `val' field to a nonzero
value (the equivalent single-letter option character, if there is
one). For long options that have a zero `flag' field, `getopt'
returns the contents of the `val' field. */
struct gg_option
{
# if defined __STDC__ && __STDC__
const char *name;
# else
char *name;
# endif
/* has_arg can't be an enum because some compilers complain about
type mismatches in all the code that assumes it is an int. */
int has_arg;
int *flag;
int val;
};
/* Names for the values of the `has_arg' field of `struct option'. */
# define no_argument 0
# define required_argument 1
# define optional_argument 2
#endif /* need getopt */
/* Get definitions and prototypes for functions to process the
arguments in ARGV (ARGC of them, minus the program name) for
options given in OPTS.
Return the option character from OPTS just read. Return -1 when
there are no more options. For unrecognized options, or options
missing arguments, `optopt' is set to the option letter, and '?' is
returned.
The OPTS string is a list of characters which are recognized option
letters, optionally followed by colons, specifying that that letter
takes an argument, to be placed in `optarg'.
If a letter in OPTS is followed by two colons, its argument is
optional. This behavior is specific to the GNU `getopt'.
The argument `--' causes premature termination of argument
scanning, explicitly telling `getopt' that there are no more
options.
If OPTS begins with `--', then non-option arguments are treated as
arguments to the option '\0'. This behavior is specific to the GNU
`getopt'. */
#if defined __STDC__ && __STDC__
# ifdef __GNU_LIBRARY__
/* Many other libraries have conflicting prototypes for getopt, with
differences in the consts, in stdlib.h. To avoid compilation
errors, only prototype getopt for the GNU C library. */
extern int gg_getopt (int argc, char *const *argv, const char *shortopts);
# else /* not __GNU_LIBRARY__ */
extern int gg_getopt (int argc, char *const *argv, const char *shortopts);
# endif /* __GNU_LIBRARY__ */
# ifndef __need_getopt
extern int gg_getopt_long (int argc, char *const *argv, const char *shortopts,
const struct gg_option *longopts, int *longind);
extern int gg_getopt_long_only (int argc, char *const *argv,
const char *shortopts,
const struct gg_option *longopts, int *longind);
/* Internal only. Users should not call this directly. */
extern int _getopt_internal (int argc, char *const *argv,
const char *shortopts,
const struct gg_option *longopts, int *longind,
int long_only);
# endif
#else /* not __STDC__ */
extern int gg_getopt ();
# ifndef __need_getopt
extern int gg_getopt_long ();
extern int gg_getopt_long_only ();
extern int _getopt_internal ();
# endif
#endif /* __STDC__ */
#ifdef __cplusplus
}
#endif
/* Make sure we later can get all the definitions and declarations. */
#undef __need_getopt
#endif /* getopt.h */

557
gnugo/utils/gg_utils.c Normal file
View File

@ -0,0 +1,557 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* This is GNU Go, a Go program. Contact gnugo@gnu.org, or see *
* http://www.gnu.org/software/gnugo/ for more information. *
* *
* Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
* 2008 and 2009 by the Free Software Foundation. *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation - version 3 or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License in file COPYING for more details. *
* *
* You should have received a copy of the GNU General Public *
* License along with this program; if not, write to the Free *
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02111, USA. *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include "gg_utils.h"
#include "random.h"
#ifdef HAVE_GLIB_H
#include <glib.h>
#endif
/* Avoid compiler warnings with unused parameters */
#define UNUSED(x) (void)x
/* Define TERMINFO or ANSI_COLOR to enable coloring of pieces.
* This is normally done in config.h.
*/
/* enabling color */
/* linux console :
* 0=black
* 1=red
* 2=green
* 3=yellow/brown
* 4=blue
* 5=magenta
* 6=cyan
* 7=white
*/
#ifdef TERMINFO
#ifdef _AIX
#define _TPARM_COMPAT
#endif
#if HAVE_CURSES_H
#include <curses.h>
#elif HAVE_NCURSES_CURSES_H
#include <ncurses/curses.h>
#else
#endif
#if HAVE_TERM_H
#include <term.h>
#elif HAVE_NCURSES_TERM_H
#include <ncurses/term.h>
#else
#endif
/* terminfo attributes */
static char *setaf; /* terminfo string to set color */
static char *op; /* terminfo string to reset colors */
static int init = 0;
#endif /* TERMINFO */
/* for gg_cputime */
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_TIMES_H
#include <sys/times.h>
#elif defined(WIN32)
#include <windows.h>
#endif
void
gg_init_color()
{
#ifdef TERMINFO
/* compiler is set to make string literals const char *
* But system header files dont prototype things correctly.
* These are equivalent to a non-const string literals
*/
static char setaf_literal[] = "setaf";
static char op_literal[] = "op";
static char empty_literal[] = "";
if (init)
return;
init = 1;
setupterm(NULL, 2, NULL);
setaf = tigetstr(setaf_literal);
if (!setaf)
setaf = empty_literal;
op = tigetstr(op_literal);
if (!op)
op = empty_literal;
#endif /* TERMINFO */
}
#ifdef WIN32
#ifdef VC
#include <crtdbg.h>
verifyW32(BOOL b)
{
if (!b) {
_ASSERTE(0 && "Win32 Error");
fprintf(stderr, "Win32 Err: %ld\n", GetLastError());
}
}
#else
/* mingw32 lacks crtdbg.h and _ASSERTE */
verifyW32(BOOL b)
{
if (!b) {
fprintf(stderr, "Win32 Err: %ld\n", GetLastError());
}
}
#endif
#endif
void
write_color_char_no_space(int c, int x)
{
#ifdef TERMINFO
fprintf(stderr, "%s%c", tparm(setaf, c, 0, 0, 0, 0, 0, 0, 0, 0), x);
fputs(tparm(op, 0, 0, 0, 0, 0, 0, 0, 0, 0), stderr);
#elif defined(ANSI_COLOR)
fprintf(stderr, "\033[%dm%c\033[0m", 30+c, x);
#elif defined(WIN32)
static HANDLE hStdErr = 0;
DWORD iCharsWritten;
BOOL succeed32;
CONSOLE_SCREEN_BUFFER_INFO bufInfo;
if (!hStdErr) {
hStdErr = GetStdHandle(STD_ERROR_HANDLE);
if (hStdErr == INVALID_HANDLE_VALUE) {
fprintf(stderr, "Unable to open stderr.\n");
}
}
/* Red & Blue are switched from what MS-Windows wants:
* FOREGROUND_BLUE 0x0001 // text color contains blue.
* FOREGROUND_GREEN 0x0002 // text color contains green.
* FOREGROUND_RED 0x0004 // text color contains red
* This magic switches the bits back:
*/
c = (c & 1) * 4 + (c & 2) + (c & 4) / 4;
c += FOREGROUND_INTENSITY;
succeed32 = GetConsoleScreenBufferInfo(hStdErr, &bufInfo);
if (!succeed32) { /* Probably redirecting output, just give plain text. */
fprintf(stderr, "%c", x);
return;
}
verifyW32(SetConsoleTextAttribute(hStdErr, (WORD) c));
verifyW32(WriteConsole(hStdErr, &x, 1, &iCharsWritten, 0));
verifyW32(SetConsoleTextAttribute(hStdErr, bufInfo.wAttributes));
#else
fprintf(stderr, "%c", x);
#endif
}
void
write_color_string(int c, const char *str)
{
while (*str)
write_color_char_no_space(c, *str++);
}
void
write_color_char(int c, int x)
{
fprintf(stderr, " ");
write_color_char_no_space(c, x);
}
/*
* A wrapper around vsnprintf.
*/
void
gg_vsnprintf(char *dest, unsigned long len, const char *fmt, va_list args)
{
#ifdef HAVE_VSNPRINTF
vsnprintf(dest, len, fmt, args);
#elif HAVE_G_VSNPRINTF
g_vsnprintf(dest, len, fmt, args);
#elif HAVE__VSNPRINTF
_vsnprintf(dest, len, fmt, args);
#else
UNUSED(len);
vsprintf(dest, fmt, args);
#endif
}
void
gg_snprintf(char *dest, unsigned long len, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
gg_vsnprintf(dest, len, fmt, args);
va_end(args);
}
/* Get the time of day, calling gettimeofday from sys/time.h
* if available, otherwise substituting a workaround for portability.
*/
double
gg_gettimeofday(void)
{
struct timeval tv;
#ifdef HAVE_GETTIMEOFDAY
gettimeofday(&tv, NULL);
#else
tv.tv_sec = time(NULL);
tv.tv_usec = 0;
#endif
return tv.tv_sec + 1.e-6 * tv.tv_usec;
}
const char *
gg_version(void)
{
return VERSION;
}
/* return cputime used in secs */
double
gg_cputime(void)
{
#if HAVE_SYS_TIMES_H && HAVE_TIMES && HAVE_UNISTD_H
struct tms t;
times(&t);
return (t.tms_utime + t.tms_stime + t.tms_cutime + t.tms_cstime)
/ ((double) sysconf(_SC_CLK_TCK));
#elif defined(WIN32)
FILETIME creationTime, exitTime, kernelTime, userTime;
ULARGE_INTEGER uKernelTime, uUserTime, uElapsedTime;
GetProcessTimes(GetCurrentProcess(), &creationTime, &exitTime,
&kernelTime, &userTime);
uKernelTime.LowPart = kernelTime.dwLowDateTime;
uKernelTime.HighPart = kernelTime.dwHighDateTime;
uUserTime.LowPart = userTime.dwLowDateTime;
uUserTime.HighPart = userTime.dwHighDateTime;
uElapsedTime.QuadPart = uKernelTime.QuadPart + uUserTime.QuadPart;
/*_ASSERTE(0 && "Debug Times");*/
/* convert from multiples of 100nanosecs to seconds: */
return (signed __int64)(uElapsedTime.QuadPart) * 1.e-7;
#else
static int warned = 0;
if (!warned) {
fprintf(stderr, "CPU timing unavailable - returning wall time.");
warned = 1;
}
/* return wall clock seconds */
return gg_gettimeofday();
#endif
}
/* Before we sort floating point values (or just compare them) we
* may need to normalize them. This may sound cryptic but is
* required to avoid an obscure platform dependency.
*
* The underlying problem is that most fractional decimal numbers
* can't be represented exactly in a floating point number with base
* two. The error may be small but it is there. When such numbers
* are added or subtracted, the errors accumulate and even if the
* result (counting exactly) should be a number which can be
* represented exactly, this cannot be assumed to be the case.
*
* To give an example of this, the computation 0.3 + 0.05 - 0.35 may
* sum to 0, a small negative value, or a small positive value.
* Moreover, which case we encounter depends on the number of
* mantissa bits in the floating point type used and the exact
* details of the floating point arithmetic on the platform.
*
* In the context of sorting, assume that two values both should be
* 0.35, but one has been computed as 0.3 + 0.05 and the other
* directly assigned 0.35. Then it depends on the platform whether
* they compare as equal or one of them is larger than the other.
*
* This code normalizes the values to avoid this problem. It is
* assumed that all values encountered are integer multiples of a.
*/
float
gg_normalize_float(float x, float a)
{
return a * ((int) (0.5 + x / a));
}
int
gg_normalize_float2int(float x, float a)
{
return ((int) (0.5 + x / a));
}
/* A sorting algorithm, call-compatible with the libc qsort() function.
*
* The reason to prefer this to standard qsort() is that quicksort is
* an unstable sorting algorithm, i.e. the relative ordering of
* elements with the same comparison value may change. Exactly how the
* ordering changes depends on implementation specific details like
* the strategy for choosing the pivot element. Thus a list with
* "equal" values may be sorted differently between platforms, which
* potentially can lead to significant differences in the move
* generation.
*
* This is an implementation of the combsort algorithm.
*
* Testing shows that it is faster than the GNU libc qsort() function
* on small data sets and within a factor of two slower for large
* random data sets. Its performance does not degenerate for common
* special cases (i.e. sorted or reversed data) but it seems to be
* susceptible to O(N^2) behavior for repetitive data with specific
* cycle lengths.
*
* Like qsort() this algorithm is unstable, but since the same
* implementation (this one) is used on all platforms, the reordering
* of equal elements will be consistent.
*/
void
gg_sort(void *base, size_t nel, size_t width,
int (*cmp)(const void *, const void *))
{
int gap = nel;
int swap_made;
char *end = (char *) base + width * (nel - 1);
do {
char *a, *b;
swap_made = 0;
gap = (10 * gap + 3) / 13;
for (a = base, b = a + gap * width; b <= end; a += width, b += width) {
if (cmp((void *) a, (void *) b) > 0) {
char *c = a;
char *d = b;
size_t size = width;
while (size-- > 0) {
char tmp = *c;
*c++ = *d;
*d++ = tmp;
}
swap_made = 1;
}
}
} while (gap > 1 || swap_made);
}
/* Linearly interpolate f(x) from the data given in interpolation_data. */
float
gg_interpolate(struct interpolation_data *f, float x)
{
int i;
float ratio;
float diff;
if (x < f->range_lowerbound)
return f->values[0];
else if (x > f->range_upperbound)
return f->values[f->sections];
else {
ratio = ((float) f->sections) * (x - f->range_lowerbound)
/ (f->range_upperbound - f->range_lowerbound);
i = (int) ratio;
diff = ratio - ((float) i);
if (0)
fprintf(stderr, "Floating point Ratio: %f, integer: %d, diff %f",
ratio, i, diff);
return ((1 - diff) * f->values[i] + diff * f->values[i+1]);
}
}
/* This is the simplest function that returns appr. a when a is small,
* and approximately b when a is large.
*/
float
soft_cap(float a, float b)
{
return ((a * b) / (a + b));
}
/* Reorientation of point (i, j) into (*ri, *rj) */
void
rotate(int i, int j, int *ri, int *rj, int bs, int rot)
{
int bs1;
assert(bs > 0);
assert(ri != NULL && rj != NULL);
assert(rot >= 0 && rot < 8);
/* PASS case */
if (i == -1 && j == -1) {
*ri = i;
*rj = j;
return;
}
assert(i >= 0 && i < bs);
assert(j >= 0 && j < bs);
bs1 = bs - 1;
if (rot == 0) {
/* identity map */
*ri = i;
*rj = j;
}
else if (rot == 1) {
/* rotation over 90 degrees */
*ri = bs1 - j;
*rj = i;
}
else if (rot == 2) {
/* rotation over 180 degrees */
*ri = bs1 - i;
*rj = bs1 - j;
}
else if (rot == 3) {
/* rotation over 270 degrees */
*ri = j;
*rj = bs1 - i;
}
else if (rot == 4) {
/* flip along diagonal */
*ri = j;
*rj = i;
}
else if (rot == 5) {
/* flip */
*ri = bs1 - i;
*rj = j;
}
else if (rot == 6) {
/* flip along diagonal */
*ri = bs1 - j;
*rj = bs1 - i;
}
else if (rot == 7) {
/* flip */
*ri = i;
*rj = bs1 - j;
}
}
/* inverse reorientation of reorientation rot */
void
inv_rotate(int i, int j, int *ri, int *rj, int bs, int rot)
{
/* every reorientation is it's own inverse except rotations
over 90 and 270 degrees */
if (rot == 1)
rotate(i, j, ri, rj, bs, 3);
else if (rot == 3)
rotate(i, j, ri, rj, bs, 1);
else
rotate(i, j, ri, rj, bs, rot);
}
/* Intermediate layer to random.c. gg_srand() should only be called via the
* functions below.
*/
/* Private variable remembering the random seed. */
static unsigned int random_seed;
unsigned int
get_random_seed()
{
return random_seed;
}
void
set_random_seed(unsigned int seed)
{
random_seed = seed;
gg_srand(seed);
}
/* Update the random seed. This should be called at the start of each
* new game.
* We reset the random seed before obtaining a new one, to make the
* next random seed depend deterministically on the old one.
*/
void
update_random_seed(void)
{
gg_srand(random_seed);
random_seed = gg_rand();
/* Since random seed 0 has a special interpretation when given as
* command line argument with the -r option, we make sure to avoid
* it.
*/
if (random_seed == 0)
random_seed = 1;
gg_srand(random_seed);
}
/* Restart the pseudo-random sequence with the initialization given
* by the random seed. Should be called at each move.
*/
void
reuse_random_seed()
{
gg_srand(random_seed);
}
/*
* Local Variables:
* tab-width: 8
* c-basic-offset: 2
* End:
*/

104
gnugo/utils/gg_utils.h Normal file
View File

@ -0,0 +1,104 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* This is GNU Go, a Go program. Contact gnugo@gnu.org, or see *
* http://www.gnu.org/software/gnugo/ for more information. *
* *
* Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
* 2008 and 2009 by the Free Software Foundation. *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation - version 3 or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License in file COPYING for more details. *
* *
* You should have received a copy of the GNU General Public *
* License along with this program; if not, write to the Free *
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02111, USA. *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef _GG_UTILS_H_
#define _GG_UTILS_H_
#include <stdarg.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif
#ifdef __MINGW32__
#include <windows.h>
#include <winsock.h>
#include <io.h>
#endif
#ifdef HAVE_WINSOCK_IO_H
#include <winsock.h>
#include <io.h>
#endif
void gg_init_color(void);
void write_color_char(int c, int x);
void write_color_string(int c, const char *str);
void gg_vsnprintf(char *dest, unsigned long len, const char *fmt,
va_list args);
void gg_snprintf(char *dest, unsigned long len, const char *fmt, ...);
double gg_gettimeofday(void);
double gg_cputime(void);
float gg_normalize_float(float x, float a);
int gg_normalize_float2int(float x, float a);
void gg_sort(void *base, size_t nel, size_t width,
int (*compar)(const void *, const void *));
#define MAX_INTERPOLATION_STEPS 20
struct interpolation_data
{
int sections;
float range_lowerbound;
float range_upperbound;
float values[MAX_INTERPOLATION_STEPS + 1];
};
float gg_interpolate(struct interpolation_data *f, float x);
float soft_cap(float a, float b);
const char *gg_version(void);
/* prototypes for basic reorientation functions */
void rotate(int i, int j, int *ri, int *rj, int bs, int rot);
void inv_rotate(int i, int j, int *ri, int *rj, int bs, int rot);
void update_random_seed(void);
void set_random_seed(unsigned int seed);
unsigned int get_random_seed(void);
void reuse_random_seed(void);
#endif /* _GG_UTILS_H_ */
/*
* Local Variables:
* tab-width: 8
* c-basic-offset: 2
* End:
*/

201
gnugo/utils/random.c Normal file
View File

@ -0,0 +1,201 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* This is GNU Go, a Go program. Contact gnugo@gnu.org, or see *
* http://www.gnu.org/software/gnugo/ for more information. *
* *
* Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
* 2008 and 2009 by the Free Software Foundation. *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation - version 3 or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License in file COPYING for more details. *
* *
* You should have received a copy of the GNU General Public *
* License along with this program; if not, write to the Free *
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02111, USA. *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include <limits.h>
#include <assert.h>
#include "random.h"
/* This is an implementation of the TGFSR (twisted generalized
* feedback shift register) random number generator TT800, which was
* published in:
*
* Matsumoto, M. and Kurita, Y.: Twisted GFSR generators II.
* ACM Transactions on Modeling and Computer Simulations,
* Vol 4, No. 3, July 1994, pp 254--266
*
* The generator produces a pseudo-random sequence of 32 bit integers
* with period 2^800 - 1 and is reported to have excellent
* equidistribution properties, as well as being fast.
*/
/* Algorithm parameters. */
#define N 25
static const int m = 7;
static const int s = 7;
static const int t = 15;
static const unsigned int a = 0x8ebfd028U;
static const unsigned int b = 0x2b5b2500U;
static const unsigned int c = 0xdb8b0000U;
/* Global state for the random number generator. */
static unsigned int x[N];
static int k;
/* Set when properly seeded. */
static int rand_initialized = 0;
/* We use this to detect whether unsigned ints are bigger than 32
* bits. If they are we need to clear higher order bits, otherwise we
* can optimize by not doing the masking.
*/
#define BIG_UINT (UINT_MAX > 0xffffffffU)
/* Iterate the TGFSR once to get a new state which can be used to
* produce another 25 random numbers.
*/
static void
iterate_tgfsr(void)
{
int i;
for (i = 0; i < N - m; i++)
x[i] = x[i + m] ^ (x[i] >> 1) ^ ((x[i] & 1) ? a : 0);
for (; i < N; i++)
x[i] = x[i + m - N] ^ (x[i] >> 1) ^ ((x[i] & 1) ? a : 0);
}
/* Produce a random number from the next word of the internal state.
*/
static unsigned int
next_rand(void)
{
int y;
if (!rand_initialized) {
assert(rand_initialized); /* Abort. */
gg_srand(1); /* Initialize silently if assertions disabled. */
}
if (++k == N) {
iterate_tgfsr();
k = 0;
}
y = x[k] ^ ((x[k] << s) & b);
y ^= ((y << t) & c);
#if BIG_UINT
y &= 0xffffffffU;
#endif
return y;
}
/* Seed the random number generator. The first word of the internal
* state is set by the (lower) 32 bits of seed. The remaining 24 words
* are generated from the first one by a linear congruential pseudo
* random generator.
*
* FIXME: The constants in this generator has not been checked, but
* since they only are used to produce a very short sequence, which in
* turn only is a seed to a stronger generator, it probably doesn't
* matter much.
*/
void
gg_srand(unsigned int seed)
{
int i;
for (i = 0; i < N; i++) {
#if BIG_UINT
seed &= 0xffffffffU;
#endif
x[i] = seed;
seed *= 1313;
seed += 88897;
}
k = N-1; /* Force an immediate iteration of the TGFSR. */
rand_initialized = 1;
}
/* Obtain one random integer value in the interval [0, 2^31-1].
*/
int
gg_rand(void)
{
return (int) (next_rand() & 0x7fffffff);
}
/* Obtain one random integer value in the interval [0, 2^32-1].
*/
unsigned int
gg_urand(void)
{
return next_rand();
}
/* Obtain one random floating point value in the half open interval
* [0.0, 1.0).
*
* If the value is converted to a floating point type with less than
* 32 bits mantissa (or if the double type should happen to be
* unusually short), the value 1.0 may be attained.
*/
double
gg_drand(void)
{
return next_rand() * 2.328306436538696e-10;
}
/* Retrieve the internal state of the random generator.
*/
void
gg_get_rand_state(struct gg_rand_state *state)
{
int i;
for (i = 0; i < N; i++)
state->x[i] = x[i];
state->k = k;
}
/* Set the internal state of the random number generator.
*/
void
gg_set_rand_state(struct gg_rand_state *state)
{
int i;
for (i = 0; i < N; i++)
x[i] = state->x[i];
k = state->k;
}
/*
* Local Variables:
* tab-width: 8
* c-basic-offset: 2
* End:
*/

87
gnugo/utils/random.h Normal file
View File

@ -0,0 +1,87 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* This is GNU Go, a Go program. Contact gnugo@gnu.org, or see *
* http://www.gnu.org/software/gnugo/ for more information. *
* *
* Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
* 2008 and 2009 by the Free Software Foundation. *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation - version 3 or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License in file COPYING for more details. *
* *
* You should have received a copy of the GNU General Public *
* License along with this program; if not, write to the Free *
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02111, USA. *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef _RANDOM_H_
#define _RANDOM_H_
/* This random number generator produces 32 bit unsigned integers, no
* more, no less. Internally in the algorithm and for storing the
* state we need a type that is at least 32 bits wide. A longer type
* doesn't hurt but means a waste of bits.
*
* ISO C guarantees that an unsigned long always is at least 32 bits.
* It is not uncommon, however, that it is longer. An unsigned int is
* not guaranteed to be more than 16 bits wide, but on modern
* platforms we can be certain that this type too is 32 bits (or
* more). Also the GNU Coding Standards explicitly state that the
* possibility of ints shorter than 32 bits should be ignored.
*
* We could make a typedef here to choose exactly which type to use.
* In order to avoid various complications in the interface to the
* random number generator, however, we prefer to consistently use
* unsigned int internally and we assume this type to be at least 32
* bits wide.
*/
/* Internal state of the random number generator. */
struct gg_rand_state {
unsigned int x[25]; /* Internal state. */
int k; /* Word counter. */
};
/* Seed the random number generator. If an unsigned int is larger than
* 32 bits, only the 32 least significant bits are used for seeding.
*/
void gg_srand(unsigned int seed);
/* Obtain one random integer value in the interval [0, 2^31-1]. */
int gg_rand(void);
/* Obtain one random integer value in the interval [0, 2^32-1]. */
unsigned int gg_urand(void);
/* Obtain one random floating point value in the half open interval
* [0.0, 1.0).
*
* If the value is converted to a floating point type with less than
* 32 bits mantissa (or if the double type should happen to be
* unusually short), the value 1.0 may be attained.
*/
double gg_drand(void);
/* Retrieve the internal state of the random generator. */
void gg_get_rand_state(struct gg_rand_state *state);
/* Set the internal state of the random number generator. */
void gg_set_rand_state(struct gg_rand_state *state);
#endif /* _RANDOM_H_ */
/*
* Local Variables:
* tab-width: 8
* c-basic-offset: 2
* End:
*/

159
gnugo/utils/utils.dsp Normal file
View File

@ -0,0 +1,159 @@
# Microsoft Developer Studio Project File - Name="utils" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=utils - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "utils.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "utils.mak" CFG="utils - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "utils - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "utils - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "utils - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /GX /Zi /O2 /I "." /I ".." /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "HAVE_CONFIG_H" /Fd"Release/utils" /FD /c
# ADD BASE RSC /l 0x809 /d "NDEBUG"
# ADD RSC /l 0x809 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "utils - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /W2 /Gm /GX /ZI /Od /I "." /I ".." /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D "HAVE_CONFIG_H" /FR /Fd"Debug/utils" /FD /GZ /c
# ADD BASE RSC /l 0x809 /d "_DEBUG"
# ADD RSC /l 0x809 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ENDIF
# Begin Target
# Name "utils - Win32 Release"
# Name "utils - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\config.vc
!IF "$(CFG)" == "utils - Win32 Release"
# Begin Custom Build
InputPath=..\config.vc
"..\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
copy ..\config.vc ..\config.h
# End Custom Build
!ELSEIF "$(CFG)" == "utils - Win32 Debug"
# Begin Custom Build
InputPath=..\config.vc
"..\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
copy ..\config.vc ..\config.h
# End Custom Build
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\getopt.c
# End Source File
# Begin Source File
SOURCE=.\getopt1.c
# End Source File
# Begin Source File
SOURCE=.\gg_utils.c
# End Source File
# Begin Source File
SOURCE=.\random.c
# End Source File
# Begin Source File
SOURCE=.\winsocket.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=..\config.h
# End Source File
# Begin Source File
SOURCE=".\gg-getopt.h"
# End Source File
# Begin Source File
SOURCE=.\gg_utils.h
# End Source File
# Begin Source File
SOURCE=.\random.h
# End Source File
# Begin Source File
SOURCE=.\winsocket.h
# End Source File
# End Group
# End Target
# End Project

237
gnugo/utils/winsocket.c Normal file
View File

@ -0,0 +1,237 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* This is GNU Go, a Go program. Contact gnugo@gnu.org, or see *
* http://www.gnu.org/software/gnugo/ for more information. *
* *
* Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
* 2008 and 2009 by the Free Software Foundation. *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation - version 3 or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License in file COPYING for more details. *
* *
* You should have received a copy of the GNU General Public *
* License along with this program; if not, write to the Free *
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02111, USA. *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Workaround M$ Windows C library deficiency: it cannot handle
* sockets as stdio streams. So we do this ourselves, more or less.
*
* Call winsocket_activate(...) with socket handle to use. After this
* fake stream NULL will work over the socket, while other streams
* will (hopefully) keep working as usual.
*/
#define WINSOCKET_H_INTERNAL_INCLUSION
#include "winsocket.h"
#if USE_WINDOWS_SOCKET_CLUDGE
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <winsock.h>
static int socket_handle = 0;
static int socket_end_of_file = 0;
void
winsocket_activate(int _socket_handle)
{
assert(socket_handle == 0);
socket_handle = _socket_handle;
}
/* Miscellaneous functions. */
void
winsocket_setbuf(FILE *file, char *buffer)
{
if (file != NULL)
setbuf(file, buffer);
else
assert(socket_handle != 0);
}
int
winsocket_fflush(FILE *file)
{
if (file != NULL)
return fflush(file);
else {
assert(socket_handle != 0);
return 0;
}
}
int
winsocket_feof(FILE *file)
{
if (file != NULL)
return feof(file);
else {
assert(socket_handle != 0);
return socket_end_of_file;
}
}
int
winsocket_fclose(FILE *file)
{
if (file != NULL)
return fclose(file);
else {
assert(socket_handle != 0);
return 0;
}
}
/* Input functions. */
size_t
winsocket_fread(void *buffer, size_t size, size_t num_items, FILE *file)
{
if (file != NULL)
return fread(buffer, size, num_items, file);
else {
assert(socket_handle != 0);
if (recv(socket_handle, (char *) buffer, size * num_items, 0)
== size * num_items)
return num_items;
else {
socket_end_of_file = 1;
return EOF;
}
}
}
char *
winsocket_fgets(char *buffer, int size, FILE *file)
{
if (file != NULL)
return fgets(buffer, size, file);
else {
/* FIXME: Optimize if reading char-by-char is too slow. */
int stored_length;
for (stored_length = 0; stored_length < size - 1; stored_length) {
if (recv(socket_handle, buffer + stored_length, 1, 0) != 1) {
socket_end_of_file = 1;
break;
}
if (buffer[stored_length++] == '\n')
break;
}
if (stored_length == 0)
return NULL;
buffer[stored_length + 1] = 0;
return buffer;
}
}
/* Output functions. */
size_t
winsocket_fwrite(const void *buffer, size_t size, size_t num_items,
FILE *file)
{
if (file != NULL)
return fwrite(buffer, size, num_items, file);
else {
assert(socket_handle != 0);
return ((send(socket_handle, (const char *) buffer, size * num_items, 0)
== size * num_items)
? num_items : EOF);
}
}
int
winsocket_fputc(int character, FILE *file)
{
if (file != NULL)
return fputc(character, file);
else {
assert(socket_handle != 0);
return (send(socket_handle, (const char *) &character, 1, 0) == 1
? character : EOF);
}
}
int
winsocket_fputs(const char *string, FILE *file)
{
if (file != NULL)
return fputs(string, file);
else {
int length = strlen(string);
assert(socket_handle != 0);
return send(socket_handle, string, length, 0) == length ? length : EOF;
}
}
int
winsocket_fprintf(FILE *file, const char *format_string, ...)
{
va_list arguments;
int result;
va_start(arguments, format_string);
result = winsocket_vfprintf(file, format_string, arguments);
va_end(arguments);
return result;
}
int
winsocket_vfprintf(FILE *file, const char *format_string, va_list arguments)
{
if (file != NULL)
return vfprintf(file, format_string, arguments);
else {
char buffer[0x1000];
int length = _vsnprintf(buffer, sizeof buffer, format_string, arguments);
assert(socket_handle != 0);
return send(socket_handle, buffer, length, 0) == length ? length : -1;
}
}
#endif /* USE_WINDOWS_SOCKET_CLUDGE */
/*
* Local Variables:
* tab-width: 8
* c-basic-offset: 2
* End:
*/

105
gnugo/utils/winsocket.h Normal file
View File

@ -0,0 +1,105 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* This is GNU Go, a Go program. Contact gnugo@gnu.org, or see *
* http://www.gnu.org/software/gnugo/ for more information. *
* *
* Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, *
* 2008 and 2009 by the Free Software Foundation. *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation - version 3 or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License in file COPYING for more details. *
* *
* You should have received a copy of the GNU General Public *
* License along with this program; if not, write to the Free *
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02111, USA. *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef GNU_GO_WINSOCKET_H
#define GNU_GO_WINSOCKET_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#define USE_WINDOWS_SOCKET_CLUDGE \
((defined(_WIN32) || defined(_WIN32_WCE)) \
&& defined(ENABLE_SOCKET_SUPPORT))
#if USE_WINDOWS_SOCKET_CLUDGE
#include <stdarg.h>
#include <stdio.h>
#ifndef WINSOCKET_H_INTERNAL_INCLUSION
/* (sic.) Teh cludge. */
/* At least in some versions of `stdio.h' on Windows, feof() is a
* macro, not a function.
*/
#ifdef feof
#undef feof
#endif
#define setbuf winsocket_setbuf
#define fflush winsocket_fflush
#define feof winsocket_feof
#define fclose winsocket_fclose
#define fread winsocket_fread
#define fgets winsocket_fgets
#define fwrite winsocket_fwrite
#define fputc winsocket_fputc
#define fputs winsocket_fputs
#define fprintf winsocket_fprintf
#define vfprintf winsocket_vfprintf
#endif /* WINSOCKET_H_INTERNAL_INCLUSION */
void winsocket_activate(int _socket_handle);
void winsocket_setbuf(FILE *file, char *buffer);
int winsocket_fflush(FILE *file);
int winsocket_feof(FILE *file);
int winsocket_fclose(FILE *file);
size_t winsocket_fread(void *buffer,
size_t size, size_t num_items, FILE *file);
char * winsocket_fgets(char *buffer, int size, FILE *file);
size_t winsocket_fwrite(const void *buffer,
size_t size, size_t num_items, FILE *file);
int winsocket_fputc(int character, FILE *file);
int winsocket_fputs(const char *string, FILE *file);
int winsocket_fprintf(FILE *file, const char *format_string, ...);
int winsocket_vfprintf(FILE *file, const char *format_string,
va_list arguments);
#endif /* USE_WINDOWS_SOCKET_CLUDGE */
#endif /* GNU_GO_WINSOCKET_H */
/*
* Local Variables:
* tab-width: 8
* c-basic-offset: 2
* End:
*/