help: Avoid depending on Gnulib mbswidth
[dxcommon.git] / tests / libs.at
blobd1c6d1fcbd1ec5c70c32a60bff842bca59e7859d
1 # Copyright © 2019-2020, 2022-2024 Nick Bowler
3 # This program is free software: you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation, either version 3 of the License, or
6 # (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program.  If not, see <https://www.gnu.org/licenses/>.
16 AT_BANNER([Library tests])
18 # TEST_DUMMY_PKGCONFIG([cflags], [libs])
20 # Create a hack pkg-config script in the current working directory which
21 # responds to --cflags and --libs with the provided values.  The macro
22 # arguments should each be a single shell word, suitable for the right
23 # hand side of a shell assignment.
24 m4_define([TEST_DUMMY_PKGCONFIG],
25 [[cat >pkg-config <<EOF
26 #!/bin/sh
27 cflags= libs=
28 for arg
30   case \$arg in
31   --cflags) cflags=]$1[;;
32   --libs) libs=]$2[;;
33   --atleast-pkgconfig-version) exit;;
34   esac
35 done
36 printf '%s %s\n' "\$cflags" "\$libs"
37 EOF
38 chmod +x pkg-config
39 ]])
41 AT_SETUP([libdiscid probes])
42 AT_KEYWORDS([lib libdiscid])
44 mkdir discid
45 AT_DATA([discid/discid.h],
46 [[typedef void DiscId;
47 DiscId *discid_new(void);
48 void discid_free(DiscId *);
49 #ifndef DISCID_VERSION_MAJOR
50 #  define DISCID_VERSION_MAJOR 2
51 #endif
52 ]])
54 AT_DATA([test.in],
55 [[@HAVE_LIBDISCID@
56 @LIBDISCID_CFLAGS@
57 @LIBDISCID_LIBS@
58 ]])
60 TEST_CONFIGURE_AC([[DX_LIB_LIBDISCID([1.2.3], [HAVE_LIBDISCID=yes],
61                                               [HAVE_LIBDISCID=no])
62 AC_SUBST([HAVE_LIBDISCID])
63 AC_CONFIG_FILES([test])
64 ]])
65 TEST_AUTORECONF
67 # Check the search via explicit flags
68 TEST_CONFIGURE([LIBDISCID_CFLAGS=-I. LIBDISCID_LIBS="$builddir/t/libdummy.a"])
69 AT_CHECK_UNQUOTED([cat test], [0], [yes
70 -I.
71 $builddir/t/libdummy.a
74 # Check the search via pkg-config
75 TEST_DUMMY_PKGCONFIG([-I.], [$builddir/t/libdummy.a])
76 TEST_CONFIGURE([PKG_CONFIG=$PWD/pkg-config])
77 AT_CHECK_UNQUOTED([cat test], [0], [yes
78 -I.
79 $builddir/t/libdummy.a
82 # Check the default -ldiscid search
83 cp "$builddir/t/libdummy.a" libdiscid.a
84 TEST_CONFIGURE([PKG_CONFIG=false CFLAGS=-I. LDFLAGS=-L.])
85 AT_CHECK_UNQUOTED([cat test], [0], [yes
87 -ldiscid
90 # Check the failure case
91 TEST_CONFIGURE([PKG_CONFIG=false CFLAGS='-I. -DDISCID_VERSION_MAJOR=0'])
92 AT_CHECK_UNQUOTED([cat test], [0], [no
97 AT_CLEANUP
99 AT_SETUP([curses probes])
100 AT_KEYWORDS([lib curses ncurses])
102 AT_DATA([curses.h],
103 [[void initscr(void) { }
104 void endwin(void) { }
105 void curs_set(int);
108 AT_DATA([test.in],
109 [[@HAVE_CURSES@
110 @CURSES_CFLAGS@
111 @CURSES_LIBS@
114 TEST_CONFIGURE_AC([[DX_LIB_CURSES([HAVE_CURSES=yes], [HAVE_CURSES=no])
115 AC_SUBST([HAVE_CURSES])
116 AC_CONFIG_FILES([test])
118 TEST_AUTORECONF
120 # Check the search via explicit flags
121 TEST_CONFIGURE([CURSES_CFLAGS=-I. CURSES_LIBS="$builddir/t/libdummy.a"])
122 AT_CHECK_UNQUOTED([cat test], [0], [yes
124 $builddir/t/libdummy.a
127 # Check the search via pkg-config
128 TEST_DUMMY_PKGCONFIG([-I.], [$builddir/t/libdummy.a])
129 TEST_CONFIGURE([PKG_CONFIG=$PWD/pkg-config])
130 AT_CHECK_UNQUOTED([cat test], [0], [yes
132 $builddir/t/libdummy.a
135 # Check the default -lcurses search
136 cp "$builddir/t/libdummy.a" libcurses.a
137 TEST_CONFIGURE([PKG_CONFIG=false CFLAGS=-I. LDFLAGS=-L.])
138 AT_CHECK_UNQUOTED([cat test], [0], [yes
140 -lcurses
143 # Check the failure case
144 cp "$builddir/t/libempty.a" libcurses.a
145 TEST_CONFIGURE([PKG_CONFIG=false CFLAGS=-I. LDFLAGS=-L.])
146 AT_CHECK_UNQUOTED([cat test], [0], [no
151 AT_CLEANUP
153 AT_SETUP([DX_CHECK_CURSES_GETMOUSE_NCURSES])
154 AT_KEYWORDS([lib curses ncurses])
156 mkdir ncurses sysv bogus
157 AT_DATA([ncurses/curses.h],
158 [[typedef struct MEVENT { int x; } MEVENT;
159 int getmouse_nc_(MEVENT *);
160 #define getmouse getmouse_nc_
163 AT_DATA([sysv/curses.h],
164 [[unsigned getmouse(void);
167 AT_DATA([bogus/curses.h],
168 [[typedef int MEVENT;
169 int getmouse_bogus_(void *);
170 #define getmouse getmouse_bogus_
173 AT_DATA([test.in],
174 [[@dx_cv_curses_have_getmouse_ncurses@
177 TEST_CONFIGURE_AC([[AC_CONFIG_HEADERS([config.h])
178 DX_CHECK_CURSES_GETMOUSE_NCURSES
179 AC_SUBST([dx_cv_curses_have_getmouse_ncurses])
180 AC_CONFIG_FILES([test])
182 TEST_AUTORECONF
184 TEST_CONFIGURE([CURSES_CFLAGS=-Incurses CURSES_LIBS="$builddir/t/libdummy.a"])
185 AT_CHECK([cat test && grep HAVE_CURSES config.h], [0], [yes
186 #define HAVE_CURSES_GETMOUSE_NCURSES 1
189 TEST_CONFIGURE([CURSES_CFLAGS=-Isysv CURSES_LIBS="$builddir/t/libdummy.a"])
190 AT_CHECK([cat test && grep HAVE_CURSES config.h], [0], [no
191 /* #undef HAVE_CURSES_GETMOUSE_NCURSES */
194 TEST_CONFIGURE([CURSES_CFLAGS=-Ibogus CURSES_LIBS="$builddir/t/libdummy.a"])
195 AT_CHECK([cat test && grep HAVE_CURSES config.h], [0], [no
196 /* #undef HAVE_CURSES_GETMOUSE_NCURSES */
199 AT_CLEANUP
201 AT_SETUP([DX_CHECK_CURSES_MOUSE_SUPPORT])
202 AT_KEYWORDS([lib curses ncurses])
204 mkdir hp ncurses sysv
206 # HP-UX 11 curses contains definitions of mouse functions in the library but
207 # is missing declarations and associated macros in <curses.h>, although they
208 # are present in the alternate "cur_colr" implementation.
210 # Regardless, neither implementation seems to have working mouse support with
211 # any X terminal emulator so for now no workarounds are provided and the checks
212 # are expected to return "no".
213 AT_DATA([hp/curses.h],
214 [[int mouse_set(unsigned long);
215 int request_mouse_pos(void);
218 # Ncurses-like mouse functions.
219 AT_DATA([ncurses/curses.h],
220 [[unsigned long mousemask(unsigned long, unsigned long *);
221 typedef int MEVENT;
222 int getmouse_nc_(MEVENT *);
223 #define getmouse getmouse_nc_
224 #define BUTTON1_RELEASED 1L
225 #define BUTTON1_PRESSED 2L
227 /* rename this to avoid false positives in the test */
228 #define mouse_set mouse_set_bogus_
231 # SysV-like mouse funcitons.
232 AT_DATA([sysv/curses.h],
233 [[int mouse_set(unsigned long);
234 int request_mouse_pos(void);
236 #define BUTTON_STATUS(x) 0
237 #define BUTTON_RELEASED 0
238 #define BUTTON_PRESSED 1
240 #define BUTTON1_RELEASED 1L
241 #define BUTTON1_PRESSED 2L
244 AT_DATA([test.in],
245 [[@dx_cv_curses_have_mouse_set@
246 @dx_cv_curses_have_mousemask@
247 @dx_cv_curses_have_getmouse_ncurses@
248 @dx_cv_curses_have_request_mouse_pos@
251 TEST_CONFIGURE_AC([[AC_CONFIG_HEADERS([config.h])
252 DX_CHECK_CURSES_MOUSE_SUPPORT
253 AC_SUBST([dx_cv_curses_have_mouse_set])
254 AC_SUBST([dx_cv_curses_have_mousemask])
255 AC_SUBST([dx_cv_curses_have_request_mouse_pos])
256 AC_SUBST([dx_cv_curses_have_getmouse_ncurses])
257 AC_CONFIG_FILES([test])
259 TEST_AUTORECONF
261 TEST_CONFIGURE([CURSES_CFLAGS=-Ihp CURSES_LIBS="$builddir/t/libdummy.a"])
262 AT_CHECK([cat test && grep CURSES_MOUSE_SUPPORT config.h], [0], [no
266 /* #undef HAVE_CURSES_MOUSE_SUPPORT */
269 TEST_CONFIGURE([CURSES_CFLAGS=-Incurses CURSES_LIBS="$builddir/t/libdummy.a"])
270 AT_CHECK([cat test && grep CURSES_MOUSE_SUPPORT config.h], [0], [no
274 #define HAVE_CURSES_MOUSE_SUPPORT 1
277 TEST_CONFIGURE([CURSES_CFLAGS=-Isysv CURSES_LIBS="$builddir/t/libdummy.a"])
278 AT_CHECK([cat test && grep CURSES_MOUSE_SUPPORT config.h], [0], [yes
282 #define HAVE_CURSES_MOUSE_SUPPORT 1
285 AT_CLEANUP
287 AT_SETUP([GLib GNU inline workaround])
289 TEST_DUMMY_PKGCONFIG([-I.], [$builddir/t/libdummy.a])
291 # This test will only work if we have a version of GCC that implements
292 # C99 inline semantics by default.
293 AT_DATA([a.c],
294 [[#if __GNUC__
295 extern inline void my_dup_fn(void) { }
296 #endif
297 int main(void) { return 0; }
299 AT_DATA([b.c],
300 [[#if __GNUC__
301 extern inline void my_dup_fn(void) { }
302 #endif
305 AT_DATA([test.sh.in],
306 [[#!/bin/sh
307 @CC@ @CPPFLAGS@ @CFLAGS@ -c a.c || exit 77
308 @CC@ @CPPFLAGS@ @CFLAGS@ -c b.c || exit 77
309 @CC@ @CFLAGS@ @LDFLAGS@ a.o b.o || exit 0
310 exit 77
313 AT_DATA([glib.h],
314 [[#define GLIB_CHECK_VERSION(x, y, z) 1
315 const char *g_get_prgname(void);
318 TEST_CONFIGURE_AC([[AC_CONFIG_HEADERS([config.h])
319 DX_LIB_GLIB2
320 AC_CONFIG_FILES([test.sh], [chmod +x test.sh])
322 TEST_AUTORECONF
323 TEST_CONFIGURE([PKG_CONFIG=$PWD/pkg-config])
324 AT_CHECK([./test.sh], [0], [ignore], [ignore])
326 AT_CHECK([grep '#.*G_INLINE_FUNC' config.h], [0],
327 [/* #undef G_INLINE_FUNC */
329 AT_CHECK([grep '#.*G_IMPLEMENT_INLINES' config.h], [0],
330 [/* #undef G_IMPLEMENT_INLINES */
333 cp glib.h glib-orig.h
334 cat glib-orig.h - >glib.h <<'EOF'
335 #ifndef G_INLINE_FUNC
336 #  define G_INLINE_FUNC extern inline
337 #endif
338 G_INLINE_FUNC void break_things(void) { }
341 TEST_CONFIGURE([PKG_CONFIG=$PWD/pkg-config])
342 AT_CHECK([grep '#.*G_INLINE_FUNC' config.h], [0],
343 [#define G_INLINE_FUNC static inline
345 AT_CHECK([grep '#.*G_IMPLEMENT_INLINES' config.h], [0],
346 [/* #undef G_IMPLEMENT_INLINES */
349 cat glib-orig.h - >glib.h <<'EOF'
350 #define G_INLINE_FUNC extern inline
351 #ifdef G_IMPLEMENT_INLINES
352 extern void break_things(void);
353 #else
354 G_INLINE_FUNC void break_things(void) { }
355 #endif
358 TEST_CONFIGURE([PKG_CONFIG=$PWD/pkg-config])
359 AT_CHECK([grep '#.*G_INLINE_FUNC' config.h], [0],
360 [/* #undef G_INLINE_FUNC */
362 AT_CHECK([grep '#.*G_IMPLEMENT_INLINES' config.h], [0],
363 [#define G_IMPLEMENT_INLINES 1
366 AT_CLEANUP
368 AT_SETUP([DX_CHECK_SYSLOG])
370 AT_DATA([syslog.h],
371 [[/* since syslog is normally in the standard C library, to make negative
372 link tests possible we use a dummy external name */
373 extern void dx_link_stub(void);
375 static void openlog(const char *, int, int) { dx_link_stub(); }
376 static void syslog(int, const char *, ...) { dx_link_stub(); }
377 static void closelog(void) { dx_link_stub(); }
379 #define LOG_PID  1
380 #define LOG_USER 2
381 #define LOG_ERR  0
384 AT_DATA([test.in],
385 [[@ac_cv_header_syslog_h@
386 @dx_cv_have_syslog@
389 TEST_CONFIGURE_AC([[DX_CHECK_SYSLOG
390 AC_SUBST([ac_cv_header_syslog_h])
391 AC_SUBST([dx_cv_have_syslog])
392 AC_CONFIG_FILES([test])
394 TEST_AUTORECONF
396 TEST_CONFIGURE([CFLAGS=-I.])
397 AT_CHECK([cat test], [0], [yes
401 TEST_CONFIGURE([CFLAGS=-I. LIBS="$builddir/t/libdummy.a"])
402 AT_CHECK([cat test], [0], [yes
406 AT_CLEANUP
408 AT_SETUP([DX_CHECK_GETLINE])
410 AT_DATA([stdio.h],
411 [[/* since getline is normally in the standard C library, to make negative link
412 tests possible we use a dummy external name */
413 extern void dx_link_stub(void);
414 typedef unsigned long size_t;
415 typedef long ssize_t;
416 typedef int FILE;
418 static FILE stdin[1];
420 #if !NO_GETLINE_DECL
421 static size_t getline(char **line, size_t *n, FILE *f) { dx_link_stub(); }
422 #endif
425 AT_DATA([test.in],
426 [[@dx_cv_have_getline@
427 @DEFS@
430 TEST_CONFIGURE_AC([[AC_PROG_CC
431 CPPFLAGS="-I$srcdir $CPPFLAGS"
432 DX_CHECK_GETLINE
433 AC_SUBST([dx_cv_have_getline])
434 AC_CONFIG_FILES([test])
436 TEST_AUTORECONF
438 TEST_CONFIGURE
439 AT_CHECK([sed '[s/-DPACKAGE\([^\\ ]*\\.\)*[^ ]* *//g]' test], [0], [no
443 TEST_CONFIGURE([LIBS="$builddir/t/libdummy.a"])
444 AT_CHECK([sed '[s/-DPACKAGE\([^\\ ]*\\.\)*[^ ]* *//g]' test], [0], [yes
445 -DHAVE_GETLINE=1
448 TEST_CONFIGURE([CPPFLAGS="-DNO_GETLINE_DECL" LIBS="$builddir/t/libdummy.a"])
449 AT_CHECK([sed '[s/-DPACKAGE\([^\\ ]*\\.\)*[^ ]* *//g]' test], [0], [no
453 AT_CLEANUP
455 AT_SETUP([DX_CHECK_GETOPT_LONG(_ONLY)])
456 AT_KEYWORDS([DX_CHECK_GETOPT_LONG DX_CHECK_GETOPT_LONG_ONLY])
458 AT_DATA([getopt.h],
459 [[/* since getopt_long(_only) is normally in the standard C library, to make
460 negative link tests possible we use a dummy external name */
461 extern void dx_link_stub(void);
463 #if !NO_STRUCT_DECL
464 struct option { char *name; int has_arg, *flag, val; };
465 #endif
467 #if !NO_VAR_DECL
468 extern int optind, optopt, opterr;
469 extern char *optarg;
470 #endif
472 #if !NO_GETOPT_LONG_DECL
473 static int getopt_long(int argc, char * const *argv, const char *sopts,
474                        const struct option *lopts, int *idx)
476   dx_link_stub();
477   return 0;
479 #endif
481 #if !NO_GETOPT_LONG_ONLY_DECL
482 static int getopt_long_only(int argc, char * const *argv, const char *sopts,
483                             const struct option *lopts, int *idx)
485 #if NO_GETOPT_LONG_ONLY
486   extern void dx_link_error(void);
487   dx_link_error();
488 #else
489   dx_link_stub();
490 #endif
491   return 0;
493 #endif
496 AT_DATA([test.in],
497 [[@dx_cv_have_getopt_long@ @dx_cv_have_getopt_long_only@
498 @DEFS@
501 TEST_CONFIGURE_AC([[AC_PROG_CC
502 CPPFLAGS="-I$srcdir $CPPFLAGS"
503 DX_CHECK_GETOPT_LONG
504 DX_CHECK_GETOPT_LONG_ONLY
505 AC_SUBST([dx_cv_have_getopt_long])
506 AC_SUBST([dx_cv_have_getopt_long_only])
507 AC_CONFIG_FILES([test])
509 TEST_AUTORECONF
511 TEST_CONFIGURE
512 AT_CHECK([sed '[s/-DPACKAGE\([^\\ ]*\\.\)*[^ ]* *//g]' test], [0], [no no
516 LIBS="$builddir/t/libdummy.a"; export LIBS
517 TEST_CONFIGURE
518 AT_CHECK([sed '[s/-DPACKAGE\([^\\ ]*\\.\)*[^ ]* *//g]' test], [0], [yes yes
519 -DHAVE_GETOPT_LONG=1 -DHAVE_GETOPT_LONG_ONLY=1
522 TEST_CONFIGURE([CPPFLAGS="-DNO_GETOPT_LONG_ONLY"])
523 AT_CHECK([sed '[s/-DPACKAGE\([^\\ ]*\\.\)*[^ ]* *//g]' test], [0], [yes no
524 -DHAVE_GETOPT_LONG=1
527 TEST_CONFIGURE([CPPFLAGS="-DNO_STRUCT_DECL"])
528 AT_CHECK([sed '[s/-DPACKAGE\([^\\ ]*\\.\)*[^ ]* *//g]' test], [0], [no no
532 TEST_CONFIGURE([CPPFLAGS="-DNO_VAR_DECL"])
533 AT_CHECK([sed '[s/-DPACKAGE\([^\\ ]*\\.\)*[^ ]* *//g]' test], [0], [no no
537 AT_CLEANUP
539 AT_SETUP([DX_CHECK_MBRTOWC_WCWIDTH])
541 AT_DATA([wchar.h],
542 [[/* Since mbrtowc and wcwidth are normally in the standard C library, to make
543 negative link tests possible we use a dummy external name */
544 extern void dx_link_stub(void);
546 #if !NO_MBSTATE_DECL && (!HPUX_MBSTATE_DECL || _XOPEN_SOURCE == 500)
547 typedef int mbstate_t;
548 #endif
550 typedef unsigned short wchar_t;
551 wchar_t dummy_extern;
553 #if NO_MBRTOWC
554 #  define mbrtowc nonexistent_function
555 #else
556 static unsigned mbrtowc(wchar_t *out, const char *s, unsigned n, int *ps)
558   dx_link_stub();
559   *out = dummy_extern;
560   return 0;
562 #endif
564 #if NO_WCWIDTH
565 #  define wcwidth nonexistent_function
566 #else
567 static int wcwidth(wchar_t c)
569   dx_link_stub();
570   return 0;
572 #endif
575 AT_DATA([test.in],
576 [[@dx_cv_have_mbrtowc_wcwidth@
577 @DEFS@
580 TEST_CONFIGURE_AC([[AC_PROG_CC
581 CPPFLAGS="-I$srcdir $CPPFLAGS"
583 AC_DEFUN([AC_USE_SYSTEM_EXTENSIONS],
584   [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <wchar.h>
585 mbstate_t x;])], [],
586     [save_CPPFLAGS=$CPPFLAGS; CPPFLAGS="-D_XOPEN_SOURCE=500 $CPPFLAGS"
587 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <wchar.h>
588 mbstate_t x;])], [AC_DEFINE([_XOPEN_SOURCE], [500])])
589 CPPFLAGS=$save_CPPFLAGS])])
591 DX_CHECK_MBRTOWC_WCWIDTH
592 AC_SUBST([dx_cv_have_mbrtowc_wcwidth])
593 AC_CONFIG_FILES([test])
595 TEST_AUTORECONF
597 TEST_CONFIGURE
598 AT_CHECK([sed '[s/-DPACKAGE\([^\\ ]*\\.\)*[^ ]* *//g]' test], [0], [no
602 LIBS="$builddir/t/libdummy.a"; export LIBS
603 TEST_CONFIGURE
604 AT_CHECK([sed '[s/-DPACKAGE\([^\\ ]*\\.\)*[^ ]* *//g]' test], [0], [yes
605 -DHAVE_MBRTOWC=1 -DHAVE_WCWIDTH=1
608 TEST_CONFIGURE([CPPFLAGS=-DHPUX_MBSTATE_DECL])
609 AT_CHECK([sed '[s/-DPACKAGE\([^\\ ]*\\.\)*[^ ]* *//g]' test], [0], [yes
610 -D_XOPEN_SOURCE=500 -DHAVE_MBRTOWC=1 -DHAVE_WCWIDTH=1
613 TEST_CONFIGURE([CPPFLAGS=-DNO_MBRTOWC])
614 AT_CHECK([sed '[s/-DPACKAGE\([^\\ ]*\\.\)*[^ ]* *//g]' test], [0], [no
618 TEST_CONFIGURE([CPPFLAGS=-DNO_WCWIDTH])
619 AT_CHECK([sed '[s/-DPACKAGE\([^\\ ]*\\.\)*[^ ]* *//g]' test], [0], [no
623 AT_CLEANUP