aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am4
-rw-r--r--src/flash/common.h1
-rw-r--r--src/flash/nor/bluenrg-x.c1
-rw-r--r--src/gnulib/Makefile.am237
-rw-r--r--src/gnulib/attribute.h218
-rw-r--r--src/gnulib/gl_anyhash1.h31
-rw-r--r--src/gnulib/gl_anyhash2.h82
-rw-r--r--src/gnulib/gl_anyhash_primes.h87
-rw-r--r--src/gnulib/gl_linkedhash_map.c330
-rw-r--r--src/gnulib/gl_linkedhash_map.h34
-rw-r--r--src/gnulib/gl_map.c3
-rw-r--r--src/gnulib/gl_map.h370
-rw-r--r--src/gnulib/limits.in.h121
-rw-r--r--src/gnulib/size_max.h30
-rw-r--r--src/gnulib/stdbool.in.h132
-rw-r--r--src/gnulib/stdint.in.h740
-rw-r--r--src/gnulib/sys_types.in.h106
-rw-r--r--src/gnulib/xsize.c3
-rw-r--r--src/gnulib/xsize.h108
-rw-r--r--src/helper/binarybuffer.c1
-rw-r--r--src/helper/bits.h1
-rw-r--r--src/helper/configuration.c2
-rw-r--r--src/helper/fileio.c1
-rw-r--r--src/helper/fileio.h2
-rw-r--r--src/helper/log.c1
-rw-r--r--src/helper/options.c1
-rw-r--r--src/helper/replacements.c1
-rw-r--r--src/helper/replacements.h1
-rw-r--r--src/helper/time_support.h1
-rw-r--r--src/jtag/adapter.c4
-rw-r--r--src/jtag/aice/aice_pipe.c1
-rw-r--r--src/jtag/aice/aice_transport.c1
-rw-r--r--src/jtag/aice/aice_usb.c1
-rw-r--r--src/jtag/core.c1
-rw-r--r--src/jtag/drivers/arm-jtag-ew.c1
-rw-r--r--src/jtag/drivers/cmsis_dap.c1
-rw-r--r--src/jtag/drivers/cmsis_dap_usb_bulk.c1
-rw-r--r--src/jtag/drivers/jlink.c1
-rw-r--r--src/jtag/drivers/jtag_usb_common.c1
-rw-r--r--src/jtag/drivers/jtag_usb_common.h3
-rw-r--r--src/jtag/drivers/jtag_vpi.c2
-rw-r--r--src/jtag/drivers/mpsse.c1
-rw-r--r--src/jtag/drivers/remote_bitbang.c2
-rw-r--r--src/jtag/drivers/rlink.c1
-rw-r--r--src/jtag/drivers/rlink.h1
-rw-r--r--src/jtag/drivers/stlink_usb.c1
-rw-r--r--src/jtag/drivers/ulink.c1
-rw-r--r--src/jtag/drivers/usb_blaster/ublast2_access_libusb.c1
-rw-r--r--src/jtag/drivers/usb_blaster/usb_blaster.c1
-rw-r--r--src/jtag/jtag.h1
-rw-r--r--src/m4/00gnulib.m485
-rw-r--r--src/m4/absolute-header.m4100
-rw-r--r--src/m4/extern-inline.m4114
-rw-r--r--src/m4/gnulib-cache.m457
-rw-r--r--src/m4/gnulib-common.m4727
-rw-r--r--src/m4/gnulib-comp.m4261
-rw-r--r--src/m4/gnulib-tool.m457
-rw-r--r--src/m4/include_next.m4224
-rw-r--r--src/m4/limits-h.m443
-rw-r--r--src/m4/multiarch.m465
-rw-r--r--src/m4/off_t.m418
-rw-r--r--src/m4/pid_t.m438
-rw-r--r--src/m4/size_max.m475
-rw-r--r--src/m4/ssize_t.m423
-rw-r--r--src/m4/std-gnu11.m4829
-rw-r--r--src/m4/stdbool.m4122
-rw-r--r--src/m4/stdint.m4533
-rw-r--r--src/m4/sys_types_h.m458
-rw-r--r--src/m4/wint_t.m457
-rw-r--r--src/m4/xsize.m412
-rw-r--r--src/m4/zzgnulib.m423
-rw-r--r--src/main.c1
-rw-r--r--src/pld/pld.c1
-rw-r--r--src/pld/xilinx_bit.c2
-rw-r--r--src/pld/xilinx_bit.h2
-rw-r--r--src/rtos/FreeRTOS.c348
-rw-r--r--src/rtos/ThreadX.c18
-rw-r--r--src/rtos/nuttx.c18
-rw-r--r--src/rtos/rtos.c58
-rw-r--r--src/rtos/rtos.h21
-rw-r--r--src/rtos/rtos_chibios_stackings.c18
-rw-r--r--src/rtos/rtos_ecos_stackings.c10
-rw-r--r--src/rtos/rtos_embkernel_stackings.c10
-rw-r--r--src/rtos/rtos_mqx_stackings.c9
-rw-r--r--src/rtos/rtos_riot_stackings.c20
-rw-r--r--src/rtos/rtos_standard_stackings.c101
-rw-r--r--src/rtos/rtos_standard_stackings.h2
-rw-r--r--src/rtos/rtos_ucos_iii_stackings.c19
-rw-r--r--src/server/gdb_server.c3
-rw-r--r--src/server/server.h1
-rw-r--r--src/svf/svf.c1
-rw-r--r--src/target/algorithm.h3
-rw-r--r--src/target/armv4_5_cache.h2
-rw-r--r--src/target/breakpoints.h2
-rw-r--r--src/target/image.h1
-rw-r--r--src/target/nds32_edm.h2
-rw-r--r--src/target/register.h3
-rw-r--r--src/target/semihosting_common.h1
-rw-r--r--src/target/target.h2
-rw-r--r--src/target/trace.h2
-rw-r--r--src/transport/transport.c1
-rw-r--r--src/xsvf/xsvf.c1
102 files changed, 6675 insertions, 207 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 781c1e7..41153fb 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,3 +1,5 @@
+SUBDIRS += src/gnulib
+
noinst_LTLIBRARIES += %D%/libopenocd.la
bin_PROGRAMS += %D%/openocd
@@ -19,6 +21,7 @@ else
endif
%C%_libopenocd_la_CPPFLAGS =
+%C%_openocd_LDADD += src/gnulib/libgnu.a
# banner output includes RELSTR appended to $VERSION from the configure script
# guess-rev.sh returns either a repository version ID or "-snapshot"
@@ -60,6 +63,7 @@ BIN2C = $(srcdir)/%D%/helper/bin2char.sh
STARTUP_TCL_SRCS =
EXTRA_DIST += $(STARTUP_TCL_SRCS)
+EXTRA_DIST += m4/gnulib-cache.m4
BUILT_SOURCES += %D%/startup_tcl.inc
diff --git a/src/flash/common.h b/src/flash/common.h
index 4244f13..69f60d9 100644
--- a/src/flash/common.h
+++ b/src/flash/common.h
@@ -19,6 +19,7 @@
#define OPENOCD_FLASH_COMMON_H
#include <helper/log.h>
+#include <helper/replacements.h>
/**
* Parses the optional '.index' portion of a flash bank identifier.
diff --git a/src/flash/nor/bluenrg-x.c b/src/flash/nor/bluenrg-x.c
index 57aebc5..cf968cb 100644
--- a/src/flash/nor/bluenrg-x.c
+++ b/src/flash/nor/bluenrg-x.c
@@ -20,6 +20,7 @@
#include "config.h"
#endif
+#include "helper/types.h"
#include <target/algorithm.h>
#include <target/armv7m.h>
#include <target/cortex_m.h>
diff --git a/src/gnulib/Makefile.am b/src/gnulib/Makefile.am
new file mode 100644
index 0000000..62accdf
--- /dev/null
+++ b/src/gnulib/Makefile.am
@@ -0,0 +1,237 @@
+## DO NOT EDIT! GENERATED AUTOMATICALLY!
+## Process this file with automake to produce Makefile.in.
+# Copyright (C) 2002-2021 Free Software Foundation, Inc.
+#
+# This file 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; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This file 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 for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this file. If not, see <https://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License,
+# this file may be distributed as part of a program that
+# contains a configuration script generated by Autoconf, under
+# the same distribution terms as the rest of that program.
+#
+# Generated by gnulib-tool.
+# Reproduce by:
+# gnulib-tool --import \
+# --lib=libgnu \
+# --source-base=src/gnulib \
+# --m4-base=src/m4 \
+# --doc-base=doc \
+# --tests-base=tests \
+# --aux-dir=. \
+# --no-conditional-dependencies \
+# --no-libtool \
+# --macro-prefix=gl \
+# linkedhash-map
+
+AUTOMAKE_OPTIONS = 1.11 gnits
+
+SUBDIRS =
+noinst_HEADERS =
+noinst_LIBRARIES =
+noinst_LTLIBRARIES =
+EXTRA_DIST =
+BUILT_SOURCES =
+SUFFIXES =
+MOSTLYCLEANFILES = core *.stackdump
+MOSTLYCLEANDIRS =
+CLEANFILES =
+DISTCLEANFILES =
+MAINTAINERCLEANFILES =
+# No GNU Make output.
+
+AM_CPPFLAGS =
+AM_CFLAGS =
+
+noinst_LIBRARIES += libgnu.a
+
+libgnu_a_SOURCES =
+libgnu_a_LIBADD = $(gl_LIBOBJS)
+libgnu_a_DEPENDENCIES = $(gl_LIBOBJS)
+EXTRA_libgnu_a_SOURCES =
+
+## begin gnulib module absolute-header
+
+# Use this preprocessor expression to decide whether #include_next works.
+# Do not rely on a 'configure'-time test for this, since the expression
+# might appear in an installed header, which is used by some other compiler.
+HAVE_INCLUDE_NEXT = (__GNUC__ || __clang__ || 60000000 <= __DECC_VER)
+
+## end gnulib module absolute-header
+
+## begin gnulib module attribute
+
+
+EXTRA_DIST += attribute.h
+
+## end gnulib module attribute
+
+## begin gnulib module limits-h
+
+BUILT_SOURCES += $(LIMITS_H)
+
+# We need the following in order to create <limits.h> when the system
+# doesn't have one that is compatible with GNU.
+if GL_GENERATE_LIMITS_H
+limits.h: limits.in.h $(top_builddir)/config.status
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
+ sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+ -e 's|@''NEXT_LIMITS_H''@|$(NEXT_LIMITS_H)|g' \
+ < $(srcdir)/limits.in.h; \
+ } > $@-t && \
+ mv $@-t $@
+else
+limits.h: $(top_builddir)/config.status
+ rm -f $@
+endif
+MOSTLYCLEANFILES += limits.h limits.h-t
+
+EXTRA_DIST += limits.in.h
+
+## end gnulib module limits-h
+
+## begin gnulib module linkedhash-map
+
+libgnu_a_SOURCES += gl_linkedhash_map.h gl_linkedhash_map.c gl_anyhash1.h gl_anyhash2.h gl_anyhash_primes.h
+
+## end gnulib module linkedhash-map
+
+## begin gnulib module map
+
+libgnu_a_SOURCES += gl_map.h gl_map.c
+
+## end gnulib module map
+
+## begin gnulib module size_max
+
+libgnu_a_SOURCES += size_max.h
+
+## end gnulib module size_max
+
+## begin gnulib module stdbool
+
+BUILT_SOURCES += $(STDBOOL_H)
+
+# We need the following in order to create <stdbool.h> when the system
+# doesn't have one that works.
+if GL_GENERATE_STDBOOL_H
+stdbool.h: stdbool.in.h $(top_builddir)/config.status
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+ sed -e 's/@''HAVE__BOOL''@/$(HAVE__BOOL)/g' < $(srcdir)/stdbool.in.h; \
+ } > $@-t && \
+ mv $@-t $@
+else
+stdbool.h: $(top_builddir)/config.status
+ rm -f $@
+endif
+MOSTLYCLEANFILES += stdbool.h stdbool.h-t
+
+EXTRA_DIST += stdbool.in.h
+
+## end gnulib module stdbool
+
+## begin gnulib module stdint
+
+BUILT_SOURCES += $(STDINT_H)
+
+# We need the following in order to create <stdint.h> when the system
+# doesn't have one that works with the given compiler.
+if GL_GENERATE_STDINT_H
+stdint.h: stdint.in.h $(top_builddir)/config.status
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+ sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+ -e 's/@''HAVE_STDINT_H''@/$(HAVE_STDINT_H)/g' \
+ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+ -e 's|@''NEXT_STDINT_H''@|$(NEXT_STDINT_H)|g' \
+ -e 's/@''HAVE_C99_STDINT_H''@/$(HAVE_C99_STDINT_H)/g' \
+ -e 's/@''HAVE_SYS_TYPES_H''@/$(HAVE_SYS_TYPES_H)/g' \
+ -e 's/@''HAVE_INTTYPES_H''@/$(HAVE_INTTYPES_H)/g' \
+ -e 's/@''HAVE_SYS_INTTYPES_H''@/$(HAVE_SYS_INTTYPES_H)/g' \
+ -e 's/@''HAVE_SYS_BITYPES_H''@/$(HAVE_SYS_BITYPES_H)/g' \
+ -e 's/@''HAVE_WCHAR_H''@/$(HAVE_WCHAR_H)/g' \
+ -e 's/@''APPLE_UNIVERSAL_BUILD''@/$(APPLE_UNIVERSAL_BUILD)/g' \
+ -e 's/@''BITSIZEOF_PTRDIFF_T''@/$(BITSIZEOF_PTRDIFF_T)/g' \
+ -e 's/@''PTRDIFF_T_SUFFIX''@/$(PTRDIFF_T_SUFFIX)/g' \
+ -e 's/@''BITSIZEOF_SIG_ATOMIC_T''@/$(BITSIZEOF_SIG_ATOMIC_T)/g' \
+ -e 's/@''HAVE_SIGNED_SIG_ATOMIC_T''@/$(HAVE_SIGNED_SIG_ATOMIC_T)/g' \
+ -e 's/@''SIG_ATOMIC_T_SUFFIX''@/$(SIG_ATOMIC_T_SUFFIX)/g' \
+ -e 's/@''BITSIZEOF_SIZE_T''@/$(BITSIZEOF_SIZE_T)/g' \
+ -e 's/@''SIZE_T_SUFFIX''@/$(SIZE_T_SUFFIX)/g' \
+ -e 's/@''BITSIZEOF_WCHAR_T''@/$(BITSIZEOF_WCHAR_T)/g' \
+ -e 's/@''HAVE_SIGNED_WCHAR_T''@/$(HAVE_SIGNED_WCHAR_T)/g' \
+ -e 's/@''WCHAR_T_SUFFIX''@/$(WCHAR_T_SUFFIX)/g' \
+ -e 's/@''BITSIZEOF_WINT_T''@/$(BITSIZEOF_WINT_T)/g' \
+ -e 's/@''HAVE_SIGNED_WINT_T''@/$(HAVE_SIGNED_WINT_T)/g' \
+ -e 's/@''WINT_T_SUFFIX''@/$(WINT_T_SUFFIX)/g' \
+ -e 's/@''GNULIB_OVERRIDES_WINT_T''@/$(GNULIB_OVERRIDES_WINT_T)/g' \
+ < $(srcdir)/stdint.in.h; \
+ } > $@-t && \
+ mv $@-t $@
+else
+stdint.h: $(top_builddir)/config.status
+ rm -f $@
+endif
+MOSTLYCLEANFILES += stdint.h stdint.h-t
+
+EXTRA_DIST += stdint.in.h
+
+## end gnulib module stdint
+
+## begin gnulib module sys_types
+
+BUILT_SOURCES += sys/types.h
+
+# We need the following in order to create <sys/types.h> when the system
+# doesn't have one that works with the given compiler.
+sys/types.h: sys_types.in.h $(top_builddir)/config.status
+ $(AM_V_at)$(MKDIR_P) sys
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+ sed -e 's|@''GUARD_PREFIX''@|GL|g' \
+ -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+ -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+ -e 's|@''NEXT_SYS_TYPES_H''@|$(NEXT_SYS_TYPES_H)|g' \
+ -e 's|@''WINDOWS_64_BIT_OFF_T''@|$(WINDOWS_64_BIT_OFF_T)|g' \
+ -e 's|@''WINDOWS_STAT_INODES''@|$(WINDOWS_STAT_INODES)|g' \
+ < $(srcdir)/sys_types.in.h; \
+ } > $@-t && \
+ mv $@-t $@
+MOSTLYCLEANFILES += sys/types.h sys/types.h-t
+
+EXTRA_DIST += sys_types.in.h
+
+## end gnulib module sys_types
+
+## begin gnulib module xsize
+
+libgnu_a_SOURCES += xsize.h xsize.c
+
+## end gnulib module xsize
+
+
+mostlyclean-local: mostlyclean-generic
+ @for dir in '' $(MOSTLYCLEANDIRS); do \
+ if test -n "$$dir" && test -d $$dir; then \
+ echo "rmdir $$dir"; rmdir $$dir; \
+ fi; \
+ done; \
+ :
diff --git a/src/gnulib/attribute.h b/src/gnulib/attribute.h
new file mode 100644
index 0000000..8224527
--- /dev/null
+++ b/src/gnulib/attribute.h
@@ -0,0 +1,218 @@
+/* ATTRIBUTE_* macros for using attributes in GCC and similar compilers
+
+ Copyright 2020-2021 Free Software Foundation, Inc.
+
+ 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; either version 3 of the License, 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 for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Paul Eggert. */
+
+/* Provide public ATTRIBUTE_* names for the private _GL_ATTRIBUTE_*
+ macros used within Gnulib. */
+
+/* These attributes can be placed in two ways:
+ - At the start of a declaration (i.e. even before storage-class
+ specifiers!); then they apply to all entities that are declared
+ by the declaration.
+ - Immediately after the name of an entity being declared by the
+ declaration; then they apply to that entity only. */
+
+#ifndef _GL_ATTRIBUTE_H
+#define _GL_ATTRIBUTE_H
+
+
+/* This file defines two types of attributes:
+ * C2X standard attributes. These have macro names that do not begin with
+ 'ATTRIBUTE_'.
+ * Selected GCC attributes; see:
+ https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
+ https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html
+ https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html
+ These names begin with 'ATTRIBUTE_' to avoid name clashes. */
+
+
+/* =============== Attributes for specific kinds of functions =============== */
+
+/* Attributes for functions that should not be used. */
+
+/* Warn if the entity is used. */
+/* Applies to:
+ - function, variable,
+ - struct, union, struct/union member,
+ - enumeration, enumeration item,
+ - typedef,
+ in C++ also: namespace, class, template specialization. */
+#define DEPRECATED _GL_ATTRIBUTE_DEPRECATED
+
+/* If a function call is not optimized way, warn with MSG. */
+/* Applies to: functions. */
+#define ATTRIBUTE_WARNING(msg) _GL_ATTRIBUTE_WARNING (msg)
+
+/* If a function call is not optimized way, report an error with MSG. */
+/* Applies to: functions. */
+#define ATTRIBUTE_ERROR(msg) _GL_ATTRIBUTE_ERROR (msg)
+
+
+/* Attributes for memory-allocating functions. */
+
+/* The function returns a pointer to freshly allocated memory. */
+/* Applies to: functions. */
+#define ATTRIBUTE_MALLOC _GL_ATTRIBUTE_MALLOC
+
+/* ATTRIBUTE_ALLOC_SIZE ((N)) - The Nth argument of the function
+ is the size of the returned memory block.
+ ATTRIBUTE_ALLOC_SIZE ((M, N)) - Multiply the Mth and Nth arguments
+ to determine the size of the returned memory block. */
+/* Applies to: function, pointer to function, function types. */
+#define ATTRIBUTE_ALLOC_SIZE(args) _GL_ATTRIBUTE_ALLOC_SIZE (args)
+
+
+/* Attributes for variadic functions. */
+
+/* The variadic function expects a trailing NULL argument.
+ ATTRIBUTE_SENTINEL () - The last argument is NULL (requires C99).
+ ATTRIBUTE_SENTINEL ((N)) - The (N+1)st argument from the end is NULL. */
+/* Applies to: functions. */
+#define ATTRIBUTE_SENTINEL(pos) _GL_ATTRIBUTE_SENTINEL (pos)
+
+
+/* ================== Attributes for compiler diagnostics ================== */
+
+/* Attributes that help the compiler diagnose programmer mistakes.
+ Some of them may also help for some compiler optimizations. */
+
+/* ATTRIBUTE_FORMAT ((ARCHETYPE, STRING-INDEX, FIRST-TO-CHECK)) -
+ The STRING-INDEXth function argument is a format string of style
+ ARCHETYPE, which is one of:
+ printf, gnu_printf
+ scanf, gnu_scanf,
+ strftime, gnu_strftime,
+ strfmon,
+ or the same thing prefixed and suffixed with '__'.
+ If FIRST-TO-CHECK is not 0, arguments starting at FIRST-TO_CHECK
+ are suitable for the format string. */
+/* Applies to: functions. */
+#define ATTRIBUTE_FORMAT(spec) _GL_ATTRIBUTE_FORMAT (spec)
+
+/* ATTRIBUTE_NONNULL ((N1, N2,...)) - Arguments N1, N2,... must not be NULL.
+ ATTRIBUTE_NONNULL () - All pointer arguments must not be null. */
+/* Applies to: functions. */
+#define ATTRIBUTE_NONNULL(args) _GL_ATTRIBUTE_NONNULL (args)
+
+/* The function's return value is a non-NULL pointer. */
+/* Applies to: functions. */
+#define ATTRIBUTE_RETURNS_NONNULL _GL_ATTRIBUTE_RETURNS_NONNULL
+
+/* Warn if the caller does not use the return value,
+ unless the caller uses something like ignore_value. */
+/* Applies to: function, enumeration, class. */
+#define NODISCARD _GL_ATTRIBUTE_NODISCARD
+
+
+/* Attributes that disable false alarms when the compiler diagnoses
+ programmer "mistakes". */
+
+/* Do not warn if the entity is not used. */
+/* Applies to:
+ - function, variable,
+ - struct, union, struct/union member,
+ - enumeration, enumeration item,
+ - typedef,
+ in C++ also: class. */
+#define MAYBE_UNUSED _GL_ATTRIBUTE_MAYBE_UNUSED
+
+/* The contents of a character array is not meant to be NUL-terminated. */
+/* Applies to: struct/union members and variables that are arrays of element
+ type '[[un]signed] char'. */
+#define ATTRIBUTE_NONSTRING _GL_ATTRIBUTE_NONSTRING
+
+/* Do not warn if control flow falls through to the immediately
+ following 'case' or 'default' label. */
+/* Applies to: Empty statement (;), inside a 'switch' statement. */
+#define FALLTHROUGH _GL_ATTRIBUTE_FALLTHROUGH
+
+
+/* ================== Attributes for debugging information ================== */
+
+/* Attributes regarding debugging information emitted by the compiler. */
+
+/* Omit the function from stack traces when debugging. */
+/* Applies to: function. */
+#define ATTRIBUTE_ARTIFICIAL _GL_ATTRIBUTE_ARTIFICIAL
+
+/* Make the entity visible to debuggers etc., even with '-fwhole-program'. */
+/* Applies to: functions, variables. */
+#define ATTRIBUTE_EXTERNALLY_VISIBLE _GL_ATTRIBUTE_EXTERNALLY_VISIBLE
+
+
+/* ========== Attributes that mainly direct compiler optimizations ========== */
+
+/* The function does not throw exceptions. */
+/* Applies to: functions. */
+#define ATTRIBUTE_NOTHROW _GL_ATTRIBUTE_NOTHROW
+
+/* Do not inline the function. */
+/* Applies to: functions. */
+#define ATTRIBUTE_NOINLINE _GL_ATTRIBUTE_NOINLINE
+
+/* Always inline the function, and report an error if the compiler
+ cannot inline. */
+/* Applies to: function. */
+#define ATTRIBUTE_ALWAYS_INLINE _GL_ATTRIBUTE_ALWAYS_INLINE
+
+/* It is OK for a compiler to omit duplicate calls with the same arguments.
+ This attribute is safe for a function that neither depends on
+ nor affects observable state, and always returns exactly once -
+ e.g., does not loop forever, and does not call longjmp.
+ (This attribute is stricter than ATTRIBUTE_PURE.) */
+/* Applies to: functions. */
+#define ATTRIBUTE_CONST _GL_ATTRIBUTE_CONST
+
+/* It is OK for a compiler to omit duplicate calls with the same
+ arguments if observable state is not changed between calls.
+ This attribute is safe for a function that does not affect
+ observable state, and always returns exactly once.
+ (This attribute is looser than ATTRIBUTE_CONST.) */
+/* Applies to: functions. */
+#define ATTRIBUTE_PURE _GL_ATTRIBUTE_PURE
+
+/* The function is rarely executed. */
+/* Applies to: functions. */
+#define ATTRIBUTE_COLD _GL_ATTRIBUTE_COLD
+
+/* If called from some other compilation unit, the function executes
+ code from that unit only by return or by exception handling,
+ letting the compiler optimize that unit more aggressively. */
+/* Applies to: functions. */
+#define ATTRIBUTE_LEAF _GL_ATTRIBUTE_LEAF
+
+/* For struct members: The member has the smallest possible alignment.
+ For struct, union, class: All members have the smallest possible alignment,
+ minimizing the memory required. */
+/* Applies to: struct members, struct, union,
+ in C++ also: class. */
+#define ATTRIBUTE_PACKED _GL_ATTRIBUTE_PACKED
+
+
+/* ================ Attributes that make invalid code valid ================ */
+
+/* Attributes that prevent fatal compiler optimizations for code that is not
+ fully ISO C compliant. */
+
+/* Pointers to the type may point to the same storage as pointers to
+ other types, thus disabling strict aliasing optimization. */
+/* Applies to: types. */
+#define ATTRIBUTE_MAY_ALIAS _GL_ATTRIBUTE_MAY_ALIAS
+
+
+#endif /* _GL_ATTRIBUTE_H */
diff --git a/src/gnulib/gl_anyhash1.h b/src/gnulib/gl_anyhash1.h
new file mode 100644
index 0000000..3253673
--- /dev/null
+++ b/src/gnulib/gl_anyhash1.h
@@ -0,0 +1,31 @@
+/* Hash table for sequential list, set, and map data type.
+ Copyright (C) 2006, 2009-2021 Free Software Foundation, Inc.
+ Written by Bruno Haible <bruno@clisp.org>, 2006.
+
+ 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; either version 3 of the License, 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 for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Common code of
+ gl_linkedhash_list.c, gl_avltreehash_list.c, gl_rbtreehash_list.c,
+ gl_linkedhash_set.c, gl_hash_set.c,
+ gl_linkedhash_map.c, gl_hash_map.c. */
+
+/* Hash table entry. */
+struct gl_hash_entry
+{
+ struct gl_hash_entry *hash_next; /* chain of entries in same bucket */
+ size_t hashcode; /* cache of the hash code of
+ - the key (for map data type) or
+ - the value (for list, set data types) */
+};
+typedef struct gl_hash_entry * gl_hash_entry_t;
diff --git a/src/gnulib/gl_anyhash2.h b/src/gnulib/gl_anyhash2.h
new file mode 100644
index 0000000..d8b5fb0
--- /dev/null
+++ b/src/gnulib/gl_anyhash2.h
@@ -0,0 +1,82 @@
+/* Hash table for sequential list, set, and map data type.
+ Copyright (C) 2006, 2009-2021 Free Software Foundation, Inc.
+ Written by Bruno Haible <bruno@clisp.org>, 2006.
+
+ 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; either version 3 of the License, 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 for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Common code of
+ gl_linkedhash_list.c, gl_avltreehash_list.c, gl_rbtreehash_list.c,
+ gl_linkedhash_set.c, gl_hash_set.c,
+ gl_linkedhash_map.c, gl_hash_map.c. */
+
+#include "gl_anyhash_primes.h"
+
+/* Resizes the hash table with a new estimated size. */
+static void
+hash_resize (CONTAINER_T container, size_t estimate)
+{
+ size_t new_size = next_prime (estimate);
+
+ if (new_size > container->table_size)
+ {
+ gl_hash_entry_t *old_table = container->table;
+ /* Allocate the new table. */
+ gl_hash_entry_t *new_table;
+ size_t i;
+
+ if (size_overflow_p (xtimes (new_size, sizeof (gl_hash_entry_t))))
+ goto fail;
+ new_table =
+ (gl_hash_entry_t *) calloc (new_size, sizeof (gl_hash_entry_t));
+ if (new_table == NULL)
+ goto fail;
+
+ /* Iterate through the entries of the old table. */
+ for (i = container->table_size; i > 0; )
+ {
+ gl_hash_entry_t node = old_table[--i];
+
+ while (node != NULL)
+ {
+ gl_hash_entry_t next = node->hash_next;
+ /* Add the entry to the new table. */
+ size_t bucket = node->hashcode % new_size;
+ node->hash_next = new_table[bucket];
+ new_table[bucket] = node;
+
+ node = next;
+ }
+ }
+
+ container->table = new_table;
+ container->table_size = new_size;
+ free (old_table);
+ }
+ return;
+
+ fail:
+ /* Just continue without resizing the table. */
+ return;
+}
+
+/* Resizes the hash table if needed, after CONTAINER_COUNT (container) was
+ incremented. */
+static void
+hash_resize_after_add (CONTAINER_T container)
+{
+ size_t count = CONTAINER_COUNT (container);
+ size_t estimate = xsum (count, count / 2); /* 1.5 * count */
+ if (estimate > container->table_size)
+ hash_resize (container, estimate);
+}
diff --git a/src/gnulib/gl_anyhash_primes.h b/src/gnulib/gl_anyhash_primes.h
new file mode 100644
index 0000000..b723e64
--- /dev/null
+++ b/src/gnulib/gl_anyhash_primes.h
@@ -0,0 +1,87 @@
+/* Table of primes, for use by hash tables.
+ Copyright (C) 2006, 2009-2021 Free Software Foundation, Inc.
+ Written by Bruno Haible <bruno@clisp.org>, 2006.
+
+ 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; either version 3 of the License, 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 for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Array of primes, approximately in steps of factor 1.2.
+ This table was computed by executing the Common Lisp expression
+ (dotimes (i 244) (format t "nextprime(~D)~%" (ceiling (expt 1.2d0 i))))
+ and feeding the result to PARI/gp. */
+static const size_t primes[] =
+ {
+ 11, 13, 17, 19, 23, 29, 37, 41, 47, 59, 67, 83, 97, 127, 139, 167, 199,
+ 239, 293, 347, 419, 499, 593, 709, 853, 1021, 1229, 1471, 1777, 2129, 2543,
+ 3049, 3659, 4391, 5273, 6323, 7589, 9103, 10937, 13109, 15727, 18899,
+ 22651, 27179, 32609, 39133, 46957, 56359, 67619, 81157, 97369, 116849,
+ 140221, 168253, 201907, 242309, 290761, 348889, 418667, 502409, 602887,
+ 723467, 868151, 1041779, 1250141, 1500181, 1800191, 2160233, 2592277,
+ 3110741, 3732887, 4479463, 5375371, 6450413, 7740517, 9288589, 11146307,
+ 13375573, 16050689, 19260817, 23112977, 27735583, 33282701, 39939233,
+ 47927081, 57512503, 69014987, 82818011, 99381577, 119257891, 143109469,
+ 171731387, 206077643, 247293161, 296751781, 356102141, 427322587,
+ 512787097, 615344489, 738413383, 886096061, 1063315271, 1275978331,
+ 1531174013, 1837408799, 2204890543UL, 2645868653UL, 3175042391UL,
+ 3810050851UL,
+#if SIZE_MAX > 4294967295UL
+ 4572061027UL, 5486473229UL, 6583767889UL, 7900521449UL, 9480625733UL,
+ 11376750877UL, 13652101063UL, 16382521261UL, 19659025513UL, 23590830631UL,
+ 28308996763UL, 33970796089UL, 40764955463UL, 48917946377UL, 58701535657UL,
+ 70441842749UL, 84530211301UL, 101436253561UL, 121723504277UL,
+ 146068205131UL, 175281846149UL, 210338215379UL, 252405858521UL,
+ 302887030151UL, 363464436191UL, 436157323417UL, 523388788231UL,
+ 628066545713UL, 753679854847UL, 904415825857UL, 1085298991109UL,
+ 1302358789181UL, 1562830547009UL, 1875396656429UL, 2250475987709UL,
+ 2700571185239UL, 3240685422287UL, 3888822506759UL, 4666587008147UL,
+ 5599904409713UL, 6719885291641UL, 8063862349969UL, 9676634819959UL,
+ 11611961783951UL, 13934354140769UL, 16721224968907UL, 20065469962669UL,
+ 24078563955191UL, 28894276746229UL, 34673132095507UL, 41607758514593UL,
+ 49929310217531UL, 59915172260971UL, 71898206713183UL, 86277848055823UL,
+ 103533417666967UL, 124240101200359UL, 149088121440451UL, 178905745728529UL,
+ 214686894874223UL, 257624273849081UL, 309149128618903UL, 370978954342639UL,
+ 445174745211143UL, 534209694253381UL, 641051633104063UL, 769261959724877UL,
+ 923114351670013UL, 1107737222003791UL, 1329284666404567UL,
+ 1595141599685509UL, 1914169919622551UL, 2297003903547091UL,
+ 2756404684256459UL, 3307685621107757UL, 3969222745329323UL,
+ 4763067294395177UL, 5715680753274209UL, 6858816903929113UL,
+ 8230580284714831UL, 9876696341657791UL, 11852035609989371UL,
+ 14222442731987227UL, 17066931278384657UL, 20480317534061597UL,
+ 24576381040873903UL, 29491657249048679UL, 35389988698858471UL,
+ 42467986438630267UL, 50961583726356109UL, 61153900471627387UL,
+ 73384680565952851UL, 88061616679143347UL, 105673940014972061UL,
+ 126808728017966413UL, 152170473621559703UL, 182604568345871671UL,
+ 219125482015045997UL, 262950578418055169UL, 315540694101666193UL,
+ 378648832921999397UL, 454378599506399233UL, 545254319407679131UL,
+ 654305183289214771UL, 785166219947057701UL, 942199463936469157UL,
+ 1130639356723763129UL, 1356767228068515623UL, 1628120673682218619UL,
+ 1953744808418662409UL, 2344493770102394881UL, 2813392524122873857UL,
+ 3376071028947448339UL, 4051285234736937517UL, 4861542281684325481UL,
+ 5833850738021191727UL, 7000620885625427969UL, 8400745062750513217UL,
+ 10080894075300616261UL, 12097072890360739951UL, 14516487468432885797UL,
+ 17419784962119465179UL,
+#endif
+ SIZE_MAX /* sentinel, to ensure the search terminates */
+ };
+
+/* Returns a suitable prime >= ESTIMATE. */
+static size_t
+next_prime (size_t estimate)
+{
+ size_t i;
+
+ for (i = 0; i < sizeof (primes) / sizeof (primes[0]); i++)
+ if (primes[i] >= estimate)
+ return primes[i];
+ return SIZE_MAX; /* not a prime, but better than nothing */
+}
diff --git a/src/gnulib/gl_linkedhash_map.c b/src/gnulib/gl_linkedhash_map.c
new file mode 100644
index 0000000..e2cf9fb
--- /dev/null
+++ b/src/gnulib/gl_linkedhash_map.c
@@ -0,0 +1,330 @@
+/* Map data type implemented by a hash table with a linked list.
+ Copyright (C) 2006, 2008-2021 Free Software Foundation, Inc.
+ Written by Bruno Haible <bruno@clisp.org>, 2018.
+
+ 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; either version 3 of the License, 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 for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+/* Specification. */
+#include "gl_linkedhash_map.h"
+
+#include <stdint.h> /* for uintptr_t, SIZE_MAX */
+#include <stdlib.h>
+
+#include "xsize.h"
+
+/* --------------------------- gl_map_t Data Type --------------------------- */
+
+#include "gl_anyhash1.h"
+
+/* Concrete list node implementation, valid for this file only. */
+struct gl_list_node_impl
+{
+ struct gl_hash_entry h; /* hash table entry fields; must be first */
+ struct gl_list_node_impl *next;
+ struct gl_list_node_impl *prev;
+ const void *key;
+ const void *value;
+};
+typedef struct gl_list_node_impl * gl_list_node_t;
+
+/* Concrete gl_map_impl type, valid for this file only. */
+struct gl_map_impl
+{
+ struct gl_map_impl_base base;
+ gl_mapkey_hashcode_fn hashcode_fn;
+ /* A hash table: managed as an array of collision lists. */
+ struct gl_hash_entry **table;
+ size_t table_size;
+ /* A circular list anchored at root.
+ The first node is = root.next, the last node is = root.prev.
+ The root's value is unused. */
+ struct gl_list_node_impl root;
+ /* Number of list nodes, excluding the root. */
+ size_t count;
+};
+
+#define CONTAINER_T gl_map_t
+#define CONTAINER_COUNT(map) (map)->count
+#include "gl_anyhash2.h"
+
+/* If the symbol SIGNAL_SAFE_MAP is defined, the code is compiled in such
+ a way that a gl_map_t data structure may be used from within a signal
+ handler. The operations allowed in the signal handler are:
+ gl_map_iterator, gl_map_iterator_next, gl_map_iterator_free.
+ The map and node fields that are therefore accessed from the signal handler
+ are:
+ map->root, node->next, node->value.
+ We are careful to make modifications to these fields only in an order
+ that maintains the consistency of the list data structure at any moment,
+ and we use 'volatile' assignments to prevent the compiler from reordering
+ such assignments. */
+#ifdef SIGNAL_SAFE_MAP
+# define ASYNCSAFE(type) *(type volatile *)&
+#else
+# define ASYNCSAFE(type)
+#endif
+
+/* --------------------------- gl_map_t Data Type --------------------------- */
+
+static gl_map_t
+gl_linkedhash_nx_create_empty (gl_map_implementation_t implementation,
+ gl_mapkey_equals_fn equals_fn,
+ gl_mapkey_hashcode_fn hashcode_fn,
+ gl_mapkey_dispose_fn kdispose_fn,
+ gl_mapvalue_dispose_fn vdispose_fn)
+{
+ struct gl_map_impl *map =
+ (struct gl_map_impl *) malloc (sizeof (struct gl_map_impl));
+
+ if (map == NULL)
+ return NULL;
+
+ map->base.vtable = implementation;
+ map->base.equals_fn = equals_fn;
+ map->base.kdispose_fn = kdispose_fn;
+ map->base.vdispose_fn = vdispose_fn;
+ map->hashcode_fn = hashcode_fn;
+ map->table_size = 11;
+ map->table =
+ (gl_hash_entry_t *) calloc (map->table_size, sizeof (gl_hash_entry_t));
+ if (map->table == NULL)
+ goto fail;
+ map->root.next = &map->root;
+ map->root.prev = &map->root;
+ map->count = 0;
+
+ return map;
+
+ fail:
+ free (map);
+ return NULL;
+}
+
+static size_t _GL_ATTRIBUTE_PURE
+gl_linkedhash_size (gl_map_t map)
+{
+ return map->count;
+}
+
+static bool _GL_ATTRIBUTE_PURE
+gl_linkedhash_search (gl_map_t map, const void *key, const void **valuep)
+{
+ size_t hashcode =
+ (map->hashcode_fn != NULL
+ ? map->hashcode_fn (key)
+ : (size_t)(uintptr_t) key);
+ size_t bucket = hashcode % map->table_size;
+ gl_mapkey_equals_fn equals = map->base.equals_fn;
+
+ /* Look for a match in the hash bucket. */
+ gl_list_node_t node;
+
+ for (node = (gl_list_node_t) map->table[bucket];
+ node != NULL;
+ node = (gl_list_node_t) node->h.hash_next)
+ if (node->h.hashcode == hashcode
+ && (equals != NULL
+ ? equals (key, node->key)
+ : key == node->key))
+ {
+ *valuep = node->value;
+ return true;
+ }
+ return false;
+}
+
+static int
+gl_linkedhash_nx_getput (gl_map_t map, const void *key, const void *value,
+ const void **oldvaluep)
+{
+ size_t hashcode =
+ (map->hashcode_fn != NULL
+ ? map->hashcode_fn (key)
+ : (size_t)(uintptr_t) key);
+ size_t bucket = hashcode % map->table_size;
+ gl_mapkey_equals_fn equals = map->base.equals_fn;
+
+ /* Look for a match in the hash bucket. */
+ {
+ gl_list_node_t node;
+
+ for (node = (gl_list_node_t) map->table[bucket];
+ node != NULL;
+ node = (gl_list_node_t) node->h.hash_next)
+ if (node->h.hashcode == hashcode
+ && (equals != NULL
+ ? equals (key, node->key)
+ : key == node->key))
+ {
+ *oldvaluep = node->value;
+ node->value = value;
+ return 0;
+ }
+ }
+
+ /* Allocate a new node. */
+ gl_list_node_t node =
+ (struct gl_list_node_impl *) malloc (sizeof (struct gl_list_node_impl));
+
+ if (node == NULL)
+ return -1;
+
+ ASYNCSAFE(const void *) node->key = key;
+ ASYNCSAFE(const void *) node->value = value;
+ node->h.hashcode = hashcode;
+
+ /* Add node to the hash table. */
+ node->h.hash_next = map->table[bucket];
+ map->table[bucket] = &node->h;
+
+ /* Add node to the map. */
+ ASYNCSAFE(gl_list_node_t) node->next = &map->root;
+ node->prev = map->root.prev;
+ ASYNCSAFE(gl_list_node_t) node->prev->next = node;
+ map->root.prev = node;
+ map->count++;
+
+ hash_resize_after_add (map);
+
+ return 1;
+}
+
+static bool
+gl_linkedhash_getremove (gl_map_t map, const void *key, const void **oldvaluep)
+{
+ size_t hashcode =
+ (map->hashcode_fn != NULL
+ ? map->hashcode_fn (key)
+ : (size_t)(uintptr_t) key);
+ size_t bucket = hashcode % map->table_size;
+ gl_mapkey_equals_fn equals = map->base.equals_fn;
+
+ /* Look for the first match in the hash bucket. */
+ gl_list_node_t *nodep;
+
+ for (nodep = (gl_list_node_t *) &map->table[bucket];
+ *nodep != NULL;
+ nodep = (gl_list_node_t *) &(*nodep)->h.hash_next)
+ {
+ gl_list_node_t node = *nodep;
+ if (node->h.hashcode == hashcode
+ && (equals != NULL
+ ? equals (key, node->key)
+ : key == node->key))
+ {
+ *oldvaluep = node->value;
+
+ /* Remove node from the hash table. */
+ *nodep = (gl_list_node_t) node->h.hash_next;
+
+ /* Remove node from the list. */
+ {
+ gl_list_node_t prev = node->prev;
+ gl_list_node_t next = node->next;
+
+ ASYNCSAFE(gl_list_node_t) prev->next = next;
+ next->prev = prev;
+ }
+ map->count--;
+
+ if (map->base.kdispose_fn != NULL)
+ map->base.kdispose_fn (node->key);
+ free (node);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static void
+gl_linkedhash_free (gl_map_t map)
+{
+ gl_mapkey_dispose_fn kdispose = map->base.kdispose_fn;
+ gl_mapvalue_dispose_fn vdispose = map->base.vdispose_fn;
+ gl_list_node_t node;
+
+ for (node = map->root.next; node != &map->root; )
+ {
+ gl_list_node_t next = node->next;
+ if (vdispose != NULL)
+ vdispose (node->value);
+ if (kdispose != NULL)
+ kdispose (node->key);
+ free (node);
+ node = next;
+ }
+ free (map->table);
+ free (map);
+}
+
+/* ---------------------- gl_map_iterator_t Data Type ---------------------- */
+
+/* Iterate through the list, not through the hash buckets, so that the order
+ in which the pairs are returned is predictable. */
+
+static gl_map_iterator_t
+gl_linkedhash_iterator (gl_map_t map)
+{
+ gl_map_iterator_t result;
+
+ result.vtable = map->base.vtable;
+ result.map = map;
+ result.p = map->root.next;
+ result.q = &map->root;
+#if defined GCC_LINT || defined lint
+ result.i = 0;
+ result.j = 0;
+ result.count = 0;
+#endif
+
+ return result;
+}
+
+static bool
+gl_linkedhash_iterator_next (gl_map_iterator_t *iterator,
+ const void **keyp, const void **valuep)
+{
+ if (iterator->p != iterator->q)
+ {
+ gl_list_node_t node = (gl_list_node_t) iterator->p;
+ *keyp = node->key;
+ *valuep = node->value;
+ iterator->p = node->next;
+ return true;
+ }
+ else
+ return false;
+}
+
+static void
+gl_linkedhash_iterator_free (gl_map_iterator_t *iterator)
+{
+}
+
+
+const struct gl_map_implementation gl_linkedhash_map_implementation =
+ {
+ gl_linkedhash_nx_create_empty,
+ gl_linkedhash_size,
+ gl_linkedhash_search,
+ gl_linkedhash_nx_getput,
+ gl_linkedhash_getremove,
+ gl_linkedhash_free,
+ gl_linkedhash_iterator,
+ gl_linkedhash_iterator_next,
+ gl_linkedhash_iterator_free
+ };
diff --git a/src/gnulib/gl_linkedhash_map.h b/src/gnulib/gl_linkedhash_map.h
new file mode 100644
index 0000000..56c2f3d
--- /dev/null
+++ b/src/gnulib/gl_linkedhash_map.h
@@ -0,0 +1,34 @@
+/* Map data type implemented by a hash table with a linked list.
+ Copyright (C) 2006, 2009-2021 Free Software Foundation, Inc.
+ Written by Bruno Haible <bruno@clisp.org>, 2018.
+
+ 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; either version 3 of the License, 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 for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+#ifndef _GL_LINKEDHASH_MAP_H
+#define _GL_LINKEDHASH_MAP_H
+
+#include "gl_map.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const struct gl_map_implementation gl_linkedhash_map_implementation;
+#define GL_LINKEDHASH_MAP &gl_linkedhash_map_implementation
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GL_LINKEDHASH_MAP_H */
diff --git a/src/gnulib/gl_map.c b/src/gnulib/gl_map.c
new file mode 100644
index 0000000..758a65f
--- /dev/null
+++ b/src/gnulib/gl_map.c
@@ -0,0 +1,3 @@
+#include <config.h>
+#define GL_MAP_INLINE _GL_EXTERN_INLINE
+#include "gl_map.h"
diff --git a/src/gnulib/gl_map.h b/src/gnulib/gl_map.h
new file mode 100644
index 0000000..051ec59
--- /dev/null
+++ b/src/gnulib/gl_map.h
@@ -0,0 +1,370 @@
+/* Abstract map data type.
+ Copyright (C) 2006-2007, 2009-2021 Free Software Foundation, Inc.
+ Written by Bruno Haible <bruno@clisp.org>, 2018.
+
+ 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; either version 3 of the License, 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 for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+#ifndef _GL_MAP_H
+#define _GL_MAP_H
+
+#include <stdbool.h>
+#include <stddef.h>
+
+#ifndef _GL_INLINE_HEADER_BEGIN
+ #error "Please include config.h first."
+#endif
+_GL_INLINE_HEADER_BEGIN
+#ifndef GL_MAP_INLINE
+# define GL_MAP_INLINE _GL_INLINE
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* gl_map is an abstract map data type. It can contain any number of
+ (key, value) pairs, where
+ - keys and values are objects ('void *' or 'const void *' pointers),
+ - There are no (key, value1) and (key, value2) pairs with the same key
+ (in the sense of a given comparator function).
+
+ There are several implementations of this map datatype, optimized for
+ different operations or for memory. You can start using the simplest map
+ implementation, GL_ARRAY_MAP, and switch to a different implementation
+ later, when you realize which operations are performed the most frequently.
+ The API of the different implementations is exactly the same; when switching
+ to a different implementation, you only have to change the gl_map_create
+ call.
+
+ The implementations are:
+ GL_ARRAY_MAP a growable array
+ GL_LINKEDHASH_MAP a hash table with a linked list
+ GL_HASH_MAP a hash table
+
+ The memory consumption is asymptotically the same: O(1) for every pair
+ in the map. When looking more closely at the average memory consumed
+ for an object, GL_ARRAY_MAP is the most compact representation, then comes
+ GL_HASH_MAP, and GL_LINKEDHASH_MAP needs the most memory.
+
+ The guaranteed average performance of the operations is, for a map of
+ n pairs:
+
+ Operation ARRAY LINKEDHASH
+ HASH
+
+ gl_map_size O(1) O(1)
+ gl_map_get O(n) O(1)
+ gl_map_put O(n) O(1)
+ gl_map_remove O(n) O(1)
+ gl_map_search O(n) O(1)
+ gl_map_iterator O(1) O(1)
+ gl_map_iterator_next O(1) O(1)
+ */
+
+/* --------------------------- gl_map_t Data Type --------------------------- */
+
+/* Type of function used to compare two keys.
+ NULL denotes pointer comparison. */
+typedef bool (*gl_mapkey_equals_fn) (const void *key1, const void *key2);
+
+/* Type of function used to compute a hash code.
+ NULL denotes a function that depends only on the pointer itself. */
+typedef size_t (*gl_mapkey_hashcode_fn) (const void *key);
+
+#ifndef _GL_MAP_DISPOSE_FNS_DEFINED
+
+/* Type of function used to dispose a key once a (key, value) pair is removed
+ from a map. NULL denotes a no-op. */
+typedef void (*gl_mapkey_dispose_fn) (const void *key);
+
+/* Type of function used to dispose a value once a (key, value) pair is removed
+ from a map. NULL denotes a no-op. */
+typedef void (*gl_mapvalue_dispose_fn) (const void *value);
+
+# define _GL_MAP_DISPOSE_FNS_DEFINED 1
+#endif
+
+struct gl_map_impl;
+/* Type representing an entire map. */
+typedef struct gl_map_impl * gl_map_t;
+
+struct gl_map_implementation;
+/* Type representing a map datatype implementation. */
+typedef const struct gl_map_implementation * gl_map_implementation_t;
+
+#if 0 /* Unless otherwise specified, these are defined inline below. */
+
+/* Creates an empty map.
+ IMPLEMENTATION is one of GL_ARRAY_MAP, GL_LINKEDHASH_MAP, GL_HASH_MAP.
+ EQUALS_FN is a key comparison function or NULL.
+ HASHCODE_FN is a key hash code function or NULL.
+ KDISPOSE_FN is a key disposal function or NULL.
+ VDISPOSE_FN is a value disposal function or NULL. */
+/* declared in gl_xmap.h */
+extern gl_map_t gl_map_create_empty (gl_map_implementation_t implementation,
+ gl_mapkey_equals_fn equals_fn,
+ gl_mapkey_hashcode_fn hashcode_fn,
+ gl_mapkey_dispose_fn kdispose_fn,
+ gl_mapvalue_dispose_fn vdispose_fn);
+/* Likewise. Returns NULL upon out-of-memory. */
+extern gl_map_t gl_map_nx_create_empty (gl_map_implementation_t implementation,
+ gl_mapkey_equals_fn equals_fn,
+ gl_mapkey_hashcode_fn hashcode_fn,
+ gl_mapkey_dispose_fn kdispose_fn,
+ gl_mapvalue_dispose_fn vdispose_fn);
+
+/* Returns the current number of pairs in a map. */
+extern size_t gl_map_size (gl_map_t map);
+
+/* Searches whether a pair with the given key is already in the map.
+ Returns the value if found, or NULL if not present in the map. */
+extern const void * gl_map_get (gl_map_t map, const void *key);
+
+/* Searches whether a pair with the given key is already in the map.
+ Returns true and sets *VALUEP to the value if found.
+ Returns false if not present in the map. */
+extern bool gl_map_search (gl_map_t map, const void *key, const void **valuep);
+
+/* Adds a pair to a map.
+ Returns true if a pair with the given key was not already in the map and so
+ this pair was added.
+ Returns false if a pair with the given key was already in the map and only
+ its value was replaced. */
+/* declared in gl_xmap.h */
+extern bool gl_map_put (gl_map_t map, const void *key, const void *value);
+/* Likewise. Returns -1 upon out-of-memory. */
+extern int gl_map_nx_put (gl_map_t map, const void *key, const void *value)
+ _GL_ATTRIBUTE_NODISCARD;
+
+/* Adds a pair to a map and retrieves the previous value.
+ Returns true if a pair with the given key was not already in the map and so
+ this pair was added.
+ Returns false and sets *OLDVALUEP to the previous value, if a pair with the
+ given key was already in the map and only its value was replaced. */
+/* declared in gl_xmap.h */
+extern bool gl_map_getput (gl_map_t map, const void *key, const void *value,
+ const void **oldvaluep);
+/* Likewise. Returns -1 upon out-of-memory. */
+extern int gl_map_nx_getput (gl_map_t map, const void *key, const void *value,
+ const void **oldvaluep)
+ _GL_ATTRIBUTE_NODISCARD;
+
+/* Removes a pair from a map.
+ Returns true if the key was found and its pair removed.
+ Returns false otherwise. */
+extern bool gl_map_remove (gl_map_t map, const void *key);
+
+/* Removes a pair from a map and retrieves the previous value.
+ Returns true and sets *OLDVALUEP to the previous value, if the key was found
+ and its pair removed.
+ Returns false otherwise. */
+extern bool gl_map_getremove (gl_map_t map, const void *key,
+ const void **oldvaluep);
+
+/* Frees an entire map.
+ (But this call does not free the keys and values of the pairs in the map.
+ It only invokes the KDISPOSE_FN on each key and the VDISPOSE_FN on each value
+ of the pairs in the map.) */
+extern void gl_map_free (gl_map_t map);
+
+#endif /* End of inline and gl_xmap.h-defined functions. */
+
+/* ---------------------- gl_map_iterator_t Data Type ---------------------- */
+
+/* Functions for iterating through a map.
+ Note: Iterating through a map of type GL_HASH_MAP returns the pairs in an
+ unpredictable order. If you need a predictable order, use GL_LINKEDHASH_MAP
+ instead of GL_HASH_MAP. */
+
+/* Type of an iterator that traverses a map.
+ This is a fixed-size struct, so that creation of an iterator doesn't need
+ memory allocation on the heap. */
+typedef struct
+{
+ /* For fast dispatch of gl_map_iterator_next. */
+ const struct gl_map_implementation *vtable;
+ /* For detecting whether the last returned pair was removed. */
+ gl_map_t map;
+ size_t count;
+ /* Other, implementation-private fields. */
+ void *p; void *q;
+ size_t i; size_t j;
+} gl_map_iterator_t;
+
+#if 0 /* These are defined inline below. */
+
+/* Creates an iterator traversing a map.
+ The map's contents must not be modified while the iterator is in use,
+ except for modifying the value of the last returned key or removing the
+ last returned pair. */
+extern gl_map_iterator_t gl_map_iterator (gl_map_t map);
+
+/* If there is a next pair, stores the next pair in *KEYP and *VALUEP, advances
+ the iterator, and returns true. Otherwise, returns false. */
+extern bool gl_map_iterator_next (gl_map_iterator_t *iterator,
+ const void **keyp, const void **valuep);
+
+/* Frees an iterator. */
+extern void gl_map_iterator_free (gl_map_iterator_t *iterator);
+
+#endif /* End of inline functions. */
+
+/* ------------------------- Implementation Details ------------------------- */
+
+struct gl_map_implementation
+{
+ /* gl_map_t functions. */
+ gl_map_t (*nx_create_empty) (gl_map_implementation_t implementation,
+ gl_mapkey_equals_fn equals_fn,
+ gl_mapkey_hashcode_fn hashcode_fn,
+ gl_mapkey_dispose_fn kdispose_fn,
+ gl_mapvalue_dispose_fn vdispose_fn);
+ size_t (*size) (gl_map_t map);
+ bool (*search) (gl_map_t map, const void *key, const void **valuep);
+ int (*nx_getput) (gl_map_t map, const void *key, const void *value,
+ const void **oldvaluep);
+ bool (*getremove) (gl_map_t map, const void *key, const void **oldvaluep);
+ void (*map_free) (gl_map_t map);
+ /* gl_map_iterator_t functions. */
+ gl_map_iterator_t (*iterator) (gl_map_t map);
+ bool (*iterator_next) (gl_map_iterator_t *iterator,
+ const void **keyp, const void **valuep);
+ void (*iterator_free) (gl_map_iterator_t *iterator);
+};
+
+struct gl_map_impl_base
+{
+ const struct gl_map_implementation *vtable;
+ gl_mapkey_equals_fn equals_fn;
+ gl_mapkey_dispose_fn kdispose_fn;
+ gl_mapvalue_dispose_fn vdispose_fn;
+};
+
+/* Define most functions of this file as accesses to the
+ struct gl_map_implementation. */
+
+GL_MAP_INLINE gl_map_t
+gl_map_nx_create_empty (gl_map_implementation_t implementation,
+ gl_mapkey_equals_fn equals_fn,
+ gl_mapkey_hashcode_fn hashcode_fn,
+ gl_mapkey_dispose_fn kdispose_fn,
+ gl_mapvalue_dispose_fn vdispose_fn)
+{
+ return implementation->nx_create_empty (implementation,
+ equals_fn, hashcode_fn,
+ kdispose_fn, vdispose_fn);
+}
+
+GL_MAP_INLINE size_t
+gl_map_size (gl_map_t map)
+{
+ return ((const struct gl_map_impl_base *) map)->vtable->size (map);
+}
+
+GL_MAP_INLINE bool
+gl_map_search (gl_map_t map, const void *key, const void **valuep)
+{
+ return ((const struct gl_map_impl_base *) map)->vtable
+ ->search (map, key, valuep);
+}
+
+GL_MAP_INLINE _GL_ATTRIBUTE_NODISCARD int
+gl_map_nx_getput (gl_map_t map, const void *key, const void *value,
+ const void **oldvaluep)
+{
+ return ((const struct gl_map_impl_base *) map)->vtable
+ ->nx_getput (map, key, value, oldvaluep);
+}
+
+GL_MAP_INLINE bool
+gl_map_getremove (gl_map_t map, const void *key, const void **oldvaluep)
+{
+ return ((const struct gl_map_impl_base *) map)->vtable
+ ->getremove (map, key, oldvaluep);
+}
+
+GL_MAP_INLINE void
+gl_map_free (gl_map_t map)
+{
+ ((const struct gl_map_impl_base *) map)->vtable->map_free (map);
+}
+
+GL_MAP_INLINE gl_map_iterator_t
+gl_map_iterator (gl_map_t map)
+{
+ return ((const struct gl_map_impl_base *) map)->vtable->iterator (map);
+}
+
+GL_MAP_INLINE bool
+gl_map_iterator_next (gl_map_iterator_t *iterator,
+ const void **keyp, const void **valuep)
+{
+ return iterator->vtable->iterator_next (iterator, keyp, valuep);
+}
+
+GL_MAP_INLINE void
+gl_map_iterator_free (gl_map_iterator_t *iterator)
+{
+ iterator->vtable->iterator_free (iterator);
+}
+
+/* Define the convenience functions, that is, the functions that are independent
+ of the implementation. */
+
+GL_MAP_INLINE const void *
+gl_map_get (gl_map_t map, const void *key)
+{
+ const void *value = NULL;
+ gl_map_search (map, key, &value);
+ return value;
+}
+
+GL_MAP_INLINE _GL_ATTRIBUTE_NODISCARD int
+gl_map_nx_put (gl_map_t map, const void *key, const void *value)
+{
+ const void *oldvalue;
+ int result = gl_map_nx_getput (map, key, value, &oldvalue);
+ if (result == 0)
+ {
+ gl_mapvalue_dispose_fn vdispose_fn =
+ ((const struct gl_map_impl_base *) map)->vdispose_fn;
+ if (vdispose_fn != NULL)
+ vdispose_fn (oldvalue);
+ }
+ return result;
+}
+
+GL_MAP_INLINE bool
+gl_map_remove (gl_map_t map, const void *key)
+{
+ const void *oldvalue;
+ bool result = gl_map_getremove (map, key, &oldvalue);
+ if (result)
+ {
+ gl_mapvalue_dispose_fn vdispose_fn =
+ ((const struct gl_map_impl_base *) map)->vdispose_fn;
+ if (vdispose_fn != NULL)
+ vdispose_fn (oldvalue);
+ }
+ return result;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+_GL_INLINE_HEADER_END
+
+#endif /* _GL_MAP_H */
diff --git a/src/gnulib/limits.in.h b/src/gnulib/limits.in.h
new file mode 100644
index 0000000..076ab9e
--- /dev/null
+++ b/src/gnulib/limits.in.h
@@ -0,0 +1,121 @@
+/* A GNU-like <limits.h>.
+
+ Copyright 2016-2021 Free Software Foundation, Inc.
+
+ 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; either 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 for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <https://www.gnu.org/licenses/>. */
+
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+@PRAGMA_COLUMNS@
+
+#if defined _GL_ALREADY_INCLUDING_LIMITS_H
+/* Special invocation convention:
+ On Haiku/x86_64, we have a sequence of nested includes
+ <limits.h> -> <syslimits.h> -> <limits.h>.
+ In this situation, LONG_MAX and INT_MAX are not yet defined,
+ therefore we should not attempt to define LONG_BIT. */
+
+#@INCLUDE_NEXT@ @NEXT_LIMITS_H@
+
+#else
+/* Normal invocation convention. */
+
+#ifndef _@GUARD_PREFIX@_LIMITS_H
+
+# define _GL_ALREADY_INCLUDING_LIMITS_H
+
+/* The include_next requires a split double-inclusion guard. */
+# @INCLUDE_NEXT@ @NEXT_LIMITS_H@
+
+# undef _GL_ALREADY_INCLUDING_LIMITS_H
+
+#ifndef _@GUARD_PREFIX@_LIMITS_H
+#define _@GUARD_PREFIX@_LIMITS_H
+
+#ifndef LLONG_MIN
+# if defined LONG_LONG_MIN /* HP-UX 11.31 */
+# define LLONG_MIN LONG_LONG_MIN
+# elif defined LONGLONG_MIN /* IRIX 6.5 */
+# define LLONG_MIN LONGLONG_MIN
+# elif defined __GNUC__
+# define LLONG_MIN (- __LONG_LONG_MAX__ - 1LL)
+# endif
+#endif
+#ifndef LLONG_MAX
+# if defined LONG_LONG_MAX /* HP-UX 11.31 */
+# define LLONG_MAX LONG_LONG_MAX
+# elif defined LONGLONG_MAX /* IRIX 6.5 */
+# define LLONG_MAX LONGLONG_MAX
+# elif defined __GNUC__
+# define LLONG_MAX __LONG_LONG_MAX__
+# endif
+#endif
+#ifndef ULLONG_MAX
+# if defined ULONG_LONG_MAX /* HP-UX 11.31 */
+# define ULLONG_MAX ULONG_LONG_MAX
+# elif defined ULONGLONG_MAX /* IRIX 6.5 */
+# define ULLONG_MAX ULONGLONG_MAX
+# elif defined __GNUC__
+# define ULLONG_MAX (__LONG_LONG_MAX__ * 2ULL + 1ULL)
+# endif
+#endif
+
+/* The number of usable bits in an unsigned or signed integer type
+ with minimum value MIN and maximum value MAX, as an int expression
+ suitable in #if. Cover all known practical hosts. This
+ implementation exploits the fact that MAX is 1 less than a power of
+ 2, and merely counts the number of 1 bits in MAX; "COBn" means
+ "count the number of 1 bits in the low-order n bits"). */
+#define _GL_INTEGER_WIDTH(min, max) (((min) < 0) + _GL_COB128 (max))
+#define _GL_COB128(n) (_GL_COB64 ((n) >> 31 >> 31 >> 2) + _GL_COB64 (n))
+#define _GL_COB64(n) (_GL_COB32 ((n) >> 31 >> 1) + _GL_COB32 (n))
+#define _GL_COB32(n) (_GL_COB16 ((n) >> 16) + _GL_COB16 (n))
+#define _GL_COB16(n) (_GL_COB8 ((n) >> 8) + _GL_COB8 (n))
+#define _GL_COB8(n) (_GL_COB4 ((n) >> 4) + _GL_COB4 (n))
+#define _GL_COB4(n) (!!((n) & 8) + !!((n) & 4) + !!((n) & 2) + !!((n) & 1))
+
+#ifndef WORD_BIT
+/* Assume 'int' is 32 bits wide. */
+# define WORD_BIT 32
+#endif
+#ifndef LONG_BIT
+/* Assume 'long' is 32 or 64 bits wide. */
+# if LONG_MAX == INT_MAX
+# define LONG_BIT 32
+# else
+# define LONG_BIT 64
+# endif
+#endif
+
+/* Macros specified by ISO/IEC TS 18661-1:2014. */
+
+#if (! defined ULLONG_WIDTH \
+ && (defined _GNU_SOURCE || defined __STDC_WANT_IEC_60559_BFP_EXT__))
+# define CHAR_WIDTH _GL_INTEGER_WIDTH (CHAR_MIN, CHAR_MAX)
+# define SCHAR_WIDTH _GL_INTEGER_WIDTH (SCHAR_MIN, SCHAR_MAX)
+# define UCHAR_WIDTH _GL_INTEGER_WIDTH (0, UCHAR_MAX)
+# define SHRT_WIDTH _GL_INTEGER_WIDTH (SHRT_MIN, SHRT_MAX)
+# define USHRT_WIDTH _GL_INTEGER_WIDTH (0, USHRT_MAX)
+# define INT_WIDTH _GL_INTEGER_WIDTH (INT_MIN, INT_MAX)
+# define UINT_WIDTH _GL_INTEGER_WIDTH (0, UINT_MAX)
+# define LONG_WIDTH _GL_INTEGER_WIDTH (LONG_MIN, LONG_MAX)
+# define ULONG_WIDTH _GL_INTEGER_WIDTH (0, ULONG_MAX)
+# define LLONG_WIDTH _GL_INTEGER_WIDTH (LLONG_MIN, LLONG_MAX)
+# define ULLONG_WIDTH _GL_INTEGER_WIDTH (0, ULLONG_MAX)
+#endif /* !ULLONG_WIDTH && (_GNU_SOURCE || __STDC_WANT_IEC_60559_BFP_EXT__) */
+
+#endif /* _@GUARD_PREFIX@_LIMITS_H */
+#endif /* _@GUARD_PREFIX@_LIMITS_H */
+#endif
diff --git a/src/gnulib/size_max.h b/src/gnulib/size_max.h
new file mode 100644
index 0000000..16cfa09
--- /dev/null
+++ b/src/gnulib/size_max.h
@@ -0,0 +1,30 @@
+/* size_max.h -- declare SIZE_MAX through system headers
+ Copyright (C) 2005-2006, 2009-2021 Free Software Foundation, Inc.
+ Written by Simon Josefsson.
+
+ 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; either 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 for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <https://www.gnu.org/licenses/>. */
+
+#ifndef GNULIB_SIZE_MAX_H
+#define GNULIB_SIZE_MAX_H
+
+/* Get SIZE_MAX declaration on systems like Solaris 7/8/9. */
+# include <limits.h>
+/* Get SIZE_MAX declaration on systems like glibc 2. */
+# if HAVE_STDINT_H
+# include <stdint.h>
+# endif
+/* On systems where these include files don't define it, SIZE_MAX is defined
+ in config.h. */
+
+#endif /* GNULIB_SIZE_MAX_H */
diff --git a/src/gnulib/stdbool.in.h b/src/gnulib/stdbool.in.h
new file mode 100644
index 0000000..28e0a53
--- /dev/null
+++ b/src/gnulib/stdbool.in.h
@@ -0,0 +1,132 @@
+/* Copyright (C) 2001-2003, 2006-2021 Free Software Foundation, Inc.
+ Written by Bruno Haible <haible@clisp.cons.org>, 2001.
+
+ 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; either 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 for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <https://www.gnu.org/licenses/>. */
+
+#ifndef _GL_STDBOOL_H
+#define _GL_STDBOOL_H
+
+/* ISO C 99 <stdbool.h> for platforms that lack it. */
+
+/* Usage suggestions:
+
+ Programs that use <stdbool.h> should be aware of some limitations
+ and standards compliance issues.
+
+ Standards compliance:
+
+ - <stdbool.h> must be #included before 'bool', 'false', 'true'
+ can be used.
+
+ - You cannot assume that sizeof (bool) == 1.
+
+ - Programs should not undefine the macros bool, true, and false,
+ as C99 lists that as an "obsolescent feature".
+
+ Limitations of this substitute, when used in a C89 environment:
+
+ - <stdbool.h> must be #included before the '_Bool' type can be used.
+
+ - You cannot assume that _Bool is a typedef; it might be a macro.
+
+ - Bit-fields of type 'bool' are not supported. Portable code
+ should use 'unsigned int foo : 1;' rather than 'bool foo : 1;'.
+
+ - In C99, casts and automatic conversions to '_Bool' or 'bool' are
+ performed in such a way that every nonzero value gets converted
+ to 'true', and zero gets converted to 'false'. This doesn't work
+ with this substitute. With this substitute, only the values 0 and 1
+ give the expected result when converted to _Bool' or 'bool'.
+
+ - C99 allows the use of (_Bool)0.0 in constant expressions, but
+ this substitute cannot always provide this property.
+
+ Also, it is suggested that programs use 'bool' rather than '_Bool';
+ this isn't required, but 'bool' is more common. */
+
+
+/* 7.16. Boolean type and values */
+
+/* BeOS <sys/socket.h> already #defines false 0, true 1. We use the same
+ definitions below, but temporarily we have to #undef them. */
+#if defined __BEOS__ && !defined __HAIKU__
+# include <OS.h> /* defines bool but not _Bool */
+# undef false
+# undef true
+#endif
+
+#ifdef __cplusplus
+# define _Bool bool
+# define bool bool
+#else
+# if defined __BEOS__ && !defined __HAIKU__
+ /* A compiler known to have 'bool'. */
+ /* If the compiler already has both 'bool' and '_Bool', we can assume they
+ are the same types. */
+# if !@HAVE__BOOL@
+typedef bool _Bool;
+# endif
+# else
+# if !defined __GNUC__
+ /* If @HAVE__BOOL@:
+ Some HP-UX cc and AIX IBM C compiler versions have compiler bugs when
+ the built-in _Bool type is used. See
+ https://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
+ https://lists.gnu.org/r/bug-coreutils/2005-11/msg00161.html
+ https://lists.gnu.org/r/bug-coreutils/2005-10/msg00086.html
+ Similar bugs are likely with other compilers as well; this file
+ wouldn't be used if <stdbool.h> was working.
+ So we override the _Bool type.
+ If !@HAVE__BOOL@:
+ Need to define _Bool ourselves. As 'signed char' or as an enum type?
+ Use of a typedef, with SunPRO C, leads to a stupid
+ "warning: _Bool is a keyword in ISO C99".
+ Use of an enum type, with IRIX cc, leads to a stupid
+ "warning(1185): enumerated type mixed with another type".
+ Even the existence of an enum type, without a typedef,
+ "Invalid enumerator. (badenum)" with HP-UX cc on Tru64.
+ The only benefit of the enum, debuggability, is not important
+ with these compilers. So use 'signed char' and no enum. */
+# define _Bool signed char
+# else
+ /* With this compiler, trust the _Bool type if the compiler has it. */
+# if !@HAVE__BOOL@
+ /* For the sake of symbolic names in gdb, define true and false as
+ enum constants, not only as macros.
+ It is tempting to write
+ typedef enum { false = 0, true = 1 } _Bool;
+ so that gdb prints values of type 'bool' symbolically. But then
+ values of type '_Bool' might promote to 'int' or 'unsigned int'
+ (see ISO C 99 6.7.2.2.(4)); however, '_Bool' must promote to 'int'
+ (see ISO C 99 6.3.1.1.(2)). So add a negative value to the
+ enum; this ensures that '_Bool' promotes to 'int'. */
+typedef enum { _Bool_must_promote_to_int = -1, false = 0, true = 1 } _Bool;
+# endif
+# endif
+# endif
+# define bool _Bool
+#endif
+
+/* The other macros must be usable in preprocessor directives. */
+#ifdef __cplusplus
+# define false false
+# define true true
+#else
+# define false 0
+# define true 1
+#endif
+
+#define __bool_true_false_are_defined 1
+
+#endif /* _GL_STDBOOL_H */
diff --git a/src/gnulib/stdint.in.h b/src/gnulib/stdint.in.h
new file mode 100644
index 0000000..7a8f27c
--- /dev/null
+++ b/src/gnulib/stdint.in.h
@@ -0,0 +1,740 @@
+/* Copyright (C) 2001-2002, 2004-2021 Free Software Foundation, Inc.
+ Written by Paul Eggert, Bruno Haible, Sam Steingold, Peter Burwood.
+ This file is part of gnulib.
+
+ 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; either 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 for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <https://www.gnu.org/licenses/>. */
+
+/*
+ * ISO C 99 <stdint.h> for platforms that lack it.
+ * <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stdint.h.html>
+ */
+
+#ifndef _@GUARD_PREFIX@_STDINT_H
+
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+@PRAGMA_COLUMNS@
+
+/* When including a system file that in turn includes <inttypes.h>,
+ use the system <inttypes.h>, not our substitute. This avoids
+ problems with (for example) VMS, whose <sys/bitypes.h> includes
+ <inttypes.h>. */
+#define _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H
+
+/* On Android (Bionic libc), <sys/types.h> includes this file before
+ having defined 'time_t'. Therefore in this case avoid including
+ other system header files; just include the system's <stdint.h>.
+ Ideally we should test __BIONIC__ here, but it is only defined after
+ <sys/cdefs.h> has been included; hence test __ANDROID__ instead. */
+#if defined __ANDROID__ && defined _GL_INCLUDING_SYS_TYPES_H
+# @INCLUDE_NEXT@ @NEXT_STDINT_H@
+#else
+
+/* Get those types that are already defined in other system include
+ files, so that we can "#define int8_t signed char" below without
+ worrying about a later system include file containing a "typedef
+ signed char int8_t;" that will get messed up by our macro. Our
+ macros should all be consistent with the system versions, except
+ for the "fast" types and macros, which we recommend against using
+ in public interfaces due to compiler differences. */
+
+#if @HAVE_STDINT_H@
+# if defined __sgi && ! defined __c99
+ /* Bypass IRIX's <stdint.h> if in C89 mode, since it merely annoys users
+ with "This header file is to be used only for c99 mode compilations"
+ diagnostics. */
+# define __STDINT_H__
+# endif
+
+ /* Some pre-C++11 <stdint.h> implementations need this. */
+# ifdef __cplusplus
+# ifndef __STDC_CONSTANT_MACROS
+# define __STDC_CONSTANT_MACROS 1
+# endif
+# ifndef __STDC_LIMIT_MACROS
+# define __STDC_LIMIT_MACROS 1
+# endif
+# endif
+
+ /* Other systems may have an incomplete or buggy <stdint.h>.
+ Include it before <inttypes.h>, since any "#include <stdint.h>"
+ in <inttypes.h> would reinclude us, skipping our contents because
+ _@GUARD_PREFIX@_STDINT_H is defined.
+ The include_next requires a split double-inclusion guard. */
+# @INCLUDE_NEXT@ @NEXT_STDINT_H@
+#endif
+
+#if ! defined _@GUARD_PREFIX@_STDINT_H && ! defined _GL_JUST_INCLUDE_SYSTEM_STDINT_H
+#define _@GUARD_PREFIX@_STDINT_H
+
+/* Get SCHAR_MIN, SCHAR_MAX, UCHAR_MAX, INT_MIN, INT_MAX,
+ LONG_MIN, LONG_MAX, ULONG_MAX, _GL_INTEGER_WIDTH. */
+#include <limits.h>
+
+/* Override WINT_MIN and WINT_MAX if gnulib's <wchar.h> or <wctype.h> overrides
+ wint_t. */
+#if @GNULIB_OVERRIDES_WINT_T@
+# undef WINT_MIN
+# undef WINT_MAX
+# define WINT_MIN 0x0U
+# define WINT_MAX 0xffffffffU
+#endif
+
+#if ! @HAVE_C99_STDINT_H@
+
+/* <sys/types.h> defines some of the stdint.h types as well, on glibc,
+ IRIX 6.5, and OpenBSD 3.8 (via <machine/types.h>).
+ AIX 5.2 <sys/types.h> isn't needed and causes troubles.
+ Mac OS X 10.4.6 <sys/types.h> includes <stdint.h> (which is us), but
+ relies on the system <stdint.h> definitions, so include
+ <sys/types.h> after @NEXT_STDINT_H@. */
+# if @HAVE_SYS_TYPES_H@ && ! defined _AIX
+# include <sys/types.h>
+# endif
+
+# if @HAVE_INTTYPES_H@
+ /* In OpenBSD 3.8, <inttypes.h> includes <machine/types.h>, which defines
+ int{8,16,32,64}_t, uint{8,16,32,64}_t and __BIT_TYPES_DEFINED__.
+ <inttypes.h> also defines intptr_t and uintptr_t. */
+# include <inttypes.h>
+# elif @HAVE_SYS_INTTYPES_H@
+ /* Solaris 7 <sys/inttypes.h> has the types except the *_fast*_t types, and
+ the macros except for *_FAST*_*, INTPTR_MIN, PTRDIFF_MIN, PTRDIFF_MAX. */
+# include <sys/inttypes.h>
+# endif
+
+# if @HAVE_SYS_BITYPES_H@ && ! defined __BIT_TYPES_DEFINED__
+ /* Linux libc4 >= 4.6.7 and libc5 have a <sys/bitypes.h> that defines
+ int{8,16,32,64}_t and __BIT_TYPES_DEFINED__. In libc5 >= 5.2.2 it is
+ included by <sys/types.h>. */
+# include <sys/bitypes.h>
+# endif
+
+# undef _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H
+
+/* Minimum and maximum values for an integer type under the usual assumption.
+ Return an unspecified value if BITS == 0, adding a check to pacify
+ picky compilers. */
+
+/* These are separate macros, because if you try to merge these macros into
+ a single one, HP-UX cc rejects the resulting expression in constant
+ expressions. */
+# define _STDINT_UNSIGNED_MIN(bits, zero) \
+ (zero)
+# define _STDINT_SIGNED_MIN(bits, zero) \
+ (~ _STDINT_MAX (1, bits, zero))
+
+# define _STDINT_MAX(signed, bits, zero) \
+ (((((zero) + 1) << ((bits) ? (bits) - 1 - (signed) : 0)) - 1) * 2 + 1)
+
+#if !GNULIB_defined_stdint_types
+
+/* 7.18.1.1. Exact-width integer types */
+
+/* Here we assume a standard architecture where the hardware integer
+ types have 8, 16, 32, optionally 64 bits. */
+
+# undef int8_t
+# undef uint8_t
+typedef signed char gl_int8_t;
+typedef unsigned char gl_uint8_t;
+# define int8_t gl_int8_t
+# define uint8_t gl_uint8_t
+
+# undef int16_t
+# undef uint16_t
+typedef short int gl_int16_t;
+typedef unsigned short int gl_uint16_t;
+# define int16_t gl_int16_t
+# define uint16_t gl_uint16_t
+
+# undef int32_t
+# undef uint32_t
+typedef int gl_int32_t;
+typedef unsigned int gl_uint32_t;
+# define int32_t gl_int32_t
+# define uint32_t gl_uint32_t
+
+/* If the system defines INT64_MAX, assume int64_t works. That way,
+ if the underlying platform defines int64_t to be a 64-bit long long
+ int, the code below won't mistakenly define it to be a 64-bit long
+ int, which would mess up C++ name mangling. We must use #ifdef
+ rather than #if, to avoid an error with HP-UX 10.20 cc. */
+
+# ifdef INT64_MAX
+# define GL_INT64_T
+# else
+/* Do not undefine int64_t if gnulib is not being used with 64-bit
+ types, since otherwise it breaks platforms like Tandem/NSK. */
+# if LONG_MAX >> 31 >> 31 == 1
+# undef int64_t
+typedef long int gl_int64_t;
+# define int64_t gl_int64_t
+# define GL_INT64_T
+# elif defined _MSC_VER
+# undef int64_t
+typedef __int64 gl_int64_t;
+# define int64_t gl_int64_t
+# define GL_INT64_T
+# else
+# undef int64_t
+typedef long long int gl_int64_t;
+# define int64_t gl_int64_t
+# define GL_INT64_T
+# endif
+# endif
+
+# ifdef UINT64_MAX
+# define GL_UINT64_T
+# else
+# if ULONG_MAX >> 31 >> 31 >> 1 == 1
+# undef uint64_t
+typedef unsigned long int gl_uint64_t;
+# define uint64_t gl_uint64_t
+# define GL_UINT64_T
+# elif defined _MSC_VER
+# undef uint64_t
+typedef unsigned __int64 gl_uint64_t;
+# define uint64_t gl_uint64_t
+# define GL_UINT64_T
+# else
+# undef uint64_t
+typedef unsigned long long int gl_uint64_t;
+# define uint64_t gl_uint64_t
+# define GL_UINT64_T
+# endif
+# endif
+
+/* Avoid collision with Solaris 2.5.1 <pthread.h> etc. */
+# define _UINT8_T
+# define _UINT32_T
+# define _UINT64_T
+
+
+/* 7.18.1.2. Minimum-width integer types */
+
+/* Here we assume a standard architecture where the hardware integer
+ types have 8, 16, 32, optionally 64 bits. Therefore the leastN_t types
+ are the same as the corresponding N_t types. */
+
+# undef int_least8_t
+# undef uint_least8_t
+# undef int_least16_t
+# undef uint_least16_t
+# undef int_least32_t
+# undef uint_least32_t
+# undef int_least64_t
+# undef uint_least64_t
+# define int_least8_t int8_t
+# define uint_least8_t uint8_t
+# define int_least16_t int16_t
+# define uint_least16_t uint16_t
+# define int_least32_t int32_t
+# define uint_least32_t uint32_t
+# ifdef GL_INT64_T
+# define int_least64_t int64_t
+# endif
+# ifdef GL_UINT64_T
+# define uint_least64_t uint64_t
+# endif
+
+/* 7.18.1.3. Fastest minimum-width integer types */
+
+/* Note: Other <stdint.h> substitutes may define these types differently.
+ It is not recommended to use these types in public header files. */
+
+/* Here we assume a standard architecture where the hardware integer
+ types have 8, 16, 32, optionally 64 bits. Therefore the fastN_t types
+ are taken from the same list of types. The following code normally
+ uses types consistent with glibc, as that lessens the chance of
+ incompatibility with older GNU hosts. */
+
+# undef int_fast8_t
+# undef uint_fast8_t
+# undef int_fast16_t
+# undef uint_fast16_t
+# undef int_fast32_t
+# undef uint_fast32_t
+# undef int_fast64_t
+# undef uint_fast64_t
+typedef signed char gl_int_fast8_t;
+typedef unsigned char gl_uint_fast8_t;
+
+# ifdef __sun
+/* Define types compatible with SunOS 5.10, so that code compiled under
+ earlier SunOS versions works with code compiled under SunOS 5.10. */
+typedef int gl_int_fast32_t;
+typedef unsigned int gl_uint_fast32_t;
+# else
+typedef long int gl_int_fast32_t;
+typedef unsigned long int gl_uint_fast32_t;
+# endif
+typedef gl_int_fast32_t gl_int_fast16_t;
+typedef gl_uint_fast32_t gl_uint_fast16_t;
+
+# define int_fast8_t gl_int_fast8_t
+# define uint_fast8_t gl_uint_fast8_t
+# define int_fast16_t gl_int_fast16_t
+# define uint_fast16_t gl_uint_fast16_t
+# define int_fast32_t gl_int_fast32_t
+# define uint_fast32_t gl_uint_fast32_t
+# ifdef GL_INT64_T
+# define int_fast64_t int64_t
+# endif
+# ifdef GL_UINT64_T
+# define uint_fast64_t uint64_t
+# endif
+
+/* 7.18.1.4. Integer types capable of holding object pointers */
+
+/* kLIBC's <stdint.h> defines _INTPTR_T_DECLARED and needs its own
+ definitions of intptr_t and uintptr_t (which use int and unsigned)
+ to avoid clashes with declarations of system functions like sbrk.
+ Similarly, MinGW WSL-5.4.1 <stdint.h> needs its own intptr_t and
+ uintptr_t to avoid conflicting declarations of system functions like
+ _findclose in <io.h>. */
+# if !((defined __KLIBC__ && defined _INTPTR_T_DECLARED) \
+ || defined __MINGW32__)
+# undef intptr_t
+# undef uintptr_t
+# ifdef _WIN64
+typedef long long int gl_intptr_t;
+typedef unsigned long long int gl_uintptr_t;
+# else
+typedef long int gl_intptr_t;
+typedef unsigned long int gl_uintptr_t;
+# endif
+# define intptr_t gl_intptr_t
+# define uintptr_t gl_uintptr_t
+# endif
+
+/* 7.18.1.5. Greatest-width integer types */
+
+/* Note: These types are compiler dependent. It may be unwise to use them in
+ public header files. */
+
+/* If the system defines INTMAX_MAX, assume that intmax_t works, and
+ similarly for UINTMAX_MAX and uintmax_t. This avoids problems with
+ assuming one type where another is used by the system. */
+
+# ifndef INTMAX_MAX
+# undef INTMAX_C
+# undef intmax_t
+# if LONG_MAX >> 30 == 1
+typedef long long int gl_intmax_t;
+# define intmax_t gl_intmax_t
+# elif defined GL_INT64_T
+# define intmax_t int64_t
+# else
+typedef long int gl_intmax_t;
+# define intmax_t gl_intmax_t
+# endif
+# endif
+
+# ifndef UINTMAX_MAX
+# undef UINTMAX_C
+# undef uintmax_t
+# if ULONG_MAX >> 31 == 1
+typedef unsigned long long int gl_uintmax_t;
+# define uintmax_t gl_uintmax_t
+# elif defined GL_UINT64_T
+# define uintmax_t uint64_t
+# else
+typedef unsigned long int gl_uintmax_t;
+# define uintmax_t gl_uintmax_t
+# endif
+# endif
+
+/* Verify that intmax_t and uintmax_t have the same size. Too much code
+ breaks if this is not the case. If this check fails, the reason is likely
+ to be found in the autoconf macros. */
+typedef int _verify_intmax_size[sizeof (intmax_t) == sizeof (uintmax_t)
+ ? 1 : -1];
+
+# define GNULIB_defined_stdint_types 1
+# endif /* !GNULIB_defined_stdint_types */
+
+/* 7.18.2. Limits of specified-width integer types */
+
+/* 7.18.2.1. Limits of exact-width integer types */
+
+/* Here we assume a standard architecture where the hardware integer
+ types have 8, 16, 32, optionally 64 bits. */
+
+# undef INT8_MIN
+# undef INT8_MAX
+# undef UINT8_MAX
+# define INT8_MIN (~ INT8_MAX)
+# define INT8_MAX 127
+# define UINT8_MAX 255
+
+# undef INT16_MIN
+# undef INT16_MAX
+# undef UINT16_MAX
+# define INT16_MIN (~ INT16_MAX)
+# define INT16_MAX 32767
+# define UINT16_MAX 65535
+
+# undef INT32_MIN
+# undef INT32_MAX
+# undef UINT32_MAX
+# define INT32_MIN (~ INT32_MAX)
+# define INT32_MAX 2147483647
+# define UINT32_MAX 4294967295U
+
+# if defined GL_INT64_T && ! defined INT64_MAX
+/* Prefer (- INTMAX_C (1) << 63) over (~ INT64_MAX) because SunPRO C 5.0
+ evaluates the latter incorrectly in preprocessor expressions. */
+# define INT64_MIN (- INTMAX_C (1) << 63)
+# define INT64_MAX INTMAX_C (9223372036854775807)
+# endif
+
+# if defined GL_UINT64_T && ! defined UINT64_MAX
+# define UINT64_MAX UINTMAX_C (18446744073709551615)
+# endif
+
+/* 7.18.2.2. Limits of minimum-width integer types */
+
+/* Here we assume a standard architecture where the hardware integer
+ types have 8, 16, 32, optionally 64 bits. Therefore the leastN_t types
+ are the same as the corresponding N_t types. */
+
+# undef INT_LEAST8_MIN
+# undef INT_LEAST8_MAX
+# undef UINT_LEAST8_MAX
+# define INT_LEAST8_MIN INT8_MIN
+# define INT_LEAST8_MAX INT8_MAX
+# define UINT_LEAST8_MAX UINT8_MAX
+
+# undef INT_LEAST16_MIN
+# undef INT_LEAST16_MAX
+# undef UINT_LEAST16_MAX
+# define INT_LEAST16_MIN INT16_MIN
+# define INT_LEAST16_MAX INT16_MAX
+# define UINT_LEAST16_MAX UINT16_MAX
+
+# undef INT_LEAST32_MIN
+# undef INT_LEAST32_MAX
+# undef UINT_LEAST32_MAX
+# define INT_LEAST32_MIN INT32_MIN
+# define INT_LEAST32_MAX INT32_MAX
+# define UINT_LEAST32_MAX UINT32_MAX
+
+# undef INT_LEAST64_MIN
+# undef INT_LEAST64_MAX
+# ifdef GL_INT64_T
+# define INT_LEAST64_MIN INT64_MIN
+# define INT_LEAST64_MAX INT64_MAX
+# endif
+
+# undef UINT_LEAST64_MAX
+# ifdef GL_UINT64_T
+# define UINT_LEAST64_MAX UINT64_MAX
+# endif
+
+/* 7.18.2.3. Limits of fastest minimum-width integer types */
+
+/* Here we assume a standard architecture where the hardware integer
+ types have 8, 16, 32, optionally 64 bits. Therefore the fastN_t types
+ are taken from the same list of types. */
+
+# undef INT_FAST8_MIN
+# undef INT_FAST8_MAX
+# undef UINT_FAST8_MAX
+# define INT_FAST8_MIN SCHAR_MIN
+# define INT_FAST8_MAX SCHAR_MAX
+# define UINT_FAST8_MAX UCHAR_MAX
+
+# undef INT_FAST16_MIN
+# undef INT_FAST16_MAX
+# undef UINT_FAST16_MAX
+# define INT_FAST16_MIN INT_FAST32_MIN
+# define INT_FAST16_MAX INT_FAST32_MAX
+# define UINT_FAST16_MAX UINT_FAST32_MAX
+
+# undef INT_FAST32_MIN
+# undef INT_FAST32_MAX
+# undef UINT_FAST32_MAX
+# ifdef __sun
+# define INT_FAST32_MIN INT_MIN
+# define INT_FAST32_MAX INT_MAX
+# define UINT_FAST32_MAX UINT_MAX
+# else
+# define INT_FAST32_MIN LONG_MIN
+# define INT_FAST32_MAX LONG_MAX
+# define UINT_FAST32_MAX ULONG_MAX
+# endif
+
+# undef INT_FAST64_MIN
+# undef INT_FAST64_MAX
+# ifdef GL_INT64_T
+# define INT_FAST64_MIN INT64_MIN
+# define INT_FAST64_MAX INT64_MAX
+# endif
+
+# undef UINT_FAST64_MAX
+# ifdef GL_UINT64_T
+# define UINT_FAST64_MAX UINT64_MAX
+# endif
+
+/* 7.18.2.4. Limits of integer types capable of holding object pointers */
+
+# undef INTPTR_MIN
+# undef INTPTR_MAX
+# undef UINTPTR_MAX
+# ifdef _WIN64
+# define INTPTR_MIN LLONG_MIN
+# define INTPTR_MAX LLONG_MAX
+# define UINTPTR_MAX ULLONG_MAX
+# else
+# define INTPTR_MIN LONG_MIN
+# define INTPTR_MAX LONG_MAX
+# define UINTPTR_MAX ULONG_MAX
+# endif
+
+/* 7.18.2.5. Limits of greatest-width integer types */
+
+# ifndef INTMAX_MAX
+# undef INTMAX_MIN
+# ifdef INT64_MAX
+# define INTMAX_MIN INT64_MIN
+# define INTMAX_MAX INT64_MAX
+# else
+# define INTMAX_MIN INT32_MIN
+# define INTMAX_MAX INT32_MAX
+# endif
+# endif
+
+# ifndef UINTMAX_MAX
+# ifdef UINT64_MAX
+# define UINTMAX_MAX UINT64_MAX
+# else
+# define UINTMAX_MAX UINT32_MAX
+# endif
+# endif
+
+/* 7.18.3. Limits of other integer types */
+
+/* ptrdiff_t limits */
+# undef PTRDIFF_MIN
+# undef PTRDIFF_MAX
+# if @APPLE_UNIVERSAL_BUILD@
+# ifdef _LP64
+# define PTRDIFF_MIN _STDINT_SIGNED_MIN (64, 0l)
+# define PTRDIFF_MAX _STDINT_MAX (1, 64, 0l)
+# else
+# define PTRDIFF_MIN _STDINT_SIGNED_MIN (32, 0)
+# define PTRDIFF_MAX _STDINT_MAX (1, 32, 0)
+# endif
+# else
+# define PTRDIFF_MIN \
+ _STDINT_SIGNED_MIN (@BITSIZEOF_PTRDIFF_T@, 0@PTRDIFF_T_SUFFIX@)
+# define PTRDIFF_MAX \
+ _STDINT_MAX (1, @BITSIZEOF_PTRDIFF_T@, 0@PTRDIFF_T_SUFFIX@)
+# endif
+
+/* sig_atomic_t limits */
+# undef SIG_ATOMIC_MIN
+# undef SIG_ATOMIC_MAX
+# if @HAVE_SIGNED_SIG_ATOMIC_T@
+# define SIG_ATOMIC_MIN \
+ _STDINT_SIGNED_MIN (@BITSIZEOF_SIG_ATOMIC_T@, 0@SIG_ATOMIC_T_SUFFIX@)
+# else
+# define SIG_ATOMIC_MIN \
+ _STDINT_UNSIGNED_MIN (@BITSIZEOF_SIG_ATOMIC_T@, 0@SIG_ATOMIC_T_SUFFIX@)
+# endif
+# define SIG_ATOMIC_MAX \
+ _STDINT_MAX (@HAVE_SIGNED_SIG_ATOMIC_T@, @BITSIZEOF_SIG_ATOMIC_T@, \
+ 0@SIG_ATOMIC_T_SUFFIX@)
+
+
+/* size_t limit */
+# undef SIZE_MAX
+# if @APPLE_UNIVERSAL_BUILD@
+# ifdef _LP64
+# define SIZE_MAX _STDINT_MAX (0, 64, 0ul)
+# else
+# define SIZE_MAX _STDINT_MAX (0, 32, 0ul)
+# endif
+# else
+# define SIZE_MAX _STDINT_MAX (0, @BITSIZEOF_SIZE_T@, 0@SIZE_T_SUFFIX@)
+# endif
+
+/* wchar_t limits */
+/* Get WCHAR_MIN, WCHAR_MAX.
+ This include is not on the top, above, because on OSF/1 4.0 we have a
+ sequence of nested includes
+ <wchar.h> -> <stdio.h> -> <getopt.h> -> <stdlib.h>, and the latter includes
+ <stdint.h> and assumes its types are already defined. */
+# if @HAVE_WCHAR_H@ && ! (defined WCHAR_MIN && defined WCHAR_MAX)
+# define _GL_JUST_INCLUDE_SYSTEM_WCHAR_H
+# include <wchar.h>
+# undef _GL_JUST_INCLUDE_SYSTEM_WCHAR_H
+# endif
+# undef WCHAR_MIN
+# undef WCHAR_MAX
+# if @HAVE_SIGNED_WCHAR_T@
+# define WCHAR_MIN \
+ _STDINT_SIGNED_MIN (@BITSIZEOF_WCHAR_T@, 0@WCHAR_T_SUFFIX@)
+# else
+# define WCHAR_MIN \
+ _STDINT_UNSIGNED_MIN (@BITSIZEOF_WCHAR_T@, 0@WCHAR_T_SUFFIX@)
+# endif
+# define WCHAR_MAX \
+ _STDINT_MAX (@HAVE_SIGNED_WCHAR_T@, @BITSIZEOF_WCHAR_T@, 0@WCHAR_T_SUFFIX@)
+
+/* wint_t limits */
+/* If gnulib's <wchar.h> or <wctype.h> overrides wint_t, @WINT_T_SUFFIX@ is not
+ accurate, therefore use the definitions from above. */
+# if !@GNULIB_OVERRIDES_WINT_T@
+# undef WINT_MIN
+# undef WINT_MAX
+# if @HAVE_SIGNED_WINT_T@
+# define WINT_MIN \
+ _STDINT_SIGNED_MIN (@BITSIZEOF_WINT_T@, 0@WINT_T_SUFFIX@)
+# else
+# define WINT_MIN \
+ _STDINT_UNSIGNED_MIN (@BITSIZEOF_WINT_T@, 0@WINT_T_SUFFIX@)
+# endif
+# define WINT_MAX \
+ _STDINT_MAX (@HAVE_SIGNED_WINT_T@, @BITSIZEOF_WINT_T@, 0@WINT_T_SUFFIX@)
+# endif
+
+/* 7.18.4. Macros for integer constants */
+
+/* 7.18.4.1. Macros for minimum-width integer constants */
+/* According to ISO C 99 Technical Corrigendum 1 */
+
+/* Here we assume a standard architecture where the hardware integer
+ types have 8, 16, 32, optionally 64 bits, and int is 32 bits. */
+
+# undef INT8_C
+# undef UINT8_C
+# define INT8_C(x) x
+# define UINT8_C(x) x
+
+# undef INT16_C
+# undef UINT16_C
+# define INT16_C(x) x
+# define UINT16_C(x) x
+
+# undef INT32_C
+# undef UINT32_C
+# define INT32_C(x) x
+# define UINT32_C(x) x ## U
+
+# undef INT64_C
+# undef UINT64_C
+# if LONG_MAX >> 31 >> 31 == 1
+# define INT64_C(x) x##L
+# elif defined _MSC_VER
+# define INT64_C(x) x##i64
+# else
+# define INT64_C(x) x##LL
+# endif
+# if ULONG_MAX >> 31 >> 31 >> 1 == 1
+# define UINT64_C(x) x##UL
+# elif defined _MSC_VER
+# define UINT64_C(x) x##ui64
+# else
+# define UINT64_C(x) x##ULL
+# endif
+
+/* 7.18.4.2. Macros for greatest-width integer constants */
+
+# ifndef INTMAX_C
+# if LONG_MAX >> 30 == 1
+# define INTMAX_C(x) x##LL
+# elif defined GL_INT64_T
+# define INTMAX_C(x) INT64_C(x)
+# else
+# define INTMAX_C(x) x##L
+# endif
+# endif
+
+# ifndef UINTMAX_C
+# if ULONG_MAX >> 31 == 1
+# define UINTMAX_C(x) x##ULL
+# elif defined GL_UINT64_T
+# define UINTMAX_C(x) UINT64_C(x)
+# else
+# define UINTMAX_C(x) x##UL
+# endif
+# endif
+
+#endif /* !@HAVE_C99_STDINT_H@ */
+
+/* Macros specified by ISO/IEC TS 18661-1:2014. */
+
+#if (!defined UINTMAX_WIDTH \
+ && (defined _GNU_SOURCE || defined __STDC_WANT_IEC_60559_BFP_EXT__))
+# ifdef INT8_MAX
+# define INT8_WIDTH _GL_INTEGER_WIDTH (INT8_MIN, INT8_MAX)
+# endif
+# ifdef UINT8_MAX
+# define UINT8_WIDTH _GL_INTEGER_WIDTH (0, UINT8_MAX)
+# endif
+# ifdef INT16_MAX
+# define INT16_WIDTH _GL_INTEGER_WIDTH (INT16_MIN, INT16_MAX)
+# endif
+# ifdef UINT16_MAX
+# define UINT16_WIDTH _GL_INTEGER_WIDTH (0, UINT16_MAX)
+# endif
+# ifdef INT32_MAX
+# define INT32_WIDTH _GL_INTEGER_WIDTH (INT32_MIN, INT32_MAX)
+# endif
+# ifdef UINT32_MAX
+# define UINT32_WIDTH _GL_INTEGER_WIDTH (0, UINT32_MAX)
+# endif
+# ifdef INT64_MAX
+# define INT64_WIDTH _GL_INTEGER_WIDTH (INT64_MIN, INT64_MAX)
+# endif
+# ifdef UINT64_MAX
+# define UINT64_WIDTH _GL_INTEGER_WIDTH (0, UINT64_MAX)
+# endif
+# define INT_LEAST8_WIDTH _GL_INTEGER_WIDTH (INT_LEAST8_MIN, INT_LEAST8_MAX)
+# define UINT_LEAST8_WIDTH _GL_INTEGER_WIDTH (0, UINT_LEAST8_MAX)
+# define INT_LEAST16_WIDTH _GL_INTEGER_WIDTH (INT_LEAST16_MIN, INT_LEAST16_MAX)
+# define UINT_LEAST16_WIDTH _GL_INTEGER_WIDTH (0, UINT_LEAST16_MAX)
+# define INT_LEAST32_WIDTH _GL_INTEGER_WIDTH (INT_LEAST32_MIN, INT_LEAST32_MAX)
+# define UINT_LEAST32_WIDTH _GL_INTEGER_WIDTH (0, UINT_LEAST32_MAX)
+# define INT_LEAST64_WIDTH _GL_INTEGER_WIDTH (INT_LEAST64_MIN, INT_LEAST64_MAX)
+# define UINT_LEAST64_WIDTH _GL_INTEGER_WIDTH (0, UINT_LEAST64_MAX)
+# define INT_FAST8_WIDTH _GL_INTEGER_WIDTH (INT_FAST8_MIN, INT_FAST8_MAX)
+# define UINT_FAST8_WIDTH _GL_INTEGER_WIDTH (0, UINT_FAST8_MAX)
+# define INT_FAST16_WIDTH _GL_INTEGER_WIDTH (INT_FAST16_MIN, INT_FAST16_MAX)
+# define UINT_FAST16_WIDTH _GL_INTEGER_WIDTH (0, UINT_FAST16_MAX)
+# define INT_FAST32_WIDTH _GL_INTEGER_WIDTH (INT_FAST32_MIN, INT_FAST32_MAX)
+# define UINT_FAST32_WIDTH _GL_INTEGER_WIDTH (0, UINT_FAST32_MAX)
+# define INT_FAST64_WIDTH _GL_INTEGER_WIDTH (INT_FAST64_MIN, INT_FAST64_MAX)
+# define UINT_FAST64_WIDTH _GL_INTEGER_WIDTH (0, UINT_FAST64_MAX)
+# define INTPTR_WIDTH _GL_INTEGER_WIDTH (INTPTR_MIN, INTPTR_MAX)
+# define UINTPTR_WIDTH _GL_INTEGER_WIDTH (0, UINTPTR_MAX)
+# define INTMAX_WIDTH _GL_INTEGER_WIDTH (INTMAX_MIN, INTMAX_MAX)
+# define UINTMAX_WIDTH _GL_INTEGER_WIDTH (0, UINTMAX_MAX)
+# define PTRDIFF_WIDTH _GL_INTEGER_WIDTH (PTRDIFF_MIN, PTRDIFF_MAX)
+# define SIZE_WIDTH _GL_INTEGER_WIDTH (0, SIZE_MAX)
+# define WCHAR_WIDTH _GL_INTEGER_WIDTH (WCHAR_MIN, WCHAR_MAX)
+# ifdef WINT_MAX
+# define WINT_WIDTH _GL_INTEGER_WIDTH (WINT_MIN, WINT_MAX)
+# endif
+# ifdef SIG_ATOMIC_MAX
+# define SIG_ATOMIC_WIDTH _GL_INTEGER_WIDTH (SIG_ATOMIC_MIN, SIG_ATOMIC_MAX)
+# endif
+#endif /* !WINT_WIDTH && (_GNU_SOURCE || __STDC_WANT_IEC_60559_BFP_EXT__) */
+
+#endif /* _@GUARD_PREFIX@_STDINT_H */
+#endif /* !(defined __ANDROID__ && ...) */
+#endif /* !defined _@GUARD_PREFIX@_STDINT_H && !defined _GL_JUST_INCLUDE_SYSTEM_STDINT_H */
diff --git a/src/gnulib/sys_types.in.h b/src/gnulib/sys_types.in.h
new file mode 100644
index 0000000..654e803
--- /dev/null
+++ b/src/gnulib/sys_types.in.h
@@ -0,0 +1,106 @@
+/* Provide a more complete sys/types.h.
+
+ Copyright (C) 2011-2021 Free Software Foundation, Inc.
+
+ 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; either 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 for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <https://www.gnu.org/licenses/>. */
+
+#if __GNUC__ >= 3
+@PRAGMA_SYSTEM_HEADER@
+#endif
+@PRAGMA_COLUMNS@
+
+#if defined _WIN32 && !defined __CYGWIN__ \
+ && (defined __need_off_t || defined __need___off64_t \
+ || defined __need_ssize_t || defined __need_time_t)
+
+/* Special invocation convention inside mingw header files. */
+
+#@INCLUDE_NEXT@ @NEXT_SYS_TYPES_H@
+
+#else
+/* Normal invocation convention. */
+
+#ifndef _@GUARD_PREFIX@_SYS_TYPES_H
+
+/* The include_next requires a split double-inclusion guard. */
+# define _GL_INCLUDING_SYS_TYPES_H
+#@INCLUDE_NEXT@ @NEXT_SYS_TYPES_H@
+# undef _GL_INCLUDING_SYS_TYPES_H
+
+#ifndef _@GUARD_PREFIX@_SYS_TYPES_H
+#define _@GUARD_PREFIX@_SYS_TYPES_H
+
+/* Override off_t if Large File Support is requested on native Windows. */
+#if @WINDOWS_64_BIT_OFF_T@
+/* Same as int64_t in <stdint.h>. */
+# if defined _MSC_VER
+# define off_t __int64
+# else
+# define off_t long long int
+# endif
+/* Indicator, for gnulib internal purposes. */
+# define _GL_WINDOWS_64_BIT_OFF_T 1
+#endif
+
+/* Override dev_t and ino_t if distinguishable inodes support is requested
+ on native Windows. */
+#if @WINDOWS_STAT_INODES@
+
+# if @WINDOWS_STAT_INODES@ == 2
+/* Experimental, not useful in Windows 10. */
+
+/* Define dev_t to a 64-bit type. */
+# if !defined GNULIB_defined_dev_t
+typedef unsigned long long int rpl_dev_t;
+# undef dev_t
+# define dev_t rpl_dev_t
+# define GNULIB_defined_dev_t 1
+# endif
+
+/* Define ino_t to a 128-bit type. */
+# if !defined GNULIB_defined_ino_t
+/* MSVC does not have a 128-bit integer type.
+ GCC has a 128-bit integer type __int128, but only on 64-bit targets. */
+typedef struct { unsigned long long int _gl_ino[2]; } rpl_ino_t;
+# undef ino_t
+# define ino_t rpl_ino_t
+# define GNULIB_defined_ino_t 1
+# endif
+
+# else /* @WINDOWS_STAT_INODES@ == 1 */
+
+/* Define ino_t to a 64-bit type. */
+# if !defined GNULIB_defined_ino_t
+typedef unsigned long long int rpl_ino_t;
+# undef ino_t
+# define ino_t rpl_ino_t
+# define GNULIB_defined_ino_t 1
+# endif
+
+# endif
+
+/* Indicator, for gnulib internal purposes. */
+# define _GL_WINDOWS_STAT_INODES @WINDOWS_STAT_INODES@
+
+#endif
+
+/* MSVC 9 defines size_t in <stddef.h>, not in <sys/types.h>. */
+/* But avoid namespace pollution on glibc systems. */
+#if (defined _WIN32 && ! defined __CYGWIN__) && ! defined __GLIBC__
+# include <stddef.h>
+#endif
+
+#endif /* _@GUARD_PREFIX@_SYS_TYPES_H */
+#endif /* _@GUARD_PREFIX@_SYS_TYPES_H */
+#endif /* __need_XXX */
diff --git a/src/gnulib/xsize.c b/src/gnulib/xsize.c
new file mode 100644
index 0000000..4b4914c
--- /dev/null
+++ b/src/gnulib/xsize.c
@@ -0,0 +1,3 @@
+#include <config.h>
+#define XSIZE_INLINE _GL_EXTERN_INLINE
+#include "xsize.h"
diff --git a/src/gnulib/xsize.h b/src/gnulib/xsize.h
new file mode 100644
index 0000000..b69bafc
--- /dev/null
+++ b/src/gnulib/xsize.h
@@ -0,0 +1,108 @@
+/* xsize.h -- Checked size_t computations.
+
+ Copyright (C) 2003, 2008-2021 Free Software Foundation, Inc.
+
+ 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; either 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 for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <https://www.gnu.org/licenses/>. */
+
+#ifndef _XSIZE_H
+#define _XSIZE_H
+
+/* Get size_t. */
+#include <stddef.h>
+
+/* Get SIZE_MAX. */
+#include <limits.h>
+#if HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
+/* Get ATTRIBUTE_PURE. */
+#include "attribute.h"
+
+#ifndef _GL_INLINE_HEADER_BEGIN
+ #error "Please include config.h first."
+#endif
+_GL_INLINE_HEADER_BEGIN
+#ifndef XSIZE_INLINE
+# define XSIZE_INLINE _GL_INLINE
+#endif
+
+/* The size of memory objects is often computed through expressions of
+ type size_t. Example:
+ void* p = malloc (header_size + n * element_size).
+ These computations can lead to overflow. When this happens, malloc()
+ returns a piece of memory that is way too small, and the program then
+ crashes while attempting to fill the memory.
+ To avoid this, the functions and macros in this file check for overflow.
+ The convention is that SIZE_MAX represents overflow.
+ malloc (SIZE_MAX) is not guaranteed to fail -- think of a malloc
+ implementation that uses mmap --, it's recommended to use size_overflow_p()
+ or size_in_bounds_p() before invoking malloc().
+ The example thus becomes:
+ size_t size = xsum (header_size, xtimes (n, element_size));
+ void *p = (size_in_bounds_p (size) ? malloc (size) : NULL);
+*/
+
+/* Convert an arbitrary value >= 0 to type size_t. */
+#define xcast_size_t(N) \
+ ((N) <= SIZE_MAX ? (size_t) (N) : SIZE_MAX)
+
+/* Sum of two sizes, with overflow check. */
+XSIZE_INLINE size_t ATTRIBUTE_PURE
+xsum (size_t size1, size_t size2)
+{
+ size_t sum = size1 + size2;
+ return (sum >= size1 ? sum : SIZE_MAX);
+}
+
+/* Sum of three sizes, with overflow check. */
+XSIZE_INLINE size_t ATTRIBUTE_PURE
+xsum3 (size_t size1, size_t size2, size_t size3)
+{
+ return xsum (xsum (size1, size2), size3);
+}
+
+/* Sum of four sizes, with overflow check. */
+XSIZE_INLINE size_t ATTRIBUTE_PURE
+xsum4 (size_t size1, size_t size2, size_t size3, size_t size4)
+{
+ return xsum (xsum (xsum (size1, size2), size3), size4);
+}
+
+/* Maximum of two sizes, with overflow check. */
+XSIZE_INLINE size_t ATTRIBUTE_PURE
+xmax (size_t size1, size_t size2)
+{
+ /* No explicit check is needed here, because for any n:
+ max (SIZE_MAX, n) == SIZE_MAX and max (n, SIZE_MAX) == SIZE_MAX. */
+ return (size1 >= size2 ? size1 : size2);
+}
+
+/* Multiplication of a count with an element size, with overflow check.
+ The count must be >= 0 and the element size must be > 0.
+ This is a macro, not a function, so that it works correctly even
+ when N is of a wider type and N > SIZE_MAX. */
+#define xtimes(N, ELSIZE) \
+ ((N) <= SIZE_MAX / (ELSIZE) ? (size_t) (N) * (ELSIZE) : SIZE_MAX)
+
+/* Check for overflow. */
+#define size_overflow_p(SIZE) \
+ ((SIZE) == SIZE_MAX)
+/* Check against overflow. */
+#define size_in_bounds_p(SIZE) \
+ ((SIZE) != SIZE_MAX)
+
+_GL_INLINE_HEADER_END
+
+#endif /* _XSIZE_H */
diff --git a/src/helper/binarybuffer.c b/src/helper/binarybuffer.c
index 44d139f..3d35702 100644
--- a/src/helper/binarybuffer.c
+++ b/src/helper/binarybuffer.c
@@ -23,6 +23,7 @@
#include "config.h"
#endif
+#include "helper/replacements.h"
#include "log.h"
#include "binarybuffer.h"
diff --git a/src/helper/bits.h b/src/helper/bits.h
index cdcac9e..00d3c02 100644
--- a/src/helper/bits.h
+++ b/src/helper/bits.h
@@ -24,6 +24,7 @@
#ifndef OPENOCD_HELPER_BITS_H
#define OPENOCD_HELPER_BITS_H
+#include <helper/replacements.h>
#include <helper/types.h>
#define BIT(nr) (1UL << (nr))
diff --git a/src/helper/configuration.c b/src/helper/configuration.c
index 114ad2c..8f4f118 100644
--- a/src/helper/configuration.c
+++ b/src/helper/configuration.c
@@ -18,12 +18,14 @@
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "configuration.h"
#include "log.h"
+#include "replacements.h"
static size_t num_config_files;
static char **config_file_names;
diff --git a/src/helper/fileio.c b/src/helper/fileio.c
index 9dd57e7..b6f1f4e 100644
--- a/src/helper/fileio.c
+++ b/src/helper/fileio.c
@@ -29,6 +29,7 @@
#include "log.h"
#include "configuration.h"
#include "fileio.h"
+#include "replacements.h"
struct fileio {
char *url;
diff --git a/src/helper/fileio.h b/src/helper/fileio.h
index 02592e2..16c1046 100644
--- a/src/helper/fileio.h
+++ b/src/helper/fileio.h
@@ -25,6 +25,8 @@
#ifndef OPENOCD_HELPER_FILEIO_H
#define OPENOCD_HELPER_FILEIO_H
+#include "types.h"
+
#define FILEIO_MAX_ERROR_STRING (128)
enum fileio_type {
diff --git a/src/helper/log.c b/src/helper/log.c
index 7440b70..f5a8062 100644
--- a/src/helper/log.c
+++ b/src/helper/log.c
@@ -28,6 +28,7 @@
#include "log.h"
#include "command.h"
+#include "replacements.h"
#include "time_support.h"
#include <stdarg.h>
diff --git a/src/helper/options.c b/src/helper/options.c
index 0ccbf56..246c6a8 100644
--- a/src/helper/options.c
+++ b/src/helper/options.c
@@ -31,6 +31,7 @@
#include <limits.h>
#include <stdlib.h>
+#include <string.h>
#if IS_DARWIN
#include <libproc.h>
#endif
diff --git a/src/helper/replacements.c b/src/helper/replacements.c
index b4bb94f..f4ecb8d 100644
--- a/src/helper/replacements.c
+++ b/src/helper/replacements.c
@@ -62,6 +62,7 @@ void *fill_malloc(size_t size)
#ifdef _WIN32
#include <io.h>
+#include <winsock2.h>
#endif
/* replacements for gettimeofday */
diff --git a/src/helper/replacements.h b/src/helper/replacements.h
index ac50095..1b6e5bd 100644
--- a/src/helper/replacements.h
+++ b/src/helper/replacements.h
@@ -26,6 +26,7 @@
#define OPENOCD_HELPER_REPLACEMENTS_H
#include <stdint.h>
+#include <helper/system.h>
/* MIN,MAX macros */
#ifndef MIN
diff --git a/src/helper/time_support.h b/src/helper/time_support.h
index a9f2dff..3c7d425 100644
--- a/src/helper/time_support.h
+++ b/src/helper/time_support.h
@@ -26,6 +26,7 @@
#define OPENOCD_HELPER_TIME_SUPPORT_H
#include <time.h>
+#include "types.h"
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
diff --git a/src/jtag/adapter.c b/src/jtag/adapter.c
index af75917..13368ab 100644
--- a/src/jtag/adapter.c
+++ b/src/jtag/adapter.c
@@ -37,10 +37,6 @@
#include <transport/transport.h>
#include <jtag/drivers/jtag_usb_common.h>
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-
/**
* @file
* Holds support for configuring debug adapters from TCl scripts.
diff --git a/src/jtag/aice/aice_pipe.c b/src/jtag/aice/aice_pipe.c
index c0e532c..2dd24b9 100644
--- a/src/jtag/aice/aice_pipe.c
+++ b/src/jtag/aice/aice_pipe.c
@@ -27,6 +27,7 @@
#include <helper/log.h>
#include <helper/time_support.h>
+#include <helper/system.h>
#include "aice_port.h"
#include "aice_pipe.h"
diff --git a/src/jtag/aice/aice_transport.c b/src/jtag/aice/aice_transport.c
index ea710ad..0c9f303 100644
--- a/src/jtag/aice/aice_transport.c
+++ b/src/jtag/aice/aice_transport.c
@@ -27,6 +27,7 @@
#include <target/target.h>
#include <jtag/aice/aice_interface.h>
#include <jtag/aice/aice_transport.h>
+#include <string.h>
/* */
static int jim_newtap_expected_id(Jim_Nvp *n, Jim_GetOptInfo *goi,
diff --git a/src/jtag/aice/aice_usb.c b/src/jtag/aice/aice_usb.c
index 7688aea..c5a0eb7 100644
--- a/src/jtag/aice/aice_usb.c
+++ b/src/jtag/aice/aice_usb.c
@@ -22,6 +22,7 @@
#include <jtag/drivers/libusb_helper.h>
#include <helper/log.h>
#include <helper/time_support.h>
+#include <helper/system.h>
#include <target/target.h>
#include <jtag/jtag.h>
#include <target/nds32_insn.h>
diff --git a/src/jtag/core.c b/src/jtag/core.c
index 5abf832..ac58906 100644
--- a/src/jtag/core.c
+++ b/src/jtag/core.c
@@ -35,6 +35,7 @@
#include "interface.h"
#include <transport/transport.h>
#include <helper/jep106.h>
+#include "helper/system.h"
#ifdef HAVE_STRINGS_H
#include <strings.h>
diff --git a/src/jtag/drivers/arm-jtag-ew.c b/src/jtag/drivers/arm-jtag-ew.c
index 40d52ac..754f937 100644
--- a/src/jtag/drivers/arm-jtag-ew.c
+++ b/src/jtag/drivers/arm-jtag-ew.c
@@ -22,6 +22,7 @@
#include <jtag/interface.h>
#include <jtag/commands.h>
+#include "helper/system.h"
#include <usb.h>
#include "usb_common.h"
diff --git a/src/jtag/drivers/cmsis_dap.c b/src/jtag/drivers/cmsis_dap.c
index 16480ae..e2762e1 100644
--- a/src/jtag/drivers/cmsis_dap.c
+++ b/src/jtag/drivers/cmsis_dap.c
@@ -36,6 +36,7 @@
#endif
#include <transport/transport.h>
+#include "helper/replacements.h"
#include <jtag/swd.h>
#include <jtag/interface.h>
#include <jtag/commands.h>
diff --git a/src/jtag/drivers/cmsis_dap_usb_bulk.c b/src/jtag/drivers/cmsis_dap_usb_bulk.c
index 0134c03..9c76449 100644
--- a/src/jtag/drivers/cmsis_dap_usb_bulk.c
+++ b/src/jtag/drivers/cmsis_dap_usb_bulk.c
@@ -37,6 +37,7 @@
#include <libusb.h>
#include <helper/log.h>
+#include <helper/replacements.h>
#include "cmsis_dap.h"
diff --git a/src/jtag/drivers/jlink.c b/src/jtag/drivers/jlink.c
index 15d252c..8c1a811 100644
--- a/src/jtag/drivers/jlink.c
+++ b/src/jtag/drivers/jlink.c
@@ -39,6 +39,7 @@
#include <jtag/swd.h>
#include <jtag/commands.h>
#include <jtag/drivers/jtag_usb_common.h>
+#include <src/helper/replacements.h>
#include <target/cortex_m.h>
#include <libjaylink/libjaylink.h>
diff --git a/src/jtag/drivers/jtag_usb_common.c b/src/jtag/drivers/jtag_usb_common.c
index 969ea84..f18ea54 100644
--- a/src/jtag/drivers/jtag_usb_common.c
+++ b/src/jtag/drivers/jtag_usb_common.c
@@ -4,6 +4,7 @@
*/
#include <helper/log.h>
+#include <string.h>
#include "jtag_usb_common.h"
diff --git a/src/jtag/drivers/jtag_usb_common.h b/src/jtag/drivers/jtag_usb_common.h
index 8c03742..c4c28cc 100644
--- a/src/jtag/drivers/jtag_usb_common.h
+++ b/src/jtag/drivers/jtag_usb_common.h
@@ -6,6 +6,9 @@
#ifndef OPENOCD_JTAG_USB_COMMON_H
#define OPENOCD_JTAG_USB_COMMON_H
+#include <helper/replacements.h>
+#include <helper/types.h>
+
void jtag_usb_set_location(const char *location);
const char *jtag_usb_get_location(void);
bool jtag_usb_location_equal(uint8_t dev_bus, uint8_t *port_path,
diff --git a/src/jtag/drivers/jtag_vpi.c b/src/jtag/drivers/jtag_vpi.c
index c5ffe83..aeed6a5 100644
--- a/src/jtag/drivers/jtag_vpi.c
+++ b/src/jtag/drivers/jtag_vpi.c
@@ -33,7 +33,7 @@
#include <netinet/tcp.h>
#endif
-#include <string.h>
+#include "helper/replacements.h"
#define NO_TAP_SHIFT 0
#define TAP_SHIFT 1
diff --git a/src/jtag/drivers/mpsse.c b/src/jtag/drivers/mpsse.c
index fe8b6b8..39c49e7 100644
--- a/src/jtag/drivers/mpsse.c
+++ b/src/jtag/drivers/mpsse.c
@@ -22,6 +22,7 @@
#include "mpsse.h"
#include "helper/log.h"
+#include "helper/replacements.h"
#include "helper/time_support.h"
#include <libusb.h>
diff --git a/src/jtag/drivers/remote_bitbang.c b/src/jtag/drivers/remote_bitbang.c
index 6637952..ef27056 100644
--- a/src/jtag/drivers/remote_bitbang.c
+++ b/src/jtag/drivers/remote_bitbang.c
@@ -24,6 +24,8 @@
#include <sys/un.h>
#include <netdb.h>
#endif
+#include "helper/system.h"
+#include "helper/replacements.h"
#include <jtag/interface.h>
#include "bitbang.h"
diff --git a/src/jtag/drivers/rlink.c b/src/jtag/drivers/rlink.c
index be4ad08..d15dba7 100644
--- a/src/jtag/drivers/rlink.c
+++ b/src/jtag/drivers/rlink.c
@@ -29,6 +29,7 @@
/* project specific includes */
#include <jtag/interface.h>
#include <jtag/commands.h>
+#include "helper/replacements.h"
#include "rlink.h"
#include "rlink_st7.h"
#include "rlink_ep1_cmd.h"
diff --git a/src/jtag/drivers/rlink.h b/src/jtag/drivers/rlink.h
index 74b6258..0c15a32 100644
--- a/src/jtag/drivers/rlink.h
+++ b/src/jtag/drivers/rlink.h
@@ -19,6 +19,7 @@
#ifndef OPENOCD_JTAG_DRIVERS_RLINK_H
#define OPENOCD_JTAG_DRIVERS_RLINK_H
+#include "helper/types.h"
struct rlink_speed_table {
uint8_t const *dtc;
uint16_t dtc_size;
diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c
index 4545bcb..a6d7c3a 100644
--- a/src/jtag/drivers/stlink_usb.c
+++ b/src/jtag/drivers/stlink_usb.c
@@ -32,6 +32,7 @@
/* project specific includes */
#include <helper/binarybuffer.h>
#include <helper/bits.h>
+#include <helper/system.h>
#include <jtag/interface.h>
#include <jtag/hla/hla_layout.h>
#include <jtag/hla/hla_transport.h>
diff --git a/src/jtag/drivers/ulink.c b/src/jtag/drivers/ulink.c
index ccc023f..1b773fa 100644
--- a/src/jtag/drivers/ulink.c
+++ b/src/jtag/drivers/ulink.c
@@ -21,6 +21,7 @@
#endif
#include <math.h>
+#include "helper/system.h"
#include <jtag/interface.h>
#include <jtag/commands.h>
#include <target/image.h>
diff --git a/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c b/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c
index 6f15fa7..15028b7 100644
--- a/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c
+++ b/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c
@@ -23,6 +23,7 @@
#endif
#include <jtag/interface.h>
#include <jtag/commands.h>
+#include "helper/system.h"
#include <libusb_helper.h>
#include <target/image.h>
diff --git a/src/jtag/drivers/usb_blaster/usb_blaster.c b/src/jtag/drivers/usb_blaster/usb_blaster.c
index 5002a5f..c312468 100644
--- a/src/jtag/drivers/usb_blaster/usb_blaster.c
+++ b/src/jtag/drivers/usb_blaster/usb_blaster.c
@@ -77,6 +77,7 @@
#include <jtag/interface.h>
#include <jtag/commands.h>
#include <helper/time_support.h>
+#include <helper/replacements.h>
#include "ublast_access.h"
/* system includes */
diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h
index 2fa5802..cc403df 100644
--- a/src/jtag/jtag.h
+++ b/src/jtag/jtag.h
@@ -24,6 +24,7 @@
#include <helper/binarybuffer.h>
#include <helper/log.h>
+#include <helper/replacements.h>
#ifndef DEBUG_JTAG_IOZ
#define DEBUG_JTAG_IOZ 64
diff --git a/src/m4/00gnulib.m4 b/src/m4/00gnulib.m4
new file mode 100644
index 0000000..9ba1743
--- /dev/null
+++ b/src/m4/00gnulib.m4
@@ -0,0 +1,85 @@
+# 00gnulib.m4 serial 8
+dnl Copyright (C) 2009-2021 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This file must be named something that sorts before all other
+dnl gnulib-provided .m4 files. It is needed until the clang fix has
+dnl been included in Autoconf.
+
+# The following definitions arrange to use a compiler option
+# -Werror=implicit-function-declaration in AC_CHECK_DECL, when the
+# compiler is clang. Without it, clang implicitly declares "known"
+# library functions in C mode, but not in C++ mode, which would cause
+# Gnulib to omit a declaration and thus later produce an error in C++
+# mode. As of clang 9.0, these "known" functions are identified through
+# LIBBUILTIN invocations in the LLVM source file
+# llvm/tools/clang/include/clang/Basic/Builtins.def.
+# It's not possible to AC_REQUIRE the extra tests from AC_CHECK_DECL,
+# because AC_CHECK_DECL, like other Autoconf built-ins, is not supposed
+# to AC_REQUIRE anything: some configure.ac files have their first
+# AC_CHECK_DECL executed conditionally. Therefore append the extra tests
+# to AC_PROG_CC.
+AC_DEFUN([gl_COMPILER_CLANG],
+[
+dnl AC_REQUIRE([AC_PROG_CC])
+ AC_CACHE_CHECK([whether the compiler is clang],
+ [gl_cv_compiler_clang],
+ [dnl Use _AC_COMPILE_IFELSE instead of AC_EGREP_CPP, to avoid error
+ dnl "circular dependency of AC_LANG_COMPILER(C)" if AC_PROG_CC has
+ dnl not yet been invoked.
+ _AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[
+ #ifdef __clang__
+ barfbarf
+ #endif
+ ]],[[]])
+ ],
+ [gl_cv_compiler_clang=no],
+ [gl_cv_compiler_clang=yes])
+ ])
+])
+AC_DEFUN([gl_COMPILER_PREPARE_CHECK_DECL],
+[
+dnl AC_REQUIRE([AC_PROG_CC])
+dnl AC_REQUIRE([gl_COMPILER_CLANG])
+ AC_CACHE_CHECK([for compiler option needed when checking for declarations],
+ [gl_cv_compiler_check_decl_option],
+ [if test $gl_cv_compiler_clang = yes; then
+ dnl Test whether the compiler supports the option
+ dnl '-Werror=implicit-function-declaration'.
+ save_ac_compile="$ac_compile"
+ ac_compile="$ac_compile -Werror=implicit-function-declaration"
+ dnl Use _AC_COMPILE_IFELSE instead of AC_COMPILE_IFELSE, to avoid a
+ dnl warning "AC_COMPILE_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS".
+ _AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]],[[]])],
+ [gl_cv_compiler_check_decl_option='-Werror=implicit-function-declaration'],
+ [gl_cv_compiler_check_decl_option=none])
+ ac_compile="$save_ac_compile"
+ else
+ gl_cv_compiler_check_decl_option=none
+ fi
+ ])
+ if test "x$gl_cv_compiler_check_decl_option" != xnone; then
+ ac_compile_for_check_decl="$ac_compile $gl_cv_compiler_check_decl_option"
+ else
+ ac_compile_for_check_decl="$ac_compile"
+ fi
+])
+dnl Redefine _AC_CHECK_DECL_BODY so that it references ac_compile_for_check_decl
+dnl instead of ac_compile. If, for whatever reason, the override of AC_PROG_CC
+dnl in zzgnulib.m4 is inactive, use the original ac_compile.
+m4_define([_AC_CHECK_DECL_BODY],
+[ ac_save_ac_compile="$ac_compile"
+ if test -n "$ac_compile_for_check_decl"; then
+ ac_compile="$ac_compile_for_check_decl"
+ fi]
+m4_defn([_AC_CHECK_DECL_BODY])[ ac_compile="$ac_save_ac_compile"
+])
+
+# gl_00GNULIB
+# -----------
+# Witness macro that this file has been included. Needed to force
+# Automake to include this file prior to all other gnulib .m4 files.
+AC_DEFUN([gl_00GNULIB])
diff --git a/src/m4/absolute-header.m4 b/src/m4/absolute-header.m4
new file mode 100644
index 0000000..52d80d0
--- /dev/null
+++ b/src/m4/absolute-header.m4
@@ -0,0 +1,100 @@
+# absolute-header.m4 serial 17
+dnl Copyright (C) 2006-2021 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Derek Price.
+
+# gl_ABSOLUTE_HEADER(HEADER1 HEADER2 ...)
+# ---------------------------------------
+# Find the absolute name of a header file, testing first if the header exists.
+# If the header were sys/inttypes.h, this macro would define
+# ABSOLUTE_SYS_INTTYPES_H to the '""' quoted absolute name of sys/inttypes.h
+# in config.h
+# (e.g. '#define ABSOLUTE_SYS_INTTYPES_H "///usr/include/sys/inttypes.h"').
+# The three "///" are to pacify Sun C 5.8, which otherwise would say
+# "warning: #include of /usr/include/... may be non-portable".
+# Use '""', not '<>', so that the /// cannot be confused with a C99 comment.
+# Note: This macro assumes that the header file is not empty after
+# preprocessing, i.e. it does not only define preprocessor macros but also
+# provides some type/enum definitions or function/variable declarations.
+AC_DEFUN([gl_ABSOLUTE_HEADER],
+[AC_REQUIRE([AC_CANONICAL_HOST])
+AC_LANG_PREPROC_REQUIRE()dnl
+m4_foreach_w([gl_HEADER_NAME], [$1],
+ [AS_VAR_PUSHDEF([gl_absolute_header],
+ [gl_cv_absolute_]m4_defn([gl_HEADER_NAME]))dnl
+ AC_CACHE_CHECK([absolute name of <]m4_defn([gl_HEADER_NAME])[>],
+ [gl_absolute_header],
+ [AS_VAR_PUSHDEF([ac_header_exists],
+ [ac_cv_header_]m4_defn([gl_HEADER_NAME]))dnl
+ AC_CHECK_HEADERS_ONCE(m4_defn([gl_HEADER_NAME]))dnl
+ if test AS_VAR_GET([ac_header_exists]) = yes; then
+ gl_ABSOLUTE_HEADER_ONE(m4_defn([gl_HEADER_NAME]))
+ fi
+ AS_VAR_POPDEF([ac_header_exists])dnl
+ ])dnl
+ AC_DEFINE_UNQUOTED(AS_TR_CPP([ABSOLUTE_]m4_defn([gl_HEADER_NAME])),
+ ["AS_VAR_GET([gl_absolute_header])"],
+ [Define this to an absolute name of <]m4_defn([gl_HEADER_NAME])[>.])
+ AS_VAR_POPDEF([gl_absolute_header])dnl
+])dnl
+])# gl_ABSOLUTE_HEADER
+
+# gl_ABSOLUTE_HEADER_ONE(HEADER)
+# ------------------------------
+# Like gl_ABSOLUTE_HEADER, except that:
+# - it assumes that the header exists,
+# - it uses the current CPPFLAGS,
+# - it does not cache the result,
+# - it is silent.
+AC_DEFUN([gl_ABSOLUTE_HEADER_ONE],
+[
+ AC_REQUIRE([AC_CANONICAL_HOST])
+ AC_LANG_CONFTEST([AC_LANG_SOURCE([[#include <]]m4_dquote([$1])[[>]])])
+ dnl AIX "xlc -E" and "cc -E" omit #line directives for header files
+ dnl that contain only a #include of other header files and no
+ dnl non-comment tokens of their own. This leads to a failure to
+ dnl detect the absolute name of <dirent.h>, <signal.h>, <poll.h>
+ dnl and others. The workaround is to force preservation of comments
+ dnl through option -C. This ensures all necessary #line directives
+ dnl are present. GCC supports option -C as well.
+ case "$host_os" in
+ aix*) gl_absname_cpp="$ac_cpp -C" ;;
+ *) gl_absname_cpp="$ac_cpp" ;;
+ esac
+changequote(,)
+ case "$host_os" in
+ mingw*)
+ dnl For the sake of native Windows compilers (excluding gcc),
+ dnl treat backslash as a directory separator, like /.
+ dnl Actually, these compilers use a double-backslash as
+ dnl directory separator, inside the
+ dnl # line "filename"
+ dnl directives.
+ gl_dirsep_regex='[/\\]'
+ ;;
+ *)
+ gl_dirsep_regex='\/'
+ ;;
+ esac
+ dnl A sed expression that turns a string into a basic regular
+ dnl expression, for use within "/.../".
+ gl_make_literal_regex_sed='s,[]$^\\.*/[],\\&,g'
+ gl_header_literal_regex=`echo '$1' \
+ | sed -e "$gl_make_literal_regex_sed"`
+ gl_absolute_header_sed="/${gl_dirsep_regex}${gl_header_literal_regex}/"'{
+ s/.*"\(.*'"${gl_dirsep_regex}${gl_header_literal_regex}"'\)".*/\1/
+ s|^/[^/]|//&|
+ p
+ q
+ }'
+changequote([,])
+ dnl eval is necessary to expand gl_absname_cpp.
+ dnl Ultrix and Pyramid sh refuse to redirect output of eval,
+ dnl so use subshell.
+ AS_VAR_SET([gl_cv_absolute_]AS_TR_SH([[$1]]),
+[`(eval "$gl_absname_cpp conftest.$ac_ext") 2>&AS_MESSAGE_LOG_FD |
+ sed -n "$gl_absolute_header_sed"`])
+])
diff --git a/src/m4/extern-inline.m4 b/src/m4/extern-inline.m4
new file mode 100644
index 0000000..a2acf12
--- /dev/null
+++ b/src/m4/extern-inline.m4
@@ -0,0 +1,114 @@
+dnl 'extern inline' a la ISO C99.
+
+dnl Copyright 2012-2021 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_EXTERN_INLINE],
+[
+ AH_VERBATIM([extern_inline],
+[/* Please see the Gnulib manual for how to use these macros.
+
+ Suppress extern inline with HP-UX cc, as it appears to be broken; see
+ <https://lists.gnu.org/r/bug-texinfo/2013-02/msg00030.html>.
+
+ Suppress extern inline with Sun C in standards-conformance mode, as it
+ mishandles inline functions that call each other. E.g., for 'inline void f
+ (void) { } inline void g (void) { f (); }', c99 incorrectly complains
+ 'reference to static identifier "f" in extern inline function'.
+ This bug was observed with Sun C 5.12 SunOS_i386 2011/11/16.
+
+ Suppress extern inline (with or without __attribute__ ((__gnu_inline__)))
+ on configurations that mistakenly use 'static inline' to implement
+ functions or macros in standard C headers like <ctype.h>. For example,
+ if isdigit is mistakenly implemented via a static inline function,
+ a program containing an extern inline function that calls isdigit
+ may not work since the C standard prohibits extern inline functions
+ from calling static functions (ISO C 99 section 6.7.4.(3).
+ This bug is known to occur on:
+
+ OS X 10.8 and earlier; see:
+ https://lists.gnu.org/r/bug-gnulib/2012-12/msg00023.html
+
+ DragonFly; see
+ http://muscles.dragonflybsd.org/bulk/clang-master-potential/20141111_102002/logs/ah-tty-0.3.12.log
+
+ FreeBSD; see:
+ https://lists.gnu.org/r/bug-gnulib/2014-07/msg00104.html
+
+ OS X 10.9 has a macro __header_inline indicating the bug is fixed for C and
+ for clang but remains for g++; see <https://trac.macports.org/ticket/41033>.
+ Assume DragonFly and FreeBSD will be similar.
+
+ GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99
+ inline semantics, unless -fgnu89-inline is used. It defines a macro
+ __GNUC_STDC_INLINE__ to indicate this situation or a macro
+ __GNUC_GNU_INLINE__ to indicate the opposite situation.
+ GCC 4.2 with -std=c99 or -std=gnu99 implements the GNU C inline
+ semantics but warns, unless -fgnu89-inline is used:
+ warning: C99 inline functions are not supported; using GNU89
+ warning: to disable this warning use -fgnu89-inline or the gnu_inline function attribute
+ It defines a macro __GNUC_GNU_INLINE__ to indicate this situation.
+ */
+#if (((defined __APPLE__ && defined __MACH__) \
+ || defined __DragonFly__ || defined __FreeBSD__) \
+ && (defined __header_inline \
+ ? (defined __cplusplus && defined __GNUC_STDC_INLINE__ \
+ && ! defined __clang__) \
+ : ((! defined _DONT_USE_CTYPE_INLINE_ \
+ && (defined __GNUC__ || defined __cplusplus)) \
+ || (defined _FORTIFY_SOURCE && 0 < _FORTIFY_SOURCE \
+ && defined __GNUC__ && ! defined __cplusplus))))
+# define _GL_EXTERN_INLINE_STDHEADER_BUG
+#endif
+#if ((__GNUC__ \
+ ? defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__ \
+ : (199901L <= __STDC_VERSION__ \
+ && !defined __HP_cc \
+ && !defined __PGI \
+ && !(defined __SUNPRO_C && __STDC__))) \
+ && !defined _GL_EXTERN_INLINE_STDHEADER_BUG)
+# define _GL_INLINE inline
+# define _GL_EXTERN_INLINE extern inline
+# define _GL_EXTERN_INLINE_IN_USE
+#elif (2 < __GNUC__ + (7 <= __GNUC_MINOR__) && !defined __STRICT_ANSI__ \
+ && !defined _GL_EXTERN_INLINE_STDHEADER_BUG)
+# if defined __GNUC_GNU_INLINE__ && __GNUC_GNU_INLINE__
+ /* __gnu_inline__ suppresses a GCC 4.2 diagnostic. */
+# define _GL_INLINE extern inline __attribute__ ((__gnu_inline__))
+# else
+# define _GL_INLINE extern inline
+# endif
+# define _GL_EXTERN_INLINE extern
+# define _GL_EXTERN_INLINE_IN_USE
+#else
+# define _GL_INLINE static _GL_UNUSED
+# define _GL_EXTERN_INLINE static _GL_UNUSED
+#endif
+
+/* In GCC 4.6 (inclusive) to 5.1 (exclusive),
+ suppress bogus "no previous prototype for 'FOO'"
+ and "no previous declaration for 'FOO'" diagnostics,
+ when FOO is an inline function in the header; see
+ <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54113> and
+ <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63877>. */
+#if __GNUC__ == 4 && 6 <= __GNUC_MINOR__
+# if defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__
+# define _GL_INLINE_HEADER_CONST_PRAGMA
+# else
+# define _GL_INLINE_HEADER_CONST_PRAGMA \
+ _Pragma ("GCC diagnostic ignored \"-Wsuggest-attribute=const\"")
+# endif
+# define _GL_INLINE_HEADER_BEGIN \
+ _Pragma ("GCC diagnostic push") \
+ _Pragma ("GCC diagnostic ignored \"-Wmissing-prototypes\"") \
+ _Pragma ("GCC diagnostic ignored \"-Wmissing-declarations\"") \
+ _GL_INLINE_HEADER_CONST_PRAGMA
+# define _GL_INLINE_HEADER_END \
+ _Pragma ("GCC diagnostic pop")
+#else
+# define _GL_INLINE_HEADER_BEGIN
+# define _GL_INLINE_HEADER_END
+#endif])
+])
diff --git a/src/m4/gnulib-cache.m4 b/src/m4/gnulib-cache.m4
new file mode 100644
index 0000000..c9777fe
--- /dev/null
+++ b/src/m4/gnulib-cache.m4
@@ -0,0 +1,57 @@
+# Copyright (C) 2002-2021 Free Software Foundation, Inc.
+#
+# This file 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; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This file 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 for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this file. If not, see <https://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License,
+# this file may be distributed as part of a program that
+# contains a configuration script generated by Autoconf, under
+# the same distribution terms as the rest of that program.
+#
+# Generated by gnulib-tool.
+#
+# This file represents the specification of how gnulib-tool is used.
+# It acts as a cache: It is written and read by gnulib-tool.
+# In projects that use version control, this file is meant to be put under
+# version control, like the configure.ac and various Makefile.am files.
+
+
+# Specification in the form of a command-line invocation:
+# gnulib-tool --import \
+# --lib=libgnu \
+# --source-base=src/gnulib \
+# --m4-base=src/m4 \
+# --doc-base=doc \
+# --tests-base=tests \
+# --aux-dir=. \
+# --no-conditional-dependencies \
+# --no-libtool \
+# --macro-prefix=gl \
+# linkedhash-map
+
+# Specification in the form of a few gnulib-tool.m4 macro invocations:
+gl_LOCAL_DIR([])
+gl_MODULES([
+ linkedhash-map
+])
+gl_AVOID([])
+gl_SOURCE_BASE([src/gnulib])
+gl_M4_BASE([src/m4])
+gl_PO_BASE([])
+gl_DOC_BASE([doc])
+gl_TESTS_BASE([tests])
+gl_LIB([libgnu])
+gl_MAKEFILE_NAME([])
+gl_MACRO_PREFIX([gl])
+gl_PO_DOMAIN([])
+gl_WITNESS_C_MACRO([])
diff --git a/src/m4/gnulib-common.m4 b/src/m4/gnulib-common.m4
new file mode 100644
index 0000000..f2eff10
--- /dev/null
+++ b/src/m4/gnulib-common.m4
@@ -0,0 +1,727 @@
+# gnulib-common.m4 serial 63
+dnl Copyright (C) 2007-2021 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_PREREQ([2.62])
+
+# gl_COMMON
+# is expanded unconditionally through gnulib-tool magic.
+AC_DEFUN([gl_COMMON], [
+ dnl Use AC_REQUIRE here, so that the code is expanded once only.
+ AC_REQUIRE([gl_00GNULIB])
+ AC_REQUIRE([gl_COMMON_BODY])
+ AC_REQUIRE([gl_ZZGNULIB])
+])
+AC_DEFUN([gl_COMMON_BODY], [
+ AH_VERBATIM([_GL_GNUC_PREREQ],
+[/* True if the compiler says it groks GNU C version MAJOR.MINOR. */
+#if defined __GNUC__ && defined __GNUC_MINOR__
+# define _GL_GNUC_PREREQ(major, minor) \
+ ((major) < __GNUC__ + ((minor) <= __GNUC_MINOR__))
+#else
+# define _GL_GNUC_PREREQ(major, minor) 0
+#endif
+])
+ AH_VERBATIM([_Noreturn],
+[/* The _Noreturn keyword of C11. */
+#ifndef _Noreturn
+# if (defined __cplusplus \
+ && ((201103 <= __cplusplus && !(__GNUC__ == 4 && __GNUC_MINOR__ == 7)) \
+ || (defined _MSC_VER && 1900 <= _MSC_VER)) \
+ && 0)
+ /* [[noreturn]] is not practically usable, because with it the syntax
+ extern _Noreturn void func (...);
+ would not be valid; such a declaration would only be valid with 'extern'
+ and '_Noreturn' swapped, or without the 'extern' keyword. However, some
+ AIX system header files and several gnulib header files use precisely
+ this syntax with 'extern'. */
+# define _Noreturn [[noreturn]]
+# elif ((!defined __cplusplus || defined __clang__) \
+ && (201112 <= (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) \
+ || (!defined __STRICT_ANSI__ \
+ && (_GL_GNUC_PREREQ (4, 7) \
+ || (defined __apple_build_version__ \
+ ? 6000000 <= __apple_build_version__ \
+ : 3 < __clang_major__ + (5 <= __clang_minor__))))))
+ /* _Noreturn works as-is. */
+# elif _GL_GNUC_PREREQ (2, 8) || defined __clang__ || 0x5110 <= __SUNPRO_C
+# define _Noreturn __attribute__ ((__noreturn__))
+# elif 1200 <= (defined _MSC_VER ? _MSC_VER : 0)
+# define _Noreturn __declspec (noreturn)
+# else
+# define _Noreturn
+# endif
+#endif
+])
+ AH_VERBATIM([isoc99_inline],
+[/* Work around a bug in Apple GCC 4.0.1 build 5465: In C99 mode, it supports
+ the ISO C 99 semantics of 'extern inline' (unlike the GNU C semantics of
+ earlier versions), but does not display it by setting __GNUC_STDC_INLINE__.
+ __APPLE__ && __MACH__ test for Mac OS X.
+ __APPLE_CC__ tests for the Apple compiler and its version.
+ __STDC_VERSION__ tests for the C99 mode. */
+#if defined __APPLE__ && defined __MACH__ && __APPLE_CC__ >= 5465 && !defined __cplusplus && __STDC_VERSION__ >= 199901L && !defined __GNUC_STDC_INLINE__
+# define __GNUC_STDC_INLINE__ 1
+#endif])
+ AH_VERBATIM([attribute],
+[/* Attributes. */
+#if (defined __has_attribute \
+ && (!defined __clang_minor__ \
+ || 3 < __clang_major__ + (5 <= __clang_minor__)))
+# define _GL_HAS_ATTRIBUTE(attr) __has_attribute (__##attr##__)
+#else
+# define _GL_HAS_ATTRIBUTE(attr) _GL_ATTR_##attr
+# define _GL_ATTR_alloc_size _GL_GNUC_PREREQ (4, 3)
+# define _GL_ATTR_always_inline _GL_GNUC_PREREQ (3, 2)
+# define _GL_ATTR_artificial _GL_GNUC_PREREQ (4, 3)
+# define _GL_ATTR_cold _GL_GNUC_PREREQ (4, 3)
+# define _GL_ATTR_const _GL_GNUC_PREREQ (2, 95)
+# define _GL_ATTR_deprecated _GL_GNUC_PREREQ (3, 1)
+# define _GL_ATTR_diagnose_if 0
+# define _GL_ATTR_error _GL_GNUC_PREREQ (4, 3)
+# define _GL_ATTR_externally_visible _GL_GNUC_PREREQ (4, 1)
+# define _GL_ATTR_fallthrough _GL_GNUC_PREREQ (7, 0)
+# define _GL_ATTR_format _GL_GNUC_PREREQ (2, 7)
+# define _GL_ATTR_leaf _GL_GNUC_PREREQ (4, 6)
+# ifdef _ICC
+# define _GL_ATTR_may_alias 0
+# else
+# define _GL_ATTR_may_alias _GL_GNUC_PREREQ (3, 3)
+# endif
+# define _GL_ATTR_malloc _GL_GNUC_PREREQ (3, 0)
+# define _GL_ATTR_noinline _GL_GNUC_PREREQ (3, 1)
+# define _GL_ATTR_nonnull _GL_GNUC_PREREQ (3, 3)
+# define _GL_ATTR_nonstring _GL_GNUC_PREREQ (8, 0)
+# define _GL_ATTR_nothrow _GL_GNUC_PREREQ (3, 3)
+# define _GL_ATTR_packed _GL_GNUC_PREREQ (2, 7)
+# define _GL_ATTR_pure _GL_GNUC_PREREQ (2, 96)
+# define _GL_ATTR_returns_nonnull _GL_GNUC_PREREQ (4, 9)
+# define _GL_ATTR_sentinel _GL_GNUC_PREREQ (4, 0)
+# define _GL_ATTR_unused _GL_GNUC_PREREQ (2, 7)
+# define _GL_ATTR_warn_unused_result _GL_GNUC_PREREQ (3, 4)
+#endif
+
+]dnl There is no _GL_ATTRIBUTE_ALIGNED; use stdalign's _Alignas instead.
+[
+#if _GL_HAS_ATTRIBUTE (alloc_size)
+# define _GL_ATTRIBUTE_ALLOC_SIZE(args) __attribute__ ((__alloc_size__ args))
+#else
+# define _GL_ATTRIBUTE_ALLOC_SIZE(args)
+#endif
+
+#if _GL_HAS_ATTRIBUTE (always_inline)
+# define _GL_ATTRIBUTE_ALWAYS_INLINE __attribute__ ((__always_inline__))
+#else
+# define _GL_ATTRIBUTE_ALWAYS_INLINE
+#endif
+
+#if _GL_HAS_ATTRIBUTE (artificial)
+# define _GL_ATTRIBUTE_ARTIFICIAL __attribute__ ((__artificial__))
+#else
+# define _GL_ATTRIBUTE_ARTIFICIAL
+#endif
+
+/* Avoid __attribute__ ((cold)) on MinGW; see thread starting at
+ <https://lists.gnu.org/r/emacs-devel/2019-04/msg01152.html>.
+ Also, Oracle Studio 12.6 requires 'cold' not '__cold__'. */
+#if _GL_HAS_ATTRIBUTE (cold) && !defined __MINGW32__
+# ifndef __SUNPRO_C
+# define _GL_ATTRIBUTE_COLD __attribute__ ((__cold__))
+# else
+# define _GL_ATTRIBUTE_COLD __attribute__ ((cold))
+# endif
+#else
+# define _GL_ATTRIBUTE_COLD
+#endif
+
+#if _GL_HAS_ATTRIBUTE (const)
+# define _GL_ATTRIBUTE_CONST __attribute__ ((__const__))
+#else
+# define _GL_ATTRIBUTE_CONST
+#endif
+
+#if 201710L < __STDC_VERSION__
+# define _GL_ATTRIBUTE_DEPRECATED [[__deprecated__]]
+#elif _GL_HAS_ATTRIBUTE (deprecated)
+# define _GL_ATTRIBUTE_DEPRECATED __attribute__ ((__deprecated__))
+#else
+# define _GL_ATTRIBUTE_DEPRECATED
+#endif
+
+#if _GL_HAS_ATTRIBUTE (error)
+# define _GL_ATTRIBUTE_ERROR(msg) __attribute__ ((__error__ (msg)))
+# define _GL_ATTRIBUTE_WARNING(msg) __attribute__ ((__warning__ (msg)))
+#elif _GL_HAS_ATTRIBUTE (diagnose_if)
+# define _GL_ATTRIBUTE_ERROR(msg) __attribute__ ((__diagnose_if__ (1, msg, "error")))
+# define _GL_ATTRIBUTE_WARNING(msg) __attribute__ ((__diagnose_if__ (1, msg, "warning")))
+#else
+# define _GL_ATTRIBUTE_ERROR(msg)
+# define _GL_ATTRIBUTE_WARNING(msg)
+#endif
+
+#if _GL_HAS_ATTRIBUTE (externally_visible)
+# define _GL_ATTRIBUTE_EXTERNALLY_VISIBLE __attribute__ ((externally_visible))
+#else
+# define _GL_ATTRIBUTE_EXTERNALLY_VISIBLE
+#endif
+
+/* FALLTHROUGH is special, because it always expands to something. */
+#if 201710L < __STDC_VERSION__
+# define _GL_ATTRIBUTE_FALLTHROUGH [[__fallthrough__]]
+#elif _GL_HAS_ATTRIBUTE (fallthrough)
+# define _GL_ATTRIBUTE_FALLTHROUGH __attribute__ ((__fallthrough__))
+#else
+# define _GL_ATTRIBUTE_FALLTHROUGH ((void) 0)
+#endif
+
+#if _GL_HAS_ATTRIBUTE (format)
+# define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec))
+#else
+# define _GL_ATTRIBUTE_FORMAT(spec)
+#endif
+
+#if _GL_HAS_ATTRIBUTE (leaf)
+# define _GL_ATTRIBUTE_LEAF __attribute__ ((__leaf__))
+#else
+# define _GL_ATTRIBUTE_LEAF
+#endif
+
+/* Oracle Studio 12.6 mishandles may_alias despite __has_attribute OK. */
+#if _GL_HAS_ATTRIBUTE (may_alias) && !defined __SUNPRO_C
+# define _GL_ATTRIBUTE_MAY_ALIAS __attribute__ ((__may_alias__))
+#else
+# define _GL_ATTRIBUTE_MAY_ALIAS
+#endif
+
+#if 201710L < __STDC_VERSION__
+# define _GL_ATTRIBUTE_MAYBE_UNUSED [[__maybe_unused__]]
+#elif _GL_HAS_ATTRIBUTE (unused)
+# define _GL_ATTRIBUTE_MAYBE_UNUSED __attribute__ ((__unused__))
+#else
+# define _GL_ATTRIBUTE_MAYBE_UNUSED
+#endif
+/* Earlier spellings of this macro. */
+#define _GL_UNUSED _GL_ATTRIBUTE_MAYBE_UNUSED
+#define _UNUSED_PARAMETER_ _GL_ATTRIBUTE_MAYBE_UNUSED
+
+#if _GL_HAS_ATTRIBUTE (malloc)
+# define _GL_ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
+#else
+# define _GL_ATTRIBUTE_MALLOC
+#endif
+
+#if 201710L < __STDC_VERSION__
+# define _GL_ATTRIBUTE_NODISCARD [[__nodiscard__]]
+#elif _GL_HAS_ATTRIBUTE (warn_unused_result)
+# define _GL_ATTRIBUTE_NODISCARD __attribute__ ((__warn_unused_result__))
+#else
+# define _GL_ATTRIBUTE_NODISCARD
+#endif
+
+#if _GL_HAS_ATTRIBUTE (noinline)
+# define _GL_ATTRIBUTE_NOINLINE __attribute__ ((__noinline__))
+#else
+# define _GL_ATTRIBUTE_NOINLINE
+#endif
+
+#if _GL_HAS_ATTRIBUTE (nonnull)
+# define _GL_ATTRIBUTE_NONNULL(args) __attribute__ ((__nonnull__ args))
+#else
+# define _GL_ATTRIBUTE_NONNULL(args)
+#endif
+
+#if _GL_HAS_ATTRIBUTE (nonstring)
+# define _GL_ATTRIBUTE_NONSTRING __attribute__ ((__nonstring__))
+#else
+# define _GL_ATTRIBUTE_NONSTRING
+#endif
+
+/* There is no _GL_ATTRIBUTE_NORETURN; use _Noreturn instead. */
+
+#if _GL_HAS_ATTRIBUTE (nothrow) && !defined __cplusplus
+# define _GL_ATTRIBUTE_NOTHROW __attribute__ ((__nothrow__))
+#else
+# define _GL_ATTRIBUTE_NOTHROW
+#endif
+
+#if _GL_HAS_ATTRIBUTE (packed)
+# define _GL_ATTRIBUTE_PACKED __attribute__ ((__packed__))
+#else
+# define _GL_ATTRIBUTE_PACKED
+#endif
+
+#if _GL_HAS_ATTRIBUTE (pure)
+# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__))
+#else
+# define _GL_ATTRIBUTE_PURE
+#endif
+
+#if _GL_HAS_ATTRIBUTE (returns_nonnull)
+# define _GL_ATTRIBUTE_RETURNS_NONNULL __attribute__ ((__returns_nonnull__))
+#else
+# define _GL_ATTRIBUTE_RETURNS_NONNULL
+#endif
+
+#if _GL_HAS_ATTRIBUTE (sentinel)
+# define _GL_ATTRIBUTE_SENTINEL(pos) __attribute__ ((__sentinel__ pos))
+#else
+# define _GL_ATTRIBUTE_SENTINEL(pos)
+#endif
+
+]dnl There is no _GL_ATTRIBUTE_VISIBILITY; see m4/visibility.m4 instead.
+[
+/* To support C++ as well as C, use _GL_UNUSED_LABEL with trailing ';'. */
+#if !defined __cplusplus || _GL_GNUC_PREREQ (4, 5)
+# define _GL_UNUSED_LABEL _GL_ATTRIBUTE_MAYBE_UNUSED
+#else
+# define _GL_UNUSED_LABEL
+#endif
+])
+ AH_VERBATIM([async_safe],
+[/* The _GL_ASYNC_SAFE marker should be attached to functions that are
+ signal handlers (for signals other than SIGABRT, SIGPIPE) or can be
+ invoked from such signal handlers. Such functions have some restrictions:
+ * All functions that it calls should be marked _GL_ASYNC_SAFE as well,
+ or should be listed as async-signal-safe in POSIX
+ <https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04>
+ section 2.4.3. Note that malloc(), sprintf(), and fwrite(), in
+ particular, are NOT async-signal-safe.
+ * All memory locations (variables and struct fields) that these functions
+ access must be marked 'volatile'. This holds for both read and write
+ accesses. Otherwise the compiler might optimize away stores to and
+ reads from such locations that occur in the program, depending on its
+ data flow analysis. For example, when the program contains a loop
+ that is intended to inspect a variable set from within a signal handler
+ while (!signal_occurred)
+ ;
+ the compiler is allowed to transform this into an endless loop if the
+ variable 'signal_occurred' is not declared 'volatile'.
+ Additionally, recall that:
+ * A signal handler should not modify errno (except if it is a handler
+ for a fatal signal and ends by raising the same signal again, thus
+ provoking the termination of the process). If it invokes a function
+ that may clobber errno, it needs to save and restore the value of
+ errno. */
+#define _GL_ASYNC_SAFE
+])
+ AH_VERBATIM([micro_optimizations],
+[/* _GL_CMP (n1, n2) performs a three-valued comparison on n1 vs. n2, where
+ n1 and n2 are expressions without side effects, that evaluate to real
+ numbers (excluding NaN).
+ It returns
+ 1 if n1 > n2
+ 0 if n1 == n2
+ -1 if n1 < n2
+ The naïve code (n1 > n2 ? 1 : n1 < n2 ? -1 : 0) produces a conditional
+ jump with nearly all GCC versions up to GCC 10.
+ This variant (n1 < n2 ? -1 : n1 > n2) produces a conditional with many
+ GCC versions up to GCC 9.
+ The better code (n1 > n2) - (n1 < n2) from Hacker's Delight § 2-9
+ avoids conditional jumps in all GCC versions >= 3.4. */
+#define _GL_CMP(n1, n2) (((n1) > (n2)) - ((n1) < (n2)))
+])
+ dnl Hint which direction to take regarding cross-compilation guesses:
+ dnl When a user installs a program on a platform they are not intimately
+ dnl familiar with, --enable-cross-guesses=conservative is the appropriate
+ dnl choice. It implements the "If we don't know, assume the worst" principle.
+ dnl However, when an operating system developer (on a platform which is not
+ dnl yet known to gnulib) builds packages for their platform, they want to
+ dnl expose, not hide, possible platform bugs; in this case,
+ dnl --enable-cross-guesses=risky is the appropriate choice.
+ dnl Sets the variables
+ dnl gl_cross_guess_normal (to be used when 'yes' is good and 'no' is bad),
+ dnl gl_cross_guess_inverted (to be used when 'no' is good and 'yes' is bad).
+ AC_ARG_ENABLE([cross-guesses],
+ [AS_HELP_STRING([--enable-cross-guesses={conservative|risky}],
+ [specify policy for cross-compilation guesses])],
+ [if test "x$enableval" != xconservative && test "x$enableval" != xrisky; then
+ AC_MSG_WARN([invalid argument supplied to --enable-cross-guesses])
+ enableval=conservative
+ fi
+ gl_cross_guesses="$enableval"],
+ [gl_cross_guesses=conservative])
+ if test $gl_cross_guesses = risky; then
+ gl_cross_guess_normal="guessing yes"
+ gl_cross_guess_inverted="guessing no"
+ else
+ gl_cross_guess_normal="guessing no"
+ gl_cross_guess_inverted="guessing yes"
+ fi
+ dnl Preparation for running test programs:
+ dnl Tell glibc to write diagnostics from -D_FORTIFY_SOURCE=2 to stderr, not
+ dnl to /dev/tty, so they can be redirected to log files. Such diagnostics
+ dnl arise e.g., in the macros gl_PRINTF_DIRECTIVE_N, gl_SNPRINTF_DIRECTIVE_N.
+ LIBC_FATAL_STDERR_=1
+ export LIBC_FATAL_STDERR_
+])
+
+# gl_MODULE_INDICATOR_CONDITION
+# expands to a C preprocessor expression that evaluates to 1 or 0, depending
+# whether a gnulib module that has been requested shall be considered present
+# or not.
+m4_define([gl_MODULE_INDICATOR_CONDITION], [1])
+
+# gl_MODULE_INDICATOR_SET_VARIABLE([modulename])
+# sets the shell variable that indicates the presence of the given module to
+# a C preprocessor expression that will evaluate to 1.
+AC_DEFUN([gl_MODULE_INDICATOR_SET_VARIABLE],
+[
+ gl_MODULE_INDICATOR_SET_VARIABLE_AUX(
+ [GNULIB_[]m4_translit([[$1]],
+ [abcdefghijklmnopqrstuvwxyz./-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])],
+ [gl_MODULE_INDICATOR_CONDITION])
+])
+
+# gl_MODULE_INDICATOR_SET_VARIABLE_AUX([variable])
+# modifies the shell variable to include the gl_MODULE_INDICATOR_CONDITION.
+# The shell variable's value is a C preprocessor expression that evaluates
+# to 0 or 1.
+AC_DEFUN([gl_MODULE_INDICATOR_SET_VARIABLE_AUX],
+[
+ m4_if(m4_defn([gl_MODULE_INDICATOR_CONDITION]), [1],
+ [
+ dnl Simplify the expression VALUE || 1 to 1.
+ $1=1
+ ],
+ [gl_MODULE_INDICATOR_SET_VARIABLE_AUX_OR([$1],
+ [gl_MODULE_INDICATOR_CONDITION])])
+])
+
+# gl_MODULE_INDICATOR_SET_VARIABLE_AUX_OR([variable], [condition])
+# modifies the shell variable to include the given condition. The shell
+# variable's value is a C preprocessor expression that evaluates to 0 or 1.
+AC_DEFUN([gl_MODULE_INDICATOR_SET_VARIABLE_AUX_OR],
+[
+ dnl Simplify the expression 1 || CONDITION to 1.
+ if test "$[]$1" != 1; then
+ dnl Simplify the expression 0 || CONDITION to CONDITION.
+ if test "$[]$1" = 0; then
+ $1=$2
+ else
+ $1="($[]$1 || $2)"
+ fi
+ fi
+])
+
+# gl_MODULE_INDICATOR([modulename])
+# defines a C macro indicating the presence of the given module
+# in a location where it can be used.
+# | Value | Value |
+# | in lib/ | in tests/ |
+# --------------------------------------------+---------+-----------+
+# Module present among main modules: | 1 | 1 |
+# --------------------------------------------+---------+-----------+
+# Module present among tests-related modules: | 0 | 1 |
+# --------------------------------------------+---------+-----------+
+# Module not present at all: | 0 | 0 |
+# --------------------------------------------+---------+-----------+
+AC_DEFUN([gl_MODULE_INDICATOR],
+[
+ AC_DEFINE_UNQUOTED([GNULIB_]m4_translit([[$1]],
+ [abcdefghijklmnopqrstuvwxyz./-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ___]),
+ [gl_MODULE_INDICATOR_CONDITION],
+ [Define to a C preprocessor expression that evaluates to 1 or 0,
+ depending whether the gnulib module $1 shall be considered present.])
+])
+
+# gl_MODULE_INDICATOR_FOR_TESTS([modulename])
+# defines a C macro indicating the presence of the given module
+# in lib or tests. This is useful to determine whether the module
+# should be tested.
+# | Value | Value |
+# | in lib/ | in tests/ |
+# --------------------------------------------+---------+-----------+
+# Module present among main modules: | 1 | 1 |
+# --------------------------------------------+---------+-----------+
+# Module present among tests-related modules: | 1 | 1 |
+# --------------------------------------------+---------+-----------+
+# Module not present at all: | 0 | 0 |
+# --------------------------------------------+---------+-----------+
+AC_DEFUN([gl_MODULE_INDICATOR_FOR_TESTS],
+[
+ AC_DEFINE([GNULIB_TEST_]m4_translit([[$1]],
+ [abcdefghijklmnopqrstuvwxyz./-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ___]), [1],
+ [Define to 1 when the gnulib module $1 should be tested.])
+])
+
+# gl_ASSERT_NO_GNULIB_POSIXCHECK
+# asserts that there will never be a need to #define GNULIB_POSIXCHECK.
+# and thereby enables an optimization of configure and config.h.
+# Used by Emacs.
+AC_DEFUN([gl_ASSERT_NO_GNULIB_POSIXCHECK],
+[
+ dnl Override gl_WARN_ON_USE_PREPARE.
+ dnl But hide this definition from 'aclocal'.
+ AC_DEFUN([gl_W][ARN_ON_USE_PREPARE], [])
+])
+
+# gl_ASSERT_NO_GNULIB_TESTS
+# asserts that there will be no gnulib tests in the scope of the configure.ac
+# and thereby enables an optimization of config.h.
+# Used by Emacs.
+AC_DEFUN([gl_ASSERT_NO_GNULIB_TESTS],
+[
+ dnl Override gl_MODULE_INDICATOR_FOR_TESTS.
+ AC_DEFUN([gl_MODULE_INDICATOR_FOR_TESTS], [])
+])
+
+# Test whether <features.h> exists.
+# Set HAVE_FEATURES_H.
+AC_DEFUN([gl_FEATURES_H],
+[
+ AC_CHECK_HEADERS_ONCE([features.h])
+ if test $ac_cv_header_features_h = yes; then
+ HAVE_FEATURES_H=1
+ else
+ HAVE_FEATURES_H=0
+ fi
+ AC_SUBST([HAVE_FEATURES_H])
+])
+
+# gl_PROG_CC_C99
+# Modifies the value of the shell variable CC in an attempt to make $CC
+# understand ISO C99 source code.
+AC_DEFUN([gl_PROG_CC_C99],
+[
+ dnl Just use AC_PROG_CC_C99.
+ dnl When AC_PROG_CC_C99 and AC_PROG_CC_STDC are used together, the substituted
+ dnl value of CC will contain the C99 enabling options twice. But this is only
+ dnl a cosmetic problem.
+ dnl With Autoconf >= 2.70, use AC_PROG_CC since it implies AC_PROG_CC_C99;
+ dnl this avoids a "warning: The macro `AC_PROG_CC_C99' is obsolete."
+ m4_version_prereq([2.70],
+ [AC_REQUIRE([AC_PROG_CC])],
+ [AC_REQUIRE([AC_PROG_CC_C99])])
+])
+
+# gl_PROG_AR_RANLIB
+# Determines the values for AR, ARFLAGS, RANLIB that fit with the compiler.
+# The user can set the variables AR, ARFLAGS, RANLIB if he wants to override
+# the values.
+AC_DEFUN([gl_PROG_AR_RANLIB],
+[
+ dnl Minix 3 comes with two toolchains: The Amsterdam Compiler Kit compiler
+ dnl as "cc", and GCC as "gcc". They have different object file formats and
+ dnl library formats. In particular, the GNU binutils programs ar and ranlib
+ dnl produce libraries that work only with gcc, not with cc.
+ AC_REQUIRE([AC_PROG_CC])
+ dnl The '][' hides this use from 'aclocal'.
+ AC_BEFORE([$0], [A][M_PROG_AR])
+ AC_CACHE_CHECK([for Minix Amsterdam compiler], [gl_cv_c_amsterdam_compiler],
+ [
+ AC_EGREP_CPP([Amsterdam],
+ [
+#ifdef __ACK__
+Amsterdam
+#endif
+ ],
+ [gl_cv_c_amsterdam_compiler=yes],
+ [gl_cv_c_amsterdam_compiler=no])
+ ])
+
+ dnl Don't compete with AM_PROG_AR's decision about AR/ARFLAGS if we are not
+ dnl building with __ACK__.
+ if test $gl_cv_c_amsterdam_compiler = yes; then
+ if test -z "$AR"; then
+ AR='cc -c.a'
+ fi
+ if test -z "$ARFLAGS"; then
+ ARFLAGS='-o'
+ fi
+ else
+ dnl AM_PROG_AR was added in automake v1.11.2. AM_PROG_AR does not AC_SUBST
+ dnl ARFLAGS variable (it is filed into Makefile.in directly by automake
+ dnl script on-demand, if not specified by ./configure of course).
+ dnl Don't AC_REQUIRE the AM_PROG_AR otherwise the code for __ACK__ above
+ dnl will be ignored. Also, pay attention to call AM_PROG_AR in else block
+ dnl because AM_PROG_AR is written so it could re-set AR variable even for
+ dnl __ACK__. It may seem like its easier to avoid calling the macro here,
+ dnl but we need to AC_SUBST both AR/ARFLAGS (thus those must have some good
+ dnl default value and automake should usually know them).
+ dnl
+ dnl The '][' hides this use from 'aclocal'.
+ m4_ifdef([A][M_PROG_AR], [A][M_PROG_AR], [:])
+ fi
+
+ dnl In case the code above has not helped with setting AR/ARFLAGS, use
+ dnl Automake-documented default values for AR and ARFLAGS, but prefer
+ dnl ${host}-ar over ar (useful for cross-compiling).
+ AC_CHECK_TOOL([AR], [ar], [ar])
+ if test -z "$ARFLAGS"; then
+ ARFLAGS='cr'
+ fi
+
+ AC_SUBST([AR])
+ AC_SUBST([ARFLAGS])
+ if test -z "$RANLIB"; then
+ if test $gl_cv_c_amsterdam_compiler = yes; then
+ RANLIB=':'
+ else
+ dnl Use the ranlib program if it is available.
+ AC_PROG_RANLIB
+ fi
+ fi
+ AC_SUBST([RANLIB])
+])
+
+# AC_C_RESTRICT
+# This definition is copied from post-2.70 Autoconf and overrides the
+# AC_C_RESTRICT macro from autoconf 2.60..2.70.
+m4_version_prereq([2.70.1], [], [
+AC_DEFUN([AC_C_RESTRICT],
+[AC_CACHE_CHECK([for C/C++ restrict keyword], [ac_cv_c_restrict],
+ [ac_cv_c_restrict=no
+ # Put '__restrict__' first, to avoid problems with glibc and non-GCC; see:
+ # https://lists.gnu.org/archive/html/bug-autoconf/2016-02/msg00006.html
+ # Put 'restrict' last, because C++ lacks it.
+ for ac_kw in __restrict__ __restrict _Restrict restrict; do
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[typedef int *int_ptr;
+ int foo (int_ptr $ac_kw ip) { return ip[0]; }
+ int bar (int [$ac_kw]); /* Catch GCC bug 14050. */
+ int bar (int ip[$ac_kw]) { return ip[0]; }
+ ]],
+ [[int s[1];
+ int *$ac_kw t = s;
+ t[0] = 0;
+ return foo (t) + bar (t);
+ ]])],
+ [ac_cv_c_restrict=$ac_kw])
+ test "$ac_cv_c_restrict" != no && break
+ done
+ ])
+ AH_VERBATIM([restrict],
+[/* Define to the equivalent of the C99 'restrict' keyword, or to
+ nothing if this is not supported. Do not define if restrict is
+ supported only directly. */
+#undef restrict
+/* Work around a bug in older versions of Sun C++, which did not
+ #define __restrict__ or support _Restrict or __restrict__
+ even though the corresponding Sun C compiler ended up with
+ "#define restrict _Restrict" or "#define restrict __restrict__"
+ in the previous line. This workaround can be removed once
+ we assume Oracle Developer Studio 12.5 (2016) or later. */
+#if defined __SUNPRO_CC && !defined __RESTRICT && !defined __restrict__
+# define _Restrict
+# define __restrict__
+#endif])
+ case $ac_cv_c_restrict in
+ restrict) ;;
+ no) AC_DEFINE([restrict], []) ;;
+ *) AC_DEFINE_UNQUOTED([restrict], [$ac_cv_c_restrict]) ;;
+ esac
+])# AC_C_RESTRICT
+])
+
+# gl_BIGENDIAN
+# is like AC_C_BIGENDIAN, except that it can be AC_REQUIREd.
+# Note that AC_REQUIRE([AC_C_BIGENDIAN]) does not work reliably because some
+# macros invoke AC_C_BIGENDIAN with arguments.
+AC_DEFUN([gl_BIGENDIAN],
+[
+ AC_C_BIGENDIAN
+])
+
+# A temporary file descriptor.
+# Must be less than 10, because dash 0.5.8 does not support redirections
+# with multi-digit file descriptors.
+m4_define([GL_TMP_FD], 9)
+
+# gl_SILENT(command)
+# executes command, but without the normal configure output.
+# This is useful when you want to invoke AC_CACHE_CHECK (or AC_CHECK_FUNC etc.)
+# inside another AC_CACHE_CHECK.
+AC_DEFUN([gl_SILENT],
+[
+ exec GL_TMP_FD>&AS_MESSAGE_FD AS_MESSAGE_FD>/dev/null
+ $1
+ exec AS_MESSAGE_FD>&GL_TMP_FD GL_TMP_FD>&-
+])
+
+# gl_CACHE_VAL_SILENT(cache-id, command-to-set-it)
+# is like AC_CACHE_VAL(cache-id, command-to-set-it), except that it does not
+# output a spurious "(cached)" mark in the midst of other configure output.
+# This macro should be used instead of AC_CACHE_VAL when it is not surrounded
+# by an AC_MSG_CHECKING/AC_MSG_RESULT pair.
+AC_DEFUN([gl_CACHE_VAL_SILENT],
+[
+ gl_SILENT([
+ AC_CACHE_VAL([$1], [$2])
+ ])
+])
+
+dnl Expands to some code for use in .c programs that, on native Windows, defines
+dnl the Microsoft deprecated alias function names to the underscore-prefixed
+dnl actual function names. With this macro, these function names are available
+dnl without linking with '-loldnames' and without generating warnings.
+dnl Usage: Use it after all system header files are included.
+dnl #include <...>
+dnl #include <...>
+dnl ]GL_MDA_DEFINES[
+dnl ...
+AC_DEFUN([GL_MDA_DEFINES],[
+AC_REQUIRE([_GL_MDA_DEFINES])
+[$gl_mda_defines]
+])
+AC_DEFUN([_GL_MDA_DEFINES],
+[gl_mda_defines='
+#if defined _WIN32 && !defined __CYGWIN__
+#define access _access
+#define chdir _chdir
+#define chmod _chmod
+#define close _close
+#define creat _creat
+#define dup _dup
+#define dup2 _dup2
+#define ecvt _ecvt
+#define execl _execl
+#define execle _execle
+#define execlp _execlp
+#define execv _execv
+#define execve _execve
+#define execvp _execvp
+#define execvpe _execvpe
+#define fcloseall _fcloseall
+#define fcvt _fcvt
+#define fdopen _fdopen
+#define fileno _fileno
+#define gcvt _gcvt
+#define getcwd _getcwd
+#define getpid _getpid
+#define getw _getw
+#define isatty _isatty
+#define j0 _j0
+#define j1 _j1
+#define jn _jn
+#define lfind _lfind
+#define lsearch _lsearch
+#define lseek _lseek
+#define memccpy _memccpy
+#define mkdir _mkdir
+#define mktemp _mktemp
+#define open _open
+#define putenv _putenv
+#define putw _putw
+#define read _read
+#define rmdir _rmdir
+#define strdup _strdup
+#define swab _swab
+#define tempnam _tempnam
+#define tzset _tzset
+#define umask _umask
+#define unlink _unlink
+#define utime _utime
+#define wcsdup _wcsdup
+#define write _write
+#define y0 _y0
+#define y1 _y1
+#define yn _yn
+#endif
+'
+])
diff --git a/src/m4/gnulib-comp.m4 b/src/m4/gnulib-comp.m4
new file mode 100644
index 0000000..4534c72
--- /dev/null
+++ b/src/m4/gnulib-comp.m4
@@ -0,0 +1,261 @@
+# DO NOT EDIT! GENERATED AUTOMATICALLY!
+# Copyright (C) 2002-2021 Free Software Foundation, Inc.
+#
+# This file 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; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This file 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 for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this file. If not, see <https://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License,
+# this file may be distributed as part of a program that
+# contains a configuration script generated by Autoconf, under
+# the same distribution terms as the rest of that program.
+#
+# Generated by gnulib-tool.
+#
+# This file represents the compiled summary of the specification in
+# gnulib-cache.m4. It lists the computed macro invocations that need
+# to be invoked from configure.ac.
+# In projects that use version control, this file can be treated like
+# other built files.
+
+
+# This macro should be invoked from ./configure.ac, in the section
+# "Checks for programs", right after AC_PROG_CC, and certainly before
+# any checks for libraries, header files, types and library functions.
+AC_DEFUN([gl_EARLY],
+[
+ m4_pattern_forbid([^gl_[A-Z]])dnl the gnulib macro namespace
+ m4_pattern_allow([^gl_ES$])dnl a valid locale name
+ m4_pattern_allow([^gl_LIBOBJS$])dnl a variable
+ m4_pattern_allow([^gl_LTLIBOBJS$])dnl a variable
+
+ # Pre-early section.
+ AC_REQUIRE([gl_PROG_AR_RANLIB])
+
+ # Code from module absolute-header:
+ # Code from module attribute:
+ # Code from module c99:
+ # Code from module extern-inline:
+ # Code from module include_next:
+ # Code from module limits-h:
+ # Code from module linkedhash-map:
+ # Code from module map:
+ # Code from module multiarch:
+ # Code from module size_max:
+ # Code from module ssize_t:
+ # Code from module std-gnu11:
+ # Code from module stdbool:
+ # Code from module stdint:
+ # Code from module sys_types:
+ # Code from module xsize:
+])
+
+# This macro should be invoked from ./configure.ac, in the section
+# "Check for header files, types and library functions".
+AC_DEFUN([gl_INIT],
+[
+ AM_CONDITIONAL([GL_COND_LIBTOOL], [false])
+ gl_cond_libtool=false
+ gl_libdeps=
+ gl_ltlibdeps=
+ gl_m4_base='src/m4'
+ m4_pushdef([AC_LIBOBJ], m4_defn([gl_LIBOBJ]))
+ m4_pushdef([AC_REPLACE_FUNCS], m4_defn([gl_REPLACE_FUNCS]))
+ m4_pushdef([AC_LIBSOURCES], m4_defn([gl_LIBSOURCES]))
+ m4_pushdef([gl_LIBSOURCES_LIST], [])
+ m4_pushdef([gl_LIBSOURCES_DIR], [])
+ gl_COMMON
+ gl_source_base='src/gnulib'
+ AC_REQUIRE([gl_EXTERN_INLINE])
+ gl_LIMITS_H
+ gl_MULTIARCH
+ gl_SIZE_MAX
+ gt_TYPE_SSIZE_T
+ AM_STDBOOL_H
+ gl_STDINT_H
+ gl_SYS_TYPES_H
+ AC_PROG_MKDIR_P
+ gl_XSIZE
+ # End of code from modules
+ m4_ifval(gl_LIBSOURCES_LIST, [
+ m4_syscmd([test ! -d ]m4_defn([gl_LIBSOURCES_DIR])[ ||
+ for gl_file in ]gl_LIBSOURCES_LIST[ ; do
+ if test ! -r ]m4_defn([gl_LIBSOURCES_DIR])[/$gl_file ; then
+ echo "missing file ]m4_defn([gl_LIBSOURCES_DIR])[/$gl_file" >&2
+ exit 1
+ fi
+ done])dnl
+ m4_if(m4_sysval, [0], [],
+ [AC_FATAL([expected source file, required through AC_LIBSOURCES, not found])])
+ ])
+ m4_popdef([gl_LIBSOURCES_DIR])
+ m4_popdef([gl_LIBSOURCES_LIST])
+ m4_popdef([AC_LIBSOURCES])
+ m4_popdef([AC_REPLACE_FUNCS])
+ m4_popdef([AC_LIBOBJ])
+ AC_CONFIG_COMMANDS_PRE([
+ gl_libobjs=
+ gl_ltlibobjs=
+ if test -n "$gl_LIBOBJS"; then
+ # Remove the extension.
+ sed_drop_objext='s/\.o$//;s/\.obj$//'
+ for i in `for i in $gl_LIBOBJS; do echo "$i"; done | sed -e "$sed_drop_objext" | sort | uniq`; do
+ gl_libobjs="$gl_libobjs $i.$ac_objext"
+ gl_ltlibobjs="$gl_ltlibobjs $i.lo"
+ done
+ fi
+ AC_SUBST([gl_LIBOBJS], [$gl_libobjs])
+ AC_SUBST([gl_LTLIBOBJS], [$gl_ltlibobjs])
+ ])
+ gltests_libdeps=
+ gltests_ltlibdeps=
+ m4_pushdef([AC_LIBOBJ], m4_defn([gltests_LIBOBJ]))
+ m4_pushdef([AC_REPLACE_FUNCS], m4_defn([gltests_REPLACE_FUNCS]))
+ m4_pushdef([AC_LIBSOURCES], m4_defn([gltests_LIBSOURCES]))
+ m4_pushdef([gltests_LIBSOURCES_LIST], [])
+ m4_pushdef([gltests_LIBSOURCES_DIR], [])
+ gl_COMMON
+ gl_source_base='tests'
+changequote(,)dnl
+ gltests_WITNESS=IN_`echo "${PACKAGE-$PACKAGE_TARNAME}" | LC_ALL=C tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ | LC_ALL=C sed -e 's/[^A-Z0-9_]/_/g'`_GNULIB_TESTS
+changequote([, ])dnl
+ AC_SUBST([gltests_WITNESS])
+ gl_module_indicator_condition=$gltests_WITNESS
+ m4_pushdef([gl_MODULE_INDICATOR_CONDITION], [$gl_module_indicator_condition])
+ m4_popdef([gl_MODULE_INDICATOR_CONDITION])
+ m4_ifval(gltests_LIBSOURCES_LIST, [
+ m4_syscmd([test ! -d ]m4_defn([gltests_LIBSOURCES_DIR])[ ||
+ for gl_file in ]gltests_LIBSOURCES_LIST[ ; do
+ if test ! -r ]m4_defn([gltests_LIBSOURCES_DIR])[/$gl_file ; then
+ echo "missing file ]m4_defn([gltests_LIBSOURCES_DIR])[/$gl_file" >&2
+ exit 1
+ fi
+ done])dnl
+ m4_if(m4_sysval, [0], [],
+ [AC_FATAL([expected source file, required through AC_LIBSOURCES, not found])])
+ ])
+ m4_popdef([gltests_LIBSOURCES_DIR])
+ m4_popdef([gltests_LIBSOURCES_LIST])
+ m4_popdef([AC_LIBSOURCES])
+ m4_popdef([AC_REPLACE_FUNCS])
+ m4_popdef([AC_LIBOBJ])
+ AC_CONFIG_COMMANDS_PRE([
+ gltests_libobjs=
+ gltests_ltlibobjs=
+ if test -n "$gltests_LIBOBJS"; then
+ # Remove the extension.
+ sed_drop_objext='s/\.o$//;s/\.obj$//'
+ for i in `for i in $gltests_LIBOBJS; do echo "$i"; done | sed -e "$sed_drop_objext" | sort | uniq`; do
+ gltests_libobjs="$gltests_libobjs $i.$ac_objext"
+ gltests_ltlibobjs="$gltests_ltlibobjs $i.lo"
+ done
+ fi
+ AC_SUBST([gltests_LIBOBJS], [$gltests_libobjs])
+ AC_SUBST([gltests_LTLIBOBJS], [$gltests_ltlibobjs])
+ ])
+ LIBGNU_LIBDEPS="$gl_libdeps"
+ AC_SUBST([LIBGNU_LIBDEPS])
+ LIBGNU_LTLIBDEPS="$gl_ltlibdeps"
+ AC_SUBST([LIBGNU_LTLIBDEPS])
+])
+
+# Like AC_LIBOBJ, except that the module name goes
+# into gl_LIBOBJS instead of into LIBOBJS.
+AC_DEFUN([gl_LIBOBJ], [
+ AS_LITERAL_IF([$1], [gl_LIBSOURCES([$1.c])])dnl
+ gl_LIBOBJS="$gl_LIBOBJS $1.$ac_objext"
+])
+
+# Like AC_REPLACE_FUNCS, except that the module name goes
+# into gl_LIBOBJS instead of into LIBOBJS.
+AC_DEFUN([gl_REPLACE_FUNCS], [
+ m4_foreach_w([gl_NAME], [$1], [AC_LIBSOURCES(gl_NAME[.c])])dnl
+ AC_CHECK_FUNCS([$1], , [gl_LIBOBJ($ac_func)])
+])
+
+# Like AC_LIBSOURCES, except the directory where the source file is
+# expected is derived from the gnulib-tool parameterization,
+# and alloca is special cased (for the alloca-opt module).
+# We could also entirely rely on EXTRA_lib..._SOURCES.
+AC_DEFUN([gl_LIBSOURCES], [
+ m4_foreach([_gl_NAME], [$1], [
+ m4_if(_gl_NAME, [alloca.c], [], [
+ m4_define([gl_LIBSOURCES_DIR], [src/gnulib])
+ m4_append([gl_LIBSOURCES_LIST], _gl_NAME, [ ])
+ ])
+ ])
+])
+
+# Like AC_LIBOBJ, except that the module name goes
+# into gltests_LIBOBJS instead of into LIBOBJS.
+AC_DEFUN([gltests_LIBOBJ], [
+ AS_LITERAL_IF([$1], [gltests_LIBSOURCES([$1.c])])dnl
+ gltests_LIBOBJS="$gltests_LIBOBJS $1.$ac_objext"
+])
+
+# Like AC_REPLACE_FUNCS, except that the module name goes
+# into gltests_LIBOBJS instead of into LIBOBJS.
+AC_DEFUN([gltests_REPLACE_FUNCS], [
+ m4_foreach_w([gl_NAME], [$1], [AC_LIBSOURCES(gl_NAME[.c])])dnl
+ AC_CHECK_FUNCS([$1], , [gltests_LIBOBJ($ac_func)])
+])
+
+# Like AC_LIBSOURCES, except the directory where the source file is
+# expected is derived from the gnulib-tool parameterization,
+# and alloca is special cased (for the alloca-opt module).
+# We could also entirely rely on EXTRA_lib..._SOURCES.
+AC_DEFUN([gltests_LIBSOURCES], [
+ m4_foreach([_gl_NAME], [$1], [
+ m4_if(_gl_NAME, [alloca.c], [], [
+ m4_define([gltests_LIBSOURCES_DIR], [tests])
+ m4_append([gltests_LIBSOURCES_LIST], _gl_NAME, [ ])
+ ])
+ ])
+])
+
+# This macro records the list of files which have been installed by
+# gnulib-tool and may be removed by future gnulib-tool invocations.
+AC_DEFUN([gl_FILE_LIST], [
+ lib/attribute.h
+ lib/gl_anyhash1.h
+ lib/gl_anyhash2.h
+ lib/gl_anyhash_primes.h
+ lib/gl_linkedhash_map.c
+ lib/gl_linkedhash_map.h
+ lib/gl_map.c
+ lib/gl_map.h
+ lib/limits.in.h
+ lib/size_max.h
+ lib/stdbool.in.h
+ lib/stdint.in.h
+ lib/sys_types.in.h
+ lib/xsize.c
+ lib/xsize.h
+ m4/00gnulib.m4
+ m4/absolute-header.m4
+ m4/extern-inline.m4
+ m4/gnulib-common.m4
+ m4/include_next.m4
+ m4/limits-h.m4
+ m4/multiarch.m4
+ m4/off_t.m4
+ m4/pid_t.m4
+ m4/size_max.m4
+ m4/ssize_t.m4
+ m4/std-gnu11.m4
+ m4/stdbool.m4
+ m4/stdint.m4
+ m4/sys_types_h.m4
+ m4/wint_t.m4
+ m4/xsize.m4
+ m4/zzgnulib.m4
+])
diff --git a/src/m4/gnulib-tool.m4 b/src/m4/gnulib-tool.m4
new file mode 100644
index 0000000..3d56d83
--- /dev/null
+++ b/src/m4/gnulib-tool.m4
@@ -0,0 +1,57 @@
+# gnulib-tool.m4 serial 2
+dnl Copyright (C) 2004-2005, 2009-2021 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl The following macros need not be invoked explicitly.
+dnl Invoking them does nothing except to declare default arguments
+dnl for "gnulib-tool --import".
+
+dnl Usage: gl_LOCAL_DIR([DIR])
+AC_DEFUN([gl_LOCAL_DIR], [])
+
+dnl Usage: gl_MODULES([module1 module2 ...])
+AC_DEFUN([gl_MODULES], [])
+
+dnl Usage: gl_AVOID([module1 module2 ...])
+AC_DEFUN([gl_AVOID], [])
+
+dnl Usage: gl_SOURCE_BASE([DIR])
+AC_DEFUN([gl_SOURCE_BASE], [])
+
+dnl Usage: gl_M4_BASE([DIR])
+AC_DEFUN([gl_M4_BASE], [])
+
+dnl Usage: gl_PO_BASE([DIR])
+AC_DEFUN([gl_PO_BASE], [])
+
+dnl Usage: gl_DOC_BASE([DIR])
+AC_DEFUN([gl_DOC_BASE], [])
+
+dnl Usage: gl_TESTS_BASE([DIR])
+AC_DEFUN([gl_TESTS_BASE], [])
+
+dnl Usage: gl_WITH_TESTS
+AC_DEFUN([gl_WITH_TESTS], [])
+
+dnl Usage: gl_LIB([LIBNAME])
+AC_DEFUN([gl_LIB], [])
+
+dnl Usage: gl_LGPL or gl_LGPL([VERSION])
+AC_DEFUN([gl_LGPL], [])
+
+dnl Usage: gl_MAKEFILE_NAME([FILENAME])
+AC_DEFUN([gl_MAKEFILE_NAME], [])
+
+dnl Usage: gl_LIBTOOL
+AC_DEFUN([gl_LIBTOOL], [])
+
+dnl Usage: gl_MACRO_PREFIX([PREFIX])
+AC_DEFUN([gl_MACRO_PREFIX], [])
+
+dnl Usage: gl_PO_DOMAIN([DOMAIN])
+AC_DEFUN([gl_PO_DOMAIN], [])
+
+dnl Usage: gl_VC_FILES([BOOLEAN])
+AC_DEFUN([gl_VC_FILES], [])
diff --git a/src/m4/include_next.m4 b/src/m4/include_next.m4
new file mode 100644
index 0000000..bdd542b
--- /dev/null
+++ b/src/m4/include_next.m4
@@ -0,0 +1,224 @@
+# include_next.m4 serial 26
+dnl Copyright (C) 2006-2021 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Paul Eggert and Derek Price.
+
+dnl Sets INCLUDE_NEXT, INCLUDE_NEXT_AS_FIRST_DIRECTIVE, PRAGMA_SYSTEM_HEADER,
+dnl and PRAGMA_COLUMNS.
+dnl
+dnl INCLUDE_NEXT expands to 'include_next' if the compiler supports it, or to
+dnl 'include' otherwise.
+dnl
+dnl INCLUDE_NEXT_AS_FIRST_DIRECTIVE expands to 'include_next' if the compiler
+dnl supports it in the special case that it is the first include directive in
+dnl the given file, or to 'include' otherwise.
+dnl
+dnl PRAGMA_SYSTEM_HEADER can be used in files that contain #include_next,
+dnl so as to avoid GCC warnings when the gcc option -pedantic is used.
+dnl '#pragma GCC system_header' has the same effect as if the file was found
+dnl through the include search path specified with '-isystem' options (as
+dnl opposed to the search path specified with '-I' options). Namely, gcc
+dnl does not warn about some things, and on some systems (Solaris and Interix)
+dnl __STDC__ evaluates to 0 instead of to 1. The latter is an undesired side
+dnl effect; we are therefore careful to use 'defined __STDC__' or '1' instead
+dnl of plain '__STDC__'.
+dnl
+dnl PRAGMA_COLUMNS can be used in files that override system header files, so
+dnl as to avoid compilation errors on HP NonStop systems when the gnulib file
+dnl is included by a system header file that does a "#pragma COLUMNS 80" (which
+dnl has the effect of truncating the lines of that file and all files that it
+dnl includes to 80 columns) and the gnulib file has lines longer than 80
+dnl columns.
+
+AC_DEFUN([gl_INCLUDE_NEXT],
+[
+ AC_LANG_PREPROC_REQUIRE()
+ AC_CACHE_CHECK([whether the preprocessor supports include_next],
+ [gl_cv_have_include_next],
+ [rm -rf conftestd1a conftestd1b conftestd2
+ mkdir conftestd1a conftestd1b conftestd2
+ dnl IBM C 9.0, 10.1 (original versions, prior to the 2009-01 updates) on
+ dnl AIX 6.1 support include_next when used as first preprocessor directive
+ dnl in a file, but not when preceded by another include directive. Check
+ dnl for this bug by including <stdio.h>.
+ dnl Additionally, with this same compiler, include_next is a no-op when
+ dnl used in a header file that was included by specifying its absolute
+ dnl file name. Despite these two bugs, include_next is used in the
+ dnl compiler's <math.h>. By virtue of the second bug, we need to use
+ dnl include_next as well in this case.
+ cat <<EOF > conftestd1a/conftest.h
+#define DEFINED_IN_CONFTESTD1
+#include_next <conftest.h>
+#ifdef DEFINED_IN_CONFTESTD2
+int foo;
+#else
+#error "include_next doesn't work"
+#endif
+EOF
+ cat <<EOF > conftestd1b/conftest.h
+#define DEFINED_IN_CONFTESTD1
+#include <stdio.h>
+#include_next <conftest.h>
+#ifdef DEFINED_IN_CONFTESTD2
+int foo;
+#else
+#error "include_next doesn't work"
+#endif
+EOF
+ cat <<EOF > conftestd2/conftest.h
+#ifndef DEFINED_IN_CONFTESTD1
+#error "include_next test doesn't work"
+#endif
+#define DEFINED_IN_CONFTESTD2
+EOF
+ gl_save_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$gl_save_CPPFLAGS -Iconftestd1b -Iconftestd2"
+dnl We intentionally avoid using AC_LANG_SOURCE here.
+ AC_COMPILE_IFELSE([AC_LANG_DEFINES_PROVIDED[#include <conftest.h>]],
+ [gl_cv_have_include_next=yes],
+ [CPPFLAGS="$gl_save_CPPFLAGS -Iconftestd1a -Iconftestd2"
+ AC_COMPILE_IFELSE([AC_LANG_DEFINES_PROVIDED[#include <conftest.h>]],
+ [gl_cv_have_include_next=buggy],
+ [gl_cv_have_include_next=no])
+ ])
+ CPPFLAGS="$gl_save_CPPFLAGS"
+ rm -rf conftestd1a conftestd1b conftestd2
+ ])
+ PRAGMA_SYSTEM_HEADER=
+ if test $gl_cv_have_include_next = yes; then
+ INCLUDE_NEXT=include_next
+ INCLUDE_NEXT_AS_FIRST_DIRECTIVE=include_next
+ if test -n "$GCC"; then
+ PRAGMA_SYSTEM_HEADER='#pragma GCC system_header'
+ fi
+ else
+ if test $gl_cv_have_include_next = buggy; then
+ INCLUDE_NEXT=include
+ INCLUDE_NEXT_AS_FIRST_DIRECTIVE=include_next
+ else
+ INCLUDE_NEXT=include
+ INCLUDE_NEXT_AS_FIRST_DIRECTIVE=include
+ fi
+ fi
+ AC_SUBST([INCLUDE_NEXT])
+ AC_SUBST([INCLUDE_NEXT_AS_FIRST_DIRECTIVE])
+ AC_SUBST([PRAGMA_SYSTEM_HEADER])
+
+ dnl HP NonStop systems, which define __TANDEM, limit the line length
+ dnl after including some system header files.
+ AC_CACHE_CHECK([whether source code line length is unlimited],
+ [gl_cv_source_line_length_unlimited],
+ [AC_EGREP_CPP([choke me],
+ [
+#ifdef __TANDEM
+choke me
+#endif
+ ],
+ [gl_cv_source_line_length_unlimited=no],
+ [gl_cv_source_line_length_unlimited=yes])
+ ])
+ if test $gl_cv_source_line_length_unlimited = no; then
+ PRAGMA_COLUMNS="#pragma COLUMNS 10000"
+ else
+ PRAGMA_COLUMNS=
+ fi
+ AC_SUBST([PRAGMA_COLUMNS])
+])
+
+# gl_CHECK_NEXT_HEADERS(HEADER1 HEADER2 ...)
+# ------------------------------------------
+# For each arg foo.h, if #include_next works, define NEXT_FOO_H to be
+# '<foo.h>'; otherwise define it to be
+# '"///usr/include/foo.h"', or whatever other absolute file name is suitable.
+# Also, if #include_next works as first preprocessing directive in a file,
+# define NEXT_AS_FIRST_DIRECTIVE_FOO_H to be '<foo.h>'; otherwise define it to
+# be
+# '"///usr/include/foo.h"', or whatever other absolute file name is suitable.
+# That way, a header file with the following line:
+# #@INCLUDE_NEXT@ @NEXT_FOO_H@
+# or
+# #@INCLUDE_NEXT_AS_FIRST_DIRECTIVE@ @NEXT_AS_FIRST_DIRECTIVE_FOO_H@
+# behaves (after sed substitution) as if it contained
+# #include_next <foo.h>
+# even if the compiler does not support include_next.
+# The three "///" are to pacify Sun C 5.8, which otherwise would say
+# "warning: #include of /usr/include/... may be non-portable".
+# Use '""', not '<>', so that the /// cannot be confused with a C99 comment.
+# Note: This macro assumes that the header file is not empty after
+# preprocessing, i.e. it does not only define preprocessor macros but also
+# provides some type/enum definitions or function/variable declarations.
+#
+# This macro also checks whether each header exists, by invoking
+# AC_CHECK_HEADERS_ONCE or AC_CHECK_HEADERS on each argument.
+AC_DEFUN([gl_CHECK_NEXT_HEADERS],
+[
+ gl_NEXT_HEADERS_INTERNAL([$1], [check])
+])
+
+# gl_NEXT_HEADERS(HEADER1 HEADER2 ...)
+# ------------------------------------
+# Like gl_CHECK_NEXT_HEADERS, except do not check whether the headers exist.
+# This is suitable for headers like <stddef.h> that are standardized by C89
+# and therefore can be assumed to exist.
+AC_DEFUN([gl_NEXT_HEADERS],
+[
+ gl_NEXT_HEADERS_INTERNAL([$1], [assume])
+])
+
+# The guts of gl_CHECK_NEXT_HEADERS and gl_NEXT_HEADERS.
+AC_DEFUN([gl_NEXT_HEADERS_INTERNAL],
+[
+ AC_REQUIRE([gl_INCLUDE_NEXT])
+ AC_REQUIRE([AC_CANONICAL_HOST])
+
+ m4_if([$2], [check],
+ [AC_CHECK_HEADERS_ONCE([$1])
+ ])
+
+ m4_foreach_w([gl_HEADER_NAME], [$1],
+ [AS_VAR_PUSHDEF([gl_next_header],
+ [gl_cv_next_]m4_defn([gl_HEADER_NAME]))
+ if test $gl_cv_have_include_next = yes; then
+ AS_VAR_SET([gl_next_header], ['<'gl_HEADER_NAME'>'])
+ else
+ AC_CACHE_CHECK(
+ [absolute name of <]m4_defn([gl_HEADER_NAME])[>],
+ [gl_next_header],
+ [m4_if([$2], [check],
+ [AS_VAR_PUSHDEF([gl_header_exists],
+ [ac_cv_header_]m4_defn([gl_HEADER_NAME]))
+ if test AS_VAR_GET([gl_header_exists]) = yes; then
+ AS_VAR_POPDEF([gl_header_exists])
+ ])
+ gl_ABSOLUTE_HEADER_ONE(gl_HEADER_NAME)
+ AS_VAR_COPY([gl_header], [gl_cv_absolute_]AS_TR_SH(gl_HEADER_NAME))
+ AS_VAR_SET([gl_next_header], ['"'$gl_header'"'])
+ m4_if([$2], [check],
+ [else
+ AS_VAR_SET([gl_next_header], ['<'gl_HEADER_NAME'>'])
+ fi
+ ])
+ ])
+ fi
+ AC_SUBST(
+ AS_TR_CPP([NEXT_]m4_defn([gl_HEADER_NAME])),
+ [AS_VAR_GET([gl_next_header])])
+ if test $gl_cv_have_include_next = yes || test $gl_cv_have_include_next = buggy; then
+ # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include_next'
+ gl_next_as_first_directive='<'gl_HEADER_NAME'>'
+ else
+ # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include'
+ gl_next_as_first_directive=AS_VAR_GET([gl_next_header])
+ fi
+ AC_SUBST(
+ AS_TR_CPP([NEXT_AS_FIRST_DIRECTIVE_]m4_defn([gl_HEADER_NAME])),
+ [$gl_next_as_first_directive])
+ AS_VAR_POPDEF([gl_next_header])])
+])
+
+# Autoconf 2.68 added warnings for our use of AC_COMPILE_IFELSE;
+# this fallback is safe for all earlier autoconf versions.
+m4_define_default([AC_LANG_DEFINES_PROVIDED])
diff --git a/src/m4/limits-h.m4 b/src/m4/limits-h.m4
new file mode 100644
index 0000000..70dbb7d
--- /dev/null
+++ b/src/m4/limits-h.m4
@@ -0,0 +1,43 @@
+dnl Check whether limits.h has needed features.
+
+dnl Copyright 2016-2021 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Paul Eggert.
+
+AC_DEFUN_ONCE([gl_LIMITS_H],
+[
+ gl_CHECK_NEXT_HEADERS([limits.h])
+
+ AC_CACHE_CHECK([whether limits.h has LLONG_MAX, WORD_BIT, ULLONG_WIDTH etc.],
+ [gl_cv_header_limits_width],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#ifndef __STDC_WANT_IEC_60559_BFP_EXT__
+ #define __STDC_WANT_IEC_60559_BFP_EXT__ 1
+ #endif
+ #include <limits.h>
+ long long llm = LLONG_MAX;
+ int wb = WORD_BIT;
+ int ullw = ULLONG_WIDTH;
+ ]])],
+ [gl_cv_header_limits_width=yes],
+ [gl_cv_header_limits_width=no])])
+ if test "$gl_cv_header_limits_width" = yes; then
+ LIMITS_H=
+ else
+ LIMITS_H=limits.h
+ fi
+ AC_SUBST([LIMITS_H])
+ AM_CONDITIONAL([GL_GENERATE_LIMITS_H], [test -n "$LIMITS_H"])
+])
+
+dnl Unconditionally enables the replacement of <limits.h>.
+AC_DEFUN([gl_REPLACE_LIMITS_H],
+[
+ AC_REQUIRE([gl_LIMITS_H])
+ LIMITS_H='limits.h'
+ AM_CONDITIONAL([GL_GENERATE_LIMITS_H], [test -n "$LIMITS_H"])
+])
diff --git a/src/m4/multiarch.m4 b/src/m4/multiarch.m4
new file mode 100644
index 0000000..f1678d9
--- /dev/null
+++ b/src/m4/multiarch.m4
@@ -0,0 +1,65 @@
+# multiarch.m4 serial 9
+dnl Copyright (C) 2008-2021 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+# Determine whether the compiler is or may be producing universal binaries.
+#
+# On Mac OS X 10.5 and later systems, the user can create libraries and
+# executables that work on multiple system types--known as "fat" or
+# "universal" binaries--by specifying multiple '-arch' options to the
+# compiler but only a single '-arch' option to the preprocessor. Like
+# this:
+#
+# ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+# CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+# CPP="gcc -E" CXXCPP="g++ -E"
+#
+# Detect this situation and set APPLE_UNIVERSAL_BUILD accordingly.
+
+AC_DEFUN_ONCE([gl_MULTIARCH],
+[
+ dnl Code similar to autoconf-2.63 AC_C_BIGENDIAN.
+ AC_CACHE_CHECK([whether the compiler produces multi-arch binaries],
+ [gl_cv_c_multiarch],
+ [gl_cv_c_multiarch=no
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE(
+ [[#ifndef __APPLE_CC__
+ not a universal capable compiler
+ #endif
+ typedef int dummy;
+ ]])],
+ [
+ dnl Check for potential -arch flags. It is not universal unless
+ dnl there are at least two -arch flags with different values.
+ arch=
+ prev=
+ for word in ${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS}; do
+ if test -n "$prev"; then
+ case $word in
+ i?86 | x86_64 | ppc | ppc64 | arm | arm64)
+ if test -z "$arch" || test "$arch" = "$word"; then
+ arch="$word"
+ else
+ gl_cv_c_multiarch=yes
+ fi
+ ;;
+ esac
+ prev=
+ else
+ if test "x$word" = "x-arch"; then
+ prev=arch
+ fi
+ fi
+ done
+ ])
+ ])
+ if test $gl_cv_c_multiarch = yes; then
+ APPLE_UNIVERSAL_BUILD=1
+ else
+ APPLE_UNIVERSAL_BUILD=0
+ fi
+ AC_SUBST([APPLE_UNIVERSAL_BUILD])
+])
diff --git a/src/m4/off_t.m4 b/src/m4/off_t.m4
new file mode 100644
index 0000000..bdec43c
--- /dev/null
+++ b/src/m4/off_t.m4
@@ -0,0 +1,18 @@
+# off_t.m4 serial 1
+dnl Copyright (C) 2012-2021 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl Check whether to override the 'off_t' type.
+dnl Set WINDOWS_64_BIT_OFF_T.
+
+AC_DEFUN([gl_TYPE_OFF_T],
+[
+ m4_ifdef([gl_LARGEFILE], [
+ AC_REQUIRE([gl_LARGEFILE])
+ ], [
+ WINDOWS_64_BIT_OFF_T=0
+ ])
+ AC_SUBST([WINDOWS_64_BIT_OFF_T])
+])
diff --git a/src/m4/pid_t.m4 b/src/m4/pid_t.m4
new file mode 100644
index 0000000..b7650a1
--- /dev/null
+++ b/src/m4/pid_t.m4
@@ -0,0 +1,38 @@
+# pid_t.m4 serial 4
+dnl Copyright (C) 2020-2021 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+# The following implementation works around a problem in autoconf <= 2.69.
+m4_version_prereq([2.70], [], [
+
+dnl Define pid_t if the headers don't define it.
+AC_DEFUN([AC_TYPE_PID_T],
+[
+ AC_CHECK_TYPE([pid_t],
+ [],
+ [dnl On 64-bit native Windows, define it to the equivalent of 'intptr_t'
+ dnl (= 'long long' = '__int64'), because that is the return type
+ dnl of the _spawnv* functions
+ dnl <https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/spawnvp-wspawnvp>
+ dnl and the argument type of the _cwait function
+ dnl <https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/cwait>.
+ dnl Otherwise (on 32-bit Windows and on old Unix platforms), define it
+ dnl to 'int'.
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[
+ #if defined _WIN64 && !defined __CYGWIN__
+ LLP64
+ #endif
+ ]])
+ ],
+ [gl_pid_type='int'],
+ [gl_pid_type='__int64'])
+ AC_DEFINE_UNQUOTED([pid_t], [$gl_pid_type],
+ [Define as a signed integer type capable of holding a process identifier.])
+ ],
+ [AC_INCLUDES_DEFAULT])
+])
+
+])# m4_version_prereq 2.70
diff --git a/src/m4/size_max.m4 b/src/m4/size_max.m4
new file mode 100644
index 0000000..1d41ce9
--- /dev/null
+++ b/src/m4/size_max.m4
@@ -0,0 +1,75 @@
+# size_max.m4 serial 12
+dnl Copyright (C) 2003, 2005-2006, 2008-2021 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+AC_PREREQ([2.61])
+
+AC_DEFUN([gl_SIZE_MAX],
+[
+ AC_CHECK_HEADERS([stdint.h])
+ dnl First test whether the system already has SIZE_MAX.
+ AC_CACHE_CHECK([for SIZE_MAX], [gl_cv_size_max], [
+ gl_cv_size_max=no
+ AC_EGREP_CPP([Found it], [
+#include <limits.h>
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef SIZE_MAX
+Found it
+#endif
+], [gl_cv_size_max=yes])
+ if test $gl_cv_size_max != yes; then
+ dnl Define it ourselves. Here we assume that the type 'size_t' is not wider
+ dnl than the type 'unsigned long'. Try hard to find a definition that can
+ dnl be used in a preprocessor #if, i.e. doesn't contain a cast.
+ AC_COMPUTE_INT([size_t_bits_minus_1], [sizeof (size_t) * CHAR_BIT - 1],
+ [#include <stddef.h>
+#include <limits.h>], [size_t_bits_minus_1=])
+ AC_COMPUTE_INT([fits_in_uint], [sizeof (size_t) <= sizeof (unsigned int)],
+ [#include <stddef.h>], [fits_in_uint=])
+ if test -n "$size_t_bits_minus_1" && test -n "$fits_in_uint"; then
+ if test $fits_in_uint = 1; then
+ dnl Even though SIZE_MAX fits in an unsigned int, it must be of type
+ dnl 'unsigned long' if the type 'size_t' is the same as 'unsigned long'.
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <stddef.h>
+ extern size_t foo;
+ extern unsigned long foo;
+ ]],
+ [[]])],
+ [fits_in_uint=0])
+ fi
+ dnl We cannot use 'expr' to simplify this expression, because 'expr'
+ dnl works only with 'long' integers in the host environment, while we
+ dnl might be cross-compiling from a 32-bit platform to a 64-bit platform.
+ if test $fits_in_uint = 1; then
+ gl_cv_size_max="(((1U << $size_t_bits_minus_1) - 1) * 2 + 1)"
+ else
+ gl_cv_size_max="(((1UL << $size_t_bits_minus_1) - 1) * 2 + 1)"
+ fi
+ else
+ dnl Shouldn't happen, but who knows...
+ gl_cv_size_max='((size_t)~(size_t)0)'
+ fi
+ fi
+ ])
+ if test "$gl_cv_size_max" != yes; then
+ AC_DEFINE_UNQUOTED([SIZE_MAX], [$gl_cv_size_max],
+ [Define as the maximum value of type 'size_t', if the system doesn't define it.])
+ fi
+ dnl Don't redefine SIZE_MAX in config.h if config.h is re-included after
+ dnl <stdint.h>. Remember that the #undef in AH_VERBATIM gets replaced with
+ dnl #define by AC_DEFINE_UNQUOTED.
+ AH_VERBATIM([SIZE_MAX],
+[/* Define as the maximum value of type 'size_t', if the system doesn't define
+ it. */
+#ifndef SIZE_MAX
+# undef SIZE_MAX
+#endif])
+])
diff --git a/src/m4/ssize_t.m4 b/src/m4/ssize_t.m4
new file mode 100644
index 0000000..f0ed509
--- /dev/null
+++ b/src/m4/ssize_t.m4
@@ -0,0 +1,23 @@
+# ssize_t.m4 serial 5 (gettext-0.18.2)
+dnl Copyright (C) 2001-2003, 2006, 2010-2021 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+dnl Test whether ssize_t is defined.
+
+AC_DEFUN([gt_TYPE_SSIZE_T],
+[
+ AC_CACHE_CHECK([for ssize_t], [gt_cv_ssize_t],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <sys/types.h>]],
+ [[int x = sizeof (ssize_t *) + sizeof (ssize_t);
+ return !x;]])],
+ [gt_cv_ssize_t=yes], [gt_cv_ssize_t=no])])
+ if test $gt_cv_ssize_t = no; then
+ AC_DEFINE([ssize_t], [int],
+ [Define as a signed type of the same size as size_t.])
+ fi
+])
diff --git a/src/m4/std-gnu11.m4 b/src/m4/std-gnu11.m4
new file mode 100644
index 0000000..7b1a042
--- /dev/null
+++ b/src/m4/std-gnu11.m4
@@ -0,0 +1,829 @@
+# Prefer GNU C11 and C++11 to earlier versions. -*- coding: utf-8 -*-
+
+# This implementation is taken from GNU Autoconf lib/autoconf/c.m4
+# commit 017d5ddd82854911f0119691d91ea8a1438824d6
+# dated Sun Apr 3 13:57:17 2016 -0700
+# This implementation will be obsolete once we can assume Autoconf 2.70
+# or later is installed everywhere a Gnulib program might be developed.
+
+m4_version_prereq([2.70], [], [
+
+
+# Copyright (C) 2001-2021 Free Software Foundation, Inc.
+
+# 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, either version 3 of the License, 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 for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+# Written by David MacKenzie, with help from
+# Akim Demaille, Paul Eggert,
+# François Pinard, Karl Berry, Richard Pixley, Ian Lance Taylor,
+# Roland McGrath, Noah Friedman, david d zuhn, and many others.
+
+
+# AC_PROG_CC([COMPILER ...])
+# --------------------------
+# COMPILER ... is a space separated list of C compilers to search for.
+# This just gives the user an opportunity to specify an alternative
+# search list for the C compiler.
+AC_DEFUN_ONCE([AC_PROG_CC],
+[AC_LANG_PUSH(C)dnl
+AC_ARG_VAR([CC], [C compiler command])dnl
+AC_ARG_VAR([CFLAGS], [C compiler flags])dnl
+_AC_ARG_VAR_LDFLAGS()dnl
+_AC_ARG_VAR_LIBS()dnl
+_AC_ARG_VAR_CPPFLAGS()dnl
+m4_ifval([$1],
+ [AC_CHECK_TOOLS(CC, [$1])],
+[AC_CHECK_TOOL(CC, gcc)
+if test -z "$CC"; then
+ dnl Here we want:
+ dnl AC_CHECK_TOOL(CC, cc)
+ dnl but without the check for a tool without the prefix.
+ dnl Until the check is removed from there, copy the code:
+ if test -n "$ac_tool_prefix"; then
+ AC_CHECK_PROG(CC, [${ac_tool_prefix}cc], [${ac_tool_prefix}cc])
+ fi
+fi
+if test -z "$CC"; then
+ AC_CHECK_PROG(CC, cc, cc, , , /usr/ucb/cc)
+fi
+if test -z "$CC"; then
+ AC_CHECK_TOOLS(CC, cl.exe)
+fi
+if test -z "$CC"; then
+ AC_CHECK_TOOL(CC, clang)
+fi
+])
+
+test -z "$CC" && AC_MSG_FAILURE([no acceptable C compiler found in \$PATH])
+
+# Provide some information about the compiler.
+_AS_ECHO_LOG([checking for _AC_LANG compiler version])
+set X $ac_compile
+ac_compiler=$[2]
+for ac_option in --version -v -V -qversion -version; do
+ _AC_DO_LIMIT([$ac_compiler $ac_option >&AS_MESSAGE_LOG_FD])
+done
+
+m4_expand_once([_AC_COMPILER_EXEEXT])[]dnl
+m4_expand_once([_AC_COMPILER_OBJEXT])[]dnl
+_AC_LANG_COMPILER_GNU
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+_AC_PROG_CC_G
+dnl
+dnl Set ac_prog_cc_stdc to the supported C version.
+dnl Also set the documented variable ac_cv_prog_cc_stdc;
+dnl its name was chosen when it was cached, but it is no longer cached.
+_AC_PROG_CC_C11([ac_prog_cc_stdc=c11
+ ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11],
+ [_AC_PROG_CC_C99([ac_prog_cc_stdc=c99
+ ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99],
+ [_AC_PROG_CC_C89([ac_prog_cc_stdc=c89
+ ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89],
+ [ac_prog_cc_stdc=no
+ ac_cv_prog_cc_stdc=no])])])
+dnl
+AC_LANG_POP(C)dnl
+])# AC_PROG_CC
+
+
+
+# AC_PROG_CXX([LIST-OF-COMPILERS])
+# --------------------------------
+# LIST-OF-COMPILERS is a space separated list of C++ compilers to search
+# for (if not specified, a default list is used). This just gives the
+# user an opportunity to specify an alternative search list for the C++
+# compiler.
+# aCC HP-UX C++ compiler much better than `CC', so test before.
+# FCC Fujitsu C++ compiler
+# KCC KAI C++ compiler
+# RCC Rational C++
+# xlC_r AIX C Set++ (with support for reentrant code)
+# xlC AIX C Set++
+AC_DEFUN([AC_PROG_CXX],
+[AC_LANG_PUSH(C++)dnl
+AC_ARG_VAR([CXX], [C++ compiler command])dnl
+AC_ARG_VAR([CXXFLAGS], [C++ compiler flags])dnl
+_AC_ARG_VAR_LDFLAGS()dnl
+_AC_ARG_VAR_LIBS()dnl
+_AC_ARG_VAR_CPPFLAGS()dnl
+_AC_ARG_VAR_PRECIOUS([CCC])dnl
+if test -z "$CXX"; then
+ if test -n "$CCC"; then
+ CXX=$CCC
+ else
+ AC_CHECK_TOOLS(CXX,
+ [m4_default([$1],
+ [g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++])],
+ g++)
+ fi
+fi
+# Provide some information about the compiler.
+_AS_ECHO_LOG([checking for _AC_LANG compiler version])
+set X $ac_compile
+ac_compiler=$[2]
+for ac_option in --version -v -V -qversion; do
+ _AC_DO_LIMIT([$ac_compiler $ac_option >&AS_MESSAGE_LOG_FD])
+done
+
+m4_expand_once([_AC_COMPILER_EXEEXT])[]dnl
+m4_expand_once([_AC_COMPILER_OBJEXT])[]dnl
+_AC_LANG_COMPILER_GNU
+if test $ac_compiler_gnu = yes; then
+ GXX=yes
+else
+ GXX=
+fi
+_AC_PROG_CXX_G
+_AC_PROG_CXX_CXX11([ac_prog_cxx_stdcxx=cxx11
+ ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx11
+ ac_cv_prog_cxx_cxx98=$ac_cv_prog_cxx_cxx11],
+ [_AC_PROG_CXX_CXX98([ac_prog_cxx_stdcxx=cxx98
+ ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx98],
+ [ac_prog_cxx_stdcxx=no
+ ac_cv_prog_cxx_stdcxx=no])])
+AC_LANG_POP(C++)dnl
+])# AC_PROG_CXX
+
+
+# _AC_C_STD_TRY(STANDARD, TEST-PROLOGUE, TEST-BODY, OPTION-LIST,
+# ACTION-IF-AVAILABLE, ACTION-IF-UNAVAILABLE)
+# --------------------------------------------------------------
+# Check whether the C compiler accepts features of STANDARD (e.g `c89', `c99')
+# by trying to compile a program of TEST-PROLOGUE and TEST-BODY. If this fails,
+# try again with each compiler option in the space-separated OPTION-LIST; if one
+# helps, append it to CC. If eventually successful, run ACTION-IF-AVAILABLE,
+# else ACTION-IF-UNAVAILABLE.
+AC_DEFUN([_AC_C_STD_TRY],
+[AC_MSG_CHECKING([for $CC option to enable ]m4_translit($1, [c], [C])[ features])
+AC_CACHE_VAL(ac_cv_prog_cc_$1,
+[ac_cv_prog_cc_$1=no
+ac_save_CC=$CC
+AC_LANG_CONFTEST([AC_LANG_PROGRAM([$2], [$3])])
+for ac_arg in '' $4
+do
+ CC="$ac_save_CC $ac_arg"
+ _AC_COMPILE_IFELSE([], [ac_cv_prog_cc_$1=$ac_arg])
+ test "x$ac_cv_prog_cc_$1" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+])# AC_CACHE_VAL
+ac_prog_cc_stdc_options=
+case "x$ac_cv_prog_cc_$1" in
+ x)
+ AC_MSG_RESULT([none needed]) ;;
+ xno)
+ AC_MSG_RESULT([unsupported]) ;;
+ *)
+ ac_prog_cc_stdc_options=" $ac_cv_prog_cc_$1"
+ CC=$CC$ac_prog_cc_stdc_options
+ AC_MSG_RESULT([$ac_cv_prog_cc_$1]) ;;
+esac
+AS_IF([test "x$ac_cv_prog_cc_$1" != xno], [$5], [$6])
+])# _AC_C_STD_TRY
+
+# _AC_C_C99_TEST_HEADER
+# ---------------------
+# A C header suitable for testing for C99.
+AC_DEFUN([_AC_C_C99_TEST_HEADER],
+[[#include <stdarg.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <stdio.h>
+
+// Check varargs macros. These examples are taken from C99 6.10.3.5.
+#define debug(...) fprintf (stderr, __VA_ARGS__)
+#define showlist(...) puts (#__VA_ARGS__)
+#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
+static void
+test_varargs_macros (void)
+{
+ int x = 1234;
+ int y = 5678;
+ debug ("Flag");
+ debug ("X = %d\n", x);
+ showlist (The first, second, and third items.);
+ report (x>y, "x is %d but y is %d", x, y);
+}
+
+// Check long long types.
+#define BIG64 18446744073709551615ull
+#define BIG32 4294967295ul
+#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
+#if !BIG_OK
+ your preprocessor is broken;
+#endif
+#if BIG_OK
+#else
+ your preprocessor is broken;
+#endif
+static long long int bignum = -9223372036854775807LL;
+static unsigned long long int ubignum = BIG64;
+
+struct incomplete_array
+{
+ int datasize;
+ double data[];
+};
+
+struct named_init {
+ int number;
+ const wchar_t *name;
+ double average;
+};
+
+typedef const char *ccp;
+
+static inline int
+test_restrict (ccp restrict text)
+{
+ // See if C++-style comments work.
+ // Iterate through items via the restricted pointer.
+ // Also check for declarations in for loops.
+ for (unsigned int i = 0; *(text+i) != '\0'; ++i)
+ continue;
+ return 0;
+}
+
+// Check varargs and va_copy.
+static bool
+test_varargs (const char *format, ...)
+{
+ va_list args;
+ va_start (args, format);
+ va_list args_copy;
+ va_copy (args_copy, args);
+
+ const char *str = "";
+ int number = 0;
+ float fnumber = 0;
+
+ while (*format)
+ {
+ switch (*format++)
+ {
+ case 's': // string
+ str = va_arg (args_copy, const char *);
+ break;
+ case 'd': // int
+ number = va_arg (args_copy, int);
+ break;
+ case 'f': // float
+ fnumber = va_arg (args_copy, double);
+ break;
+ default:
+ break;
+ }
+ }
+ va_end (args_copy);
+ va_end (args);
+
+ return *str && number && fnumber;
+}]])# _AC_C_C99_TEST_HEADER
+
+# _AC_C_C99_TEST_BODY
+# -------------------
+# A C body suitable for testing for C99, assuming the corresponding header.
+AC_DEFUN([_AC_C_C99_TEST_BODY],
+[[
+ // Check bool.
+ _Bool success = false;
+
+ // Check restrict.
+ if (test_restrict ("String literal") == 0)
+ success = true;
+ char *restrict newvar = "Another string";
+
+ // Check varargs.
+ success &= test_varargs ("s, d' f .", "string", 65, 34.234);
+ test_varargs_macros ();
+
+ // Check flexible array members.
+ struct incomplete_array *ia =
+ malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
+ ia->datasize = 10;
+ for (int i = 0; i < ia->datasize; ++i)
+ ia->data[i] = i * 1.234;
+
+ // Check named initializers.
+ struct named_init ni = {
+ .number = 34,
+ .name = L"Test wide string",
+ .average = 543.34343,
+ };
+
+ ni.number = 58;
+
+ int dynamic_array[ni.number];
+ dynamic_array[ni.number - 1] = 543;
+
+ // work around unused variable warnings
+ return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x'
+ || dynamic_array[ni.number - 1] != 543);
+]])
+
+# _AC_PROG_CC_C99 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE])
+# ----------------------------------------------------------------
+# If the C compiler is not in ISO C99 mode by default, try to add an
+# option to output variable CC to make it so. This macro tries
+# various options that select ISO C99 on some system or another. It
+# considers the compiler to be in ISO C99 mode if it handles _Bool,
+# // comments, flexible array members, inline, long long int, mixed
+# code and declarations, named initialization of structs, restrict,
+# va_copy, varargs macros, variable declarations in for loops and
+# variable length arrays.
+AC_DEFUN([_AC_PROG_CC_C99],
+[_AC_C_STD_TRY([c99],
+[_AC_C_C99_TEST_HEADER],
+[_AC_C_C99_TEST_BODY],
+dnl Try
+dnl GCC -std=gnu99 (unused restrictive modes: -std=c99 -std=iso9899:1999)
+dnl IBM XL C -qlanglvl=extc1x (V12.1; does not pass C11 test)
+dnl IBM XL C -qlanglvl=extc99
+dnl (pre-V12.1; unused restrictive mode: -qlanglvl=stdc99)
+dnl HP cc -AC99
+dnl Intel ICC -std=c99, -c99 (deprecated)
+dnl IRIX -c99
+dnl Solaris -D_STDC_C99=
+dnl cc's -xc99 option uses linker magic to define the external
+dnl symbol __xpg4 as if by "int __xpg4 = 1;", which enables C99
+dnl behavior for C library functions. This is not wanted here,
+dnl because it means that a single module compiled with -xc99
+dnl alters C runtime behavior for the entire program, not for
+dnl just the module. Instead, define the (private) symbol
+dnl _STDC_C99, which suppresses a bogus failure in <stdbool.h>.
+dnl The resulting compiler passes the test case here, and that's
+dnl good enough. For more, please see the thread starting at:
+dnl https://lists.gnu.org/r/autoconf/2010-12/msg00059.html
+dnl Tru64 -c99
+dnl with extended modes being tried first.
+[[-std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc1x -qlanglvl=extc99]], [$1], [$2])[]dnl
+])# _AC_PROG_CC_C99
+
+
+# _AC_PROG_CC_C11 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE])
+# ----------------------------------------------------------------
+# If the C compiler is not in ISO C11 mode by default, try to add an
+# option to output variable CC to make it so. This macro tries
+# various options that select ISO C11 on some system or another. It
+# considers the compiler to be in ISO C11 mode if it handles _Alignas,
+# _Alignof, _Noreturn, _Static_assert, UTF-8 string literals,
+# duplicate typedefs, and anonymous structures and unions.
+AC_DEFUN([_AC_PROG_CC_C11],
+[_AC_C_STD_TRY([c11],
+[_AC_C_C99_TEST_HEADER[
+// Check _Alignas.
+char _Alignas (double) aligned_as_double;
+char _Alignas (0) no_special_alignment;
+extern char aligned_as_int;
+char _Alignas (0) _Alignas (int) aligned_as_int;
+
+// Check _Alignof.
+enum
+{
+ int_alignment = _Alignof (int),
+ int_array_alignment = _Alignof (int[100]),
+ char_alignment = _Alignof (char)
+};
+_Static_assert (0 < -_Alignof (int), "_Alignof is signed");
+
+// Check _Noreturn.
+int _Noreturn does_not_return (void) { for (;;) continue; }
+
+// Check _Static_assert.
+struct test_static_assert
+{
+ int x;
+ _Static_assert (sizeof (int) <= sizeof (long int),
+ "_Static_assert does not work in struct");
+ long int y;
+};
+
+// Check UTF-8 literals.
+#define u8 syntax error!
+char const utf8_literal[] = u8"happens to be ASCII" "another string";
+
+// Check duplicate typedefs.
+typedef long *long_ptr;
+typedef long int *long_ptr;
+typedef long_ptr long_ptr;
+
+// Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1.
+struct anonymous
+{
+ union {
+ struct { int i; int j; };
+ struct { int k; long int l; } w;
+ };
+ int m;
+} v1;
+]],
+[_AC_C_C99_TEST_BODY[
+ v1.i = 2;
+ v1.w.k = 5;
+ _Static_assert ((offsetof (struct anonymous, i)
+ == offsetof (struct anonymous, w.k)),
+ "Anonymous union alignment botch");
+]],
+dnl Try
+dnl GCC -std=gnu11 (unused restrictive mode: -std=c11)
+dnl with extended modes being tried first.
+dnl
+dnl Do not try -qlanglvl=extc1x, because IBM XL C V12.1 (the latest version as
+dnl of September 2012) does not pass the C11 test. For now, try extc1x when
+dnl compiling the C99 test instead, since it enables _Static_assert and
+dnl _Noreturn, which is a win. If -qlanglvl=extc11 or -qlanglvl=extc1x passes
+dnl the C11 test in some future version of IBM XL C, we'll add it here,
+dnl preferably extc11.
+[[-std=gnu11]], [$1], [$2])[]dnl
+])# _AC_PROG_CC_C11
+
+
+# AC_PROG_CC_C89
+# --------------
+# Do not use AU_ALIAS here and in AC_PROG_CC_C99 and AC_PROG_CC_STDC,
+# as that'd be incompatible with how Automake redefines AC_PROG_CC. See
+# <https://lists.gnu.org/r/autoconf/2012-10/msg00048.html>.
+AU_DEFUN([AC_PROG_CC_C89],
+ [AC_REQUIRE([AC_PROG_CC])],
+ [$0 is obsolete; use AC_PROG_CC]
+)
+
+# AC_PROG_CC_C99
+# --------------
+AU_DEFUN([AC_PROG_CC_C99],
+ [AC_REQUIRE([AC_PROG_CC])],
+ [$0 is obsolete; use AC_PROG_CC]
+)
+
+# AC_PROG_CC_STDC
+# ---------------
+AU_DEFUN([AC_PROG_CC_STDC],
+ [AC_REQUIRE([AC_PROG_CC])],
+ [$0 is obsolete; use AC_PROG_CC]
+)
+
+
+# AC_C_PROTOTYPES
+# ---------------
+# Check if the C compiler supports prototypes, included if it needs
+# options.
+AC_DEFUN([AC_C_PROTOTYPES],
+[AC_REQUIRE([AC_PROG_CC])dnl
+if test "$ac_prog_cc_stdc" != no; then
+ AC_DEFINE(PROTOTYPES, 1,
+ [Define to 1 if the C compiler supports function prototypes.])
+ AC_DEFINE(__PROTOTYPES, 1,
+ [Define like PROTOTYPES; this can be used by system headers.])
+fi
+])# AC_C_PROTOTYPES
+
+
+# _AC_CXX_STD_TRY(STANDARD, TEST-PROLOGUE, TEST-BODY, OPTION-LIST,
+# ACTION-IF-AVAILABLE, ACTION-IF-UNAVAILABLE)
+# ----------------------------------------------------------------
+# Check whether the C++ compiler accepts features of STANDARD (e.g
+# `cxx98', `cxx11') by trying to compile a program of TEST-PROLOGUE
+# and TEST-BODY. If this fails, try again with each compiler option
+# in the space-separated OPTION-LIST; if one helps, append it to CXX.
+# If eventually successful, run ACTION-IF-AVAILABLE, else
+# ACTION-IF-UNAVAILABLE.
+AC_DEFUN([_AC_CXX_STD_TRY],
+[AC_MSG_CHECKING([for $CXX option to enable ]m4_translit(m4_translit($1, [x], [+]), [a-z], [A-Z])[ features])
+AC_LANG_PUSH(C++)dnl
+AC_CACHE_VAL(ac_cv_prog_cxx_$1,
+[ac_cv_prog_cxx_$1=no
+ac_save_CXX=$CXX
+AC_LANG_CONFTEST([AC_LANG_PROGRAM([$2], [$3])])
+for ac_arg in '' $4
+do
+ CXX="$ac_save_CXX $ac_arg"
+ _AC_COMPILE_IFELSE([], [ac_cv_prog_cxx_$1=$ac_arg])
+ test "x$ac_cv_prog_cxx_$1" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CXX=$ac_save_CXX
+])# AC_CACHE_VAL
+ac_prog_cxx_stdcxx_options=
+case "x$ac_cv_prog_cxx_$1" in
+ x)
+ AC_MSG_RESULT([none needed]) ;;
+ xno)
+ AC_MSG_RESULT([unsupported]) ;;
+ *)
+ ac_prog_cxx_stdcxx_options=" $ac_cv_prog_cxx_$1"
+ CXX=$CXX$ac_prog_cxx_stdcxx_options
+ AC_MSG_RESULT([$ac_cv_prog_cxx_$1]) ;;
+esac
+AC_LANG_POP(C++)dnl
+AS_IF([test "x$ac_cv_prog_cxx_$1" != xno], [$5], [$6])
+])# _AC_CXX_STD_TRY
+
+# _AC_CXX_CXX98_TEST_HEADER
+# -------------------------
+# A C++ header suitable for testing for CXX98.
+AC_DEFUN([_AC_CXX_CXX98_TEST_HEADER],
+[[
+#include <algorithm>
+#include <cstdlib>
+#include <fstream>
+#include <iomanip>
+#include <iostream>
+#include <list>
+#include <map>
+#include <set>
+#include <sstream>
+#include <stdexcept>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace test {
+ typedef std::vector<std::string> string_vec;
+ typedef std::pair<int,bool> map_value;
+ typedef std::map<std::string,map_value> map_type;
+ typedef std::set<int> set_type;
+
+ template<typename T>
+ class printer {
+ public:
+ printer(std::ostringstream& os): os(os) {}
+ void operator() (T elem) { os << elem << std::endl; }
+ private:
+ std::ostringstream& os;
+ };
+}
+]])# _AC_CXX_CXX98_TEST_HEADER
+
+# _AC_CXX_CXX98_TEST_BODY
+# -----------------------
+# A C++ body suitable for testing for CXX98, assuming the corresponding header.
+AC_DEFUN([_AC_CXX_CXX98_TEST_BODY],
+[[
+
+try {
+ // Basic string.
+ std::string teststr("ASCII text");
+ teststr += " string";
+
+ // Simple vector.
+ test::string_vec testvec;
+ testvec.push_back(teststr);
+ testvec.push_back("foo");
+ testvec.push_back("bar");
+ if (testvec.size() != 3) {
+ throw std::runtime_error("vector size is not 1");
+ }
+
+ // Dump vector into stringstream and obtain string.
+ std::ostringstream os;
+ for (test::string_vec::const_iterator i = testvec.begin();
+ i != testvec.end(); ++i) {
+ if (i + 1 != testvec.end()) {
+ os << teststr << '\n';
+ }
+ }
+ // Check algorithms work.
+ std::for_each(testvec.begin(), testvec.end(), test::printer<std::string>(os));
+ std::string os_out = os.str();
+
+ // Test pair and map.
+ test::map_type testmap;
+ testmap.insert(std::make_pair(std::string("key"),
+ std::make_pair(53,false)));
+
+ // Test set.
+ int values[] = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, 14, 19, 17, 8, 6, 20, 16, 2, 11, 1};
+ test::set_type testset(values, values + sizeof(values)/sizeof(values[0]));
+ std::list<int> testlist(testset.begin(), testset.end());
+ std::copy(testset.begin(), testset.end(), std::back_inserter(testlist));
+} catch (const std::exception& e) {
+ std::cerr << "Caught exception: " << e.what() << std::endl;
+
+ // Test fstream
+ std::ofstream of("test.txt");
+ of << "Test ASCII text\n" << std::flush;
+ of << "N= " << std::hex << std::setw(8) << std::left << 534 << std::endl;
+ of.close();
+}
+std::exit(0);
+]])
+
+# _AC_CXX_CXX11_TEST_HEADER
+# -------------------------
+# A C++ header suitable for testing for CXX11.
+AC_DEFUN([_AC_CXX_CXX11_TEST_HEADER],
+[[
+#include <deque>
+#include <functional>
+#include <memory>
+#include <tuple>
+#include <array>
+#include <regex>
+#include <iostream>
+
+namespace cxx11test
+{
+ typedef std::shared_ptr<std::string> sptr;
+ typedef std::weak_ptr<std::string> wptr;
+
+ typedef std::tuple<std::string,int,double> tp;
+ typedef std::array<int, 20> int_array;
+
+ constexpr int get_val() { return 20; }
+
+ struct testinit
+ {
+ int i;
+ double d;
+ };
+
+ class delegate {
+ public:
+ delegate(int n) : n(n) {}
+ delegate(): delegate(2354) {}
+
+ virtual int getval() { return this->n; };
+ protected:
+ int n;
+ };
+
+ class overridden : public delegate {
+ public:
+ overridden(int n): delegate(n) {}
+ virtual int getval() override final { return this->n * 2; }
+ };
+
+ class nocopy {
+ public:
+ nocopy(int i): i(i) {}
+ nocopy() = default;
+ nocopy(const nocopy&) = delete;
+ nocopy & operator=(const nocopy&) = delete;
+ private:
+ int i;
+ };
+}
+]])# _AC_CXX_CXX11_TEST_HEADER
+
+# _AC_CXX_CXX11_TEST_BODY
+# -----------------------
+# A C++ body suitable for testing for CXX11, assuming the corresponding header.
+AC_DEFUN([_AC_CXX_CXX11_TEST_BODY],
+[[
+{
+ // Test auto and decltype
+ std::deque<int> d;
+ d.push_front(43);
+ d.push_front(484);
+ d.push_front(3);
+ d.push_front(844);
+ int total = 0;
+ for (auto i = d.begin(); i != d.end(); ++i) { total += *i; }
+
+ auto a1 = 6538;
+ auto a2 = 48573953.4;
+ auto a3 = "String literal";
+
+ decltype(a2) a4 = 34895.034;
+}
+{
+ // Test constexpr
+ short sa[cxx11test::get_val()] = { 0 };
+}
+{
+ // Test initializer lists
+ cxx11test::testinit il = { 4323, 435234.23544 };
+}
+{
+ // Test range-based for and lambda
+ cxx11test::int_array array = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, 14, 19, 17, 8, 6, 20, 16, 2, 11, 1};
+ for (int &x : array) { x += 23; }
+ std::for_each(array.begin(), array.end(), [](int v1){ std::cout << v1; });
+}
+{
+ using cxx11test::sptr;
+ using cxx11test::wptr;
+
+ sptr sp(new std::string("ASCII string"));
+ wptr wp(sp);
+ sptr sp2(wp);
+}
+{
+ cxx11test::tp tuple("test", 54, 45.53434);
+ double d = std::get<2>(tuple);
+ std::string s;
+ int i;
+ std::tie(s,i,d) = tuple;
+}
+{
+ static std::regex filename_regex("^_?([a-z0-9_.]+-)+[a-z0-9]+$");
+ std::string testmatch("Test if this string matches");
+ bool match = std::regex_search(testmatch, filename_regex);
+}
+{
+ cxx11test::int_array array = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, 14, 19, 17, 8, 6, 20, 16, 2, 11, 1};
+ cxx11test::int_array::size_type size = array.size();
+}
+{
+ // Test constructor delegation
+ cxx11test::delegate d1;
+ cxx11test::delegate d2();
+ cxx11test::delegate d3(45);
+}
+{
+ // Test override and final
+ cxx11test::overridden o1(55464);
+}
+{
+ // Test nullptr
+ char *c = nullptr;
+}
+{
+ // Test template brackets
+ std::vector<std::pair<int,char*>> v1;
+}
+{
+ // Unicode literals
+ char const *utf8 = u8"UTF-8 string \u2500";
+ char16_t const *utf16 = u"UTF-8 string \u2500";
+ char32_t const *utf32 = U"UTF-32 string \u2500";
+}
+]])
+
+# _AC_PROG_CXX_CXX98 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE])
+# -------------------------------------------------------------------
+
+# If the C++ compiler is not in ISO C++98 mode by default, try to add
+# an option to output variable CXX to make it so. This macro tries
+# various options that select ISO C++98 on some system or another. It
+# considers the compiler to be in ISO C++98 mode if it handles basic
+# features of the std namespace including: string, containers (list,
+# map, set, vector), streams (fstreams, iostreams, stringstreams,
+# iomanip), pair, exceptions and algorithms.
+
+
+AC_DEFUN([_AC_PROG_CXX_CXX98],
+[_AC_CXX_STD_TRY([cxx98],
+[_AC_CXX_CXX98_TEST_HEADER],
+[_AC_CXX_CXX98_TEST_BODY],
+dnl Try
+dnl GCC -std=gnu++98 (unused restrictive mode: -std=c++98)
+dnl IBM XL C -qlanglvl=extended
+dnl HP aC++ -AA
+dnl Intel ICC -std=gnu++98
+dnl Solaris N/A (default)
+dnl Tru64 N/A (default, but -std gnu could be used)
+dnl with extended modes being tried first.
+[[-std=gnu++98 -std=c++98 -qlanglvl=extended -AA]], [$1], [$2])[]dnl
+])# _AC_PROG_CXX_CXX98
+
+# _AC_PROG_CXX_CXX11 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE])
+# -------------------------------------------------------------------
+# If the C++ compiler is not in ISO CXX11 mode by default, try to add
+# an option to output variable CXX to make it so. This macro tries
+# various options that select ISO C++11 on some system or another. It
+# considers the compiler to be in ISO C++11 mode if it handles all the
+# tests from the C++98 checks, plus the following: Language features
+# (auto, constexpr, decltype, default/deleted constructors, delegate
+# constructors, final, initializer lists, lambda functions, nullptr,
+# override, range-based for loops, template brackets without spaces,
+# unicode literals) and library features (array, memory (shared_ptr,
+# weak_ptr), regex and tuple types).
+AC_DEFUN([_AC_PROG_CXX_CXX11],
+[_AC_CXX_STD_TRY([cxx11],
+[_AC_CXX_CXX11_TEST_HEADER
+_AC_CXX_CXX98_TEST_HEADER],
+[_AC_CXX_CXX11_TEST_BODY
+_AC_CXX_CXX98_TEST_BODY],
+dnl Try
+dnl GCC -std=gnu++11 (unused restrictive mode: -std=c++11) [and 0x variants]
+dnl IBM XL C -qlanglvl=extended0x
+dnl (pre-V12.1; unused restrictive mode: -qlanglvl=stdcxx11)
+dnl HP aC++ -AA
+dnl Intel ICC -std=c++11 -std=c++0x
+dnl Solaris N/A (no support)
+dnl Tru64 N/A (no support)
+dnl with extended modes being tried first.
+[[-std=gnu++11 -std=c++11 -std=gnu++0x -std=c++0x -qlanglvl=extended0x -AA]], [$1], [$2])[]dnl
+])# _AC_PROG_CXX_CXX11
+
+
+])# m4_version_prereq
diff --git a/src/m4/stdbool.m4 b/src/m4/stdbool.m4
new file mode 100644
index 0000000..3169779
--- /dev/null
+++ b/src/m4/stdbool.m4
@@ -0,0 +1,122 @@
+# Check for stdbool.h that conforms to C99.
+
+dnl Copyright (C) 2002-2006, 2009-2021 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+#serial 8
+
+# Prepare for substituting <stdbool.h> if it is not supported.
+
+AC_DEFUN([AM_STDBOOL_H],
+[
+ AC_REQUIRE([AC_CHECK_HEADER_STDBOOL])
+ AC_REQUIRE([AC_CANONICAL_HOST])
+
+ dnl On some platforms, <stdbool.h> does not exist or does not conform to C99.
+ dnl On Solaris 10 with CC=cc CXX=CC, <stdbool.h> exists but is not usable
+ dnl in C++ mode (and no <cstdbool> exists). In this case, we use our
+ dnl replacement, also in C mode (for binary compatibility between C and C++).
+ if test "$ac_cv_header_stdbool_h" = yes; then
+ case "$host_os" in
+ solaris*)
+ if test -z "$GCC"; then
+ STDBOOL_H='stdbool.h'
+ else
+ STDBOOL_H=''
+ fi
+ ;;
+ *)
+ STDBOOL_H=''
+ ;;
+ esac
+ else
+ STDBOOL_H='stdbool.h'
+ fi
+ AC_SUBST([STDBOOL_H])
+ AM_CONDITIONAL([GL_GENERATE_STDBOOL_H], [test -n "$STDBOOL_H"])
+
+ if test "$ac_cv_type__Bool" = yes; then
+ HAVE__BOOL=1
+ else
+ HAVE__BOOL=0
+ fi
+ AC_SUBST([HAVE__BOOL])
+])
+
+# AM_STDBOOL_H will be renamed to gl_STDBOOL_H in the future.
+AC_DEFUN([gl_STDBOOL_H], [AM_STDBOOL_H])
+
+# This version of the macro is needed in autoconf <= 2.68.
+
+AC_DEFUN([AC_CHECK_HEADER_STDBOOL],
+ [AC_CACHE_CHECK([for stdbool.h that conforms to C99],
+ [ac_cv_header_stdbool_h],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[
+ #include <stdbool.h>
+
+ #ifdef __cplusplus
+ typedef bool Bool;
+ #else
+ typedef _Bool Bool;
+ #ifndef bool
+ "error: bool is not defined"
+ #endif
+ #ifndef false
+ "error: false is not defined"
+ #endif
+ #if false
+ "error: false is not 0"
+ #endif
+ #ifndef true
+ "error: true is not defined"
+ #endif
+ #if true != 1
+ "error: true is not 1"
+ #endif
+ #endif
+
+ #ifndef __bool_true_false_are_defined
+ "error: __bool_true_false_are_defined is not defined"
+ #endif
+
+ struct s { Bool s: 1; Bool t; bool u: 1; bool v; } s;
+
+ char a[true == 1 ? 1 : -1];
+ char b[false == 0 ? 1 : -1];
+ char c[__bool_true_false_are_defined == 1 ? 1 : -1];
+ char d[(bool) 0.5 == true ? 1 : -1];
+ /* See body of main program for 'e'. */
+ char f[(Bool) 0.0 == false ? 1 : -1];
+ char g[true];
+ char h[sizeof (Bool)];
+ char i[sizeof s.t];
+ enum { j = false, k = true, l = false * true, m = true * 256 };
+ /* The following fails for
+ HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */
+ Bool n[m];
+ char o[sizeof n == m * sizeof n[0] ? 1 : -1];
+ char p[-1 - (Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1];
+ /* Catch a bug in an HP-UX C compiler. See
+ https://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
+ https://lists.gnu.org/r/bug-coreutils/2005-11/msg00161.html
+ */
+ Bool q = true;
+ Bool *pq = &q;
+ bool *qq = &q;
+ ]],
+ [[
+ bool e = &s;
+ *pq |= q; *pq |= ! q;
+ *qq |= q; *qq |= ! q;
+ /* Refer to every declared value, to avoid compiler optimizations. */
+ return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l
+ + !m + !n + !o + !p + !q + !pq + !qq);
+ ]])],
+ [ac_cv_header_stdbool_h=yes],
+ [ac_cv_header_stdbool_h=no])])
+ AC_CHECK_TYPES([_Bool])
+])
diff --git a/src/m4/stdint.m4 b/src/m4/stdint.m4
new file mode 100644
index 0000000..a785b44
--- /dev/null
+++ b/src/m4/stdint.m4
@@ -0,0 +1,533 @@
+# stdint.m4 serial 58
+dnl Copyright (C) 2001-2021 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Paul Eggert and Bruno Haible.
+dnl Test whether <stdint.h> is supported or must be substituted.
+
+AC_PREREQ([2.61])
+
+AC_DEFUN_ONCE([gl_STDINT_H],
+[
+ AC_PREREQ([2.59])dnl
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+
+ AC_REQUIRE([gl_LIMITS_H])
+ AC_REQUIRE([gt_TYPE_WINT_T])
+
+ dnl For backward compatibility. Some packages may still be testing these
+ dnl macros.
+ AC_DEFINE([HAVE_LONG_LONG_INT], [1],
+ [Define to 1 if the system has the type 'long long int'.])
+ AC_DEFINE([HAVE_UNSIGNED_LONG_LONG_INT], [1],
+ [Define to 1 if the system has the type 'unsigned long long int'.])
+
+ dnl Check for <wchar.h>, in the same way as gl_WCHAR_H does.
+ AC_CHECK_HEADERS_ONCE([wchar.h])
+ if test $ac_cv_header_wchar_h = yes; then
+ HAVE_WCHAR_H=1
+ else
+ HAVE_WCHAR_H=0
+ fi
+ AC_SUBST([HAVE_WCHAR_H])
+
+ dnl Check for <inttypes.h>.
+ AC_CHECK_HEADERS_ONCE([inttypes.h])
+ if test $ac_cv_header_inttypes_h = yes; then
+ HAVE_INTTYPES_H=1
+ else
+ HAVE_INTTYPES_H=0
+ fi
+ AC_SUBST([HAVE_INTTYPES_H])
+
+ dnl Check for <sys/types.h>.
+ AC_CHECK_HEADERS_ONCE([sys/types.h])
+ if test $ac_cv_header_sys_types_h = yes; then
+ HAVE_SYS_TYPES_H=1
+ else
+ HAVE_SYS_TYPES_H=0
+ fi
+ AC_SUBST([HAVE_SYS_TYPES_H])
+
+ gl_CHECK_NEXT_HEADERS([stdint.h])
+ if test $ac_cv_header_stdint_h = yes; then
+ HAVE_STDINT_H=1
+ else
+ HAVE_STDINT_H=0
+ fi
+ AC_SUBST([HAVE_STDINT_H])
+
+ dnl Now see whether we need a substitute <stdint.h>.
+ if test $ac_cv_header_stdint_h = yes; then
+ AC_CACHE_CHECK([whether stdint.h conforms to C99],
+ [gl_cv_header_working_stdint_h],
+ [gl_cv_header_working_stdint_h=no
+ AC_COMPILE_IFELSE([
+ AC_LANG_PROGRAM([[
+#define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */
+#define __STDC_CONSTANT_MACROS 1
+#define __STDC_LIMIT_MACROS 1
+#include <stdint.h>
+/* Dragonfly defines WCHAR_MIN, WCHAR_MAX only in <wchar.h>. */
+#if !(defined WCHAR_MIN && defined WCHAR_MAX)
+#error "WCHAR_MIN, WCHAR_MAX not defined in <stdint.h>"
+#endif
+]
+gl_STDINT_INCLUDES
+[
+#ifdef INT8_MAX
+int8_t a1 = INT8_MAX;
+int8_t a1min = INT8_MIN;
+#endif
+#ifdef INT16_MAX
+int16_t a2 = INT16_MAX;
+int16_t a2min = INT16_MIN;
+#endif
+#ifdef INT32_MAX
+int32_t a3 = INT32_MAX;
+int32_t a3min = INT32_MIN;
+#endif
+#ifdef INT64_MAX
+int64_t a4 = INT64_MAX;
+int64_t a4min = INT64_MIN;
+#endif
+#ifdef UINT8_MAX
+uint8_t b1 = UINT8_MAX;
+#else
+typedef int b1[(unsigned char) -1 != 255 ? 1 : -1];
+#endif
+#ifdef UINT16_MAX
+uint16_t b2 = UINT16_MAX;
+#endif
+#ifdef UINT32_MAX
+uint32_t b3 = UINT32_MAX;
+#endif
+#ifdef UINT64_MAX
+uint64_t b4 = UINT64_MAX;
+#endif
+int_least8_t c1 = INT8_C (0x7f);
+int_least8_t c1max = INT_LEAST8_MAX;
+int_least8_t c1min = INT_LEAST8_MIN;
+int_least16_t c2 = INT16_C (0x7fff);
+int_least16_t c2max = INT_LEAST16_MAX;
+int_least16_t c2min = INT_LEAST16_MIN;
+int_least32_t c3 = INT32_C (0x7fffffff);
+int_least32_t c3max = INT_LEAST32_MAX;
+int_least32_t c3min = INT_LEAST32_MIN;
+int_least64_t c4 = INT64_C (0x7fffffffffffffff);
+int_least64_t c4max = INT_LEAST64_MAX;
+int_least64_t c4min = INT_LEAST64_MIN;
+uint_least8_t d1 = UINT8_C (0xff);
+uint_least8_t d1max = UINT_LEAST8_MAX;
+uint_least16_t d2 = UINT16_C (0xffff);
+uint_least16_t d2max = UINT_LEAST16_MAX;
+uint_least32_t d3 = UINT32_C (0xffffffff);
+uint_least32_t d3max = UINT_LEAST32_MAX;
+uint_least64_t d4 = UINT64_C (0xffffffffffffffff);
+uint_least64_t d4max = UINT_LEAST64_MAX;
+int_fast8_t e1 = INT_FAST8_MAX;
+int_fast8_t e1min = INT_FAST8_MIN;
+int_fast16_t e2 = INT_FAST16_MAX;
+int_fast16_t e2min = INT_FAST16_MIN;
+int_fast32_t e3 = INT_FAST32_MAX;
+int_fast32_t e3min = INT_FAST32_MIN;
+int_fast64_t e4 = INT_FAST64_MAX;
+int_fast64_t e4min = INT_FAST64_MIN;
+uint_fast8_t f1 = UINT_FAST8_MAX;
+uint_fast16_t f2 = UINT_FAST16_MAX;
+uint_fast32_t f3 = UINT_FAST32_MAX;
+uint_fast64_t f4 = UINT_FAST64_MAX;
+#ifdef INTPTR_MAX
+intptr_t g = INTPTR_MAX;
+intptr_t gmin = INTPTR_MIN;
+#endif
+#ifdef UINTPTR_MAX
+uintptr_t h = UINTPTR_MAX;
+#endif
+intmax_t i = INTMAX_MAX;
+uintmax_t j = UINTMAX_MAX;
+
+/* Check that SIZE_MAX has the correct type, if possible. */
+#if 201112 <= __STDC_VERSION__
+int k = _Generic (SIZE_MAX, size_t: 0);
+#elif (2 <= __GNUC__ || 4 <= __clang_major__ || defined __IBM__TYPEOF__ \
+ || (0x5110 <= __SUNPRO_C && !__STDC__))
+extern size_t k;
+extern __typeof__ (SIZE_MAX) k;
+#endif
+
+#include <limits.h> /* for CHAR_BIT */
+#define TYPE_MINIMUM(t) \
+ ((t) ((t) 0 < (t) -1 ? (t) 0 : ~ TYPE_MAXIMUM (t)))
+#define TYPE_MAXIMUM(t) \
+ ((t) ((t) 0 < (t) -1 \
+ ? (t) -1 \
+ : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1)))
+struct s {
+ int check_PTRDIFF:
+ PTRDIFF_MIN == TYPE_MINIMUM (ptrdiff_t)
+ && PTRDIFF_MAX == TYPE_MAXIMUM (ptrdiff_t)
+ ? 1 : -1;
+ /* Detect bug in FreeBSD 6.0 / ia64. */
+ int check_SIG_ATOMIC:
+ SIG_ATOMIC_MIN == TYPE_MINIMUM (sig_atomic_t)
+ && SIG_ATOMIC_MAX == TYPE_MAXIMUM (sig_atomic_t)
+ ? 1 : -1;
+ int check_SIZE: SIZE_MAX == TYPE_MAXIMUM (size_t) ? 1 : -1;
+ int check_WCHAR:
+ WCHAR_MIN == TYPE_MINIMUM (wchar_t)
+ && WCHAR_MAX == TYPE_MAXIMUM (wchar_t)
+ ? 1 : -1;
+ /* Detect bug in mingw. */
+ int check_WINT:
+ WINT_MIN == TYPE_MINIMUM (wint_t)
+ && WINT_MAX == TYPE_MAXIMUM (wint_t)
+ ? 1 : -1;
+
+ /* Detect bugs in glibc 2.4 and Solaris 10 stdint.h, among others. */
+ int check_UINT8_C:
+ (-1 < UINT8_C (0)) == (-1 < (uint_least8_t) 0) ? 1 : -1;
+ int check_UINT16_C:
+ (-1 < UINT16_C (0)) == (-1 < (uint_least16_t) 0) ? 1 : -1;
+
+ /* Detect bugs in OpenBSD 3.9 stdint.h. */
+#ifdef UINT8_MAX
+ int check_uint8: (uint8_t) -1 == UINT8_MAX ? 1 : -1;
+#endif
+#ifdef UINT16_MAX
+ int check_uint16: (uint16_t) -1 == UINT16_MAX ? 1 : -1;
+#endif
+#ifdef UINT32_MAX
+ int check_uint32: (uint32_t) -1 == UINT32_MAX ? 1 : -1;
+#endif
+#ifdef UINT64_MAX
+ int check_uint64: (uint64_t) -1 == UINT64_MAX ? 1 : -1;
+#endif
+ int check_uint_least8: (uint_least8_t) -1 == UINT_LEAST8_MAX ? 1 : -1;
+ int check_uint_least16: (uint_least16_t) -1 == UINT_LEAST16_MAX ? 1 : -1;
+ int check_uint_least32: (uint_least32_t) -1 == UINT_LEAST32_MAX ? 1 : -1;
+ int check_uint_least64: (uint_least64_t) -1 == UINT_LEAST64_MAX ? 1 : -1;
+ int check_uint_fast8: (uint_fast8_t) -1 == UINT_FAST8_MAX ? 1 : -1;
+ int check_uint_fast16: (uint_fast16_t) -1 == UINT_FAST16_MAX ? 1 : -1;
+ int check_uint_fast32: (uint_fast32_t) -1 == UINT_FAST32_MAX ? 1 : -1;
+ int check_uint_fast64: (uint_fast64_t) -1 == UINT_FAST64_MAX ? 1 : -1;
+ int check_uintptr: (uintptr_t) -1 == UINTPTR_MAX ? 1 : -1;
+ int check_uintmax: (uintmax_t) -1 == UINTMAX_MAX ? 1 : -1;
+ int check_size: (size_t) -1 == SIZE_MAX ? 1 : -1;
+};
+ ]])],
+ [dnl Determine whether the various *_MIN, *_MAX macros are usable
+ dnl in preprocessor expression. We could do it by compiling a test
+ dnl program for each of these macros. It is faster to run a program
+ dnl that inspects the macro expansion.
+ dnl This detects a bug on HP-UX 11.23/ia64.
+ AC_RUN_IFELSE([
+ AC_LANG_PROGRAM([[
+#define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */
+#define __STDC_CONSTANT_MACROS 1
+#define __STDC_LIMIT_MACROS 1
+#include <stdint.h>
+]
+gl_STDINT_INCLUDES
+[
+#include <stdio.h>
+#include <string.h>
+#define MVAL(macro) MVAL1(macro)
+#define MVAL1(expression) #expression
+static const char *macro_values[] =
+ {
+#ifdef INT8_MAX
+ MVAL (INT8_MAX),
+#endif
+#ifdef INT16_MAX
+ MVAL (INT16_MAX),
+#endif
+#ifdef INT32_MAX
+ MVAL (INT32_MAX),
+#endif
+#ifdef INT64_MAX
+ MVAL (INT64_MAX),
+#endif
+#ifdef UINT8_MAX
+ MVAL (UINT8_MAX),
+#endif
+#ifdef UINT16_MAX
+ MVAL (UINT16_MAX),
+#endif
+#ifdef UINT32_MAX
+ MVAL (UINT32_MAX),
+#endif
+#ifdef UINT64_MAX
+ MVAL (UINT64_MAX),
+#endif
+ NULL
+ };
+]], [[
+ const char **mv;
+ for (mv = macro_values; *mv != NULL; mv++)
+ {
+ const char *value = *mv;
+ /* Test whether it looks like a cast expression. */
+ if (strncmp (value, "((unsigned int)"/*)*/, 15) == 0
+ || strncmp (value, "((unsigned short)"/*)*/, 17) == 0
+ || strncmp (value, "((unsigned char)"/*)*/, 16) == 0
+ || strncmp (value, "((int)"/*)*/, 6) == 0
+ || strncmp (value, "((signed short)"/*)*/, 15) == 0
+ || strncmp (value, "((signed char)"/*)*/, 14) == 0)
+ return mv - macro_values + 1;
+ }
+ return 0;
+]])],
+ [gl_cv_header_working_stdint_h=yes],
+ [],
+ [case "$host_os" in
+ # Guess yes on native Windows.
+ mingw*) gl_cv_header_working_stdint_h="guessing yes" ;;
+ # In general, assume it works.
+ *) gl_cv_header_working_stdint_h="guessing yes" ;;
+ esac
+ ])
+ ])
+ ])
+ fi
+
+ HAVE_C99_STDINT_H=0
+ HAVE_SYS_BITYPES_H=0
+ HAVE_SYS_INTTYPES_H=0
+ STDINT_H=stdint.h
+ case "$gl_cv_header_working_stdint_h" in
+ *yes)
+ HAVE_C99_STDINT_H=1
+ dnl Now see whether the system <stdint.h> works without
+ dnl __STDC_CONSTANT_MACROS/__STDC_LIMIT_MACROS defined.
+ dnl If not, there would be problems when stdint.h is included from C++.
+ AC_CACHE_CHECK([whether stdint.h works without ISO C predefines],
+ [gl_cv_header_stdint_without_STDC_macros],
+ [gl_cv_header_stdint_without_STDC_macros=no
+ AC_COMPILE_IFELSE([
+ AC_LANG_PROGRAM([[
+#define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */
+#include <stdint.h>
+]
+gl_STDINT_INCLUDES
+[
+intmax_t im = INTMAX_MAX;
+int32_t i32 = INT32_C (0x7fffffff);
+ ]])],
+ [gl_cv_header_stdint_without_STDC_macros=yes])
+ ])
+
+ if test $gl_cv_header_stdint_without_STDC_macros = no; then
+ AC_DEFINE([__STDC_CONSTANT_MACROS], [1],
+ [Define to 1 if the system <stdint.h> predates C++11.])
+ AC_DEFINE([__STDC_LIMIT_MACROS], [1],
+ [Define to 1 if the system <stdint.h> predates C++11.])
+ fi
+ AC_CACHE_CHECK([whether stdint.h has UINTMAX_WIDTH etc.],
+ [gl_cv_header_stdint_width],
+ [gl_cv_header_stdint_width=no
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[
+ /* Work if build is not clean. */
+ #define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1
+ #ifndef __STDC_WANT_IEC_60559_BFP_EXT__
+ #define __STDC_WANT_IEC_60559_BFP_EXT__ 1
+ #endif
+ #include <stdint.h>
+ ]gl_STDINT_INCLUDES[
+ int iw = UINTMAX_WIDTH;
+ ]])],
+ [gl_cv_header_stdint_width=yes])])
+ if test "$gl_cv_header_stdint_width" = yes; then
+ STDINT_H=
+ fi
+ ;;
+ *)
+ dnl Check for <sys/inttypes.h>, and for
+ dnl <sys/bitypes.h> (used in Linux libc4 >= 4.6.7 and libc5).
+ AC_CHECK_HEADERS([sys/inttypes.h sys/bitypes.h])
+ if test $ac_cv_header_sys_inttypes_h = yes; then
+ HAVE_SYS_INTTYPES_H=1
+ fi
+ if test $ac_cv_header_sys_bitypes_h = yes; then
+ HAVE_SYS_BITYPES_H=1
+ fi
+ gl_STDINT_TYPE_PROPERTIES
+ ;;
+ esac
+
+ dnl The substitute stdint.h needs the substitute limit.h's _GL_INTEGER_WIDTH.
+ gl_REPLACE_LIMITS_H
+
+ AC_SUBST([HAVE_C99_STDINT_H])
+ AC_SUBST([HAVE_SYS_BITYPES_H])
+ AC_SUBST([HAVE_SYS_INTTYPES_H])
+ AC_SUBST([STDINT_H])
+ AM_CONDITIONAL([GL_GENERATE_STDINT_H], [test -n "$STDINT_H"])
+])
+
+dnl gl_STDINT_BITSIZEOF(TYPES, INCLUDES)
+dnl Determine the size of each of the given types in bits.
+AC_DEFUN([gl_STDINT_BITSIZEOF],
+[
+ dnl Use a shell loop, to avoid bloating configure, and
+ dnl - extra AH_TEMPLATE calls, so that autoheader knows what to put into
+ dnl config.h.in,
+ dnl - extra AC_SUBST calls, so that the right substitutions are made.
+ m4_foreach_w([gltype], [$1],
+ [AH_TEMPLATE([BITSIZEOF_]m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]),
+ [Define to the number of bits in type ']gltype['.])])
+ for gltype in $1 ; do
+ AC_CACHE_CHECK([for bit size of $gltype], [gl_cv_bitsizeof_${gltype}],
+ [AC_COMPUTE_INT([result], [sizeof ($gltype) * CHAR_BIT],
+ [$2
+#include <limits.h>], [result=unknown])
+ eval gl_cv_bitsizeof_${gltype}=\$result
+ ])
+ eval result=\$gl_cv_bitsizeof_${gltype}
+ if test $result = unknown; then
+ dnl Use a nonempty default, because some compilers, such as IRIX 5 cc,
+ dnl do a syntax check even on unused #if conditions and give an error
+ dnl on valid C code like this:
+ dnl #if 0
+ dnl # if > 32
+ dnl # endif
+ dnl #endif
+ result=0
+ fi
+ GLTYPE=`echo "$gltype" | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'`
+ AC_DEFINE_UNQUOTED([BITSIZEOF_${GLTYPE}], [$result])
+ eval BITSIZEOF_${GLTYPE}=\$result
+ done
+ m4_foreach_w([gltype], [$1],
+ [AC_SUBST([BITSIZEOF_]m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]))])
+])
+
+dnl gl_CHECK_TYPES_SIGNED(TYPES, INCLUDES)
+dnl Determine the signedness of each of the given types.
+dnl Define HAVE_SIGNED_TYPE if type is signed.
+AC_DEFUN([gl_CHECK_TYPES_SIGNED],
+[
+ dnl Use a shell loop, to avoid bloating configure, and
+ dnl - extra AH_TEMPLATE calls, so that autoheader knows what to put into
+ dnl config.h.in,
+ dnl - extra AC_SUBST calls, so that the right substitutions are made.
+ m4_foreach_w([gltype], [$1],
+ [AH_TEMPLATE([HAVE_SIGNED_]m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]),
+ [Define to 1 if ']gltype[' is a signed integer type.])])
+ for gltype in $1 ; do
+ AC_CACHE_CHECK([whether $gltype is signed], [gl_cv_type_${gltype}_signed],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([$2[
+ int verify[2 * (($gltype) -1 < ($gltype) 0) - 1];]])],
+ result=yes, result=no)
+ eval gl_cv_type_${gltype}_signed=\$result
+ ])
+ eval result=\$gl_cv_type_${gltype}_signed
+ GLTYPE=`echo $gltype | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'`
+ if test "$result" = yes; then
+ AC_DEFINE_UNQUOTED([HAVE_SIGNED_${GLTYPE}], [1])
+ eval HAVE_SIGNED_${GLTYPE}=1
+ else
+ eval HAVE_SIGNED_${GLTYPE}=0
+ fi
+ done
+ m4_foreach_w([gltype], [$1],
+ [AC_SUBST([HAVE_SIGNED_]m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]))])
+])
+
+dnl gl_INTEGER_TYPE_SUFFIX(TYPES, INCLUDES)
+dnl Determine the suffix to use for integer constants of the given types.
+dnl Define t_SUFFIX for each such type.
+AC_DEFUN([gl_INTEGER_TYPE_SUFFIX],
+[
+ dnl Use a shell loop, to avoid bloating configure, and
+ dnl - extra AH_TEMPLATE calls, so that autoheader knows what to put into
+ dnl config.h.in,
+ dnl - extra AC_SUBST calls, so that the right substitutions are made.
+ m4_foreach_w([gltype], [$1],
+ [AH_TEMPLATE(m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_])[_SUFFIX],
+ [Define to l, ll, u, ul, ull, etc., as suitable for
+ constants of type ']gltype['.])])
+ for gltype in $1 ; do
+ AC_CACHE_CHECK([for $gltype integer literal suffix],
+ [gl_cv_type_${gltype}_suffix],
+ [eval gl_cv_type_${gltype}_suffix=no
+ eval result=\$gl_cv_type_${gltype}_signed
+ if test "$result" = yes; then
+ glsufu=
+ else
+ glsufu=u
+ fi
+ for glsuf in "$glsufu" ${glsufu}l ${glsufu}ll ${glsufu}i64; do
+ case $glsuf in
+ '') gltype1='int';;
+ l) gltype1='long int';;
+ ll) gltype1='long long int';;
+ i64) gltype1='__int64';;
+ u) gltype1='unsigned int';;
+ ul) gltype1='unsigned long int';;
+ ull) gltype1='unsigned long long int';;
+ ui64)gltype1='unsigned __int64';;
+ esac
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([$2[
+ extern $gltype foo;
+ extern $gltype1 foo;]])],
+ [eval gl_cv_type_${gltype}_suffix=\$glsuf])
+ eval result=\$gl_cv_type_${gltype}_suffix
+ test "$result" != no && break
+ done])
+ GLTYPE=`echo $gltype | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'`
+ eval result=\$gl_cv_type_${gltype}_suffix
+ test "$result" = no && result=
+ eval ${GLTYPE}_SUFFIX=\$result
+ AC_DEFINE_UNQUOTED([${GLTYPE}_SUFFIX], [$result])
+ done
+ m4_foreach_w([gltype], [$1],
+ [AC_SUBST(m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_])[_SUFFIX])])
+])
+
+dnl gl_STDINT_INCLUDES
+AC_DEFUN([gl_STDINT_INCLUDES],
+[[
+ #include <stddef.h>
+ #include <signal.h>
+ #if HAVE_WCHAR_H
+ # include <wchar.h>
+ #endif
+]])
+
+dnl gl_STDINT_TYPE_PROPERTIES
+dnl Compute HAVE_SIGNED_t, BITSIZEOF_t and t_SUFFIX, for all the types t
+dnl of interest to stdint.in.h.
+AC_DEFUN([gl_STDINT_TYPE_PROPERTIES],
+[
+ AC_REQUIRE([gl_MULTIARCH])
+ if test $APPLE_UNIVERSAL_BUILD = 0; then
+ gl_STDINT_BITSIZEOF([ptrdiff_t size_t],
+ [gl_STDINT_INCLUDES])
+ fi
+ gl_STDINT_BITSIZEOF([sig_atomic_t wchar_t wint_t],
+ [gl_STDINT_INCLUDES])
+ gl_CHECK_TYPES_SIGNED([sig_atomic_t wchar_t wint_t],
+ [gl_STDINT_INCLUDES])
+ gl_cv_type_ptrdiff_t_signed=yes
+ gl_cv_type_size_t_signed=no
+ if test $APPLE_UNIVERSAL_BUILD = 0; then
+ gl_INTEGER_TYPE_SUFFIX([ptrdiff_t size_t],
+ [gl_STDINT_INCLUDES])
+ fi
+ gl_INTEGER_TYPE_SUFFIX([sig_atomic_t wchar_t wint_t],
+ [gl_STDINT_INCLUDES])
+
+ dnl If wint_t is smaller than 'int', it cannot satisfy the ISO C 99
+ dnl requirement that wint_t is "unchanged by default argument promotions".
+ dnl In this case gnulib's <wchar.h> and <wctype.h> override wint_t.
+ dnl Set the variable BITSIZEOF_WINT_T accordingly.
+ if test $GNULIB_OVERRIDES_WINT_T = 1; then
+ BITSIZEOF_WINT_T=32
+ fi
+])
diff --git a/src/m4/sys_types_h.m4 b/src/m4/sys_types_h.m4
new file mode 100644
index 0000000..2172c83
--- /dev/null
+++ b/src/m4/sys_types_h.m4
@@ -0,0 +1,58 @@
+# sys_types_h.m4 serial 11
+dnl Copyright (C) 2011-2021 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN_ONCE([gl_SYS_TYPES_H],
+[
+ dnl Use sane struct stat types in OpenVMS 8.2 and later.
+ AC_DEFINE([_USE_STD_STAT], 1, [For standard stat data types on VMS.])
+
+ AC_REQUIRE([gl_SYS_TYPES_H_DEFAULTS])
+ gl_NEXT_HEADERS([sys/types.h])
+
+ dnl Ensure the type pid_t gets defined.
+ AC_REQUIRE([AC_TYPE_PID_T])
+
+ dnl Ensure the type mode_t gets defined.
+ AC_REQUIRE([AC_TYPE_MODE_T])
+
+ dnl Whether to override the 'off_t' type.
+ AC_REQUIRE([gl_TYPE_OFF_T])
+
+ dnl Whether to override the 'dev_t' and 'ino_t' types.
+ m4_ifdef([gl_WINDOWS_STAT_INODES], [
+ AC_REQUIRE([gl_WINDOWS_STAT_INODES])
+ ], [
+ WINDOWS_STAT_INODES=0
+ ])
+ AC_SUBST([WINDOWS_STAT_INODES])
+])
+
+AC_DEFUN([gl_SYS_TYPES_H_DEFAULTS],
+[
+])
+
+# This works around a buggy version in autoconf <= 2.69.
+# See <https://lists.gnu.org/r/autoconf/2016-08/msg00014.html>
+# The 2.70 version isn't quoted properly, so override it too.
+
+m4_version_prereq([2.70.1], [], [
+
+m4_undefine([AC_HEADER_MAJOR])
+AC_DEFUN([AC_HEADER_MAJOR],
+[AC_CHECK_HEADERS_ONCE([sys/types.h])
+AC_CHECK_HEADER([sys/mkdev.h],
+ [AC_DEFINE([MAJOR_IN_MKDEV], [1],
+ [Define to 1 if `major', `minor', and `makedev' are
+ declared in <mkdev.h>.])])
+if test $ac_cv_header_sys_mkdev_h = no; then
+ AC_CHECK_HEADER([sys/sysmacros.h],
+ [AC_DEFINE([MAJOR_IN_SYSMACROS], [1],
+ [Define to 1 if `major', `minor', and `makedev'
+ are declared in <sysmacros.h>.])])
+fi
+])# AC_HEADER_MAJOR
+
+])
diff --git a/src/m4/wint_t.m4 b/src/m4/wint_t.m4
new file mode 100644
index 0000000..2fc7467
--- /dev/null
+++ b/src/m4/wint_t.m4
@@ -0,0 +1,57 @@
+# wint_t.m4 serial 10
+dnl Copyright (C) 2003, 2007-2021 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+dnl Test whether <wchar.h> has the 'wint_t' type and whether gnulib's
+dnl <wchar.h> or <wctype.h> would, if present, override 'wint_t'.
+dnl Prerequisite: AC_PROG_CC
+
+AC_DEFUN([gt_TYPE_WINT_T],
+[
+ AC_CACHE_CHECK([for wint_t], [gt_cv_c_wint_t],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <wchar.h>
+ wint_t foo = (wchar_t)'\0';]],
+ [[]])],
+ [gt_cv_c_wint_t=yes],
+ [gt_cv_c_wint_t=no])])
+ if test $gt_cv_c_wint_t = yes; then
+ AC_DEFINE([HAVE_WINT_T], [1], [Define if you have the 'wint_t' type.])
+
+ dnl Determine whether gnulib's <wchar.h> or <wctype.h> would, if present,
+ dnl override 'wint_t'.
+ AC_CACHE_CHECK([whether wint_t is large enough],
+ [gl_cv_type_wint_t_large_enough],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <wchar.h>
+ int verify[sizeof (wint_t) < sizeof (int) ? -1 : 1];
+ ]])],
+ [gl_cv_type_wint_t_large_enough=yes],
+ [gl_cv_type_wint_t_large_enough=no])])
+ if test $gl_cv_type_wint_t_large_enough = no; then
+ GNULIB_OVERRIDES_WINT_T=1
+ else
+ GNULIB_OVERRIDES_WINT_T=0
+ fi
+ else
+ GNULIB_OVERRIDES_WINT_T=0
+ fi
+ AC_SUBST([GNULIB_OVERRIDES_WINT_T])
+])
+
+dnl Prerequisites of the 'wint_t' override.
+AC_DEFUN([gl_TYPE_WINT_T_PREREQ],
+[
+ AC_CHECK_HEADERS_ONCE([crtdefs.h])
+ if test $ac_cv_header_crtdefs_h = yes; then
+ HAVE_CRTDEFS_H=1
+ else
+ HAVE_CRTDEFS_H=0
+ fi
+ AC_SUBST([HAVE_CRTDEFS_H])
+])
diff --git a/src/m4/xsize.m4 b/src/m4/xsize.m4
new file mode 100644
index 0000000..64e8a4f
--- /dev/null
+++ b/src/m4/xsize.m4
@@ -0,0 +1,12 @@
+# xsize.m4 serial 5
+dnl Copyright (C) 2003-2004, 2008-2021 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_XSIZE],
+[
+ dnl Prerequisites of lib/xsize.h.
+ AC_REQUIRE([gl_SIZE_MAX])
+ AC_CHECK_HEADERS([stdint.h])
+])
diff --git a/src/m4/zzgnulib.m4 b/src/m4/zzgnulib.m4
new file mode 100644
index 0000000..b953384
--- /dev/null
+++ b/src/m4/zzgnulib.m4
@@ -0,0 +1,23 @@
+# zzgnulib.m4 serial 1
+dnl Copyright (C) 2020-2021 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This file must be named something that sorts after all other
+dnl package- or gnulib-provided .m4 files - at least for those packages
+dnl that redefine AC_PROG_CC.
+
+dnl Redefine AC_PROG_CC so that it ends with invocations of gl_COMPILER_CLANG
+dnl and gl_COMPILER_PREPARE_CHECK_DECL.
+m4_define([AC_PROG_CC],
+ m4_defn([AC_PROG_CC])[
+gl_COMPILER_CLANG
+gl_COMPILER_PREPARE_CHECK_DECL
+])
+
+# gl_ZZGNULIB
+# -----------
+# Witness macro that this file has been included. Needed to force
+# Automake to include this file after all other gnulib .m4 files.
+AC_DEFUN([gl_ZZGNULIB])
diff --git a/src/main.c b/src/main.c
index 83e60d8..a437b6b 100644
--- a/src/main.c
+++ b/src/main.c
@@ -20,6 +20,7 @@
#include "config.h"
#endif
#include "openocd.h"
+#include "helper/system.h"
/* This is the main entry for developer PC hosted OpenOCD.
*
diff --git a/src/pld/pld.c b/src/pld/pld.c
index ef7993c..6f4da12 100644
--- a/src/pld/pld.c
+++ b/src/pld/pld.c
@@ -22,6 +22,7 @@
#include "pld.h"
#include <helper/log.h>
+#include <helper/replacements.h>
#include <helper/time_support.h>
diff --git a/src/pld/xilinx_bit.c b/src/pld/xilinx_bit.c
index f83d894..a530ee7 100644
--- a/src/pld/xilinx_bit.c
+++ b/src/pld/xilinx_bit.c
@@ -25,7 +25,7 @@
#include <helper/log.h>
#include <sys/stat.h>
-
+#include <helper/system.h>
static int read_section(FILE *input_file, int length_size, char section,
uint32_t *buffer_length, uint8_t **buffer)
diff --git a/src/pld/xilinx_bit.h b/src/pld/xilinx_bit.h
index 1a35c3b..625a9d3 100644
--- a/src/pld/xilinx_bit.h
+++ b/src/pld/xilinx_bit.h
@@ -19,6 +19,8 @@
#ifndef OPENOCD_PLD_XILINX_BIT_H
#define OPENOCD_PLD_XILINX_BIT_H
+#include "helper/types.h"
+
struct xilinx_bit_file {
uint8_t unknown_header[13];
uint8_t *source_file;
diff --git a/src/rtos/FreeRTOS.c b/src/rtos/FreeRTOS.c
index ee9b48b..697f189 100644
--- a/src/rtos/FreeRTOS.c
+++ b/src/rtos/FreeRTOS.c
@@ -27,12 +27,11 @@
#include "rtos.h"
#include "helper/log.h"
#include "helper/types.h"
+#include "gnulib/gl_linkedhash_map.h"
#include "rtos_standard_stackings.h"
#include "target/armv7m.h"
#include "target/cortex_m.h"
-
-
#define FREERTOS_MAX_PRIORITIES 63
#define FreeRTOS_STRUCT(int_type, ptr_type, list_prev_offset)
@@ -52,11 +51,85 @@ struct FreeRTOS_params {
const unsigned char list_elem_content_offset;
const unsigned char thread_stack_offset;
const unsigned char thread_name_offset;
- const struct rtos_register_stacking *stacking_info_cm3;
- const struct rtos_register_stacking *stacking_info_cm4f;
- const struct rtos_register_stacking *stacking_info_cm4f_fpu;
+ int (*stacking)(struct rtos *rtos, const struct rtos_register_stacking **stacking,
+ target_addr_t stack_ptr);
+};
+
+struct FreeRTOS_thread_entry {
+ threadid_t threadid;
+ target_addr_t tcb;
};
+struct FreeRTOS {
+ const struct FreeRTOS_params *param;
+ threadid_t last_threadid;
+ /* Map from threadid to FreeRTOS_thread_entry. This map owns the value and
+ * is responsible for free()ing it. */
+ gl_map_t entry_by_threadid;
+ /* Map from tcb to FreeRTOS_thread_entry. */
+ gl_map_t entry_by_tcb;
+};
+
+static int cortex_m_stacking(struct rtos *rtos, const struct rtos_register_stacking **stacking,
+ target_addr_t stack_ptr)
+{
+ /* Check for armv7m with *enabled* FPU, i.e. a Cortex-M4F */
+ int cm4_fpu_enabled = 0;
+ struct armv7m_common *armv7m_target = target_to_armv7m(rtos->target);
+ if (is_armv7m(armv7m_target)) {
+ if (armv7m_target->fp_feature == FPv4_SP) {
+ /* Found ARM v7m target which includes a FPU */
+ uint32_t cpacr;
+
+ int retval = target_read_u32(rtos->target, FPU_CPACR, &cpacr);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Could not read CPACR register to check FPU state");
+ return retval;
+ }
+
+ /* Check if CP10 and CP11 are set to full access. */
+ if (cpacr & 0x00F00000) {
+ /* Found target with enabled FPU */
+ cm4_fpu_enabled = 1;
+ }
+ }
+ }
+
+ if (cm4_fpu_enabled == 1) {
+ /* Read the LR to decide between stacking with or without FPU */
+ uint32_t LR_svc = 0;
+ int retval = target_read_u32(rtos->target,
+ stack_ptr + 0x20,
+ &LR_svc);
+ if (retval != ERROR_OK) {
+ LOG_OUTPUT("Error reading stack frame from FreeRTOS thread");
+ return retval;
+ }
+ if ((LR_svc & 0x10) == 0)
+ *stacking = &rtos_standard_Cortex_M4F_FPU_stacking;
+ else
+ *stacking = &rtos_standard_Cortex_M4F_stacking;
+ } else {
+ *stacking = &rtos_standard_Cortex_M3_stacking;
+ }
+
+ return ERROR_OK;
+}
+
+static int nds32_stacking(struct rtos *rtos, const struct rtos_register_stacking **stacking,
+ target_addr_t stack_ptr)
+{
+ *stacking = &rtos_standard_NDS32_N1068_stacking;
+ return ERROR_OK;
+}
+
+static int riscv_stacking(struct rtos *rtos, const struct rtos_register_stacking **stacking,
+ target_addr_t stack_ptr)
+{
+ *stacking = &rtos_standard_RV32_stacking;
+ return ERROR_OK;
+}
+
static const struct FreeRTOS_params FreeRTOS_params_list[] = {
{
"cortex_m", /* target_name */
@@ -68,9 +141,7 @@ static const struct FreeRTOS_params FreeRTOS_params_list[] = {
12, /* list_elem_content_offset */
0, /* thread_stack_offset; */
52, /* thread_name_offset; */
- &rtos_standard_Cortex_M3_stacking, /* stacking_info */
- &rtos_standard_Cortex_M4F_stacking,
- &rtos_standard_Cortex_M4F_FPU_stacking,
+ cortex_m_stacking,
},
{
"hla_target", /* target_name */
@@ -82,9 +153,7 @@ static const struct FreeRTOS_params FreeRTOS_params_list[] = {
12, /* list_elem_content_offset */
0, /* thread_stack_offset; */
52, /* thread_name_offset; */
- &rtos_standard_Cortex_M3_stacking, /* stacking_info */
- &rtos_standard_Cortex_M4F_stacking,
- &rtos_standard_Cortex_M4F_FPU_stacking,
+ cortex_m_stacking,
},
{
"nds32_v3", /* target_name */
@@ -96,9 +165,19 @@ static const struct FreeRTOS_params FreeRTOS_params_list[] = {
12, /* list_elem_content_offset */
0, /* thread_stack_offset; */
52, /* thread_name_offset; */
- &rtos_standard_NDS32_N1068_stacking, /* stacking_info */
- &rtos_standard_Cortex_M4F_stacking,
- &rtos_standard_Cortex_M4F_FPU_stacking,
+ nds32_stacking,
+ },
+ {
+ "riscv", /* target_name */
+ 4, /* thread_count_width; */
+ 4, /* pointer_width; */
+ 16, /* list_next_offset; */
+ 20, /* list_width; */
+ 8, /* list_elem_next_offset; */
+ 12, /* list_elem_content_offset */
+ 0, /* thread_stack_offset; */
+ 52, /* thread_name_offset; */
+ riscv_stacking,
},
};
@@ -107,8 +186,10 @@ static const struct FreeRTOS_params FreeRTOS_params_list[] = {
static bool FreeRTOS_detect_rtos(struct target *target);
static int FreeRTOS_create(struct target *target);
static int FreeRTOS_update_threads(struct rtos *rtos);
-static int FreeRTOS_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,
+static int FreeRTOS_get_thread_reg_list(struct rtos *rtos, threadid_t thread_id,
struct rtos_reg **reg_list, int *num_regs);
+static int FreeRTOS_get_thread_reg(struct rtos *rtos, threadid_t thread_id,
+ uint32_t reg_num, struct rtos_reg *reg);
static int FreeRTOS_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[]);
struct rtos_type FreeRTOS_rtos = {
@@ -118,6 +199,7 @@ struct rtos_type FreeRTOS_rtos = {
.create = FreeRTOS_create,
.update_threads = FreeRTOS_update_threads,
.get_thread_reg_list = FreeRTOS_get_thread_reg_list,
+ .get_thread_reg = FreeRTOS_get_thread_reg,
.get_symbol_list_to_lookup = FreeRTOS_get_symbol_list_to_lookup,
};
@@ -164,21 +246,21 @@ static int FreeRTOS_update_threads(struct rtos *rtos)
{
int retval;
unsigned int tasks_found = 0;
- const struct FreeRTOS_params *param;
if (rtos->rtos_specific_params == NULL)
- return -1;
+ return ERROR_FAIL;
- param = (const struct FreeRTOS_params *) rtos->rtos_specific_params;
+ struct FreeRTOS *freertos = (struct FreeRTOS *) rtos->rtos_specific_params;
+ const struct FreeRTOS_params *param = freertos->param;
if (rtos->symbols == NULL) {
LOG_ERROR("No symbols for FreeRTOS");
- return -3;
+ return ERROR_FAIL;
}
if (rtos->symbols[FreeRTOS_VAL_uxCurrentNumberOfTasks].address == 0) {
LOG_ERROR("Don't have the number of threads in FreeRTOS");
- return -2;
+ return ERROR_FAIL;
}
uint32_t thread_list_size = 0;
@@ -206,12 +288,12 @@ static int FreeRTOS_update_threads(struct rtos *rtos)
LOG_ERROR("Error reading current thread in FreeRTOS thread list");
return retval;
}
- rtos->current_thread = pointer_casts_are_bad;
+ target_addr_t pxCurrentTCB = pointer_casts_are_bad;
LOG_DEBUG("FreeRTOS: Read pxCurrentTCB at 0x%" PRIx64 ", value 0x%" PRIx64,
rtos->symbols[FreeRTOS_VAL_pxCurrentTCB].address,
- rtos->current_thread);
+ pxCurrentTCB);
- if ((thread_list_size == 0) || (rtos->current_thread == 0)) {
+ if ((thread_list_size == 0) || (pxCurrentTCB == 0)) {
/* Either : No RTOS threads - there is always at least the current execution though */
/* OR : No current thread - all threads suspended - show the current execution
* of idling */
@@ -245,19 +327,23 @@ static int FreeRTOS_update_threads(struct rtos *rtos)
}
/* Find out how many lists are needed to be read from pxReadyTasksLists, */
+ uint32_t top_used_priority = 0;
if (rtos->symbols[FreeRTOS_VAL_uxTopUsedPriority].address == 0) {
- LOG_ERROR("FreeRTOS: uxTopUsedPriority is not defined, consult the OpenOCD manual for a work-around");
- return ERROR_FAIL;
+ LOG_WARNING("FreeRTOS: uxTopUsedPriority is not defined, consult the OpenOCD manual for a work-around");
+ /* This is a hack specific to the binary I'm debugging.
+ * Ideally we get https://github.com/FreeRTOS/FreeRTOS-Kernel/issues/33
+ * into our FreeRTOS source. */
+ top_used_priority = 6;
+ } else {
+ retval = target_read_u32(rtos->target,
+ rtos->symbols[FreeRTOS_VAL_uxTopUsedPriority].address,
+ &top_used_priority);
+ if (retval != ERROR_OK)
+ return retval;
+ LOG_DEBUG("FreeRTOS: Read uxTopUsedPriority at 0x%" PRIx64 ", value %" PRIu32,
+ rtos->symbols[FreeRTOS_VAL_uxTopUsedPriority].address,
+ top_used_priority);
}
- uint32_t top_used_priority = 0;
- retval = target_read_u32(rtos->target,
- rtos->symbols[FreeRTOS_VAL_uxTopUsedPriority].address,
- &top_used_priority);
- if (retval != ERROR_OK)
- return retval;
- LOG_DEBUG("FreeRTOS: Read uxTopUsedPriority at 0x%" PRIx64 ", value %" PRIu32,
- rtos->symbols[FreeRTOS_VAL_uxTopUsedPriority].address,
- top_used_priority);
if (top_used_priority > FREERTOS_MAX_PRIORITIES) {
LOG_ERROR("FreeRTOS top used priority is unreasonably big, not proceeding: %" PRIu32,
top_used_priority);
@@ -289,6 +375,7 @@ static int FreeRTOS_update_threads(struct rtos *rtos)
list_of_lists[num_lists++] = rtos->symbols[FreeRTOS_VAL_xSuspendedTaskList].address;
list_of_lists[num_lists++] = rtos->symbols[FreeRTOS_VAL_xTasksWaitingTermination].address;
+ rtos->current_thread = 0;
for (unsigned int i = 0; i < num_lists; i++) {
if (list_of_lists[i] == 0)
continue;
@@ -336,10 +423,34 @@ static int FreeRTOS_update_threads(struct rtos *rtos)
free(list_of_lists);
return retval;
}
- rtos->thread_details[tasks_found].threadid = pointer_casts_are_bad;
- LOG_DEBUG("FreeRTOS: Read Thread ID at 0x%" PRIx32 ", value 0x%" PRIx64,
- list_elem_ptr + param->list_elem_content_offset,
- rtos->thread_details[tasks_found].threadid);
+
+ target_addr_t tcb = pointer_casts_are_bad;
+ const struct FreeRTOS_thread_entry *value =
+ gl_map_get(freertos->entry_by_tcb, &tcb);
+
+ if (value == NULL) {
+ struct FreeRTOS_thread_entry *new_value = calloc(1, sizeof(struct FreeRTOS_thread_entry));
+ new_value->tcb = tcb;
+ /* threadid can't be 0. */
+ new_value->threadid = ++freertos->last_threadid;
+
+ if (gl_map_nx_put(freertos->entry_by_tcb, &new_value->tcb, new_value) == -1) {
+ LOG_ERROR("gl_map_nx_put failed");
+ return ERROR_FAIL;
+ }
+ if (gl_map_nx_put(freertos->entry_by_threadid, &new_value->threadid, new_value) == -1) {
+ LOG_ERROR("gl_map_nx_put failed");
+ return ERROR_FAIL;
+ }
+ value = new_value;
+ }
+
+ rtos->thread_details[tasks_found].threadid = value->threadid;
+
+ LOG_DEBUG("FreeRTOS: Thread %" PRId64 " has TCB 0x%" TARGET_PRIxADDR
+ "; read from 0x%" PRIx32,
+ value->threadid, value->tcb,
+ list_elem_ptr + param->list_elem_content_offset);
/* get thread name */
@@ -348,7 +459,7 @@ static int FreeRTOS_update_threads(struct rtos *rtos)
/* Read the thread name */
retval = target_read_buffer(rtos->target,
- rtos->thread_details[tasks_found].threadid + param->thread_name_offset,
+ value->tcb + param->thread_name_offset,
FREERTOS_THREAD_NAME_STR_SIZE,
(uint8_t *)&tmp_str);
if (retval != ERROR_OK) {
@@ -358,7 +469,7 @@ static int FreeRTOS_update_threads(struct rtos *rtos)
}
tmp_str[FREERTOS_THREAD_NAME_STR_SIZE-1] = '\x00';
LOG_DEBUG("FreeRTOS: Read Thread Name at 0x%" PRIx64 ", value '%s'",
- rtos->thread_details[tasks_found].threadid + param->thread_name_offset,
+ value->tcb + param->thread_name_offset,
tmp_str);
if (tmp_str[0] == '\x00')
@@ -369,8 +480,9 @@ static int FreeRTOS_update_threads(struct rtos *rtos)
strcpy(rtos->thread_details[tasks_found].thread_name_str, tmp_str);
rtos->thread_details[tasks_found].exists = true;
- if (rtos->thread_details[tasks_found].threadid == rtos->current_thread) {
+ if (value->tcb == pxCurrentTCB) {
char running_str[] = "State: Running";
+ rtos->current_thread = value->threadid;
rtos->thread_details[tasks_found].extra_info_str = malloc(
sizeof(running_str));
strcpy(rtos->thread_details[tasks_found].extra_info_str,
@@ -402,76 +514,75 @@ static int FreeRTOS_update_threads(struct rtos *rtos)
return 0;
}
-static int FreeRTOS_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,
- struct rtos_reg **reg_list, int *num_regs)
+static int FreeRTOS_get_stacking_info(struct rtos *rtos, threadid_t thread_id,
+ const struct rtos_register_stacking **stacking_info,
+ target_addr_t *stack_ptr)
{
- int retval;
- const struct FreeRTOS_params *param;
- int64_t stack_ptr = 0;
-
- if (rtos == NULL)
- return -1;
+ if (rtos->rtos_specific_params == NULL) {
+ LOG_ERROR("rtos_specific_params is NULL!");
+ return ERROR_FAIL;
+ }
- if (thread_id == 0)
- return -2;
+ struct FreeRTOS *freertos = (struct FreeRTOS *) rtos->rtos_specific_params;
+ const struct FreeRTOS_params *param = freertos->param;
- if (rtos->rtos_specific_params == NULL)
- return -1;
-
- param = (const struct FreeRTOS_params *) rtos->rtos_specific_params;
+ const struct FreeRTOS_thread_entry *entry =
+ gl_map_get(freertos->entry_by_threadid, &thread_id);
+ if (entry == NULL) {
+ LOG_ERROR("Unknown thread id: %" PRId64, thread_id);
+ return ERROR_FAIL;
+ }
/* Read the stack pointer */
uint32_t pointer_casts_are_bad;
- retval = target_read_u32(rtos->target,
- thread_id + param->thread_stack_offset,
+ int retval = target_read_u32(rtos->target,
+ entry->tcb + param->thread_stack_offset,
&pointer_casts_are_bad);
if (retval != ERROR_OK) {
- LOG_ERROR("Error reading stack frame from FreeRTOS thread");
+ LOG_ERROR("Error reading stack frame from FreeRTOS thread %" PRIx64, thread_id);
return retval;
}
- stack_ptr = pointer_casts_are_bad;
- LOG_DEBUG("FreeRTOS: Read stack pointer at 0x%" PRIx64 ", value 0x%" PRIx64,
- thread_id + param->thread_stack_offset,
- stack_ptr);
+ *stack_ptr = pointer_casts_are_bad;
+ LOG_DEBUG("[%" PRId64 "] FreeRTOS: Read stack pointer at 0x%" PRIx64 ", value 0x%" PRIx64,
+ thread_id, entry->tcb + param->thread_stack_offset, *stack_ptr);
- /* Check for armv7m with *enabled* FPU, i.e. a Cortex-M4F */
- int cm4_fpu_enabled = 0;
- struct armv7m_common *armv7m_target = target_to_armv7m(rtos->target);
- if (is_armv7m(armv7m_target)) {
- if (armv7m_target->fp_feature == FPv4_SP) {
- /* Found ARM v7m target which includes a FPU */
- uint32_t cpacr;
+ if (param->stacking(rtos, stacking_info, *stack_ptr) != ERROR_OK) {
+ LOG_ERROR("No stacking info found for %s!", param->target_name);
+ return ERROR_FAIL;
+ }
- retval = target_read_u32(rtos->target, FPU_CPACR, &cpacr);
- if (retval != ERROR_OK) {
- LOG_ERROR("Could not read CPACR register to check FPU state");
- return -1;
- }
+ return ERROR_OK;
+}
- /* Check if CP10 and CP11 are set to full access. */
- if (cpacr & 0x00F00000) {
- /* Found target with enabled FPU */
- cm4_fpu_enabled = 1;
- }
- }
- }
+static int FreeRTOS_get_thread_reg_list(struct rtos *rtos, threadid_t thread_id,
+ struct rtos_reg **reg_list, int *num_regs)
+{
+ /* Let the caller read registers directly for the current thread. */
+ if (thread_id == 0)
+ return ERROR_FAIL;
- if (cm4_fpu_enabled == 1) {
- /* Read the LR to decide between stacking with or without FPU */
- uint32_t LR_svc = 0;
- retval = target_read_u32(rtos->target,
- stack_ptr + 0x20,
- &LR_svc);
- if (retval != ERROR_OK) {
- LOG_OUTPUT("Error reading stack frame from FreeRTOS thread");
- return retval;
- }
- if ((LR_svc & 0x10) == 0)
- return rtos_generic_stack_read(rtos->target, param->stacking_info_cm4f_fpu, stack_ptr, reg_list, num_regs);
- else
- return rtos_generic_stack_read(rtos->target, param->stacking_info_cm4f, stack_ptr, reg_list, num_regs);
- } else
- return rtos_generic_stack_read(rtos->target, param->stacking_info_cm3, stack_ptr, reg_list, num_regs);
+ const struct rtos_register_stacking *stacking_info;
+ target_addr_t stack_ptr;
+ if (FreeRTOS_get_stacking_info(rtos, thread_id, &stacking_info, &stack_ptr) != ERROR_OK)
+ return ERROR_FAIL;
+
+ return rtos_generic_stack_read(rtos->target, stacking_info, stack_ptr, reg_list, num_regs);
+}
+
+static int FreeRTOS_get_thread_reg(struct rtos *rtos, threadid_t thread_id,
+ uint32_t reg_num, struct rtos_reg *reg)
+{
+ LOG_DEBUG("reg_num=%d", reg_num);
+ /* Let the caller read registers directly for the current thread. */
+ if (thread_id == 0)
+ return ERROR_FAIL;
+
+ const struct rtos_register_stacking *stacking_info;
+ target_addr_t stack_ptr;
+ if (FreeRTOS_get_stacking_info(rtos, thread_id, &stacking_info, &stack_ptr) != ERROR_OK)
+ return ERROR_FAIL;
+
+ return rtos_generic_stack_read_reg(rtos->target, stacking_info, stack_ptr, reg_num, reg);
}
static int FreeRTOS_get_symbol_list_to_lookup(symbol_table_elem_t *symbol_list[])
@@ -545,6 +656,25 @@ static bool FreeRTOS_detect_rtos(struct target *target)
return false;
}
+static bool target_addr_equals(const void *x1, const void *x2)
+{
+ const target_addr_t *a1 = x1;
+ const target_addr_t *a2 = x2;
+ return *a1 == *a2;
+}
+
+static size_t target_addr_hash(const void *x)
+{
+ const target_addr_t *a = x;
+ return *a;
+}
+
+static void free_const(const void *x)
+{
+ /* Cast away const. */
+ free((void *) x);
+}
+
static int FreeRTOS_create(struct target *target)
{
int i = 0;
@@ -554,9 +684,29 @@ static int FreeRTOS_create(struct target *target)
}
if (i >= FREERTOS_NUM_PARAMS) {
LOG_ERROR("Could not find target in FreeRTOS compatibility list");
- return -1;
+ return ERROR_FAIL;
+ }
+
+ target->rtos->rtos_specific_params = calloc(1, sizeof(struct FreeRTOS));
+ if (target->rtos->rtos_specific_params == NULL) {
+ LOG_ERROR("calloc failed");
+ return ERROR_FAIL;
+ }
+
+ struct FreeRTOS *freertos = (struct FreeRTOS *) target->rtos->rtos_specific_params;
+ freertos->entry_by_threadid = gl_map_nx_create_empty(
+ GL_LINKEDHASH_MAP, target_addr_equals, target_addr_hash, NULL, free_const);
+ if (freertos->entry_by_threadid == NULL) {
+ LOG_ERROR("gl_map_nx_create_empty failed");
+ return ERROR_FAIL;
+ }
+ freertos->entry_by_tcb = gl_map_nx_create_empty(
+ GL_LINKEDHASH_MAP, target_addr_equals, target_addr_hash, NULL, NULL);
+ if (freertos->entry_by_tcb == NULL) {
+ LOG_ERROR("gl_map_nx_create_empty failed");
+ return ERROR_FAIL;
}
+ freertos->param = &FreeRTOS_params_list[i];
- target->rtos->rtos_specific_params = (void *) &FreeRTOS_params_list[i];
return 0;
}
diff --git a/src/rtos/ThreadX.c b/src/rtos/ThreadX.c
index 7d58725..53788c7 100644
--- a/src/rtos/ThreadX.c
+++ b/src/rtos/ThreadX.c
@@ -112,18 +112,16 @@ static const struct stack_register_offset rtos_threadx_arm926ejs_stack_offsets_i
static const struct rtos_register_stacking rtos_threadx_arm926ejs_stacking[] = {
{
- ARM926EJS_REGISTERS_SIZE_SOLICITED, /* stack_registers_size */
- -1, /* stack_growth_direction */
- 17, /* num_output_registers */
- NULL, /* stack_alignment */
- rtos_threadx_arm926ejs_stack_offsets_solicited /* register_offsets */
+ .stack_registers_size = ARM926EJS_REGISTERS_SIZE_SOLICITED,
+ .stack_growth_direction = -1,
+ .num_output_registers = 17,
+ .register_offsets = rtos_threadx_arm926ejs_stack_offsets_solicited
},
{
- ARM926EJS_REGISTERS_SIZE_INTERRUPT, /* stack_registers_size */
- -1, /* stack_growth_direction */
- 17, /* num_output_registers */
- NULL, /* stack_alignment */
- rtos_threadx_arm926ejs_stack_offsets_interrupt /* register_offsets */
+ .stack_registers_size = ARM926EJS_REGISTERS_SIZE_INTERRUPT,
+ .stack_growth_direction = -1,
+ .num_output_registers = 17,
+ .register_offsets = rtos_threadx_arm926ejs_stack_offsets_interrupt
},
};
diff --git a/src/rtos/nuttx.c b/src/rtos/nuttx.c
index 19b93ba..df5dbe1 100644
--- a/src/rtos/nuttx.c
+++ b/src/rtos/nuttx.c
@@ -119,11 +119,10 @@ static const struct stack_register_offset nuttx_stack_offsets_cortex_m[] = {
static const struct rtos_register_stacking nuttx_stacking_cortex_m = {
- 0x48, /* stack_registers_size */
- -1, /* stack_growth_direction */
- 17, /* num_output_registers */
- 0, /* stack_alignment */
- nuttx_stack_offsets_cortex_m /* register_offsets */
+ .stack_registers_size = 0x48,
+ .stack_growth_direction = -1,
+ .num_output_registers = 17,
+ .register_offsets = nuttx_stack_offsets_cortex_m
};
static const struct stack_register_offset nuttx_stack_offsets_cortex_m_fpu[] = {
@@ -147,11 +146,10 @@ static const struct stack_register_offset nuttx_stack_offsets_cortex_m_fpu[] = {
};
static const struct rtos_register_stacking nuttx_stacking_cortex_m_fpu = {
- 0x8c, /* stack_registers_size */
- -1, /* stack_growth_direction */
- 17, /* num_output_registers */
- 0, /* stack_alignment */
- nuttx_stack_offsets_cortex_m_fpu /* register_offsets */
+ .stack_registers_size = 0x8c,
+ .stack_growth_direction = -1,
+ .num_output_registers = 17,
+ .register_offsets = nuttx_stack_offsets_cortex_m_fpu
};
static int pid_offset = PID;
diff --git a/src/rtos/rtos.c b/src/rtos/rtos.c
index f88925a..86ea088 100644
--- a/src/rtos/rtos.c
+++ b/src/rtos/rtos.c
@@ -68,7 +68,9 @@ int rtos_smp_init(struct target *target)
return ERROR_TARGET_INIT_FAILED;
}
-static int rtos_target_for_threadid(struct connection *connection, int64_t threadid, struct target **t)
+static int rtos_target_for_threadid(struct connection *connection,
+ threadid_t threadid,
+ struct target **t)
{
struct target *curr = get_target_from_connection(connection);
if (t)
@@ -475,7 +477,7 @@ static int rtos_put_gdb_reg_list(struct connection *connection,
int rtos_get_gdb_reg(struct connection *connection, int reg_num)
{
struct target *target = get_target_from_connection(connection);
- int64_t current_threadid = target->rtos->current_threadid;
+ threadid_t current_threadid = target->rtos->current_threadid;
if ((target->rtos != NULL) && (current_threadid != -1) &&
(current_threadid != 0) &&
((current_threadid != target->rtos->current_thread) ||
@@ -492,6 +494,7 @@ int rtos_get_gdb_reg(struct connection *connection, int reg_num)
int retval;
if (target->rtos->type->get_thread_reg) {
reg_list = calloc(1, sizeof(*reg_list));
+ reg_list[0].number = reg_num;
num_regs = 1;
retval = target->rtos->type->get_thread_reg(target->rtos,
current_threadid, reg_num, &reg_list[0]);
@@ -573,7 +576,7 @@ int rtos_set_reg(struct connection *connection, int reg_num,
int rtos_generic_stack_read(struct target *target,
const struct rtos_register_stacking *stacking,
- int64_t stack_ptr,
+ target_addr_t stack_ptr,
struct rtos_reg **reg_list,
int *num_regs)
{
@@ -585,7 +588,7 @@ int rtos_generic_stack_read(struct target *target,
}
/* Read the stack */
uint8_t *stack_data = malloc(stacking->stack_registers_size);
- uint32_t address = stack_ptr;
+ target_addr_t address = stack_ptr;
if (stacking->stack_growth_direction == 1)
address -= stacking->stack_registers_size;
@@ -595,7 +598,7 @@ int rtos_generic_stack_read(struct target *target,
LOG_ERROR("Error reading stack frame from thread");
return retval;
}
- LOG_DEBUG("RTOS: Read stack frame at 0x%" PRIx32, address);
+ LOG_DEBUG("RTOS: Read stack frame at " TARGET_ADDR_FMT, address);
#if 0
LOG_OUTPUT("Stack Data :");
@@ -625,6 +628,9 @@ int rtos_generic_stack_read(struct target *target,
buf_cpy(&new_stack_ptr, (*reg_list)[i].value, (*reg_list)[i].size);
else if (offset != -1)
buf_cpy(stack_data + offset, (*reg_list)[i].value, (*reg_list)[i].size);
+
+ LOG_DEBUG("register %d has value 0x%" PRIx64, (*reg_list)[i].number,
+ buf_get_u64((*reg_list)[i].value, 0, 64));
}
free(stack_data);
@@ -632,6 +638,48 @@ int rtos_generic_stack_read(struct target *target,
return ERROR_OK;
}
+/* Read an individual register from the RTOS stack. */
+int rtos_generic_stack_read_reg(struct target *target,
+ const struct rtos_register_stacking *stacking,
+ target_addr_t stack_ptr,
+ uint32_t reg_num, struct rtos_reg *reg)
+{
+ LOG_DEBUG("stack_ptr=" TARGET_ADDR_FMT ", reg_num=%d", stack_ptr, reg_num);
+ unsigned total_count = MAX(stacking->total_register_count, stacking->num_output_registers);
+ unsigned i;
+ for (i = 0; i < total_count; i++) {
+ if (stacking->register_offsets[i].number == reg_num)
+ break;
+ }
+ if (i >= total_count) {
+ /* This register is not on the stack. Return error so a caller somewhere
+ * will just read the register directly fromt he target. */
+ return ERROR_FAIL;
+ }
+
+ const struct stack_register_offset *offsets = &stacking->register_offsets[i];
+ reg->size = offsets->width_bits;
+
+ unsigned width_bytes = DIV_ROUND_UP(offsets->width_bits, 8);
+ if (offsets->offset >= 0) {
+ target_addr_t address = stack_ptr;
+
+ if (stacking->stack_growth_direction == 1)
+ address -= stacking->stack_registers_size;
+
+ if (target_read_buffer(
+ target, address + offsets->offset,
+ width_bytes, reg->value) != ERROR_OK)
+ return ERROR_FAIL;
+ LOG_DEBUG("register %d has value 0x%" PRIx64, reg->number,
+ buf_get_u64(reg->value, 0, 64));
+ } else {
+ memset(reg->value, 0, width_bytes);
+ }
+
+ return ERROR_OK;
+}
+
static int rtos_try_next(struct target *target)
{
struct rtos *os = target->rtos;
diff --git a/src/rtos/rtos.h b/src/rtos/rtos.h
index 1bda730..9f91e19 100644
--- a/src/rtos/rtos.h
+++ b/src/rtos/rtos.h
@@ -58,7 +58,7 @@ struct rtos {
int thread_count;
int (*gdb_thread_packet)(struct connection *connection, char const *packet, int packet_size);
int (*gdb_v_packet)(struct connection *connection, char const *packet, int packet_size);
- int (*gdb_target_for_threadid)(struct connection *connection, int64_t thread_id, struct target **p_target);
+ int (*gdb_target_for_threadid)(struct connection *connection, threadid_t thread_id, struct target **p_target);
void *rtos_specific_params;
};
@@ -75,9 +75,9 @@ struct rtos_type {
int (*smp_init)(struct target *target);
int (*update_threads)(struct rtos *rtos);
/** Return a list of general registers, with their values filled out. */
- int (*get_thread_reg_list)(struct rtos *rtos, int64_t thread_id,
+ int (*get_thread_reg_list)(struct rtos *rtos, threadid_t thread_id,
struct rtos_reg **reg_list, int *num_regs);
- int (*get_thread_reg)(struct rtos *rtos, int64_t thread_id,
+ int (*get_thread_reg)(struct rtos *rtos, threadid_t thread_id,
uint32_t reg_num, struct rtos_reg *reg);
int (*get_symbol_list_to_lookup)(symbol_table_elem_t *symbol_list[]);
int (*clean)(struct target *target);
@@ -89,7 +89,7 @@ struct rtos_type {
* the thread current. This is an assumption that cannot hold for a real
* target running a multi-threading OS. If an RTOS can do this, override
* needs_fake_step(). */
- bool (*needs_fake_step)(struct target *target, int64_t thread_id);
+ bool (*needs_fake_step)(struct target *target, threadid_t thread_id);
/* Implement these if different threads in the RTOS can see memory
* differently (for instance because address translation might be different
* for each thread). */
@@ -110,6 +110,7 @@ struct stack_register_offset {
struct rtos_register_stacking {
unsigned char stack_registers_size;
signed char stack_growth_direction;
+ /* The number of gdb general registers, in order. */
unsigned char num_output_registers;
/* Some targets require evaluating the stack to determine the
* actual stack pointer for a process. If this field is NULL,
@@ -121,6 +122,10 @@ struct rtos_register_stacking {
const struct rtos_register_stacking *stacking,
int64_t stack_ptr);
const struct stack_register_offset *register_offsets;
+ /* Total number of registers on the stack, including the general ones. This
+ * may be 0 if there are no additional registers on the stack beyond the
+ * general ones. */
+ unsigned total_register_count;
};
#define GDB_THREAD_PACKET_NOT_CONSUMED (-40)
@@ -131,9 +136,13 @@ int rtos_set_reg(struct connection *connection, int reg_num,
uint8_t *reg_value);
int rtos_generic_stack_read(struct target *target,
const struct rtos_register_stacking *stacking,
- int64_t stack_ptr,
+ target_addr_t stack_ptr,
struct rtos_reg **reg_list,
int *num_regs);
+int rtos_generic_stack_read_reg(struct target *target,
+ const struct rtos_register_stacking *stacking,
+ target_addr_t stack_ptr,
+ uint32_t reg_num, struct rtos_reg *reg);
int gdb_thread_packet(struct connection *connection, char const *packet, int packet_size);
int rtos_get_gdb_reg(struct connection *connection, int reg_num);
int rtos_get_gdb_reg_list(struct connection *connection);
@@ -142,7 +151,7 @@ void rtos_free_threadlist(struct rtos *rtos);
int rtos_smp_init(struct target *target);
/* function for handling symbol access */
int rtos_qsymbol(struct connection *connection, char const *packet, int packet_size);
-bool rtos_needs_fake_step(struct target *target, int64_t thread_id);
+bool rtos_needs_fake_step(struct target *target, threadid_t thread_id);
int rtos_read_buffer(struct target *target, target_addr_t address,
uint32_t size, uint8_t *buffer);
int rtos_write_buffer(struct target *target, target_addr_t address,
diff --git a/src/rtos/rtos_chibios_stackings.c b/src/rtos/rtos_chibios_stackings.c
index 2887930..77bcb86 100644
--- a/src/rtos/rtos_chibios_stackings.c
+++ b/src/rtos/rtos_chibios_stackings.c
@@ -47,11 +47,10 @@ static const struct stack_register_offset rtos_chibios_arm_v7m_stack_offsets[ARM
};
const struct rtos_register_stacking rtos_chibios_arm_v7m_stacking = {
- 0x24, /* stack_registers_size */
- -1, /* stack_growth_direction */
- ARMV7M_NUM_CORE_REGS, /* num_output_registers */
- NULL, /* stack_alignment */
- rtos_chibios_arm_v7m_stack_offsets /* register_offsets */
+ .stack_registers_size = 0x24,
+ .stack_growth_direction = -1,
+ .num_output_registers = ARMV7M_NUM_CORE_REGS,
+ .register_offsets = rtos_chibios_arm_v7m_stack_offsets
};
static const struct stack_register_offset rtos_chibios_arm_v7m_stack_offsets_w_fpu[ARMV7M_NUM_CORE_REGS] = {
@@ -75,9 +74,8 @@ static const struct stack_register_offset rtos_chibios_arm_v7m_stack_offsets_w_f
};
const struct rtos_register_stacking rtos_chibios_arm_v7m_stacking_w_fpu = {
- 0x64, /* stack_registers_size */
- -1, /* stack_growth_direction */
- ARMV7M_NUM_CORE_REGS, /* num_output_registers */
- NULL, /* stack_alignment */
- rtos_chibios_arm_v7m_stack_offsets_w_fpu /* register_offsets */
+ .stack_registers_size = 0x64,
+ .stack_growth_direction = -1,
+ .num_output_registers = ARMV7M_NUM_CORE_REGS,
+ .register_offsets = rtos_chibios_arm_v7m_stack_offsets_w_fpu
};
diff --git a/src/rtos/rtos_ecos_stackings.c b/src/rtos/rtos_ecos_stackings.c
index ca98d94..c6b0712 100644
--- a/src/rtos/rtos_ecos_stackings.c
+++ b/src/rtos/rtos_ecos_stackings.c
@@ -43,9 +43,9 @@ static const struct stack_register_offset rtos_eCos_Cortex_M3_stack_offsets[ARMV
};
const struct rtos_register_stacking rtos_eCos_Cortex_M3_stacking = {
- 0x44, /* stack_registers_size */
- -1, /* stack_growth_direction */
- ARMV7M_NUM_CORE_REGS, /* num_output_registers */
- rtos_generic_stack_align8, /* stack_alignment */
- rtos_eCos_Cortex_M3_stack_offsets /* register_offsets */
+ .stack_registers_size = 0x44,
+ .stack_growth_direction = -1,
+ .num_output_registers = ARMV7M_NUM_CORE_REGS,
+ .calculate_process_stack = rtos_generic_stack_align8,
+ .register_offsets = rtos_eCos_Cortex_M3_stack_offsets
};
diff --git a/src/rtos/rtos_embkernel_stackings.c b/src/rtos/rtos_embkernel_stackings.c
index 543a8cd..8c0fd2a 100644
--- a/src/rtos/rtos_embkernel_stackings.c
+++ b/src/rtos/rtos_embkernel_stackings.c
@@ -45,9 +45,9 @@ static const struct stack_register_offset rtos_embkernel_Cortex_M_stack_offsets[
};
const struct rtos_register_stacking rtos_embkernel_Cortex_M_stacking = {
- 0x40, /* stack_registers_size */
- -1, /* stack_growth_direction */
- ARMV7M_NUM_CORE_REGS, /* num_output_registers */
- rtos_generic_stack_align8, /* stack_alignment */
- rtos_embkernel_Cortex_M_stack_offsets /* register_offsets */
+ .stack_registers_size = 0x40,
+ .stack_growth_direction = -1,
+ .num_output_registers = ARMV7M_NUM_CORE_REGS,
+ .calculate_process_stack = rtos_generic_stack_align8,
+ .register_offsets = rtos_embkernel_Cortex_M_stack_offsets
};
diff --git a/src/rtos/rtos_mqx_stackings.c b/src/rtos/rtos_mqx_stackings.c
index f2d3b22..f99190e 100644
--- a/src/rtos/rtos_mqx_stackings.c
+++ b/src/rtos/rtos_mqx_stackings.c
@@ -71,9 +71,8 @@ static const struct stack_register_offset rtos_mqx_arm_v7m_stack_offsets[ARMV7M_
};
const struct rtos_register_stacking rtos_mqx_arm_v7m_stacking = {
- 0x4C, /* stack_registers_size, calculate offset base address */
- -1, /* stack_growth_direction */
- ARMV7M_NUM_CORE_REGS, /* num_output_registers */
- NULL, /* stack_alignment */
- rtos_mqx_arm_v7m_stack_offsets /* register_offsets */
+ .stack_registers_size = 0x4C, /* calculate offset base address */
+ .stack_growth_direction = -1,
+ .num_output_registers = ARMV7M_NUM_CORE_REGS,
+ .register_offsets = rtos_mqx_arm_v7m_stack_offsets
};
diff --git a/src/rtos/rtos_riot_stackings.c b/src/rtos/rtos_riot_stackings.c
index 23f4d17..6489426 100644
--- a/src/rtos/rtos_riot_stackings.c
+++ b/src/rtos/rtos_riot_stackings.c
@@ -58,11 +58,11 @@ static const struct stack_register_offset rtos_riot_cortex_m0_stack_offsets[ARMV
};
const struct rtos_register_stacking rtos_riot_cortex_m0_stacking = {
- 0x44, /* stack_registers_size */
- -1, /* stack_growth_direction */
- ARMV7M_NUM_CORE_REGS, /* num_output_registers */
- rtos_riot_cortex_m_stack_align, /* stack_alignment */
- rtos_riot_cortex_m0_stack_offsets /* register_offsets */
+ .stack_registers_size = 0x44,
+ .stack_growth_direction = -1,
+ .num_output_registers = ARMV7M_NUM_CORE_REGS,
+ .calculate_process_stack = rtos_riot_cortex_m_stack_align,
+ .register_offsets = rtos_riot_cortex_m0_stack_offsets
};
/* see thread_arch.c */
@@ -87,9 +87,9 @@ static const struct stack_register_offset rtos_riot_cortex_m34_stack_offsets[ARM
};
const struct rtos_register_stacking rtos_riot_cortex_m34_stacking = {
- 0x44, /* stack_registers_size */
- -1, /* stack_growth_direction */
- ARMV7M_NUM_CORE_REGS, /* num_output_registers */
- rtos_riot_cortex_m_stack_align, /* stack_alignment */
- rtos_riot_cortex_m34_stack_offsets /* register_offsets */
+ .stack_registers_size = 0x44,
+ .stack_growth_direction = -1,
+ .num_output_registers = ARMV7M_NUM_CORE_REGS,
+ .calculate_process_stack = rtos_riot_cortex_m_stack_align,
+ .register_offsets = rtos_riot_cortex_m34_stack_offsets
};
diff --git a/src/rtos/rtos_standard_stackings.c b/src/rtos/rtos_standard_stackings.c
index 7b054cb..7ff5b89 100644
--- a/src/rtos/rtos_standard_stackings.c
+++ b/src/rtos/rtos_standard_stackings.c
@@ -22,6 +22,7 @@
#include "rtos.h"
#include "target/armv7m.h"
+#include "target/riscv/riscv.h"
static const struct stack_register_offset rtos_standard_Cortex_M3_stack_offsets[ARMV7M_NUM_CORE_REGS] = {
{ ARMV7M_R0, 0x20, 32 }, /* r0 */
@@ -152,6 +153,47 @@ static const struct stack_register_offset rtos_standard_NDS32_N1068_stack_offset
{ 35, 0x10, 32 }, /* IFC_LP */
};
+static const struct stack_register_offset rtos_standard_RV32_stack_offsets[] = {
+ /* zero isn't on the stack. By making its offset -1 we leave the value at 0
+ * inside rtos_generic_stack_read(). */
+ { GDB_REGNO_ZERO, -1, 32 },
+ { GDB_REGNO_RA, 0x04, 32 },
+ { GDB_REGNO_SP, 0x08, 32 },
+ { GDB_REGNO_GP, 0x0c, 32 },
+ { GDB_REGNO_TP, 0x10, 32 },
+ { GDB_REGNO_T0, 0x14, 32 },
+ { GDB_REGNO_T1, 0x18, 32 },
+ { GDB_REGNO_T2, 0x1c, 32 },
+ { GDB_REGNO_FP, 0x20, 32 },
+ { GDB_REGNO_S1, 0x24, 32 },
+ { GDB_REGNO_A0, 0x28, 32 },
+ { GDB_REGNO_A1, 0x2c, 32 },
+ { GDB_REGNO_A2, 0x30, 32 },
+ { GDB_REGNO_A3, 0x34, 32 },
+ { GDB_REGNO_A4, 0x38, 32 },
+ { GDB_REGNO_A5, 0x3c, 32 },
+ { GDB_REGNO_A6, 0x40, 32 },
+ { GDB_REGNO_A7, 0x44, 32 },
+ { GDB_REGNO_S2, 0x48, 32 },
+ { GDB_REGNO_S3, 0x4c, 32 },
+ { GDB_REGNO_S4, 0x50, 32 },
+ { GDB_REGNO_S5, 0x54, 32 },
+ { GDB_REGNO_S6, 0x58, 32 },
+ { GDB_REGNO_S7, 0x5c, 32 },
+ { GDB_REGNO_S8, 0x60, 32 },
+ { GDB_REGNO_S9, 0x64, 32 },
+ { GDB_REGNO_S10, 0x68, 32 },
+ { GDB_REGNO_S11, 0x6c, 32 },
+ { GDB_REGNO_T3, 0x70, 32 },
+ { GDB_REGNO_T4, 0x74, 32 },
+ { GDB_REGNO_T5, 0x78, 32 },
+ { GDB_REGNO_T6, 0x7c, 32 },
+ { GDB_REGNO_PC, 0x80, 32 },
+ /* Registers below are on the stack, but not what gdb expects to return from
+ * a 'g' packet so are only accessible through get_reg. */
+ { GDB_REGNO_MSTATUS, 0x84, 32 },
+};
+
static int64_t rtos_generic_stack_align(struct target *target,
const uint8_t *stack_data, const struct rtos_register_stacking *stacking,
int64_t stack_ptr, int align)
@@ -249,41 +291,50 @@ static int64_t rtos_standard_Cortex_M4F_FPU_stack_align(struct target *target,
const struct rtos_register_stacking rtos_standard_Cortex_M3_stacking = {
- 0x40, /* stack_registers_size */
- -1, /* stack_growth_direction */
- ARMV7M_NUM_CORE_REGS, /* num_output_registers */
- rtos_standard_Cortex_M3_stack_align, /* stack_alignment */
- rtos_standard_Cortex_M3_stack_offsets /* register_offsets */
+ .stack_registers_size = 0x40,
+ .stack_growth_direction = -1,
+ .num_output_registers = ARMV7M_NUM_CORE_REGS,
+ .calculate_process_stack = rtos_standard_Cortex_M3_stack_align,
+ .register_offsets = rtos_standard_Cortex_M3_stack_offsets
};
const struct rtos_register_stacking rtos_standard_Cortex_M4F_stacking = {
- 0x44, /* stack_registers_size 4 more for LR*/
- -1, /* stack_growth_direction */
- ARMV7M_NUM_CORE_REGS, /* num_output_registers */
- rtos_standard_Cortex_M4F_stack_align, /* stack_alignment */
- rtos_standard_Cortex_M4F_stack_offsets /* register_offsets */
+ .stack_registers_size = 0x44, /* 4 more for LR*/
+ .stack_growth_direction = -1,
+ .num_output_registers = ARMV7M_NUM_CORE_REGS,
+ .calculate_process_stack = rtos_standard_Cortex_M4F_stack_align,
+ .register_offsets = rtos_standard_Cortex_M4F_stack_offsets
};
const struct rtos_register_stacking rtos_standard_Cortex_M4F_FPU_stacking = {
- 0xcc, /* stack_registers_size 4 more for LR + 48 more for FPU S0-S15 register*/
- -1, /* stack_growth_direction */
- ARMV7M_NUM_CORE_REGS, /* num_output_registers */
- rtos_standard_Cortex_M4F_FPU_stack_align, /* stack_alignment */
- rtos_standard_Cortex_M4F_FPU_stack_offsets /* register_offsets */
+ .stack_registers_size = 0xcc, /* 4 more for LR + 48 more for FPU S0-S15 register*/
+ .stack_growth_direction = -1,
+ .num_output_registers = ARMV7M_NUM_CORE_REGS,
+ .calculate_process_stack = rtos_standard_Cortex_M4F_FPU_stack_align,
+ .register_offsets = rtos_standard_Cortex_M4F_FPU_stack_offsets
};
const struct rtos_register_stacking rtos_standard_Cortex_R4_stacking = {
- 0x48, /* stack_registers_size */
- -1, /* stack_growth_direction */
- 26, /* num_output_registers */
- rtos_generic_stack_align8, /* stack_alignment */
- rtos_standard_Cortex_R4_stack_offsets /* register_offsets */
+ .stack_registers_size = 0x48,
+ .stack_growth_direction = -1,
+ .num_output_registers = 26,
+ .calculate_process_stack = rtos_generic_stack_align8,
+ .register_offsets = rtos_standard_Cortex_R4_stack_offsets
};
const struct rtos_register_stacking rtos_standard_NDS32_N1068_stacking = {
- 0x90, /* stack_registers_size */
- -1, /* stack_growth_direction */
- 32, /* num_output_registers */
- rtos_generic_stack_align8, /* stack_alignment */
- rtos_standard_NDS32_N1068_stack_offsets /* register_offsets */
+ .stack_registers_size = 0x90,
+ .stack_growth_direction = -1,
+ .num_output_registers = 32,
+ .calculate_process_stack = rtos_generic_stack_align8,
+ .register_offsets = rtos_standard_NDS32_N1068_stack_offsets
+};
+
+const struct rtos_register_stacking rtos_standard_RV32_stacking = {
+ .stack_registers_size = (32 + 2) * 4,
+ .stack_growth_direction = -1,
+ .num_output_registers = 33,
+ .calculate_process_stack = rtos_generic_stack_align8,
+ .register_offsets = rtos_standard_RV32_stack_offsets,
+ .total_register_count = ARRAY_SIZE(rtos_standard_RV32_stack_offsets)
};
diff --git a/src/rtos/rtos_standard_stackings.h b/src/rtos/rtos_standard_stackings.h
index 6971efd..302ebed 100644
--- a/src/rtos/rtos_standard_stackings.h
+++ b/src/rtos/rtos_standard_stackings.h
@@ -37,4 +37,6 @@ int64_t rtos_Cortex_M_stack_align(struct target *target,
const uint8_t *stack_data, const struct rtos_register_stacking *stacking,
int64_t stack_ptr, size_t xpsr_offset);
+extern const struct rtos_register_stacking rtos_standard_RV32_stacking;
+
#endif /* OPENOCD_RTOS_RTOS_STANDARD_STACKINGS_H */
diff --git a/src/rtos/rtos_ucos_iii_stackings.c b/src/rtos/rtos_ucos_iii_stackings.c
index d093563..1081d37 100644
--- a/src/rtos/rtos_ucos_iii_stackings.c
+++ b/src/rtos/rtos_ucos_iii_stackings.c
@@ -68,17 +68,16 @@ static const struct stack_register_offset rtos_uCOS_III_eSi_RISC_stack_offsets[]
};
const struct rtos_register_stacking rtos_uCOS_III_Cortex_M_stacking = {
- 0x40, /* stack_registers_size */
- -1, /* stack_growth_direction */
- ARRAY_SIZE(rtos_uCOS_III_Cortex_M_stack_offsets), /* num_output_registers */
- rtos_generic_stack_align8, /* stack_alignment */
- rtos_uCOS_III_Cortex_M_stack_offsets /* register_offsets */
+ .stack_registers_size = 0x40,
+ .stack_growth_direction = -1,
+ .num_output_registers = ARRAY_SIZE(rtos_uCOS_III_Cortex_M_stack_offsets),
+ .calculate_process_stack = rtos_generic_stack_align8,
+ .register_offsets = rtos_uCOS_III_Cortex_M_stack_offsets
};
const struct rtos_register_stacking rtos_uCOS_III_eSi_RISC_stacking = {
- 0x4c, /* stack_registers_size */
- -1, /* stack_growth_direction */
- ARRAY_SIZE(rtos_uCOS_III_eSi_RISC_stack_offsets), /* num_output_registers */
- NULL, /* stack_alignment */
- rtos_uCOS_III_eSi_RISC_stack_offsets /* register_offsets */
+ .stack_registers_size = 0x4c,
+ .stack_growth_direction = -1,
+ .num_output_registers = ARRAY_SIZE(rtos_uCOS_III_eSi_RISC_stack_offsets),
+ .register_offsets = rtos_uCOS_III_eSi_RISC_stack_offsets
};
diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c
index a5f4acb..c1d46fb 100644
--- a/src/server/gdb_server.c
+++ b/src/server/gdb_server.c
@@ -1318,7 +1318,7 @@ static int gdb_get_register_packet(struct connection *connection,
if (reg_list_size <= reg_num) {
LOG_ERROR("gdb requested a non-existing register");
- return ERROR_SERVER_REMOTE_CLOSED;
+ return gdb_error(connection, retval);
}
if (!reg_list[reg_num]->valid) {
@@ -2635,6 +2635,7 @@ static int gdb_query_packet(struct connection *connection,
cmd = malloc((packet_size - 6) / 2 + 1);
size_t len = unhexify((uint8_t *)cmd, packet + 6, (packet_size - 6) / 2);
cmd[len] = 0;
+ LOG_DEBUG("qRcmd: %s", cmd);
/* We want to print all debug output to GDB connection */
log_add_callback(gdb_log_callback, connection);
diff --git a/src/server/server.h b/src/server/server.h
index 99f5fe2..4ae6e95 100644
--- a/src/server/server.h
+++ b/src/server/server.h
@@ -30,6 +30,7 @@
#endif
#include <helper/log.h>
+#include <helper/replacements.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
diff --git a/src/svf/svf.c b/src/svf/svf.c
index 6087034..f35c613 100644
--- a/src/svf/svf.c
+++ b/src/svf/svf.c
@@ -31,6 +31,7 @@
#include <jtag/jtag.h>
#include "svf.h"
+#include "helper/system.h"
#include <helper/time_support.h>
/* SVF command */
diff --git a/src/target/algorithm.h b/src/target/algorithm.h
index 8894241..0fc49d0 100644
--- a/src/target/algorithm.h
+++ b/src/target/algorithm.h
@@ -19,6 +19,9 @@
#ifndef OPENOCD_TARGET_ALGORITHM_H
#define OPENOCD_TARGET_ALGORITHM_H
+#include "helper/types.h"
+#include "helper/replacements.h"
+
enum param_direction {
PARAM_IN,
PARAM_OUT,
diff --git a/src/target/armv4_5_cache.h b/src/target/armv4_5_cache.h
index 768938f..985a3a7 100644
--- a/src/target/armv4_5_cache.h
+++ b/src/target/armv4_5_cache.h
@@ -19,6 +19,8 @@
#ifndef OPENOCD_TARGET_ARMV4_5_CACHE_H
#define OPENOCD_TARGET_ARMV4_5_CACHE_H
+#include "helper/types.h"
+
struct command_invocation;
struct armv4_5_cachesize {
diff --git a/src/target/breakpoints.h b/src/target/breakpoints.h
index 20faf4e..8c247f7 100644
--- a/src/target/breakpoints.h
+++ b/src/target/breakpoints.h
@@ -21,6 +21,8 @@
#include <stdint.h>
+#include "helper/types.h"
+
struct target;
enum breakpoint_type {
diff --git a/src/target/image.h b/src/target/image.h
index 53c27d8..59b6508 100644
--- a/src/target/image.h
+++ b/src/target/image.h
@@ -26,6 +26,7 @@
#define OPENOCD_TARGET_IMAGE_H
#include <helper/fileio.h>
+#include <helper/replacements.h>
#ifdef HAVE_ELF_H
#include <elf.h>
diff --git a/src/target/nds32_edm.h b/src/target/nds32_edm.h
index 1dec190..2b5067a 100644
--- a/src/target/nds32_edm.h
+++ b/src/target/nds32_edm.h
@@ -19,6 +19,8 @@
#ifndef OPENOCD_TARGET_NDS32_EDM_H
#define OPENOCD_TARGET_NDS32_EDM_H
+#include "helper/types.h"
+
/**
* @file
* This is the interface to the Embedded Debug Module for Andes cores.
diff --git a/src/target/register.h b/src/target/register.h
index 5f1c25f..a7705f7 100644
--- a/src/target/register.h
+++ b/src/target/register.h
@@ -22,6 +22,9 @@
#ifndef OPENOCD_TARGET_REGISTER_H
#define OPENOCD_TARGET_REGISTER_H
+#include "helper/replacements.h"
+#include "helper/types.h"
+
struct target;
enum reg_type {
diff --git a/src/target/semihosting_common.h b/src/target/semihosting_common.h
index 8fb5e0c..b83464e 100644
--- a/src/target/semihosting_common.h
+++ b/src/target/semihosting_common.h
@@ -25,6 +25,7 @@
#include <stdint.h>
#include <stdbool.h>
#include <time.h>
+#include "helper/replacements.h"
/*
* According to:
diff --git a/src/target/target.h b/src/target/target.h
index f6044c5..9389690 100644
--- a/src/target/target.h
+++ b/src/target/target.h
@@ -32,6 +32,8 @@
#define OPENOCD_TARGET_TARGET_H
#include <helper/list.h>
+#include "helper/replacements.h"
+#include "helper/system.h"
#include <jim.h>
struct reg;
diff --git a/src/target/trace.h b/src/target/trace.h
index 2966bbd..45308c0 100644
--- a/src/target/trace.h
+++ b/src/target/trace.h
@@ -19,6 +19,8 @@
#ifndef OPENOCD_TARGET_TRACE_H
#define OPENOCD_TARGET_TRACE_H
+#include "helper/types.h"
+
struct target;
struct command_context;
diff --git a/src/transport/transport.c b/src/transport/transport.c
index cb000ab..ba1f9e9 100644
--- a/src/transport/transport.c
+++ b/src/transport/transport.c
@@ -42,6 +42,7 @@
*/
#include <helper/log.h>
+#include <helper/replacements.h>
#include <transport/transport.h>
extern struct command_context *global_cmd_ctx;
diff --git a/src/xsvf/xsvf.c b/src/xsvf/xsvf.c
index eaa5a3a..2a7b56d 100644
--- a/src/xsvf/xsvf.c
+++ b/src/xsvf/xsvf.c
@@ -39,6 +39,7 @@
#endif
#include "xsvf.h"
+#include "helper/system.h"
#include <jtag/jtag.h>
#include <svf/svf.h>