Mon, 31 Aug 2026 15:49:31 +0200
add option to select a specific curses implementation
resolves #981
| configure | file | annotate | diff | comparison | revisions | |
| make/chklib.sh | file | annotate | diff | comparison | revisions | |
| make/project.xml | file | annotate | diff | comparison | revisions | |
| src/input.h | file | annotate | diff | comparison | revisions | |
| src/main.c | file | annotate | diff | comparison | revisions | |
| test/Makefile | file | annotate | diff | comparison | revisions |
--- a/configure Tue Aug 25 22:25:33 2026 +0200 +++ b/configure Mon Aug 31 15:49:31 2026 +0200 @@ -99,6 +99,10 @@ --debug add extra compile flags for debug builds --release add extra compile flags for release builds +Options: + --curses=(ncursesw|cursesw|ncurses|curses) + The curses implementation to use. + Optional Features: --enable-asan address sanitizer --enable-strict-errors treat compiler warnings as errors @@ -175,6 +179,8 @@ "--help"*) printhelp ;; "--debug") BUILD_TYPE="debug" ;; "--release") BUILD_TYPE="release" ;; + "--curses="*) OPT_CURSES=${ARG#--curses=} ;; + "--curses") echo "option '$ARG' needs a value:"; echo " $ARG=(ncursesw|cursesw|ncurses|curses)"; abort_configure ;; "--enable-asan") FEATURE_ASAN=on ;; "--disable-asan") unset FEATURE_ASAN ;; "--enable-strict-errors") FEATURE_STRICT_ERRORS=on ;; @@ -339,10 +345,10 @@ dep_checked_asan=1 return 0 } -dependency_error_ncurses() +dependency_error_ncursesw() { - print_check_msg "$dep_checked_ncurses" "checking for ncurses... " - # dependency ncurses + print_check_msg "$dep_checked_ncursesw" "checking for ncursesw... " + # dependency ncursesw while true do if [ -z "$PKG_CONFIG" ]; then @@ -354,6 +360,172 @@ else break fi + print_check_msg "$dep_checked_ncursesw" "yes\n" + dep_checked_ncursesw=1 + return 1 + done + + # dependency ncursesw + while true + do + if ./make/chklib.sh ncursesw > /dev/null 2>&1 ; then + : + else + break + fi + if ./make/chklib.sh tinfo > /dev/null 2>&1 ; then + : + else + break + fi + TEMP_LDFLAGS="$TEMP_LDFLAGS -lncursesw -ltinfo" + print_check_msg "$dep_checked_ncursesw" "yes\n" + dep_checked_ncursesw=1 + return 1 + done + + # dependency ncursesw + while true + do + if ./make/chklib.sh ncursesw > /dev/null 2>&1 ; then + : + else + break + fi + TEMP_LDFLAGS="$TEMP_LDFLAGS -lncursesw" + print_check_msg "$dep_checked_ncursesw" "yes\n" + dep_checked_ncursesw=1 + return 1 + done + + print_check_msg "$dep_checked_ncursesw" "no\n" + dep_checked_ncursesw=1 + return 0 +} +dependency_error_curses() +{ + print_check_msg "$dep_checked_curses" "checking for curses... " + # dependency curses + while true + do + if [ -z "$PKG_CONFIG" ]; then + break + fi + if test_pkg_config "curses" "" "" "" ; then + TEMP_CFLAGS="$TEMP_CFLAGS `"$PKG_CONFIG" --cflags curses`" + TEMP_LDFLAGS="$TEMP_LDFLAGS `"$PKG_CONFIG" --libs curses`" + else + break + fi + print_check_msg "$dep_checked_curses" "yes\n" + dep_checked_curses=1 + return 1 + done + + # dependency curses + while true + do + if ./make/chklib.sh curses > /dev/null 2>&1 ; then + : + else + break + fi + TEMP_LDFLAGS="$TEMP_LDFLAGS -lcurses" + print_check_msg "$dep_checked_curses" "yes\n" + dep_checked_curses=1 + return 1 + done + + print_check_msg "$dep_checked_curses" "no\n" + dep_checked_curses=1 + return 0 +} +dependency_error_cursesw() +{ + print_check_msg "$dep_checked_cursesw" "checking for cursesw... " + # dependency cursesw + while true + do + if [ -z "$PKG_CONFIG" ]; then + break + fi + if test_pkg_config "cursesw" "" "" "" ; then + TEMP_CFLAGS="$TEMP_CFLAGS `"$PKG_CONFIG" --cflags cursesw`" + TEMP_LDFLAGS="$TEMP_LDFLAGS `"$PKG_CONFIG" --libs cursesw`" + else + break + fi + print_check_msg "$dep_checked_cursesw" "yes\n" + dep_checked_cursesw=1 + return 1 + done + + # dependency cursesw + while true + do + if ./make/chklib.sh cursesw > /dev/null 2>&1 ; then + : + else + break + fi + TEMP_LDFLAGS="$TEMP_LDFLAGS -lcursesw" + print_check_msg "$dep_checked_cursesw" "yes\n" + dep_checked_cursesw=1 + return 1 + done + + print_check_msg "$dep_checked_cursesw" "no\n" + dep_checked_cursesw=1 + return 0 +} +dependency_error_ncurses() +{ + print_check_msg "$dep_checked_ncurses" "checking for ncurses... " + # dependency ncurses + while true + do + if [ -z "$PKG_CONFIG" ]; then + break + fi + if test_pkg_config "ncurses" "" "" "" ; then + TEMP_CFLAGS="$TEMP_CFLAGS `"$PKG_CONFIG" --cflags ncurses`" + TEMP_LDFLAGS="$TEMP_LDFLAGS `"$PKG_CONFIG" --libs ncurses`" + else + break + fi + print_check_msg "$dep_checked_ncurses" "yes\n" + dep_checked_ncurses=1 + return 1 + done + + # dependency ncurses + while true + do + if ./make/chklib.sh ncurses > /dev/null 2>&1 ; then + : + else + break + fi + if ./make/chklib.sh tinfo > /dev/null 2>&1 ; then + : + else + break + fi + TEMP_LDFLAGS="$TEMP_LDFLAGS -lncurses -ltinfo" + print_check_msg "$dep_checked_ncurses" "yes\n" + dep_checked_ncurses=1 + return 1 + done + + # dependency ncurses + while true + do + if ./make/chklib.sh ncurses > /dev/null 2>&1 ; then + : + else + break + fi + TEMP_LDFLAGS="$TEMP_LDFLAGS -lncurses" print_check_msg "$dep_checked_ncurses" "yes\n" dep_checked_ncurses=1 return 1 @@ -412,6 +584,54 @@ # # OPTION VALUES # +checkopt_curses_ncursesw() +{ + VERR=0 + if dependency_error_ncursesw ; then + VERR=1 + fi + if [ $VERR -ne 0 ]; then + return 1 + fi + return 0 +} +checkopt_curses_cursesw() +{ + VERR=0 + if dependency_error_cursesw ; then + VERR=1 + fi + if [ $VERR -ne 0 ]; then + return 1 + fi + return 0 +} +checkopt_curses_ncurses() +{ + VERR=0 + if dependency_error_ncurses ; then + VERR=1 + fi + if [ $VERR -ne 0 ]; then + return 1 + fi + TEMP_CFLAGS="$TEMP_CFLAGS -DDISABLE_UNICODE" + TEMP_CXXFLAGS="$TEMP_CXXFLAGS -DDISABLE_UNICODE" + return 0 +} +checkopt_curses_curses() +{ + VERR=0 + if dependency_error_curses ; then + VERR=1 + fi + if [ $VERR -ne 0 ]; then + return 1 + fi + TEMP_CFLAGS="$TEMP_CFLAGS -DDISABLE_UNICODE" + TEMP_CXXFLAGS="$TEMP_CXXFLAGS -DDISABLE_UNICODE" + return 0 +} # # TARGETS @@ -424,10 +644,6 @@ TEMP_CXXFLAGS= TEMP_LDFLAGS= -if dependency_error_ncurses; then - DEPENDENCIES_FAILED="$DEPENDENCIES_FAILED ncurses " - ERROR=1 -fi # Features if [ -n "$FEATURE_ASAN" ]; then @@ -464,6 +680,85 @@ : fi +# Option: --curses +if [ -z "$OPT_CURSES" ]; then + echo "auto-detecting option 'curses'" + SAVED_ERROR="$ERROR" + SAVED_DEPENDENCIES_FAILED="$DEPENDENCIES_FAILED" + ERROR=1 + while true + do + if checkopt_curses_ncursesw ; then + echo " curses: ncursesw" >> "$TEMP_DIR/options" + ERROR=0 + break + fi + if checkopt_curses_cursesw ; then + echo " curses: cursesw" >> "$TEMP_DIR/options" + ERROR=0 + break + fi + if checkopt_curses_ncurses ; then + echo " curses: ncurses" >> "$TEMP_DIR/options" + ERROR=0 + break + fi + if checkopt_curses_curses ; then + echo " curses: curses" >> "$TEMP_DIR/options" + ERROR=0 + break + fi + break + done + if [ $ERROR -ne 0 ]; then + SAVED_ERROR=1 + SAVED_DEPENDENCIES_FAILED="option 'curses' $SAVED_DEPENDENCIES_FAILED" + fi + ERROR="$SAVED_ERROR" + DEPENDENCIES_FAILED="$SAVED_DEPENDENCIES_FAILED" +else + echo "checking option curses = $OPT_CURSES" + if false; then + false + elif [ "$OPT_CURSES" = "ncursesw" ]; then + echo " curses: $OPT_CURSES" >> $TEMP_DIR/options + if checkopt_curses_ncursesw ; then + : + else + ERROR=1 + DEPENDENCIES_FAILED="option 'curses' $DEPENDENCIES_FAILED" + fi + elif [ "$OPT_CURSES" = "cursesw" ]; then + echo " curses: $OPT_CURSES" >> $TEMP_DIR/options + if checkopt_curses_cursesw ; then + : + else + ERROR=1 + DEPENDENCIES_FAILED="option 'curses' $DEPENDENCIES_FAILED" + fi + elif [ "$OPT_CURSES" = "ncurses" ]; then + echo " curses: $OPT_CURSES" >> $TEMP_DIR/options + if checkopt_curses_ncurses ; then + : + else + ERROR=1 + DEPENDENCIES_FAILED="option 'curses' $DEPENDENCIES_FAILED" + fi + elif [ "$OPT_CURSES" = "curses" ]; then + echo " curses: $OPT_CURSES" >> $TEMP_DIR/options + if checkopt_curses_curses ; then + : + else + ERROR=1 + DEPENDENCIES_FAILED="option 'curses' $DEPENDENCIES_FAILED" + fi + else + echo + echo "Invalid option value - usage:" + echo " --curses=(ncursesw|cursesw|ncurses|curses)" + abort_configure + fi +fi if [ -n "${TEMP_CFLAGS}" ] && [ -n "$lang_c" ]; then echo "CFLAGS += $TEMP_CFLAGS" >> "$TEMP_DIR/flags.mk" @@ -505,6 +800,9 @@ echo "Config:" fi echo +echo "Options:" +cat "$TEMP_DIR/options" +echo echo "Features:" printf ' %-16s' 'asan:' if [ -n "$FEATURE_ASAN" ]; then
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/make/chklib.sh Mon Aug 31 15:49:31 2026 +0200 @@ -0,0 +1,16 @@ +#!/bin/sh + +libname="$1" +cc="$CC" +if test -z "$cc"; then cc=cc; fi +if test -z "$libname"; then exit 1; fi + +echo 'int main(){return 0;}' > .chklib-test.c + +if $cc -o /dev/null .chklib-test.c "-l$libname" ; then + rm .chklib-test.c + exit 0 +else + rm .chklib-test.c + exit 1 +fi
--- a/make/project.xml Tue Aug 25 22:25:33 2026 +0200 +++ b/make/project.xml Mon Aug 31 15:49:31 2026 +0200 @@ -14,15 +14,75 @@ <dependency> <lang>c</lang> </dependency> - <dependency name="ncurses"> + + <dependency name="ncursesw"> <pkgconfig>ncursesw</pkgconfig> </dependency> + <dependency name="ncursesw"> + <test>./make/chklib.sh ncursesw</test> + <test>./make/chklib.sh tinfo</test> + <ldflags>-lncursesw -ltinfo</ldflags> + </dependency> + <dependency name="ncursesw"> + <test>./make/chklib.sh ncursesw</test> + <ldflags>-lncursesw</ldflags> + </dependency> + + <dependency name="cursesw"> + <pkgconfig>cursesw</pkgconfig> + </dependency> + <dependency name="cursesw"> + <test>./make/chklib.sh cursesw</test> + <ldflags>-lcursesw</ldflags> + </dependency> + + <dependency name="curses"> + <pkgconfig>curses</pkgconfig> + </dependency> + <dependency name="curses"> + <test>./make/chklib.sh curses</test> + <ldflags>-lcurses</ldflags> + </dependency> + + <dependency name="ncurses"> + <pkgconfig>ncurses</pkgconfig> + </dependency> + <dependency name="ncurses"> + <test>./make/chklib.sh ncurses</test> + <test>./make/chklib.sh tinfo</test> + <ldflags>-lncurses -ltinfo</ldflags> + </dependency> + <dependency name="ncurses"> + <test>./make/chklib.sh ncurses</test> + <ldflags>-lncurses</ldflags> + </dependency> + <dependency name="asan" toolchain="gnuc"> <cflags>-fsanitize=address</cflags> <ldflags>-fsanitize=address</ldflags> </dependency> <target> - <dependencies>ncurses</dependencies> + <option arg="curses"> + <desc>The curses implementation to use.</desc> + <value str="ncursesw"> + <dependencies>ncursesw</dependencies> + </value> + <value str="cursesw"> + <dependencies>cursesw</dependencies> + </value> + <value str="ncurses"> + <dependencies>ncurses</dependencies> + <define name="DISABLE_UNICODE"/> + </value> + <value str="curses"> + <dependencies>curses</dependencies> + <define name="DISABLE_UNICODE"/> + </value> + <default value="ncursesw"/> + <default value="cursesw"/> + <default value="ncurses"/> + <default value="curses"/> + </option> <feature name="asan"> <desc>address sanitizer</desc> <dependencies>asan</dependencies>
--- a/src/input.h Tue Aug 25 22:25:33 2026 +0200 +++ b/src/input.h Mon Aug 31 15:49:31 2026 +0200 @@ -31,7 +31,7 @@ #define INPUT_H #include <stdlib.h> -#include <ncurses.h> +#include <curses.h> #ifdef __cplusplus extern "C" {
--- a/src/main.c Tue Aug 25 22:25:33 2026 +0200 +++ b/src/main.c Mon Aug 31 15:49:31 2026 +0200 @@ -42,6 +42,7 @@ #include <errno.h> #include <unistd.h> #include <getopt.h> +#include <curses.h> typedef struct { /** @@ -70,7 +71,9 @@ memset(&settings, 0, sizeof(settings)); settings.servercolor = WHITE; settings.port = 27015; +#ifndef DISABLE_UNICODE settings.unicode = !!setlocale(LC_CTYPE, "C.UTF-8"); +#endif } static void cleanup() { @@ -184,7 +187,9 @@ " -h This help page\n" " -p TCP port to use (default: 27015)\n" " -u Use Unix domain socket instead of TCP\n" +#ifndef DISABLE_UNICODE " -U Disables unicode pieces\n" +#endif " -v Print version information and exits\n" "\nTime control (default: disabled)\n" " -t <time> Time limit in minutes (or seconds when used with 's' suffix)\n"
--- a/test/Makefile Tue Aug 25 22:25:33 2026 +0200 +++ b/test/Makefile Mon Aug 31 15:49:31 2026 +0200 @@ -53,7 +53,44 @@ $(CC) -o $@ $(CFLAGS) -c $< $(BUILDDIR)/test-real-pgn.o: test-real-pgn.c ucxtest.h ../src/chess/pgn.h \ - ../src/chess/rules.h + ../src/chess/rules.h data/game001.pgn data/game002.pgn data/game003.pgn \ + data/game004.pgn data/game005.pgn data/game006.pgn data/game007.pgn \ + data/game008.pgn data/game009.pgn data/game010.pgn data/game011.pgn \ + data/game012.pgn data/game013.pgn data/game014.pgn data/game015.pgn \ + data/game016.pgn data/game017.pgn data/game018.pgn data/game019.pgn \ + data/game020.pgn data/game021.pgn data/game022.pgn data/game023.pgn \ + data/game024.pgn data/game025.pgn data/game026.pgn data/game027.pgn \ + data/game028.pgn data/game029.pgn data/game030.pgn data/game031.pgn \ + data/game032.pgn data/game033.pgn data/game034.pgn data/game035.pgn \ + data/game036.pgn data/game037.pgn data/game038.pgn data/game039.pgn \ + data/game040.pgn data/game041.pgn data/game042.pgn data/game043.pgn \ + data/game044.pgn data/game045.pgn data/game046.pgn data/game047.pgn \ + data/game048.pgn data/game049.pgn data/game050.pgn data/game051.pgn \ + data/game052.pgn data/game053.pgn data/game054.pgn data/game055.pgn \ + data/game056.pgn data/game057.pgn data/game058.pgn data/game059.pgn \ + data/game060.pgn data/game061.pgn data/game062.pgn data/game063.pgn \ + data/game064.pgn data/game065.pgn data/game066.pgn data/game067.pgn \ + data/game068.pgn data/game069.pgn data/game070.pgn data/game071.pgn \ + data/game072.pgn data/game073.pgn data/game074.pgn data/game075.pgn \ + data/game076.pgn data/game077.pgn data/game078.pgn data/game079.pgn \ + data/game080.pgn data/game081.pgn data/game082.pgn data/game083.pgn \ + data/game084.pgn data/game085.pgn data/game086.pgn data/game087.pgn \ + data/game088.pgn data/game089.pgn data/game090.pgn data/game091.pgn \ + data/game092.pgn data/game093.pgn data/game094.pgn data/game095.pgn \ + data/game096.pgn data/game097.pgn data/game098.pgn data/game099.pgn \ + data/game100.pgn data/game101.pgn data/game102.pgn data/game103.pgn \ + data/game104.pgn data/game105.pgn data/game106.pgn data/game107.pgn \ + data/game108.pgn data/game109.pgn data/game110.pgn data/game111.pgn \ + data/game112.pgn data/game113.pgn data/game114.pgn data/game115.pgn \ + data/game116.pgn data/game117.pgn data/game118.pgn data/game119.pgn \ + data/game120.pgn data/game121.pgn data/game122.pgn data/game123.pgn \ + data/game124.pgn data/game125.pgn data/game126.pgn data/game127.pgn \ + data/game128.pgn data/game129.pgn data/game130.pgn data/game131.pgn \ + data/game132.pgn data/game133.pgn data/game134.pgn data/game135.pgn \ + data/game136.pgn data/game137.pgn data/game138.pgn data/game139.pgn \ + data/game140.pgn data/game141.pgn data/game142.pgn data/game143.pgn \ + data/game144.pgn data/game145.pgn data/game146.pgn data/game147.pgn \ + data/game148.pgn data/game149.pgn data/game150.pgn @echo "Compiling $<" $(CC) -o $@ $(CFLAGS) -c $<